Initial food blog app

This commit is contained in:
Andy
2026-03-21 11:57:08 +00:00
commit b83762bfc3
33 changed files with 8621 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
"use client"
import Link from "next/link"
import { motion } from "framer-motion"
import { Restaurant, Visit } from "@/app/types"
function priceLabel(range: number) {
return "€".repeat(range)
}
function formatDate(iso: string) {
return new Date(iso).toLocaleDateString("en-GB", {
day: "numeric",
month: "short",
year: "numeric",
})
}
interface Props {
restaurant: Restaurant
latestVisit: Visit
index: number
}
export default function RestaurantCard({ restaurant, latestVisit, index }: Props) {
return (
<motion.div
initial={{ opacity: 0, y: 24 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, delay: index * 0.08, ease: [0.25, 0.1, 0.25, 1] }}
>
<Link href={`/restaurant/${restaurant.id}`}>
<div className="group relative rounded-2xl border border-white/[0.06] bg-white/[0.03] hover:bg-white/[0.06] hover:border-white/[0.12] transition-all duration-300 p-5 cursor-pointer overflow-hidden">
{/* Amber glow on hover */}
<div className="absolute inset-0 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-500 pointer-events-none"
style={{ background: "radial-gradient(circle at 50% 0%, rgba(245,158,11,0.06) 0%, transparent 70%)" }}
/>
<div className="flex items-start justify-between gap-4">
<div className="flex-1 min-w-0">
<h3 className="text-lg font-bold text-[#f5f5f5] group-hover:text-[#f59e0b] transition-colors truncate">
{restaurant.name}
</h3>
<p className="text-sm text-white/40 mt-0.5">
{restaurant.city}, {restaurant.country}
</p>
</div>
<div className="flex flex-col items-end gap-1 shrink-0">
<div className="flex items-center gap-1.5">
<span className="text-[#f59e0b] font-black text-lg leading-none">
{latestVisit.rating}
</span>
<span className="text-white/30 text-xs">/10</span>
</div>
<span className="text-white/30 text-xs font-medium tracking-wide">
{priceLabel(restaurant.price_range)}
</span>
</div>
</div>
<div className="mt-4">
{latestVisit.dishes[0] && (
<p className="text-sm text-white/60 italic truncate">
&ldquo;{latestVisit.dishes[0]}&rdquo;
</p>
)}
</div>
<div className="mt-4 flex items-center justify-between">
<div className="flex flex-wrap gap-1.5">
{restaurant.cuisine.slice(0, 3).map((tag) => (
<span
key={tag}
className="text-[10px] font-semibold uppercase tracking-wider text-[#f59e0b]/70 bg-[#f59e0b]/10 rounded-full px-2.5 py-0.5"
>
{tag}
</span>
))}
</div>
<span className="text-xs text-white/25 shrink-0">
{formatDate(latestVisit.date)}
</span>
</div>
{restaurant.visits.length > 1 && (
<div className="mt-3 pt-3 border-t border-white/[0.05]">
<p className="text-xs text-white/30">
{restaurant.visits.length} visits
</p>
</div>
)}
</div>
</Link>
</motion.div>
)
}