@shopbite-de/storefront 1.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/.dockerignore +28 -0
- package/.env.example +11 -0
- package/.github/workflows/build.yaml +48 -0
- package/.github/workflows/ci.yaml +102 -0
- package/.prettierignore +6 -0
- package/.prettierrc +1 -0
- package/api-types/storeApiSchema.json +13863 -0
- package/api-types/storeApiTypes.d.ts +7010 -0
- package/app/app.config.ts +18 -0
- package/app/app.vue +99 -0
- package/app/assets/css/main.css +60 -0
- package/app/assets/fonts/Courier_Prime/CourierPrime-Bold.ttf +0 -0
- package/app/assets/fonts/Courier_Prime/CourierPrime-BoldItalic.ttf +0 -0
- package/app/assets/fonts/Courier_Prime/CourierPrime-Italic.ttf +0 -0
- package/app/assets/fonts/Courier_Prime/CourierPrime-Regular.ttf +0 -0
- package/app/assets/fonts/Courier_Prime/OFL.txt +93 -0
- package/app/assets/fonts/Kalam/Kalam-Bold.ttf +0 -0
- package/app/assets/fonts/Kalam/Kalam-Light.ttf +0 -0
- package/app/assets/fonts/Kalam/Kalam-Regular.ttf +0 -0
- package/app/assets/fonts/Kalam/OFL.txt +93 -0
- package/app/assets/fonts/Marcellus/Marcellus-Regular.ttf +0 -0
- package/app/assets/fonts/Marcellus/OFL.txt +93 -0
- package/app/assets/fonts/Sora/OFL.txt +93 -0
- package/app/assets/fonts/Sora/README.txt +70 -0
- package/app/assets/fonts/Sora/Sora-VariableFont_wght.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-Bold.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-ExtraBold.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-ExtraLight.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-Light.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-Medium.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-Regular.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-SemiBold.ttf +0 -0
- package/app/assets/fonts/Sora/static/Sora-Thin.ttf +0 -0
- package/app/components/AddToWishlist.vue +55 -0
- package/app/components/Address/Card.vue +32 -0
- package/app/components/Address/Detail.vue +22 -0
- package/app/components/Address/Form.vue +117 -0
- package/app/components/AnimatedSection.vue +77 -0
- package/app/components/BottomNavi.vue +63 -0
- package/app/components/Cart/Item.vue +112 -0
- package/app/components/Cart/QuickView.vue +55 -0
- package/app/components/Category/Header.vue +53 -0
- package/app/components/Category/Listing.vue +295 -0
- package/app/components/Checkout/DeliveryTimeSelect.vue +177 -0
- package/app/components/Checkout/LoginOrRegister.vue +43 -0
- package/app/components/Checkout/PaymentAndDelivery.vue +101 -0
- package/app/components/Checkout/PaymentMethod.vue +30 -0
- package/app/components/Checkout/ShippingMethod.vue +30 -0
- package/app/components/Checkout/Summary.vue +125 -0
- package/app/components/Cta.vue +34 -0
- package/app/components/Features.vue +36 -0
- package/app/components/Food/Marquee.vue +35 -0
- package/app/components/Food/MarqueeItem.vue +72 -0
- package/app/components/Footer.vue +51 -0
- package/app/components/Header.vue +160 -0
- package/app/components/Hero.vue +77 -0
- package/app/components/ImageGallery.vue +46 -0
- package/app/components/Loading.vue +29 -0
- package/app/components/Navigation/DesktopLeft.vue +51 -0
- package/app/components/Navigation/DesktopLeft2.vue +43 -0
- package/app/components/Navigation/MobileTop.vue +59 -0
- package/app/components/Navigation/MobileTop2.vue +42 -0
- package/app/components/Order/Detail.vue +84 -0
- package/app/components/Product/Card.vue +132 -0
- package/app/components/Product/Category.vue +153 -0
- package/app/components/Product/Configurator.vue +65 -0
- package/app/components/Product/CrossSelling.vue +95 -0
- package/app/components/Product/DeselectIngredient.vue +46 -0
- package/app/components/Product/Detail.vue +187 -0
- package/app/components/Product/SearchBar.vue +109 -0
- package/app/components/PublicAnnouncement.vue +17 -0
- package/app/components/Topseller.vue +43 -0
- package/app/components/User/Detail.vue +47 -0
- package/app/components/User/LoginForm.vue +105 -0
- package/app/components/User/RegistrationForm.vue +340 -0
- package/app/components/Wishlist.vue +102 -0
- package/app/composables/useDeliveryTime.ts +139 -0
- package/app/composables/useInterval.ts +15 -0
- package/app/composables/usePizzaToppings.ts +31 -0
- package/app/composables/useProductEvents.test.ts +111 -0
- package/app/composables/useProductEvents.ts +22 -0
- package/app/composables/useProductVariants.ts +61 -0
- package/app/composables/useScrollAnimation.ts +39 -0
- package/app/composables/useTopSellers.ts +34 -0
- package/app/error.vue +30 -0
- package/app/layouts/account.vue +74 -0
- package/app/layouts/default.vue +6 -0
- package/app/layouts/listing.vue +32 -0
- package/app/layouts/listing2.vue +8 -0
- package/app/middleware/trailing-slash.global.ts +19 -0
- package/app/pages/account/recover/password/index.vue +143 -0
- package/app/pages/anmelden.vue +32 -0
- package/app/pages/bestellung.vue +103 -0
- package/app/pages/c/[...all].vue +49 -0
- package/app/pages/index.vue +59 -0
- package/app/pages/konto/adressen.vue +135 -0
- package/app/pages/konto/bestellung/[id].vue +41 -0
- package/app/pages/konto/bestellungen.vue +53 -0
- package/app/pages/konto/index.vue +74 -0
- package/app/pages/konto/profil.vue +160 -0
- package/app/pages/merkliste.vue +11 -0
- package/app/pages/order/[id].vue +69 -0
- package/app/pages/passwort-vergessen.vue +103 -0
- package/app/pages/registrierung/bestaetigen.vue +44 -0
- package/app/pages/registrierung/index.vue +24 -0
- package/app/pages/speisekarte.vue +58 -0
- package/app/pages/unternehmen/[slug].vue +66 -0
- package/app/types/Association.d.ts +11 -0
- package/app/utils/businessHours.ts +119 -0
- package/app/utils/formatDate.ts +9 -0
- package/app/utils/holidays.ts +43 -0
- package/app/utils/storeHours.ts +8 -0
- package/app/utils/time.ts +20 -0
- package/app/validation/addressSchema.ts +34 -0
- package/app/validation/registrationSchema.ts +156 -0
- package/bun.dockerfile +60 -0
- package/compose.yml +17 -0
- package/container +7 -0
- package/content/index.yml +91 -0
- package/content/navigation.yml +67 -0
- package/content/unternehmen/agb.md +1 -0
- package/content/unternehmen/datenschutz.md +1 -0
- package/content/unternehmen/impressum.md +39 -0
- package/content.config.ts +134 -0
- package/eslint.config.mjs +8 -0
- package/node.dockerfile +33 -0
- package/nuxt.config.ts +153 -0
- package/package.json +70 -0
- package/public/dark/Logo.svg +32 -0
- package/public/favicon.ico +0 -0
- package/public/light/Logo.svg +32 -0
- package/renovate.json +4 -0
- package/server/tsconfig.json +3 -0
- package/shopware.d.ts +19 -0
- package/tsconfig.json +4 -0
- package/vitest.config.mts +26 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// schemas/registrationSchema.ts
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
export const createRegistrationSchema = (state: any) =>
|
|
6
|
+
z.object({
|
|
7
|
+
accountType: z.string(),
|
|
8
|
+
email: z.string().email("Invalid email"),
|
|
9
|
+
firstName: z.string().min(1),
|
|
10
|
+
lastName: z.string().min(1),
|
|
11
|
+
guest: z.boolean(),
|
|
12
|
+
password: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.refine(
|
|
16
|
+
(val) => {
|
|
17
|
+
return state.guest || (val && val.length >= 8);
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
message: "Password muss mindestens 8 Zeichen lang sein.",
|
|
21
|
+
},
|
|
22
|
+
),
|
|
23
|
+
passwordConfirm: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.refine(
|
|
27
|
+
(val) => {
|
|
28
|
+
return state.guest || val === state.password;
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
message: "Password stimmt nicht überein.",
|
|
32
|
+
},
|
|
33
|
+
),
|
|
34
|
+
billingAddress: z.object({
|
|
35
|
+
firstName: z.string().min(1).optional(),
|
|
36
|
+
lastName: z.string().min(1).optional(),
|
|
37
|
+
company: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.refine(
|
|
41
|
+
(val) => {
|
|
42
|
+
return (
|
|
43
|
+
state.accountType !== "commercial" ||
|
|
44
|
+
(val !== undefined && val !== "")
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
message: "Als Geschäftskunde ist dieses Feld pflicht.",
|
|
49
|
+
},
|
|
50
|
+
),
|
|
51
|
+
department: z.string().optional(),
|
|
52
|
+
street: z.string().min(1),
|
|
53
|
+
zipcode: z.string().min(1).optional(),
|
|
54
|
+
city: z.string().min(1, {
|
|
55
|
+
message: "Bitte geben Sie den Ort an.",
|
|
56
|
+
}),
|
|
57
|
+
countryId: z.string().min(1),
|
|
58
|
+
phoneNumber: z.string().min(7),
|
|
59
|
+
}),
|
|
60
|
+
shippingAddress: z.object({
|
|
61
|
+
firstName: z
|
|
62
|
+
.string()
|
|
63
|
+
.min(1)
|
|
64
|
+
.optional()
|
|
65
|
+
.refine(
|
|
66
|
+
(val) => {
|
|
67
|
+
return (
|
|
68
|
+
!state.isShippingAddressDifferent ||
|
|
69
|
+
(val !== undefined && val !== "")
|
|
70
|
+
);
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
message: "Erforderlich.",
|
|
74
|
+
},
|
|
75
|
+
),
|
|
76
|
+
lastName: z
|
|
77
|
+
.string()
|
|
78
|
+
.min(1)
|
|
79
|
+
.optional()
|
|
80
|
+
.refine(
|
|
81
|
+
(val) => {
|
|
82
|
+
return (
|
|
83
|
+
!state.isShippingAddressDifferent ||
|
|
84
|
+
(val !== undefined && val !== "")
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
message: "Erforderlich.",
|
|
89
|
+
},
|
|
90
|
+
),
|
|
91
|
+
company: z
|
|
92
|
+
.string()
|
|
93
|
+
.min(1)
|
|
94
|
+
.optional()
|
|
95
|
+
.refine(
|
|
96
|
+
(val) => {
|
|
97
|
+
return (
|
|
98
|
+
!state.isShippingAddressDifferent ||
|
|
99
|
+
(val !== undefined && val !== "")
|
|
100
|
+
);
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
message: "Erforderlich.",
|
|
104
|
+
},
|
|
105
|
+
),
|
|
106
|
+
department: z.string().optional(),
|
|
107
|
+
phoneNumber: z
|
|
108
|
+
.string()
|
|
109
|
+
.optional()
|
|
110
|
+
.refine(
|
|
111
|
+
(val) => {
|
|
112
|
+
return (
|
|
113
|
+
!state.isShippingAddressDifferent ||
|
|
114
|
+
(val !== undefined && val !== "")
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
message: "Erforderlich.",
|
|
119
|
+
},
|
|
120
|
+
),
|
|
121
|
+
street: z
|
|
122
|
+
.string()
|
|
123
|
+
.optional()
|
|
124
|
+
.refine(
|
|
125
|
+
(val) => {
|
|
126
|
+
return (
|
|
127
|
+
!state.isShippingAddressDifferent ||
|
|
128
|
+
(val !== undefined && val !== "")
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
message: "Erforderlich.",
|
|
133
|
+
},
|
|
134
|
+
),
|
|
135
|
+
zipcode: z.string().min(1).optional(),
|
|
136
|
+
city: z
|
|
137
|
+
.string()
|
|
138
|
+
.optional()
|
|
139
|
+
.refine(
|
|
140
|
+
(val) => {
|
|
141
|
+
return (
|
|
142
|
+
!state.isShippingAddressDifferent ||
|
|
143
|
+
(val !== undefined && val !== "")
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
message: "Erforderlich.",
|
|
148
|
+
},
|
|
149
|
+
),
|
|
150
|
+
countryId: z.string().min(1),
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
export type RegistrationSchema = z.infer<
|
|
155
|
+
ReturnType<typeof createRegistrationSchema>
|
|
156
|
+
>;
|
package/bun.dockerfile
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
FROM oven/bun:1-alpine AS build
|
|
2
|
+
|
|
3
|
+
ARG NUXT_PUBLIC_SHOPWARE_ENDPOINT='https://my.shop/store-api'
|
|
4
|
+
ARG NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN='TOKEN'
|
|
5
|
+
|
|
6
|
+
ENV NUXT_PUBLIC_SHOPWARE_ENDPOINT=${NUXT_PUBLIC_SHOPWARE_ENDPOINT}
|
|
7
|
+
ENV NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN=${NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN}
|
|
8
|
+
ENV NODE_ENV=production
|
|
9
|
+
ENV BUN_INSTALL_BIN=/usr/local/bin
|
|
10
|
+
|
|
11
|
+
WORKDIR /app
|
|
12
|
+
|
|
13
|
+
COPY --chown=bun:bun package.json bun.lock ./
|
|
14
|
+
|
|
15
|
+
USER bun
|
|
16
|
+
|
|
17
|
+
COPY package.json bun.lock ./
|
|
18
|
+
|
|
19
|
+
RUN bun install --frozen-lockfile --production --ignore-scripts
|
|
20
|
+
|
|
21
|
+
COPY . .
|
|
22
|
+
|
|
23
|
+
RUN bun run build
|
|
24
|
+
|
|
25
|
+
FROM oven/bun:1-alpine AS dev
|
|
26
|
+
|
|
27
|
+
ENV BUN_INSTALL_BIN=/usr/local/bin
|
|
28
|
+
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
RUN chown -R bun:bun /app
|
|
32
|
+
|
|
33
|
+
USER bun
|
|
34
|
+
|
|
35
|
+
WORKDIR /app
|
|
36
|
+
|
|
37
|
+
COPY --chown=bun:bun package.json bun.lock ./
|
|
38
|
+
|
|
39
|
+
RUN bun install --frozen-lockfile --ignore-scripts
|
|
40
|
+
|
|
41
|
+
COPY --chown=bun:bun . .
|
|
42
|
+
|
|
43
|
+
EXPOSE 3000
|
|
44
|
+
EXPOSE 24678
|
|
45
|
+
|
|
46
|
+
CMD [ "bun", "run", "dev" ]
|
|
47
|
+
|
|
48
|
+
FROM oven/bun:1-alpine AS production
|
|
49
|
+
|
|
50
|
+
WORKDIR /app
|
|
51
|
+
|
|
52
|
+
COPY --from=build --chown=bun:bun /app/.output /app/.output
|
|
53
|
+
|
|
54
|
+
RUN chown -R bun:bun /app
|
|
55
|
+
|
|
56
|
+
USER bun
|
|
57
|
+
|
|
58
|
+
EXPOSE 3000
|
|
59
|
+
|
|
60
|
+
CMD [ "bun", ".output/server/index.mjs" ]
|
package/compose.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
services:
|
|
2
|
+
app:
|
|
3
|
+
build:
|
|
4
|
+
dockerfile: node.dockerfile
|
|
5
|
+
context: .
|
|
6
|
+
args:
|
|
7
|
+
NUXT_PUBLIC_SHOPWARE_ENDPOINT: ${NUXT_PUBLIC_SHOPWARE_ENDPOINT:-https://my.shop/store-api}
|
|
8
|
+
NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN: ${NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN:-TOKEN}
|
|
9
|
+
user: node
|
|
10
|
+
env_file:
|
|
11
|
+
- .env
|
|
12
|
+
volumes:
|
|
13
|
+
- ".:/app"
|
|
14
|
+
- "/app/node_modules"
|
|
15
|
+
ports:
|
|
16
|
+
- '3000:3000'
|
|
17
|
+
- '24678:24678'
|
package/container
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
seo:
|
|
2
|
+
title: ShopBite – Kostenloses Online-Bestellsystem für Gastronomie
|
|
3
|
+
description: Dein eigenes Bestellsystem ohne Provisionen, ohne monatliche Kosten – 100% Open Source und individuell anpassbar. Perfekt für Pizzerien, Imbisse und Lieferdienste.
|
|
4
|
+
title: Pizzeria La Fattoria
|
|
5
|
+
description: Italienisch-deutsche Küche in Obertshausen seit 1997.
|
|
6
|
+
hero:
|
|
7
|
+
backgroundVideo: https://shopware.shopbite.de/media/10/59/96/1762465181/background.mp4
|
|
8
|
+
headline: ALTE SCHMIEDE
|
|
9
|
+
usps:
|
|
10
|
+
- title: 4.5 ⭐
|
|
11
|
+
subtitle: 720+ Reviews
|
|
12
|
+
icon: i-simple-icons-google
|
|
13
|
+
link: https://www.google.com/maps/place/?q=place_id:ChIJJ-6VNfcTvUcR2r7Sax3SN2s
|
|
14
|
+
- title: 28 Jahre
|
|
15
|
+
subtitle: in Obertshausen
|
|
16
|
+
icon: i-lucide-award
|
|
17
|
+
- title: Lieferservice
|
|
18
|
+
subtitle: Schnell & zuverlässig
|
|
19
|
+
icon: i-lucide-bike
|
|
20
|
+
links:
|
|
21
|
+
- label: Speisekarte
|
|
22
|
+
icon: i-lucide-arrow-right
|
|
23
|
+
trailing: true
|
|
24
|
+
color: primary
|
|
25
|
+
to: /speisekarte
|
|
26
|
+
size: xl
|
|
27
|
+
- label: Tisch reservieren
|
|
28
|
+
icon: i-lucide-phone
|
|
29
|
+
size: xl
|
|
30
|
+
color: neutral
|
|
31
|
+
variant: outline
|
|
32
|
+
to: 'tel:+490610474127'
|
|
33
|
+
target: _blank
|
|
34
|
+
features:
|
|
35
|
+
title: Alle [Informationen]{.text-primary} auf einen Blick
|
|
36
|
+
description: Sie können Speisen und Getränke abholen, liefern lassen, oder vor Ort in unserem Restaurant genießen.
|
|
37
|
+
headline: ALTE SCHMIEDE
|
|
38
|
+
features:
|
|
39
|
+
- title: Öffnungszeiten
|
|
40
|
+
description: Von 11:30 - 14:30 und 17:30 - 23:00 Uhr. Samstags von 17:30 - 23:30 Uhr. Dienstag ist Ruhetag.
|
|
41
|
+
icon: i-lucide-clock
|
|
42
|
+
ui:
|
|
43
|
+
leading: bg-accented/50 p-2 rounded-md border border-muted border-dashed
|
|
44
|
+
- title: Lieferung
|
|
45
|
+
description: Wir liefern nach Obertshausen und Lämmerspiel. Ab 15€ liefern wir frei Haus, darunter berechnen wir lediglich 1€. Die Lieferzeit beträgt bei normaler Auslastung ca. 30 min
|
|
46
|
+
icon: i-lucide-truck
|
|
47
|
+
ui:
|
|
48
|
+
leading: bg-accented/50 p-2 rounded-md border border-muted border-dashed
|
|
49
|
+
- title: Reservierungen und Bestellungen
|
|
50
|
+
description: Reservierungen nehmen wir ausschließlich telefonisch entgegen. Bestellungen nehmen wir gerne telefonisch oder online entgegen.
|
|
51
|
+
icon: i-lucide-pizza
|
|
52
|
+
ui:
|
|
53
|
+
leading: bg-accented/50 p-2 rounded-md border border-muted border-dashed
|
|
54
|
+
marquee:
|
|
55
|
+
title: Das lieben unsere Kunden
|
|
56
|
+
description: Kundenbilder
|
|
57
|
+
headline: ALTE SCHMIEDE
|
|
58
|
+
items:
|
|
59
|
+
- productId: 019a4f2e717b7df7a349761a56c43ac3
|
|
60
|
+
image: https://shopware.shopbite.de/media/e4/82/55/1762465420/72.webp
|
|
61
|
+
- productId: 019a4f4552ff7251a1fa20a2e1a3a707
|
|
62
|
+
image: https://shopware.shopbite.de/media/5f/43/cc/1762465330/131.webp
|
|
63
|
+
- productId: 019a4ea153e671c6ba20810b541e1455
|
|
64
|
+
image: https://shopware.shopbite.de/media/f1/53/f9/1762465329/35.webp
|
|
65
|
+
- productId: 019a4ea153e671c6ba20810b541e1455
|
|
66
|
+
image: https://shopware.shopbite.de/media/5f/c7/ec/1762465330/122.webp
|
|
67
|
+
gallery:
|
|
68
|
+
title: Restaurant
|
|
69
|
+
description: Genießen Sie leckeres Essen in einem rustikalen und gemütlichen Ambiente.
|
|
70
|
+
headline: ALTE SCHMIEDE
|
|
71
|
+
links:
|
|
72
|
+
- label: Tisch reservieren
|
|
73
|
+
to: tel:+49610471427
|
|
74
|
+
color: primary
|
|
75
|
+
variant: subtle
|
|
76
|
+
trailingIcon: i-lucide-phone
|
|
77
|
+
images:
|
|
78
|
+
- image: https://shopware.shopbite.de/media/71/2a/1a/1762465670/restaurant1.webp
|
|
79
|
+
alt: La Fattoria Restaurant Innenbereich 1
|
|
80
|
+
- image: https://shopware.shopbite.de/media/61/ea/77/1762465670/restaurant2.webp
|
|
81
|
+
alt: La Fattoria Restaurant Innenbereich 2
|
|
82
|
+
- image: https://shopware.shopbite.de/media/6d/ac/ca/1762465670/restaurant3.webp
|
|
83
|
+
alt: La Fattoria Restaurant Innenbereich 3
|
|
84
|
+
- image: https://shopware.shopbite.de/media/af/d6/da/1762465670/restaurant4.webp
|
|
85
|
+
alt: La Fattoria Restaurant Innenbereich 4
|
|
86
|
+
- image: https://shopware.shopbite.de/media/6a/ff/e2/1762465670/restaurant5.webp
|
|
87
|
+
alt: La Fattoria Restaurant Innenbereich 5
|
|
88
|
+
- image: https://shopware.shopbite.de/media/80/76/d0/1762465670/restaurant6.webp
|
|
89
|
+
alt: La Fattoria Restaurant Innenbereich 6
|
|
90
|
+
- image: https://nbg1.your-objectstorage.com/lafattoria-public/media/30/f7/76/1763383122/restaurant10.webp
|
|
91
|
+
alt: La Fattoria Restaurant Innenbereich 10
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
main:
|
|
2
|
+
- label: Start
|
|
3
|
+
icon: i-lucide-home
|
|
4
|
+
to: /
|
|
5
|
+
- label: Speisekarte
|
|
6
|
+
icon: i-lucide-utensils
|
|
7
|
+
to: /speisekarte
|
|
8
|
+
- label: Speisekarte 2
|
|
9
|
+
icon: i-lucide-utensils
|
|
10
|
+
to: /c/Pizza/
|
|
11
|
+
- label: Routenplaner
|
|
12
|
+
icon: i-lucide-map-pinned
|
|
13
|
+
to: https://www.openstreetmap.org/directions?from=&to=50.080610%2C8.863783#map=19/50.080323/8.864079
|
|
14
|
+
target: _blank
|
|
15
|
+
- label: Merkliste
|
|
16
|
+
icon: i-lucide-book-heart
|
|
17
|
+
to: /merkliste
|
|
18
|
+
|
|
19
|
+
account:
|
|
20
|
+
loggedIn:
|
|
21
|
+
- - label: Mein Konto
|
|
22
|
+
type: label
|
|
23
|
+
- - label: Konto
|
|
24
|
+
icon: i-lucide-user
|
|
25
|
+
to: /konto
|
|
26
|
+
- label: Bestellungen
|
|
27
|
+
icon: i-lucide-pizza
|
|
28
|
+
to: /konto/bestellungen
|
|
29
|
+
- label: Adressen
|
|
30
|
+
icon: i-lucide-house
|
|
31
|
+
to: /konto/adressen
|
|
32
|
+
- - label: Abmelden
|
|
33
|
+
icon: i-lucide-log-out
|
|
34
|
+
action: logout
|
|
35
|
+
loggedOut:
|
|
36
|
+
- - label: Jetzt anmelden
|
|
37
|
+
type: label
|
|
38
|
+
- - label: Zur Anmeldung
|
|
39
|
+
icon: i-lucide-user
|
|
40
|
+
to: /anmelden
|
|
41
|
+
|
|
42
|
+
footer:
|
|
43
|
+
withGithubLink: true
|
|
44
|
+
withColorModeSwitch: true
|
|
45
|
+
text: Alle Preise inkl. gesetzlicher Mehrwertsteuer zzgl. Versandkosten, wenn nicht anders beschrieben
|
|
46
|
+
columns:
|
|
47
|
+
- label: Informationen
|
|
48
|
+
children:
|
|
49
|
+
- label: Impressum
|
|
50
|
+
to: /impressum
|
|
51
|
+
- label: Datenschutz
|
|
52
|
+
to: /datenschutz
|
|
53
|
+
- label: AGB
|
|
54
|
+
to: /agb
|
|
55
|
+
- label: Top Kategorien
|
|
56
|
+
children:
|
|
57
|
+
- label: Pizza
|
|
58
|
+
to: /c/Pizza/
|
|
59
|
+
- label: Nudeln
|
|
60
|
+
to: /c/Nudeln/
|
|
61
|
+
- label: Fleischgerichte
|
|
62
|
+
to: /c/Fleischgerichte/
|
|
63
|
+
- label: Unternehmen
|
|
64
|
+
children:
|
|
65
|
+
- label: 'Tel: 06104 71427'
|
|
66
|
+
- label: Kantstraße 6
|
|
67
|
+
- label: 631679 Oberthsuasen
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# AGB
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Datenschutz
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Impressum
|
|
2
|
+
|
|
3
|
+
## Angaben gemäß § 5 TMG
|
|
4
|
+
|
|
5
|
+
Bekim Veliu und Cefajet Veliu GbR
|
|
6
|
+
|
|
7
|
+
Kantstr. 6<br>63179 Obertshausen<br>Deutschland
|
|
8
|
+
|
|
9
|
+
**Vertreten durch:**<br>Bekim Veliu
|
|
10
|
+
|
|
11
|
+
**Kontakt:**<br>Telefon: +49 6104 71427<br>E-Mail: service@pizzeria-lafattoria.de
|
|
12
|
+
|
|
13
|
+
## Umsatzsteuer-ID
|
|
14
|
+
|
|
15
|
+
Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz:
|
|
16
|
+
|
|
17
|
+
## Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV
|
|
18
|
+
|
|
19
|
+
Bekim Veliu<br>Kantstr. 6<br>63179 Obertshausen
|
|
20
|
+
|
|
21
|
+
## Administrator und technischer Ansprechpartner dieser Seite
|
|
22
|
+
|
|
23
|
+
Lirim Veliu<br>lirim@veliu.net
|
|
24
|
+
|
|
25
|
+
## Haftungshinweis
|
|
26
|
+
|
|
27
|
+
Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. Für den Inhalt
|
|
28
|
+
der verlinkten Seiten sind ausschließlich deren Betreiber verantwortlich.
|
|
29
|
+
|
|
30
|
+
## Streitbeilegung
|
|
31
|
+
|
|
32
|
+
Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: https://ec.europa.eu/consumers/odr/
|
|
33
|
+
Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.
|
|
34
|
+
|
|
35
|
+
## Urheberrecht
|
|
36
|
+
|
|
37
|
+
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht.
|
|
38
|
+
Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes
|
|
39
|
+
bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { defineCollection, defineContentConfig } from "@nuxt/content";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
const createEnum = (options: [string, ...string[]]) => z.enum(options);
|
|
5
|
+
|
|
6
|
+
const createLinkSchema = () =>
|
|
7
|
+
z.object({
|
|
8
|
+
label: z.string().nonempty(),
|
|
9
|
+
to: z.string().nonempty(),
|
|
10
|
+
icon: z.string().optional().editor({ input: "icon" }),
|
|
11
|
+
size: createEnum(["xs", "sm", "md", "lg", "xl"]),
|
|
12
|
+
trailing: z.boolean().optional(),
|
|
13
|
+
target: createEnum(["_blank", "_self"]),
|
|
14
|
+
color: createEnum([
|
|
15
|
+
"primary",
|
|
16
|
+
"secondary",
|
|
17
|
+
"neutral",
|
|
18
|
+
"error",
|
|
19
|
+
"warning",
|
|
20
|
+
"success",
|
|
21
|
+
"info",
|
|
22
|
+
]),
|
|
23
|
+
variant: createEnum([
|
|
24
|
+
"solid",
|
|
25
|
+
"outline",
|
|
26
|
+
"subtle",
|
|
27
|
+
"soft",
|
|
28
|
+
"ghost",
|
|
29
|
+
"link",
|
|
30
|
+
]),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const createBaseSchema = () =>
|
|
34
|
+
z.object({
|
|
35
|
+
title: z.string().nonempty(),
|
|
36
|
+
description: z.string().nonempty(),
|
|
37
|
+
headline: z.string().optional(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const createFeatureSchema = () =>
|
|
41
|
+
createBaseSchema().extend({
|
|
42
|
+
icon: z.string().editor({ input: "icon" }),
|
|
43
|
+
ui: z
|
|
44
|
+
.object({
|
|
45
|
+
leading: z.string().optional(),
|
|
46
|
+
})
|
|
47
|
+
.editor({ hidden: true }),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const createNavigationItemSchema = () =>
|
|
51
|
+
z.object({
|
|
52
|
+
label: z.string().nonempty(),
|
|
53
|
+
icon: z.string().optional().editor({ input: "icon" }),
|
|
54
|
+
to: z.string().nonempty(),
|
|
55
|
+
target: createEnum(["_blank", "_self"]),
|
|
56
|
+
type: createEnum(["label", "item"]).optional(),
|
|
57
|
+
action: z.string().optional(),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const createFooterColumnSchema = () =>
|
|
61
|
+
z.object({
|
|
62
|
+
label: z.string().nonempty(),
|
|
63
|
+
children: z.array(
|
|
64
|
+
z.object({
|
|
65
|
+
label: z.string().nonempty(),
|
|
66
|
+
to: z.string().optional(),
|
|
67
|
+
}),
|
|
68
|
+
),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export default defineContentConfig({
|
|
72
|
+
collections: {
|
|
73
|
+
home: defineCollection({
|
|
74
|
+
source: "index.yml",
|
|
75
|
+
type: "page",
|
|
76
|
+
schema: z.object({
|
|
77
|
+
hero: z.object({
|
|
78
|
+
backgroundVideo: z.string().optional(),
|
|
79
|
+
headline: z.string().optional(),
|
|
80
|
+
links: z.array(createLinkSchema()),
|
|
81
|
+
usps: z.array(
|
|
82
|
+
z.object({
|
|
83
|
+
title: z.string().optional(),
|
|
84
|
+
subtitle: z.string().optional(),
|
|
85
|
+
icon: z.string().optional(),
|
|
86
|
+
link: z.string().optional(),
|
|
87
|
+
}),
|
|
88
|
+
),
|
|
89
|
+
}),
|
|
90
|
+
features: createBaseSchema().extend({
|
|
91
|
+
features: z.array(createFeatureSchema()),
|
|
92
|
+
}),
|
|
93
|
+
marquee: createBaseSchema().extend({
|
|
94
|
+
items: z.array(
|
|
95
|
+
z.object({
|
|
96
|
+
image: z.string().nonempty(),
|
|
97
|
+
productId: z.string().nonempty(),
|
|
98
|
+
}),
|
|
99
|
+
),
|
|
100
|
+
}),
|
|
101
|
+
gallery: createBaseSchema().extend({
|
|
102
|
+
images: z.array(
|
|
103
|
+
z.object({
|
|
104
|
+
image: z.string().nonempty(),
|
|
105
|
+
alt: z.string().nonempty(),
|
|
106
|
+
}),
|
|
107
|
+
),
|
|
108
|
+
links: z.array(createLinkSchema()),
|
|
109
|
+
}),
|
|
110
|
+
}),
|
|
111
|
+
}),
|
|
112
|
+
navigation: defineCollection({
|
|
113
|
+
source: "navigation.yml",
|
|
114
|
+
type: "page",
|
|
115
|
+
schema: z.object({
|
|
116
|
+
main: z.array(createNavigationItemSchema()),
|
|
117
|
+
account: z.object({
|
|
118
|
+
loggedIn: z.array(z.array(createNavigationItemSchema())),
|
|
119
|
+
loggedOut: z.array(z.array(createNavigationItemSchema())),
|
|
120
|
+
}),
|
|
121
|
+
footer: z.object({
|
|
122
|
+
withGithubLink: z.boolean(),
|
|
123
|
+
withColorModeSwitch: z.boolean(),
|
|
124
|
+
text: z.string().optional(),
|
|
125
|
+
columns: z.array(createFooterColumnSchema()),
|
|
126
|
+
}),
|
|
127
|
+
}),
|
|
128
|
+
}),
|
|
129
|
+
unternehmen: defineCollection({
|
|
130
|
+
source: "unternehmen/*.md",
|
|
131
|
+
type: "page",
|
|
132
|
+
}),
|
|
133
|
+
},
|
|
134
|
+
});
|
package/node.dockerfile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
FROM node:24-alpine AS build
|
|
2
|
+
|
|
3
|
+
ARG PNPM_VERSION=10.20.0
|
|
4
|
+
ARG NUXT_PUBLIC_SHOPWARE_ENDPOINT='https://my.shop/store-api'
|
|
5
|
+
ARG NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN='TOKEN'
|
|
6
|
+
|
|
7
|
+
ENV PNPM_VERSION=${PNPM_VERSION}
|
|
8
|
+
ENV NUXT_PUBLIC_SHOPWARE_ENDPOINT=${NUXT_PUBLIC_SHOPWARE_ENDPOINT}
|
|
9
|
+
ENV NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN=${NUXT_PUBLIC_SHOPWARE_ACCESS_TOKEN}
|
|
10
|
+
ENV NODE_ENV=production
|
|
11
|
+
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
|
12
|
+
|
|
13
|
+
WORKDIR /app
|
|
14
|
+
|
|
15
|
+
RUN npm install -g pnpm@${PNPM_VERSION}
|
|
16
|
+
|
|
17
|
+
COPY . .
|
|
18
|
+
|
|
19
|
+
RUN pnpm install --frozen-lockfile --prefer-offline --production
|
|
20
|
+
|
|
21
|
+
RUN pnpm build
|
|
22
|
+
|
|
23
|
+
FROM node:24-alpine AS production
|
|
24
|
+
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
ENV NODE_ENV=production
|
|
28
|
+
|
|
29
|
+
COPY --from=build /app/.output /app/.output
|
|
30
|
+
|
|
31
|
+
EXPOSE 3000
|
|
32
|
+
|
|
33
|
+
CMD [ "node", ".output/server/index.mjs" ]
|