perf: modified routing button in cafe detail page
This commit is contained in:
parent
5b7f904dbe
commit
165c7fd0eb
2 changed files with 58 additions and 15 deletions
|
|
@ -168,18 +168,51 @@ function ImageCarousel({ images }: { images: string[] }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openNavigationPicker(name: string, lat: number, lng: number) {
|
function NavigationSheet({
|
||||||
const mapsUrl = `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}`;
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
lat,
|
||||||
|
lng,
|
||||||
|
}: {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
lat: number;
|
||||||
|
lng: number;
|
||||||
|
}) {
|
||||||
|
if (!isOpen) return null;
|
||||||
|
|
||||||
if (navigator.share) {
|
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
||||||
try {
|
|
||||||
await navigator.share({ title: name, url: mapsUrl });
|
const apps: { label: string; url: string }[] = [
|
||||||
} catch {
|
{ label: "نشان", url: `https://neshan.org/maps/@${lat},${lng},15z` },
|
||||||
// user dismissed the native share sheet
|
{ label: "بلد", url: `https://balad.ir/p?lat=${lat}&lng=${lng}` },
|
||||||
}
|
{ label: "Waze", url: `https://waze.com/ul?ll=${lat},${lng}&navigate=yes` },
|
||||||
} else {
|
{ label: "Google Maps", url: `https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}` },
|
||||||
window.open(mapsUrl, "_blank");
|
...(isIOS ? [{ label: "Apple Maps", url: `maps://?daddr=${lat},${lng}` }] : []),
|
||||||
}
|
];
|
||||||
|
|
||||||
|
return createPortal(
|
||||||
|
<>
|
||||||
|
<div className="fixed inset-0 z-9998 bg-black/50" onClick={onClose} />
|
||||||
|
<div className="fixed inset-x-0 bottom-0 z-9999 rounded-t-3xl bg-white px-5 pb-8 pt-4">
|
||||||
|
<div className="mx-auto mb-4 h-1 w-10 rounded-full bg-gray-200" />
|
||||||
|
<h3 className="mb-4 text-right font-semibold text-gray-900">مسیریابی با</h3>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
{apps.map((app) => (
|
||||||
|
<button
|
||||||
|
key={app.label}
|
||||||
|
type="button"
|
||||||
|
onClick={() => { window.open(app.url, "_blank"); onClose(); }}
|
||||||
|
className="w-full rounded-2xl border border-gray-200 py-3 text-center text-gray-900 active:bg-gray-50"
|
||||||
|
>
|
||||||
|
{app.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>,
|
||||||
|
document.body,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CafeDetail() {
|
export default function CafeDetail() {
|
||||||
|
|
@ -187,6 +220,7 @@ export default function CafeDetail() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const now = useNow();
|
const now = useNow();
|
||||||
const [isReservationOpen, setIsReservationOpen] = useState(false);
|
const [isReservationOpen, setIsReservationOpen] = useState(false);
|
||||||
|
const [isNavigationOpen, setIsNavigationOpen] = useState(false);
|
||||||
const [schedules, setSchedules] = useState<CafeSchedule[]>([]);
|
const [schedules, setSchedules] = useState<CafeSchedule[]>([]);
|
||||||
const [selectedEventUuid] = useState("");
|
const [selectedEventUuid] = useState("");
|
||||||
const [schedule, setSchedule] = useState<CafeEventSchedule | undefined>(
|
const [schedule, setSchedule] = useState<CafeEventSchedule | undefined>(
|
||||||
|
|
@ -332,9 +366,7 @@ export default function CafeDetail() {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() => setIsNavigationOpen(true)}
|
||||||
openNavigationPicker(cafe.name, mapPosition[0], mapPosition[1])
|
|
||||||
}
|
|
||||||
className="mt-4 w-full rounded-2xl border border-[#223D5D] py-3 text-center text-gray-900"
|
className="mt-4 w-full rounded-2xl border border-[#223D5D] py-3 text-center text-gray-900"
|
||||||
>
|
>
|
||||||
مسیریابی
|
مسیریابی
|
||||||
|
|
@ -368,6 +400,12 @@ export default function CafeDetail() {
|
||||||
ticketPrice={schedule ? Number(schedule.ticket_price) : 0}
|
ticketPrice={schedule ? Number(schedule.ticket_price) : 0}
|
||||||
cafeMatchScheduleUuid={schedule?.schedule_uuid ?? ""}
|
cafeMatchScheduleUuid={schedule?.schedule_uuid ?? ""}
|
||||||
/>
|
/>
|
||||||
|
<NavigationSheet
|
||||||
|
isOpen={isNavigationOpen}
|
||||||
|
onClose={() => setIsNavigationOpen(false)}
|
||||||
|
lat={mapPosition[0]}
|
||||||
|
lng={mapPosition[1]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ function MyReservationsRow() {
|
||||||
function CafeCard({ cafe }: { cafe: Cafe }) {
|
function CafeCard({ cafe }: { cafe: Cafe }) {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const remainingTickets = cafe.schedules?.[0]?.remaining_tickets
|
const remainingTickets = cafe.schedules?.[0]?.remaining_tickets
|
||||||
|
const firstImage = cafe.media.find((m) => m.type === 'image')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -251,7 +252,11 @@ function CafeCard({ cafe }: { cafe: Cafe }) {
|
||||||
onClick={() => navigate(`/cafe/${cafe.uuid}`, { state: { cafe } })}
|
onClick={() => navigate(`/cafe/${cafe.uuid}`, { state: { cafe } })}
|
||||||
className="flex w-full items-center justify-start gap-4 rounded-2xl bg-white p-4 text-right shadow-sm"
|
className="flex w-full items-center justify-start gap-4 rounded-2xl bg-white p-4 text-right shadow-sm"
|
||||||
>
|
>
|
||||||
<div className="h-32 w-36 shrink-0 rounded-xl bg-gray-200" />
|
<div className="h-32 w-36 shrink-0 overflow-hidden rounded-xl bg-gray-200">
|
||||||
|
{firstImage && (
|
||||||
|
<img src={firstImage.url} alt="" className="h-full w-full object-cover" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="flex flex-col items-start gap-2">
|
<div className="flex flex-col items-start gap-2">
|
||||||
<h3 className="font-semibold text-gray-900">{cafe.name}</h3>
|
<h3 className="font-semibold text-gray-900">{cafe.name}</h3>
|
||||||
{remainingTickets !== undefined && (
|
{remainingTickets !== undefined && (
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue