first commit

This commit is contained in:
1lAaN 2026-11-13 13:57:04 +01:00
commit 32e1970a5a
13078 changed files with 2477284 additions and 0 deletions

18
.nuxt/app.config.mjs Normal file
View file

@ -0,0 +1,18 @@
import { _replaceAppConfig } from '#app/config'
import { defuFn } from 'defu'
const inlineConfig = {
"nuxt": {}
}
// Vite - webpack is handled directly in #app/config
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
_replaceAppConfig(newModule.default)
})
}
export default /*@__PURE__*/ defuFn(inlineConfig)

88
.nuxt/components.d.ts vendored Normal file
View file

@ -0,0 +1,88 @@
import type { DefineComponent, SlotsType } from 'vue'
type IslandComponent<T> = DefineComponent<{}, {refresh: () => Promise<void>}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, SlotsType<{ fallback: { error: unknown } }>> & T
type HydrationStrategies = {
hydrateOnVisible?: IntersectionObserverInit | true
hydrateOnIdle?: number | true
hydrateOnInteraction?: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap> | true
hydrateOnMediaQuery?: string
hydrateAfter?: number
hydrateWhen?: boolean
hydrateNever?: true
}
type LazyComponent<T> = DefineComponent<HydrationStrategies, {}, {}, {}, {}, {}, {}, { hydrated: () => void }> & T
export const CartSummary: typeof import("../components/CartSummary.vue")['default']
export const CustomizeModal: typeof import("../components/CustomizeModal.vue")['default']
export const DishCard: typeof import("../components/DishCard.vue")['default']
export const DishPhoto: typeof import("../components/DishPhoto.vue")['default']
export const Icon: typeof import("../components/Icon.vue")['default']
export const LeafMonstera: typeof import("../components/LeafMonstera.vue")['default']
export const LeafPalm: typeof import("../components/LeafPalm.vue")['default']
export const Logo: typeof import("../components/Logo.vue")['default']
export const MobileBar: typeof import("../components/MobileBar.vue")['default']
export const SiteFooter: typeof import("../components/SiteFooter.vue")['default']
export const SiteHeader: typeof import("../components/SiteHeader.vue")['default']
export const Toucan: typeof import("../components/Toucan.vue")['default']
export const NuxtWelcome: typeof import("../node_modules/nuxt/dist/app/components/welcome.vue")['default']
export const NuxtLayout: typeof import("../node_modules/nuxt/dist/app/components/nuxt-layout")['default']
export const NuxtErrorBoundary: typeof import("../node_modules/nuxt/dist/app/components/nuxt-error-boundary.vue")['default']
export const ClientOnly: typeof import("../node_modules/nuxt/dist/app/components/client-only")['default']
export const DevOnly: typeof import("../node_modules/nuxt/dist/app/components/dev-only")['default']
export const ServerPlaceholder: typeof import("../node_modules/nuxt/dist/app/components/server-placeholder")['default']
export const NuxtLink: typeof import("../node_modules/nuxt/dist/app/components/nuxt-link")['default']
export const NuxtLoadingIndicator: typeof import("../node_modules/nuxt/dist/app/components/nuxt-loading-indicator")['default']
export const NuxtTime: typeof import("../node_modules/nuxt/dist/app/components/nuxt-time.vue")['default']
export const NuxtRouteAnnouncer: typeof import("../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']
export const NuxtImg: typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']
export const NuxtPicture: typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']
export const NuxtPage: typeof import("../node_modules/nuxt/dist/pages/runtime/page")['default']
export const NoScript: typeof import("../node_modules/nuxt/dist/head/runtime/components")['NoScript']
export const Link: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Link']
export const Base: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Base']
export const Title: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Title']
export const Meta: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Meta']
export const Style: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Style']
export const Head: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Head']
export const Html: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Html']
export const Body: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Body']
export const NuxtIsland: typeof import("../node_modules/nuxt/dist/app/components/nuxt-island")['default']
export const LazyCartSummary: LazyComponent<typeof import("../components/CartSummary.vue")['default']>
export const LazyCustomizeModal: LazyComponent<typeof import("../components/CustomizeModal.vue")['default']>
export const LazyDishCard: LazyComponent<typeof import("../components/DishCard.vue")['default']>
export const LazyDishPhoto: LazyComponent<typeof import("../components/DishPhoto.vue")['default']>
export const LazyIcon: LazyComponent<typeof import("../components/Icon.vue")['default']>
export const LazyLeafMonstera: LazyComponent<typeof import("../components/LeafMonstera.vue")['default']>
export const LazyLeafPalm: LazyComponent<typeof import("../components/LeafPalm.vue")['default']>
export const LazyLogo: LazyComponent<typeof import("../components/Logo.vue")['default']>
export const LazyMobileBar: LazyComponent<typeof import("../components/MobileBar.vue")['default']>
export const LazySiteFooter: LazyComponent<typeof import("../components/SiteFooter.vue")['default']>
export const LazySiteHeader: LazyComponent<typeof import("../components/SiteHeader.vue")['default']>
export const LazyToucan: LazyComponent<typeof import("../components/Toucan.vue")['default']>
export const LazyNuxtWelcome: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/welcome.vue")['default']>
export const LazyNuxtLayout: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-layout")['default']>
export const LazyNuxtErrorBoundary: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-error-boundary.vue")['default']>
export const LazyClientOnly: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/client-only")['default']>
export const LazyDevOnly: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/dev-only")['default']>
export const LazyServerPlaceholder: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/server-placeholder")['default']>
export const LazyNuxtLink: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-link")['default']>
export const LazyNuxtLoadingIndicator: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-loading-indicator")['default']>
export const LazyNuxtTime: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-time.vue")['default']>
export const LazyNuxtRouteAnnouncer: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']>
export const LazyNuxtImg: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']>
export const LazyNuxtPicture: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']>
export const LazyNuxtPage: LazyComponent<typeof import("../node_modules/nuxt/dist/pages/runtime/page")['default']>
export const LazyNoScript: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['NoScript']>
export const LazyLink: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Link']>
export const LazyBase: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Base']>
export const LazyTitle: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Title']>
export const LazyMeta: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Meta']>
export const LazyStyle: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Style']>
export const LazyHead: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Head']>
export const LazyHtml: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Html']>
export const LazyBody: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Body']>
export const LazyNuxtIsland: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-island")['default']>
export const componentNames: string[]

4006
.nuxt/dev/index.mjs Normal file

File diff suppressed because it is too large Load diff

1
.nuxt/dev/index.mjs.map Normal file

File diff suppressed because one or more lines are too long

1
.nuxt/dist/server/client.manifest.mjs vendored Normal file
View file

@ -0,0 +1 @@
export default ({"@vite/client":{prefetch:!0,isEntry:!0,file:"@vite/client",css:[],module:!0,resourceType:"script",dynamicImports:void 0},"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,isEntry:!0,file:"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js",dynamicImports:void 0}})

View file

@ -0,0 +1 @@
export default (h=>({dependencies:{"@vite/client":{scripts:{"@vite/client":{prefetch:!0,isEntry:!0,file:"@vite/client",css:[],module:!0,resourceType:"script",dynamicImports:void 0}},styles:{},preload:{},prefetch:{}},"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js":{scripts:{"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js":h={resourceType:"script",module:!0,prefetch:!0,preload:!0,isEntry:!0,file:"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js",dynamicImports:void 0}},styles:{},preload:{"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js":h},prefetch:{}}},entrypoints:["@vite/client","/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js"],modules:{"@vite/client":{file:"@vite/client",resourceType:"script",mimeType:void 0,module:!0},"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js":{file:"/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/nuxt/dist/app/entry.js",resourceType:"script",mimeType:void 0,module:!0}},resourceCount:2}))()

38
.nuxt/imports.d.ts vendored Normal file
View file

@ -0,0 +1,38 @@
export { useScriptTriggerConsent, useScriptEventPage, useScriptTriggerElement, useScript, useScriptGoogleAnalytics, useScriptPlausibleAnalytics, useScriptCrisp, useScriptClarity, useScriptCloudflareWebAnalytics, useScriptVercelAnalytics, useScriptPostHog, useScriptFathomAnalytics, useScriptMatomoAnalytics, useScriptMixpanelAnalytics, useScriptBingUet, useScriptGoogleTagManager, useScriptGoogleAdsense, useScriptGoogleRecaptcha, useScriptGoogleSignIn, useScriptSegment, useScriptMetaPixel, useScriptXPixel, useScriptTikTokPixel, useScriptIntercom, useScriptHotjar, useScriptStripe, useScriptLemonSqueezy, useScriptVimeoPlayer, useScriptYouTubePlayer, useScriptGoogleMaps, useScriptNpm, useScriptUmamiAnalytics, useScriptSnapchatPixel, useScriptRybbitAnalytics, useScriptDatabuddyAnalytics, useScriptRedditPixel, useScriptPayPal, useScriptGravatar, useScriptAhrefsAnalytics, useScriptCalendly, useScriptLinkedInInsight, useScriptUsercentrics, useScriptSpeedCurve } from '#app/composables/script-stubs';
export { isVue2, isVue3 } from 'vue-demi';
export { defineNuxtLink } from '#app/components/nuxt-link';
export { useNuxtApp, tryUseNuxtApp, defineNuxtPlugin, definePayloadPlugin, useRuntimeConfig, defineAppConfig } from '#app/nuxt';
export { useAppConfig, updateAppConfig } from '#app/config';
export { defineNuxtComponent } from '#app/composables/component';
export { useAsyncData, useLazyAsyncData, useNuxtData, refreshNuxtData, clearNuxtData } from '#app/composables/asyncData';
export { useHydration } from '#app/composables/hydrate';
export { callOnce } from '#app/composables/once';
export { useState, clearNuxtState } from '#app/composables/state';
export { clearError, createError, isNuxtError, showError, useError } from '#app/composables/error';
export { useFetch, useLazyFetch } from '#app/composables/fetch';
export { useCookie, refreshCookie } from '#app/composables/cookie';
export { onPrehydrate, prerenderRoutes, useRequestHeader, useRequestHeaders, useResponseHeader, useRequestEvent, useRequestFetch, setResponseStatus } from '#app/composables/ssr';
export { onNuxtReady } from '#app/composables/ready';
export { preloadComponents, prefetchComponents, preloadRouteComponents } from '#app/composables/preload';
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, setPageLayout, navigateTo, useRoute, useRouter } from '#app/composables/router';
export { isPrerendered, loadPayload, preloadPayload, definePayloadReducer, definePayloadReviver } from '#app/composables/payload';
export { useLoadingIndicator } from '#app/composables/loading-indicator';
export { getAppManifest, getRouteRules } from '#app/composables/manifest';
export { reloadNuxtApp } from '#app/composables/chunk';
export { useRequestURL } from '#app/composables/url';
export { usePreviewMode } from '#app/composables/preview';
export { useRouteAnnouncer } from '#app/composables/route-announcer';
export { useRuntimeHook } from '#app/composables/runtime-hook';
export { useHead, useHeadSafe, useServerHeadSafe, useServerHead, useSeoMeta, useServerSeoMeta, injectHead } from '#app/composables/head';
export { onBeforeRouteLeave, onBeforeRouteUpdate, useLink } from 'vue-router';
export { withCtx, withDirectives, withKeys, withMemo, withModifiers, withScopeId, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onServerPrefetch, onUnmounted, onUpdated, computed, customRef, isProxy, isReactive, isReadonly, isRef, markRaw, proxyRefs, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, watch, watchEffect, watchPostEffect, watchSyncEffect, onWatcherCleanup, isShallow, effect, effectScope, getCurrentScope, onScopeDispose, defineComponent, defineAsyncComponent, resolveComponent, getCurrentInstance, h, inject, hasInjectionContext, nextTick, provide, toValue, useModel, useAttrs, useCssModule, useSlots, useTransitionState, useId, useTemplateRef, useShadowRoot, useCssVars, Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue';
export { requestIdleCallback, cancelIdleCallback } from '#app/compat/idle-callback';
export { setInterval } from '#app/compat/interval';
export { definePageMeta } from '../node_modules/nuxt/dist/pages/runtime/composables';
export { defineLazyHydrationComponent } from '#app/composables/lazy-hydration';
export { useOrders, useAdminSettings, orderAction, saveSettings, unlockSound, ding } from '../composables/useAdmin';
export { useCart, useCustomize, CartLine } from '../composables/useCart';
export { useShop, priceOf, sizesOf, orderable } from '../composables/useShop';
export { useToast } from '../composables/useToast';
export { eur, hhmm, payLabel } from '../utils/format';
export { printTicket } from '../utils/ticket';

View file

@ -0,0 +1 @@
{"id":"dev","timestamp":1794563310711}

View file

@ -0,0 +1 @@
{"id":"dev","timestamp":1794563310711,"prerendered":[]}

17
.nuxt/nitro.json Normal file
View file

@ -0,0 +1,17 @@
{
"date": "2026-11-13T09:48:33.080Z",
"preset": "nitro-dev",
"framework": {
"name": "nuxt",
"version": "3.21.10"
},
"versions": {
"nitro": "2.13.5"
},
"dev": {
"pid": 86369,
"workerAddress": {
"socketPath": "/var/folders/yl/bqcq2f6j7c3_11k9hy_52fv00000gn/T/nitro-worker-86369-1-1-6874.sock"
}
}
}

22
.nuxt/nuxt.d.ts vendored Normal file
View file

@ -0,0 +1,22 @@
/// <reference types="@nuxt/telemetry" />
/// <reference path="types/nitro-layouts.d.ts" />
/// <reference path="types/builder-env.d.ts" />
/// <reference types="nuxt" />
/// <reference path="types/app-defaults.d.ts" />
/// <reference path="types/plugins.d.ts" />
/// <reference path="types/build.d.ts" />
/// <reference path="types/schema.d.ts" />
/// <reference path="types/app.config.d.ts" />
/// <reference path="../node_modules/@nuxt/vite-builder/dist/index.d.mts" />
/// <reference path="../node_modules/@nuxt/nitro-server/dist/index.d.mts" />
/// <reference path="types/layouts.d.ts" />
/// <reference types="vue-router" />
/// <reference path="types/middleware.d.ts" />
/// <reference path="types/nitro-middleware.d.ts" />
/// <reference path="types/components.d.ts" />
/// <reference path="imports.d.ts" />
/// <reference path="types/imports.d.ts" />
/// <reference path="schema/nuxt.schema.d.ts" />
/// <reference path="types/nitro.d.ts" />
export {}

9
.nuxt/nuxt.json Normal file
View file

@ -0,0 +1,9 @@
{
"_hash": "tXXXbcKELZa149FjFbwsE5XuxvLllqPGRpndIhtV_C8",
"project": {
"rootDir": "/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo"
},
"versions": {
"nuxt": "3.21.10"
}
}

17
.nuxt/schema/nuxt.schema.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
export interface NuxtCustomSchema {
}
export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined>
type _CustomAppConfig = CustomAppConfig
declare module '@nuxt/schema' {
interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends _CustomAppConfig {}
}
declare module 'nuxt/schema' {
interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends _CustomAppConfig {}
}

View file

@ -0,0 +1,3 @@
{
"id": "#"
}

176
.nuxt/tsconfig.json Normal file
View file

@ -0,0 +1,176 @@
{
"compilerOptions": {
"paths": {
"nuxt": [
"../node_modules/nuxt"
],
"@unhead/vue": [
"../node_modules/@unhead/vue"
],
"@nuxt/devtools": [
"../node_modules/@nuxt/devtools"
],
"@vue/runtime-core": [
"../node_modules/@vue/runtime-core"
],
"@vue/compiler-sfc": [
"../node_modules/@vue/compiler-sfc"
],
"@nuxt/schema": [
"../node_modules/@nuxt/schema"
],
"defu": [
"../node_modules/defu"
],
"h3": [
"../node_modules/h3"
],
"consola": [
"../node_modules/consola"
],
"ofetch": [
"../node_modules/ofetch"
],
"crossws": [
"../node_modules/crossws"
],
"unplugin-vue-router/client": [
"../node_modules/unplugin-vue-router/client"
],
"nitropack": [
"../node_modules/nitropack"
],
"vite/client": [
"../node_modules/vite/client"
],
"nitropack/types": [
"../node_modules/nitropack/types"
],
"nitropack/runtime": [
"../node_modules/nitropack/runtime"
],
"~": [
".."
],
"~/*": [
"../*"
],
"@": [
".."
],
"@/*": [
"../*"
],
"~~": [
".."
],
"~~/*": [
"../*"
],
"@@": [
".."
],
"@@/*": [
"../*"
],
"#shared": [
"../shared"
],
"#shared/*": [
"../shared/*"
],
"assets": [
"../assets"
],
"assets/*": [
"../assets/*"
],
"public": [
"../public"
],
"public/*": [
"../public/*"
],
"#server": [
"../server"
],
"#server/*": [
"../server/*"
],
"#app": [
"../node_modules/nuxt/dist/app"
],
"#app/*": [
"../node_modules/nuxt/dist/app/*"
],
"vue-demi": [
"../node_modules/nuxt/dist/app/compat/vue-demi"
],
"#vue-router": [
"../node_modules/vue-router"
],
"#unhead/composables": [
"../node_modules/nuxt/dist/head/runtime/composables/v3"
],
"#imports": [
"./imports"
],
"#app-manifest": [
"./manifest/meta/dev.json"
],
"#components": [
"./components"
],
"#build": [
"."
],
"#build/*": [
"./*"
]
},
"esModuleInterop": true,
"skipLibCheck": true,
"target": "ESNext",
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
"verbatimModuleSyntax": true,
"allowArbitraryExtensions": true,
"strict": true,
"noUncheckedIndexedAccess": false,
"forceConsistentCasingInFileNames": true,
"noImplicitOverride": true,
"module": "ESNext",
"noEmit": true,
"lib": [
"ESNext",
"dom",
"dom.iterable",
"webworker"
],
"jsx": "preserve",
"jsxImportSource": "vue",
"types": [],
"moduleResolution": "Bundler",
"useDefineForClassFields": true,
"noImplicitThis": true,
"allowSyntheticDefaultImports": true
},
"include": [
"../**/*",
"../.config/nuxt.*",
"./nuxt.d.ts",
"../node_modules/runtime",
"../node_modules/dist/runtime",
".."
],
"exclude": [
"../dist",
"../.data",
"../../../../../../node_modules",
"../node_modules/runtime/server",
"../node_modules/dist/runtime/server",
"dev"
]
}

141
.nuxt/tsconfig.server.json Normal file
View file

@ -0,0 +1,141 @@
{
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"allowJs": true,
"resolveJsonModule": true,
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"paths": {
"#imports": [
"./types/nitro-imports"
],
"~/*": [
"../*"
],
"@/*": [
"../*"
],
"~~/*": [
"../*"
],
"@@/*": [
"../*"
],
"nuxt": [
"../node_modules/nuxt"
],
"@unhead/vue": [
"../node_modules/@unhead/vue"
],
"@nuxt/devtools": [
"../node_modules/@nuxt/devtools"
],
"@vue/runtime-core": [
"../node_modules/@vue/runtime-core"
],
"@vue/compiler-sfc": [
"../node_modules/@vue/compiler-sfc"
],
"@nuxt/schema": [
"../node_modules/@nuxt/schema"
],
"defu": [
"../node_modules/defu"
],
"h3": [
"../node_modules/h3"
],
"consola": [
"../node_modules/consola"
],
"ofetch": [
"../node_modules/ofetch"
],
"crossws": [
"../node_modules/crossws"
],
"unplugin-vue-router/client": [
"../node_modules/unplugin-vue-router/client"
],
"nitropack": [
"../node_modules/nitropack"
],
"vite/client": [
"../node_modules/vite/client"
],
"nitropack/types": [
"../node_modules/nitropack/types"
],
"nitropack/runtime": [
"../node_modules/nitropack/runtime"
],
"#shared": [
"../shared"
],
"#shared/*": [
"../shared/*"
],
"assets": [
"../assets"
],
"assets/*": [
"../assets/*"
],
"public": [
"../public"
],
"public/*": [
"../public/*"
],
"#server": [
"../server"
],
"#server/*": [
"../server/*"
],
"#build": [
"./"
],
"#build/*": [
"./*"
],
"#internal/nuxt/paths": [
"../node_modules/@nuxt/nitro-server/dist/runtime/utils/paths"
],
"#unhead/composables": [
"../node_modules/nuxt/dist/head/runtime/composables/v3"
]
},
"lib": [
"esnext",
"webworker",
"dom.iterable"
],
"noUncheckedIndexedAccess": true,
"allowArbitraryExtensions": true
},
"include": [
"./types/nitro-nuxt.d.ts",
"../node_modules/runtime/server",
"../node_modules/dist/runtime/server",
"../server/**/*",
"../shared/**/*.d.ts",
"./types/nitro.d.ts",
"../**/*"
],
"exclude": [
"../node_modules",
"../../../../../../node_modules",
"../node_modules/nuxt/node_modules",
"../node_modules/@nuxt/telemetry/node_modules",
"../dist"
]
}

7
.nuxt/types/app-defaults.d.ts vendored Normal file
View file

@ -0,0 +1,7 @@
declare module 'nuxt/app/defaults' {
type DefaultAsyncDataErrorValue = null
type DefaultAsyncDataValue = null
type DefaultErrorValue = null
type DedupeOption = boolean | 'cancel' | 'defer'
}

31
.nuxt/types/app.config.d.ts vendored Normal file
View file

@ -0,0 +1,31 @@
import type { CustomAppConfig } from 'nuxt/schema'
import type { Defu } from 'defu'
declare const inlineConfig = {
"nuxt": {}
}
type ResolvedAppConfig = Defu<typeof inlineConfig, []>
type IsAny<T> = 0 extends 1 & T ? true : false
type MergedAppConfig<Resolved extends Record<string, unknown>, Custom extends Record<string, unknown>> = {
[K in keyof (Resolved & Custom)]: K extends keyof Custom
? unknown extends Custom[K]
? Resolved[K]
: IsAny<Custom[K]> extends true
? Resolved[K]
: Custom[K] extends Record<string, any>
? Resolved[K] extends Record<string, any>
? MergedAppConfig<Resolved[K], Custom[K]>
: Exclude<Custom[K], undefined>
: Exclude<Custom[K], undefined>
: Resolved[K]
}
declare module 'nuxt/schema' {
interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
declare module '@nuxt/schema' {
interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}

24
.nuxt/types/build.d.ts vendored Normal file
View file

@ -0,0 +1,24 @@
declare module "#build/app-component.mjs";
declare module "#build/nitro.client.mjs";
declare module "#build/plugins.client.mjs";
declare module "#build/css.mjs";
declare module "#build/fetch.mjs";
declare module "#build/error-component.mjs";
declare module "#build/global-polyfills.mjs";
declare module "#build/layouts.mjs";
declare module "#build/middleware.mjs";
declare module "#build/nuxt.config.mjs";
declare module "#build/paths.mjs";
declare module "#build/root-component.mjs";
declare module "#build/plugins.server.mjs";
declare module "#build/test-component-wrapper.mjs";
declare module "#build/routes.mjs";
declare module "#build/pages.mjs";
declare module "#build/router.options.mjs";
declare module "#build/unhead-options.mjs";
declare module "#build/unhead.config.mjs";
declare module "#build/components.plugin.mjs";
declare module "#build/component-names.mjs";
declare module "#build/components.islands.mjs";
declare module "#build/component-chunk.mjs";
declare module "#build/route-rules.mjs";

1
.nuxt/types/builder-env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
import "vite/client";

93
.nuxt/types/components.d.ts vendored Normal file
View file

@ -0,0 +1,93 @@
import type { DefineComponent, SlotsType } from 'vue'
type IslandComponent<T> = DefineComponent<{}, {refresh: () => Promise<void>}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, SlotsType<{ fallback: { error: unknown } }>> & T
type HydrationStrategies = {
hydrateOnVisible?: IntersectionObserverInit | true
hydrateOnIdle?: number | true
hydrateOnInteraction?: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap> | true
hydrateOnMediaQuery?: string
hydrateAfter?: number
hydrateWhen?: boolean
hydrateNever?: true
}
type LazyComponent<T> = DefineComponent<HydrationStrategies, {}, {}, {}, {}, {}, {}, { hydrated: () => void }> & T
interface _GlobalComponents {
CartSummary: typeof import("../../components/CartSummary.vue")['default']
CustomizeModal: typeof import("../../components/CustomizeModal.vue")['default']
DishCard: typeof import("../../components/DishCard.vue")['default']
DishPhoto: typeof import("../../components/DishPhoto.vue")['default']
Icon: typeof import("../../components/Icon.vue")['default']
LeafMonstera: typeof import("../../components/LeafMonstera.vue")['default']
LeafPalm: typeof import("../../components/LeafPalm.vue")['default']
Logo: typeof import("../../components/Logo.vue")['default']
MobileBar: typeof import("../../components/MobileBar.vue")['default']
SiteFooter: typeof import("../../components/SiteFooter.vue")['default']
SiteHeader: typeof import("../../components/SiteHeader.vue")['default']
Toucan: typeof import("../../components/Toucan.vue")['default']
NuxtWelcome: typeof import("../../node_modules/nuxt/dist/app/components/welcome.vue")['default']
NuxtLayout: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-layout")['default']
NuxtErrorBoundary: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-error-boundary.vue")['default']
ClientOnly: typeof import("../../node_modules/nuxt/dist/app/components/client-only")['default']
DevOnly: typeof import("../../node_modules/nuxt/dist/app/components/dev-only")['default']
ServerPlaceholder: typeof import("../../node_modules/nuxt/dist/app/components/server-placeholder")['default']
NuxtLink: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-link")['default']
NuxtLoadingIndicator: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-loading-indicator")['default']
NuxtTime: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-time.vue")['default']
NuxtRouteAnnouncer: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']
NuxtImg: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']
NuxtPicture: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']
NuxtPage: typeof import("../../node_modules/nuxt/dist/pages/runtime/page")['default']
NoScript: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['NoScript']
Link: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Link']
Base: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Base']
Title: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Title']
Meta: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Meta']
Style: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Style']
Head: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Head']
Html: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Html']
Body: typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Body']
NuxtIsland: typeof import("../../node_modules/nuxt/dist/app/components/nuxt-island")['default']
LazyCartSummary: LazyComponent<typeof import("../../components/CartSummary.vue")['default']>
LazyCustomizeModal: LazyComponent<typeof import("../../components/CustomizeModal.vue")['default']>
LazyDishCard: LazyComponent<typeof import("../../components/DishCard.vue")['default']>
LazyDishPhoto: LazyComponent<typeof import("../../components/DishPhoto.vue")['default']>
LazyIcon: LazyComponent<typeof import("../../components/Icon.vue")['default']>
LazyLeafMonstera: LazyComponent<typeof import("../../components/LeafMonstera.vue")['default']>
LazyLeafPalm: LazyComponent<typeof import("../../components/LeafPalm.vue")['default']>
LazyLogo: LazyComponent<typeof import("../../components/Logo.vue")['default']>
LazyMobileBar: LazyComponent<typeof import("../../components/MobileBar.vue")['default']>
LazySiteFooter: LazyComponent<typeof import("../../components/SiteFooter.vue")['default']>
LazySiteHeader: LazyComponent<typeof import("../../components/SiteHeader.vue")['default']>
LazyToucan: LazyComponent<typeof import("../../components/Toucan.vue")['default']>
LazyNuxtWelcome: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/welcome.vue")['default']>
LazyNuxtLayout: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-layout")['default']>
LazyNuxtErrorBoundary: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-error-boundary.vue")['default']>
LazyClientOnly: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/client-only")['default']>
LazyDevOnly: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/dev-only")['default']>
LazyServerPlaceholder: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/server-placeholder")['default']>
LazyNuxtLink: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-link")['default']>
LazyNuxtLoadingIndicator: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-loading-indicator")['default']>
LazyNuxtTime: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-time.vue")['default']>
LazyNuxtRouteAnnouncer: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']>
LazyNuxtImg: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']>
LazyNuxtPicture: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']>
LazyNuxtPage: LazyComponent<typeof import("../../node_modules/nuxt/dist/pages/runtime/page")['default']>
LazyNoScript: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['NoScript']>
LazyLink: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Link']>
LazyBase: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Base']>
LazyTitle: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Title']>
LazyMeta: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Meta']>
LazyStyle: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Style']>
LazyHead: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Head']>
LazyHtml: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Html']>
LazyBody: LazyComponent<typeof import("../../node_modules/nuxt/dist/head/runtime/components")['Body']>
LazyNuxtIsland: LazyComponent<typeof import("../../node_modules/nuxt/dist/app/components/nuxt-island")['default']>
}
declare module 'vue' {
export interface GlobalComponents extends _GlobalComponents { }
}
export {}

425
.nuxt/types/imports.d.ts vendored Normal file
View file

@ -0,0 +1,425 @@
// Generated by auto imports
export {}
declare global {
const abortNavigation: typeof import('../../node_modules/nuxt/dist/app/composables/router').abortNavigation
const addRouteMiddleware: typeof import('../../node_modules/nuxt/dist/app/composables/router').addRouteMiddleware
const callOnce: typeof import('../../node_modules/nuxt/dist/app/composables/once').callOnce
const cancelIdleCallback: typeof import('../../node_modules/nuxt/dist/app/compat/idle-callback').cancelIdleCallback
const clearError: typeof import('../../node_modules/nuxt/dist/app/composables/error').clearError
const clearNuxtData: typeof import('../../node_modules/nuxt/dist/app/composables/asyncData').clearNuxtData
const clearNuxtState: typeof import('../../node_modules/nuxt/dist/app/composables/state').clearNuxtState
const computed: typeof import('vue').computed
const createError: typeof import('../../node_modules/nuxt/dist/app/composables/error').createError
const customRef: typeof import('vue').customRef
const defineAppConfig: typeof import('../../node_modules/nuxt/dist/app/nuxt').defineAppConfig
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
const defineComponent: typeof import('vue').defineComponent
const defineLazyHydrationComponent: typeof import('../../node_modules/nuxt/dist/app/composables/lazy-hydration').defineLazyHydrationComponent
const defineNuxtComponent: typeof import('../../node_modules/nuxt/dist/app/composables/component').defineNuxtComponent
const defineNuxtLink: typeof import('../../node_modules/nuxt/dist/app/components/nuxt-link').defineNuxtLink
const defineNuxtPlugin: typeof import('../../node_modules/nuxt/dist/app/nuxt').defineNuxtPlugin
const defineNuxtRouteMiddleware: typeof import('../../node_modules/nuxt/dist/app/composables/router').defineNuxtRouteMiddleware
const definePageMeta: typeof import('../../node_modules/nuxt/dist/pages/runtime/composables').definePageMeta
const definePayloadPlugin: typeof import('../../node_modules/nuxt/dist/app/nuxt').definePayloadPlugin
const definePayloadReducer: typeof import('../../node_modules/nuxt/dist/app/composables/payload').definePayloadReducer
const definePayloadReviver: typeof import('../../node_modules/nuxt/dist/app/composables/payload').definePayloadReviver
const ding: typeof import('../../composables/useAdmin').ding
const effect: typeof import('vue').effect
const effectScope: typeof import('vue').effectScope
const eur: typeof import('../../utils/format').eur
const getAppManifest: typeof import('../../node_modules/nuxt/dist/app/composables/manifest').getAppManifest
const getCurrentInstance: typeof import('vue').getCurrentInstance
const getCurrentScope: typeof import('vue').getCurrentScope
const getRouteRules: typeof import('../../node_modules/nuxt/dist/app/composables/manifest').getRouteRules
const h: typeof import('vue').h
const hasInjectionContext: typeof import('vue').hasInjectionContext
const hhmm: typeof import('../../utils/format').hhmm
const inject: typeof import('vue').inject
const injectHead: typeof import('../../node_modules/nuxt/dist/app/composables/head').injectHead
const isNuxtError: typeof import('../../node_modules/nuxt/dist/app/composables/error').isNuxtError
const isPrerendered: typeof import('../../node_modules/nuxt/dist/app/composables/payload').isPrerendered
const isProxy: typeof import('vue').isProxy
const isReactive: typeof import('vue').isReactive
const isReadonly: typeof import('vue').isReadonly
const isRef: typeof import('vue').isRef
const isShallow: typeof import('vue').isShallow
const isVue2: typeof import('../../node_modules/nuxt/dist/app/compat/vue-demi').isVue2
const isVue3: typeof import('../../node_modules/nuxt/dist/app/compat/vue-demi').isVue3
const loadPayload: typeof import('../../node_modules/nuxt/dist/app/composables/payload').loadPayload
const markRaw: typeof import('vue').markRaw
const navigateTo: typeof import('../../node_modules/nuxt/dist/app/composables/router').navigateTo
const nextTick: typeof import('vue').nextTick
const onActivated: typeof import('vue').onActivated
const onBeforeMount: typeof import('vue').onBeforeMount
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
const onDeactivated: typeof import('vue').onDeactivated
const onErrorCaptured: typeof import('vue').onErrorCaptured
const onMounted: typeof import('vue').onMounted
const onNuxtReady: typeof import('../../node_modules/nuxt/dist/app/composables/ready').onNuxtReady
const onPrehydrate: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').onPrehydrate
const onRenderTracked: typeof import('vue').onRenderTracked
const onRenderTriggered: typeof import('vue').onRenderTriggered
const onScopeDispose: typeof import('vue').onScopeDispose
const onServerPrefetch: typeof import('vue').onServerPrefetch
const onUnmounted: typeof import('vue').onUnmounted
const onUpdated: typeof import('vue').onUpdated
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
const orderAction: typeof import('../../composables/useAdmin').orderAction
const orderable: typeof import('../../composables/useShop').orderable
const payLabel: typeof import('../../utils/format').payLabel
const prefetchComponents: typeof import('../../node_modules/nuxt/dist/app/composables/preload').prefetchComponents
const preloadComponents: typeof import('../../node_modules/nuxt/dist/app/composables/preload').preloadComponents
const preloadPayload: typeof import('../../node_modules/nuxt/dist/app/composables/payload').preloadPayload
const preloadRouteComponents: typeof import('../../node_modules/nuxt/dist/app/composables/preload').preloadRouteComponents
const prerenderRoutes: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').prerenderRoutes
const priceOf: typeof import('../../composables/useShop').priceOf
const printTicket: typeof import('../../utils/ticket').printTicket
const provide: typeof import('vue').provide
const proxyRefs: typeof import('vue').proxyRefs
const reactive: typeof import('vue').reactive
const readonly: typeof import('vue').readonly
const ref: typeof import('vue').ref
const refreshCookie: typeof import('../../node_modules/nuxt/dist/app/composables/cookie').refreshCookie
const refreshNuxtData: typeof import('../../node_modules/nuxt/dist/app/composables/asyncData').refreshNuxtData
const reloadNuxtApp: typeof import('../../node_modules/nuxt/dist/app/composables/chunk').reloadNuxtApp
const requestIdleCallback: typeof import('../../node_modules/nuxt/dist/app/compat/idle-callback').requestIdleCallback
const resolveComponent: typeof import('vue').resolveComponent
const saveSettings: typeof import('../../composables/useAdmin').saveSettings
const setInterval: typeof import('../../node_modules/nuxt/dist/app/compat/interval').setInterval
const setPageLayout: typeof import('../../node_modules/nuxt/dist/app/composables/router').setPageLayout
const setResponseStatus: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').setResponseStatus
const shallowReactive: typeof import('vue').shallowReactive
const shallowReadonly: typeof import('vue').shallowReadonly
const shallowRef: typeof import('vue').shallowRef
const showError: typeof import('../../node_modules/nuxt/dist/app/composables/error').showError
const sizesOf: typeof import('../../composables/useShop').sizesOf
const toRaw: typeof import('vue').toRaw
const toRef: typeof import('vue').toRef
const toRefs: typeof import('vue').toRefs
const toValue: typeof import('vue').toValue
const triggerRef: typeof import('vue').triggerRef
const tryUseNuxtApp: typeof import('../../node_modules/nuxt/dist/app/nuxt').tryUseNuxtApp
const unlockSound: typeof import('../../composables/useAdmin').unlockSound
const unref: typeof import('vue').unref
const updateAppConfig: typeof import('../../node_modules/nuxt/dist/app/config').updateAppConfig
const useAdminSettings: typeof import('../../composables/useAdmin').useAdminSettings
const useAppConfig: typeof import('../../node_modules/nuxt/dist/app/config').useAppConfig
const useAsyncData: typeof import('../../node_modules/nuxt/dist/app/composables/asyncData').useAsyncData
const useAttrs: typeof import('vue').useAttrs
const useCart: typeof import('../../composables/useCart').useCart
const useCookie: typeof import('../../node_modules/nuxt/dist/app/composables/cookie').useCookie
const useCssModule: typeof import('vue').useCssModule
const useCssVars: typeof import('vue').useCssVars
const useCustomize: typeof import('../../composables/useCart').useCustomize
const useError: typeof import('../../node_modules/nuxt/dist/app/composables/error').useError
const useFetch: typeof import('../../node_modules/nuxt/dist/app/composables/fetch').useFetch
const useHead: typeof import('../../node_modules/nuxt/dist/app/composables/head').useHead
const useHeadSafe: typeof import('../../node_modules/nuxt/dist/app/composables/head').useHeadSafe
const useHydration: typeof import('../../node_modules/nuxt/dist/app/composables/hydrate').useHydration
const useId: typeof import('vue').useId
const useLazyAsyncData: typeof import('../../node_modules/nuxt/dist/app/composables/asyncData').useLazyAsyncData
const useLazyFetch: typeof import('../../node_modules/nuxt/dist/app/composables/fetch').useLazyFetch
const useLink: typeof import('vue-router').useLink
const useLoadingIndicator: typeof import('../../node_modules/nuxt/dist/app/composables/loading-indicator').useLoadingIndicator
const useModel: typeof import('vue').useModel
const useNuxtApp: typeof import('../../node_modules/nuxt/dist/app/nuxt').useNuxtApp
const useNuxtData: typeof import('../../node_modules/nuxt/dist/app/composables/asyncData').useNuxtData
const useOrders: typeof import('../../composables/useAdmin').useOrders
const usePreviewMode: typeof import('../../node_modules/nuxt/dist/app/composables/preview').usePreviewMode
const useRequestEvent: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').useRequestEvent
const useRequestFetch: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').useRequestFetch
const useRequestHeader: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').useRequestHeader
const useRequestHeaders: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').useRequestHeaders
const useRequestURL: typeof import('../../node_modules/nuxt/dist/app/composables/url').useRequestURL
const useResponseHeader: typeof import('../../node_modules/nuxt/dist/app/composables/ssr').useResponseHeader
const useRoute: typeof import('../../node_modules/nuxt/dist/app/composables/router').useRoute
const useRouteAnnouncer: typeof import('../../node_modules/nuxt/dist/app/composables/route-announcer').useRouteAnnouncer
const useRouter: typeof import('../../node_modules/nuxt/dist/app/composables/router').useRouter
const useRuntimeConfig: typeof import('../../node_modules/nuxt/dist/app/nuxt').useRuntimeConfig
const useRuntimeHook: typeof import('../../node_modules/nuxt/dist/app/composables/runtime-hook').useRuntimeHook
const useScript: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScript
const useScriptAhrefsAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptAhrefsAnalytics
const useScriptBingUet: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptBingUet
const useScriptCalendly: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptCalendly
const useScriptClarity: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptClarity
const useScriptCloudflareWebAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptCloudflareWebAnalytics
const useScriptCrisp: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptCrisp
const useScriptDatabuddyAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptDatabuddyAnalytics
const useScriptEventPage: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptEventPage
const useScriptFathomAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptFathomAnalytics
const useScriptGoogleAdsense: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleAdsense
const useScriptGoogleAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleAnalytics
const useScriptGoogleMaps: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleMaps
const useScriptGoogleRecaptcha: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleRecaptcha
const useScriptGoogleSignIn: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleSignIn
const useScriptGoogleTagManager: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGoogleTagManager
const useScriptGravatar: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptGravatar
const useScriptHotjar: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptHotjar
const useScriptIntercom: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptIntercom
const useScriptLemonSqueezy: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptLemonSqueezy
const useScriptLinkedInInsight: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptLinkedInInsight
const useScriptMatomoAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptMatomoAnalytics
const useScriptMetaPixel: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptMetaPixel
const useScriptMixpanelAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptMixpanelAnalytics
const useScriptNpm: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptNpm
const useScriptPayPal: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptPayPal
const useScriptPlausibleAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptPlausibleAnalytics
const useScriptPostHog: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptPostHog
const useScriptRedditPixel: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptRedditPixel
const useScriptRybbitAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptRybbitAnalytics
const useScriptSegment: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptSegment
const useScriptSnapchatPixel: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptSnapchatPixel
const useScriptSpeedCurve: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptSpeedCurve
const useScriptStripe: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptStripe
const useScriptTikTokPixel: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptTikTokPixel
const useScriptTriggerConsent: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptTriggerConsent
const useScriptTriggerElement: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptTriggerElement
const useScriptUmamiAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptUmamiAnalytics
const useScriptUsercentrics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptUsercentrics
const useScriptVercelAnalytics: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptVercelAnalytics
const useScriptVimeoPlayer: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptVimeoPlayer
const useScriptXPixel: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptXPixel
const useScriptYouTubePlayer: typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs').useScriptYouTubePlayer
const useSeoMeta: typeof import('../../node_modules/nuxt/dist/app/composables/head').useSeoMeta
const useServerHead: typeof import('../../node_modules/nuxt/dist/app/composables/head').useServerHead
const useServerHeadSafe: typeof import('../../node_modules/nuxt/dist/app/composables/head').useServerHeadSafe
const useServerSeoMeta: typeof import('../../node_modules/nuxt/dist/app/composables/head').useServerSeoMeta
const useShadowRoot: typeof import('vue').useShadowRoot
const useShop: typeof import('../../composables/useShop').useShop
const useSlots: typeof import('vue').useSlots
const useState: typeof import('../../node_modules/nuxt/dist/app/composables/state').useState
const useTemplateRef: typeof import('vue').useTemplateRef
const useToast: typeof import('../../composables/useToast').useToast
const useTransitionState: typeof import('vue').useTransitionState
const watch: typeof import('vue').watch
const watchEffect: typeof import('vue').watchEffect
const watchPostEffect: typeof import('vue').watchPostEffect
const watchSyncEffect: typeof import('vue').watchSyncEffect
const withCtx: typeof import('vue').withCtx
const withDirectives: typeof import('vue').withDirectives
const withKeys: typeof import('vue').withKeys
const withMemo: typeof import('vue').withMemo
const withModifiers: typeof import('vue').withModifiers
const withScopeId: typeof import('vue').withScopeId
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
// @ts-ignore
export type { CartLine } from '../../composables/useCart'
import('../../composables/useCart')
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly abortNavigation: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['abortNavigation']>
readonly addRouteMiddleware: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['addRouteMiddleware']>
readonly callOnce: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/once')['callOnce']>
readonly cancelIdleCallback: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/compat/idle-callback')['cancelIdleCallback']>
readonly clearError: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/error')['clearError']>
readonly clearNuxtData: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/asyncData')['clearNuxtData']>
readonly clearNuxtState: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/state')['clearNuxtState']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly createError: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/error')['createError']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly defineAppConfig: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['defineAppConfig']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly defineLazyHydrationComponent: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/lazy-hydration')['defineLazyHydrationComponent']>
readonly defineNuxtComponent: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/component')['defineNuxtComponent']>
readonly defineNuxtLink: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/components/nuxt-link')['defineNuxtLink']>
readonly defineNuxtPlugin: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['defineNuxtPlugin']>
readonly defineNuxtRouteMiddleware: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['defineNuxtRouteMiddleware']>
readonly definePageMeta: UnwrapRef<typeof import('../../node_modules/nuxt/dist/pages/runtime/composables')['definePageMeta']>
readonly definePayloadPlugin: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['definePayloadPlugin']>
readonly definePayloadReducer: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/payload')['definePayloadReducer']>
readonly definePayloadReviver: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/payload')['definePayloadReviver']>
readonly ding: UnwrapRef<typeof import('../../composables/useAdmin')['ding']>
readonly effect: UnwrapRef<typeof import('vue')['effect']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly eur: UnwrapRef<typeof import('../../utils/format')['eur']>
readonly getAppManifest: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/manifest')['getAppManifest']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly getRouteRules: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/manifest')['getRouteRules']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly hasInjectionContext: UnwrapRef<typeof import('vue')['hasInjectionContext']>
readonly hhmm: UnwrapRef<typeof import('../../utils/format')['hhmm']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly injectHead: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['injectHead']>
readonly isNuxtError: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/error')['isNuxtError']>
readonly isPrerendered: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/payload')['isPrerendered']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly isShallow: UnwrapRef<typeof import('vue')['isShallow']>
readonly isVue2: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/compat/vue-demi')['isVue2']>
readonly isVue3: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/compat/vue-demi')['isVue3']>
readonly loadPayload: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/payload')['loadPayload']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly navigateTo: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['navigateTo']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onNuxtReady: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ready')['onNuxtReady']>
readonly onPrehydrate: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['onPrehydrate']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
readonly orderAction: UnwrapRef<typeof import('../../composables/useAdmin')['orderAction']>
readonly orderable: UnwrapRef<typeof import('../../composables/useShop')['orderable']>
readonly payLabel: UnwrapRef<typeof import('../../utils/format')['payLabel']>
readonly prefetchComponents: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/preload')['prefetchComponents']>
readonly preloadComponents: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/preload')['preloadComponents']>
readonly preloadPayload: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/payload')['preloadPayload']>
readonly preloadRouteComponents: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/preload')['preloadRouteComponents']>
readonly prerenderRoutes: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['prerenderRoutes']>
readonly priceOf: UnwrapRef<typeof import('../../composables/useShop')['priceOf']>
readonly printTicket: UnwrapRef<typeof import('../../utils/ticket')['printTicket']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly proxyRefs: UnwrapRef<typeof import('vue')['proxyRefs']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly refreshCookie: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/cookie')['refreshCookie']>
readonly refreshNuxtData: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/asyncData')['refreshNuxtData']>
readonly reloadNuxtApp: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/chunk')['reloadNuxtApp']>
readonly requestIdleCallback: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/compat/idle-callback')['requestIdleCallback']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly saveSettings: UnwrapRef<typeof import('../../composables/useAdmin')['saveSettings']>
readonly setInterval: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/compat/interval')['setInterval']>
readonly setPageLayout: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['setPageLayout']>
readonly setResponseStatus: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['setResponseStatus']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly showError: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/error')['showError']>
readonly sizesOf: UnwrapRef<typeof import('../../composables/useShop')['sizesOf']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryUseNuxtApp: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['tryUseNuxtApp']>
readonly unlockSound: UnwrapRef<typeof import('../../composables/useAdmin')['unlockSound']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly updateAppConfig: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/config')['updateAppConfig']>
readonly useAdminSettings: UnwrapRef<typeof import('../../composables/useAdmin')['useAdminSettings']>
readonly useAppConfig: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/config')['useAppConfig']>
readonly useAsyncData: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/asyncData')['useAsyncData']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCart: UnwrapRef<typeof import('../../composables/useCart')['useCart']>
readonly useCookie: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/cookie')['useCookie']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useCustomize: UnwrapRef<typeof import('../../composables/useCart')['useCustomize']>
readonly useError: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/error')['useError']>
readonly useFetch: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/fetch')['useFetch']>
readonly useHead: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useHead']>
readonly useHeadSafe: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useHeadSafe']>
readonly useHydration: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/hydrate')['useHydration']>
readonly useId: UnwrapRef<typeof import('vue')['useId']>
readonly useLazyAsyncData: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/asyncData')['useLazyAsyncData']>
readonly useLazyFetch: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/fetch')['useLazyFetch']>
readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
readonly useLoadingIndicator: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/loading-indicator')['useLoadingIndicator']>
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useNuxtApp: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['useNuxtApp']>
readonly useNuxtData: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/asyncData')['useNuxtData']>
readonly useOrders: UnwrapRef<typeof import('../../composables/useAdmin')['useOrders']>
readonly usePreviewMode: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/preview')['usePreviewMode']>
readonly useRequestEvent: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['useRequestEvent']>
readonly useRequestFetch: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['useRequestFetch']>
readonly useRequestHeader: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['useRequestHeader']>
readonly useRequestHeaders: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['useRequestHeaders']>
readonly useRequestURL: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/url')['useRequestURL']>
readonly useResponseHeader: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/ssr')['useResponseHeader']>
readonly useRoute: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['useRoute']>
readonly useRouteAnnouncer: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/route-announcer')['useRouteAnnouncer']>
readonly useRouter: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/router')['useRouter']>
readonly useRuntimeConfig: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/nuxt')['useRuntimeConfig']>
readonly useRuntimeHook: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/runtime-hook')['useRuntimeHook']>
readonly useScript: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScript']>
readonly useScriptAhrefsAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptAhrefsAnalytics']>
readonly useScriptBingUet: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptBingUet']>
readonly useScriptCalendly: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptCalendly']>
readonly useScriptClarity: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptClarity']>
readonly useScriptCloudflareWebAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptCloudflareWebAnalytics']>
readonly useScriptCrisp: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptCrisp']>
readonly useScriptDatabuddyAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptDatabuddyAnalytics']>
readonly useScriptEventPage: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptEventPage']>
readonly useScriptFathomAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptFathomAnalytics']>
readonly useScriptGoogleAdsense: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleAdsense']>
readonly useScriptGoogleAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleAnalytics']>
readonly useScriptGoogleMaps: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleMaps']>
readonly useScriptGoogleRecaptcha: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleRecaptcha']>
readonly useScriptGoogleSignIn: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleSignIn']>
readonly useScriptGoogleTagManager: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGoogleTagManager']>
readonly useScriptGravatar: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptGravatar']>
readonly useScriptHotjar: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptHotjar']>
readonly useScriptIntercom: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptIntercom']>
readonly useScriptLemonSqueezy: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptLemonSqueezy']>
readonly useScriptLinkedInInsight: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptLinkedInInsight']>
readonly useScriptMatomoAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptMatomoAnalytics']>
readonly useScriptMetaPixel: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptMetaPixel']>
readonly useScriptMixpanelAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptMixpanelAnalytics']>
readonly useScriptNpm: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptNpm']>
readonly useScriptPayPal: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptPayPal']>
readonly useScriptPlausibleAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptPlausibleAnalytics']>
readonly useScriptPostHog: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptPostHog']>
readonly useScriptRedditPixel: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptRedditPixel']>
readonly useScriptRybbitAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptRybbitAnalytics']>
readonly useScriptSegment: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptSegment']>
readonly useScriptSnapchatPixel: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptSnapchatPixel']>
readonly useScriptSpeedCurve: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptSpeedCurve']>
readonly useScriptStripe: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptStripe']>
readonly useScriptTikTokPixel: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptTikTokPixel']>
readonly useScriptTriggerConsent: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptTriggerConsent']>
readonly useScriptTriggerElement: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptTriggerElement']>
readonly useScriptUmamiAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptUmamiAnalytics']>
readonly useScriptUsercentrics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptUsercentrics']>
readonly useScriptVercelAnalytics: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptVercelAnalytics']>
readonly useScriptVimeoPlayer: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptVimeoPlayer']>
readonly useScriptXPixel: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptXPixel']>
readonly useScriptYouTubePlayer: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/script-stubs')['useScriptYouTubePlayer']>
readonly useSeoMeta: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useSeoMeta']>
readonly useServerHead: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useServerHead']>
readonly useServerHeadSafe: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useServerHeadSafe']>
readonly useServerSeoMeta: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/head')['useServerSeoMeta']>
readonly useShadowRoot: UnwrapRef<typeof import('vue')['useShadowRoot']>
readonly useShop: UnwrapRef<typeof import('../../composables/useShop')['useShop']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useState: UnwrapRef<typeof import('../../node_modules/nuxt/dist/app/composables/state')['useState']>
readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
readonly useToast: UnwrapRef<typeof import('../../composables/useToast')['useToast']>
readonly useTransitionState: UnwrapRef<typeof import('vue')['useTransitionState']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
readonly withCtx: UnwrapRef<typeof import('vue')['withCtx']>
readonly withDirectives: UnwrapRef<typeof import('vue')['withDirectives']>
readonly withKeys: UnwrapRef<typeof import('vue')['withKeys']>
readonly withMemo: UnwrapRef<typeof import('vue')['withMemo']>
readonly withModifiers: UnwrapRef<typeof import('vue')['withModifiers']>
readonly withScopeId: UnwrapRef<typeof import('vue')['withScopeId']>
}
}

