Create src/components/SystemSettings.tsx
Browse files
src/components/SystemSettings.tsx
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import { useOncologyStore } from '../store/useOncologyStore';
|
| 3 |
+
import {
|
| 4 |
+
Settings,
|
| 5 |
+
Trash2,
|
| 6 |
+
Download,
|
| 7 |
+
Moon,
|
| 8 |
+
Sun,
|
| 9 |
+
Monitor,
|
| 10 |
+
Database,
|
| 11 |
+
AlertTriangle,
|
| 12 |
+
Activity
|
| 13 |
+
} from 'lucide-react';
|
| 14 |
+
|
| 15 |
+
const SystemSettings: React.FC = () => {
|
| 16 |
+
const {
|
| 17 |
+
theme,
|
| 18 |
+
setTheme,
|
| 19 |
+
isToxicityModelEnabled,
|
| 20 |
+
toggleToxicityModel,
|
| 21 |
+
sessions,
|
| 22 |
+
setView
|
| 23 |
+
} = useOncologyStore();
|
| 24 |
+
|
| 25 |
+
const exportVault = () => {
|
| 26 |
+
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(sessions));
|
| 27 |
+
const downloadAnchorNode = document.createElement('a');
|
| 28 |
+
downloadAnchorNode.setAttribute("href", dataStr);
|
| 29 |
+
downloadAnchorNode.setAttribute("download", `abyssinia_vault_${Date.now()}.json`);
|
| 30 |
+
document.body.appendChild(downloadAnchorNode);
|
| 31 |
+
downloadAnchorNode.click();
|
| 32 |
+
downloadAnchorNode.remove();
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
const clearVault = () => {
|
| 36 |
+
if (window.confirm("CRITICAL: THIS WILL PERMANENTLY ERASE ALL CLINICAL SESSIONS. PROCEED?")) {
|
| 37 |
+
localStorage.removeItem('abyssinia-v15-vault');
|
| 38 |
+
window.location.reload();
|
| 39 |
+
}
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
return (
|
| 43 |
+
<div className="max-w-4xl mx-auto space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-700">
|
| 44 |
+
<header className="pb-6 border-b border-slate-800">
|
| 45 |
+
<div className="flex items-center gap-3">
|
| 46 |
+
<Settings className="w-6 h-6 text-gemini-500" />
|
| 47 |
+
<h2 className="text-2xl font-black italic uppercase tracking-tighter text-slate-100">
|
| 48 |
+
System Configuration
|
| 49 |
+
</h2>
|
| 50 |
+
</div>
|
| 51 |
+
<p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest mt-2">
|
| 52 |
+
V15.0.0-STABLE / KERNEL: PRODUCTION / ARCH: x64
|
| 53 |
+
</p>
|
| 54 |
+
</header>
|
| 55 |
+
|
| 56 |
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
| 57 |
+
{/* Appearance Section */}
|
| 58 |
+
<section className="bg-slate-900/40 border border-slate-800 rounded-2xl p-6 space-y-6">
|
| 59 |
+
<h3 className="text-[11px] font-black uppercase text-slate-400 tracking-[0.2em] flex items-center gap-2">
|
| 60 |
+
<Monitor className="w-4 h-4" /> Visual Engine
|
| 61 |
+
</h3>
|
| 62 |
+
|
| 63 |
+
<div className="grid grid-cols-3 gap-2">
|
| 64 |
+
{[
|
| 65 |
+
{ id: 'light', icon: Sun, label: 'Light' },
|
| 66 |
+
{ id: 'dark', icon: Moon, label: 'Dark' },
|
| 67 |
+
{ id: 'system', icon: Monitor, label: 'Auto' }
|
| 68 |
+
].map((t) => (
|
| 69 |
+
<button
|
| 70 |
+
key={t.id}
|
| 71 |
+
onClick={() => setTheme(t.id as any)}
|
| 72 |
+
className={`flex flex-col items-center gap-2 p-3 rounded-xl border transition-all ${
|
| 73 |
+
theme === t.id
|
| 74 |
+
? 'bg-gemini-500/10 border-gemini-500 text-gemini-500'
|
| 75 |
+
: 'bg-slate-950/50 border-slate-800 text-slate-500 hover:border-slate-700'
|
| 76 |
+
}`}
|
| 77 |
+
>
|
| 78 |
+
<t.icon className="w-5 h-5" />
|
| 79 |
+
<span className="text-[10px] font-bold uppercase">{t.label}</span>
|
| 80 |
+
</button>
|
| 81 |
+
))}
|
| 82 |
+
</div>
|
| 83 |
+
</section>
|
| 84 |
+
|
| 85 |
+
{/* Model Configuration */}
|
| 86 |
+
<section className="bg-slate-900/40 border border-slate-800 rounded-2xl p-6 space-y-6">
|
| 87 |
+
<h3 className="text-[11px] font-black uppercase text-slate-400 tracking-[0.2em] flex items-center gap-2">
|
| 88 |
+
<Activity className="w-4 h-4" /> Predictive Analytics
|
| 89 |
+
</h3>
|
| 90 |
+
|
| 91 |
+
<div className="flex items-center justify-between p-4 bg-slate-950/50 border border-slate-800 rounded-xl">
|
| 92 |
+
<div>
|
| 93 |
+
<p className="text-xs font-bold text-slate-200 uppercase">Toxicity Forecasting</p>
|
| 94 |
+
<p className="text-[10px] text-slate-500 mt-1">Pharmacological AE mapping engine</p>
|
| 95 |
+
</div>
|
| 96 |
+
<button
|
| 97 |
+
onClick={toggleToxicityModel}
|
| 98 |
+
className={`w-12 h-6 rounded-full transition-colors relative ${
|
| 99 |
+
isToxicityModelEnabled ? 'bg-gemini-500' : 'bg-slate-800'
|
| 100 |
+
}`}
|
| 101 |
+
>
|
| 102 |
+
<div className={`absolute top-1 w-4 h-4 bg-white rounded-full transition-all ${
|
| 103 |
+
isToxicityModelEnabled ? 'left-7' : 'left-1'
|
| 104 |
+
}`} />
|
| 105 |
+
</button>
|
| 106 |
+
</div>
|
| 107 |
+
</section>
|
| 108 |
+
</div>
|
| 109 |
+
|
| 110 |
+
{/* Data Management Section */}
|
| 111 |
+
<section className="bg-slate-900/40 border border-slate-800 rounded-2xl p-6 space-y-6">
|
| 112 |
+
<h3 className="text-[11px] font-black uppercase text-slate-400 tracking-[0.2em] flex items-center gap-2">
|
| 113 |
+
<Database className="w-4 h-4" /> Clinical Vault Management
|
| 114 |
+
</h3>
|
| 115 |
+
|
| 116 |
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 117 |
+
<button
|
| 118 |
+
onClick={exportVault}
|
| 119 |
+
className="flex items-center justify-between p-4 bg-slate-950/50 border border-slate-800 hover:border-gemini-500/50 rounded-xl transition-all group"
|
| 120 |
+
>
|
| 121 |
+
<div className="text-left">
|
| 122 |
+
<p className="text-xs font-bold text-slate-200 uppercase">Export Case History</p>
|
| 123 |
+
<p className="text-[10px] text-slate-500 mt-1">Download encrypted JSON archive</p>
|
| 124 |
+
</div>
|
| 125 |
+
<Download className="w-5 h-5 text-slate-600 group-hover:text-gemini-500 transition-colors" />
|
| 126 |
+
</button>
|
| 127 |
+
|
| 128 |
+
<button
|
| 129 |
+
onClick={clearVault}
|
| 130 |
+
className="flex items-center justify-between p-4 bg-red-500/5 border border-red-500/20 hover:bg-red-500/10 hover:border-red-500/50 rounded-xl transition-all group"
|
| 131 |
+
>
|
| 132 |
+
<div className="text-left">
|
| 133 |
+
<p className="text-xs font-bold text-red-400 uppercase">Purge Local Vault</p>
|
| 134 |
+
<p className="text-[10px] text-red-500/60 mt-1">Erase all records and signatures</p>
|
| 135 |
+
</div>
|
| 136 |
+
<Trash2 className="w-5 h-5 text-red-900 group-hover:text-red-500 transition-colors" />
|
| 137 |
+
</button>
|
| 138 |
+
</div>
|
| 139 |
+
|
| 140 |
+
<div className="p-4 bg-amber-500/5 border border-amber-500/20 rounded-xl flex gap-4 items-start">
|
| 141 |
+
<AlertTriangle className="w-5 h-5 text-amber-500 shrink-0 mt-0.5" />
|
| 142 |
+
<p className="text-[10px] text-amber-500/80 leading-relaxed uppercase font-medium">
|
| 143 |
+
Note: All data is stored locally in this browser. Clearing the cache or using a
|
| 144 |
+
different workstation will result in the loss of case history unless a JSON
|
| 145 |
+
export is performed beforehand.
|
| 146 |
+
</p>
|
| 147 |
+
</div>
|
| 148 |
+
</section>
|
| 149 |
+
</div>
|
| 150 |
+
);
|
| 151 |
+
};
|
| 152 |
+
|
| 153 |
+
export default SystemSettings;
|