@sanidesk/site-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -0
- package/dist/asset.d.ts +27 -0
- package/dist/asset.d.ts.map +1 -0
- package/dist/components/AddressBlock.vue.d.ts +41 -0
- package/dist/components/AddressBlock.vue.d.ts.map +1 -0
- package/dist/components/ContactForm.vue.d.ts +36 -0
- package/dist/components/ContactForm.vue.d.ts.map +1 -0
- package/dist/components/FeaturedItems.vue.d.ts +29 -0
- package/dist/components/FeaturedItems.vue.d.ts.map +1 -0
- package/dist/components/HoursBlock.vue.d.ts +32 -0
- package/dist/components/HoursBlock.vue.d.ts.map +1 -0
- package/dist/components/MenuPreview.vue.d.ts +26 -0
- package/dist/components/MenuPreview.vue.d.ts.map +1 -0
- package/dist/components/PoweredBy.vue.d.ts +21 -0
- package/dist/components/PoweredBy.vue.d.ts.map +1 -0
- package/dist/components/PublicFloorplanViewer.vue.d.ts +26 -0
- package/dist/components/PublicFloorplanViewer.vue.d.ts.map +1 -0
- package/dist/components/ReservationForm.vue.d.ts +103 -0
- package/dist/components/ReservationForm.vue.d.ts.map +1 -0
- package/dist/components/SocialLinks.vue.d.ts +31 -0
- package/dist/components/SocialLinks.vue.d.ts.map +1 -0
- package/dist/composables/use-contact-form.d.ts +45 -0
- package/dist/composables/use-contact-form.d.ts.map +1 -0
- package/dist/composables/use-featured-items.d.ts +40 -0
- package/dist/composables/use-featured-items.d.ts.map +1 -0
- package/dist/composables/use-hours-block.d.ts +78 -0
- package/dist/composables/use-hours-block.d.ts.map +1 -0
- package/dist/composables/use-menu-preview.d.ts +23 -0
- package/dist/composables/use-menu-preview.d.ts.map +1 -0
- package/dist/composables/use-reservation-form.d.ts +171 -0
- package/dist/composables/use-reservation-form.d.ts.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1083 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# @sanidesk/site-kit
|
|
2
|
+
|
|
3
|
+
> Headless Vue 3 primitives for SaniDesk tenant public sites.
|
|
4
|
+
|
|
5
|
+
Use these components when building a tenant template against the SaniDesk platform. Each primitive handles data fetching, state, and integration glue (API calls, deep-link construction, validation). **Markup and styles are owned by your template** via scoped slots — there is no opinionated design system here, so you can match any brand.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm add @sanidesk/site-kit vue
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`vue@^3.5` is a peer dependency — install it in your template repo if it isn't already.
|
|
14
|
+
|
|
15
|
+
## Asset helper — `createAssetFn`
|
|
16
|
+
|
|
17
|
+
Asset URLs for template-shipped files (logos, fonts, hero images) need to resolve correctly across three environments: standalone Vite dev, monorepo Nuxt dev, and production CDN. The helper abstracts that.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// templates/my-tenant/lib/asset.ts
|
|
21
|
+
import { createAssetFn } from '@sanidesk/site-kit';
|
|
22
|
+
|
|
23
|
+
export const asset = createAssetFn('my-tenant'); // your tenant slug
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```vue
|
|
27
|
+
<!-- anywhere in your template -->
|
|
28
|
+
<script setup>
|
|
29
|
+
import { asset } from '../lib/asset';
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<img :src="asset('hero.jpg')" alt="Hero" />
|
|
34
|
+
<img :srcset="`${asset('logo-480.webp')} 480w, ${asset('logo.webp')} 1280w`" />
|
|
35
|
+
</template>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Resolution modes (the helper picks automatically):
|
|
39
|
+
- **Standalone Vite** (`VITE_TEMPLATE_LOCAL=true`): `/assets/<path>` — Vite serves your template's `assets/` folder
|
|
40
|
+
- **Monorepo Nuxt fallback**: `/templates/<slug>/assets/<path>` — the platform's Nitro dev server serves from disk
|
|
41
|
+
- **Production CDN**: `https://cdn.sanidesk.ch/templates/<slug>/v<N>/assets/<path>` — versioned, immutable, long-cache
|
|
42
|
+
|
|
43
|
+
Absolute URLs (`https://...`) pass through unchanged.
|
|
44
|
+
|
|
45
|
+
## Components
|
|
46
|
+
|
|
47
|
+
All components follow the same pattern: a prop-driven container that fetches the data and exposes it via a default scoped slot. The slot lets you render whatever markup matches your template's aesthetic.
|
|
48
|
+
|
|
49
|
+
### MenuPreview
|
|
50
|
+
|
|
51
|
+
Fetches a tenant's menu (sections + items) and renders via slot.
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<MenuPreview :tenant-slug="slug" :menu-slug="'main'">
|
|
55
|
+
<template #default="{ menu, loading, error }">
|
|
56
|
+
<div v-if="loading">Loading...</div>
|
|
57
|
+
<div v-else-if="error">Sorry, couldn't load the menu.</div>
|
|
58
|
+
<section v-for="section in menu.sections" :key="section.id">
|
|
59
|
+
<h3>{{ section.name }}</h3>
|
|
60
|
+
<ul>
|
|
61
|
+
<li v-for="item in section.items" :key="item.id">
|
|
62
|
+
{{ item.name }} — {{ item.price_cents / 100 }} CHF
|
|
63
|
+
</li>
|
|
64
|
+
</ul>
|
|
65
|
+
</section>
|
|
66
|
+
</template>
|
|
67
|
+
</MenuPreview>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### FeaturedItems
|
|
71
|
+
|
|
72
|
+
Catalog items tagged "signature" or "featured" — useful for landing-page teasers.
|
|
73
|
+
|
|
74
|
+
```vue
|
|
75
|
+
<FeaturedItems :tenant-slug="slug" :limit="6" tag="signature">
|
|
76
|
+
<template #default="{ items, loading }">
|
|
77
|
+
<article v-for="item in items" :key="item.id">
|
|
78
|
+
<h4>{{ item.name }}</h4>
|
|
79
|
+
<p>{{ item.description }}</p>
|
|
80
|
+
</article>
|
|
81
|
+
</template>
|
|
82
|
+
</FeaturedItems>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### AddressBlock
|
|
86
|
+
|
|
87
|
+
Renders the tenant's address. Pass the `businessInfo` from `useTenant()`.
|
|
88
|
+
|
|
89
|
+
```vue
|
|
90
|
+
<AddressBlock :business-info="businessInfo">
|
|
91
|
+
<template #default="{ formatted }">
|
|
92
|
+
<p>{{ formatted }}</p>
|
|
93
|
+
</template>
|
|
94
|
+
</AddressBlock>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### HoursBlock
|
|
98
|
+
|
|
99
|
+
Opening hours + this-week schedule + next-open computation.
|
|
100
|
+
|
|
101
|
+
```vue
|
|
102
|
+
<HoursBlock :tenant-slug="slug">
|
|
103
|
+
<template #default="{ week, isOpenNow, nextOpen }">
|
|
104
|
+
<p v-if="isOpenNow">Open now</p>
|
|
105
|
+
<p v-else-if="nextOpen">Next open: {{ nextOpen.day }} at {{ nextOpen.time }}</p>
|
|
106
|
+
<ul>
|
|
107
|
+
<li v-for="day in week" :key="day.weekday">
|
|
108
|
+
{{ day.weekday }}: {{ day.label }}
|
|
109
|
+
</li>
|
|
110
|
+
</ul>
|
|
111
|
+
</template>
|
|
112
|
+
</HoursBlock>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### SocialLinks
|
|
116
|
+
|
|
117
|
+
Filtered list of social links from tenant branding (Instagram, Facebook, etc).
|
|
118
|
+
|
|
119
|
+
```vue
|
|
120
|
+
<SocialLinks :branding="branding">
|
|
121
|
+
<template #default="{ links }">
|
|
122
|
+
<a v-for="link in links" :key="link.platform" :href="link.url">
|
|
123
|
+
{{ link.platform }}
|
|
124
|
+
</a>
|
|
125
|
+
</template>
|
|
126
|
+
</SocialLinks>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### ContactForm
|
|
130
|
+
|
|
131
|
+
Sends through the tenant's per-tenant mail account. Spam-protected, rate-limited.
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<ContactForm :tenant-slug="slug">
|
|
135
|
+
<template #default="{ submit, fields, loading, submitted }">
|
|
136
|
+
<form v-if="!submitted" @submit.prevent="submit">
|
|
137
|
+
<input v-model="fields.name" placeholder="Your name" />
|
|
138
|
+
<input v-model="fields.email" type="email" placeholder="Email" />
|
|
139
|
+
<textarea v-model="fields.message" />
|
|
140
|
+
<button :disabled="loading">Send</button>
|
|
141
|
+
</form>
|
|
142
|
+
<p v-else>Thanks — we'll get back to you soon.</p>
|
|
143
|
+
</template>
|
|
144
|
+
</ContactForm>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### ReservationForm
|
|
148
|
+
|
|
149
|
+
Restaurant-vertical reservation flow (date/time → table → contact). Pulls available slots from the tenant's reservations module.
|
|
150
|
+
|
|
151
|
+
```vue
|
|
152
|
+
<ReservationForm :tenant-slug="slug">
|
|
153
|
+
<template #default="{ step, slots, selectSlot, ... }">
|
|
154
|
+
<!-- multi-step UI -->
|
|
155
|
+
</template>
|
|
156
|
+
</ReservationForm>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### PublicFloorplanViewer
|
|
160
|
+
|
|
161
|
+
Read-only SVG floorplan viewer used inside ReservationForm — typically you won't import this directly.
|
|
162
|
+
|
|
163
|
+
### PoweredBy
|
|
164
|
+
|
|
165
|
+
A simple "Powered by SaniDesk" badge with link. Required in template footers per the platform contract.
|
|
166
|
+
|
|
167
|
+
```vue
|
|
168
|
+
<PoweredBy />
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Composables (without the wrapper component)
|
|
172
|
+
|
|
173
|
+
If you don't want the components' default markup pattern, you can call the composables directly and build your own UI:
|
|
174
|
+
|
|
175
|
+
- `useMenuPreview({ tenantSlug, menuSlug })`
|
|
176
|
+
- `useFeaturedItems({ tenantSlug, tag, limit })`
|
|
177
|
+
- `useHoursBlock({ tenantSlug })`
|
|
178
|
+
- `useReservationForm({ tenantSlug })`
|
|
179
|
+
|
|
180
|
+
Each returns reactive refs and async functions. See the `.d.ts` files in `node_modules/@sanidesk/site-kit/dist/composables/` for full signatures.
|
|
181
|
+
|
|
182
|
+
## Tenant context — `useTenant()`
|
|
183
|
+
|
|
184
|
+
Templates render against a tenant context provided by the platform's Nuxt host. Inside a template page you get `tenant`, `branding`, `businessInfo`, etc. injected automatically — see `apps/sites/app/composables/use-tenant.ts` in the platform monorepo. Your template just declares page-level props:
|
|
185
|
+
|
|
186
|
+
```vue
|
|
187
|
+
<script setup lang="ts">
|
|
188
|
+
import type { Tenant, TenantBranding } from '@sanidesk/types';
|
|
189
|
+
|
|
190
|
+
defineProps<{
|
|
191
|
+
slug: string;
|
|
192
|
+
tenant: Tenant | null;
|
|
193
|
+
branding: TenantBranding | null;
|
|
194
|
+
}>();
|
|
195
|
+
</script>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Source + design rationale
|
|
199
|
+
|
|
200
|
+
Source: [github.com/sanigear/sanidesk/tree/main/packages/site-kit](https://github.com/sanigear/sanidesk/tree/main/packages/site-kit)
|
|
201
|
+
|
|
202
|
+
Design doc: `docs/SITE-KIT.md` in the source repo.
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
UNLICENSED — for use within the SaniDesk platform and authorized tenant template engagements.
|
package/dist/asset.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface AssetConfig {
|
|
2
|
+
/** When true, the template is being served by its own standalone Vite
|
|
3
|
+
* (TP5 frontend-developer workflow). `asset()` resolves to `/assets/<path>`. */
|
|
4
|
+
local?: boolean;
|
|
5
|
+
/** Per-slug version map injected by the release worker (TP6). Slugs not in
|
|
6
|
+
* the map fall back to the monorepo URL pattern. */
|
|
7
|
+
versions?: Record<string, string>;
|
|
8
|
+
/** CDN origin. Defaults to `https://cdn.sanidesk.ch`. */
|
|
9
|
+
cdnBase?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build the resolved URL for one (slug, path) pair under one config. Exported
|
|
13
|
+
* for testability; production code calls `createAssetFn(slug)` and uses the
|
|
14
|
+
* returned closure.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveAssetUrl(slug: string, path: string, config: AssetConfig): string;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a slug-bound `asset(path)` function. Each tenant template calls
|
|
19
|
+
* this exactly once (in `lib/asset.ts`) and re-exports the result. Every
|
|
20
|
+
* other file imports the bound `asset` from there.
|
|
21
|
+
*
|
|
22
|
+
* @param slug Tenant template slug, e.g. `'medusabar'`.
|
|
23
|
+
* @param configOverride Test-only. Production code omits this and the config
|
|
24
|
+
* is read from `import.meta.env` at module init time.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createAssetFn(slug: string, configOverride?: AssetConfig): (path: string) => string;
|
|
27
|
+
//# sourceMappingURL=asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,WAAW;IAC1B;qFACiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;yDACqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4CD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,GAClB,MAAM,CAiBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,WAAW,GAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAM1B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { TenantBusinessInfo } from '@sanidesk/types';
|
|
2
|
+
export interface AddressBlockProps {
|
|
3
|
+
/** Pass through whatever `useTenant().businessInfo` returns. */
|
|
4
|
+
info: TenantBusinessInfo | null;
|
|
5
|
+
}
|
|
6
|
+
export interface AddressBlockSlotProps {
|
|
7
|
+
legalName: string | null;
|
|
8
|
+
street: string | null;
|
|
9
|
+
postalCode: string | null;
|
|
10
|
+
city: string | null;
|
|
11
|
+
country: string;
|
|
12
|
+
/** Single-line address, e.g. `"Chaltenbodenstrasse 16, 8834 Schindellegi"`. */
|
|
13
|
+
fullAddress: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Address split into display lines for multi-line layouts:
|
|
16
|
+
* line 1 → street + house number
|
|
17
|
+
* line 2 → "8834 Schindellegi" (Swiss order: postal code, then city)
|
|
18
|
+
* Empty parts are dropped so callers can `<li v-for>` without conditionals.
|
|
19
|
+
*/
|
|
20
|
+
addressLines: string[];
|
|
21
|
+
phone: string | null;
|
|
22
|
+
email: string | null;
|
|
23
|
+
/** Google Maps deep link, derived from street + postal + city. `null` when address incomplete. */
|
|
24
|
+
mapsUrl: string | null;
|
|
25
|
+
/** `tel:` link respecting the stored format. */
|
|
26
|
+
telHref: string | null;
|
|
27
|
+
/** `mailto:` link. */
|
|
28
|
+
mailHref: string | null;
|
|
29
|
+
}
|
|
30
|
+
type __VLS_Slots = {
|
|
31
|
+
default(slotProps: AddressBlockSlotProps): unknown;
|
|
32
|
+
};
|
|
33
|
+
declare const __VLS_component: import("vue").DefineComponent<AddressBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AddressBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
35
|
+
export default _default;
|
|
36
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
37
|
+
new (): {
|
|
38
|
+
$slots: S;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=AddressBlock.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddressBlock.vue.d.ts","sourceRoot":"","sources":["../../src/components/AddressBlock.vue"],"names":[],"mappings":"AA2FA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kGAAkG;IAClG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gDAAgD;IAChD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAoCD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACpD,CAAC;AA+CF,QAAA,MAAM,eAAe,8SAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ContactFormState, type ContactFormErrors } from '../composables/use-contact-form';
|
|
2
|
+
export interface ContactFormProps {
|
|
3
|
+
/** Tenant slug. */
|
|
4
|
+
slug: string;
|
|
5
|
+
/** Destination address — must be a registered tenant_email_account. */
|
|
6
|
+
toEmail: string;
|
|
7
|
+
/** API base, default `/api`. */
|
|
8
|
+
apiBase?: string;
|
|
9
|
+
/** Localized error strings — defaults are English. */
|
|
10
|
+
messages?: {
|
|
11
|
+
required?: string;
|
|
12
|
+
invalidEmail?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface ContactFormSlotProps {
|
|
16
|
+
form: ContactFormState;
|
|
17
|
+
errors: ContactFormErrors;
|
|
18
|
+
submitting: boolean;
|
|
19
|
+
submitted: boolean;
|
|
20
|
+
serverError: string | null;
|
|
21
|
+
isValid: boolean;
|
|
22
|
+
submit: () => Promise<boolean>;
|
|
23
|
+
reset: () => void;
|
|
24
|
+
}
|
|
25
|
+
type __VLS_Slots = {
|
|
26
|
+
default(slotProps: ContactFormSlotProps): unknown;
|
|
27
|
+
};
|
|
28
|
+
declare const __VLS_component: import("vue").DefineComponent<ContactFormProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ContactFormProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
29
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
30
|
+
export default _default;
|
|
31
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
32
|
+
new (): {
|
|
33
|
+
$slots: S;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=ContactForm.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContactForm.vue.d.ts","sourceRoot":"","sources":["../../src/components/ContactForm.vue"],"names":[],"mappings":"AA2DA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAcD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAAC;CACnD,CAAC;AA8CF,QAAA,MAAM,eAAe,4SAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type PublicCatalogItem } from '../composables/use-featured-items';
|
|
2
|
+
export interface FeaturedItemsProps {
|
|
3
|
+
/** Tenant slug — usually `tenant.value.slug`. */
|
|
4
|
+
slug: string;
|
|
5
|
+
/** Filter by tag (e.g. `"signature"`, `"staff-pick"`). */
|
|
6
|
+
tag?: string;
|
|
7
|
+
/** Cap the rendered list. */
|
|
8
|
+
limit?: number;
|
|
9
|
+
/** API base, default `/api`. */
|
|
10
|
+
apiBase?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface FeaturedItemsSlotProps {
|
|
13
|
+
items: PublicCatalogItem[];
|
|
14
|
+
loading: boolean;
|
|
15
|
+
error: Error | null;
|
|
16
|
+
refresh: () => Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
type __VLS_Slots = {
|
|
19
|
+
default(slotProps: FeaturedItemsSlotProps): unknown;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_component: import("vue").DefineComponent<FeaturedItemsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FeaturedItemsProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
23
|
+
export default _default;
|
|
24
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
25
|
+
new (): {
|
|
26
|
+
$slots: S;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=FeaturedItems.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeaturedItems.vue.d.ts","sourceRoot":"","sources":["../../src/components/FeaturedItems.vue"],"names":[],"mappings":"AAgDA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAYD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,sBAAsB,GAAG,OAAO,CAAC;CACrD,CAAC;AAsCF,QAAA,MAAM,eAAe,gTAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type WeekDay, type WeekGroup, type DateOverrideWithName, type NextOpenSlot } from '../composables/use-hours-block';
|
|
2
|
+
export interface HoursBlockProps {
|
|
3
|
+
/** Tenant slug — usually `tenant.value.slug`. */
|
|
4
|
+
slug: string;
|
|
5
|
+
/** API base, default `/api`. */
|
|
6
|
+
apiBase?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HoursBlockSlotProps {
|
|
9
|
+
/** Per-day view in Mo→Su order. */
|
|
10
|
+
week: WeekDay[];
|
|
11
|
+
/** Same data as `week`, with consecutive identical days collapsed. */
|
|
12
|
+
weekCompact: WeekGroup[];
|
|
13
|
+
upcomingOverrides: DateOverrideWithName[];
|
|
14
|
+
isOpenNow: boolean;
|
|
15
|
+
nextOpenSlot: NextOpenSlot | null;
|
|
16
|
+
timezone: string;
|
|
17
|
+
loading: boolean;
|
|
18
|
+
error: Error | null;
|
|
19
|
+
refresh: () => Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
type __VLS_Slots = {
|
|
22
|
+
default(slotProps: HoursBlockSlotProps): unknown;
|
|
23
|
+
};
|
|
24
|
+
declare const __VLS_component: import("vue").DefineComponent<HoursBlockProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<HoursBlockProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=HoursBlock.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HoursBlock.vue.d.ts","sourceRoot":"","sources":["../../src/components/HoursBlock.vue"],"names":[],"mappings":"AAyDA,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,sEAAsE;IACtE,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAUD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC;CAClD,CAAC;AAgDF,QAAA,MAAM,eAAe,0SAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MenuFull, MenuItemFull } from '@sanidesk/types';
|
|
2
|
+
export interface MenuPreviewProps {
|
|
3
|
+
slug: string;
|
|
4
|
+
apiBase?: string;
|
|
5
|
+
limit?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface MenuPreviewSlotProps {
|
|
8
|
+
items: MenuItemFull[];
|
|
9
|
+
menus: MenuFull[];
|
|
10
|
+
loading: boolean;
|
|
11
|
+
error: Error | null;
|
|
12
|
+
orderHref: string;
|
|
13
|
+
refresh: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
type __VLS_Slots = {
|
|
16
|
+
default(slotProps: MenuPreviewSlotProps): unknown;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_component: import("vue").DefineComponent<MenuPreviewProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<MenuPreviewProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
20
|
+
export default _default;
|
|
21
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
22
|
+
new (): {
|
|
23
|
+
$slots: S;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=MenuPreview.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuPreview.vue.d.ts","sourceRoot":"","sources":["../../src/components/MenuPreview.vue"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAWD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAAC;CACnD,CAAC;AA0CF,QAAA,MAAM,eAAe,4SAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PoweredByProps {
|
|
2
|
+
variant?: 'wordmark' | 'icon';
|
|
3
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
|
+
theme?: 'light' | 'dark';
|
|
5
|
+
/** Override the "powered by" prefix text. */
|
|
6
|
+
label?: string;
|
|
7
|
+
/** Hide the "powered by" prefix entirely. */
|
|
8
|
+
hideLabel?: boolean;
|
|
9
|
+
/** Override the link target. */
|
|
10
|
+
href?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: import("vue").DefineComponent<PoweredByProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<PoweredByProps> & Readonly<{}>, {
|
|
13
|
+
variant: "wordmark" | "icon";
|
|
14
|
+
size: "sm" | "md" | "lg";
|
|
15
|
+
theme: "light" | "dark";
|
|
16
|
+
label: string;
|
|
17
|
+
hideLabel: boolean;
|
|
18
|
+
href: string;
|
|
19
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
export default _default;
|
|
21
|
+
//# sourceMappingURL=PoweredBy.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoweredBy.vue.d.ts","sourceRoot":"","sources":["../../src/components/PoweredBy.vue"],"names":[],"mappings":"AA4LA,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;aATW,UAAU,GAAG,MAAM;UACtB,IAAI,GAAG,IAAI,GAAG,IAAI;WACjB,OAAO,GAAG,MAAM;WAEhB,MAAM;eAEF,OAAO;UAEZ,MAAM;;AAyMf,wBAOG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PublicTableRow } from '../composables/use-reservation-form';
|
|
2
|
+
export type TableState = 'available' | 'unavailable' | 'selected';
|
|
3
|
+
export interface PublicFloorplanViewerProps {
|
|
4
|
+
/** Floorplan data — the `data` field of the API's `floor_plan` payload. */
|
|
5
|
+
data: unknown;
|
|
6
|
+
/** Bookable tables list — used to map object_id ↔ db id. */
|
|
7
|
+
tables: PublicTableRow[];
|
|
8
|
+
/** Currently picked table db id, or empty string when none. */
|
|
9
|
+
pickedTableId: string;
|
|
10
|
+
/** Db ids of tables that fit the current party size. */
|
|
11
|
+
fittingTableIds: string[];
|
|
12
|
+
/** Allow taps on available/selected tables. Defaults to true. */
|
|
13
|
+
tappable?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface PublicFloorplanViewerEmits {
|
|
16
|
+
(e: 'select', tableDbId: string): void;
|
|
17
|
+
}
|
|
18
|
+
declare const _default: import("vue").DefineComponent<PublicFloorplanViewerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
19
|
+
select: (tableDbId: string) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<PublicFloorplanViewerProps> & Readonly<{
|
|
21
|
+
onSelect?: ((tableDbId: string) => any) | undefined;
|
|
22
|
+
}>, {
|
|
23
|
+
tappable: boolean;
|
|
24
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
export default _default;
|
|
26
|
+
//# sourceMappingURL=PublicFloorplanViewer.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicFloorplanViewer.vue.d.ts","sourceRoot":"","sources":["../../src/components/PublicFloorplanViewer.vue"],"names":[],"mappings":"AAqVA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAmD1E,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAElE,MAAM,WAAW,0BAA0B;IACzC,2EAA2E;IAC3E,IAAI,EAAE,OAAO,CAAC;IACd,4DAA4D;IAC5D,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;;;;;;cALY,OAAO;;AAkVpB,wBAQG"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type ReservationFormState, type ReservationFormErrors, type AvailabilitySlot, type AlternativeSlot, type PublicFloorplan, type PublicFloorPlanEntry, type PublicTableRow, type ReservationSpec, type SubmitResult, type FormStep } from '../composables/use-reservation-form';
|
|
2
|
+
/**
|
|
3
|
+
* Renderless three-step reservation widget. Templates own all chrome —
|
|
4
|
+
* this component provides state + actions through the default slot, the
|
|
5
|
+
* same way ContactForm does.
|
|
6
|
+
*
|
|
7
|
+
* Step 1 — Wann: pick date + time + party_size. Slot grid auto-loads on
|
|
8
|
+
* date/party change (debounced via watch).
|
|
9
|
+
* Step 2 — Tisch: 'auto' (server picks) or 'pick' (floorplan + fitting
|
|
10
|
+
* tables glow). Floorplan is fetched once on first entry to step 2.
|
|
11
|
+
* Step 3 — Kontakt: name + phone/email + occasion/notes + honeypot.
|
|
12
|
+
*
|
|
13
|
+
* After submit:
|
|
14
|
+
* - status === 'confirmed' → state.step = 'confirmed', `result.cancel_token` populated
|
|
15
|
+
* - status === 'pending_manual' → state.step = 'pending'
|
|
16
|
+
*/
|
|
17
|
+
export interface ReservationFormProps {
|
|
18
|
+
/** Tenant slug — same as MenuPreview etc. */
|
|
19
|
+
slug: string;
|
|
20
|
+
/** API base, defaults to `/api`. */
|
|
21
|
+
apiBase?: string;
|
|
22
|
+
/** Initial party size. Defaults to 2. */
|
|
23
|
+
initialPartySize?: number;
|
|
24
|
+
/** Initial date (YYYY-MM-DD). Defaults to today. */
|
|
25
|
+
initialDate?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Pre-fill contact-step fields. Templates pass last-used values from
|
|
28
|
+
* `useCustomerProfileCache(tenantSlug)` so returning customers see
|
|
29
|
+
* their info already filled in. Empty / undefined leaves blank.
|
|
30
|
+
*/
|
|
31
|
+
initialContact?: {
|
|
32
|
+
first_name?: string;
|
|
33
|
+
last_name?: string;
|
|
34
|
+
email?: string;
|
|
35
|
+
phone?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Locale snapshot saved on the reservation (drives reminder/confirmation
|
|
38
|
+
* email locale). Falls back to `navigator.language`. */
|
|
39
|
+
customerLocale?: string;
|
|
40
|
+
/** Localized error messages (en defaults). */
|
|
41
|
+
messages?: {
|
|
42
|
+
requiredField?: string;
|
|
43
|
+
invalidEmail?: string;
|
|
44
|
+
phoneOrEmail?: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export interface ReservationFormSlotProps {
|
|
48
|
+
state: ReservationFormState;
|
|
49
|
+
errors: ReservationFormErrors;
|
|
50
|
+
serverError: string | null;
|
|
51
|
+
loading: boolean;
|
|
52
|
+
submitting: boolean;
|
|
53
|
+
result: SubmitResult | null;
|
|
54
|
+
slots: AvailabilitySlot[];
|
|
55
|
+
alternatives: AlternativeSlot[];
|
|
56
|
+
floorplan: PublicFloorplan | null;
|
|
57
|
+
/** Active plan id (driven by setActiveFloorPlan) — drives the pill
|
|
58
|
+
* toggle on tenants with multiple plans (e.g. main + terrace). */
|
|
59
|
+
activeFloorPlanId: string | null;
|
|
60
|
+
activeFloorPlan: PublicFloorPlanEntry | null;
|
|
61
|
+
activeTables: PublicTableRow[];
|
|
62
|
+
fittingTableIds: string[];
|
|
63
|
+
hasAnyAvailability: boolean;
|
|
64
|
+
/** Tenant rules — null until /spec returns. Templates use it for
|
|
65
|
+
* `min/max` on the date input and the oversized-party CTA. */
|
|
66
|
+
spec: ReservationSpec | null;
|
|
67
|
+
minDate: string;
|
|
68
|
+
maxDate: string;
|
|
69
|
+
isPartyOversized: boolean;
|
|
70
|
+
goToStep: (step: FormStep) => void;
|
|
71
|
+
next: () => Promise<boolean>;
|
|
72
|
+
back: () => void;
|
|
73
|
+
submit: () => Promise<boolean>;
|
|
74
|
+
reset: () => void;
|
|
75
|
+
loadFloorplan: () => Promise<void>;
|
|
76
|
+
setActiveFloorPlan: (planId: string) => void;
|
|
77
|
+
}
|
|
78
|
+
type __VLS_Slots = {
|
|
79
|
+
default(slotProps: ReservationFormSlotProps): unknown;
|
|
80
|
+
};
|
|
81
|
+
declare const __VLS_component: import("vue").DefineComponent<ReservationFormProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
82
|
+
submitted: (contact: {
|
|
83
|
+
first_name: string;
|
|
84
|
+
last_name: string;
|
|
85
|
+
email: string;
|
|
86
|
+
phone: string;
|
|
87
|
+
}) => any;
|
|
88
|
+
}, string, import("vue").PublicProps, Readonly<ReservationFormProps> & Readonly<{
|
|
89
|
+
onSubmitted?: ((contact: {
|
|
90
|
+
first_name: string;
|
|
91
|
+
last_name: string;
|
|
92
|
+
email: string;
|
|
93
|
+
phone: string;
|
|
94
|
+
}) => any) | undefined;
|
|
95
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
96
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
97
|
+
export default _default;
|
|
98
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
99
|
+
new (): {
|
|
100
|
+
$slots: S;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=ReservationForm.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReservationForm.vue.d.ts","sourceRoot":"","sources":["../../src/components/ReservationForm.vue"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface SocialLinksProps {
|
|
2
|
+
/** `tenant_branding.social_links` — `{ instagram: "https://...", facebook: "..." }`. */
|
|
3
|
+
links: Record<string, string> | null | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Order in which platforms should render. Platforms in `links` but not in
|
|
6
|
+
* this list render after the listed ones, in object-iteration order.
|
|
7
|
+
*/
|
|
8
|
+
platformOrder?: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
export interface SocialLinkEntry {
|
|
11
|
+
/** Platform key as stored — `"instagram"`, `"facebook"`, etc. */
|
|
12
|
+
platform: string;
|
|
13
|
+
/** The URL. */
|
|
14
|
+
url: string;
|
|
15
|
+
}
|
|
16
|
+
export interface SocialLinksSlotProps {
|
|
17
|
+
entries: SocialLinkEntry[];
|
|
18
|
+
hasLinks: boolean;
|
|
19
|
+
}
|
|
20
|
+
type __VLS_Slots = {
|
|
21
|
+
default(slotProps: SocialLinksSlotProps): unknown;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_component: import("vue").DefineComponent<SocialLinksProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<SocialLinksProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
25
|
+
export default _default;
|
|
26
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
27
|
+
new (): {
|
|
28
|
+
$slots: S;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=SocialLinks.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialLinks.vue.d.ts","sourceRoot":"","sources":["../../src/components/SocialLinks.vue"],"names":[],"mappings":"AAqEA,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmCD,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAAC;CACnD,CAAC;AAiCF,QAAA,MAAM,eAAe,4SAMnB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|