feat(#3): frontend scaffold (Next.js 14 App Router, TS, Tailwind, галерея)
Deploy / deploy (push) Failing after 5s
Deploy / deploy (push) Failing after 5s
Каркас витрины дизайнера Ники: главная (hero + сетка галереи), страница работы (детали + место под аукцион), список аукционов, подписка-заглушка. Клиент к backend /api с graceful-фолбэком на демо-работы при недоступном API. Standalone-сборка + Dockerfile. Сборка npm run build и tsc --noEmit проходят. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
be29d02cc0
commit
ad35d4e992
@@ -0,0 +1,55 @@
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import type { Work } from '@/lib/types';
|
||||
import { coverOf, formatPrice } from '@/lib/format';
|
||||
|
||||
export default function WorkCard({ work }: { work: Work }) {
|
||||
const href = `/works/${work.slug || work.id}`;
|
||||
const cover = coverOf(work, 800, 1000);
|
||||
const onAuction = work.auction_mode !== 'none';
|
||||
const sold = work.status === 'sold';
|
||||
|
||||
return (
|
||||
<Link href={href} className="group block animate-fade-in">
|
||||
<figure className="relative overflow-hidden bg-line/40 dark:bg-white/5">
|
||||
{/* Пропорция портретного холста */}
|
||||
<div className="relative aspect-[4/5] w-full">
|
||||
<Image
|
||||
src={cover}
|
||||
alt={work.title}
|
||||
fill
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
||||
className="object-cover transition-transform duration-700 ease-gallery group-hover:scale-[1.03]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{(onAuction || sold) && (
|
||||
<figcaption className="absolute left-3 top-3 flex gap-2">
|
||||
{sold && (
|
||||
<span className="rounded-full bg-ink/85 px-3 py-1 text-[11px] uppercase tracking-wide text-paper">
|
||||
Продано
|
||||
</span>
|
||||
)}
|
||||
{onAuction && !sold && (
|
||||
<span className="rounded-full bg-accent/90 px-3 py-1 text-[11px] uppercase tracking-wide text-white">
|
||||
Аукцион
|
||||
</span>
|
||||
)}
|
||||
</figcaption>
|
||||
)}
|
||||
</figure>
|
||||
|
||||
<div className="mt-4 flex items-baseline justify-between gap-4">
|
||||
<div className="min-w-0">
|
||||
<h3 className="truncate font-serif text-xl tracking-tightest">
|
||||
{work.title}
|
||||
</h3>
|
||||
<p className="mt-0.5 text-sm text-muted">
|
||||
{[work.medium, work.year].filter(Boolean).join(' · ') || 'Работа'}
|
||||
</p>
|
||||
</div>
|
||||
<p className="shrink-0 text-sm text-accent">{formatPrice(work.price)}</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user