290 lines
8.6 KiB
TypeScript
290 lines
8.6 KiB
TypeScript
import { createRouter, createWebHistory } from "vue-router";
|
|
|
|
import { useSessionStore } from "@/stores/session";
|
|
import { isMobileHost, toMobilePath } from "./mobileHost";
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes: [
|
|
{ path: "/admin", redirect: "/admin/dashboard" },
|
|
{
|
|
path: "/m",
|
|
name: "mobile-home",
|
|
component: () => import("@/views/mobile/MobileHomeView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/m/listings",
|
|
name: "mobile-listings",
|
|
component: () => import("@/views/mobile/MobileHomeView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/m/listings/:id",
|
|
name: "mobile-listing-detail",
|
|
component: () => import("@/views/mobile/MobileListingDetailView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/m/login",
|
|
name: "mobile-login",
|
|
component: () => import("@/views/mobile/MobileLoginView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/m/register",
|
|
name: "mobile-register",
|
|
component: () => import("@/views/mobile/MobileRegisterView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/m/messages",
|
|
name: "mobile-messages",
|
|
component: () => import("@/views/mobile/MobileMessagesView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/m/realname",
|
|
name: "mobile-realname",
|
|
component: () => import("@/views/mobile/MobileRealnameView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/m/profile",
|
|
name: "mobile-profile",
|
|
component: () => import("@/views/mobile/MobileProfileView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/m/orders",
|
|
name: "mobile-orders",
|
|
component: () => import("@/views/mobile/MobileOrdersView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/m/orders/:id",
|
|
name: "mobile-order-detail",
|
|
component: () => import("@/views/account/OrderDetailView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/m/seller/listings/create",
|
|
name: "mobile-seller-listing-create",
|
|
component: () =>
|
|
import("@/views/mobile/MobileSellerListingCreateView.vue"),
|
|
meta: { layout: "blank", requiresAuth: true, requiresRealname: true },
|
|
},
|
|
{
|
|
path: "/",
|
|
name: "home",
|
|
component: () => import("@/views/public/HomeView.vue"),
|
|
},
|
|
{
|
|
path: "/login",
|
|
name: "login",
|
|
component: () => import("@/views/account/LoginView.vue"),
|
|
},
|
|
{
|
|
path: "/listings",
|
|
name: "listings",
|
|
component: () => import("@/views/public/ListingsView.vue"),
|
|
},
|
|
{
|
|
path: "/listings/:id",
|
|
name: "listing-detail",
|
|
component: () => import("@/views/public/ListingDetailView.vue"),
|
|
},
|
|
{
|
|
path: "/orders/create",
|
|
name: "order-create",
|
|
component: () => import("@/views/account/OrderCreateView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/orders",
|
|
name: "orders",
|
|
component: () => import("@/views/account/OrdersView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/orders/:id",
|
|
name: "order-detail",
|
|
component: () => import("@/views/account/OrderDetailView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/wallet",
|
|
name: "wallet",
|
|
component: () => import("@/views/account/WalletView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/notifications",
|
|
name: "notifications",
|
|
component: () => import("@/views/account/NotificationsView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/realname",
|
|
name: "realname",
|
|
component: () => import("@/views/account/RealnameView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/seller/listings",
|
|
name: "seller-listings",
|
|
component: () => import("@/views/seller/SellerListingsView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/seller/listings/create",
|
|
name: "seller-listing-create",
|
|
component: () => import("@/views/seller/SellerListingCreateView.vue"),
|
|
meta: { requiresAuth: true, requiresRealname: true },
|
|
},
|
|
{
|
|
path: "/seller/handoffs",
|
|
name: "seller-handoffs",
|
|
component: () => import("@/views/seller/SellerHandoffsView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/seller/earnings",
|
|
name: "seller-earnings",
|
|
component: () => import("@/views/seller/SellerEarningsView.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/admin/login",
|
|
name: "admin-login",
|
|
component: () => import("@/views/admin/AdminLoginView.vue"),
|
|
meta: { layout: "blank" },
|
|
},
|
|
{
|
|
path: "/admin/dashboard",
|
|
name: "admin-dashboard",
|
|
component: () => import("@/views/admin/AdminDashboardView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/users",
|
|
name: "admin-users",
|
|
component: () => import("@/views/admin/AdminUsersView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/orders",
|
|
name: "admin-orders",
|
|
component: () => import("@/views/admin/AdminOrdersView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/orders/:id",
|
|
name: "admin-order-detail",
|
|
component: () => import("@/views/admin/AdminOrderDetailView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/listings",
|
|
name: "admin-listings",
|
|
component: () => import("@/views/admin/AdminListingsView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/listings/:id",
|
|
name: "admin-listing-detail",
|
|
component: () => import("@/views/admin/AdminListingDetailView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/listings/review",
|
|
name: "admin-listing-review",
|
|
component: () => import("@/views/admin/AdminListingReviewView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/disputes",
|
|
name: "admin-disputes",
|
|
component: () => import("@/views/admin/AdminDisputesView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/wallet-ledger",
|
|
name: "admin-wallet-ledger",
|
|
component: () => import("@/views/admin/AdminWalletLedgerView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/system-configs",
|
|
name: "admin-system-configs",
|
|
component: () => import("@/views/admin/AdminSystemConfigsView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
{
|
|
path: "/admin/audit-logs",
|
|
name: "admin-audit-logs",
|
|
component: () => import("@/views/admin/AdminAuditLogsView.vue"),
|
|
meta: { layout: "admin", requiresAdmin: true },
|
|
},
|
|
],
|
|
});
|
|
|
|
router.beforeEach(async (to) => {
|
|
if (isMobileHost() && to.path !== toMobilePath(to.path)) {
|
|
return { path: toMobilePath(to.path), query: to.query, hash: to.hash };
|
|
}
|
|
|
|
if (to.meta.requiresAuth) {
|
|
const session = useSessionStore();
|
|
const hasToken = !!localStorage.getItem("access_token");
|
|
if (!hasToken) {
|
|
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
|
|
return { path: loginPath, query: { redirect: to.fullPath } };
|
|
}
|
|
if (!session.phone) {
|
|
try {
|
|
await session.loadMe();
|
|
} catch {
|
|
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
|
|
return { path: loginPath, query: { redirect: to.fullPath } };
|
|
}
|
|
}
|
|
}
|
|
|
|
if (to.meta.requiresRealname) {
|
|
const session = useSessionStore();
|
|
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
|
|
const realnamePath = to.path.startsWith("/m") ? "/m/realname" : "/realname";
|
|
|
|
if (session.realnameStatus !== "verified") {
|
|
try {
|
|
await session.loadMe();
|
|
} catch {
|
|
if (!localStorage.getItem("access_token")) {
|
|
return { path: loginPath, query: { redirect: to.fullPath } };
|
|
}
|
|
}
|
|
}
|
|
|
|
if (session.realnameStatus !== "verified") {
|
|
return { path: realnamePath, query: { redirect: to.fullPath } };
|
|
}
|
|
}
|
|
|
|
if (
|
|
to.path === "/admin/login" &&
|
|
localStorage.getItem("admin_access_token")
|
|
) {
|
|
return "/admin/dashboard";
|
|
}
|
|
if (to.meta.requiresAdmin) {
|
|
const token = localStorage.getItem("admin_access_token");
|
|
if (!token) {
|
|
return "/admin/login";
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
|
|
export default router;
|