-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.tsx
More file actions
143 lines (133 loc) · 5.46 KB
/
App.tsx
File metadata and controls
143 lines (133 loc) · 5.46 KB
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
139
140
141
142
143
import React, { useState, useEffect } from 'react';
import {
LayoutDashboard,
FlaskConical,
BarChart3,
Settings,
Plus,
ChevronRight,
Zap,
Clock,
DollarSign,
TrendingUp,
BrainCircuit,
Database
} from 'lucide-react';
import Dashboard from './components/Dashboard';
import Experiments from './components/Experiments';
import Analysis from './components/Analysis';
import { ExperimentRun } from './types';
const INITIAL_RUNS: ExperimentRun[] = [
{
id: 'run-1',
round: 1,
parameters: { mediaType: 'Standard A', temperature: 37, ph: 7.2, dissolvedOxygen: 40, glucoseFeedRate: 1.5 },
results: { yield: 1.2, purity: 85, titer: 0.8, viability: 92 },
status: 'completed',
timestamp: '2024-03-01T10:00:00Z'
},
{
id: 'run-2',
round: 1,
parameters: { mediaType: 'Standard B', temperature: 37, ph: 7.4, dissolvedOxygen: 45, glucoseFeedRate: 1.2 },
results: { yield: 1.5, purity: 88, titer: 1.1, viability: 94 },
status: 'completed',
timestamp: '2024-03-02T10:00:00Z'
},
{
id: 'run-3',
round: 2,
parameters: { mediaType: 'Optimized V1', temperature: 36.5, ph: 7.1, dissolvedOxygen: 50, glucoseFeedRate: 2.0 },
results: { yield: 3.8, purity: 92, titer: 2.8, viability: 96 },
status: 'completed',
timestamp: '2024-03-10T10:00:00Z'
}
];
const App: React.FC = () => {
const [activeTab, setActiveTab] = useState<'dashboard' | 'experiments' | 'analysis'>('dashboard');
const [runs, setRuns] = useState<ExperimentRun[]>(INITIAL_RUNS);
const addRun = (newRun: ExperimentRun) => {
setRuns(prev => [...prev, newRun]);
};
return (
<div className="flex h-screen bg-slate-50 font-sans text-slate-900">
{/* Sidebar */}
<aside className="w-64 bg-white border-r border-slate-200 flex flex-col">
<div className="p-6">
<div className="flex items-center gap-2 mb-8">
<div className="bg-indigo-600 p-2 rounded-lg text-white">
<BrainCircuit size={24} />
</div>
<div>
<h1 className="text-xl font-bold tracking-tight text-indigo-900 leading-none">AccelBio</h1>
<span className="text-[10px] uppercase tracking-widest text-indigo-500 font-semibold">Adaptive AI Engine</span>
</div>
</div>
<nav className="space-y-1">
<button
onClick={() => setActiveTab('dashboard')}
className={`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${activeTab === 'dashboard' ? 'bg-indigo-50 text-indigo-700 font-medium' : 'text-slate-500 hover:bg-slate-50'}`}
>
<LayoutDashboard size={20} />
Dashboard
</button>
<button
onClick={() => setActiveTab('experiments')}
className={`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${activeTab === 'experiments' ? 'bg-indigo-50 text-indigo-700 font-medium' : 'text-slate-500 hover:bg-slate-50'}`}
>
<FlaskConical size={20} />
Experiments
</button>
<button
onClick={() => setActiveTab('analysis')}
className={`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${activeTab === 'analysis' ? 'bg-indigo-50 text-indigo-700 font-medium' : 'text-slate-500 hover:bg-slate-50'}`}
>
<BarChart3 size={20} />
Analytics
</button>
</nav>
</div>
<div className="mt-auto p-6 border-t border-slate-200">
<div className="bg-slate-50 rounded-xl p-4 mb-4">
<p className="text-xs text-slate-500 mb-2">Usage Credits</p>
<div className="h-2 w-full bg-slate-200 rounded-full overflow-hidden">
<div className="h-full w-2/3 bg-indigo-500"></div>
</div>
<p className="text-[10px] mt-1 text-slate-400">840 / 1200 used</p>
</div>
<button className="flex items-center gap-3 text-slate-500 hover:text-slate-700 w-full px-4">
<Settings size={20} />
Settings
</button>
</div>
</aside>
{/* Main Content */}
<main className="flex-1 overflow-y-auto">
<header className="h-16 bg-white border-b border-slate-200 flex items-center justify-between px-8 sticky top-0 z-10">
<div className="flex items-center gap-2 text-sm text-slate-500">
<span>Project</span>
<ChevronRight size={14} />
<span className="text-slate-900 font-medium">Plasmid Rescue Alpha</span>
</div>
<div className="flex items-center gap-4">
<div className="flex -space-x-2">
{[1, 2, 3].map(i => (
<img key={i} className="w-8 h-8 rounded-full border-2 border-white" src={`https://picsum.photos/seed/${i + 10}/32/32`} alt="user" />
))}
</div>
<button className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg text-sm font-medium flex items-center gap-2 transition-all">
<Plus size={18} />
New Experiment
</button>
</div>
</header>
<div className="p-8">
{activeTab === 'dashboard' && <Dashboard runs={runs} />}
{activeTab === 'experiments' && <Experiments runs={runs} onAddRun={addRun} />}
{activeTab === 'analysis' && <Analysis runs={runs} />}
</div>
</main>
</div>
);
};
export default App;