16
.nuxt/types/layouts.d.ts vendored Normal file
View file

@ -0,0 +1,16 @@
import type { ComputedRef, MaybeRef } from 'vue'
type ComponentProps<T> = T extends new(...args: any) => { $props: infer P } ? NonNullable<P>
: T extends (props: infer P, ...args: any) => any ? P
: {}
declare module 'nuxt/app' {
interface NuxtLayouts {
admin: ComponentProps<typeof import("/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/layouts/admin.vue").default>,
default: ComponentProps<typeof import("/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/layouts/default.vue").default>,
}
export type LayoutKey = keyof NuxtLayouts extends never ? string : keyof NuxtLayouts
interface PageMeta {
layout?: MaybeRef<LayoutKey | false> | ComputedRef<LayoutKey | false>
}
}

7
.nuxt/types/middleware.d.ts vendored Normal file
View file

@ -0,0 +1,7 @@
import type { NavigationGuard } from 'vue-router'
export type MiddlewareKey = never
declare module 'nuxt/app' {
interface PageMeta {
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
}
}

14
.nuxt/types/nitro-config.d.ts vendored Normal file
View file

@ -0,0 +1,14 @@
// Generated by nitro
// App Config
import type { Defu } from 'defu'
type UserAppConfig = Defu<{}, []>
declare module "nitropack/types" {
interface AppConfig extends UserAppConfig {}
}
export {}

