import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { MetaFunction } from "@remix-run/node";
import { safeGoBack } from "~/utils/helpers";
import {
useSellerData,
useGetSellerProducts,
} from "../requestHandler/use-seller-hooks";
import {
useGetInstagramPosts,
useInstagramSync,
} from "../requestHandler/use-instagram-hooks";
import {
ArrowRight,
Star,
ChevronDown,
X,
Menu,
GalleryThumbnailsIcon,
Plus,
Images,
Instagram,
Headset,
} from "lucide-react";
import { useMemo, useState } from "react";
import {
DrawerContent,
Drawer,
DrawerHeader,
DrawerTitle,
} from "../components/ui/drawer";
import { Button } from "../components/ui/button";
import { Seller as SellerType } from "../../src/api/types";
import UiProvider from "../components/UiProvider";
import MondrianProductList from "../components/MondrianProductList";
import { useStoreOwnership } from "../hooks/useStoreOwnership";
import { LoadingModal } from "./store.add.manual.$storeId";
import SellerLogo from "../components/SellerLogo";
import CallDialog from "../components/CallDialog";
export default function Store() {
const { storeId } = useParams();
const [searchParams, setSearchParams] = useSearchParams();
const { data } = useSellerData(storeId);
// Check store ownership - this will redirect if user doesn't own the store
const { isLoading: isOwnershipLoading } = useStoreOwnership(storeId);
// Get active tab from URL parameters, default to "products"
const activeTab =
(searchParams.get("tab") as "products" | "instagram") || "products";
// Function to update tab and URL
const setActiveTab = (tab: "products" | "instagram") => {
const newSearchParams = new URLSearchParams(searchParams);
newSearchParams.set("tab", tab);
setSearchParams(newSearchParams, { replace: true });
};
// Fetch Store products with infinite scroll
const {
data: productsData,
isLoading: isProductsLoading,
fetchNextPage: fetchNextProductsPage,
hasNextPage: hasNextProductsPage,
isFetchingNextPage: isFetchingNextProductsPage,
isError: isProductsError,
refetch: refetchProducts,
} = useGetSellerProducts(storeId || "");
// Fetch Instagram posts with infinite scroll
const {
data: instagramData,
isLoading: isInstagramLoading,
fetchNextPage: fetchNextInstagramPage,
hasNextPage: hasNextInstagramPage,
isFetchingNextPage: isFetchingNextInstagramPage,
isError: isInstagramError,
refetch: refetchInstagram,
} = useGetInstagramPosts();
const products = productsData?.pages.flatMap((page) => page.results) || [];
const instagramPosts =
instagramData?.pages.flatMap((page) => page.results) || [];
const [addProductDrawerOpen, setAddProductDrawerOpen] = useState(false);
const [instagramSyncDrawerOpen, setInstagramSyncDrawerOpen] = useState(false);
const [isCallModalOpen, setIsCallModalOpen] = useState(false);
const supportPhone = useMemo(
() => import.meta.env.VITE_SUPPORT_PHONE || "",
[]
);
const handleCallConfirm = () => {
window.location.href = `tel:${supportPhone}`;
setIsCallModalOpen(false);
};
// Show loading while checking ownership
if (isOwnershipLoading) {
return (
);
}
return (
{data?.followerCount}
دنبال کننده
{data?.reviewAverage}
{Array.from({ length: 5 }).map((_, index) => (
))}
{data?.productCount}
تعداد محصولات
{/* Tab Navigation */}
setActiveTab("products")}
className={`p-2 text-center transition-colors border-b-2 ${
activeTab === "products"
? "bg-WHITE text-BLACK shadow-sm"
: "text-BLACK2 border-WHITE"
}`}
role="button"
tabIndex={0}
aria-label="Products"
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setActiveTab("products");
}
}}
>
محصولات
setActiveTab("instagram")}
className={`p-2 text-center transition-colors border-b-2 ${
activeTab === "instagram"
? "bg-WHITE text-BLACK shadow-sm"
: "text-BLACK2 border-WHITE"
}`}
role="button"
tabIndex={0}
aria-label="Instagram"
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setActiveTab("instagram");
}
}}
>
همه پستها
{/* Tab Content */}
{activeTab === "products" ? (
{/* seller products */}
({
id: product?.id || "",
title: product?.title || "",
images: product?.imageUrls || [],
isActive: product?.isActive,
}))}
storePage={true}
fetchNextPage={fetchNextProductsPage}
hasNextPage={!!hasNextProductsPage}
isFetchingNextPage={isFetchingNextProductsPage}
isLoading={isProductsLoading}
isError={isProductsError}
refetch={refetchProducts}
emptyState={{
image: ,
title: "فروشگاه شما محصولی ندارد!",
description:
"پست جدید بسازید یا پستهای اینستاگرام خود را وارد فروشگاه کنید.",
}}
/>
) : (
{/* Instagram posts */}
({
id: post?.id?.toString() || "",
title: post?.caption || "",
images: post?.localMedia || [],
isDraft: !post?.convertedToProduct,
}))}
fetchNextPage={fetchNextInstagramPage}
hasNextPage={!!hasNextInstagramPage}
isFetchingNextPage={isFetchingNextInstagramPage}
isLoading={isInstagramLoading}
isError={isInstagramError}
refetch={refetchInstagram}
emptyState={{
image: ,
title: "هیچ پست اینستاگرامی یافت نشد!",
description: "ابتدا پستهای اینستاگرام خود را همگامسازی کنید.",
}}
/>
)}
{
setAddProductDrawerOpen(false);
setInstagramSyncDrawerOpen(true);
}}
/>
);
}
const AddProductDrawer = ({
isOpen,
instaIsAuthenticated,
onOpenChange,
sellerUsername,
onOpenInstagramSync,
}: {
isOpen: boolean;
instaIsAuthenticated: boolean;
onOpenChange: (open: boolean) => void;
sellerUsername: string;
onOpenInstagramSync: () => void;
}) => {
const navigate = useNavigate();
return (
onOpenChange(false)}
/>
افزودن محصول جدید
{
if (instaIsAuthenticated) onOpenInstagramSync();
else navigate(`/store/authenticate/instagram/${sellerUsername}`);
}}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
if (instaIsAuthenticated) onOpenInstagramSync();
else
navigate(`/store/authenticate/instagram/${sellerUsername}`);
}
}}
role="button"
tabIndex={0}
aria-label="Instagram sync"
>
پستهای اینستاگرام
navigate(`/store/add/manual/${sellerUsername}`)}
onKeyDown={(e) =>
(e.key === "Enter" || e.key === " ") &&
navigate(`/store/add/manual/${sellerUsername}`)
}
role="button"
tabIndex={0}
aria-label="Camera"
>
ایجاد محصول
);
};
export const InstagramSyncDrawer = ({
isOpen,
onOpenChange,
storeId,
setIsCallModalOpen,
}: {
isOpen: boolean;
onOpenChange: (open: boolean) => void;
storeId: string;
setIsCallModalOpen: (open: boolean) => void;
}) => {
const [count, setCount] = useState(1);
const instagramSync = useInstagramSync();
const navigate = useNavigate();
const handleSync = async () => {
try {
const result = await instagramSync.mutateAsync({ count });
console.log("Instagram sync result:", result);
onOpenChange(false);
navigate(`/store/${storeId}?tab=instagram`);
} catch (error) {
console.error("Instagram sync error:", error);
}
};
return (
<>
onOpenChange(false)}
/>
همگامسازی اینستاگرام
{
setIsCallModalOpen(true);
}}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setIsCallModalOpen(true);
}
}}
role="button"
tabIndex={0}
>
{/* main content */}
{/* Count Input Section */}
تعداد پستهایی که میخواهید همگامسازی کنید:
برای مثال اگر عدد 3 را وارد کنید، 3 پست آخر پیج اینستاگرام شما
دریافت و به فروشگاه اضافه خواهند شد.
{/* Number Selection Squares */}
{Array.from({ length: 10 }, (_, index) => {
const number = index + 1;
const isSelected = number <= count;
return (
);
})}
تعداد انتخاب شده: {count}
{/* Info Section */}
پیج اینستاگرام شما باید public باشد تا crawler بتواند به آن
دسترسی داشته باشد.
با انتخاب تعداد پستها، آخرین پستهای اینستاگرام شما که تابحال
همگام سازی نشده اند، دریافت و به فروشگاه اضافه خواهند شد.
شما میتوانید روزانه حداکثر 10 پست از اینستاگرام خود را همگام
سازی کنید.
{}}
title="در حال دریافت پست ها..."
description="حداکثر یک دقیقه طول میکشد."
/>
>
);
};
function ReadMoreText({
text,
maxLength,
sellerData,
}: {
text: string;
maxLength: number;
sellerData: SellerType | undefined;
}) {
const [aboutDrawerOpen, setAboutDrawerOpen] = useState(false);
if (text.length <= maxLength) {
return {text}
;
}
return (
<>
{text.substring(0, maxLength)}
...
setAboutDrawerOpen(false)}
/>
{text}
>
);
}
function SellerDetailHeader({
sellerData,
storeId,
}: {
sellerData: SellerType | undefined;
storeId: string | undefined;
}) {
const navigate = useNavigate();
const handleSettingClick = () => {
navigate(`/store/${storeId}/setting`);
};
return (
);
}
export const meta: MetaFunction = ({ params }) => {
const storeId = params.storeId;
const title = `مدیریت فروشگاه ${storeId} | ویترون`;
const description = `مدیریت محصولات و تنظیمات فروشگاه ${storeId} در ویترون`;
const imageUrl =
"https://vitrownstatics.s3.ir-thr-at1.arvanstorage.ir/SVG-06.svg?versionId=";
return [
{ title },
{ name: "description", content: description },
{
name: "keywords",
content: `مدیریت فروشگاه، ${storeId}، محصولات، اینستاگرام، ویترون`,
},
{ name: "robots", content: "noindex, follow" },
// Open Graph
{ property: "og:type", content: "website" },
{ property: "og:title", content: title },
{ property: "og:description", content: description },
{ property: "og:image", content: imageUrl },
{ property: "og:site_name", content: "ویترون" },
{ property: "og:locale", content: "fa_IR" },
// Twitter Card
{ name: "twitter:card", content: "summary" },
{ name: "twitter:title", content: title },
{ name: "twitter:description", content: description },
];
};