index.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { createRouter, createWebHistory, RouterView } from "vue-router";
  2. import { h } from "vue";
  3. import i18n, { setLanguage } from "@/i18n";
  4. const supportedLangs = ['en', 'ru', 'me', 'ua'];
  5. const routes = [
  6. {
  7. path: "/:lang(en|ru|me|ua)?",
  8. component: { render: () => h(RouterView) },
  9. children: [
  10. { path: "", name: "home", component: () => import("@/pages/Index.vue"), meta: { title: "Home" } },
  11. { path: "auth", name: "auth", component: () => import("@/pages/Auth.vue"), meta: { title: "Authentication" } },
  12. { path: "orders", name: "orders", component: () => import("@/pages/Orders.vue"), meta: { title: "My Orders" } },
  13. { path: "portfolio", name: "portfolio", component: () => import("@/pages/Portfolio.vue"), meta: { title: "Portfolio" } },
  14. { path: "admin", name: "admin", component: () => import("@/pages/Admin.vue"), meta: { title: "Admin Panel" } },
  15. { path: "privacy", name: "privacy", component: () => import("@/pages/Privacy.vue"), meta: { title: "Privacy Policy" } },
  16. { path: "about", name: "about", component: () => import("@/pages/About.vue"), meta: { title: "About Us" } },
  17. { path: "careers", name: "careers", component: () => import("@/pages/Careers.vue"), meta: { title: "Careers" } },
  18. { path: "blog", name: "blog", component: () => import("@/pages/Blog.vue"), meta: { title: "Blog" } },
  19. { path: "blog/:id", name: "blog-post", component: () => import("@/pages/BlogPost.vue"), meta: { title: "Blog Post" } },
  20. { path: "contact", name: "contact", component: () => import("@/pages/Contact.vue"), meta: { title: "Contact" } },
  21. { path: "help", name: "help", component: () => import("@/pages/HelpCenter.vue"), meta: { title: "Help Center" } },
  22. { path: "guidelines", name: "guidelines", component: () => import("@/pages/Guidelines.vue"), meta: { title: "Guidelines" } },
  23. { path: "terms", name: "terms", component: () => import("@/pages/Terms.vue"), meta: { title: "Terms of Service" } },
  24. ]
  25. },
  26. { path: "/:pathMatch(.*)*", component: () => import("@/pages/NotFound.vue"), meta: { title: "Not Found" } },
  27. ];
  28. const router = createRouter({
  29. history: createWebHistory(),
  30. routes,
  31. scrollBehavior(to) {
  32. if (to.hash) return { el: to.hash, behavior: "smooth" };
  33. return { top: 0 };
  34. },
  35. });
  36. router.beforeEach(async (to) => {
  37. const { useAuthStore } = await import("@/stores/auth");
  38. const authStore = useAuthStore();
  39. // 1. Handle Language Prefix
  40. let lang = to.params.lang as string;
  41. const savedLang = localStorage.getItem('locale') || 'en';
  42. if (!lang) {
  43. const segments = to.path.split('/').filter(Boolean);
  44. const firstSegment = segments[0];
  45. // Check if first segment looks like a language code but isn't supported
  46. if (firstSegment && firstSegment.length === 2 && !supportedLangs.includes(firstSegment)) {
  47. // It's a fake lang like /fr/auth -> redirect to /ru/auth
  48. const remainingPath = segments.slice(1).join('/');
  49. return { path: `/${savedLang}/${remainingPath}`, query: to.query, hash: to.hash };
  50. }
  51. // Skip redirect during prerendering to allow capturing the root page or specific routes
  52. if ((window as any).__PRERENDER_INJECTED) {
  53. return;
  54. }
  55. // Simple path like /auth -> /ru/auth
  56. return { path: `/${savedLang}${to.fullPath}` };
  57. }
  58. // 2. Sync i18n
  59. if (supportedLangs.includes(lang)) {
  60. if (i18n.global.locale.value !== lang) {
  61. await setLanguage(lang);
  62. }
  63. } else {
  64. // This part should technically not be reached with the current regex
  65. // but as a safety measure:
  66. return { path: `/${savedLang}/`, query: to.query };
  67. }
  68. // 3. Auth Guards
  69. if (!authStore.user && localStorage.getItem("token")) {
  70. await authStore.init();
  71. }
  72. const pathWithoutLang = to.path.replace(`/${lang}`, '') || '/';
  73. if (pathWithoutLang === "/admin" && authStore.user?.role !== "admin") {
  74. return { name: "auth", params: { lang } };
  75. }
  76. if (pathWithoutLang === "/orders" && !authStore.user) {
  77. return { name: "auth", params: { lang } };
  78. }
  79. });
  80. router.afterEach((to) => {
  81. const baseTitle = "Radionica 3D";
  82. const pageTitle = to.meta.title ? `${to.meta.title} | ${baseTitle}` : baseTitle;
  83. document.title = pageTitle;
  84. });
  85. export default router;