Files
WooNooW/admin-spa/src/components/layout/AppRoutes.tsx

280 lines
14 KiB
TypeScript

import React from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { Loader2 } from 'lucide-react';
import { __ } from '@/lib/i18n';
// Import all routes
import ResetPassword from '@/routes/ResetPassword';
import Dashboard from '@/routes/Dashboard';
import DashboardRevenue from '@/routes/Dashboard/Revenue';
import DashboardOrders from '@/routes/Dashboard/Orders';
import DashboardProducts from '@/routes/Dashboard/Products';
import DashboardCustomers from '@/routes/Dashboard/Customers';
import DashboardCoupons from '@/routes/Dashboard/Coupons';
import DashboardTaxes from '@/routes/Dashboard/Taxes';
import OrdersIndex from '@/routes/Orders';
import OrderNew from '@/routes/Orders/New';
import OrderEdit from '@/routes/Orders/Edit';
import OrderDetail from '@/routes/Orders/Detail';
import OrderInvoice from '@/routes/Orders/Invoice';
import OrderLabel from '@/routes/Orders/Label';
import ProductsIndex from '@/routes/Products';
import ProductNew from '@/routes/Products/New';
import ProductEdit from '@/routes/Products/Edit';
import ProductCategories from '@/routes/Products/Categories';
import ProductTags from '@/routes/Products/Tags';
import ProductAttributes from '@/routes/Products/Attributes';
import Licenses from '@/routes/Products/Licenses';
import LicenseDetail from '@/routes/Products/Licenses/Detail';
import SoftwareVersions from '@/routes/Products/SoftwareVersions';
import SubscriptionsIndex from '@/routes/Subscriptions';
import SubscriptionDetail from '@/routes/Subscriptions/Detail';
import CouponsIndex from '@/routes/Marketing/Coupons';
import CouponNew from '@/routes/Marketing/Coupons/New';
import CouponEdit from '@/routes/Marketing/Coupons/Edit';
import CustomersIndex from '@/routes/Customers';
import CustomerNew from '@/routes/Customers/New';
import CustomerEdit from '@/routes/Customers/Edit';
import CustomerDetail from '@/routes/Customers/Detail';
import SettingsIndex from '@/routes/Settings';
import SettingsStore from '@/routes/Settings/Store';
import SettingsPayments from '@/routes/Settings/Payments';
import SettingsShipping from '@/routes/Settings/Shipping';
import SettingsTax from '@/routes/Settings/Tax';
import SettingsCustomers from '@/routes/Settings/Customers';
import SettingsSecurity from '@/routes/Settings/Security';
import SettingsLocalPickup from '@/routes/Settings/LocalPickup';
import SettingsNotifications from '@/routes/Settings/Notifications';
import StaffNotifications from '@/routes/Settings/Notifications/Staff';
import CustomerNotifications from '@/routes/Settings/Notifications/Customer';
import ChannelConfiguration from '@/routes/Settings/Notifications/ChannelConfiguration';
import EmailConfiguration from '@/routes/Settings/Notifications/EmailConfiguration';
import PushConfiguration from '@/routes/Settings/Notifications/PushConfiguration';
import EmailCustomization from '@/routes/Settings/Notifications/EmailCustomization';
import EditTemplate from '@/routes/Settings/Notifications/EditTemplate';
import ActivityLog from '@/routes/Settings/Notifications/ActivityLog';
import SettingsDeveloper from '@/routes/Settings/Developer';
import SettingsModules from '@/routes/Settings/Modules';
import ModuleSettings from '@/routes/Settings/ModuleSettings';
import AppearanceIndex from '@/routes/Appearance';
import AppearanceGeneral from '@/routes/Appearance/General';
import AppearanceHeader from '@/routes/Appearance/Header';
import AppearanceFooter from '@/routes/Appearance/Footer';
import AppearanceShop from '@/routes/Appearance/Shop';
import AppearanceProduct from '@/routes/Appearance/Product';
import AppearanceCart from '@/routes/Appearance/Cart';
import AppearanceCheckout from '@/routes/Appearance/Checkout';
import AppearanceThankYou from '@/routes/Appearance/ThankYou';
import AppearanceAccount from '@/routes/Appearance/Account';
import AppearanceMenus from '@/routes/Appearance/Menus/MenuEditor';
import AppearancePages from '@/routes/Appearance/Pages';
import MarketingIndex from '@/routes/Marketing';
import NewsletterLayout from '@/routes/Marketing/Newsletter';
import NewsletterSubscribers from '@/routes/Marketing/Newsletter/Subscribers';
import NewsletterCampaignsList from '@/routes/Marketing/Campaigns';
import CampaignEdit from '@/routes/Marketing/Campaigns/Edit';
import AffiliatesLayout from '@/routes/Marketing/Affiliates';
import AffiliatesList from '@/routes/Marketing/Affiliates/List';
import AffiliatesReferrals from '@/routes/Marketing/Affiliates/Referrals';
import AffiliatesPayouts from '@/routes/Marketing/Affiliates/Payouts';
import MorePage from '@/routes/More';
import Help from '@/routes/Help';
import Onboarding from '@/routes/Onboarding';
import { LegacyCampaignRedirect } from '@/components/LegacyCampaignRedirect';
// Addon Route Component - Dynamically loads addon components
function AddonRoute({ config }: { config: any }) {
const [Component, setComponent] = React.useState<any>(null);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState<string | null>(null);
React.useEffect(() => {
if (!config.component_url) {
setError('No component URL provided');
setLoading(false);
return;
}
setLoading(true);
setError(null);
// Dynamically import the addon component
import(/* @vite-ignore */ config.component_url)
.then((mod) => {
setComponent(() => mod.default || mod);
setLoading(false);
})
.catch((err) => {
console.error('[AddonRoute] Failed to load component:', err);
setError(err.message || 'Failed to load addon component');
setLoading(false);
});
}, [config.component_url]);
if (loading) {
return (
<div className="flex items-center justify-center p-8">
<div className="text-center">
<Loader2 className="w-8 h-8 animate-spin mx-auto mb-2 opacity-50" />
<p className="text-sm opacity-70">{__('Loading addon...')}</p>
</div>
</div>
);
}
if (error) {
return (
<div className="p-6">
<div className="rounded-lg border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-950/50 p-4">
<h3 className="font-semibold text-red-900 dark:text-red-200 mb-2">{__('Failed to Load Addon')}</h3>
<p className="text-sm text-red-700 dark:text-red-300">{error}</p>
</div>
</div>
);
}
if (!Component) {
return (
<div className="p-6">
<div className="rounded-lg border border-yellow-200 dark:border-yellow-800 bg-yellow-50 dark:bg-yellow-950/50 p-4">
<p className="text-sm text-yellow-700 dark:text-yellow-300">{__('Addon component not found')}</p>
</div>
</div>
);
}
// Render the addon component with props
return <Component {...(config.props || {})} />;
}
export function AppRoutes() {
const addonRoutes = window.WNW_ADDON_ROUTES || [];
return (
<Routes>
{/* Dashboard */}
<Route path="/" element={<Navigate to={window.WNW_CONFIG?.onboardingCompleted ? "/dashboard" : "/setup"} replace />} />
<Route path="/setup" element={<Onboarding />} />
<Route path="/reset-password" element={<ResetPassword />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/dashboard/revenue" element={<DashboardRevenue />} />
<Route path="/dashboard/orders" element={<DashboardOrders />} />
<Route path="/dashboard/products" element={<DashboardProducts />} />
<Route path="/dashboard/customers" element={<DashboardCustomers />} />
<Route path="/dashboard/coupons" element={<DashboardCoupons />} />
<Route path="/dashboard/taxes" element={<DashboardTaxes />} />
{/* Products */}
<Route path="/products" element={<ProductsIndex />} />
<Route path="/products/new" element={<ProductNew />} />
<Route path="/products/:id/edit" element={<ProductEdit />} />
<Route path="/products/categories" element={<ProductCategories />} />
<Route path="/products/tags" element={<ProductTags />} />
<Route path="/products/attributes" element={<ProductAttributes />} />
<Route path="/products/licenses" element={<Licenses />} />
<Route path="/products/licenses/:id" element={<LicenseDetail />} />
<Route path="/products/software" element={<SoftwareVersions />} />
{/* Orders */}
<Route path="/orders" element={<OrdersIndex />} />
<Route path="/orders/new" element={<OrderNew />} />
<Route path="/orders/:id" element={<OrderDetail />} />
<Route path="/orders/:id/edit" element={<OrderEdit />} />
<Route path="/orders/:id/invoice" element={<OrderInvoice />} />
<Route path="/orders/:id/label" element={<OrderLabel />} />
{/* Subscriptions */}
<Route path="/subscriptions" element={<SubscriptionsIndex />} />
<Route path="/subscriptions/:id" element={<SubscriptionDetail />} />
{/* Coupons (under Marketing) */}
<Route path="/coupons" element={<Navigate to="/marketing/coupons" replace />} />
<Route path="/coupons/new" element={<Navigate to="/marketing/coupons/new" replace />} />
<Route path="/coupons/:id/edit" element={<CouponEdit />} />
<Route path="/marketing/coupons" element={<CouponsIndex />} />
<Route path="/marketing/coupons/new" element={<CouponNew />} />
<Route path="/marketing/coupons/:id/edit" element={<CouponEdit />} />
{/* Customers */}
<Route path="/customers" element={<CustomersIndex />} />
<Route path="/customers/new" element={<CustomerNew />} />
<Route path="/customers/:id/edit" element={<CustomerEdit />} />
<Route path="/customers/:id" element={<CustomerDetail />} />
{/* More */}
<Route path="/more" element={<MorePage />} />
{/* Settings */}
<Route path="/settings" element={<SettingsIndex />} />
<Route path="/settings/store" element={<SettingsStore />} />
<Route path="/settings/payments" element={<SettingsPayments />} />
<Route path="/settings/shipping" element={<SettingsShipping />} />
<Route path="/settings/tax" element={<SettingsTax />} />
<Route path="/settings/customers" element={<SettingsCustomers />} />
<Route path="/settings/security" element={<SettingsSecurity />} />
<Route path="/settings/taxes" element={<Navigate to="/settings/tax" replace />} />
<Route path="/settings/local-pickup" element={<SettingsLocalPickup />} />
<Route path="/settings/checkout" element={<SettingsIndex />} />
<Route path="/settings/notifications" element={<SettingsNotifications />} />
<Route path="/settings/notifications/staff" element={<StaffNotifications />} />
<Route path="/settings/notifications/customer" element={<CustomerNotifications />} />
<Route path="/settings/notifications/channels" element={<ChannelConfiguration />} />
<Route path="/settings/notifications/channels/email" element={<EmailConfiguration />} />
<Route path="/settings/notifications/channels/push" element={<PushConfiguration />} />
<Route path="/settings/notifications/email-customization" element={<EmailCustomization />} />
<Route path="/settings/notifications/edit-template" element={<EditTemplate />} />
<Route path="/settings/notifications/activity-log" element={<ActivityLog />} />
<Route path="/settings/brand" element={<SettingsIndex />} />
<Route path="/settings/developer" element={<SettingsDeveloper />} />
<Route path="/settings/modules" element={<SettingsModules />} />
<Route path="/settings/modules/:moduleId" element={<ModuleSettings />} />
{/* Appearance */}
<Route path="/appearance" element={<AppearanceIndex />} />
<Route path="/appearance/general" element={<AppearanceGeneral />} />
<Route path="/appearance/header" element={<AppearanceHeader />} />
<Route path="/appearance/footer" element={<AppearanceFooter />} />
<Route path="/appearance/shop" element={<AppearanceShop />} />
<Route path="/appearance/product" element={<AppearanceProduct />} />
<Route path="/appearance/cart" element={<AppearanceCart />} />
<Route path="/appearance/checkout" element={<AppearanceCheckout />} />
<Route path="/appearance/thankyou" element={<AppearanceThankYou />} />
<Route path="/appearance/account" element={<AppearanceAccount />} />
<Route path="/appearance/menus" element={<AppearanceMenus />} />
<Route path="/appearance/pages" element={<AppearancePages />} />
{/* Marketing */}
<Route path="/marketing" element={<MarketingIndex />} />
<Route path="/marketing/newsletter" element={<NewsletterLayout />}>
<Route index element={<Navigate to="subscribers" replace />} />
<Route path="subscribers" element={<NewsletterSubscribers />} />
<Route path="campaigns" element={<NewsletterCampaignsList />} />
<Route path="campaigns/:id" element={<CampaignEdit />} />
</Route>
<Route path="/marketing/affiliates" element={<AffiliatesLayout />}>
<Route index element={<Navigate to="list" replace />} />
<Route path="list" element={<AffiliatesList />} />
<Route path="referrals" element={<AffiliatesReferrals />} />
<Route path="payouts" element={<AffiliatesPayouts />} />
</Route>
{/* Legacy Redirects for Newsletter (using component to preserve params) */}
<Route path="/marketing/campaigns" element={<Navigate to="/marketing/newsletter/campaigns" replace />} />
<Route path="/marketing/campaigns/new" element={<Navigate to="/marketing/newsletter/campaigns/new" replace />} />
<Route path="/marketing/campaigns/:id" element={<LegacyCampaignRedirect />} />
{/* Help - Main menu route with no submenu */}
<Route path="/help" element={<Help />} />
{/* Dynamic Addon Routes */}
{addonRoutes.map((route: any) => (
<Route
key={route.path}
path={route.path}
element={<AddonRoute config={route} />}
/>
))}
</Routes>
);
}