156
.nuxt/types/nitro-imports.d.ts vendored Normal file
View file

@ -0,0 +1,156 @@
declare global {
const H3Error: typeof import('../../node_modules/h3/dist/index').H3Error
const H3Event: typeof import('../../node_modules/h3/dist/index').H3Event
const __buildAssetsURL: typeof import('../../node_modules/@nuxt/nitro-server/dist/runtime/utils/paths').buildAssetsURL
const __publicAssetsURL: typeof import('../../node_modules/@nuxt/nitro-server/dist/runtime/utils/paths').publicAssetsURL
const appendCorsHeaders: typeof import('../../node_modules/h3/dist/index').appendCorsHeaders
const appendCorsPreflightHeaders: typeof import('../../node_modules/h3/dist/index').appendCorsPreflightHeaders
const appendHeader: typeof import('../../node_modules/h3/dist/index').appendHeader
const appendHeaders: typeof import('../../node_modules/h3/dist/index').appendHeaders
const appendResponseHeader: typeof import('../../node_modules/h3/dist/index').appendResponseHeader
const appendResponseHeaders: typeof import('../../node_modules/h3/dist/index').appendResponseHeaders
const assertMethod: typeof import('../../node_modules/h3/dist/index').assertMethod
const cachedEventHandler: typeof import('../../node_modules/nitropack/dist/runtime/internal/cache').cachedEventHandler
const cachedFunction: typeof import('../../node_modules/nitropack/dist/runtime/internal/cache').cachedFunction
const callNodeListener: typeof import('../../node_modules/h3/dist/index').callNodeListener
const clearResponseHeaders: typeof import('../../node_modules/h3/dist/index').clearResponseHeaders
const clearSession: typeof import('../../node_modules/h3/dist/index').clearSession
const createApp: typeof import('../../node_modules/h3/dist/index').createApp
const createAppEventHandler: typeof import('../../node_modules/h3/dist/index').createAppEventHandler
const createError: typeof import('../../node_modules/h3/dist/index').createError
const createEvent: typeof import('../../node_modules/h3/dist/index').createEvent
const createEventStream: typeof import('../../node_modules/h3/dist/index').createEventStream
const createRouter: typeof import('../../node_modules/h3/dist/index').createRouter
const db: typeof import('../../server/utils/store').db
const defaultContentType: typeof import('../../node_modules/h3/dist/index').defaultContentType
const defineAppConfig: typeof import('../../node_modules/@nuxt/nitro-server/dist/runtime/utils/config').defineAppConfig
const defineCachedEventHandler: typeof import('../../node_modules/nitropack/dist/runtime/internal/cache').defineCachedEventHandler
const defineCachedFunction: typeof import('../../node_modules/nitropack/dist/runtime/internal/cache').defineCachedFunction
const defineEventHandler: typeof import('../../node_modules/h3/dist/index').defineEventHandler
const defineLazyEventHandler: typeof import('../../node_modules/h3/dist/index').defineLazyEventHandler
const defineNitroErrorHandler: typeof import('../../node_modules/nitropack/dist/runtime/internal/error/utils').defineNitroErrorHandler
const defineNitroPlugin: typeof import('../../node_modules/nitropack/dist/runtime/internal/plugin').defineNitroPlugin
const defineNodeListener: typeof import('../../node_modules/h3/dist/index').defineNodeListener
const defineNodeMiddleware: typeof import('../../node_modules/h3/dist/index').defineNodeMiddleware
const defineRenderHandler: typeof import('../../node_modules/nitropack/dist/runtime/internal/renderer').defineRenderHandler
const defineRequestMiddleware: typeof import('../../node_modules/h3/dist/index').defineRequestMiddleware
const defineResponseMiddleware: typeof import('../../node_modules/h3/dist/index').defineResponseMiddleware
const defineRouteMeta: typeof import('../../node_modules/nitropack/dist/runtime/internal/meta').defineRouteMeta
const defineTask: typeof import('../../node_modules/nitropack/dist/runtime/internal/task').defineTask
const defineWebSocket: typeof import('../../node_modules/h3/dist/index').defineWebSocket
const defineWebSocketHandler: typeof import('../../node_modules/h3/dist/index').defineWebSocketHandler
const deleteCookie: typeof import('../../node_modules/h3/dist/index').deleteCookie
const dynamicEventHandler: typeof import('../../node_modules/h3/dist/index').dynamicEventHandler
const eventHandler: typeof import('../../node_modules/h3/dist/index').eventHandler
const fetchWithEvent: typeof import('../../node_modules/h3/dist/index').fetchWithEvent
const findOrder: typeof import('../../server/utils/store').findOrder
const fromNodeMiddleware: typeof import('../../node_modules/h3/dist/index').fromNodeMiddleware
const fromPlainHandler: typeof import('../../node_modules/h3/dist/index').fromPlainHandler
const fromWebHandler: typeof import('../../node_modules/h3/dist/index').fromWebHandler
const getCookie: typeof import('../../node_modules/h3/dist/index').getCookie
const getHeader: typeof import('../../node_modules/h3/dist/index').getHeader
const getHeaders: typeof import('../../node_modules/h3/dist/index').getHeaders
const getMethod: typeof import('../../node_modules/h3/dist/index').getMethod
const getProxyRequestHeaders: typeof import('../../node_modules/h3/dist/index').getProxyRequestHeaders
const getQuery: typeof import('../../node_modules/h3/dist/index').getQuery
const getRequestFingerprint: typeof import('../../node_modules/h3/dist/index').getRequestFingerprint
const getRequestHeader: typeof import('../../node_modules/h3/dist/index').getRequestHeader
const getRequestHeaders: typeof import('../../node_modules/h3/dist/index').getRequestHeaders
const getRequestHost: typeof import('../../node_modules/h3/dist/index').getRequestHost
const getRequestIP: typeof import('../../node_modules/h3/dist/index').getRequestIP
const getRequestPath: typeof import('../../node_modules/h3/dist/index').getRequestPath
const getRequestProtocol: typeof import('../../node_modules/h3/dist/index').getRequestProtocol
const getRequestURL: typeof import('../../node_modules/h3/dist/index').getRequestURL
const getRequestWebStream: typeof import('../../node_modules/h3/dist/index').getRequestWebStream
const getResponseHeader: typeof import('../../node_modules/h3/dist/index').getResponseHeader
const getResponseHeaders: typeof import('../../node_modules/h3/dist/index').getResponseHeaders
const getResponseStatus: typeof import('../../node_modules/h3/dist/index').getResponseStatus
const getResponseStatusText: typeof import('../../node_modules/h3/dist/index').getResponseStatusText
const getRouteRules: typeof import('../../node_modules/nitropack/dist/runtime/internal/route-rules').getRouteRules
const getRouterParam: typeof import('../../node_modules/h3/dist/index').getRouterParam
const getRouterParams: typeof import('../../node_modules/h3/dist/index').getRouterParams
const getSession: typeof import('../../node_modules/h3/dist/index').getSession
const getValidatedQuery: typeof import('../../node_modules/h3/dist/index').getValidatedQuery
const getValidatedRouterParams: typeof import('../../node_modules/h3/dist/index').getValidatedRouterParams
const handleCacheHeaders: typeof import('../../node_modules/h3/dist/index').handleCacheHeaders
const handleCors: typeof import('../../node_modules/h3/dist/index').handleCors
const isCorsOriginAllowed: typeof import('../../node_modules/h3/dist/index').isCorsOriginAllowed
const isError: typeof import('../../node_modules/h3/dist/index').isError
const isEvent: typeof import('../../node_modules/h3/dist/index').isEvent
const isEventHandler: typeof import('../../node_modules/h3/dist/index').isEventHandler
const isMethod: typeof import('../../node_modules/h3/dist/index').isMethod
const isPreflightRequest: typeof import('../../node_modules/h3/dist/index').isPreflightRequest
const isStream: typeof import('../../node_modules/h3/dist/index').isStream
const isWebResponse: typeof import('../../node_modules/h3/dist/index').isWebResponse
const lazyEventHandler: typeof import('../../node_modules/h3/dist/index').lazyEventHandler
const nitroPlugin: typeof import('../../node_modules/nitropack/dist/runtime/internal/plugin').nitroPlugin
const parseCookies: typeof import('../../node_modules/h3/dist/index').parseCookies
const promisifyNodeListener: typeof import('../../node_modules/h3/dist/index').promisifyNodeListener
const proxyRequest: typeof import('../../node_modules/h3/dist/index').proxyRequest
const readBody: typeof import('../../node_modules/h3/dist/index').readBody
const readFormData: typeof import('../../node_modules/h3/dist/index').readFormData
const readMultipartFormData: typeof import('../../node_modules/h3/dist/index').readMultipartFormData
const readRawBody: typeof import('../../node_modules/h3/dist/index').readRawBody
const readValidatedBody: typeof import('../../node_modules/h3/dist/index').readValidatedBody
const removeResponseHeader: typeof import('../../node_modules/h3/dist/index').removeResponseHeader
const resetDb: typeof import('../../server/utils/store').resetDb
const runTask: typeof import('../../node_modules/nitropack/dist/runtime/internal/task').runTask
const sanitizeStatusCode: typeof import('../../node_modules/h3/dist/index').sanitizeStatusCode
const sanitizeStatusMessage: typeof import('../../node_modules/h3/dist/index').sanitizeStatusMessage
const sealSession: typeof import('../../node_modules/h3/dist/index').sealSession
const send: typeof import('../../node_modules/h3/dist/index').send
const sendError: typeof import('../../node_modules/h3/dist/index').sendError
const sendIterable: typeof import('../../node_modules/h3/dist/index').sendIterable
const sendNoContent: typeof import('../../node_modules/h3/dist/index').sendNoContent
const sendProxy: typeof import('../../node_modules/h3/dist/index').sendProxy
const sendRedirect: typeof import('../../node_modules/h3/dist/index').sendRedirect
const sendStream: typeof import('../../node_modules/h3/dist/index').sendStream
const sendWebResponse: typeof import('../../node_modules/h3/dist/index').sendWebResponse
const serveStatic: typeof import('../../node_modules/h3/dist/index').serveStatic
const setCookie: typeof import('../../node_modules/h3/dist/index').setCookie
const setHeader: typeof import('../../node_modules/h3/dist/index').setHeader
const setHeaders: typeof import('../../node_modules/h3/dist/index').setHeaders
const setResponseHeader: typeof import('../../node_modules/h3/dist/index').setResponseHeader
const setResponseHeaders: typeof import('../../node_modules/h3/dist/index').setResponseHeaders
const setResponseStatus: typeof import('../../node_modules/h3/dist/index').setResponseStatus
const splitCookiesString: typeof import('../../node_modules/h3/dist/index').splitCookiesString
const toEventHandler: typeof import('../../node_modules/h3/dist/index').toEventHandler
const toNodeListener: typeof import('../../node_modules/h3/dist/index').toNodeListener
const toPlainHandler: typeof import('../../node_modules/h3/dist/index').toPlainHandler
const toWebHandler: typeof import('../../node_modules/h3/dist/index').toWebHandler
const toWebRequest: typeof import('../../node_modules/h3/dist/index').toWebRequest
const unsealSession: typeof import('../../node_modules/h3/dist/index').unsealSession
const updateSession: typeof import('../../node_modules/h3/dist/index').updateSession
const useAppConfig: typeof import('../../node_modules/nitropack/dist/runtime/internal/config').useAppConfig
const useBase: typeof import('../../node_modules/h3/dist/index').useBase
const useEvent: typeof import('../../node_modules/nitropack/dist/runtime/internal/context').useEvent
const useNitroApp: typeof import('../../node_modules/nitropack/dist/runtime/internal/app').useNitroApp
const useRuntimeConfig: typeof import('../../node_modules/nitropack/dist/runtime/internal/config').useRuntimeConfig
const useSession: typeof import('../../node_modules/h3/dist/index').useSession
const useStorage: typeof import('../../node_modules/nitropack/dist/runtime/internal/storage').useStorage
const writeEarlyHints: typeof import('../../node_modules/h3/dist/index').writeEarlyHints
}
// for type re-export
declare global {
// @ts-ignore
export type { EventHandler, EventHandlerRequest, EventHandlerResponse, EventHandlerObject, H3EventContext } from '../../node_modules/h3/dist/index'
import('../../node_modules/h3/dist/index')
// @ts-ignore
export type { Size, Category, Status, Payment, Dish, Extra, OrderItem, Order, DayHours, Settings } from '../../server/utils/store'
import('../../server/utils/store')
}
export { H3Event, H3Error, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, useBase, useSession, writeEarlyHints } from 'h3';
export { useNitroApp } from 'nitropack/runtime/internal/app';
export { useRuntimeConfig, useAppConfig } from 'nitropack/runtime/internal/config';
export { defineNitroPlugin, nitroPlugin } from 'nitropack/runtime/internal/plugin';
export { defineCachedFunction, defineCachedEventHandler, cachedFunction, cachedEventHandler } from 'nitropack/runtime/internal/cache';
export { useStorage } from 'nitropack/runtime/internal/storage';
export { defineRenderHandler } from 'nitropack/runtime/internal/renderer';
export { defineRouteMeta } from 'nitropack/runtime/internal/meta';
export { getRouteRules } from 'nitropack/runtime/internal/route-rules';
export { useEvent } from 'nitropack/runtime/internal/context';
export { defineTask, runTask } from 'nitropack/runtime/internal/task';
export { defineNitroErrorHandler } from 'nitropack/runtime/internal/error/utils';
export { buildAssetsURL as __buildAssetsURL, publicAssetsURL as __publicAssetsURL } from '/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/@nuxt/nitro-server/dist/runtime/utils/paths';
export { defineAppConfig } from '/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/node_modules/@nuxt/nitro-server/dist/runtime/utils/config';
export { db, resetDb, findOrder } from '/Users/1laan/Documents/KNR Korp/CLIENT/PANZAI/panzai-demo/server/utils/store';

