From 078076b61919c9d26ba3e947785dba5cadbcc10a Mon Sep 17 00:00:00 2001 From: Semih Yesilyurt Date: Tue, 2 Jun 2026 00:07:29 +0300 Subject: [PATCH] feat(demo): public /demo namespace serving pre-warmed VW Golf 2003 catalog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the old marketing "guided tour" /demo with a real, fully-functional catalog browsing experience for the pre-warmed example vehicle. No auth required, no upstream calls — entirely served from prod DB. Backend (apps/api/src/demo): * New @Public() controller exposing five endpoints under /api/demo: - GET /vehicle → demo vehicle metadata - GET /categories/tree → top-level category tree - GET /categories/search?q= → cross-tree search - GET /categories/:id → getCategoryWithParts (parts+schema+hotspots) - GET /categories/:id/children → drill children * DemoService validates every category id against DEMO_VEHICLE_ID before any downstream service call — the public surface can't be used to read an arbitrary vehicle's catalog (1-row SELECT, NotFound on miss or wrong owner). * Vehicle id is env-driven (DEMO_VEHICLE_ID, defaults to the pre-warmed WVWZZZ1JZ3W597935 — VW Golf 2003 with 277 cats / 9841 parts / 178 schemas fully drilled in prod). * Wires CategoriesModule (already exports CategoriesService) — zero new business logic, just a thin public façade. Frontend (apps/web): * /demo (replaces old marketing page): vehicle header + top categories grid reading /api/demo/* + sticky DemoBanner with sign-up CTA. * /demo/categories/$categoryId: drill page rendering either a children grid (parent) or the existing SchemaViewer + parts panel (leaf) — same shape the dashboard uses, so hotspot overlay, breadcrumb trail, retry on upstream loadError all just work. * DemoBanner: sticky top, "Örnek araç: {label} — Kayıt Ol" CTA. The "Yeni VIN sorgula" explicit paywall trigger lands in a follow-up task. * PostHog events: demo_loaded (source query-param-aware), demo_category_clicked, demo_category_detail_viewed, demo_to_register_click (banner / footer / category_footer placements). * usePageMeta gains an opt-in `noindex` flag — demo sets it to noindex,follow for the first 4-6 weeks per spec; cleaned up on unmount so SPA navigation doesn't carry it to the next route. --- apps/api/src/app.module.ts | 2 + apps/api/src/demo/demo.controller.ts | 45 + apps/api/src/demo/demo.module.ts | 11 + apps/api/src/demo/demo.service.ts | 71 ++ apps/web/src/components/demo/demo-banner.tsx | 49 + apps/web/src/hooks/use-page-meta.ts | 24 +- apps/web/src/routeTree.gen.ts | 1132 +++++++++-------- apps/web/src/routes/demo.tsx | 562 +++----- .../routes/demo_/categories_/$categoryId.tsx | 307 +++++ 9 files changed, 1251 insertions(+), 952 deletions(-) create mode 100644 apps/api/src/demo/demo.controller.ts create mode 100644 apps/api/src/demo/demo.module.ts create mode 100644 apps/api/src/demo/demo.service.ts create mode 100644 apps/web/src/components/demo/demo-banner.tsx create mode 100644 apps/web/src/routes/demo_/categories_/$categoryId.tsx diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 58b5b21..ced2bf5 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -25,6 +25,7 @@ import configuration from "./config/configuration"; import { validate } from "./config/env.validation"; import { ContactModule } from "./contact/contact.module"; import { DatabaseModule } from "./database/database.module"; +import { DemoModule } from "./demo/demo.module"; import { EmailModule } from "./email/email.module"; import { HealthController } from "./health.controller"; import { EmexModule } from "./integrations/emex/emex.module"; @@ -82,6 +83,7 @@ import { VehiclesModule } from "./vehicles/vehicles.module"; ReferralsModule, VehiclesModule, CategoriesModule, + DemoModule, PartsModule, JobsModule, EmexModule, diff --git a/apps/api/src/demo/demo.controller.ts b/apps/api/src/demo/demo.controller.ts new file mode 100644 index 0000000..c938e5b --- /dev/null +++ b/apps/api/src/demo/demo.controller.ts @@ -0,0 +1,45 @@ +import { Controller, Get, Param, Query } from "@nestjs/common"; +import { CategoriesService } from "../categories/categories.service"; +import { Public } from "../common/decorators/public.decorator"; +import { DemoService } from "./demo.service"; + +/** + * Public /api/demo namespace — single pre-warmed vehicle, no auth. + * Every category id is validated to belong to the demo vehicle before any + * downstream service call (see DemoService.assertBelongsToDemo). + */ +@Controller("demo") +@Public() +export class DemoController { + constructor( + private demo: DemoService, + private categories: CategoriesService, + ) {} + + @Get("vehicle") + async getVehicle() { + return this.demo.getVehicle(); + } + + @Get("categories/tree") + async getCategoryTree() { + return this.categories.getCategoryTree(this.demo.demoVehicleId); + } + + @Get("categories/search") + async searchCatalog(@Query("q") q: string) { + return this.categories.searchCatalog(this.demo.demoVehicleId, q ?? ""); + } + + @Get("categories/:id") + async getCategoryWithParts(@Param("id") id: string) { + await this.demo.assertBelongsToDemo(id); + return this.categories.getCategoryWithParts(id); + } + + @Get("categories/:id/children") + async getChildren(@Param("id") id: string) { + await this.demo.assertBelongsToDemo(id); + return this.categories.getChildren(id); + } +} diff --git a/apps/api/src/demo/demo.module.ts b/apps/api/src/demo/demo.module.ts new file mode 100644 index 0000000..f40c90c --- /dev/null +++ b/apps/api/src/demo/demo.module.ts @@ -0,0 +1,11 @@ +import { Module } from "@nestjs/common"; +import { CategoriesModule } from "../categories/categories.module"; +import { DemoController } from "./demo.controller"; +import { DemoService } from "./demo.service"; + +@Module({ + imports: [CategoriesModule], + controllers: [DemoController], + providers: [DemoService], +}) +export class DemoModule {} diff --git a/apps/api/src/demo/demo.service.ts b/apps/api/src/demo/demo.service.ts new file mode 100644 index 0000000..b1564fd --- /dev/null +++ b/apps/api/src/demo/demo.service.ts @@ -0,0 +1,71 @@ +import { Inject, Injectable, Logger, NotFoundException } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { eq } from "drizzle-orm"; +import { DATABASE, type Database } from "../database/database.provider"; +import { categories, vehicles } from "../database/schema/core"; + +/** + * Demo namespace owns a single pre-warmed VIN whose catalog is fully drilled + * in prod (categories + parts + schema_pics + hotspots). The controller + * exposes the same shape as the auth-gated dashboard endpoints, but only for + * this one vehicle — every category id is validated against the demo vehicle + * before any downstream service call so the public surface cannot be used to + * read an arbitrary vehicle's catalog. + * + * Vehicle id is env-driven (DEMO_VEHICLE_ID) so it can be swapped without a + * code change. + */ +@Injectable() +export class DemoService { + private readonly logger = new Logger(DemoService.name); + private static readonly FALLBACK_VEHICLE_ID = "a81eef92-7c0a-4e41-ab0e-7714be406c38"; + + constructor( + @Inject(DATABASE) private db: Database, + private config: ConfigService, + ) {} + + get demoVehicleId(): string { + return this.config.get("DEMO_VEHICLE_ID", DemoService.FALLBACK_VEHICLE_ID); + } + + async getVehicle() { + const rows = await this.db + .select({ + id: vehicles.id, + vin: vehicles.vin, + brandName: vehicles.brandName, + model: vehicles.model, + year: vehicles.year, + engine: vehicles.engine, + bodyType: vehicles.bodyType, + source: vehicles.source, + }) + .from(vehicles) + .where(eq(vehicles.id, this.demoVehicleId)) + .limit(1); + + if (rows.length === 0) { + this.logger.error(`Demo vehicle ${this.demoVehicleId} not found in DB`); + throw new NotFoundException("Demo vehicle not configured"); + } + return rows[0]; + } + + /** + * Throws NotFoundException if the category id does not belong to the demo + * vehicle. Single 1-row lookup, cheap. Same NotFound code on miss vs + * wrong-owner so the public endpoint doesn't leak existence. + */ + async assertBelongsToDemo(categoryId: string): Promise { + const rows = await this.db + .select({ vehicleId: categories.vehicleId }) + .from(categories) + .where(eq(categories.id, categoryId)) + .limit(1); + + if (rows.length === 0 || rows[0].vehicleId !== this.demoVehicleId) { + throw new NotFoundException("Category not found"); + } + } +} diff --git a/apps/web/src/components/demo/demo-banner.tsx b/apps/web/src/components/demo/demo-banner.tsx new file mode 100644 index 0000000..a21c2b1 --- /dev/null +++ b/apps/web/src/components/demo/demo-banner.tsx @@ -0,0 +1,49 @@ +import { capture } from "@/lib/posthog"; +import { Button } from "@sase/ui"; +import { Link } from "@tanstack/react-router"; +import { Eye } from "lucide-react"; + +interface DemoBannerProps { + vehicleLabel: string; +} + +/** + * Sticky top banner shown on every /demo page. Communicates that the current + * vehicle is an example (not the visitor's own) and offers a single CTA to + * convert: a sign-up link. We deliberately avoid the "Demo modu" wording in + * favour of "Örnek araç" so the B2B audience doesn't dismiss it as a toy. + * The "Yeni VIN sorgula" gate (the explicit paywall trigger from the spec) + * is added in a follow-up task. + */ +export function DemoBanner({ vehicleLabel }: DemoBannerProps) { + return ( +
+
+
+ +

+ Örnek araç:{" "} + {vehicleLabel} + + {" "} + — Kendi aracınız için ücretsiz hesap aç + +

+
+ +
+
+ ); +} diff --git a/apps/web/src/hooks/use-page-meta.ts b/apps/web/src/hooks/use-page-meta.ts index 8138c41..6ad1dcd 100644 --- a/apps/web/src/hooks/use-page-meta.ts +++ b/apps/web/src/hooks/use-page-meta.ts @@ -10,6 +10,12 @@ interface PageMetaOptions { description: string; canonical: string; ogImage?: string; + /** + * When true, sets for the + * page lifetime. Used by /demo while we measure LP-funnel impact before + * exposing the public sandbox to search. + */ + noindex?: boolean; } function setMeta(name: string, content: string, attr: "name" | "property" = "name") { @@ -32,7 +38,13 @@ function setCanonical(href: string) { el.setAttribute("href", href); } -export function usePageMeta({ title, description, canonical, ogImage }: PageMetaOptions) { +export function usePageMeta({ + title, + description, + canonical, + ogImage, + noindex, +}: PageMetaOptions) { useEffect(() => { document.title = title; setMeta("description", description); @@ -48,6 +60,8 @@ export function usePageMeta({ title, description, canonical, ogImage }: PageMeta setMeta("twitter:description", description, "name"); setMeta("twitter:image", image, "name"); + if (noindex) setMeta("robots", "noindex,follow"); + return () => { document.title = DEFAULT_TITLE; setMeta("description", DEFAULT_DESCRIPTION); @@ -59,6 +73,12 @@ export function usePageMeta({ title, description, canonical, ogImage }: PageMeta setMeta("twitter:title", DEFAULT_TITLE, "name"); setMeta("twitter:description", DEFAULT_DESCRIPTION, "name"); setMeta("twitter:image", "https://sase.tr/og-image.png", "name"); + // Restore index-by-default when leaving a noindex page so SPA navigation + // doesn't inadvertently de-index the next route. + if (noindex) { + const el = document.querySelector('meta[name="robots"]'); + el?.remove(); + } }; - }, [title, description, canonical, ogImage]); + }, [title, description, canonical, ogImage, noindex]); } diff --git a/apps/web/src/routeTree.gen.ts b/apps/web/src/routeTree.gen.ts index 3bfb8da..f60aea4 100644 --- a/apps/web/src/routeTree.gen.ts +++ b/apps/web/src/routeTree.gen.ts @@ -8,545 +8,558 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { Route as rootRouteImport } from './routes/__root' -import { Route as TermsRouteImport } from './routes/terms' -import { Route as PrivacyRouteImport } from './routes/privacy' -import { Route as PricingRouteImport } from './routes/pricing' -import { Route as KvkkRouteImport } from './routes/kvkk' -import { Route as DemoRouteImport } from './routes/demo' -import { Route as DashboardRouteImport } from './routes/dashboard' -import { Route as ContactRouteImport } from './routes/contact' -import { Route as BlogRouteImport } from './routes/blog' -import { Route as AboutRouteImport } from './routes/about' -import { Route as AuthRouteImport } from './routes/_auth' -import { Route as IndexRouteImport } from './routes/index' -import { Route as DashboardIndexRouteImport } from './routes/dashboard/index' -import { Route as DashboardSettingsRouteImport } from './routes/dashboard/settings' -import { Route as DashboardServiceTestRouteImport } from './routes/dashboard/service-test' -import { Route as DashboardSearchRouteImport } from './routes/dashboard/search' -import { Route as DashboardHistoryRouteImport } from './routes/dashboard/history' -import { Route as DashboardChangelogRouteImport } from './routes/dashboard/changelog' -import { Route as DashboardBillingRouteImport } from './routes/dashboard/billing' -import { Route as BlogSlugRouteImport } from './routes/blog_/$slug' -import { Route as AuthResetPasswordRouteImport } from './routes/_auth/reset-password' -import { Route as AuthRegisterRouteImport } from './routes/_auth/register' -import { Route as AuthLoginRouteImport } from './routes/_auth/login' -import { Route as AuthForgotPasswordRouteImport } from './routes/_auth/forgot-password' -import { Route as AuthEmailVerifiedRouteImport } from './routes/_auth/email-verified' -import { Route as DashboardSubscriptionIndexRouteImport } from './routes/dashboard/subscription/index' -import { Route as DashboardCatalogIndexRouteImport } from './routes/dashboard/catalog/index' -import { Route as DashboardAdminIndexRouteImport } from './routes/dashboard/admin/index' -import { Route as DashboardAdminUsersRouteImport } from './routes/dashboard/admin/users' -import { Route as DashboardAdminReferralsRouteImport } from './routes/dashboard/admin/referrals' -import { Route as DashboardAdminCopyLogsRouteImport } from './routes/dashboard/admin/copy-logs' -import { Route as DashboardAdminAnalyticsRouteImport } from './routes/dashboard/admin/analytics' -import { Route as DashboardVehiclesIdIndexRouteImport } from './routes/dashboard/vehicles_/$id/index' -import { Route as DashboardCatalogBrandNameIndexRouteImport } from './routes/dashboard/catalog_/$brandName/index' -import { Route as DashboardCatalogPcatCatalogIdIndexRouteImport } from './routes/dashboard/catalog_/pcat/$catalogId/index' -import { Route as DashboardCatalogEmexCatalogCodeIndexRouteImport } from './routes/dashboard/catalog_/emex/$catalogCode/index' -import { Route as DashboardCatalogBrandNameModelIdIndexRouteImport } from './routes/dashboard/catalog_/$brandName_/$modelId/index' -import { Route as DashboardVehiclesIdCategoriesCategoryIdRouteImport } from './routes/dashboard/vehicles_/$id/categories_/$categoryId' -import { Route as DashboardCatalogPcatCatalogIdModelIdIndexRouteImport } from './routes/dashboard/catalog_/pcat/$catalogId_/$modelId/index' -import { Route as DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport } from './routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId/index' -import { Route as DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport } from './routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId' -import { Route as DashboardCatalogPcatCatalogIdModelIdCarIdIndexRouteImport } from './routes/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/index' -import { Route as DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport } from './routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId' -import { Route as DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRouteImport } from './routes/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId' +import { Route as rootRouteImport } from "./routes/__root" +import { Route as TermsRouteImport } from "./routes/terms" +import { Route as PrivacyRouteImport } from "./routes/privacy" +import { Route as PricingRouteImport } from "./routes/pricing" +import { Route as KvkkRouteImport } from "./routes/kvkk" +import { Route as DemoRouteImport } from "./routes/demo" +import { Route as DashboardRouteImport } from "./routes/dashboard" +import { Route as ContactRouteImport } from "./routes/contact" +import { Route as BlogRouteImport } from "./routes/blog" +import { Route as AboutRouteImport } from "./routes/about" +import { Route as AuthRouteImport } from "./routes/_auth" +import { Route as IndexRouteImport } from "./routes/index" +import { Route as DashboardIndexRouteImport } from "./routes/dashboard/index" +import { Route as DashboardSettingsRouteImport } from "./routes/dashboard/settings" +import { Route as DashboardServiceTestRouteImport } from "./routes/dashboard/service-test" +import { Route as DashboardSearchRouteImport } from "./routes/dashboard/search" +import { Route as DashboardHistoryRouteImport } from "./routes/dashboard/history" +import { Route as DashboardChangelogRouteImport } from "./routes/dashboard/changelog" +import { Route as DashboardBillingRouteImport } from "./routes/dashboard/billing" +import { Route as BlogSlugRouteImport } from "./routes/blog_/$slug" +import { Route as AuthResetPasswordRouteImport } from "./routes/_auth/reset-password" +import { Route as AuthRegisterRouteImport } from "./routes/_auth/register" +import { Route as AuthLoginRouteImport } from "./routes/_auth/login" +import { Route as AuthForgotPasswordRouteImport } from "./routes/_auth/forgot-password" +import { Route as AuthEmailVerifiedRouteImport } from "./routes/_auth/email-verified" +import { Route as DashboardSubscriptionIndexRouteImport } from "./routes/dashboard/subscription/index" +import { Route as DashboardCatalogIndexRouteImport } from "./routes/dashboard/catalog/index" +import { Route as DashboardAdminIndexRouteImport } from "./routes/dashboard/admin/index" +import { Route as DemoCategoriesCategoryIdRouteImport } from "./routes/demo_/categories_/$categoryId" +import { Route as DashboardAdminUsersRouteImport } from "./routes/dashboard/admin/users" +import { Route as DashboardAdminReferralsRouteImport } from "./routes/dashboard/admin/referrals" +import { Route as DashboardAdminCopyLogsRouteImport } from "./routes/dashboard/admin/copy-logs" +import { Route as DashboardAdminAnalyticsRouteImport } from "./routes/dashboard/admin/analytics" +import { Route as DashboardVehiclesIdIndexRouteImport } from "./routes/dashboard/vehicles_/$id/index" +import { Route as DashboardCatalogBrandNameIndexRouteImport } from "./routes/dashboard/catalog_/$brandName/index" +import { Route as DashboardCatalogPcatCatalogIdIndexRouteImport } from "./routes/dashboard/catalog_/pcat/$catalogId/index" +import { Route as DashboardCatalogEmexCatalogCodeIndexRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode/index" +import { Route as DashboardCatalogBrandNameModelIdIndexRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/index" +import { Route as DashboardVehiclesIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/vehicles_/$id/categories_/$categoryId" +import { Route as DashboardCatalogPcatCatalogIdModelIdIndexRouteImport } from "./routes/dashboard/catalog_/pcat/$catalogId_/$modelId/index" +import { Route as DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId/index" +import { Route as DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId" +import { Route as DashboardCatalogPcatCatalogIdModelIdCarIdIndexRouteImport } from "./routes/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/index" +import { Route as DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId" +import { Route as DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRouteImport } from "./routes/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId" const TermsRoute = TermsRouteImport.update({ - id: '/terms', - path: '/terms', + id: "/terms", + path: "/terms", getParentRoute: () => rootRouteImport, } as any) const PrivacyRoute = PrivacyRouteImport.update({ - id: '/privacy', - path: '/privacy', + id: "/privacy", + path: "/privacy", getParentRoute: () => rootRouteImport, } as any) const PricingRoute = PricingRouteImport.update({ - id: '/pricing', - path: '/pricing', + id: "/pricing", + path: "/pricing", getParentRoute: () => rootRouteImport, } as any) const KvkkRoute = KvkkRouteImport.update({ - id: '/kvkk', - path: '/kvkk', + id: "/kvkk", + path: "/kvkk", getParentRoute: () => rootRouteImport, } as any) const DemoRoute = DemoRouteImport.update({ - id: '/demo', - path: '/demo', + id: "/demo", + path: "/demo", getParentRoute: () => rootRouteImport, } as any) const DashboardRoute = DashboardRouteImport.update({ - id: '/dashboard', - path: '/dashboard', + id: "/dashboard", + path: "/dashboard", getParentRoute: () => rootRouteImport, } as any) const ContactRoute = ContactRouteImport.update({ - id: '/contact', - path: '/contact', + id: "/contact", + path: "/contact", getParentRoute: () => rootRouteImport, } as any) const BlogRoute = BlogRouteImport.update({ - id: '/blog', - path: '/blog', + id: "/blog", + path: "/blog", getParentRoute: () => rootRouteImport, } as any) const AboutRoute = AboutRouteImport.update({ - id: '/about', - path: '/about', + id: "/about", + path: "/about", getParentRoute: () => rootRouteImport, } as any) const AuthRoute = AuthRouteImport.update({ - id: '/_auth', + id: "/_auth", getParentRoute: () => rootRouteImport, } as any) const IndexRoute = IndexRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => rootRouteImport, } as any) const DashboardIndexRoute = DashboardIndexRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => DashboardRoute, } as any) const DashboardSettingsRoute = DashboardSettingsRouteImport.update({ - id: '/settings', - path: '/settings', + id: "/settings", + path: "/settings", getParentRoute: () => DashboardRoute, } as any) const DashboardServiceTestRoute = DashboardServiceTestRouteImport.update({ - id: '/service-test', - path: '/service-test', + id: "/service-test", + path: "/service-test", getParentRoute: () => DashboardRoute, } as any) const DashboardSearchRoute = DashboardSearchRouteImport.update({ - id: '/search', - path: '/search', + id: "/search", + path: "/search", getParentRoute: () => DashboardRoute, } as any) const DashboardHistoryRoute = DashboardHistoryRouteImport.update({ - id: '/history', - path: '/history', + id: "/history", + path: "/history", getParentRoute: () => DashboardRoute, } as any) const DashboardChangelogRoute = DashboardChangelogRouteImport.update({ - id: '/changelog', - path: '/changelog', + id: "/changelog", + path: "/changelog", getParentRoute: () => DashboardRoute, } as any) const DashboardBillingRoute = DashboardBillingRouteImport.update({ - id: '/billing', - path: '/billing', + id: "/billing", + path: "/billing", getParentRoute: () => DashboardRoute, } as any) const BlogSlugRoute = BlogSlugRouteImport.update({ - id: '/blog_/$slug', - path: '/blog/$slug', + id: "/blog_/$slug", + path: "/blog/$slug", getParentRoute: () => rootRouteImport, } as any) const AuthResetPasswordRoute = AuthResetPasswordRouteImport.update({ - id: '/reset-password', - path: '/reset-password', + id: "/reset-password", + path: "/reset-password", getParentRoute: () => AuthRoute, } as any) const AuthRegisterRoute = AuthRegisterRouteImport.update({ - id: '/register', - path: '/register', + id: "/register", + path: "/register", getParentRoute: () => AuthRoute, } as any) const AuthLoginRoute = AuthLoginRouteImport.update({ - id: '/login', - path: '/login', + id: "/login", + path: "/login", getParentRoute: () => AuthRoute, } as any) const AuthForgotPasswordRoute = AuthForgotPasswordRouteImport.update({ - id: '/forgot-password', - path: '/forgot-password', + id: "/forgot-password", + path: "/forgot-password", getParentRoute: () => AuthRoute, } as any) const AuthEmailVerifiedRoute = AuthEmailVerifiedRouteImport.update({ - id: '/email-verified', - path: '/email-verified', + id: "/email-verified", + path: "/email-verified", getParentRoute: () => AuthRoute, } as any) const DashboardSubscriptionIndexRoute = DashboardSubscriptionIndexRouteImport.update({ - id: '/subscription/', - path: '/subscription/', + id: "/subscription/", + path: "/subscription/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogIndexRoute = DashboardCatalogIndexRouteImport.update({ - id: '/catalog/', - path: '/catalog/', + id: "/catalog/", + path: "/catalog/", getParentRoute: () => DashboardRoute, } as any) const DashboardAdminIndexRoute = DashboardAdminIndexRouteImport.update({ - id: '/admin/', - path: '/admin/', + id: "/admin/", + path: "/admin/", getParentRoute: () => DashboardRoute, } as any) +const DemoCategoriesCategoryIdRoute = + DemoCategoriesCategoryIdRouteImport.update({ + id: "/demo_/categories_/$categoryId", + path: "/demo/categories/$categoryId", + getParentRoute: () => rootRouteImport, + } as any) const DashboardAdminUsersRoute = DashboardAdminUsersRouteImport.update({ - id: '/admin/users', - path: '/admin/users', + id: "/admin/users", + path: "/admin/users", getParentRoute: () => DashboardRoute, } as any) const DashboardAdminReferralsRoute = DashboardAdminReferralsRouteImport.update({ - id: '/admin/referrals', - path: '/admin/referrals', + id: "/admin/referrals", + path: "/admin/referrals", getParentRoute: () => DashboardRoute, } as any) const DashboardAdminCopyLogsRoute = DashboardAdminCopyLogsRouteImport.update({ - id: '/admin/copy-logs', - path: '/admin/copy-logs', + id: "/admin/copy-logs", + path: "/admin/copy-logs", getParentRoute: () => DashboardRoute, } as any) const DashboardAdminAnalyticsRoute = DashboardAdminAnalyticsRouteImport.update({ - id: '/admin/analytics', - path: '/admin/analytics', + id: "/admin/analytics", + path: "/admin/analytics", getParentRoute: () => DashboardRoute, } as any) const DashboardVehiclesIdIndexRoute = DashboardVehiclesIdIndexRouteImport.update({ - id: '/vehicles_/$id/', - path: '/vehicles/$id/', + id: "/vehicles_/$id/", + path: "/vehicles/$id/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogBrandNameIndexRoute = DashboardCatalogBrandNameIndexRouteImport.update({ - id: '/catalog_/$brandName/', - path: '/catalog/$brandName/', + id: "/catalog_/$brandName/", + path: "/catalog/$brandName/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogPcatCatalogIdIndexRoute = DashboardCatalogPcatCatalogIdIndexRouteImport.update({ - id: '/catalog_/pcat/$catalogId/', - path: '/catalog/pcat/$catalogId/', + id: "/catalog_/pcat/$catalogId/", + path: "/catalog/pcat/$catalogId/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogEmexCatalogCodeIndexRoute = DashboardCatalogEmexCatalogCodeIndexRouteImport.update({ - id: '/catalog_/emex/$catalogCode/', - path: '/catalog/emex/$catalogCode/', + id: "/catalog_/emex/$catalogCode/", + path: "/catalog/emex/$catalogCode/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogBrandNameModelIdIndexRoute = DashboardCatalogBrandNameModelIdIndexRouteImport.update({ - id: '/catalog_/$brandName_/$modelId/', - path: '/catalog/$brandName/$modelId/', + id: "/catalog_/$brandName_/$modelId/", + path: "/catalog/$brandName/$modelId/", getParentRoute: () => DashboardRoute, } as any) const DashboardVehiclesIdCategoriesCategoryIdRoute = DashboardVehiclesIdCategoriesCategoryIdRouteImport.update({ - id: '/vehicles_/$id/categories_/$categoryId', - path: '/vehicles/$id/categories/$categoryId', + id: "/vehicles_/$id/categories_/$categoryId", + path: "/vehicles/$id/categories/$categoryId", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogPcatCatalogIdModelIdIndexRoute = DashboardCatalogPcatCatalogIdModelIdIndexRouteImport.update({ - id: '/catalog_/pcat/$catalogId_/$modelId/', - path: '/catalog/pcat/$catalogId/$modelId/', + id: "/catalog_/pcat/$catalogId_/$modelId/", + path: "/catalog/pcat/$catalogId/$modelId/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute = DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport.update({ - id: '/catalog_/emex/$catalogCode_/$vehicleId/', - path: '/catalog/emex/$catalogCode/$vehicleId/', + id: "/catalog_/emex/$catalogCode_/$vehicleId/", + path: "/catalog/emex/$catalogCode/$vehicleId/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute = DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport.update({ - id: '/catalog_/$brandName_/$modelId/categories_/$categoryId', - path: '/catalog/$brandName/$modelId/categories/$categoryId', + id: "/catalog_/$brandName_/$modelId/categories_/$categoryId", + path: "/catalog/$brandName/$modelId/categories/$categoryId", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute = DashboardCatalogPcatCatalogIdModelIdCarIdIndexRouteImport.update({ - id: '/catalog_/pcat/$catalogId_/$modelId_/$carId/', - path: '/catalog/pcat/$catalogId/$modelId/$carId/', + id: "/catalog_/pcat/$catalogId_/$modelId_/$carId/", + path: "/catalog/pcat/$catalogId/$modelId/$carId/", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute = DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport.update({ - id: '/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId', - path: '/catalog/emex/$catalogCode/$vehicleId/groups/$groupId', + id: "/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId", + path: "/catalog/emex/$catalogCode/$vehicleId/groups/$groupId", getParentRoute: () => DashboardRoute, } as any) const DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute = DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRouteImport.update({ - id: '/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId', - path: '/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId', + id: "/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId", + path: "/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId", getParentRoute: () => DashboardRoute, } as any) export interface FileRoutesByFullPath { - '/': typeof IndexRoute - '/about': typeof AboutRoute - '/blog': typeof BlogRoute - '/contact': typeof ContactRoute - '/dashboard': typeof DashboardRouteWithChildren - '/demo': typeof DemoRoute - '/kvkk': typeof KvkkRoute - '/pricing': typeof PricingRoute - '/privacy': typeof PrivacyRoute - '/terms': typeof TermsRoute - '/email-verified': typeof AuthEmailVerifiedRoute - '/forgot-password': typeof AuthForgotPasswordRoute - '/login': typeof AuthLoginRoute - '/register': typeof AuthRegisterRoute - '/reset-password': typeof AuthResetPasswordRoute - '/blog/$slug': typeof BlogSlugRoute - '/dashboard/billing': typeof DashboardBillingRoute - '/dashboard/changelog': typeof DashboardChangelogRoute - '/dashboard/history': typeof DashboardHistoryRoute - '/dashboard/search': typeof DashboardSearchRoute - '/dashboard/service-test': typeof DashboardServiceTestRoute - '/dashboard/settings': typeof DashboardSettingsRoute - '/dashboard/': typeof DashboardIndexRoute - '/dashboard/admin/analytics': typeof DashboardAdminAnalyticsRoute - '/dashboard/admin/copy-logs': typeof DashboardAdminCopyLogsRoute - '/dashboard/admin/referrals': typeof DashboardAdminReferralsRoute - '/dashboard/admin/users': typeof DashboardAdminUsersRoute - '/dashboard/admin/': typeof DashboardAdminIndexRoute - '/dashboard/catalog/': typeof DashboardCatalogIndexRoute - '/dashboard/subscription/': typeof DashboardSubscriptionIndexRoute - '/dashboard/catalog/$brandName/': typeof DashboardCatalogBrandNameIndexRoute - '/dashboard/vehicles/$id/': typeof DashboardVehiclesIdIndexRoute - '/dashboard/vehicles/$id/categories/$categoryId': typeof DashboardVehiclesIdCategoriesCategoryIdRoute - '/dashboard/catalog/$brandName/$modelId/': typeof DashboardCatalogBrandNameModelIdIndexRoute - '/dashboard/catalog/emex/$catalogCode/': typeof DashboardCatalogEmexCatalogCodeIndexRoute - '/dashboard/catalog/pcat/$catalogId/': typeof DashboardCatalogPcatCatalogIdIndexRoute - '/dashboard/catalog/$brandName/$modelId/categories/$categoryId': typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute - '/dashboard/catalog/emex/$catalogCode/$vehicleId/': typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute - '/dashboard/catalog/pcat/$catalogId/$modelId/': typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute - '/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId': typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute - '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/': typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute - '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId': typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute + "/": typeof IndexRoute + "/about": typeof AboutRoute + "/blog": typeof BlogRoute + "/contact": typeof ContactRoute + "/dashboard": typeof DashboardRouteWithChildren + "/demo": typeof DemoRoute + "/kvkk": typeof KvkkRoute + "/pricing": typeof PricingRoute + "/privacy": typeof PrivacyRoute + "/terms": typeof TermsRoute + "/email-verified": typeof AuthEmailVerifiedRoute + "/forgot-password": typeof AuthForgotPasswordRoute + "/login": typeof AuthLoginRoute + "/register": typeof AuthRegisterRoute + "/reset-password": typeof AuthResetPasswordRoute + "/blog/$slug": typeof BlogSlugRoute + "/dashboard/billing": typeof DashboardBillingRoute + "/dashboard/changelog": typeof DashboardChangelogRoute + "/dashboard/history": typeof DashboardHistoryRoute + "/dashboard/search": typeof DashboardSearchRoute + "/dashboard/service-test": typeof DashboardServiceTestRoute + "/dashboard/settings": typeof DashboardSettingsRoute + "/dashboard/": typeof DashboardIndexRoute + "/dashboard/admin/analytics": typeof DashboardAdminAnalyticsRoute + "/dashboard/admin/copy-logs": typeof DashboardAdminCopyLogsRoute + "/dashboard/admin/referrals": typeof DashboardAdminReferralsRoute + "/dashboard/admin/users": typeof DashboardAdminUsersRoute + "/demo/categories/$categoryId": typeof DemoCategoriesCategoryIdRoute + "/dashboard/admin/": typeof DashboardAdminIndexRoute + "/dashboard/catalog/": typeof DashboardCatalogIndexRoute + "/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute + "/dashboard/catalog/$brandName/": typeof DashboardCatalogBrandNameIndexRoute + "/dashboard/vehicles/$id/": typeof DashboardVehiclesIdIndexRoute + "/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute + "/dashboard/catalog/$brandName/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute + "/dashboard/catalog/emex/$catalogCode/": typeof DashboardCatalogEmexCatalogCodeIndexRoute + "/dashboard/catalog/pcat/$catalogId/": typeof DashboardCatalogPcatCatalogIdIndexRoute + "/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute + "/dashboard/catalog/emex/$catalogCode/$vehicleId/": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute + "/dashboard/catalog/pcat/$catalogId/$modelId/": typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute + "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute + "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/": typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute + "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId": typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute } export interface FileRoutesByTo { - '/': typeof IndexRoute - '/about': typeof AboutRoute - '/blog': typeof BlogRoute - '/contact': typeof ContactRoute - '/demo': typeof DemoRoute - '/kvkk': typeof KvkkRoute - '/pricing': typeof PricingRoute - '/privacy': typeof PrivacyRoute - '/terms': typeof TermsRoute - '/email-verified': typeof AuthEmailVerifiedRoute - '/forgot-password': typeof AuthForgotPasswordRoute - '/login': typeof AuthLoginRoute - '/register': typeof AuthRegisterRoute - '/reset-password': typeof AuthResetPasswordRoute - '/blog/$slug': typeof BlogSlugRoute - '/dashboard/billing': typeof DashboardBillingRoute - '/dashboard/changelog': typeof DashboardChangelogRoute - '/dashboard/history': typeof DashboardHistoryRoute - '/dashboard/search': typeof DashboardSearchRoute - '/dashboard/service-test': typeof DashboardServiceTestRoute - '/dashboard/settings': typeof DashboardSettingsRoute - '/dashboard': typeof DashboardIndexRoute - '/dashboard/admin/analytics': typeof DashboardAdminAnalyticsRoute - '/dashboard/admin/copy-logs': typeof DashboardAdminCopyLogsRoute - '/dashboard/admin/referrals': typeof DashboardAdminReferralsRoute - '/dashboard/admin/users': typeof DashboardAdminUsersRoute - '/dashboard/admin': typeof DashboardAdminIndexRoute - '/dashboard/catalog': typeof DashboardCatalogIndexRoute - '/dashboard/subscription': typeof DashboardSubscriptionIndexRoute - '/dashboard/catalog/$brandName': typeof DashboardCatalogBrandNameIndexRoute - '/dashboard/vehicles/$id': typeof DashboardVehiclesIdIndexRoute - '/dashboard/vehicles/$id/categories/$categoryId': typeof DashboardVehiclesIdCategoriesCategoryIdRoute - '/dashboard/catalog/$brandName/$modelId': typeof DashboardCatalogBrandNameModelIdIndexRoute - '/dashboard/catalog/emex/$catalogCode': typeof DashboardCatalogEmexCatalogCodeIndexRoute - '/dashboard/catalog/pcat/$catalogId': typeof DashboardCatalogPcatCatalogIdIndexRoute - '/dashboard/catalog/$brandName/$modelId/categories/$categoryId': typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute - '/dashboard/catalog/emex/$catalogCode/$vehicleId': typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute - '/dashboard/catalog/pcat/$catalogId/$modelId': typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute - '/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId': typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute - '/dashboard/catalog/pcat/$catalogId/$modelId/$carId': typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute - '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId': typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute + "/": typeof IndexRoute + "/about": typeof AboutRoute + "/blog": typeof BlogRoute + "/contact": typeof ContactRoute + "/demo": typeof DemoRoute + "/kvkk": typeof KvkkRoute + "/pricing": typeof PricingRoute + "/privacy": typeof PrivacyRoute + "/terms": typeof TermsRoute + "/email-verified": typeof AuthEmailVerifiedRoute + "/forgot-password": typeof AuthForgotPasswordRoute + "/login": typeof AuthLoginRoute + "/register": typeof AuthRegisterRoute + "/reset-password": typeof AuthResetPasswordRoute + "/blog/$slug": typeof BlogSlugRoute + "/dashboard/billing": typeof DashboardBillingRoute + "/dashboard/changelog": typeof DashboardChangelogRoute + "/dashboard/history": typeof DashboardHistoryRoute + "/dashboard/search": typeof DashboardSearchRoute + "/dashboard/service-test": typeof DashboardServiceTestRoute + "/dashboard/settings": typeof DashboardSettingsRoute + "/dashboard": typeof DashboardIndexRoute + "/dashboard/admin/analytics": typeof DashboardAdminAnalyticsRoute + "/dashboard/admin/copy-logs": typeof DashboardAdminCopyLogsRoute + "/dashboard/admin/referrals": typeof DashboardAdminReferralsRoute + "/dashboard/admin/users": typeof DashboardAdminUsersRoute + "/demo/categories/$categoryId": typeof DemoCategoriesCategoryIdRoute + "/dashboard/admin": typeof DashboardAdminIndexRoute + "/dashboard/catalog": typeof DashboardCatalogIndexRoute + "/dashboard/subscription": typeof DashboardSubscriptionIndexRoute + "/dashboard/catalog/$brandName": typeof DashboardCatalogBrandNameIndexRoute + "/dashboard/vehicles/$id": typeof DashboardVehiclesIdIndexRoute + "/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute + "/dashboard/catalog/$brandName/$modelId": typeof DashboardCatalogBrandNameModelIdIndexRoute + "/dashboard/catalog/emex/$catalogCode": typeof DashboardCatalogEmexCatalogCodeIndexRoute + "/dashboard/catalog/pcat/$catalogId": typeof DashboardCatalogPcatCatalogIdIndexRoute + "/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute + "/dashboard/catalog/emex/$catalogCode/$vehicleId": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute + "/dashboard/catalog/pcat/$catalogId/$modelId": typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute + "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute + "/dashboard/catalog/pcat/$catalogId/$modelId/$carId": typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute + "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId": typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute } export interface FileRoutesById { __root__: typeof rootRouteImport - '/': typeof IndexRoute - '/_auth': typeof AuthRouteWithChildren - '/about': typeof AboutRoute - '/blog': typeof BlogRoute - '/contact': typeof ContactRoute - '/dashboard': typeof DashboardRouteWithChildren - '/demo': typeof DemoRoute - '/kvkk': typeof KvkkRoute - '/pricing': typeof PricingRoute - '/privacy': typeof PrivacyRoute - '/terms': typeof TermsRoute - '/_auth/email-verified': typeof AuthEmailVerifiedRoute - '/_auth/forgot-password': typeof AuthForgotPasswordRoute - '/_auth/login': typeof AuthLoginRoute - '/_auth/register': typeof AuthRegisterRoute - '/_auth/reset-password': typeof AuthResetPasswordRoute - '/blog_/$slug': typeof BlogSlugRoute - '/dashboard/billing': typeof DashboardBillingRoute - '/dashboard/changelog': typeof DashboardChangelogRoute - '/dashboard/history': typeof DashboardHistoryRoute - '/dashboard/search': typeof DashboardSearchRoute - '/dashboard/service-test': typeof DashboardServiceTestRoute - '/dashboard/settings': typeof DashboardSettingsRoute - '/dashboard/': typeof DashboardIndexRoute - '/dashboard/admin/analytics': typeof DashboardAdminAnalyticsRoute - '/dashboard/admin/copy-logs': typeof DashboardAdminCopyLogsRoute - '/dashboard/admin/referrals': typeof DashboardAdminReferralsRoute - '/dashboard/admin/users': typeof DashboardAdminUsersRoute - '/dashboard/admin/': typeof DashboardAdminIndexRoute - '/dashboard/catalog/': typeof DashboardCatalogIndexRoute - '/dashboard/subscription/': typeof DashboardSubscriptionIndexRoute - '/dashboard/catalog_/$brandName/': typeof DashboardCatalogBrandNameIndexRoute - '/dashboard/vehicles_/$id/': typeof DashboardVehiclesIdIndexRoute - '/dashboard/vehicles_/$id/categories_/$categoryId': typeof DashboardVehiclesIdCategoriesCategoryIdRoute - '/dashboard/catalog_/$brandName_/$modelId/': typeof DashboardCatalogBrandNameModelIdIndexRoute - '/dashboard/catalog_/emex/$catalogCode/': typeof DashboardCatalogEmexCatalogCodeIndexRoute - '/dashboard/catalog_/pcat/$catalogId/': typeof DashboardCatalogPcatCatalogIdIndexRoute - '/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId': typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute - '/dashboard/catalog_/emex/$catalogCode_/$vehicleId/': typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute - '/dashboard/catalog_/pcat/$catalogId_/$modelId/': typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute - '/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId': typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute - '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/': typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute - '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId': typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute + "/": typeof IndexRoute + "/_auth": typeof AuthRouteWithChildren + "/about": typeof AboutRoute + "/blog": typeof BlogRoute + "/contact": typeof ContactRoute + "/dashboard": typeof DashboardRouteWithChildren + "/demo": typeof DemoRoute + "/kvkk": typeof KvkkRoute + "/pricing": typeof PricingRoute + "/privacy": typeof PrivacyRoute + "/terms": typeof TermsRoute + "/_auth/email-verified": typeof AuthEmailVerifiedRoute + "/_auth/forgot-password": typeof AuthForgotPasswordRoute + "/_auth/login": typeof AuthLoginRoute + "/_auth/register": typeof AuthRegisterRoute + "/_auth/reset-password": typeof AuthResetPasswordRoute + "/blog_/$slug": typeof BlogSlugRoute + "/dashboard/billing": typeof DashboardBillingRoute + "/dashboard/changelog": typeof DashboardChangelogRoute + "/dashboard/history": typeof DashboardHistoryRoute + "/dashboard/search": typeof DashboardSearchRoute + "/dashboard/service-test": typeof DashboardServiceTestRoute + "/dashboard/settings": typeof DashboardSettingsRoute + "/dashboard/": typeof DashboardIndexRoute + "/dashboard/admin/analytics": typeof DashboardAdminAnalyticsRoute + "/dashboard/admin/copy-logs": typeof DashboardAdminCopyLogsRoute + "/dashboard/admin/referrals": typeof DashboardAdminReferralsRoute + "/dashboard/admin/users": typeof DashboardAdminUsersRoute + "/demo_/categories_/$categoryId": typeof DemoCategoriesCategoryIdRoute + "/dashboard/admin/": typeof DashboardAdminIndexRoute + "/dashboard/catalog/": typeof DashboardCatalogIndexRoute + "/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute + "/dashboard/catalog_/$brandName/": typeof DashboardCatalogBrandNameIndexRoute + "/dashboard/vehicles_/$id/": typeof DashboardVehiclesIdIndexRoute + "/dashboard/vehicles_/$id/categories_/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute + "/dashboard/catalog_/$brandName_/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute + "/dashboard/catalog_/emex/$catalogCode/": typeof DashboardCatalogEmexCatalogCodeIndexRoute + "/dashboard/catalog_/pcat/$catalogId/": typeof DashboardCatalogPcatCatalogIdIndexRoute + "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute + "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute + "/dashboard/catalog_/pcat/$catalogId_/$modelId/": typeof DashboardCatalogPcatCatalogIdModelIdIndexRoute + "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute + "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/": typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRoute + "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId": typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath fullPaths: - | '/' - | '/about' - | '/blog' - | '/contact' - | '/dashboard' - | '/demo' - | '/kvkk' - | '/pricing' - | '/privacy' - | '/terms' - | '/email-verified' - | '/forgot-password' - | '/login' - | '/register' - | '/reset-password' - | '/blog/$slug' - | '/dashboard/billing' - | '/dashboard/changelog' - | '/dashboard/history' - | '/dashboard/search' - | '/dashboard/service-test' - | '/dashboard/settings' - | '/dashboard/' - | '/dashboard/admin/analytics' - | '/dashboard/admin/copy-logs' - | '/dashboard/admin/referrals' - | '/dashboard/admin/users' - | '/dashboard/admin/' - | '/dashboard/catalog/' - | '/dashboard/subscription/' - | '/dashboard/catalog/$brandName/' - | '/dashboard/vehicles/$id/' - | '/dashboard/vehicles/$id/categories/$categoryId' - | '/dashboard/catalog/$brandName/$modelId/' - | '/dashboard/catalog/emex/$catalogCode/' - | '/dashboard/catalog/pcat/$catalogId/' - | '/dashboard/catalog/$brandName/$modelId/categories/$categoryId' - | '/dashboard/catalog/emex/$catalogCode/$vehicleId/' - | '/dashboard/catalog/pcat/$catalogId/$modelId/' - | '/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId' - | '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/' - | '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId' + | "/" + | "/about" + | "/blog" + | "/contact" + | "/dashboard" + | "/demo" + | "/kvkk" + | "/pricing" + | "/privacy" + | "/terms" + | "/email-verified" + | "/forgot-password" + | "/login" + | "/register" + | "/reset-password" + | "/blog/$slug" + | "/dashboard/billing" + | "/dashboard/changelog" + | "/dashboard/history" + | "/dashboard/search" + | "/dashboard/service-test" + | "/dashboard/settings" + | "/dashboard/" + | "/dashboard/admin/analytics" + | "/dashboard/admin/copy-logs" + | "/dashboard/admin/referrals" + | "/dashboard/admin/users" + | "/demo/categories/$categoryId" + | "/dashboard/admin/" + | "/dashboard/catalog/" + | "/dashboard/subscription/" + | "/dashboard/catalog/$brandName/" + | "/dashboard/vehicles/$id/" + | "/dashboard/vehicles/$id/categories/$categoryId" + | "/dashboard/catalog/$brandName/$modelId/" + | "/dashboard/catalog/emex/$catalogCode/" + | "/dashboard/catalog/pcat/$catalogId/" + | "/dashboard/catalog/$brandName/$modelId/categories/$categoryId" + | "/dashboard/catalog/emex/$catalogCode/$vehicleId/" + | "/dashboard/catalog/pcat/$catalogId/$modelId/" + | "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId" + | "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/" + | "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId" fileRoutesByTo: FileRoutesByTo to: - | '/' - | '/about' - | '/blog' - | '/contact' - | '/demo' - | '/kvkk' - | '/pricing' - | '/privacy' - | '/terms' - | '/email-verified' - | '/forgot-password' - | '/login' - | '/register' - | '/reset-password' - | '/blog/$slug' - | '/dashboard/billing' - | '/dashboard/changelog' - | '/dashboard/history' - | '/dashboard/search' - | '/dashboard/service-test' - | '/dashboard/settings' - | '/dashboard' - | '/dashboard/admin/analytics' - | '/dashboard/admin/copy-logs' - | '/dashboard/admin/referrals' - | '/dashboard/admin/users' - | '/dashboard/admin' - | '/dashboard/catalog' - | '/dashboard/subscription' - | '/dashboard/catalog/$brandName' - | '/dashboard/vehicles/$id' - | '/dashboard/vehicles/$id/categories/$categoryId' - | '/dashboard/catalog/$brandName/$modelId' - | '/dashboard/catalog/emex/$catalogCode' - | '/dashboard/catalog/pcat/$catalogId' - | '/dashboard/catalog/$brandName/$modelId/categories/$categoryId' - | '/dashboard/catalog/emex/$catalogCode/$vehicleId' - | '/dashboard/catalog/pcat/$catalogId/$modelId' - | '/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId' - | '/dashboard/catalog/pcat/$catalogId/$modelId/$carId' - | '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId' + | "/" + | "/about" + | "/blog" + | "/contact" + | "/demo" + | "/kvkk" + | "/pricing" + | "/privacy" + | "/terms" + | "/email-verified" + | "/forgot-password" + | "/login" + | "/register" + | "/reset-password" + | "/blog/$slug" + | "/dashboard/billing" + | "/dashboard/changelog" + | "/dashboard/history" + | "/dashboard/search" + | "/dashboard/service-test" + | "/dashboard/settings" + | "/dashboard" + | "/dashboard/admin/analytics" + | "/dashboard/admin/copy-logs" + | "/dashboard/admin/referrals" + | "/dashboard/admin/users" + | "/demo/categories/$categoryId" + | "/dashboard/admin" + | "/dashboard/catalog" + | "/dashboard/subscription" + | "/dashboard/catalog/$brandName" + | "/dashboard/vehicles/$id" + | "/dashboard/vehicles/$id/categories/$categoryId" + | "/dashboard/catalog/$brandName/$modelId" + | "/dashboard/catalog/emex/$catalogCode" + | "/dashboard/catalog/pcat/$catalogId" + | "/dashboard/catalog/$brandName/$modelId/categories/$categoryId" + | "/dashboard/catalog/emex/$catalogCode/$vehicleId" + | "/dashboard/catalog/pcat/$catalogId/$modelId" + | "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId" + | "/dashboard/catalog/pcat/$catalogId/$modelId/$carId" + | "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId" id: - | '__root__' - | '/' - | '/_auth' - | '/about' - | '/blog' - | '/contact' - | '/dashboard' - | '/demo' - | '/kvkk' - | '/pricing' - | '/privacy' - | '/terms' - | '/_auth/email-verified' - | '/_auth/forgot-password' - | '/_auth/login' - | '/_auth/register' - | '/_auth/reset-password' - | '/blog_/$slug' - | '/dashboard/billing' - | '/dashboard/changelog' - | '/dashboard/history' - | '/dashboard/search' - | '/dashboard/service-test' - | '/dashboard/settings' - | '/dashboard/' - | '/dashboard/admin/analytics' - | '/dashboard/admin/copy-logs' - | '/dashboard/admin/referrals' - | '/dashboard/admin/users' - | '/dashboard/admin/' - | '/dashboard/catalog/' - | '/dashboard/subscription/' - | '/dashboard/catalog_/$brandName/' - | '/dashboard/vehicles_/$id/' - | '/dashboard/vehicles_/$id/categories_/$categoryId' - | '/dashboard/catalog_/$brandName_/$modelId/' - | '/dashboard/catalog_/emex/$catalogCode/' - | '/dashboard/catalog_/pcat/$catalogId/' - | '/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId' - | '/dashboard/catalog_/emex/$catalogCode_/$vehicleId/' - | '/dashboard/catalog_/pcat/$catalogId_/$modelId/' - | '/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId' - | '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/' - | '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId' + | "__root__" + | "/" + | "/_auth" + | "/about" + | "/blog" + | "/contact" + | "/dashboard" + | "/demo" + | "/kvkk" + | "/pricing" + | "/privacy" + | "/terms" + | "/_auth/email-verified" + | "/_auth/forgot-password" + | "/_auth/login" + | "/_auth/register" + | "/_auth/reset-password" + | "/blog_/$slug" + | "/dashboard/billing" + | "/dashboard/changelog" + | "/dashboard/history" + | "/dashboard/search" + | "/dashboard/service-test" + | "/dashboard/settings" + | "/dashboard/" + | "/dashboard/admin/analytics" + | "/dashboard/admin/copy-logs" + | "/dashboard/admin/referrals" + | "/dashboard/admin/users" + | "/demo_/categories_/$categoryId" + | "/dashboard/admin/" + | "/dashboard/catalog/" + | "/dashboard/subscription/" + | "/dashboard/catalog_/$brandName/" + | "/dashboard/vehicles_/$id/" + | "/dashboard/vehicles_/$id/categories_/$categoryId" + | "/dashboard/catalog_/$brandName_/$modelId/" + | "/dashboard/catalog_/emex/$catalogCode/" + | "/dashboard/catalog_/pcat/$catalogId/" + | "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId" + | "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/" + | "/dashboard/catalog_/pcat/$catalogId_/$modelId/" + | "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId" + | "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/" + | "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId" fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -562,308 +575,316 @@ export interface RootRouteChildren { PrivacyRoute: typeof PrivacyRoute TermsRoute: typeof TermsRoute BlogSlugRoute: typeof BlogSlugRoute + DemoCategoriesCategoryIdRoute: typeof DemoCategoriesCategoryIdRoute } -declare module '@tanstack/react-router' { +declare module "@tanstack/react-router" { interface FileRoutesByPath { - '/terms': { - id: '/terms' - path: '/terms' - fullPath: '/terms' + "/terms": { + id: "/terms" + path: "/terms" + fullPath: "/terms" preLoaderRoute: typeof TermsRouteImport parentRoute: typeof rootRouteImport } - '/privacy': { - id: '/privacy' - path: '/privacy' - fullPath: '/privacy' + "/privacy": { + id: "/privacy" + path: "/privacy" + fullPath: "/privacy" preLoaderRoute: typeof PrivacyRouteImport parentRoute: typeof rootRouteImport } - '/pricing': { - id: '/pricing' - path: '/pricing' - fullPath: '/pricing' + "/pricing": { + id: "/pricing" + path: "/pricing" + fullPath: "/pricing" preLoaderRoute: typeof PricingRouteImport parentRoute: typeof rootRouteImport } - '/kvkk': { - id: '/kvkk' - path: '/kvkk' - fullPath: '/kvkk' + "/kvkk": { + id: "/kvkk" + path: "/kvkk" + fullPath: "/kvkk" preLoaderRoute: typeof KvkkRouteImport parentRoute: typeof rootRouteImport } - '/demo': { - id: '/demo' - path: '/demo' - fullPath: '/demo' + "/demo": { + id: "/demo" + path: "/demo" + fullPath: "/demo" preLoaderRoute: typeof DemoRouteImport parentRoute: typeof rootRouteImport } - '/dashboard': { - id: '/dashboard' - path: '/dashboard' - fullPath: '/dashboard' + "/dashboard": { + id: "/dashboard" + path: "/dashboard" + fullPath: "/dashboard" preLoaderRoute: typeof DashboardRouteImport parentRoute: typeof rootRouteImport } - '/contact': { - id: '/contact' - path: '/contact' - fullPath: '/contact' + "/contact": { + id: "/contact" + path: "/contact" + fullPath: "/contact" preLoaderRoute: typeof ContactRouteImport parentRoute: typeof rootRouteImport } - '/blog': { - id: '/blog' - path: '/blog' - fullPath: '/blog' + "/blog": { + id: "/blog" + path: "/blog" + fullPath: "/blog" preLoaderRoute: typeof BlogRouteImport parentRoute: typeof rootRouteImport } - '/about': { - id: '/about' - path: '/about' - fullPath: '/about' + "/about": { + id: "/about" + path: "/about" + fullPath: "/about" preLoaderRoute: typeof AboutRouteImport parentRoute: typeof rootRouteImport } - '/_auth': { - id: '/_auth' - path: '' - fullPath: '/' + "/_auth": { + id: "/_auth" + path: "" + fullPath: "/" preLoaderRoute: typeof AuthRouteImport parentRoute: typeof rootRouteImport } - '/': { - id: '/' - path: '/' - fullPath: '/' + "/": { + id: "/" + path: "/" + fullPath: "/" preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } - '/dashboard/': { - id: '/dashboard/' - path: '/' - fullPath: '/dashboard/' + "/dashboard/": { + id: "/dashboard/" + path: "/" + fullPath: "/dashboard/" preLoaderRoute: typeof DashboardIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/settings': { - id: '/dashboard/settings' - path: '/settings' - fullPath: '/dashboard/settings' + "/dashboard/settings": { + id: "/dashboard/settings" + path: "/settings" + fullPath: "/dashboard/settings" preLoaderRoute: typeof DashboardSettingsRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/service-test': { - id: '/dashboard/service-test' - path: '/service-test' - fullPath: '/dashboard/service-test' + "/dashboard/service-test": { + id: "/dashboard/service-test" + path: "/service-test" + fullPath: "/dashboard/service-test" preLoaderRoute: typeof DashboardServiceTestRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/search': { - id: '/dashboard/search' - path: '/search' - fullPath: '/dashboard/search' + "/dashboard/search": { + id: "/dashboard/search" + path: "/search" + fullPath: "/dashboard/search" preLoaderRoute: typeof DashboardSearchRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/history': { - id: '/dashboard/history' - path: '/history' - fullPath: '/dashboard/history' + "/dashboard/history": { + id: "/dashboard/history" + path: "/history" + fullPath: "/dashboard/history" preLoaderRoute: typeof DashboardHistoryRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/changelog': { - id: '/dashboard/changelog' - path: '/changelog' - fullPath: '/dashboard/changelog' + "/dashboard/changelog": { + id: "/dashboard/changelog" + path: "/changelog" + fullPath: "/dashboard/changelog" preLoaderRoute: typeof DashboardChangelogRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/billing': { - id: '/dashboard/billing' - path: '/billing' - fullPath: '/dashboard/billing' + "/dashboard/billing": { + id: "/dashboard/billing" + path: "/billing" + fullPath: "/dashboard/billing" preLoaderRoute: typeof DashboardBillingRouteImport parentRoute: typeof DashboardRoute } - '/blog_/$slug': { - id: '/blog_/$slug' - path: '/blog/$slug' - fullPath: '/blog/$slug' + "/blog_/$slug": { + id: "/blog_/$slug" + path: "/blog/$slug" + fullPath: "/blog/$slug" preLoaderRoute: typeof BlogSlugRouteImport parentRoute: typeof rootRouteImport } - '/_auth/reset-password': { - id: '/_auth/reset-password' - path: '/reset-password' - fullPath: '/reset-password' + "/_auth/reset-password": { + id: "/_auth/reset-password" + path: "/reset-password" + fullPath: "/reset-password" preLoaderRoute: typeof AuthResetPasswordRouteImport parentRoute: typeof AuthRoute } - '/_auth/register': { - id: '/_auth/register' - path: '/register' - fullPath: '/register' + "/_auth/register": { + id: "/_auth/register" + path: "/register" + fullPath: "/register" preLoaderRoute: typeof AuthRegisterRouteImport parentRoute: typeof AuthRoute } - '/_auth/login': { - id: '/_auth/login' - path: '/login' - fullPath: '/login' + "/_auth/login": { + id: "/_auth/login" + path: "/login" + fullPath: "/login" preLoaderRoute: typeof AuthLoginRouteImport parentRoute: typeof AuthRoute } - '/_auth/forgot-password': { - id: '/_auth/forgot-password' - path: '/forgot-password' - fullPath: '/forgot-password' + "/_auth/forgot-password": { + id: "/_auth/forgot-password" + path: "/forgot-password" + fullPath: "/forgot-password" preLoaderRoute: typeof AuthForgotPasswordRouteImport parentRoute: typeof AuthRoute } - '/_auth/email-verified': { - id: '/_auth/email-verified' - path: '/email-verified' - fullPath: '/email-verified' + "/_auth/email-verified": { + id: "/_auth/email-verified" + path: "/email-verified" + fullPath: "/email-verified" preLoaderRoute: typeof AuthEmailVerifiedRouteImport parentRoute: typeof AuthRoute } - '/dashboard/subscription/': { - id: '/dashboard/subscription/' - path: '/subscription' - fullPath: '/dashboard/subscription/' + "/dashboard/subscription/": { + id: "/dashboard/subscription/" + path: "/subscription" + fullPath: "/dashboard/subscription/" preLoaderRoute: typeof DashboardSubscriptionIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog/': { - id: '/dashboard/catalog/' - path: '/catalog' - fullPath: '/dashboard/catalog/' + "/dashboard/catalog/": { + id: "/dashboard/catalog/" + path: "/catalog" + fullPath: "/dashboard/catalog/" preLoaderRoute: typeof DashboardCatalogIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/admin/': { - id: '/dashboard/admin/' - path: '/admin' - fullPath: '/dashboard/admin/' + "/dashboard/admin/": { + id: "/dashboard/admin/" + path: "/admin" + fullPath: "/dashboard/admin/" preLoaderRoute: typeof DashboardAdminIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/admin/users': { - id: '/dashboard/admin/users' - path: '/admin/users' - fullPath: '/dashboard/admin/users' + "/demo_/categories_/$categoryId": { + id: "/demo_/categories_/$categoryId" + path: "/demo/categories/$categoryId" + fullPath: "/demo/categories/$categoryId" + preLoaderRoute: typeof DemoCategoriesCategoryIdRouteImport + parentRoute: typeof rootRouteImport + } + "/dashboard/admin/users": { + id: "/dashboard/admin/users" + path: "/admin/users" + fullPath: "/dashboard/admin/users" preLoaderRoute: typeof DashboardAdminUsersRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/admin/referrals': { - id: '/dashboard/admin/referrals' - path: '/admin/referrals' - fullPath: '/dashboard/admin/referrals' + "/dashboard/admin/referrals": { + id: "/dashboard/admin/referrals" + path: "/admin/referrals" + fullPath: "/dashboard/admin/referrals" preLoaderRoute: typeof DashboardAdminReferralsRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/admin/copy-logs': { - id: '/dashboard/admin/copy-logs' - path: '/admin/copy-logs' - fullPath: '/dashboard/admin/copy-logs' + "/dashboard/admin/copy-logs": { + id: "/dashboard/admin/copy-logs" + path: "/admin/copy-logs" + fullPath: "/dashboard/admin/copy-logs" preLoaderRoute: typeof DashboardAdminCopyLogsRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/admin/analytics': { - id: '/dashboard/admin/analytics' - path: '/admin/analytics' - fullPath: '/dashboard/admin/analytics' + "/dashboard/admin/analytics": { + id: "/dashboard/admin/analytics" + path: "/admin/analytics" + fullPath: "/dashboard/admin/analytics" preLoaderRoute: typeof DashboardAdminAnalyticsRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/vehicles_/$id/': { - id: '/dashboard/vehicles_/$id/' - path: '/vehicles/$id' - fullPath: '/dashboard/vehicles/$id/' + "/dashboard/vehicles_/$id/": { + id: "/dashboard/vehicles_/$id/" + path: "/vehicles/$id" + fullPath: "/dashboard/vehicles/$id/" preLoaderRoute: typeof DashboardVehiclesIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/$brandName/': { - id: '/dashboard/catalog_/$brandName/' - path: '/catalog/$brandName' - fullPath: '/dashboard/catalog/$brandName/' + "/dashboard/catalog_/$brandName/": { + id: "/dashboard/catalog_/$brandName/" + path: "/catalog/$brandName" + fullPath: "/dashboard/catalog/$brandName/" preLoaderRoute: typeof DashboardCatalogBrandNameIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/pcat/$catalogId/': { - id: '/dashboard/catalog_/pcat/$catalogId/' - path: '/catalog/pcat/$catalogId' - fullPath: '/dashboard/catalog/pcat/$catalogId/' + "/dashboard/catalog_/pcat/$catalogId/": { + id: "/dashboard/catalog_/pcat/$catalogId/" + path: "/catalog/pcat/$catalogId" + fullPath: "/dashboard/catalog/pcat/$catalogId/" preLoaderRoute: typeof DashboardCatalogPcatCatalogIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/emex/$catalogCode/': { - id: '/dashboard/catalog_/emex/$catalogCode/' - path: '/catalog/emex/$catalogCode' - fullPath: '/dashboard/catalog/emex/$catalogCode/' + "/dashboard/catalog_/emex/$catalogCode/": { + id: "/dashboard/catalog_/emex/$catalogCode/" + path: "/catalog/emex/$catalogCode" + fullPath: "/dashboard/catalog/emex/$catalogCode/" preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/$brandName_/$modelId/': { - id: '/dashboard/catalog_/$brandName_/$modelId/' - path: '/catalog/$brandName/$modelId' - fullPath: '/dashboard/catalog/$brandName/$modelId/' + "/dashboard/catalog_/$brandName_/$modelId/": { + id: "/dashboard/catalog_/$brandName_/$modelId/" + path: "/catalog/$brandName/$modelId" + fullPath: "/dashboard/catalog/$brandName/$modelId/" preLoaderRoute: typeof DashboardCatalogBrandNameModelIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/vehicles_/$id/categories_/$categoryId': { - id: '/dashboard/vehicles_/$id/categories_/$categoryId' - path: '/vehicles/$id/categories/$categoryId' - fullPath: '/dashboard/vehicles/$id/categories/$categoryId' + "/dashboard/vehicles_/$id/categories_/$categoryId": { + id: "/dashboard/vehicles_/$id/categories_/$categoryId" + path: "/vehicles/$id/categories/$categoryId" + fullPath: "/dashboard/vehicles/$id/categories/$categoryId" preLoaderRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/pcat/$catalogId_/$modelId/': { - id: '/dashboard/catalog_/pcat/$catalogId_/$modelId/' - path: '/catalog/pcat/$catalogId/$modelId' - fullPath: '/dashboard/catalog/pcat/$catalogId/$modelId/' + "/dashboard/catalog_/pcat/$catalogId_/$modelId/": { + id: "/dashboard/catalog_/pcat/$catalogId_/$modelId/" + path: "/catalog/pcat/$catalogId/$modelId" + fullPath: "/dashboard/catalog/pcat/$catalogId/$modelId/" preLoaderRoute: typeof DashboardCatalogPcatCatalogIdModelIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/emex/$catalogCode_/$vehicleId/': { - id: '/dashboard/catalog_/emex/$catalogCode_/$vehicleId/' - path: '/catalog/emex/$catalogCode/$vehicleId' - fullPath: '/dashboard/catalog/emex/$catalogCode/$vehicleId/' + "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/": { + id: "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/" + path: "/catalog/emex/$catalogCode/$vehicleId" + fullPath: "/dashboard/catalog/emex/$catalogCode/$vehicleId/" preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId': { - id: '/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId' - path: '/catalog/$brandName/$modelId/categories/$categoryId' - fullPath: '/dashboard/catalog/$brandName/$modelId/categories/$categoryId' + "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": { + id: "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId" + path: "/catalog/$brandName/$modelId/categories/$categoryId" + fullPath: "/dashboard/catalog/$brandName/$modelId/categories/$categoryId" preLoaderRoute: typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/': { - id: '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/' - path: '/catalog/pcat/$catalogId/$modelId/$carId' - fullPath: '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/' + "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/": { + id: "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId/" + path: "/catalog/pcat/$catalogId/$modelId/$carId" + fullPath: "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/" preLoaderRoute: typeof DashboardCatalogPcatCatalogIdModelIdCarIdIndexRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId': { - id: '/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId' - path: '/catalog/emex/$catalogCode/$vehicleId/groups/$groupId' - fullPath: '/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId' + "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId": { + id: "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId" + path: "/catalog/emex/$catalogCode/$vehicleId/groups/$groupId" + fullPath: "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId" preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport parentRoute: typeof DashboardRoute } - '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId': { - id: '/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId' - path: '/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId' - fullPath: '/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId' + "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId": { + id: "/dashboard/catalog_/pcat/$catalogId_/$modelId_/$carId_/groups/$groupId" + path: "/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId" + fullPath: "/dashboard/catalog/pcat/$catalogId/$modelId/$carId/groups/$groupId" preLoaderRoute: typeof DashboardCatalogPcatCatalogIdModelIdCarIdGroupsGroupIdRouteImport parentRoute: typeof DashboardRoute } @@ -973,6 +994,7 @@ const rootRouteChildren: RootRouteChildren = { PrivacyRoute: PrivacyRoute, TermsRoute: TermsRoute, BlogSlugRoute: BlogSlugRoute, + DemoCategoriesCategoryIdRoute: DemoCategoriesCategoryIdRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/apps/web/src/routes/demo.tsx b/apps/web/src/routes/demo.tsx index d7b4928..0533ff4 100644 --- a/apps/web/src/routes/demo.tsx +++ b/apps/web/src/routes/demo.tsx @@ -1,423 +1,195 @@ +import { DemoBanner } from "@/components/demo/demo-banner"; import { usePageMeta } from "@/hooks/use-page-meta"; -import { KEYS_16, KEYS_17 } from "@/lib/keys"; -import { getUserSettings, setUserSetting } from "@/lib/user-settings"; -import { Button, Input } from "@sase/ui"; +import { ApiError, api } from "@/lib/api-client"; +import { KEYS_8 } from "@/lib/keys"; +import { capture } from "@/lib/posthog"; +import { cleanModelName } from "@/lib/vehicle"; +import type { CategoryNode, Vehicle } from "@sase/shared"; +import { Button, Card, CardContent, CardHeader, CardTitle, Skeleton } from "@sase/ui"; +import { useQuery } from "@tanstack/react-query"; import { Link, createFileRoute } from "@tanstack/react-router"; -import { - ArrowRight, - Car, - FolderTree, - Loader2, - Lock, - Moon, - MousePointerClick, - Search, - Sun, -} from "lucide-react"; -import { useEffect, useState } from "react"; +import { ArrowRight, FolderOpen } from "lucide-react"; +import { useEffect } from "react"; export const Route = createFileRoute("/demo")({ - component: DemoPage, + component: DemoVehiclePage, }); -const EXAMPLE_CATEGORIES = [ - { name: "Motor", subcategories: ["Silindir Kapağı", "Krank Mili", "Piston", "Yağ Pompası"] }, - { name: "Şasi & Süspansiyon", subcategories: ["Amortisör", "Salıncak", "Rotil", "Viraj Demiri"] }, - { name: "Elektrik", subcategories: ["Alternatör", "Marş Motoru", "Kablo Tesisatı", "Sensörler"] }, - { name: "Karoseri", subcategories: ["Kapı Paneli", "Tampon", "Ayna", "Far"] }, - { name: "Klima & Isıtma", subcategories: ["Kompresör", "Kalorifer", "Radyatör", "Fan Motoru"] }, -]; - -const EXAMPLE_SCHEMA_PARTS = [ - { code: "1J0 820 803F", name: "Klima Kompresörü", position: "A1" }, - { code: "1J0 819 031A", name: "Kalorifer Motoru", position: "B3" }, - { code: "1J0 698 151G", name: "Ön Fren Balatası", position: "C2" }, - { code: "1J0 407 271J", name: "Alt Salıncak", position: "D1" }, -]; - -function DemoPage() { +function DemoVehiclePage() { usePageMeta({ - title: "Demo — Sase.tr | Şase Sorgulamayı Deneyin", - description: "Ücretsiz demo ile şase numarası sorgulama ve OEM parça kataloğunu keşfedin.", + title: "Örnek Araç Kataloğu — Sase.tr", + description: + "Volkswagen Golf 2003 örnek aracı üzerinden OEM parça kataloğunu, kategori ağacını ve patlamış şemaları kayıt olmadan inceleyin.", canonical: "https://sase.tr/demo", + noindex: true, }); - const [vin, setVin] = useState(""); - const [vinPreview, setVinPreview] = useState<{ - make: string; - model: string; - year: string; - engine: string; - } | null>(null); - const [vinLoading, setVinLoading] = useState(false); - const [vinError, setVinError] = useState(false); - const [step, setStep] = useState<"vin" | "categories" | "schema">("vin"); - const [selectedCategory, setSelectedCategory] = useState(null); - const [isDark, setIsDark] = useState(() => { - const theme = getUserSettings().theme ?? "dark"; - if (theme === "system") { - return window.matchMedia("(prefers-color-scheme: dark)").matches; - } - return theme === "dark"; + const { + data: vehicle, + isLoading: vehicleLoading, + isError: vehicleError, + } = useQuery({ + queryKey: ["demo-vehicle"], + queryFn: () => api.get("/demo/vehicle"), + retry: (count, err) => !(err instanceof ApiError && err.status === 404) && count < 2, }); - const toggleTheme = () => { - const next = isDark ? "light" : "dark"; - document.documentElement.classList.toggle("dark", next === "dark"); - setUserSetting("theme", next); - setIsDark(next === "dark"); - }; + const { data: categoryTree, isLoading: treeLoading } = useQuery({ + queryKey: ["demo-category-tree"], + queryFn: () => api.get("/demo/categories/tree"), + }); - // NHTSA VIN decode + // Page-view event per mount; source query param lets the funnel split by + // entry path (hero empty-Ara click vs direct vs marketing link). useEffect(() => { - if (vin.length !== 17) { - setVinPreview(null); - setVinError(false); - return; - } + const params = new URLSearchParams(window.location.search); + capture("demo_loaded", { + source: params.get("source") ?? "direct", + surface: "vehicle", + }); + }, []); - const controller = new AbortController(); - setVinLoading(true); - setVinError(false); + const vehicleLabel = vehicle?.brandName + ? `${vehicle.brandName} ${cleanModelName(vehicle.model) ?? ""} ${vehicle.year ?? ""}`.trim() + : "Örnek araç"; - fetch(`/api/vehicles/preview/${vin}`, { signal: controller.signal }) - .then((res) => { - if (!res.ok) throw new Error("Bulunamadı"); - return res.json(); - }) - .then((data) => { - const r = data.data !== undefined ? data.data : data; - if (r?.brandName) { - setVinPreview({ - make: r.brandName, - model: r.model || "—", - year: r.year ? String(r.year) : "—", - engine: r.engine || "—", - }); - } else { - setVinError(true); - } - setVinLoading(false); - }) - .catch((err) => { - if (err.name !== "AbortError") { - setVinError(true); - setVinLoading(false); - } - }); - - return () => controller.abort(); - }, [vin]); + if (vehicleError) { + return ( +
+ +
+
+

Demo aracı şu an yüklenemedi

+

+ Sayfayı tekrar açmayı deneyin. Sorun sürerse{" "} + + destek@sase.tr + + . +

+
+
+
+ ); + } return ( -
- {/* Header */} -
-
- - SASE - -
- - - - Demo - - - - -
-
-
+
+ -
- {/* Step indicator */} -
- -
- -
- -
- - {/* Step 1: VIN Input */} - {step === "vin" && ( -
-
-

- VIN ile Araç Tanımlama +
+ {/* Vehicle header */} +
+ {vehicleLoading ? ( + <> + + + + ) : ( + <> +

+ {vehicle?.brandName} {cleanModelName(vehicle?.model)}{" "} + {vehicle?.year && ({vehicle.year})}

-

- 17 haneli VIN numaranızı girin, aracınızı tanıyalım. -

-
+ {vehicle?.vin && ( +

+ {vehicle.vin} +

+ )} + {vehicle?.engine && ( +

{vehicle.engine}

+ )} + + )} +

-
- - setVin(e.target.value.toUpperCase())} - placeholder="Örnek: WVWZZZ1JZ3W597935" - maxLength={17} - className="h-14 rounded-2xl border-border bg-muted pl-12 pr-4 font-mono text-foreground placeholder:text-muted-foreground/70 focus-visible:ring-ring" - /> -
- - {/* Progress bar */} -
- {KEYS_17.map((k, i) => ( -
- ))} -
- - {vinLoading && ( -
- - Araç bilgileri alınıyor... -
- )} - - {vinPreview && !vinLoading && ( -
-
- -
-

- {vinPreview.make} {vinPreview.model} -

-

- {vinPreview.year} {vinPreview.engine !== "—" ? `• ${vinPreview.engine}` : ""} -

-
-
- -
- )} - - {vinError && !vinLoading && ( -
- VIN bilgisi bulunamadı. Lütfen kontrol edin. -
- )} - - {!vin && ( - - )} -
- )} - - {/* Step 2: Categories (static mockup) */} - {step === "categories" && ( -
-
-
-

- Parça Kategorileri -

- {vinPreview && ( -

- {vinPreview.make} {vinPreview.model} ({vinPreview.year}) -

- )} -
- -
- -
- {EXAMPLE_CATEGORIES.map((cat) => ( - - ))} -
-
- )} - - {/* Step 3: Schema & Parts (static mockup with overlay) */} - {step === "schema" && ( -
-
-
-

- {selectedCategory} — Şema & Parçalar -

- {vinPreview && ( -

- {vinPreview.make} {vinPreview.model} ({vinPreview.year}) -

- )} -
- -
- -
- {/* Schema mockup with watermark */} -
-
-
- - İnteraktif Şema -
-
-
- {/* Simplified schema grid */} -
- {KEYS_16.map((k, i) => ( -
- {[2, 5, 9, 13].includes(i) - ? EXAMPLE_SCHEMA_PARTS[[2, 5, 9, 13].indexOf(i)]?.position - : ""} -
- ))} -
- {/* Watermark overlay */} -
-
- -

- Tam şema erişimi için kayıt olun -

-
-
-
-
- - {/* Parts list */} -
-

OEM Parça Listesi

- {EXAMPLE_SCHEMA_PARTS.map((part, idx) => ( -
-
- {part.code} -

{part.name}

-
- {idx < 2 ? ( - - Görünür - - ) : ( - - - Kilitli - - )} -
+ {/* Categories */} + + + Yedek parça kategorileri + + + {treeLoading ? ( +
+ {KEYS_8.map((k) => ( + ))} - - {/* Signup overlay CTA */} -
-

Tüm parçaları ve şemaları görün

-

- 30 gün ücretsiz deneyin — kredi kartı gerekmez -

- - - -
-
+ ) : !categoryTree || categoryTree.length === 0 ? ( +
+

+ Kategoriler şu an gösterilemiyor +

+

+ Lütfen biraz sonra tekrar deneyin. +

+
+ ) : ( + + )} + + + + {/* Footer CTA — second conversion surface after browsing */} +
+
+

Kendi aracınız için sınırsız erişim

+

+ Kart bilgisi gerekmez · 30 gün ücretsiz · istediğin an iptal +

- )} + +
); } + +interface DemoCategoryGridProps { + categories: CategoryNode[]; +} + +function DemoCategoryGrid({ categories }: DemoCategoryGridProps) { + return ( +
+ {categories.map((cat) => ( + + capture("demo_category_clicked", { + category_id: cat.id, + category_name: cat.name, + source: "tree", + }) + } + className="group flex items-start gap-3 rounded-lg border border-border bg-card p-4 transition-colors hover:border-foreground/30 hover:bg-muted/40" + data-faro-user-action-name="demo-category-card" + > + +
+

{cat.name}

+ {cat.children?.length > 0 && ( +

+ {cat.children.length} alt kategori +

+ )} +
+ + + ))} +
+ ); +} diff --git a/apps/web/src/routes/demo_/categories_/$categoryId.tsx b/apps/web/src/routes/demo_/categories_/$categoryId.tsx new file mode 100644 index 0000000..97aedbb --- /dev/null +++ b/apps/web/src/routes/demo_/categories_/$categoryId.tsx @@ -0,0 +1,307 @@ +import { DemoBanner } from "@/components/demo/demo-banner"; +import { SchemaViewer } from "@/components/schema/schema-viewer"; +import { usePageMeta } from "@/hooks/use-page-meta"; +import type { CategorySchema } from "@/hooks/use-parts"; +import { api } from "@/lib/api-client"; +import { KEYS_6 } from "@/lib/keys"; +import { capture } from "@/lib/posthog"; +import { cleanModelName } from "@/lib/vehicle"; +import type { Vehicle } from "@sase/shared"; +import { Button, Skeleton } from "@sase/ui"; +import { useQuery } from "@tanstack/react-query"; +import { Link, createFileRoute, useNavigate } from "@tanstack/react-router"; +import { ArrowLeft, ArrowRight, ChevronRight, FolderOpen } from "lucide-react"; +import { Fragment, Suspense, useEffect } from "react"; + +export const Route = createFileRoute("/demo_/categories_/$categoryId")({ + component: DemoCategoryPage, +}); + +// Reuse the same hook the dashboard uses — pointed at the public demo path so +// the response shape (parts/schemaPics/hotspots/ancestors/loadError) is +// identical to what SchemaViewer expects. +function useDemoCategory(categoryId: string) { + return useQuery({ + queryKey: ["demo-category", categoryId], + queryFn: () => api.get(`/demo/categories/${categoryId}`), + enabled: !!categoryId, + }); +} + +function DemoCategoryPage() { + const { categoryId } = Route.useParams(); + const navigate = useNavigate(); + + usePageMeta({ + title: "Örnek Araç Kategorisi — Sase.tr", + description: "Örnek araç üzerinden seçilen kategorinin OEM parçalarını ve şemasını inceleyin.", + canonical: `https://sase.tr/demo/categories/${categoryId}`, + noindex: true, + }); + + const { data: vehicle } = useQuery({ + queryKey: ["demo-vehicle"], + queryFn: () => api.get("/demo/vehicle"), + }); + + const { data, isLoading, error, refetch, isFetching } = useDemoCategory(categoryId); + + const hasChildren = !!data?.children && data.children.length > 0; + const vehicleLabel = vehicle?.brandName + ? `${vehicle.brandName} ${cleanModelName(vehicle.model) ?? ""} ${vehicle.year ?? ""}`.trim() + : "Örnek araç"; + + useEffect(() => { + if (data) { + capture("demo_category_detail_viewed", { + category_id: data.id, + category_name: data.name, + is_leaf: !hasChildren, + parts_count: data.parts?.length ?? 0, + has_schema: (data.schemaPics?.length ?? 0) > 0, + }); + } + }, [data, hasChildren]); + + const handleBack = () => { + const parentId = data?.ancestors?.at(-1)?.id ?? data?.parentId ?? null; + if (parentId) { + navigate({ + to: "/demo/categories/$categoryId", + params: { categoryId: parentId }, + }); + } else { + navigate({ to: "/demo" }); + } + }; + + return ( +
+ + +
+ {/* Breadcrumb (inline — demo routes) */} + + + {/* Header */} +
+
+ +
+

+ {data?.name ?? + (isLoading ? ( + + ) : ( + "Kategori" + ))} +

+ {data?.description && ( +

{data.description}

+ )} +
+
+
+ + {/* Hard error — distinct from data.loadError */} + {error && ( +
+
+

Kategori yüklenemedi

+

+ {error instanceof Error ? error.message : "Veriler yüklenirken bir hata oluştu."} +

+
+ +
+ )} + + {/* Loading skeleton */} + {isLoading && !data && ( +
+ {KEYS_6.map((k) => ( + + ))} +
+ )} + + {/* Children grid — when this category is a parent */} + {hasChildren && data?.children && } + + {/* Leaf — schema viewer or graceful upstream-error retry */} + {data && + !hasChildren && + (data.loadError ? ( +
+
+

Katalog şu an yüklenemedi

+

+ Bu kategori tedarikçi katalogundan alınamadı. Lütfen birazdan tekrar deneyin. +

+
+ +
+ ) : ( + }> + + + ))} + + {/* Footer CTA — present on every leaf so the conversion path is always + one click away after the user has just had an "aha" moment. */} + {data && !data.loadError && ( +
+

Kendi aracınız için sınırsız erişim

+ +
+ )} +
+
+ ); +} + +interface DemoBreadcrumbProps { + vehicleLabel: string; + ancestors: Array<{ id: string; name: string }>; + currentName?: string; +} + +function DemoBreadcrumb({ vehicleLabel, ancestors, currentName }: DemoBreadcrumbProps) { + return ( + + ); +} + +interface DemoChildrenGridProps { + items: Array<{ id: string; name: string; children?: unknown[] }>; +} + +function DemoChildrenGrid({ items }: DemoChildrenGridProps) { + return ( +
+ {items.map((cat) => ( + + capture("demo_category_clicked", { + category_id: cat.id, + category_name: cat.name, + source: "drill", + }) + } + className="group flex items-start gap-3 rounded-lg border border-border bg-card p-4 transition-colors hover:border-foreground/30 hover:bg-muted/40" + data-faro-user-action-name="demo-child-card" + > + +
+

{cat.name}

+ {(cat.children?.length ?? 0) > 0 && ( +

+ {cat.children?.length} alt kategori +

+ )} +
+ + + ))} +
+ ); +} + +function SchemaSkeleton() { + return ( +
+
+ +
+
+ + {KEYS_6.map((k) => ( + + ))} +
+
+ ); +}