259 lines
8.7 KiB
TypeScript
259 lines
8.7 KiB
TypeScript
import { MetaFunction, useNavigate, useParams } from "@remix-run/react";
|
||
import { useSellerData } from "../requestHandler/use-seller-hooks";
|
||
import {
|
||
ChevronLeft,
|
||
LogOut,
|
||
LayoutDashboard,
|
||
ShoppingCart,
|
||
Truck,
|
||
PackagePlus,
|
||
TableProperties,
|
||
PenLine,
|
||
Code,
|
||
Instagram,
|
||
MessageCircle,
|
||
} from "lucide-react";
|
||
import HeaderWithSupport from "../components/HeaderWithSupport";
|
||
import { useStoreOwnership } from "../hooks/useStoreOwnership";
|
||
import { useState } from "react";
|
||
import { SunMoonToggle } from "~/components/SunMoonToggle";
|
||
import { useRootData } from "~/hooks/use-root-data";
|
||
|
||
// Import the InstagramSyncDrawer component
|
||
import { InstagramSyncDrawer } from "./store.$storeId._index";
|
||
import CallDialog from "~/components/CallDialog";
|
||
|
||
interface MenuItemType {
|
||
title: string;
|
||
link?: string;
|
||
pageName: string;
|
||
hasBorder?: boolean;
|
||
image: React.ReactNode;
|
||
}
|
||
|
||
export default function StoreSetting() {
|
||
const { storeId } = useParams();
|
||
const navigate = useNavigate();
|
||
const { data } = useSellerData(storeId);
|
||
const { theme: initialTheme } = useRootData();
|
||
|
||
// Check store ownership - this will redirect if user doesn't own the store
|
||
const { isLoading: isOwnershipLoading } = useStoreOwnership(storeId);
|
||
|
||
// State for Instagram sync drawer
|
||
const [instagramSyncDrawerOpen, setInstagramSyncDrawerOpen] = useState(false);
|
||
const [isCallModalOpen, setIsCallModalOpen] = useState(false);
|
||
|
||
// Show loading while checking ownership
|
||
if (isOwnershipLoading) {
|
||
return (
|
||
<div className="flex items-center justify-center min-h-[500px]">
|
||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// Menu items for store management
|
||
const storeMenuItems: MenuItemType[] = [
|
||
{
|
||
title: "وارد کردن پست های اینستاگرام",
|
||
pageName: "instagram-sync",
|
||
hasBorder: true,
|
||
image: <Instagram size={20} />,
|
||
},
|
||
{
|
||
title: "سفارشهای دریافتی",
|
||
pageName: "seller-orders",
|
||
link: `/store/${storeId}/orders`,
|
||
image: <ShoppingCart size={20} />,
|
||
},
|
||
{
|
||
title: "پیام های دریافتی",
|
||
pageName: "seller-messages",
|
||
link: `/store/${storeId}/threads`,
|
||
image: <MessageCircle size={20} />,
|
||
},
|
||
{
|
||
title: "داشبورد مالی",
|
||
pageName: "financial-dashboard",
|
||
link: `/store/${storeId}/financial-dashboard`,
|
||
image: <LayoutDashboard size={20} />,
|
||
},
|
||
{
|
||
title: "تعیین نحوه ارسال",
|
||
pageName: "shipping-method",
|
||
link: `/store/${storeId}/shipping-method`,
|
||
image: <Truck size={20} />,
|
||
},
|
||
{
|
||
title: "افزودن محصول جدید",
|
||
pageName: "add-product",
|
||
link: `/store/add/manual/${storeId}`,
|
||
image: <PackagePlus size={20} />,
|
||
},
|
||
{
|
||
title: "لیست محصولات",
|
||
pageName: "products-list",
|
||
link: `/store/${storeId}/products`,
|
||
image: <TableProperties size={20} />,
|
||
},
|
||
{
|
||
title: "ویرایش اطلاعات فروشگاه",
|
||
pageName: "edit-store",
|
||
link: `/store/${storeId}/edit`,
|
||
image: <PenLine size={20} />,
|
||
},
|
||
{
|
||
title: "خروج",
|
||
pageName: "logout",
|
||
link: `/store/${storeId}/logout`,
|
||
hasBorder: true,
|
||
image: <LogOut size={20} />,
|
||
},
|
||
];
|
||
|
||
const handleBack = () => {
|
||
navigate(`/store/${storeId}`);
|
||
};
|
||
|
||
const handleItemClick = (item: MenuItemType) => {
|
||
// Special handling for "instagram-sync" item
|
||
if (item.pageName === "instagram-sync") {
|
||
// Open Instagram sync drawer instead of navigating
|
||
setInstagramSyncDrawerOpen(true);
|
||
return;
|
||
}
|
||
|
||
// Special handling for "logout" item
|
||
if (item.pageName === "logout") {
|
||
// Handle logout logic
|
||
navigate("/");
|
||
return;
|
||
}
|
||
|
||
// Default rendering for other items with Link if they have a link
|
||
if (item.link) {
|
||
navigate(item.link);
|
||
return;
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="flex flex-col bg-WHITE">
|
||
{/* Header */}
|
||
<HeaderWithSupport title="تنظیمات فروشگاه" onBack={handleBack} />
|
||
|
||
{/* Store Status */}
|
||
<div className="p-4 bg-WHITE border-b border-inner-border">
|
||
<div className="flex w-full items-center justify-between">
|
||
<div className="flex flex-col gap-1 w-full">
|
||
<div className="flex w-full gap-1 items-center">
|
||
<Code size={20} />
|
||
<p className="text-R12">وضعیت فروشگاه (فعال)</p>
|
||
</div>
|
||
<p className="text-R10 text-GRAY">
|
||
در حالت فعال، فروشگاه برای مخاطبان نمایش داده میشود.
|
||
</p>
|
||
</div>
|
||
<label className="relative inline-flex items-center cursor-pointer">
|
||
<input
|
||
type="checkbox"
|
||
checked={data?.isVerified || false}
|
||
className="sr-only peer"
|
||
aria-label="وضعیت فروشگاه"
|
||
/>
|
||
<div className="w-11 h-6 bg-WHITE2 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-WHITE after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-WHITE after:border-GRAY3 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-VITROWN_BLUE border"></div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Theme Toggle */}
|
||
<div className="p-4 bg-WHITE border-b border-inner-border">
|
||
<div className="flex w-full items-center justify-between">
|
||
<div className="flex flex-col gap-1">
|
||
<p className="text-R12">
|
||
{initialTheme === "dark" ? "حالت تاریک" : "حالت روشن"}
|
||
</p>
|
||
<p className="text-R10 text-GRAY">
|
||
تغییر حالت نمایش به تاریک یا روشن
|
||
</p>
|
||
</div>
|
||
<SunMoonToggle theme={initialTheme} />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Menu Items */}
|
||
<div className="flex flex-col gap-0 w-full bg-WHITE">
|
||
{storeMenuItems.map((item, index) => (
|
||
<div
|
||
key={index}
|
||
className={`flex flex-row gap-2 items-center justify-between px-[16px] active:bg-hover transition cursor-pointer ${
|
||
item.hasBorder && "border-t-[2px]"
|
||
} h-[55px] w-full`}
|
||
onClick={() => handleItemClick(item)}
|
||
role="button"
|
||
tabIndex={0}
|
||
onKeyDown={(e) => {
|
||
if (e.key === "Enter" || e.key === " ") {
|
||
handleItemClick(item);
|
||
}
|
||
}}
|
||
>
|
||
<div className="flex flex-row gap-2 items-center">
|
||
{item.image}
|
||
<p className={"text-R12"}>{item.title}</p>
|
||
</div>
|
||
<ChevronLeft className="size-4" />
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Instagram Sync Drawer */}
|
||
<InstagramSyncDrawer
|
||
setIsCallModalOpen={setIsCallModalOpen}
|
||
isOpen={instagramSyncDrawerOpen}
|
||
onOpenChange={setInstagramSyncDrawerOpen}
|
||
storeId={storeId || ""}
|
||
/>
|
||
<CallDialog
|
||
isCallModalOpen={isCallModalOpen}
|
||
setIsCallModalOpen={setIsCallModalOpen}
|
||
handleCallConfirm={() => {
|
||
window.location.href = `tel:${import.meta.env.VITE_SUPPORT_PHONE}`;
|
||
}}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export const meta: MetaFunction = () => {
|
||
return [
|
||
{ title: "تنظیمات فروشگاه - ویترون" },
|
||
{
|
||
name: "description",
|
||
content:
|
||
"مدیریت و مشاهده تمام تنظیمات فروشگاه در فروشگاه شما. فیلتر بر اساس وضعیت و جستجو در تنظیمات فروشگاه.",
|
||
},
|
||
{
|
||
name: "keywords",
|
||
content:
|
||
"تنظیمات فروشگاه، مدیریت تنظیمات فروشگاه، فروشگاه، مشتری، ویترون",
|
||
},
|
||
{ name: "robots", content: "noindex, follow" },
|
||
{ property: "og:title", content: "تنظیمات فروشگاه - ویترون" },
|
||
{
|
||
property: "og:description",
|
||
content:
|
||
"مدیریت و مشاهده تمام تنظیمات فروشگاه در فروشگاه شما. فیلتر بر اساس وضعیت و جستجو در تنظیمات فروشگاه.",
|
||
},
|
||
{ property: "og:type", content: "website" },
|
||
{ name: "twitter:card", content: "summary" },
|
||
{ name: "twitter:title", content: "تنظیمات فروشگاه - ویترون" },
|
||
{
|
||
name: "twitter:description",
|
||
content:
|
||
"مدیریت و مشاهده تمام تنظیمات فروشگاه در فروشگاه شما. فیلتر بر اساس وضعیت و جستجو در تنظیمات فروشگاه.",
|
||
},
|
||
];
|
||
};
|