- HeaderWithSupport is now lg:hidden (all its callers are desktop-full-width store/profile pages), removing the stray mobile back+support bar on desktop. - Constrain + title the previously mobile-only pages so their content doesn't stretch edge-to-edge on desktop: store edit/create form (StoreForm), add product, shipping method, financial sub-pages (cash-funds/reports/ transactions), order detail, instagram auth; and profile add/edit address, set detail, and payment result. Forms use a narrow centered column, lists/ details a wider one. Transactions keeps its filter button (header restyled, not hidden). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import type { MetaFunction } from "@remix-run/node";
|
||
import { useParams } from "@remix-run/react";
|
||
import { ClientOnly } from "../components/ClientOnly";
|
||
import { Suspense, lazy, useEffect, useState } from "react";
|
||
import ProfilePagesHeader from "../components/ProfilePagesHeader";
|
||
import { useServiceGetAddresses } from "../utils/RequestHandler";
|
||
import { useToast } from "../hooks/use-toast";
|
||
import { Address } from "src/api/types";
|
||
import UiProvider from "~/components/UiProvider";
|
||
|
||
export const meta: MetaFunction = () => {
|
||
return [
|
||
{ title: "ویرایش آدرس" },
|
||
{
|
||
name: "description",
|
||
content: "ویرایش آدرس انتخابی",
|
||
},
|
||
];
|
||
};
|
||
|
||
export default function EditLocation() {
|
||
const params = useParams();
|
||
const { toast } = useToast();
|
||
const [addressData, setAddressData] = useState<Address | null>(null);
|
||
const [mapReady, setMapReady] = useState(false);
|
||
|
||
// Fetch the address data
|
||
const {
|
||
data: addresses,
|
||
isFetching: isLoading,
|
||
isError,
|
||
refetch,
|
||
} = useServiceGetAddresses();
|
||
|
||
// Find the specific address to edit
|
||
useEffect(() => {
|
||
if (addresses && params.id) {
|
||
// Convert address ID to a number
|
||
const address = addresses.find(
|
||
(addr: Address) => addr.id == params.id // Use == instead of === for type-insensitive comparison
|
||
);
|
||
|
||
if (address) {
|
||
setAddressData(address);
|
||
// Only prepare the map for loading after receiving the correct address
|
||
setMapReady(true);
|
||
} else {
|
||
toast({
|
||
title: "آدرس یافت نشد",
|
||
description: "آدرس مورد نظر برای ویرایش یافت نشد.",
|
||
variant: "destructive",
|
||
});
|
||
}
|
||
}
|
||
}, [addresses, params.id, toast]);
|
||
|
||
// When user leaves the page, clear the map state
|
||
useEffect(() => {
|
||
return () => {
|
||
// Clean up when leaving the page
|
||
setMapReady(false);
|
||
};
|
||
}, []);
|
||
return (
|
||
<div className="flex flex-col gap-2 w-full lg:max-w-[820px] lg:mx-auto lg:pt-6">
|
||
<ProfilePagesHeader title="ویرایش آدرس" />
|
||
<h1 className="hidden lg:block text-[28px] font-extrabold px-4 mb-2">
|
||
ویرایش آدرس
|
||
</h1>
|
||
<UiProvider
|
||
isLoading={isLoading}
|
||
isEmpty={!addressData}
|
||
isError={isError}
|
||
onRetry={refetch}
|
||
type="locationEdit"
|
||
>
|
||
<ClientOnly
|
||
fallback={
|
||
<div className="w-full bg-WHITE3 flex items-center justify-center p-4">
|
||
در حال بارگذاری فرم...
|
||
</div>
|
||
}
|
||
>
|
||
{() => {
|
||
const InteractiveMap = lazy(
|
||
() => import("../components/InteractiveMap")
|
||
);
|
||
return (
|
||
<Suspense
|
||
fallback={
|
||
<div className="w-full bg-WHITE3 flex items-center justify-center p-4">
|
||
در حال بارگذاری فرم...
|
||
</div>
|
||
}
|
||
>
|
||
{/* Only load the form when it's ready */}
|
||
{mapReady && addressData && (
|
||
<InteractiveMap
|
||
key={`edit-form-${params.id}`}
|
||
initialAddress={addressData}
|
||
isEditing={true}
|
||
addressId={params.id}
|
||
formOnly={true}
|
||
/>
|
||
)}
|
||
</Suspense>
|
||
);
|
||
}}
|
||
</ClientOnly>
|
||
</UiProvider>
|
||
</div>
|
||
);
|
||
}
|