import React, { memo, useMemo, useEffect, useState } from "react";
import buyOutline from "app/assets/icons/navbar/buy-outline.svg";
import homeOutline from "app/assets/icons/navbar/home-outline.svg";
import profileOutline from "app/assets/icons/navbar/profile-outline.svg";
import searchOutline from "app/assets/icons/navbar/search-outline.svg";
import buyFilled from "app/assets/icons/navbar/buy-filled.svg";
import homeFilled from "app/assets/icons/navbar/home-filled.svg";
import profileFilled from "app/assets/icons/navbar/profile-filled.svg";
import searchFilled from "app/assets/icons/navbar/search-filled.svg";
import { Link, useLocation, useParams } from "@remix-run/react";
import { detectPage } from "~/utils/helpers";
import { useRootData } from "~/hooks/use-root-data";
import { useCartCount } from "~/requestHandler/use-cart-hooks";
import { useSellerOrderCount } from "~/requestHandler/use-order-hooks";
import settingIconFilled from "~/assets/icons/navbar/setting-filled.svg";
import settingIconOutline from "~/assets/icons/navbar/setting-outline.svg";
import documentFilled from "~/assets/icons/navbar/document-filled.svg";
import documentOutline from "~/assets/icons/navbar/document-outline.svg";
import productsFilled from "~/assets/icons/navbar/products-filled.svg";
import productsOutline from "~/assets/icons/navbar/products-outline.svg";
/**
* Primary application layout component
* Renders either mobile or desktop header based on screen size
*/
const MyLayout = React.memo(({ children }: { children: React.ReactNode }) => {
const location = useLocation();
return (
{children}
{location.pathname.split("threads")[1] ? (
<>>
) : (
)}
);
});
MyLayout.displayName = "Layout";
const MobileBottomNavigation = () => {
const { theme } = useRootData();
const location = useLocation();
const currentPage = useMemo(
() => detectPage(location?.pathname),
[location?.pathname]
);
const cartCount = useCartCount();
const { user } = useRootData();
const [isStoreMode, setIsStoreMode] = useState(false);
const sellerOrderCount = useSellerOrderCount(!!isStoreMode);
const [storeId, setStoreId] = useState(null);
// Initialize state from sessionStorage on mount - only once
useEffect(() => {
if (typeof window === "undefined") return;
const savedMode = sessionStorage.getItem("navigationMode");
const savedStoreId = sessionStorage.getItem("currentStoreId");
if (savedMode === "store" && savedStoreId) {
setIsStoreMode(true);
setStoreId(savedStoreId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const params = useParams();
// Function to determine page type
const getPageType = useMemo(() => {
const path = location.pathname;
const mode = params.mode;
// Store management pages
const isStoreManagementPage =
path.match(/^\/store\/[^/]+$/) || // Main store page: /store/{id}
path.match(/^\/store\/[^/]+\/setting$/) || // Store settings: /store/{id}/setting
path.match(/^\/store\/[^/]+\/orders/) || // Store orders: /store/{id}/orders
path.match(/^\/store\/[^/]+\/shipping-method$/) || // Shipping method: /store/{id}/shipping-method
path.match(/^\/store\/[^/]+\/financial-dashboard$/) || // Financial dashboard: /store/{id}/financial-dashboard
path.match(/^\/store\/[^/]+\/financial-dashboard\/cash-funds$/) || // Financial dashboard: /store/{id}/financial-dashboard
path.match(/^\/store\/[^/]+\/financial-dashboard\/transactions$/) || // Financial dashboard: /store/{id}/financial-dashboard
path.match(/^\/store\/[^/]+\/financial-dashboard\/reports$/) || // Financial dashboard: /store/{id}/financial-dashboard
path.match(/^\/store\/[^/]+\/products$/) || // Products list: /store/{id}/products
path.match(/^\/store\/[^/]+\/product\/[^/]+$/) || // Product detail: /store/{id}/products/{id}
path.match(/^\/store\/[^/]+\/edit$/) || // Edit store: /store/{id}/edit
path.match(/^\/store\/add\/manual\/[^/]+$/) || // Add product: /store/add/manual/{id}
path.match(/^\/store\/create$/) || // Create store: /store/create
path.match(/^\/store\/authenticate\/instagram\/[^/]+$/) || // Instagram auth: /store/authenticate/instagram/{id}
path.match(/^\/store\/[^/]+\/threads$/) || // Threads: /store/{id}/threads
path.match(/^\/store\/[^/]+\/threads\/[^/]+$/); // Threads: /store/{id}/threads/{threadId}
// Shared pages (should preserve current mode)
const isSharedPage =
path.match(/^\/explore$/) || // Explore page
path.match(/^\/search\//) || // Search pages
path.match(/^\/product\//) || // Product detail pages
path.match(/^\/seller\/[^/]+$/); // Seller view pages (not management)
// Regular user pages
const isRegularPage =
path.match(/^\/profile/) || // Profile pages
path.match(/^\/cart/) || // Cart pages
path.match(/^\/login$/) || // Login page
path.match(/^\/logout$/) || // Logout page
path === "/"; // Home page
if (isStoreManagementPage || mode === "store") return "store";
if (isSharedPage) return "shared";
if (isRegularPage) return "regular";
return "regular"; // Default
}, [location.pathname, params.mode]);
// Update store mode based on current page
useEffect(() => {
const pageType = getPageType;
const extractStoreId = (path: string): string | null => {
let match;
// Order matters here: more specific paths first.
// Case: /store/add/manual/{id}
match = path.match(/^\/store\/add\/manual\/([^/]+)/);
if (match) return match[1];
// Case: /store/authenticate/instagram/{id}
match = path.match(/^\/store\/authenticate\/instagram\/([^/]+)/);
if (match) return match[1];
// Case: /store/{id}/* (e.g., /store/my-store/settings)
match = path.match(/^\/store\/([^/]+)\//);
if (match) return match[1];
// Case: /store/{id} (e.g., /store/my-store)
match = path.match(/^\/store\/([^/]+)$/);
if (match && match[1] !== "create") {
return match[1];
}
return null;
};
if (pageType === "store") {
// We're in store management - set store mode
const currentStoreId = extractStoreId(location.pathname);
if (currentStoreId) {
setIsStoreMode((prev) => {
if (!prev && typeof window !== "undefined") {
sessionStorage.setItem("navigationMode", "store");
}
return true;
});
setStoreId((prev) => {
if (prev !== currentStoreId && typeof window !== "undefined") {
sessionStorage.setItem("currentStoreId", currentStoreId);
}
return currentStoreId;
});
} else {
// It's a store page without an ID, like /store/create.
setIsStoreMode((prev) => {
if (prev && typeof window !== "undefined") {
sessionStorage.setItem("navigationMode", "regular");
sessionStorage.removeItem("currentStoreId");
}
return false;
});
setStoreId(null);
}
} else if (pageType === "regular") {
// We're in regular user pages - set regular mode
setIsStoreMode((prev) => {
if (prev && typeof window !== "undefined") {
sessionStorage.setItem("navigationMode", "regular");
sessionStorage.removeItem("currentStoreId");
}
return false;
});
setStoreId(null);
// Clear store mode if user logs out
if (location.pathname === "/logout" && typeof window !== "undefined") {
sessionStorage.removeItem("navigationMode");
sessionStorage.removeItem("currentStoreId");
}
} else if (pageType === "shared") {
// We're in shared pages - preserve current mode (don't read from storage on every navigation)
// State is already set from initial mount
}
}, [location.pathname, getPageType]);
const navItems = useMemo(() => {
if (isStoreMode) {
// Store mode navigation
return [
{
link: `/store/${storeId}/setting`,
icon:
currentPage === "setting"
? theme === "dark"
? settingIconOutline
: settingIconFilled
: theme === "dark"
? settingIconFilled
: settingIconOutline,
},
{
link: `/store/${storeId}/orders`,
icon:
currentPage === "orders"
? theme === "dark"
? documentOutline
: documentFilled
: theme === "dark"
? documentFilled
: documentOutline,
badge:
sellerOrderCount > 0 && user?.access_token
? sellerOrderCount
: null,
},
{
link: `/store/${storeId}/products`,
icon:
currentPage === "products"
? theme === "dark"
? productsOutline
: productsFilled
: theme === "dark"
? productsFilled
: productsOutline,
},
{
link: `/store/${storeId}`,
icon:
currentPage === "store"
? theme === "dark"
? homeOutline
: homeFilled
: theme === "dark"
? homeFilled
: homeOutline,
},
];
} else {
// Normal mode navigation
return [
{
link: "/profile",
icon:
currentPage === "profile"
? theme === "dark"
? profileOutline
: profileFilled
: theme === "dark"
? profileFilled
: profileOutline,
},
{
link: "/cart",
icon:
currentPage === "cart"
? theme === "dark"
? buyOutline
: buyFilled
: theme === "dark"
? buyFilled
: buyOutline,
badge: cartCount > 0 && user?.access_token ? cartCount : null,
},
{
link: "/explore",
icon:
currentPage === "explore" || currentPage === "search"
? theme === "dark"
? searchOutline
: searchFilled
: theme === "dark"
? searchFilled
: searchOutline,
},
{
link: "/",
icon:
currentPage === "home"
? theme === "dark"
? homeOutline
: homeFilled
: theme === "dark"
? homeFilled
: homeOutline,
},
];
}
}, [
currentPage,
cartCount,
sellerOrderCount,
user?.access_token,
isStoreMode,
storeId,
theme,
]);
return (
<>
{navItems.map((item) => (
{typeof item.icon === "string" ? (

) : (
item.icon
)}
{item.badge && (
{item.badge}
)}
))}
>
);
};
const LanguageToggle = memo(
({
onToggle,
currentLanguage,
}: {
onToggle: () => Promise;
currentLanguage: string;
}) => (
)
);
LanguageToggle.displayName = "LanguageToggle";
export default MyLayout;