feat: Add Spotify-style backdrop, Cascade OCR, Smart Scan Flow & OCR Dashboard

- BottleGrid: Implement blurred backdrop effect for bottle cards
- Cascade OCR: TextDetector → RegEx → Fuzzy Match → window.ai pipeline
- Smart Scan: Native OCR for Android, Live Text fallback for iOS
- OCR Dashboard: Admin page at /admin/ocr-logs with stats and scan history
- Features: Add feature flags in src/config/features.ts
- SQL: Add ocr_logs table migration
- Services: Update analyze-bottle to use OpenRouter, add save-ocr-log
This commit is contained in:
2026-01-18 20:38:48 +01:00
parent 83e852e5fb
commit 9ba0825bcd
46 changed files with 3874 additions and 741 deletions

View File

@@ -0,0 +1,65 @@
'use client';
import React from 'react';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
ResponsiveContainer
} from 'recharts';
interface FlavorProfile {
smoky: number;
fruity: number;
spicy: number;
sweet: number;
floral: number;
}
interface FlavorRadarProps {
profile: FlavorProfile;
size?: number;
showAxis?: boolean;
}
export default function FlavorRadar({ profile, size = 300, showAxis = true }: FlavorRadarProps) {
const data = [
{ subject: 'Smoky', A: profile.smoky, fullMark: 100 },
{ subject: 'Fruity', A: profile.fruity, fullMark: 100 },
{ subject: 'Spicy', A: profile.spicy, fullMark: 100 },
{ subject: 'Sweet', A: profile.sweet, fullMark: 100 },
{ subject: 'Floral', A: profile.floral, fullMark: 100 },
];
return (
<div style={{ width: '100%', height: size }} className="flex items-center justify-center">
<ResponsiveContainer width="100%" height="100%">
<RadarChart cx="50%" cy="50%" outerRadius="70%" data={data}>
<PolarGrid stroke="#3f3f46" />
<PolarAngleAxis
dataKey="subject"
tick={{ fill: '#71717a', fontSize: 10, fontWeight: 700 }}
/>
{!showAxis && <PolarRadiusAxis axisLine={false} tick={false} />}
{showAxis && (
<PolarRadiusAxis
angle={30}
domain={[0, 100]}
tick={{ fill: '#3f3f46', fontSize: 8 }}
axisLine={false}
/>
)}
<Radar
name="Flavor"
dataKey="A"
stroke="#d97706"
fill="#d97706"
fillOpacity={0.5}
/>
</RadarChart>
</ResponsiveContainer>
</div>
);
}