feat: implement advanced tagging system, tag weighting, and app focus refactoring

- Implemented reusable TagSelector component with i18n support
- Added tag weighting system (popularity scores 1-5)
- Created admin panel for tag management
- Integrated Nebius AI and Brave Search for 'Magic Scan'
- Refactored app focus: removed bottle status, updated counters, and displayed extended bottle details
- Updated i18n for German and English
- Added database migration scripts
This commit is contained in:
2025-12-19 12:58:44 +01:00
parent 9eb9b41061
commit b2a1d292da
30 changed files with 2420 additions and 194 deletions

View File

@@ -16,7 +16,7 @@ interface Tasting {
is_sample?: boolean;
bottle_id: string;
created_at: string;
tasting_tags?: {
tasting_buddies?: {
buddies: {
id: string;
name: string;
@@ -26,6 +26,14 @@ interface Tasting {
id: string;
name: string;
};
tasting_tags?: {
tags: {
id: string;
name: string;
category: string;
is_system_default: boolean;
}
}[];
user_id: string;
}
@@ -188,13 +196,30 @@ export default function TastingList({ initialTastings, currentUserId }: TastingL
</div>
{note.tasting_tags && note.tasting_tags.length > 0 && (
<div className="flex flex-wrap gap-1.5 pt-2">
{note.tasting_tags.map(tt => (
<span
key={tt.tags.id}
className={`px-2 py-0.5 rounded-lg text-[10px] font-bold uppercase tracking-tight border ${tt.tags.category === 'nose' ? 'bg-green-50 text-green-700 border-green-100 dark:bg-green-900/20 dark:text-green-400 dark:border-green-800/50' :
tt.tags.category === 'taste' ? 'bg-blue-50 text-blue-700 border-blue-100 dark:bg-blue-900/20 dark:text-blue-400 dark:border-blue-800/50' :
tt.tags.category === 'finish' ? 'bg-amber-50 text-amber-700 border-amber-100 dark:bg-amber-900/20 dark:text-amber-400 dark:border-amber-800/50' :
'bg-zinc-50 text-zinc-700 border-zinc-100 dark:bg-zinc-900/20 dark:text-zinc-400 dark:border-zinc-800/50'
}`}
>
{tt.tags.is_system_default ? t(`aroma.${tt.tags.name}`) : tt.tags.name}
</span>
))}
</div>
)}
{note.tasting_buddies && note.tasting_buddies.length > 0 && (
<div className="pt-3 flex items-center justify-between border-t border-zinc-100 dark:border-zinc-800">
<div className="flex items-center gap-2">
<span className="text-[10px] font-black text-zinc-400 uppercase tracking-widest flex items-center gap-1.5 mr-1">
<Users size={12} className="text-amber-500" />
{t('tasting.with') || 'Mit'}:
</span>
<AvatarStack names={note.tasting_tags.map(tag => tag.buddies.name)} />
<AvatarStack names={note.tasting_buddies.map(tag => tag.buddies.name)} />
</div>
</div>
)}