Spaces:
Running
Running
File size: 7,671 Bytes
5269e5c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | import React from 'react';
const DeviceActionModal = ({ device, action, onClose, onConfirm }) => {
if (!device || !action) return null;
const getActionIcon = (name) => {
switch (name) {
case 'Sync':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
);
case 'Backup':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2" />
</svg>
);
case 'Restore':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
);
case 'Erase':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
);
case 'Update':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-purple-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);
case 'Unlock':
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-yellow-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
);
default:
return (
<svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
);
}
};
const getActionTitle = (name) => {
switch (name) {
case 'Sync': return 'Sync Device';
case 'Backup': return 'Create Backup';
case 'Restore': return 'Restore Device';
case 'Erase': return 'Erase All Content';
case 'Update': return 'Update Software';
case 'Unlock': return 'Unlock Device';
default: return name;
}
};
const getActionDescription = (name) => {
switch (name) {
case 'Sync': return `Sync data with ${device.name} including photos, music, and contacts.`;
case 'Backup': return `Create a full backup of ${device.name} with all settings and data.`;
case 'Restore': return `Restore ${device.name} to factory settings. This will erase all data.`;
case 'Erase': return `Erase all content and settings from ${device.name}. This cannot be undone.`;
case 'Update': return `Check for and install the latest software updates for ${device.name}.`;
case 'Unlock': return `Unlock ${device.name} if it's locked or requires a passcode.`;
default: return `Perform ${name} operation on ${device.name}.`;
}
};
return (
<div className="fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true" onClick={onClose}></div>
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<div className="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full">
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mt-3 text-center sm:mt-0 sm:text-left w-full">
<div className="flex justify-center mb-4">
{getActionIcon(action.name)}
</div>
<h3 className="text-lg leading-6 font-medium text-gray-900 text-center" id="modal-title">
{getActionTitle(action.name)}
</h3>
<div className="mt-4">
<p className="text-sm text-gray-500 text-center">
{getActionDescription(action.name)}
</p>
<p className="text-sm text-gray-700 mt-2 text-center font-medium">
Device: <span className="font-bold">{device.name}</span>
</p>
</div>
{action.danger && (
<div className="mt-6 bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
</div>
<div className="ml-3">
<p className="text-sm text-red-700">
<span className="font-bold">Warning: </span>
{action.name === 'Erase'
? 'This will permanently delete all data on the device. Make sure you have a backup first.'
: 'This action may cause data loss. Proceed with caution.'}
</p>
</div>
</div>
</div>
)}
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button
type="button"
className={`w-full inline-flex justify-center rounded-md border shadow-sm px-4 py-2 text-base font-medium text-white focus:outline-none sm:ml-3 sm:w-auto sm:text-sm ${
action.danger
? 'bg-red-600 hover:bg-red-700 focus:ring-red-500'
: 'bg-blue-600 hover:bg-blue-700 focus:ring-blue-500'
}`}
onClick={() => onConfirm(device, action.name)}
>
Confirm {getActionTitle(action.name)}
</button>
<button |