Files
backup-tool/frontend/src/pages/Settings.tsx
T
alex 66f9de17c5 feat(frontend): add Dashboard, Backups, and Settings pages
- Create Dashboard page with stats cards and recent activity feed
- Create Backups page with job listing table, create modal, and actions
- Create Settings page with tabs for General, Notifications, Security, Logs
- Update App.tsx to use new page components
- Add delete method to jobsApi in client.ts
- TypeScript compiles cleanly
2026-05-11 21:54:36 +02:00

206 lines
6.3 KiB
TypeScript

import { useState } from 'react';
const tabs = [
{ id: 'general', label: 'General' },
{ id: 'notifications', label: 'Notifications' },
{ id: 'security', label: 'Security' },
{ id: 'logs', label: 'Logs' },
];
function GeneralSettings() {
return (
<div className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Backup Retention (days)
</label>
<input
type="number"
defaultValue={30}
className="w-full max-w-xs rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Default Backup Strategy
</label>
<select
defaultValue="incremental"
className="w-full max-w-xs rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="full">Full</option>
<option value="incremental">Incremental</option>
<option value="differential">Differential</option>
</select>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="auto-cleanup"
defaultChecked
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="auto-cleanup" className="text-sm text-gray-700">
Enable automatic cleanup of old backups
</label>
</div>
</div>
);
}
function NotificationSettings() {
return (
<div className="space-y-6">
<div className="flex items-center gap-3">
<input
type="checkbox"
id="email-notify"
defaultChecked
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="email-notify" className="text-sm text-gray-700">
Enable email notifications
</label>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Email Address
</label>
<input
type="email"
placeholder="admin@example.com"
className="w-full max-w-md rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="notify-failures"
defaultChecked
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="notify-failures" className="text-sm text-gray-700">
Notify on backup failures only
</label>
</div>
</div>
);
}
function SecuritySettings() {
return (
<div className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Encryption Key
</label>
<input
type="password"
placeholder="Enter encryption key"
className="w-full max-w-md rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="encrypt-backups"
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="encrypt-backups" className="text-sm text-gray-700">
Encrypt all backups
</label>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="require-auth"
defaultChecked
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="require-auth" className="text-sm text-gray-700">
Require authentication for API access
</label>
</div>
</div>
);
}
function LogSettings() {
return (
<div className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Log Level
</label>
<select
defaultValue="info"
className="w-full max-w-xs rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="debug">Debug</option>
<option value="info">Info</option>
<option value="warn">Warning</option>
<option value="error">Error</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Log Retention (days)
</label>
<input
type="number"
defaultValue={7}
className="w-full max-w-xs rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="verbose-logs"
className="w-4 h-4 text-blue-600 rounded border-gray-300"
/>
<label htmlFor="verbose-logs" className="text-sm text-gray-700">
Enable verbose logging
</label>
</div>
</div>
);
}
export function Settings() {
const [activeTab, setActiveTab] = useState('general');
const tabContent = {
general: <GeneralSettings />,
notifications: <NotificationSettings />,
security: <SecuritySettings />,
logs: <LogSettings />,
};
return (
<div className="space-y-6">
<h2 className="text-2xl font-bold text-gray-900">Settings</h2>
<div className="bg-white rounded-lg border border-gray-200">
<div className="border-b border-gray-200">
<nav className="flex -mb-px">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`px-6 py-3 text-sm font-medium border-b-2 transition-colors ${
activeTab === tab.id
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
>
{tab.label}
</button>
))}
</nav>
</div>
<div className="p-6">{tabContent[activeTab as keyof typeof tabContent]}</div>
</div>
</div>
);
}