17
.nuxt/types/nitro-layouts.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
export type LayoutKey = "admin" | "default"
declare module 'nitropack' {
interface NitroRouteConfig {
appLayout?: LayoutKey | false
}
interface NitroRouteRules {
appLayout?: LayoutKey | false
}
}
declare module 'nitropack/types' {
interface NitroRouteConfig {
appLayout?: LayoutKey | false
}
interface NitroRouteRules {
appLayout?: LayoutKey | false
}
}

17
.nuxt/types/nitro-middleware.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
export type MiddlewareKey = never
declare module 'nitropack' {
interface NitroRouteConfig {
appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>
}
interface NitroRouteRules {
appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>
}
}
declare module 'nitropack/types' {
interface NitroRouteConfig {
appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>
}
interface NitroRouteRules {
appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>
}
}

39
.nuxt/types/nitro-nuxt.d.ts vendored Normal file
View file

@ -0,0 +1,39 @@
/// <reference path="nitro-layouts.d.ts" />
/// <reference path="app.config.d.ts" />
/// <reference path="runtime-config.d.ts" />
/// <reference path="../../node_modules/@nuxt/nitro-server/dist/index.d.mts" />
/// <reference path="nitro-middleware.d.ts" />
/// <reference path="./schema.d.ts" />
import type { RuntimeConfig } from 'nuxt/schema'
import type { H3Event } from 'h3'
import type { LogObject } from 'consola'
import type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from 'nuxt/app'
declare module 'nitropack' {
interface NitroRuntimeConfigApp {
buildAssetsDir: string
cdnURL: string
}
interface NitroRuntimeConfig extends RuntimeConfig {}
interface NitroRouteConfig {
ssr?: boolean
noScripts?: boolean
/** @deprecated Use `noScripts` instead */
experimentalNoScripts?: boolean
}
interface NitroRouteRules {
ssr?: boolean
noScripts?: boolean
/** @deprecated Use `noScripts` instead */
experimentalNoScripts?: boolean
appMiddleware?: Record<string, boolean>
appLayout?: string | false
}
interface NitroRuntimeHooks {
'dev:ssr-logs': (ctx: { logs: LogObject[], path: string }) => void | Promise<void>
'render:html': (htmlContext: NuxtRenderHTMLContext, context: { event: H3Event }) => void | Promise<void>
'render:island': (islandResponse: NuxtIslandResponse, context: { event: H3Event, islandContext: NuxtIslandContext }) => void | Promise<void>
}
}

