90 lines
3.4 KiB
TypeScript
90 lines
3.4 KiB
TypeScript
import { MapPin, Phone } from "lucide-react";
|
||
import { toPersianDigits } from "@/lib/format/persian-digits";
|
||
import type { StoreDetail } from "@/types/api";
|
||
|
||
/** Iranian week: 0=Saturday..6=Friday. JS Date#getDay(): 0=Sunday..6=Saturday. */
|
||
function todaysWorkingHours(store: StoreDetail) {
|
||
const jsDay = new Date().getDay();
|
||
const iranianWeekday = (jsDay + 1) % 7;
|
||
return (
|
||
store.working_hours.find((wh) => wh.weekday === iranianWeekday) ?? null
|
||
);
|
||
}
|
||
|
||
function formatTime(value: string | null) {
|
||
if (!value) return "";
|
||
return toPersianDigits(value.slice(0, 5));
|
||
}
|
||
|
||
/** designspec.md §2.2 — hero-overlapping white info card. */
|
||
export function StoreInfoCard({ store }: { store: StoreDetail }) {
|
||
const today = todaysWorkingHours(store);
|
||
const mapsUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(`${store.name} ${store.address}`)}`;
|
||
|
||
return (
|
||
<div className="w-[90%] relative z-10 -mt-24 rounded-3xl bg-white px-4 pt-5 pb-4 shadow-[0px_4px_20px_0px_rgba(0,0,0,0.102)]">
|
||
<h1 className="text-title-large font-extrabold leading-none text-primary-action">
|
||
{store.name}
|
||
</h1>
|
||
<p className="mt-1 text-[14px] leading-none text-gray-700">
|
||
{store.category.name}
|
||
</p>
|
||
|
||
<div className="mt-3 flex flex-wrap items-center gap-2">
|
||
<span
|
||
className={`rounded-full border px-2.5 py-1.5 text-[12px] font-semibold leading-none ${
|
||
store.is_open
|
||
? "border-emerald-border bg-emerald-bg text-emerald-text-strong"
|
||
: "border-gray-300 bg-gray-100 text-gray-600"
|
||
}`}
|
||
>
|
||
<span className="inline-flex items-center gap-1.5">
|
||
<span
|
||
className={`h-1.5 w-1.5 rounded-full ${store.is_open ? "bg-emerald-500" : "bg-gray-500"}`}
|
||
/>
|
||
{store.is_open ? "فعال" : "بسته"}
|
||
</span>
|
||
</span>
|
||
<span className="text-[13px] leading-none text-gray-600">|</span>
|
||
{today && (
|
||
<span className="h-6 flex items-center rounded-full bg-teal-light px-2 py-1 text-[11px] font-semibold leading-none text-primary-action">
|
||
{today.is_closed
|
||
? "تعطیل"
|
||
: `${formatTime(today.opens_at)} تا ${formatTime(today.closes_at)}`}
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
<div className="mt-4 flex items-center gap-2 p-2">
|
||
<span className="flex h-8 w-10 shrink-0 items-center justify-center rounded-[10px] border border-teal-border bg-teal-light text-primary-action">
|
||
<MapPin className="h-4 w-4" />
|
||
</span>
|
||
<span className="flex-1 truncate text-right text-[14px] leading-normal text-foreground">
|
||
{store.address}
|
||
</span>
|
||
<a
|
||
href={mapsUrl}
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="shrink-0 text-[13px] font-medium text-teal"
|
||
>
|
||
مسیریابی
|
||
</a>
|
||
</div>
|
||
|
||
{store.phone_number && (
|
||
<a
|
||
href={`tel:${store.phone_number}`}
|
||
className="mt-2 flex items-center gap-2 p-2"
|
||
>
|
||
<span className="flex h-8 w-10 shrink-0 items-center justify-center rounded-[10px] border border-teal-border bg-teal-light text-primary-action">
|
||
<Phone className="h-4 w-4" />
|
||
</span>
|
||
<span dir="ltr" className="text-right text-[14px] text-foreground">
|
||
{store.phone_number}
|
||
</span>
|
||
</a>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|