Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/supabase/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://supabase.com/docs/guides/local-development/cli/config
# A string used to distinguish different Supabase projects on the same host. Defaults to the
# working directory name when running `supabase init`.
project_id = "backend"
project_id = "freshscan-backend"

[api]
enabled = true
Expand Down
22 changes: 22 additions & 0 deletions backend/supabase/seed.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,25 @@ VALUES
('Jorabagan Market', 'Jorabagan, Kolkata', 22.5843, 88.3594, 65.0, 65, 15, 113),
('Jadavpur Fish Market', 'Jadavpur, Kolkata', 22.4981, 88.3706, 91.0, 91, 36, 248)
ON CONFLICT DO NOTHING;

-- Insert DEV bypass user so local scans don't fail foreign key constraints
INSERT INTO auth.users (
instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, created_at, updated_at, raw_app_meta_data, raw_user_meta_data, is_super_admin
) VALUES (
'00000000-0000-0000-0000-000000000000',
'977a222c-53a1-5f37-a984-b1c98ae18bff',
'authenticated',
'authenticated',
'dev@freshscan.local',
crypt('password123', gen_salt('bf')),
now(),
now(),
now(),
'{"provider":"email","providers":["email"]}',
'{"full_name": "Dev Tester"}',
false
) ON CONFLICT DO NOTHING;

INSERT INTO public.profiles (id, email, full_name)
VALUES ('977a222c-53a1-5f37-a984-b1c98ae18bff', 'dev@freshscan.local', 'Dev Tester')
ON CONFLICT DO NOTHING;
34 changes: 22 additions & 12 deletions src/pages/AnalysisDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,32 @@ import { api } from '../lib/api';
import type { ScanResult } from '../lib/types';

const BIOMARKER_META = {
gill_saturation: { label: 'Gill Saturation', icon: Droplets },
corneal_clarity: { label: 'Corneal Clarity', icon: EyeIcon },
epidermal_tension: { label: 'Epidermal Tension', icon: Fish },
gill_saturation: { label: 'Gill Saturation', icon: Droplets },
corneal_clarity: { label: 'Corneal Clarity', icon: EyeIcon },
epidermal_tension: { label: 'Epidermal Tension', icon: Fish },
} as const;

type BiomarkerKey = keyof typeof BIOMARKER_META;

function gradeColor(grade: string) {
if (grade === 'A+' || grade === 'A') return 'text-secondary';
if (grade === 'B') return 'text-neon';
if (grade === 'B') return 'text-neon';
return 'text-error';
}

export default function AnalysisDashboard() {
const [params] = useSearchParams();
const [scan, setScan] = useState<ScanResult | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [scan, setScan] = useState<ScanResult | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');

useEffect(() => {
async function load() {
setLoading(true);
setError('');
try {
const idParam = params.get('id');
const lastId = sessionStorage.getItem('lastScanId');
const idParam = params.get('id');
const lastId = sessionStorage.getItem('lastScanId');
const targetId = idParam || lastId;

const res = targetId
Expand Down Expand Up @@ -78,7 +78,7 @@ export default function AnalysisDashboard() {

const { freshness_index, grade, confidence, classification, species, biomarkers, recommendations } = scan;
const displayId = scan.scan_display_id;
const alerts = recommendations.alert_flags;
const alerts = recommendations.alert_flags;

return (
<div className="min-h-[calc(100vh-4rem)] px-6 md:px-16 lg:px-24 py-8 md:py-12">
Expand Down Expand Up @@ -132,13 +132,23 @@ export default function AnalysisDashboard() {
/>
</div>

<div className="flex items-center gap-4">
<div className="flex items-center gap-4 flex-wrap">
<span className="font-[family-name:var(--font-mono)] text-[0.5625rem] text-secondary tracking-widest">
CLASSIFICATION: {classification}
</span>

<span className="font-[family-name:var(--font-mono)] text-[0.5625rem] text-on-surface-variant tracking-widest">
CONFIDENCE: {confidence}%
</span>

<span
className={`px-2 py-1 border text-xs font-semibold font-[family-name:var(--font-mono)] tracking-widest ${confidence < 70
? "text-error"
: "text-neon"
}`}
>
{confidence < 70 ? "LOW_CONFIDENCE" : "HIGH_CONFIDENCE"}
</span>
</div>
</GlassCard>

Expand Down Expand Up @@ -191,7 +201,7 @@ export default function AnalysisDashboard() {
<div className="space-y-3">
{(Object.keys(BIOMARKER_META) as BiomarkerKey[]).map(key => {
const meta = BIOMARKER_META[key];
const bm = biomarkers[key];
const bm = biomarkers[key];
const Icon = meta.icon;
const isAlert = bm.status === 'CAUTION';

Expand Down
Loading