36
.nuxt/types/nitro-routes.d.ts vendored Normal file
View file

@ -0,0 +1,36 @@
// Generated by nitro
import type { Serialize, Simplify } from "nitropack/types";
declare module "nitropack/types" {
type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T
interface InternalApi {
'/api/menu': {
'get': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/menu.get').default>>>>
'post': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/menu.post').default>>>>
}
'/api/menu/:id': {
'patch': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/menu/[id].patch').default>>>>
}
'/api/orders': {
'get': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/orders.get').default>>>>
'post': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/orders.post').default>>>>
}
'/api/orders/:id': {
'get': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/orders/[id].get').default>>>>
'patch': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/orders/[id].patch').default>>>>
}
'/api/reset': {
'post': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/reset.post').default>>>>
}
'/api/settings': {
'get': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/settings.get').default>>>>
'patch': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/api/settings.patch').default>>>>
}
'/__nuxt_error': {
'default': Simplify<Serialize<Awaited<ReturnType<typeof import('../../node_modules/@nuxt/nitro-server/dist/runtime/handlers/renderer').default>>>>
}
'/__nuxt_island/**': {
'default': Simplify<Serialize<Awaited<ReturnType<typeof import('../../server/#internal/nuxt/island-renderer').default>>>>
}
}
}
export {}

3
.nuxt/types/nitro.d.ts vendored Normal file
View file

@ -0,0 +1,3 @@
/// <reference path="./nitro-routes.d.ts" />
/// <reference path="./nitro-config.d.ts" />
/// <reference path="./nitro-imports.d.ts" />

37
.nuxt/types/plugins.d.ts vendored Normal file
View file

@ -0,0 +1,37 @@
// Generated by Nuxt'
import type { Plugin } from '#app'
type Decorate<T extends Record<string, any>> = { [K in keyof T as K extends string ? `$${K}` : never]: T[K] }
type InjectionType<A extends Plugin> = A extends {default: Plugin<infer T>} ? Decorate<T> : unknown
type NuxtAppInjections =
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/revive-payload.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/head/runtime/plugins/unhead.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/pages/runtime/plugins/router.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/browser-devtools-timing.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/payload.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/dev-server-logs.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/navigation-repaint.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/check-outdated-build.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/revive-payload.server.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/chunk-reload.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/pages/runtime/plugins/prefetch.client.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/pages/runtime/plugins/check-if-page-unused.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/warn.dev.server.js")> &
InjectionType<typeof import("../../node_modules/nuxt/dist/app/plugins/check-if-layout-used.js")> &
InjectionType<typeof import("../../plugins/cart.client")>
declare module '#app' {
interface NuxtApp extends NuxtAppInjections { }
interface NuxtAppLiterals {
pluginName: 'nuxt:revive-payload:client' | 'nuxt:head' | 'nuxt:router' | 'nuxt:browser-devtools-timing' | 'nuxt:payload' | 'nuxt:revive-payload:server' | 'nuxt:chunk-reload' | 'nuxt:global-components' | 'nuxt:prefetch' | 'nuxt:checkIfPageUnused' | 'nuxt:checkIfLayoutUsed'
}
}
declare module 'vue' {
interface ComponentCustomProperties extends NuxtAppInjections { }
}
export { }

67
.nuxt/types/schema.d.ts vendored Normal file
View file

@ -0,0 +1,67 @@
import { RuntimeConfig as UserRuntimeConfig, PublicRuntimeConfig as UserPublicRuntimeConfig } from 'nuxt/schema'
import { NuxtModule, ModuleDependencyMeta } from '@nuxt/schema'
interface SharedRuntimeConfig {
app: {
buildId: string,
baseURL: string,
buildAssetsDir: string,
cdnURL: string,
},
nitro: {
envPrefix: string,
},
}
interface SharedPublicRuntimeConfig {
}
declare module '@nuxt/schema' {
interface ModuleDependencies {
["@nuxt/telemetry"]?: ModuleDependencyMeta<typeof import("@nuxt/telemetry").default extends NuxtModule<infer O> ? O | false : Record<string, unknown>> | false
}
interface NuxtOptions {
/**
* Configuration for `@nuxt/telemetry`
*/
["telemetry"]: typeof import("@nuxt/telemetry").default extends NuxtModule<infer O, unknown, boolean> ? O | false : Record<string, any> | false
}
interface NuxtConfig {
/**
* Configuration for `@nuxt/telemetry`
*/
["telemetry"]?: typeof import("@nuxt/telemetry").default extends NuxtModule<infer O, unknown, boolean> ? Partial<O> | false : Record<string, any> | false
modules?: (undefined | null | false | NuxtModule<any> | string | [NuxtModule | string, Record<string, any>] | ["@nuxt/telemetry", Exclude<NuxtConfig["telemetry"], boolean>])[],
}
interface RuntimeConfig extends UserRuntimeConfig {}
interface PublicRuntimeConfig extends UserPublicRuntimeConfig {}
}
declare module 'nuxt/schema' {
interface ModuleDependencies {
["@nuxt/telemetry"]?: ModuleDependencyMeta<typeof import("@nuxt/telemetry").default extends NuxtModule<infer O> ? O | false : Record<string, unknown>> | false
}
interface NuxtOptions {
/**
* Configuration for `@nuxt/telemetry`
* @see https://www.npmjs.com/package/@nuxt/telemetry
*/
["telemetry"]: typeof import("@nuxt/telemetry").default extends NuxtModule<infer O, unknown, boolean> ? O | false : Record<string, any> | false
}
interface NuxtConfig {
/**
* Configuration for `@nuxt/telemetry`
* @see https://www.npmjs.com/package/@nuxt/telemetry
*/
["telemetry"]?: typeof import("@nuxt/telemetry").default extends NuxtModule<infer O, unknown, boolean> ? Partial<O> | false : Record<string, any> | false
modules?: (undefined | null | false | NuxtModule<any> | string | [NuxtModule | string, Record<string, any>] | ["@nuxt/telemetry", Exclude<NuxtConfig["telemetry"], boolean>])[],
}
interface RuntimeConfig extends SharedRuntimeConfig {}
interface PublicRuntimeConfig extends SharedPublicRuntimeConfig {}
}
declare module 'vue' {
interface ComponentCustomProperties {
$config: UserRuntimeConfig
}
}

0
.nuxt/types/vue-shim.d.ts vendored Normal file
View file

79
README.md Normal file
View file

@ -0,0 +1,79 @@
# PANZAÏ — Démo plateforme de commande
Démo fonctionnelle réalisée par **KNRWebsite** pour PANZAÏ — Jungle Street Food (Thonon-les-Bains).
- **Site client** (`/`) : accueil, carte, personnalisation des plats, panier, paiement (simulé), suivi de commande en direct.
- **Dashboard gérant** (`/admin`) : commandes en temps réel (kanban + son), gestion du menu (prix, ruptures), statistiques, horaires et réglages de livraison.
Le site et le dashboard sont **reliés** : une commande passée sur le téléphone apparaît dans le dashboard en 2 secondes, et le suivi côté client avance quand le gérant clique.
## Lancer la démo
Prérequis : [Node.js](https://nodejs.org) 20 ou plus.
```bash
npm install
npm run dev
```
Puis ouvre :
- Site client : http://localhost:3000
- Dashboard gérant : http://localhost:3000/admin
### Démo sur téléphone + tablette (recommandé pour le rendez-vous)
`npm run dev` écoute sur le réseau local. Le terminal affiche une adresse du type `http://192.168.1.42:3000`.
Avec le Mac, le téléphone et la tablette sur **le même Wi-Fi** :
- sur le **téléphone** : `http://<IP-du-Mac>:3000` → passer une commande ;
- sur la **tablette** (ou le Mac) : `http://<IP-du-Mac>:3000/admin` → cliquer sur **Activer le son**, puis accepter la commande.
### Version optimisée (plus rapide)
```bash
npm run build
npm start
```
## Scénario de démo conseillé (2 minutes)
1. Montrer l'accueil sur le téléphone (hero, toucan, best-sellers, bouton Commander toujours visible).
2. Ajouter un Crousty XL (sauce chili thaï) + un Pad Thaï, aller au panier, choisir Livraison, payer.
3. Sur la tablette : la commande arrive avec un son et pulse → **Accepter 20 min**.
4. Sur le téléphone : le suivi passe à « Ça chauffe au wok 🔥 ».
5. Tablette : **Marquer prête** → **Remise au livreur**. Le suivi client suit.
6. Dans **Menu** : mettre le Pad Thaï en **Rupture** → il est grisé sur le site client (≈10 s).
7. Dans **Statistiques** : montrer la commission économisée vs Uber Eats.
8. Dans **Horaires & réglages** : interrupteur « Commandes en pause » visible côté client.
Bouton **Remettre la démo à zéro** en bas de « Horaires & réglages ».
## Ce qui est simulé dans cette démo
| Élément | Démo | Production |
|---|---|---|
| Base de données | en mémoire (remise à zéro au redémarrage) | Supabase / Postgres |
| Paiement | simulé (1,4 s) | Stripe (carte, Apple Pay, Google Pay) |
| Temps réel | rafraîchissement toutes les 2 s | Supabase Realtime |
| Connexion gérant | aucune | compte sécurisé |
| SMS client | texte seulement | Brevo / Twilio |
| Avis Google, carte Maps | emplacements | API Google |
| Historique stats | chiffres de démo + jour en direct | calculé depuis la base |
| Logo | toucan provisoire | logo officiel PANZAÏ |
À compléter avec le restaurant : prix du Veggie, boissons, desserts, suppléments, horaires, zone et frais de livraison, photos HD.
## Structure
```
pages/ index, menu, panier, commande/[id], admin/*
components/ header, footer, cartes plats, fenêtre de personnalisation…
composables/ panier, données du resto, actions du dashboard
server/api/ API (menu, commandes, réglages)
server/utils/ store.ts — données de démo (carte, commandes, horaires)
assets/main.css design system (couleurs, typo, boutons)
public/img/ photos des plats
```
Stack : Nuxt 3 (Vue 3), sans dépendance externe. Polices : Shojumaru (titres) et Manrope (texte) via Google Fonts.

5
app.vue Normal file
View file

@ -0,0 +1,5 @@
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

190
assets/main.css Normal file
View file

@ -0,0 +1,190 @@
/* ───────── PANZAÏ — design tokens ───────── */
:root {
--bg: #14100D;
--bg-deep: #0E0B09;
--surface: #1F1812;
--surface-2: #2A1F17;
--surface-3: #241B15;
--wood: #5A3A22;
--wood-dark: #3A2617;
--orange-1: #FFB43A;
--orange-2: #E8622A;
--grad: linear-gradient(90deg, #FFB43A, #E8622A);
--grad-v: linear-gradient(180deg, #FFB43A 20%, #E8622A 90%);
--green: #2F6B2A;
--green-dark: #1E4A1B;
--leaf: #8CC63F;
--cream: #F3E3C3;
--white: #fff;
--danger: #FF6B4A;
--danger-text: #FF8A5C;
--line: rgba(243, 227, 195, .1);
--line-2: rgba(243, 227, 195, .18);
--radius: 22px;
--shadow: 0 24px 50px rgba(0, 0, 0, .45);
--font: Manrope, system-ui, -apple-system, sans-serif;
--display: Shojumaru, 'Bowlby One', Impact, sans-serif;
--wood-tex: repeating-linear-gradient(91deg, rgba(0,0,0,.22) 0 2px, transparent 2px 11px),
repeating-linear-gradient(89deg, rgba(255,214,160,.05) 0 1px, transparent 1px 17px),
linear-gradient(175deg, #5A3A22, #3A2617);
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
margin: 0; background: var(--bg); color: var(--cream);
font-family: var(--font); font-size: 16px; line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: var(--orange-1); }
a:hover { color: var(--cream); }
button { font: inherit; }
h1, h2, h3, p { margin: 0; }
:focus-visible { outline: 3px solid var(--orange-1); outline-offset: 2px; }
input, textarea, select { font: inherit; color: var(--white); }
/* ───────── Layout ───────── */
.container { width: 100%; max-width: 1240px; margin: 0 auto; padding: 0 16px; }
@media (min-width: 768px) { .container { padding: 0 24px; } }
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.muted { opacity: .75; }
.small { font-size: 13px; }
.strong { font-weight: 800; color: var(--white); }
.price { color: var(--orange-1); font-weight: 800; white-space: nowrap; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
/* ───────── Typo ───────── */
.display {
font-family: var(--display); font-weight: 400; letter-spacing: .3px;
background: var(--grad-v); -webkit-background-clip: text; background-clip: text; color: transparent;
line-height: 1.06;
}
.eyebrow { font-size: 13px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase; opacity: .7; }
.section-title { font-size: clamp(28px, 4vw, 44px); }
/* ───────── Boutons ───────── */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 10px;
min-height: 48px; padding: 0 20px; border: 0; border-radius: 16px; cursor: pointer;
font-weight: 800; font-size: 15px; text-decoration: none; white-space: nowrap;
transition: transform .15s ease, filter .15s ease, background .2s ease;
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: scale(.96); }
.btn:disabled { opacity: .45; cursor: not-allowed; filter: none; transform: none; }
.btn-primary { background: var(--grad); color: var(--bg); box-shadow: 0 12px 30px rgba(232, 98, 42, .3); }
.btn-primary:hover { color: var(--bg); }
.btn-ghost { background: var(--surface); color: var(--cream); border: 1px solid var(--line-2); }
.btn-ghost:hover { color: var(--cream); }
.btn-cream { background: var(--cream); color: var(--bg); }
.btn-cream:hover { color: var(--bg); }
.btn-green { background: var(--leaf); color: var(--bg); }
.btn-danger { background: transparent; border: 1px solid rgba(255,107,74,.6); color: var(--danger-text); }
.btn-lg { min-height: 58px; font-size: 17px; border-radius: 18px; padding: 0 26px; }
.btn-block { width: 100%; }
.btn-icon { width: 46px; min-height: 46px; padding: 0; border-radius: 14px; }
/* ───────── Cartes / badges ───────── */
.card { background: var(--surface); border-radius: var(--radius); }
.badge { display: inline-flex; align-items: center; padding: 5px 11px; border-radius: 999px; font-size: 12px; font-weight: 800; color: var(--bg); }
.badge-best { background: var(--orange-1); }
.badge-spicy { background: var(--orange-2); }
.badge-veggie { background: var(--leaf); }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px; background: var(--surface); font-size: 14px; font-weight: 700; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
.dot-green { background: var(--leaf); }
.dot-red { background: var(--orange-2); }
.blink { animation: blink 1.6s ease-in-out infinite; }
.wood { background: var(--wood-tex); }
.placeholder-tag {
position: absolute; padding: 4px 8px; border-radius: 6px; background: rgba(20,16,13,.88);
font-size: 10px; font-weight: 700; letter-spacing: .6px; color: var(--cream);
}
/* ───────── Formulaires ───────── */
.field { display: flex; flex-direction: column; gap: 6px; }
.label { font-size: 14px; font-weight: 800; color: var(--white); }
.input {
min-height: 52px; padding: 0 14px; border-radius: 14px; border: 1px solid var(--line-2);
background: var(--surface); font-size: 15px; width: 100%;
}
textarea.input { padding: 12px 14px; resize: vertical; min-height: 72px; }
.input::placeholder { color: rgba(243,227,195,.45); }
.input:focus { outline: 2px solid var(--orange-1); outline-offset: 1px; }
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 5px; padding: 5px; border-radius: 18px; background: var(--surface); }
.seg button { min-height: 48px; border: 0; border-radius: 14px; background: transparent; color: var(--cream); font-weight: 700; cursor: pointer; padding: 0 14px; }
.seg button[aria-pressed="true"] { background: var(--grad); color: var(--bg); font-weight: 800; }
.opt {
min-height: 48px; border-radius: 14px; border: 2px solid rgba(243,227,195,.14); background: var(--bg);
color: var(--cream); font-weight: 700; cursor: pointer; padding: 6px 12px;
display: flex; flex-direction: column; align-items: center; justify-content: center;
transition: border-color .15s, background .15s, transform .12s;
}
.opt:active { transform: scale(.96); }
.opt[aria-pressed="true"] { border-color: var(--orange-1); background: rgba(255,180,58,.12); color: var(--white); font-weight: 800; }
.switch { position: relative; width: 56px; height: 32px; border-radius: 16px; border: 0; background: var(--wood-dark); cursor: pointer; flex: none; transition: background .2s; }
.switch::after { content: ''; position: absolute; top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; transition: left .2s ease; }
.switch[aria-checked="true"] { background: var(--leaf); }
.switch[aria-checked="true"]::after { left: 28px; }
.qty { display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 14px; background: var(--bg); }
.qty button { width: 38px; height: 38px; border: 0; border-radius: 10px; background: var(--surface-2); color: var(--cream); font-size: 20px; font-weight: 800; cursor: pointer; }
.qty span { min-width: 26px; text-align: center; font-weight: 800; color: var(--white); }
/* ───────── Bol (photo) ───────── */
.dish-photo { position: relative; overflow: hidden; }
.dish-photo img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 18px 22px rgba(0,0,0,.55)); transition: transform .4s ease; }
.dish-photo .empty-bowl {
position: absolute; left: 50%; top: 50%; width: 46%; aspect-ratio: 1.3; transform: translate(-50%, -40%);
border-radius: 0 0 50% 50% / 0 0 100% 100%; background: linear-gradient(180deg, #7A5030, #2A1C12);
box-shadow: inset 0 14px 0 rgba(63,138,53,.9), 0 18px 28px rgba(0,0,0,.45);
}
/* ───────── Animations ───────── */
@keyframes blink { 50% { opacity: .35; } }
@keyframes rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes toucan { 0% { transform: translateY(50px) scale(.75); opacity: 0; } 65% { transform: translateY(-6px) scale(1.04); opacity: 1; } 100% { transform: none; opacity: 1; } }
@keyframes sway { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(3deg); } }
@keyframes pop { 0% { transform: scale(1); } 40% { transform: scale(1.25); } 100% { transform: scale(1); } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sheet { from { transform: translateY(100%); } to { transform: none; } }
@keyframes modal { from { opacity: 0; transform: translateY(24px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255,180,58,.6), 0 0 0 2px var(--orange-1); } 50% { box-shadow: 0 0 0 14px rgba(255,180,58,0), 0 0 0 2px var(--orange-1); } }
@keyframes ring { 0% { box-shadow: 0 0 0 0 rgba(255,180,58,.6); } 100% { box-shadow: 0 0 0 16px rgba(255,180,58,0); } }
@keyframes bell { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-16deg); } 40% { transform: rotate(14deg); } 60% { transform: rotate(-8deg); } }
@keyframes spin { to { transform: rotate(360deg); } }
.rise { animation: rise .7s ease both; }
.toucan-in { animation: toucan 1s cubic-bezier(.2,.9,.3,1.2) both .35s; }
.sway { animation: sway 7s ease-in-out infinite; transform-origin: 50% 100%; }
.pop { animation: pop .4s ease; }
@supports (animation-timeline: view()) {
.parallax { animation: parallax linear both; animation-timeline: view(); }
@keyframes parallax { from { translate: 0 40px; } to { translate: 0 -40px; } }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
/* ───────── Hover cartes ───────── */
.hover-lift { transition: transform .3s ease, box-shadow .3s ease; }
.hover-lift:hover { transform: translateY(-5px); box-shadow: var(--shadow); }
.hover-lift:hover .dish-photo img { transform: scale(1.05) rotate(-1.5deg); }
/* ───────── Overlay / modale ───────── */
.overlay { position: fixed; inset: 0; z-index: 60; background: rgba(8,6,5,.75); backdrop-filter: blur(4px); display: flex; align-items: flex-end; justify-content: center; animation: fade .2s ease both; }
.sheet { width: 100%; max-height: 92vh; overflow-y: auto; background: var(--surface); border-radius: 28px 28px 0 0; animation: sheet .4s cubic-bezier(.2,.9,.3,1) both; }
@media (min-width: 768px) {
.overlay { align-items: center; padding: 24px; }
.sheet { max-width: 780px; border-radius: 28px; animation: modal .3s cubic-bezier(.2,.9,.3,1) both; }
}
/* ───────── Toast ───────── */
.toast { position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%); z-index: 80; padding: 12px 18px; border-radius: 14px; background: var(--cream); color: var(--bg); font-weight: 800; box-shadow: var(--shadow); animation: rise .3s ease both; }
@media (min-width: 1024px) { .toast { bottom: 32px; } }

