feat: implement QOL features (Stats, Search, Dram of the Day)
This commit is contained in:
101
src/components/DramOfTheDay.tsx
Normal file
101
src/components/DramOfTheDay.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Sparkles, GlassWater, Dices, X } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface Bottle {
|
||||
id: string;
|
||||
name: string;
|
||||
distillery?: string;
|
||||
status: 'sealed' | 'open' | 'sampled' | 'empty';
|
||||
}
|
||||
|
||||
interface DramOfTheDayProps {
|
||||
bottles: Bottle[];
|
||||
}
|
||||
|
||||
export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
|
||||
const [suggestion, setSuggestion] = useState<Bottle | null>(null);
|
||||
const [isRolling, setIsRolling] = useState(false);
|
||||
|
||||
const suggestDram = () => {
|
||||
setIsRolling(true);
|
||||
const openBottles = bottles.filter(b => b.status === 'open' || b.status === 'sampled');
|
||||
|
||||
if (openBottles.length === 0) {
|
||||
alert('Keine offenen Flaschen gefunden! Vielleicht Zeit für ein neues Tasting? 🥃');
|
||||
setIsRolling(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Simulate a "roll" for 800ms
|
||||
setTimeout(() => {
|
||||
const randomBottle = openBottles[Math.floor(Math.random() * openBottles.length)];
|
||||
setSuggestion(randomBottle);
|
||||
setIsRolling(false);
|
||||
}, 800);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<button
|
||||
onClick={suggestDram}
|
||||
disabled={isRolling}
|
||||
className="flex items-center gap-2 px-6 py-3 bg-amber-600 hover:bg-amber-700 text-white rounded-2xl font-black uppercase tracking-widest text-xs transition-all shadow-lg shadow-amber-600/20 active:scale-95 disabled:opacity-50"
|
||||
>
|
||||
{isRolling ? (
|
||||
<Dices size={18} className="animate-spin" />
|
||||
) : (
|
||||
<Sparkles size={18} />
|
||||
)}
|
||||
Dram of the Day
|
||||
</button>
|
||||
|
||||
{suggestion && (
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center p-6 bg-black/60 backdrop-blur-sm animate-in fade-in duration-300">
|
||||
<div className="bg-white dark:bg-zinc-900 w-full max-w-sm rounded-[40px] p-8 shadow-2xl border border-amber-500/20 relative animate-in zoom-in-95 duration-300">
|
||||
<button
|
||||
onClick={() => setSuggestion(null)}
|
||||
className="absolute top-6 right-6 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200"
|
||||
>
|
||||
<X size={24} />
|
||||
</button>
|
||||
|
||||
<div className="flex flex-col items-center text-center space-y-6">
|
||||
<div className="w-20 h-20 bg-amber-100 dark:bg-amber-900/30 rounded-3xl flex items-center justify-center text-amber-600">
|
||||
<GlassWater size={40} strokeWidth={2.5} />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-amber-600">Dein heutiger Dram</h3>
|
||||
<h2 className="text-2xl font-black text-zinc-900 dark:text-white leading-tight">
|
||||
{suggestion.name}
|
||||
</h2>
|
||||
{suggestion.distillery && (
|
||||
<p className="text-zinc-500 font-bold italic">{suggestion.distillery}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="w-full pt-4">
|
||||
<Link
|
||||
href={`/bottles/${suggestion.id}`}
|
||||
onClick={() => setSuggestion(null)}
|
||||
className="block w-full py-4 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-amber-600 dark:hover:bg-amber-600 hover:text-white transition-all shadow-xl"
|
||||
>
|
||||
Flasche anschauen
|
||||
</Link>
|
||||
<button
|
||||
onClick={suggestDram}
|
||||
className="w-full mt-3 py-2 text-zinc-400 hover:text-amber-600 text-[10px] font-black uppercase tracking-widest transition-colors"
|
||||
>
|
||||
Nicht heute, noch mal würfeln
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user