View file

@ -0,0 +1,60 @@
<script setup lang="ts">
// Panier latéral (desktop) sur la page Menu
const { lines, count, subtotal, setQty, mode, bump } = useCart()
const { settings } = useShop()
const fee = computed(() => mode.value === 'livraison' && count.value && subtotal.value < (settings.value?.freeFrom ?? 3500) ? (settings.value?.deliveryFee ?? 250) : 0)
const popping = ref(false)
watch(bump, () => { popping.value = false; requestAnimationFrame(() => { popping.value = true }) })
</script>
<template>
<aside class="cs card" :class="{ pop: popping }" aria-labelledby="cs-h">
<div class="row" style="justify-content: space-between">
<h2 id="cs-h" style="font-size: 20px; font-weight: 800; color: #fff">Ton panier</h2>
<span class="small muted">{{ count }} article(s)</span>
</div>
<p v-if="!lines.length" class="empty muted">Ton panier est vide.<br>Le Crousty t'attend 🔥</p>
<ul v-else class="lines">
<li v-for="l in lines" :key="l.key">
<img v-if="l.img" :src="l.img" alt="" class="thumb">
<span v-else class="thumb ph" />
<div class="grow">
<p class="strong" style="font-size: 15px">{{ l.name }} {{ l.size }}</p>
<p class="small muted">{{ [l.meat, l.sauce, ...l.extrasLabel].filter(Boolean).join(' · ') }}</p>
<div class="row" style="justify-content: space-between; margin-top: 6px">
<div class="qty mini">
<button type="button" :aria-label="`Retirer un ${l.name}`" @click="setQty(l.key, l.qty - 1)">−</button>
<span>{{ l.qty }}</span>
<button type="button" :aria-label="`Ajouter un ${l.name}`" @click="setQty(l.key, l.qty + 1)">+</button>
</div>
<strong class="price">{{ eur(l.unit * l.qty) }}</strong>
</div>
</div>
</li>
</ul>
<dl class="tot">
<dt>Sous-total</dt><dd>{{ eur(subtotal) }}</dd>
<dt>{{ mode === 'livraison' ? 'Livraison' : 'Retrait sur place' }}</dt><dd>{{ mode === 'livraison' ? eur(fee) : 'Gratuit' }}</dd>
<dt>Frais de service</dt><dd style="color: var(--leaf)">0,00 €</dd>
<dt class="big">Total</dt><dd class="big price">{{ eur(subtotal + fee) }}</dd>
</dl>
<NuxtLink v-if="lines.length" to="/panier" class="btn btn-primary btn-lg btn-block">Commander — {{ eur(subtotal + fee) }}</NuxtLink>
<p class="small muted" style="text-align: center">Commande directe : zéro commission d'appli, 100 % pour le resto 🌴</p>
</aside>
</template>
<style scoped>
.cs { padding: 22px; display: flex; flex-direction: column; gap: 14px; border: 1px solid rgba(243,227,195,.08); box-shadow: 0 30px 60px rgba(0,0,0,.35); }
.cs.pop { animation: none; }
.empty { padding: 20px 0; text-align: center; }
.lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; max-height: 420px; overflow-y: auto; }
.lines li { display: flex; gap: 10px; padding: 10px; border-radius: 16px; background: var(--bg); }
.thumb { width: 54px; height: 54px; object-fit: contain; flex: none; }
.thumb.ph { border-radius: 12px; background: var(--surface-2); }
.qty.mini button { width: 30px; height: 30px; font-size: 16px; }
.tot { margin: 0; padding-top: 12px; border-top: 1px solid var(--line); display: grid; grid-template-columns: 1fr auto; gap: 8px; font-size: 14px; }
.tot dt { opacity: .75; }
.tot dd { margin: 0; font-weight: 700; text-align: right; }
.tot .big { font-size: 20px; font-weight: 800; opacity: 1; color: #fff; }
.tot dd.big { color: var(--orange-1); }
</style>

View file

@ -0,0 +1,148 @@
<script setup lang="ts">
import type { Size } from '~/server/utils/store'
const { dish, close } = useCustomize()
const { extras } = useShop()
const cart = useCart()
const toast = useToast()
const size = ref<Size>('XL')
const meat = ref('')
const sauce = ref('')
const picked = ref<string[]>([])
const note = ref('')
const qty = ref(1)
watch(dish, (d) => {
if (!d) return
const sizes = sizesOf(d).filter(s => d.prices[s] != null)
size.value = sizes.includes('XL') ? 'XL' : sizes[0]
meat.value = d.meats.includes('Poulet') ? 'Poulet' : (d.meats[0] || '')
sauce.value = d.sauces?.[0] || ''
picked.value = []
note.value = ''
qty.value = 1
})
const unit = computed(() => {
if (!dish.value) return 0
const base = dish.value.prices[size.value] ?? 0
return base + picked.value.reduce((a, id) => a + (extras.value.find(e => e.id === id)?.price || 0), 0)
})
function toggle(id: string) {
picked.value = picked.value.includes(id) ? picked.value.filter(x => x !== id) : [...picked.value, id]
}
function add() {
const d = dish.value
if (!d) return
cart.add({
dishId: d.id, name: d.name, img: d.img, size: size.value,
meat: meat.value || 'Légumes', sauce: d.sauces ? sauce.value : undefined,
extras: [...picked.value], extrasLabel: picked.value.map(id => extras.value.find(e => e.id === id)?.label || id),
note: note.value.trim() || undefined, qty: qty.value, unit: unit.value
})
toast.show(`${qty.value}× ${d.name} ajouté au panier`)
close()
}
function onKey(e: KeyboardEvent) { if (e.key === 'Escape' && dish.value) close() }
onMounted(() => window.addEventListener('keydown', onKey))
onBeforeUnmount(() => window.removeEventListener('keydown', onKey))
</script>
<template>
<Teleport to="body">
<div v-if="dish" class="overlay" @click.self="close">
<section class="sheet cz" role="dialog" aria-modal="true" aria-labelledby="cz-title">
<div class="cz-photo wood">
<span class="grab" aria-hidden="true" />
<DishPhoto :img="dish.img" :alt="dish.name" />
<button class="btn btn-icon closeb" type="button" aria-label="Fermer" @click="close"><Icon name="close" :stroke="2.6" /></button>
</div>
<div class="cz-body">
<div>
<div class="row" style="gap: 10px; flex-wrap: wrap">
<h2 id="cz-title" class="display" style="font-size: 28px">{{ dish.name }}</h2>
<span v-if="dish.badge" class="badge" :class="`badge-${dish.badge.tone}`">{{ dish.badge.label }}</span>
</div>
<p class="muted" style="margin-top: 6px; font-size: 14px">{{ dish.desc }}</p>
</div>
<fieldset>
<legend class="label">Taille</legend>
<div class="opts">
<button v-for="s in sizesOf(dish)" :key="s" class="opt" type="button" :aria-pressed="size === s" :disabled="dish.prices[s] == null" @click="size = s">
<strong style="font-size: 17px">{{ s }}</strong><span class="price" style="font-size: 13px">{{ eur(dish.prices[s]) }}</span>
</button>
</div>
</fieldset>
<fieldset v-if="dish.meats.length">
<legend class="label">Viande</legend>
<div class="opts">
<button v-for="m in dish.meats" :key="m" class="opt" type="button" :aria-pressed="meat === m" @click="meat = m">{{ m }}</button>
</div>
</fieldset>
<fieldset v-if="dish.sauces">
<legend class="label">Sauce</legend>
<div class="opts">
<button v-for="s in dish.sauces" :key="s" class="opt" type="button" :aria-pressed="sauce === s" @click="sauce = s">{{ s }}</button>
</div>
</fieldset>
<fieldset v-if="dish.cat === 'wok' || dish.cat === 'baguette'">
<legend class="label">Suppléments</legend>
<div class="stack" style="gap: 8px">
<button v-for="e in extras" :key="e.id" class="extra" type="button" :aria-pressed="picked.includes(e.id)" @click="toggle(e.id)">
<span class="box"><Icon v-if="picked.includes(e.id)" name="check" :size="14" :stroke="3.4" /></span>
<span class="grow">{{ e.label }}</span>
<span class="price">+{{ eur(e.price) }}</span>
</button>
</div>
</fieldset>
<div class="field">
<label class="label" for="cz-note">Note pour la cuisine</label>
<textarea id="cz-note" v-model="note" class="input" rows="2" maxlength="200" placeholder="Ex. : sans oignons frits, sauce à part…" />
</div>
</div>
<div class="cz-foot">
<div class="qty">
<button type="button" aria-label="Retirer un" @click="qty = Math.max(1, qty - 1)">−</button>
<span aria-live="polite">{{ qty }}</span>
<button type="button" aria-label="Ajouter un" @click="qty = Math.min(20, qty + 1)">+</button>
</div>
<button class="btn btn-primary btn-lg grow" type="button" @click="add">Ajouter — {{ eur(unit * qty) }}</button>
</div>
</section>
</div>
</Teleport>
</template>
<style scoped>
.cz { display: flex; flex-direction: column; }
.cz-photo { position: relative; height: 190px; flex: none; }
.cz-photo :deep(.dish-photo) { position: absolute; inset: 18px 18%; }
.grab { position: absolute; left: 50%; top: 10px; width: 40px; height: 5px; margin-left: -20px; border-radius: 3px; background: rgba(243,227,195,.5); }
.closeb { position: absolute; right: 14px; top: 18px; background: rgba(20,16,13,.88); color: var(--cream); border-radius: 50%; }
.cz-body { padding: 20px 20px 8px; display: flex; flex-direction: column; gap: 20px; }
fieldset { margin: 0; padding: 0; border: 0; }
legend { margin-bottom: 10px; }
.opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 8px; }
.extra { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 14px; border-radius: 14px; border: 1px solid var(--line); background: var(--bg); color: var(--cream); cursor: pointer; font-weight: 600; text-align: left; }
.box { width: 22px; height: 22px; border-radius: 7px; border: 2px solid rgba(243,227,195,.35); display: flex; align-items: center; justify-content: center; color: var(--bg); flex: none; }
.extra[aria-pressed="true"] .box { background: var(--grad); border: 0; }
.cz-foot { position: sticky; bottom: 0; display: flex; align-items: center; gap: 12px; padding: 14px 20px calc(18px + env(safe-area-inset-bottom)); background: var(--surface); border-top: 1px solid var(--line); }
@media (min-width: 768px) {
.cz { display: grid; grid-template-columns: 300px 1fr; grid-template-rows: 1fr auto; }
.cz-photo { height: auto; grid-row: 1 / 3; border-radius: 28px 0 0 28px; }
.cz-photo :deep(.dish-photo) { inset: 25% 8%; }
.grab { display: none; }
.closeb { left: 14px; right: auto; }
.cz-body { padding: 26px 26px 8px; }
.cz-foot { padding: 16px 26px 22px; border-radius: 0 0 28px 0; }
}
</style>

63
components/DishCard.vue Normal file
View file

@ -0,0 +1,63 @@
<script setup lang="ts">
import type { Dish } from '~/server/utils/store'
const props = withDefaults(defineProps<{ dish: Dish, layout?: 'grid' | 'row' }>(), { layout: 'grid' })
const { open } = useCustomize()
const { open: shopOpen } = useShop()
const sizes = computed(() => sizesOf(props.dish))
const can = computed(() => orderable(props.dish) && shopOpen.value)
const status = computed(() => !props.dish.available ? 'Rupture' : !orderable(props.dish) ? 'Bientôt' : !shopOpen.value ? 'En pause' : '')
</script>
<template>
<article class="dish card hover-lift" :class="[layout, { off: !dish.available }]">
<div class="photo wood">
<DishPhoto :img="dish.img" :alt="dish.name" />
<span v-if="dish.badge" class="badge tag" :class="`badge-${dish.badge.tone}`">{{ dish.badge.label }}</span>
<span v-if="!dish.available" class="badge tag-off">Rupture de stock</span>
</div>
<div class="body">
<h3>{{ dish.name }}</h3>
<p class="desc">{{ dish.desc }}</p>
<div class="foot">
<p class="prices">
<template v-for="(s, i) in sizes" :key="s">
<span v-if="i" class="muted"> · </span>
<span class="muted">{{ s }}</span> <strong class="price">{{ eur(dish.prices[s]) }}</strong>
</template>
</p>
<button v-if="can" class="btn btn-primary btn-icon add" type="button" :aria-label="`Ajouter ${dish.name}`" @click="open(dish)">
<Icon name="plus" :size="22" :stroke="3" />
</button>
<span v-else class="chip status">{{ status }}</span>
</div>
</div>
</article>
</template>
<style scoped>
.dish { overflow: hidden; display: flex; flex-direction: column; }
.photo { position: relative; height: 190px; }
.photo :deep(.dish-photo) { position: absolute; inset: 12px 7% 6px; }
.tag { position: absolute; left: 12px; top: 12px; }
.tag-off { position: absolute; right: 12px; top: 12px; background: var(--danger); color: var(--bg); }
.body { flex: 1; padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 6px; }
h3 { font-size: 19px; font-weight: 800; color: var(--white); }
.desc { font-size: 14px; opacity: .78; }
.foot { margin-top: auto; padding-top: 8px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.prices { font-size: 14px; }
.prices .price { font-size: 17px; }
.status { font-size: 13px; padding: 8px 12px; background: var(--surface-2); }
.off .photo { filter: grayscale(.8) brightness(.7); }
/* Variante liste (mobile) */
.row { flex-direction: row; gap: 14px; padding: 12px; }
.row .photo { flex: none; width: 112px; height: 124px; border-radius: 16px; overflow: hidden; }
.row .photo :deep(.dish-photo) { inset: 14px 4px 10px; }
.row .tag { left: 6px; top: 6px; font-size: 10px; padding: 3px 7px; }
.row .tag-off { display: none; }
.row .body { padding: 0; }
.row h3 { font-size: 17px; }
.row .desc { font-size: 13px; }
.row .prices .price { font-size: 15px; }
</style>

13
components/DishPhoto.vue Normal file
View file

@ -0,0 +1,13 @@
<script setup lang="ts">
defineProps<{ img?: string, alt: string }>()
</script>
<template>
<div class="dish-photo">
<img v-if="img" :src="img" :alt="alt" loading="lazy">
<template v-else>
<div class="empty-bowl" role="img" :aria-label="`Photo de ${alt} à venir`" />
<span class="placeholder-tag" style="right: 12px; bottom: 10px">PHOTO À VENIR</span>
</template>
</div>
</template>

37
components/Icon.vue Normal file
View file

@ -0,0 +1,37 @@
<script setup lang="ts">
// Icônes trait (stroke) utilisées sur tout le site
const props = withDefaults(defineProps<{ name: string, size?: number, stroke?: number }>(), { size: 20, stroke: 2 })
const paths: Record<string, string> = {
cart: 'M6 6h15l-1.5 9h-12z M6 6 5 3H2 M9 20h.01 M18 20h.01',
phone: 'M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2',
arrow: 'M5 12h14 M13 6l6 6-6 6',
back: 'M15 6l-6 6 6 6',
plus: 'M12 5v14 M5 12h14',
close: 'M6 6l12 12 M18 6 6 18',
check: 'm5 12 5 5 9-10',
shield: 'M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6z m-3.5 9 2.5 2.5 4.5-5',
flame: 'M12 22c4 0 7-3 7-7 0-5-4-7-5-12-2 2-3 4-3 6-1-1-2-2-2-4-2 2-4 5-4 10 0 4 3 7 7 7z',
bike: 'M6 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0-6 0 M18 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0-6 0 M6 17h3l3-7h4l2 7 M12 10 10 6H7',
pin: 'M12 22s7-6.5 7-12a7 7 0 0 0-14 0c0 5.5 7 12 7 12z M12 10m-2.5 0a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0-5 0',
clock: 'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0-18 0 M12 7v5l3 2',
lock: 'M5 11h14v10H5z M8 11V8a4 4 0 0 1 8 0v3',
kanban: 'M3 4h5v16H3z M10 4h5v11h-5z M17 4h4v7h-4z',
list: 'M4 6h16 M4 12h16 M4 18h10',
chart: 'M4 20V10 M10 20V4 M16 20v-7 M22 20H2',
gear: 'M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0-6 0 M12 2v3 M12 19v3 M2 12h3 M19 12h3 M5 5l2 2 M17 17l2 2 M5 19l2-2 M17 7l2-2',
print: 'M6 9V3h12v6 M6 18H4v-7h16v7h-2 M6 14h12v7H6z',
bell: 'M6 16V11a6 6 0 0 1 12 0v5l2 2H4z M10 21h4',
sound: 'M4 9v6h4l5 4V5L8 9z M16 9a4 4 0 0 1 0 6 M19 6a8 8 0 0 1 0 12',
edit: 'M4 20h4L19 9l-4-4L4 16z m10-14 4 4',
insta: 'M7 3h10a4 4 0 0 1 4 4v10a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V7a4 4 0 0 1 4-4z M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0-8 0',
tiktok: 'M14 3v11a4 4 0 1 1-4-4 M14 3c0 3 2 5 5 5',
ext: 'M14 4h6v6 M20 4l-9 9 M18 14v6H4V6h6'
}
const d = computed(() => paths[props.name] || '')
</script>
<template>
<svg :width="size" :height="size" viewBox="0 0 24 24" fill="none" stroke="currentColor" :stroke-width="stroke" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path :d="d" />
</svg>
</template>

View file

@ -0,0 +1,18 @@
<script setup lang="ts">
withDefaults(defineProps<{ color?: string, cut?: string }>(), { color: '#2F6B2A', cut: '#14100D' })
</script>
<template>
<svg viewBox="0 0 200 220" aria-hidden="true">
<path d="M100 214C52 204 12 166 8 114 4 60 46 12 100 10c56-2 94 44 92 98-2 54-42 96-92 106z" :fill="color" />
<path d="M100 214C98 150 100 80 104 12" stroke="rgba(0,0,0,.25)" stroke-width="5" fill="none" />
<g :stroke="cut" stroke-width="7" stroke-linecap="round" fill="none">
<path d="M101 60 40 40" /><path d="M101 100 14 96" /><path d="M100 140 28 170" />
<path d="M103 60 168 34" /><path d="M102 100 190 92" /><path d="M101 142 170 176" />
</g>
<g :fill="cut">
<ellipse cx="66" cy="76" rx="7" ry="4" /><ellipse cx="138" cy="74" rx="7" ry="4" />
<ellipse cx="60" cy="122" rx="7" ry="4" /><ellipse cx="144" cy="122" rx="7" ry="4" />
</g>
</svg>
</template>

15
components/LeafPalm.vue Normal file
View file

@ -0,0 +1,15 @@
<template>
<svg viewBox="0 0 240 140" aria-hidden="true">
<g fill="none" stroke-linecap="round">
<path d="M4 134Q110 44 236 20" stroke="#2F6B2A" stroke-width="4" />
<g stroke="#2F6B2A" stroke-width="8">
<path d="M32 110 20 72" /><path d="M60 88 48 46" /><path d="M90 70 82 30" />
<path d="M120 56 114 20" /><path d="M150 44 146 14" /><path d="M180 34 178 10" />
</g>
<g stroke="#3F8A35" stroke-width="8">
<path d="M34 110 44 138" /><path d="M62 88 76 124" /><path d="M92 70 108 104" />
<path d="M122 56 138 88" /><path d="M152 44 168 72" /><path d="M182 34 198 56" />
</g>
</g>
</svg>
</template>

22
components/Logo.vue Normal file
View file

@ -0,0 +1,22 @@
<script setup lang="ts">
withDefaults(defineProps<{ to?: string, sub?: string, compact?: boolean }>(), { to: '/', sub: 'JUNGLE STREET FOOD', compact: false })
</script>
<template>
<NuxtLink :to="to" class="logo" aria-label="PANZAÏ — accueil">
<span class="badge-round"><Toucan :size="compact ? 30 : 38" :branch="false" /></span>
<span class="txt">
<span class="display name">PANZAÏ</span>
<span v-if="!compact" class="sub">{{ sub }}</span>
</span>
</NuxtLink>
</template>
<style scoped>
.logo { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.badge-round { width: 46px; height: 46px; border-radius: 50%; background: linear-gradient(160deg, #5A3A22, #3A2617); border: 2px solid var(--orange-1); display: flex; align-items: center; justify-content: center; overflow: hidden; flex: none; }
.txt { display: flex; flex-direction: column; line-height: 1; }
.name { font-size: 21px; }
.sub { font-size: 10px; font-weight: 700; letter-spacing: 1.4px; opacity: .7; color: var(--cream); margin-top: 3px; }
@media (max-width: 420px) { .sub { display: none; } }
</style>

28
components/MobileBar.vue Normal file
View file

@ -0,0 +1,28 @@
<script setup lang="ts">
// Barre fixe en bas d'écran sur mobile : CTA "Commander" toujours visible
const { count, subtotal } = useCart()
const route = useRoute()
const to = computed(() => count.value ? '/panier' : '/menu')
const hidden = computed(() => route.path.startsWith('/panier') || route.path.startsWith('/commande'))
</script>
<template>
<div v-if="!hidden" class="mbar">
<NuxtLink :to="to" class="btn btn-primary btn-lg inner">
<span>{{ count ? 'Voir le panier' : 'Commander' }}</span>
<ClientOnly>
<span v-if="count" class="sum">{{ count }} article{{ count > 1 ? 's' : '' }} · {{ eur(subtotal) }}</span>
<Icon v-else name="arrow" :stroke="2.6" />
</ClientOnly>
</NuxtLink>
</div>
</template>
<style scoped>
.mbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; padding: 12px 16px calc(14px + env(safe-area-inset-bottom)); background: linear-gradient(180deg, rgba(20,16,13,0), rgba(20,16,13,.96) 35%); }
.inner { width: 100%; justify-content: space-between; padding: 0 8px 0 20px; box-shadow: 0 14px 34px rgba(0,0,0,.55); }
.inner > span:first-child { padding-left: 0; }
.sum { padding: 9px 14px; border-radius: 14px; background: var(--bg); color: var(--cream); font-size: 14px; }
.inner :deep(svg) { margin-right: 12px; }
@media (min-width: 1024px) { .mbar { display: none; } }
</style>

29
components/SiteFooter.vue Normal file
View file

@ -0,0 +1,29 @@
<template>
<footer class="ftr">
<div class="container inner">
<div class="stack" style="gap: 8px">
<p class="display" style="font-size: 30px">PANZAÏ</p>
<p class="muted small">Jungle Street Food · Produits 100 % frais · Wok feu du dragon<br>2 avenue de Champagne, 74200 Thonon-les-Bains · <a href="tel:+33485478262">04 85 47 82 62</a></p>
</div>
<div class="row" style="gap: 10px">
<a class="soc" href="https://instagram.com/panzai.jsf" target="_blank" rel="noopener" aria-label="Instagram"><Icon name="insta" /></a>
<a class="soc" href="https://tiktok.com/@panzai.jsf" target="_blank" rel="noopener" aria-label="TikTok"><Icon name="tiktok" /></a>
</div>
<nav class="row wrap small" style="gap: 18px" aria-label="Liens utiles">
<NuxtLink to="/menu">La carte</NuxtLink>
<NuxtLink to="/#infos">Horaires</NuxtLink>
<a href="#">Mentions légales</a>
<a href="#">CGV</a>
<a href="#">Allergènes</a>
</nav>
<p class="small muted">Site réalisé par <a href="https://knrwebsite.fr" style="font-weight: 800">KNRWebsite</a></p>
</div>
</footer>
</template>
<style scoped>
.ftr { margin-top: 80px; background: var(--bg-deep); border-top: 1px solid rgba(243,227,195,.08); padding: 40px 0 120px; }
.inner { display: flex; flex-wrap: wrap; gap: 24px 40px; align-items: flex-start; justify-content: space-between; }
.soc { width: 44px; height: 44px; border-radius: 14px; background: var(--surface); display: flex; align-items: center; justify-content: center; color: var(--cream); }
@media (min-width: 1024px) { .ftr { padding-bottom: 48px; } }
</style>

50
components/SiteHeader.vue Normal file
View file

@ -0,0 +1,50 @@
<script setup lang="ts">
const { count, bump } = useCart()
const { open, wait } = useShop()
const popping = ref(false)
watch(bump, () => { popping.value = false; requestAnimationFrame(() => { popping.value = true }) })
</script>
<template>
<header class="hdr">
<div class="container row inner">
<Logo />
<nav class="nav" aria-label="Navigation principale">
<NuxtLink to="/menu">Menu</NuxtLink>
<NuxtLink to="/#avis">Avis</NuxtLink>
<NuxtLink to="/#infos">Infos</NuxtLink>
</nav>
<div class="row right">
<span class="status small">
<template v-if="open"><span class="dot dot-green blink" /> Ouvert · ~{{ wait }} min</template>
<template v-else><span class="dot dot-red" /> Commandes en pause</template>
</span>
<NuxtLink to="/panier" class="cartb" :aria-label="`Panier, ${count} article(s)`">
<Icon name="cart" :size="21" />
<ClientOnly><span v-if="count" class="cnt" :class="{ pop: popping }">{{ count }}</span></ClientOnly>
</NuxtLink>
<NuxtLink to="/menu" class="btn btn-primary cta">Commander</NuxtLink>
</div>
</div>
</header>
</template>
<style scoped>
.hdr { position: sticky; top: 0; z-index: 40; background: rgba(20,16,13,.86); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-bottom: 1px solid rgba(243,227,195,.08); }
.inner { gap: 20px; min-height: 70px; }
.nav { display: flex; gap: 14px; font-size: 14px; font-weight: 700; margin-left: auto; }
.nav a { color: var(--cream); text-decoration: none; }
.nav a:hover, .nav a.router-link-exact-active { color: var(--orange-1); }
.right { gap: 12px; }
.status { display: none; align-items: center; gap: 8px; font-weight: 700; }
.cartb { position: relative; width: 44px; height: 44px; border-radius: 14px; background: var(--surface); display: flex; align-items: center; justify-content: center; color: var(--cream); }
.cnt { position: absolute; top: -5px; right: -5px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px; background: var(--orange-2); color: var(--bg); font-size: 11px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.cta { display: none; }
@media (min-width: 900px) {
.nav { gap: 28px; font-size: 15px; margin-left: 12px; }
.right { margin-left: auto; }
.status { display: inline-flex; }
.cta { display: inline-flex; }
}
@media (max-width: 380px) { .nav { gap: 10px; font-size: 13px; } }
</style>

21
components/Toucan.vue Normal file
View file

@ -0,0 +1,21 @@
<script setup lang="ts">
// Toucan provisoire (repère de mise en page) — à remplacer par le logo officiel PANZAÏ
withDefaults(defineProps<{ size?: number, branch?: boolean, label?: string }>(), { size: 120, branch: true, label: '' })
</script>
<template>
<svg viewBox="0 0 160 160" :width="size" :height="size" :role="label ? 'img' : undefined" :aria-label="label || undefined" :aria-hidden="label ? undefined : 'true'">
<path d="M44 132C30 110 30 70 52 52c16-12 32-8 38 8 8 22 2 58-20 76z" fill="#0B0908" stroke="#2A1C12" stroke-width="2" />
<path d="M58 62c8-10 24-8 28 4 2 10-6 20-18 20-8-2-12-12-10-24z" fill="#F3E3C3" />
<path d="M80 52c20-12 60-8 76 10-16 4-46 10-70 8z" fill="#FFB43A" />
<path d="M86 70c24 2 54-4 70-8-6 8-26 14-64 14z" fill="#E8622A" />
<path d="M146 58c4 1 8 2 10 4-3 2-7 3-10 3z" fill="#14100D" />
<circle cx="74" cy="54" r="7" fill="#8CC63F" />
<circle cx="75" cy="54" r="3" fill="#0B0908" />
<template v-if="branch">
<path d="M50 128 38 156l20-8z" fill="#0B0908" />
<rect x="18" y="134" width="124" height="11" rx="5.5" fill="#2A1C12" />
<path d="M60 132v8M72 132v8" stroke="#FFB43A" stroke-width="3" stroke-linecap="round" />
</template>
</svg>
</template>

45
composables/useAdmin.ts Normal file
View file

@ -0,0 +1,45 @@
import type { Order, Settings } from '~/server/utils/store'
export function useOrders() {
return useFetch<Order[]>('/api/orders', { key: 'orders', default: () => [] })
}
export function useAdminSettings() {
return useFetch<Settings>('/api/settings', { key: 'settings' })
}
export async function orderAction(id: string, action: 'accept' | 'refuse' | 'advance' | 'refund', minutes?: number) {
await $fetch(`/api/orders/${id}`, { method: 'PATCH', body: { action, minutes } })
await refreshNuxtData('orders')
}
export async function saveSettings(patch: Partial<Settings>) {
await $fetch('/api/settings', { method: 'PATCH', body: patch })
await refreshNuxtData('settings')
}
// Son de notification (WebAudio — pas de fichier à charger)
let ctx: AudioContext | null = null
export function unlockSound() {
const C = window.AudioContext || (window as any).webkitAudioContext
if (!ctx && C) ctx = new C()
ctx?.resume()
return !!ctx
}
export function ding() {
if (!ctx) return
const t0 = ctx.currentTime
const delays = [0, 0.18, 0.36]
delays.forEach((d, i) => {
const o = ctx!.createOscillator()
const g = ctx!.createGain()
o.type = 'sine'
o.frequency.value = i === 2 ? 1175 : 880
o.connect(g); g.connect(ctx!.destination)
g.gain.setValueAtTime(0.0001, t0 + d)
g.gain.exponentialRampToValueAtTime(0.3, t0 + d + 0.02)
g.gain.exponentialRampToValueAtTime(0.0001, t0 + d + 0.16)
o.start(t0 + d); o.stop(t0 + d + 0.18)
})
}

49
composables/useCart.ts Normal file
View file

@ -0,0 +1,49 @@
import type { Dish, Size } from '~/server/utils/store'
export interface CartLine {
key: string
dishId: string
name: string
img?: string
size: Size
meat: string
sauce?: string
extras: string[]
extrasLabel: string[]
note?: string
qty: number
unit: number
}
export function useCart() {
const lines = useState<CartLine[]>('cart', () => [])
const mode = useState<'livraison' | 'retrait'>('mode', () => 'livraison')
const bump = useState('cartBump', () => 0)
const count = computed(() => lines.value.reduce((a, l) => a + l.qty, 0))
const subtotal = computed(() => lines.value.reduce((a, l) => a + l.unit * l.qty, 0))
function add(line: Omit<CartLine, 'key'>) {
const same = lines.value.find(l => l.dishId === line.dishId && l.size === line.size && l.meat === line.meat
&& l.sauce === line.sauce && l.note === line.note && l.extras.join() === line.extras.join())
if (same) same.qty += line.qty
else lines.value.push({ ...line, key: Math.random().toString(36).slice(2) })
bump.value++
}
function setQty(key: string, qty: number) {
const l = lines.value.find(x => x.key === key)
if (!l) return
if (qty <= 0) lines.value = lines.value.filter(x => x.key !== key)
else l.qty = Math.min(20, qty)
}
function remove(key: string) { lines.value = lines.value.filter(x => x.key !== key) }
function clear() { lines.value = [] }
return { lines, mode, bump, count, subtotal, add, setQty, remove, clear }
}
// Fenêtre de personnalisation d'un plat (partagée par toutes les pages)
export function useCustomize() {
const dish = useState<Dish | null>('customizeDish', () => null)
return { dish, open: (d: Dish) => { dish.value = d }, close: () => { dish.value = null } }
}

23
composables/useShop.ts Normal file
View file

@ -0,0 +1,23 @@
import type { Dish, Extra, Settings } from '~/server/utils/store'
// Carte + réglages du resto, partagés par toutes les pages client.
// Rafraîchis toutes les 10 s pour refléter les changements faits dans le dashboard (rupture, pause…).
export function useShop(opts: { poll?: boolean } = {}) {
const menu = useFetch<{ dishes: Dish[], extras: Extra[] }>('/api/menu', { key: 'menu', default: () => ({ dishes: [], extras: [] }) })
const settings = useFetch<Settings>('/api/settings', { key: 'settings' })
if (import.meta.client && opts.poll) {
const t = setInterval(() => { menu.refresh(); settings.refresh() }, 10000)
onScopeDispose(() => clearInterval(t))
}
const dishes = computed(() => menu.data.value?.dishes || [])
const extras = computed(() => menu.data.value?.extras || [])
const open = computed(() => settings.data.value?.open ?? true)
const wait = computed(() => settings.data.value?.wait ?? 20)
return { dishes, extras, settings: settings.data, open, wait }
}
export const priceOf = (d: Dish, s: 'L' | 'XL') => d.prices[s]
export const sizesOf = (d: Dish) => (['L', 'XL'] as const).filter(s => s in d.prices)
export const orderable = (d: Dish) => d.available && sizesOf(d).some(s => d.prices[s] != null)

12
composables/useToast.ts Normal file
View file

@ -0,0 +1,12 @@
export function useToast() {
const msg = useState<string>('toast', () => '')
let t: ReturnType<typeof setTimeout> | undefined
return {
msg,
show(text: string) {
msg.value = text
clearTimeout(t)
t = setTimeout(() => { msg.value = '' }, 2200)
}
}
}

74
layouts/admin.vue Normal file
View file

@ -0,0 +1,74 @@
<script setup lang="ts">
const links = [
{ to: '/admin', label: 'Commandes', icon: 'kanban' },
{ to: '/admin/menu', label: 'Menu', icon: 'list' },
{ to: '/admin/stats', label: 'Statistiques', icon: 'chart' },
{ to: '/admin/horaires', label: 'Horaires & réglages', icon: 'clock' }
]
useHead({ title: 'PANZAÏ — Espace gérant', meta: [{ name: 'robots', content: 'noindex' }] })
const { data: orders, refresh } = useOrders()
const nNew = computed(() => (orders.value || []).filter(o => o.status === 'new').length)
// Rafraîchit les commandes toutes les 2 s et sonne à chaque nouvelle commande
const sound = useState('adminSound', () => false)
const seen = new Set<string>()
let primed = false
watch(orders, (list) => {
const fresh = (list || []).filter(o => o.status === 'new' && !seen.has(o.id))
;(list || []).forEach(o => seen.add(o.id))
if (primed && fresh.length && sound.value) ding()
primed = true
}, { immediate: true })
onMounted(() => {
const t = setInterval(() => refresh(), 2000)
onBeforeUnmount(() => clearInterval(t))
})
function enableSound() { sound.value = unlockSound(); if (sound.value) ding() }
</script>
<template>
<div class="adm">
<aside class="side">
<div class="brand"><Logo to="/admin" sub="ESPACE GÉRANT" /></div>
<nav aria-label="Dashboard" class="nav">
<NuxtLink v-for="l in links" :key="l.to" :to="l.to" :class="{ on: $route.path === l.to }">
<Icon :name="l.icon" :size="22" />
<span>{{ l.label }}</span>
<span v-if="l.to === '/admin' && nNew" class="cnt">{{ nNew }}</span>
</NuxtLink>
</nav>
<button class="btn soundb" :class="sound ? 'on' : ''" type="button" @click="enableSound">
<Icon name="sound" :size="18" /> {{ sound ? 'Son activé' : 'Activer le son' }}
</button>
<div class="foot">
<a href="/" target="_blank" rel="noopener" class="small"><Icon name="ext" :size="14" /> Voir le site client</a>
<p class="small muted">Propulsé par KNRWebsite</p>
</div>
</aside>
<div class="main"><slot /></div>
</div>
</template>
<style scoped>
.adm { min-height: 100vh; display: flex; flex-wrap: wrap; }
.side { flex: 1 1 220px; max-width: 240px; min-width: 200px; padding: 20px 14px; background: #100D0A; border-right: 1px solid rgba(243,227,195,.08); display: flex; flex-direction: column; gap: 22px; }
.brand { padding: 0 6px; }
.nav { display: flex; flex-direction: column; gap: 4px; }
.nav a { display: flex; align-items: center; gap: 12px; min-height: 54px; padding: 0 14px; border-radius: 14px; color: var(--cream); text-decoration: none; font-weight: 700; font-size: 15px; }
.nav a:hover { background: var(--surface); }
.nav a.on { background: rgba(255,180,58,.14); color: var(--orange-1); }
.cnt { margin-left: auto; min-width: 26px; height: 26px; padding: 0 7px; border-radius: 13px; background: var(--orange-2); color: var(--bg); font-size: 13px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.soundb { background: var(--surface); color: var(--cream); border: 1px dashed rgba(243,227,195,.3); font-size: 14px; }
.soundb.on { border: 1px solid rgba(140,198,63,.5); color: var(--leaf); }
.foot { margin-top: auto; display: flex; flex-direction: column; gap: 6px; padding: 0 8px; }
.foot a { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; text-decoration: none; }
.main { flex: 999 1 560px; min-width: 0; padding: 22px clamp(14px, 2vw, 28px) 32px; }
@media (max-width: 860px) {
.side { max-width: none; flex-basis: 100%; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 10px; border-right: 0; border-bottom: 1px solid rgba(243,227,195,.08); padding: 12px; }
.nav { flex-direction: row; overflow-x: auto; flex: 1 1 100%; order: 3; }
.nav a { flex: none; min-height: 46px; }
.soundb { margin-left: auto; }
.foot { display: none; }
}
</style>

15
layouts/default.vue Normal file
View file

@ -0,0 +1,15 @@
<script setup lang="ts">
useShop({ poll: true })
const { msg } = useToast()
</script>
<template>
<div>
<SiteHeader />
<slot />
<SiteFooter />
<MobileBar />
<CustomizeModal />
<div v-if="msg" class="toast" role="status">{{ msg }}</div>
</div>
</template>

1
node_modules/.bin/acorn generated vendored Symbolic link
View file

@ -0,0 +1 @@
../acorn/bin/acorn

1
node_modules/.bin/autoprefixer generated vendored Symbolic link
View file

@ -0,0 +1 @@
../autoprefixer/bin/autoprefixer

1
node_modules/.bin/baseline-browser-mapping generated vendored Symbolic link
View file

@ -0,0 +1 @@
../baseline-browser-mapping/dist/cli.cjs

1
node_modules/.bin/browserslist generated vendored Symbolic link
View file

@ -0,0 +1 @@
../browserslist/cli.js

1
node_modules/.bin/crc32 generated vendored Symbolic link
View file

@ -0,0 +1 @@
../crc-32/bin/crc32.njs

1
node_modules/.bin/cssesc generated vendored Symbolic link
View file

@ -0,0 +1 @@
../cssesc/bin/cssesc

1
node_modules/.bin/devtools generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/devtools/cli.mjs

1
node_modules/.bin/devtools-wizard generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/devtools-wizard/cli.mjs

1
node_modules/.bin/esbuild generated vendored Symbolic link
View file

@ -0,0 +1 @@
../esbuild/bin/esbuild

1
node_modules/.bin/fast-npm-meta generated vendored Symbolic link
View file

@ -0,0 +1 @@
../fast-npm-meta/dist/cli.mjs

1
node_modules/.bin/giget generated vendored Symbolic link
View file

@ -0,0 +1 @@
../giget/dist/cli.mjs

1
node_modules/.bin/is-docker generated vendored Symbolic link
View file

@ -0,0 +1 @@
../is-docker/cli.js

1
node_modules/.bin/is-inside-container generated vendored Symbolic link
View file

@ -0,0 +1 @@
../is-inside-container/cli.js

1
node_modules/.bin/jiti generated vendored Symbolic link
View file

@ -0,0 +1 @@
../jiti/lib/jiti-cli.mjs

1
node_modules/.bin/jsesc generated vendored Symbolic link
View file

@ -0,0 +1 @@
../jsesc/bin/jsesc

1
node_modules/.bin/json5 generated vendored Symbolic link
View file

@ -0,0 +1 @@
../json5/lib/cli.js

1
node_modules/.bin/listen generated vendored Symbolic link
View file

@ -0,0 +1 @@
../listhen/bin/listhen.mjs

1
node_modules/.bin/listhen generated vendored Symbolic link
View file

@ -0,0 +1 @@
../listhen/bin/listhen.mjs

1
node_modules/.bin/mime generated vendored Symbolic link
View file

@ -0,0 +1 @@
../mime/bin/cli.js

1
node_modules/.bin/nanoid generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs

1
node_modules/.bin/nft generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@vercel/nft/out/cli.js

1
node_modules/.bin/nitro generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nitropack/dist/cli/index.mjs

1
node_modules/.bin/nitropack generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nitropack/dist/cli/index.mjs

1
node_modules/.bin/node-gyp-build generated vendored Symbolic link
View file

@ -0,0 +1 @@
../node-gyp-build/bin.js

1
node_modules/.bin/node-gyp-build-optional generated vendored Symbolic link
View file

@ -0,0 +1 @@
../node-gyp-build/optional.js

1
node_modules/.bin/node-gyp-build-test generated vendored Symbolic link
View file

@ -0,0 +1 @@
../node-gyp-build/build-test.js

1
node_modules/.bin/node-pre-gyp generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@mapbox/node-pre-gyp/bin/node-pre-gyp

1
node_modules/.bin/node-which generated vendored Symbolic link
View file

@ -0,0 +1 @@
../which/bin/which.js

1
node_modules/.bin/nopt generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nopt/bin/nopt.js

1
node_modules/.bin/nuxi generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/cli/bin/nuxi.mjs

1
node_modules/.bin/nuxi-ng generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/cli/bin/nuxi.mjs

1
node_modules/.bin/nuxt generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/cli/bin/nuxi.mjs

1
node_modules/.bin/nuxt-cli generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/cli/bin/nuxi.mjs

1
node_modules/.bin/nuxt-telemetry generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@nuxt/telemetry/bin/nuxt-telemetry.mjs

1
node_modules/.bin/nypm generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nypm/dist/cli.mjs

1
node_modules/.bin/parser generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@babel/parser/bin/babel-parser.js

1
node_modules/.bin/resolve generated vendored Symbolic link
View file

@ -0,0 +1 @@
../resolve/bin/resolve

1
node_modules/.bin/rolldown generated vendored Symbolic link
View file

@ -0,0 +1 @@
../rolldown/bin/cli.mjs

1
node_modules/.bin/rollup generated vendored Symbolic link
View file

@ -0,0 +1 @@
../rollup/dist/bin/rollup

1
node_modules/.bin/rollup-plugin-visualizer generated vendored Symbolic link
View file

@ -0,0 +1 @@
../rollup-plugin-visualizer/dist/bin/cli.js

1
node_modules/.bin/semver generated vendored Symbolic link
View file

@ -0,0 +1 @@
../semver/bin/semver.js

1
node_modules/.bin/srvx generated vendored Symbolic link
View file

@ -0,0 +1 @@
../srvx/bin/srvx.mjs

1
node_modules/.bin/svgo generated vendored Symbolic link
View file

@ -0,0 +1 @@
../svgo/bin/svgo.js

1
node_modules/.bin/tab generated vendored Symbolic link
View file

@ -0,0 +1 @@
../@bomb.sh/tab/dist/bin/cli.mjs

1
node_modules/.bin/terser generated vendored Symbolic link
View file

@ -0,0 +1 @@
../terser/bin/terser

Some files were not shown because too many files have changed in this diff Show more