Compare commits

..

3 Commits

@ -27,7 +27,7 @@
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"graphql": "^16.8.1", "graphql": "^16.8.1",
"lucide-react": "^0.436.0", "lucide-react": "^0.436.0",
"next": "^15.0.0-canary.130", "next": "^15.0.0-canary.131",
"next-international": "^1.2.4", "next-international": "^1.2.4",
"payload": "beta", "payload": "beta",
"react": "19.0.0-rc-06d0b89e-20240801", "react": "19.0.0-rc-06d0b89e-20240801",

@ -0,0 +1,12 @@
"use server";
export const submitContactFormAction = (formData: FormData) => {
console.log(JSON.stringify(formData, null, 2));
console.log(formData.get("message"));
console.log(formData.get("subject"));
console.log(formData.get("date"));
console.log(formData.get("time"));
console.log(formData.get("name"));
console.log(formData.get("email"));
console.log(formData.get("phone"));
};

@ -0,0 +1,12 @@
"use server";
export const submitReservationFormAction = (formData: FormData) => {
console.log(JSON.stringify(formData, null, 2));
console.log(formData.get("message"));
console.log(formData.get("subject"));
console.log(formData.get("date"));
console.log(formData.get("time"));
console.log(formData.get("name"));
console.log(formData.get("email"));
console.log(formData.get("phone"));
};

@ -1,7 +1,10 @@
import { Container } from "@styled-system/jsx"; import { Cigarette, PawPrint } from "lucide-react";
import { Container, HStack, Stack } from "@styled-system/jsx";
import { Metadata } from "next"; import { Metadata } from "next";
import { Params } from "../shared"; import { Params } from "../shared";
import RichText from "@/components/rich-text"; import RichText from "@/components/rich-text";
import { Text } from "@/components/ui/text";
import { getAbout } from "@/api"; import { getAbout } from "@/api";
import { getI18n } from "@/i18n/server"; import { getI18n } from "@/i18n/server";
@ -11,7 +14,23 @@ export default async function About({ params: { locale } }: { params: Params })
return ( return (
<Container pt={6}> <Container pt={6}>
<RichText content={about.text!} /> <Stack gap={10}>
<RichText content={about.text!} />
<Stack>
{about.dogsAllowed && (
<HStack alignItems="center">
<PawPrint />
<Text>{t("about.dogsAllowed")}</Text>
</HStack>
)}
{about.fumoire && (
<HStack alignItems="center">
<Cigarette />
<Text>{t("about.fumoire")}</Text>
</HStack>
)}
</Stack>
</Stack>
</Container> </Container>
); );
} }

@ -0,0 +1,38 @@
import { HStack, styled } from "@styled-system/jsx";
import { Button } from "@/components/ui/button";
import { Field } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { getI18n } from "@/i18n/server";
import { stack } from "@styled-system/patterns";
import { submitContactFormAction } from "@/actions/contact";
export default async function ContactForm() {
const t = await getI18n();
return (
<styled.form action={submitContactFormAction} className={stack()}>
<Field.Root id="name">
<Field.Label>{t("contact.name")}</Field.Label>
<Field.Input name="name" placeholder={t("contact.name")} />
</Field.Root>
<Field.Root id="email">
<Field.Label>{t("general.email")}</Field.Label>
<Field.Input name="email" placeholder={t("general.email")} asChild>
<Input type="email" />
</Field.Input>
</Field.Root>
<Field.Root id="subject">
<Field.Label>{t("contact.subject")}</Field.Label>
<Field.Input name="subject" placeholder={t("contact.subject")} />
</Field.Root>
<Field.Root id="message">
<Field.Label>{t("contact.message")}</Field.Label>
<Field.Textarea name="message" placeholder={t("contact.message")}/>
</Field.Root>
<HStack justify="end">
<Button type="submit">{t("general.submit")}</Button>
</HStack>
</styled.form>
);
}

@ -0,0 +1,171 @@
"use client";
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
import { HStack, Stack } from "@styled-system/jsx";
import { Button } from "@/components/ui/button";
import { DatePicker } from "@/components/ui/date-picker";
import { Field } from "@/components/ui/field";
import { FormLabel } from "@/components/ui/form-label";
import { IconButton } from "@/components/ui/icon-button";
import { Input } from "@/components/ui/input";
import { NumberInput } from "@/components/ui/number-input";
import { useI18n } from "@/i18n/client";
export default function DateTimePicker() {
const t = useI18n();
return (
<HStack>
<DatePicker.Root positioning={{ sameWidth: true }} startOfWeek={2} flex={1}>
<DatePicker.Label>{t("general.date")}</DatePicker.Label>
<DatePicker.Control>
<DatePicker.Trigger asChild>
<DatePicker.Input index={0} asChild>
<Input placeholder={t("general.date")} />
</DatePicker.Input>
</DatePicker.Trigger>
</DatePicker.Control>
<DatePicker.Positioner>
<DatePicker.Content>
<DatePicker.View view="day">
<DatePicker.Context>
{(api) => (
<>
<DatePicker.ViewControl>
<DatePicker.PrevTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronLeftIcon />
</IconButton>
</DatePicker.PrevTrigger>
<DatePicker.ViewTrigger asChild>
<Button variant="ghost" size="sm">
<DatePicker.RangeText />
</Button>
</DatePicker.ViewTrigger>
<DatePicker.NextTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronRightIcon />
</IconButton>
</DatePicker.NextTrigger>
</DatePicker.ViewControl>
<DatePicker.Table>
<DatePicker.TableHead>
<DatePicker.TableRow>
{api.weekDays.map((weekDay, id) => (
<DatePicker.TableHeader key={id}>
{weekDay.narrow}
</DatePicker.TableHeader>
))}
</DatePicker.TableRow>
</DatePicker.TableHead>
<DatePicker.TableBody>
{api.weeks.map((week, id) => (
<DatePicker.TableRow key={id}>
{week.map((day, id) => (
<DatePicker.TableCell key={id} value={day}>
<DatePicker.TableCellTrigger asChild>
<IconButton variant="ghost">{day.day}</IconButton>
</DatePicker.TableCellTrigger>
</DatePicker.TableCell>
))}
</DatePicker.TableRow>
))}
</DatePicker.TableBody>
</DatePicker.Table>
</>
)}
</DatePicker.Context>
</DatePicker.View>
<DatePicker.View view="month">
<DatePicker.Context>
{(api) => (
<>
<DatePicker.ViewControl>
<DatePicker.PrevTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronLeftIcon />
</IconButton>
</DatePicker.PrevTrigger>
<DatePicker.ViewTrigger asChild>
<Button variant="ghost" size="sm">
<DatePicker.RangeText />
</Button>
</DatePicker.ViewTrigger>
<DatePicker.NextTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronRightIcon />
</IconButton>
</DatePicker.NextTrigger>
</DatePicker.ViewControl>
<DatePicker.Table>
<DatePicker.TableBody>
{api.getMonthsGrid({ columns: 4, format: "short" }).map((months, id) => (
<DatePicker.TableRow key={id}>
{months.map((month, id) => (
<DatePicker.TableCell key={id} value={month.value}>
<DatePicker.TableCellTrigger asChild>
<Button variant="ghost">{month.label}</Button>
</DatePicker.TableCellTrigger>
</DatePicker.TableCell>
))}
</DatePicker.TableRow>
))}
</DatePicker.TableBody>
</DatePicker.Table>
</>
)}
</DatePicker.Context>
</DatePicker.View>
<DatePicker.View view="year">
<DatePicker.Context>
{(api) => (
<>
<DatePicker.ViewControl>
<DatePicker.PrevTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronLeftIcon />
</IconButton>
</DatePicker.PrevTrigger>
<DatePicker.ViewTrigger asChild>
<Button variant="ghost" size="sm">
<DatePicker.RangeText />
</Button>
</DatePicker.ViewTrigger>
<DatePicker.NextTrigger asChild>
<IconButton variant="ghost" size="sm">
<ChevronRightIcon />
</IconButton>
</DatePicker.NextTrigger>
</DatePicker.ViewControl>
<DatePicker.Table>
<DatePicker.TableBody>
{api.getYearsGrid({ columns: 4 }).map((years, id) => (
<DatePicker.TableRow key={id}>
{years.map((year, id) => (
<DatePicker.TableCell key={id} value={year.value}>
<DatePicker.TableCellTrigger asChild>
<Button variant="ghost">{year.label}</Button>
</DatePicker.TableCellTrigger>
</DatePicker.TableCell>
))}
</DatePicker.TableRow>
))}
</DatePicker.TableBody>
</DatePicker.Table>
</>
)}
</DatePicker.Context>
</DatePicker.View>
</DatePicker.Content>
</DatePicker.Positioner>
</DatePicker.Root>
<Field.Root>
<Field.Label>{t("general.time")}</Field.Label>
<Field.Input asChild>
<Input placeholder={t("general.time")} type="time" />
</Field.Input>
</Field.Root>
</HStack>
);
}

@ -1,8 +1,13 @@
import { Box, HStack, Stack } from "@styled-system/jsx"; import { Box, HStack, Stack } from "@styled-system/jsx";
import { getAbout, getContact } from "@/api"; import { getAbout, getContact } from "@/api";
import ContactForm from "@/app/(frontend)/[locale]/contact/contact-form";
import { Field } from "@/components/ui/field";
import { Heading } from "@/components/ui/heading"; import { Heading } from "@/components/ui/heading";
import { Input } from "@/components/ui/input";
import { Params } from "../shared"; import { Params } from "../shared";
import ReservationForm from "@/app/(frontend)/[locale]/contact/reservation-form";
import { Tabs } from "@/components/ui/tabs";
import { Text } from "@/components/ui/text"; import { Text } from "@/components/ui/text";
import { getI18n } from "@/i18n/server"; import { getI18n } from "@/i18n/server";
import { getOpeningTimes } from "@/api/openingTimes"; import { getOpeningTimes } from "@/api/openingTimes";
@ -15,65 +20,89 @@ export default async function Contact({ params: { locale } }: { params: Params }
const openingTimes = await getOpeningTimes({ locale }); const openingTimes = await getOpeningTimes({ locale });
return ( return (
<Stack p={6} gap={10}> <Stack p={6} gap={6}>
<Heading as="h1" size="3xl"> <Heading as="h1" size="3xl">
{t("general.contact")} {t("general.contact")}
</Heading> </Heading>
<Stack> <HStack gap={10} flexWrap="wrap" justifyContent="space-between" alignItems="start">
<Heading as="h3" size="xl"> <Tabs.Root
{t("general.openingTimes")} defaultValue="reservation"
</Heading> orientation="horizontal"
{openingTimes.docs.map((ot) => ( minW={350}
<HStack key={ot.id}> flex={1}
<Text w={250}> flexGrow={1}
{t(`days.${ot.from}`)} >
{ot.to ? `- ${t(`days.${ot.to}`)}` : ""} <Tabs.List>
</Text> <Tabs.Trigger value="reservation">{t("contact.reservation")}</Tabs.Trigger>
<Text> <Tabs.Trigger value="contact">{t("general.contact")}</Tabs.Trigger>
{new Date(ot.timeOpen).toLocaleTimeString("de-CH", { timeStyle: "short" })} -{" "} <Tabs.Indicator />
{new Date(ot.timeClose).toLocaleTimeString("de-CH", { timeStyle: "short" })} </Tabs.List>
</Text> <Tabs.Content value="reservation">
</HStack> <ReservationForm />
))} </Tabs.Content>
</Stack> <Tabs.Content value="contact">
<ContactForm />
</Tabs.Content>
</Tabs.Root>
<Stack> <Stack gap={6}>
<Heading as="h3" size="xl">
{t("general.address")}
</Heading>
<HStack gap={20}>
{contact.address.embeddedMaps && (
<styled.div
dangerouslySetInnerHTML={{ __html: contact.address.embeddedMaps }}
width={600}
/>
)}
<Stack> <Stack>
<Box> <Heading as="h3" size="xl">
<Text fontWeight="bold">{about.name}</Text> {t("general.openingTimes")}
<Text> </Heading>
{contact.address.street} {contact.address.number} {openingTimes.docs.map((ot) => (
</Text> <HStack key={ot.id}>
<Text> <Text w={250}>
{contact.address.zip} {contact.address.area} {t(`days.${ot.from}`)}
</Text> {ot.to ? `- ${t(`days.${ot.to}`)}` : ""}
</Box> </Text>
{contact.phone && ( <Text>
<HStack> {new Date(ot.timeOpen).toLocaleTimeString("de-CH", { timeStyle: "short" })} -{" "}
<Text fontWeight="bold">{t("general.phoneNumber")}</Text> {new Date(ot.timeClose).toLocaleTimeString("de-CH", { timeStyle: "short" })}
<Text>{contact.phone}</Text> </Text>
</HStack> </HStack>
)} ))}
{contact.email && ( </Stack>
<HStack>
<Text fontWeight="bold">{t("general.email")}</Text> <Stack>
<Text>{contact.email}</Text> <Heading as="h3" size="xl">
</HStack> {t("general.address")}
)} </Heading>
<HStack gap={20}>
{contact.address.embeddedMaps && (
<styled.div
dangerouslySetInnerHTML={{ __html: contact.address.embeddedMaps }}
width={600}
/>
)}
<Stack>
<Box>
<Text fontWeight="bold">{about.name}</Text>
<Text>
{contact.address.street} {contact.address.number}
</Text>
<Text>
{contact.address.zip} {contact.address.area}
</Text>
</Box>
{contact.phone && (
<HStack>
<Text fontWeight="bold">{t("general.phoneNumber")}</Text>
<styled.a href={`tel:${contact.phone}`}>{contact.phone}</styled.a>
</HStack>
)}
{contact.email && (
<HStack>
<Text fontWeight="bold">{t("general.email")}</Text>
<styled.a href={`mailto:${contact.email}`}>{contact.email}</styled.a>
</HStack>
)}
</Stack>
</HStack>
</Stack> </Stack>
</HStack> </Stack>
</Stack> </HStack>
</Stack> </Stack>
); );
} }

@ -0,0 +1,45 @@
import { HStack, Stack } from "@styled-system/jsx";
import { Button } from "@/components/ui/button";
import DateTimePicker from "./date-time-picker";
import { Field } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { getI18n } from "@/i18n/server";
import { stack } from "@styled-system/patterns";
import { styled } from "@styled-system/jsx";
import { submitReservationFormAction } from "@/actions/reservation";
export default async function ReservationForm() {
const t = await getI18n();
return (
<styled.form action={submitReservationFormAction} className={stack()}>
<Field.Root id="name">
<Field.Label>{t("contact.name")}</Field.Label>
<Field.Input name="name" placeholder={t("contact.name")} />
</Field.Root>
<Field.Root id="email">
<Field.Label>{t("general.email")}</Field.Label>
<Field.Input name="email" placeholder={t("general.email")} asChild>
<Input type="email" />
</Field.Input>
</Field.Root>
<Field.Root id="phoneNumber">
<Field.Label>{t("general.phoneNumber")}</Field.Label>
<Field.Input name="phoneNumber" placeholder={t("general.phoneNumber")} />
</Field.Root>
<DateTimePicker />
<Field.Root id="guests">
<Field.Label>{t("reservation.guests")}</Field.Label>
<Field.Input name="guests" placeholder={t("reservation.guests")} />
</Field.Root>
<Field.Root id="message">
<Field.Label>{t("contact.message")}</Field.Label>
<Field.Textarea name="message" placeholder={t("contact.message")} />
</Field.Root>
<HStack justify="end">
<Button type="submit">{t("general.submit")}</Button>
</HStack>
</styled.form>
);
}

@ -0,0 +1 @@
export * as DatePicker from './styled/date-picker'

@ -0,0 +1 @@
export * as Field from './styled/field'

@ -0,0 +1 @@
export { FormLabel, type FormLabelProps } from './styled/form-label'

@ -0,0 +1 @@
export { Input, type InputProps } from './styled/input'

@ -0,0 +1,52 @@
import { forwardRef } from 'react'
import * as StyledNumberInput from './styled/number-input'
export interface NumberInputProps extends StyledNumberInput.RootProps {}
export const NumberInput = forwardRef<HTMLDivElement, NumberInputProps>((props, ref) => {
const { children, ...rootProps } = props
return (
<StyledNumberInput.Root ref={ref} {...rootProps}>
{children && <StyledNumberInput.Label>{children}</StyledNumberInput.Label>}
<StyledNumberInput.Control>
<StyledNumberInput.Input />
<StyledNumberInput.IncrementTrigger>
<ChevronUpIcon />
</StyledNumberInput.IncrementTrigger>
<StyledNumberInput.DecrementTrigger>
<ChevronDownIcon />
</StyledNumberInput.DecrementTrigger>
</StyledNumberInput.Control>
</StyledNumberInput.Root>
)
})
NumberInput.displayName = 'NumberInput'
const ChevronUpIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Up Icon</title>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m18 15l-6-6l-6 6"
/>
</svg>
)
const ChevronDownIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Down Icon</title>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m6 9l6 6l6-6"
/>
</svg>
)

@ -0,0 +1,137 @@
'use client'
import type { Assign } from '@ark-ui/react'
import { DatePicker } from '@ark-ui/react/date-picker'
import { type DatePickerVariantProps, datePicker } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(datePicker)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, DatePicker.RootProviderBaseProps>, DatePickerVariantProps>
>(DatePicker.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, DatePicker.RootBaseProps>, DatePickerVariantProps>
>(DatePicker.Root, 'root')
export const ClearTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.ClearTriggerBaseProps>
>(DatePicker.ClearTrigger, 'clearTrigger')
export const Content = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.ContentBaseProps>
>(DatePicker.Content, 'content')
export const Control = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.ControlBaseProps>
>(DatePicker.Control, 'control')
export const Input = withContext<
HTMLInputElement,
Assign<HTMLStyledProps<'input'>, DatePicker.InputBaseProps>
>(DatePicker.Input, 'input')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, DatePicker.LabelBaseProps>
>(DatePicker.Label, 'label')
export const MonthSelect = withContext<
HTMLSelectElement,
Assign<HTMLStyledProps<'select'>, DatePicker.MonthSelectBaseProps>
>(DatePicker.MonthSelect, 'monthSelect')
export const NextTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.NextTriggerBaseProps>
>(DatePicker.NextTrigger, 'nextTrigger')
export const Positioner = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.PositionerBaseProps>
>(DatePicker.Positioner, 'positioner')
export const PresetTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.PresetTriggerBaseProps>
>(DatePicker.PresetTrigger, 'presetTrigger')
export const PrevTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.PrevTriggerBaseProps>
>(DatePicker.PrevTrigger, 'prevTrigger')
export const RangeText = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.RangeTextBaseProps>
>(DatePicker.RangeText, 'rangeText')
export const TableBody = withContext<
HTMLTableSectionElement,
Assign<HTMLStyledProps<'tbody'>, DatePicker.TableBodyBaseProps>
>(DatePicker.TableBody, 'tableBody')
export const TableCell = withContext<
HTMLTableCellElement,
Assign<HTMLStyledProps<'td'>, DatePicker.TableCellBaseProps>
>(DatePicker.TableCell, 'tableCell')
export const TableCellTrigger = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.TableCellTriggerBaseProps>
>(DatePicker.TableCellTrigger, 'tableCellTrigger')
export const TableHead = withContext<
HTMLTableSectionElement,
Assign<HTMLStyledProps<'thead'>, DatePicker.TableHeadBaseProps>
>(DatePicker.TableHead, 'tableHead')
export const TableHeader = withContext<
HTMLTableCellElement,
Assign<HTMLStyledProps<'th'>, DatePicker.TableHeaderBaseProps>
>(DatePicker.TableHeader, 'tableHeader')
export const Table = withContext<
HTMLTableElement,
Assign<HTMLStyledProps<'table'>, DatePicker.TableBaseProps>
>(DatePicker.Table, 'table')
export const TableRow = withContext<
HTMLTableRowElement,
Assign<HTMLStyledProps<'tr'>, DatePicker.TableRowBaseProps>
>(DatePicker.TableRow, 'tableRow')
export const Trigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.TriggerBaseProps>
>(DatePicker.Trigger, 'trigger')
export const ViewControl = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.ViewControlBaseProps>
>(DatePicker.ViewControl, 'viewControl')
export const View = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, DatePicker.ViewBaseProps>
>(DatePicker.View, 'view')
export const ViewTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, DatePicker.ViewTriggerBaseProps>
>(DatePicker.ViewTrigger, 'viewTrigger')
export const YearSelect = withContext<
HTMLSelectElement,
Assign<HTMLStyledProps<'select'>, DatePicker.YearSelectBaseProps>
>(DatePicker.YearSelect, 'yearSelect')
export { DatePickerContext as Context } from '@ark-ui/react/date-picker'

@ -0,0 +1,49 @@
'use client'
import type { Assign } from '@ark-ui/react'
import { Field } from '@ark-ui/react/field'
import { styled } from 'styled-system/jsx'
import { type FieldVariantProps, field, input, textarea } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(field)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Field.RootProviderBaseProps>, FieldVariantProps>
>(Field.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Field.RootBaseProps>, FieldVariantProps>
>(Field.Root, 'root')
export const ErrorText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Field.ErrorTextBaseProps>
>(Field.ErrorText, 'errorText')
export const HelperText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Field.HelperTextBaseProps>
>(Field.HelperText, 'helperText')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, Field.LabelBaseProps>
>(Field.Label, 'label')
export const Select = withContext<
HTMLSelectElement,
Assign<HTMLStyledProps<'select'>, Field.SelectBaseProps>
>(Field.Select, 'select')
export type InputProps = ComponentProps<typeof Input>
export const Input = styled(Field.Input, input)
export type TextareaProps = ComponentProps<typeof Textarea>
export const Textarea = styled(Field.Textarea, textarea)
export { FieldContext as Context } from '@ark-ui/react/field'

@ -0,0 +1,7 @@
import { ark } from '@ark-ui/react/factory'
import { styled } from 'styled-system/jsx'
import { formLabel } from 'styled-system/recipes'
import type { ComponentProps } from 'styled-system/types'
export type FormLabelProps = ComponentProps<typeof FormLabel>
export const FormLabel = styled(ark.label, formLabel)

@ -0,0 +1,7 @@
import { ark } from '@ark-ui/react/factory'
import { styled } from 'styled-system/jsx'
import { input } from 'styled-system/recipes'
import type { ComponentProps } from 'styled-system/types'
export type InputProps = ComponentProps<typeof Input>
export const Input = styled(ark.input, input)

@ -0,0 +1,57 @@
'use client'
import type { Assign } from '@ark-ui/react'
import { NumberInput } from '@ark-ui/react/number-input'
import { type NumberInputVariantProps, numberInput } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(numberInput)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, NumberInput.RootProviderBaseProps>, NumberInputVariantProps>
>(NumberInput.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, NumberInput.RootBaseProps>, NumberInputVariantProps>
>(NumberInput.Root, 'root')
export const Control = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, NumberInput.ControlBaseProps>
>(NumberInput.Control, 'control')
export const DecrementTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, NumberInput.DecrementTriggerBaseProps>
>(NumberInput.DecrementTrigger, 'decrementTrigger')
export const IncrementTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, NumberInput.IncrementTriggerBaseProps>
>(NumberInput.IncrementTrigger, 'incrementTrigger')
export const Input = withContext<
HTMLInputElement,
Assign<HTMLStyledProps<'input'>, NumberInput.InputBaseProps>
>(NumberInput.Input, 'input')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, NumberInput.LabelBaseProps>
>(NumberInput.Label, 'label')
export const Scrubber = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, NumberInput.ScrubberBaseProps>
>(NumberInput.Scrubber, 'scrubber')
export const ValueText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, NumberInput.ValueTextBaseProps>
>(NumberInput.ValueText, 'valueText')
export { NumberInputContext as Context } from '@ark-ui/react/number-input'

@ -21,5 +21,15 @@ export const About: GlobalConfig = {
type: "richText", type: "richText",
localized: true, localized: true,
}, },
{
name: "dogsAllowed",
type: "checkbox",
required: true,
},
{
name: "fumoire",
type: "checkbox",
required: true,
},
], ],
}; };

@ -8,6 +8,8 @@ export default {
phoneNumber: "Telefonnummer", phoneNumber: "Telefonnummer",
email: "E-Mail", email: "E-Mail",
openingTimes: "Öffnungszeiten", openingTimes: "Öffnungszeiten",
date: "Datum",
time: "Zeit",
en: "Englisch", en: "Englisch",
de: "Deutsch", de: "Deutsch",
fr: "Französisch", fr: "Französisch",
@ -22,4 +24,14 @@ export default {
"5": "Samstag", "5": "Samstag",
"6": "Sonntag", "6": "Sonntag",
}, },
about: {
dogsAllowed: "Hunde erlaubt",
fumoire: "Fumoire verfügbar",
},
contact: {
name: "Name",
subject: "Betreff",
message: "Nachricht",
reservation: "Reservation",
},
} as const; } as const;

@ -7,6 +7,9 @@ export default {
address: "Address", address: "Address",
email: "Email", email: "Email",
openingTimes: "Opening Times", openingTimes: "Opening Times",
phoneNumber: "Phone",
date: "Date",
time: "Time",
en: "English", en: "English",
de: "German", de: "German",
fr: "French", fr: "French",
@ -21,4 +24,17 @@ export default {
"5": "Saturday", "5": "Saturday",
"6": "Sunday", "6": "Sunday",
}, },
about: {
dogsAllowed: "Dogs allowed",
fumoire: "Fumoire available",
},
contact: {
name: "Name",
subject: "Subject",
message: "Message",
reservation: "Reservation",
},
reservation: {
guests: "Guests",
},
} as const; } as const;

@ -318,6 +318,8 @@ export interface About {
}; };
[k: string]: unknown; [k: string]: unknown;
} | null; } | null;
dogsAllowed: boolean;
fumoire: boolean;
updatedAt?: string | null; updatedAt?: string | null;
createdAt?: string | null; createdAt?: string | null;
} }

@ -1831,10 +1831,10 @@
dependencies: dependencies:
sparse-bitfield "^3.0.3" sparse-bitfield "^3.0.3"
"@next/env@15.0.0-canary.130": "@next/env@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/env/-/env-15.0.0-canary.130.tgz#5f7ec61ebd746cdeac6c7297395333d772cf1840" resolved "https://registry.yarnpkg.com/@next/env/-/env-15.0.0-canary.131.tgz#6eb612e69711667f0a111a08f2b99c1dd373f4ce"
integrity sha512-TPyUrSoNel8r/zK4udsdZYlckh4GAl9lkIjdbGigsCy36SvmFLKr1+6ib0El74Lp4VYUCky7fSrp40hmiXQbAQ== integrity sha512-Fi8wxS3ZGa+C5YPZ620p+Z4kj/ZZbd37zrroAPf4beoKXn9li8LVe9SHaK3by9Pl3UBbs17t0IhQQHdQr20DSA==
"@next/env@^15.0.0-canary.104": "@next/env@^15.0.0-canary.104":
version "15.0.0-rc.0" version "15.0.0-rc.0"
@ -1848,50 +1848,50 @@
dependencies: dependencies:
fast-glob "3.3.1" fast-glob "3.3.1"
"@next/swc-darwin-arm64@15.0.0-canary.130": "@next/swc-darwin-arm64@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.0-canary.130.tgz#d92fc1435084c8ceb50b844733ec702c5446b04c" resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.0-canary.131.tgz#5d3f831297e5221d890876d4b57dc3915f9f5259"
integrity sha512-i78IahlCCxgFM5LO3Wg65ruRirLn6C3dji5quWxtuht3A2IUMMIwUaCKffFNF6PPS+gN3i6WS3ll5VKT7ETtPQ== integrity sha512-bpq9fHUE4xloHRNT2QKYmlZOiI7V7v0Z+jhevp+qGazXNkReFJCRcgjq2VNsvXtTaOOqtmBvKXnOxBXuaz8R2A==
"@next/swc-darwin-x64@15.0.0-canary.130": "@next/swc-darwin-x64@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.0-canary.130.tgz#32a0cc608ddd97682620ef7edd2278cc1dd2773b" resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.0-canary.131.tgz#f5610bea7379a3ffbecb42b76abd3bd577de30d0"
integrity sha512-6ad2/R48GmK/4Q+zDnKvZZgeBLhPY9lAoOSa7bbjDnzeum+2WLiqVwFIK6m/LQtMUvInNuXML0bxC7w87aCfgA== integrity sha512-o5ZHjXWSIZUw2EF9X+k+NJTnTWGrcXW26nLpW2DR3ZNEHT9zVzobOKELwkZm/9CxQq2nXjwj4qyx1OLEfi87kQ==
"@next/swc-linux-arm64-gnu@15.0.0-canary.130": "@next/swc-linux-arm64-gnu@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.0-canary.130.tgz#53c6df1dfee3d76091fe8c943d04cca48f512725" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.0-canary.131.tgz#9b2463bbadbd64403c3393b75e70cded2f609a3a"
integrity sha512-x1GtTrNUTFm4JvaatTEQwjcIJWXy0aGVm2xCzic+TupzP6Ofrp+KY3JwUFR1CiCBjSIemgxKOhYvKRSjDIP/Dg== integrity sha512-Ak00vwfcTZX3AlITotpzN9f3T5k7iRRQDlXOAzIchuC42suP1eKN+aIlSU8NpSdwHCC9fOSzNejZ0ELG8BQj4A==
"@next/swc-linux-arm64-musl@15.0.0-canary.130": "@next/swc-linux-arm64-musl@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.0-canary.130.tgz#e08a53220868a22c05f16677a71e40cddd174d7e" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.0-canary.131.tgz#7b8fe1221efb62443ebeb5870f5558ae48549aff"
integrity sha512-ec/kxN71GsCdp6qc2n+/Z6laIrD2DWsGS1DdVUR1jR+DAHPqCG0wPwBB+erhf0+TLBWqCyWayJ1WoSleCIfdWA== integrity sha512-urkChLdStGzZ+jqGr6vzFDwuRGaXBqxVp/K5LZyxp4edNz4i17J/jBZxKjR2XBVLtwKIMcKlECM+Ijtd+dTspQ==
"@next/swc-linux-x64-gnu@15.0.0-canary.130": "@next/swc-linux-x64-gnu@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.0-canary.130.tgz#add55bf145a02a384e24700c09626d4baf678402" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.0-canary.131.tgz#0128d2eec001b4f7127132d9029b64564f308d90"
integrity sha512-BkORXTSHrs2PW1mUuX8L7RAEtcSapH6TbhRR2jV/22VF9bAMzGmK/+/waNO0OwyMTcYu1O1eZHok3cRqESnYfQ== integrity sha512-/FjRcyy6acpCZ4JXUk5gMZNDqwvXT3oZo5Fm2lFMOOGnJgh1HhqLY3qP+F0CSXnbt788o3tcxowXJNWBchzDmQ==
"@next/swc-linux-x64-musl@15.0.0-canary.130": "@next/swc-linux-x64-musl@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.0-canary.130.tgz#5a238de6ca402be05a7c787f86916347f9921789" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.0-canary.131.tgz#1a89b43997897bc984c9a7b3dd2e6f93e14ec94c"
integrity sha512-JeWF76srIvcn9GGkXUdVz078lnlZxXfGx8otIOYMSBfwWgkcxq6aM0RpjhPqqLi1AGvCTmDzq18Wof/Hef4THQ== integrity sha512-rwRYD67Cx9K0PHIVSDsERBe4X5VzrKwp+LKH3QnzGlm+t333yCZg22q9qwwC/lnaWG3m/JOpDV5TyeKodnvPkA==
"@next/swc-win32-arm64-msvc@15.0.0-canary.130": "@next/swc-win32-arm64-msvc@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.0-canary.130.tgz#377bbd3a2552f032347a9bd511e4ba2fe086d401" resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.0-canary.131.tgz#60f8f87ec0661444dd0371bb5adbb940a9455a4b"
integrity sha512-pyzWVUUY+PbNV4i0mfF4RUF3sPNEYZ639eLCThbSbcaonAKl0ijyIuBMWUAKY7R61qu1K91/o4shLHG5Q1/kIw== integrity sha512-PvaCzdXIK/ta/V6joqTrFXkEHYuOFxvyD949Ri3TRBaTSFd1HVJnBJzFeYWQk6f7Gl4tkbiZKZnbbWG4Vh8TQA==
"@next/swc-win32-ia32-msvc@15.0.0-canary.130": "@next/swc-win32-ia32-msvc@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-15.0.0-canary.130.tgz#9e1bc8b37564d648b353e2deb3c6142a062acc06" resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-15.0.0-canary.131.tgz#f4556a82e64a3f5e33fa77f4fe0424a17dac2a9c"
integrity sha512-zKZ/rq7tm6GUrO+pOYNDAloVLn7VbIn+d2tBknpc5iC3Lp3UPO7omgD7qu3yzDRK7aw1vYxA2s7l3ojR+QnpJg== integrity sha512-R9QqvRKg+Xb5MZjYTVDhP3FpiUhJWa7fxCMJlvk/nztEMnutKFSGxgF83rz9aIVLIOYhsFNQPbtE0FIz8XAHuQ==
"@next/swc-win32-x64-msvc@15.0.0-canary.130": "@next/swc-win32-x64-msvc@15.0.0-canary.131":
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.0-canary.130.tgz#c4e614643bb6d1e0ce9e60bbcc14b8be0b544d7b" resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.0-canary.131.tgz#d7a3d6b58c7d5b28180d82230f91d534a7edbb0e"
integrity sha512-LuLjeYm+I7hFvnkI5GAUyUGbpqtAuSN9zf7v+JdTA4+1G2wSPV0qzEjtJKY5ivd3Lhq8Q8vPgSPAZoFP/Ch5bA== integrity sha512-JIcwu7FEyUuIEBCHBlQKIN5EnsC211mbtupFKHVy4+yPtiEcknjFc2PiJoGKbKfuASmfOrvFwHVj+9GdsFvaRQ==
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
@ -7250,12 +7250,12 @@ next-tick@^1.1.0:
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
next@^15.0.0-canary.130: next@^15.0.0-canary.131:
version "15.0.0-canary.130" version "15.0.0-canary.131"
resolved "https://registry.yarnpkg.com/next/-/next-15.0.0-canary.130.tgz#f43aeba1b5996935a36146ddc54c40adfa2d58b6" resolved "https://registry.yarnpkg.com/next/-/next-15.0.0-canary.131.tgz#76b7f6ccba88b30d1f95ae043614c4a788442cdc"
integrity sha512-040yF0BkJSbanzujIJ+7NbSjrxBsMSo7EtXfJmGbmt8/NzjS5hO8vaTDClKDhyU90O4WbMqHVZrTiVVfVCZ72g== integrity sha512-9KRodV+Y4ZtcTUchRU5XRlRFGqCr0iV05pm1G2F3du/8vGlgnazf16WtR091esc9JRJhnCx/mKjpTfAYn0oO7A==
dependencies: dependencies:
"@next/env" "15.0.0-canary.130" "@next/env" "15.0.0-canary.131"
"@swc/counter" "0.1.3" "@swc/counter" "0.1.3"
"@swc/helpers" "0.5.12" "@swc/helpers" "0.5.12"
busboy "1.6.0" busboy "1.6.0"
@ -7264,15 +7264,15 @@ next@^15.0.0-canary.130:
postcss "8.4.31" postcss "8.4.31"
styled-jsx "5.1.6" styled-jsx "5.1.6"
optionalDependencies: optionalDependencies:
"@next/swc-darwin-arm64" "15.0.0-canary.130" "@next/swc-darwin-arm64" "15.0.0-canary.131"
"@next/swc-darwin-x64" "15.0.0-canary.130" "@next/swc-darwin-x64" "15.0.0-canary.131"
"@next/swc-linux-arm64-gnu" "15.0.0-canary.130" "@next/swc-linux-arm64-gnu" "15.0.0-canary.131"
"@next/swc-linux-arm64-musl" "15.0.0-canary.130" "@next/swc-linux-arm64-musl" "15.0.0-canary.131"
"@next/swc-linux-x64-gnu" "15.0.0-canary.130" "@next/swc-linux-x64-gnu" "15.0.0-canary.131"
"@next/swc-linux-x64-musl" "15.0.0-canary.130" "@next/swc-linux-x64-musl" "15.0.0-canary.131"
"@next/swc-win32-arm64-msvc" "15.0.0-canary.130" "@next/swc-win32-arm64-msvc" "15.0.0-canary.131"
"@next/swc-win32-ia32-msvc" "15.0.0-canary.130" "@next/swc-win32-ia32-msvc" "15.0.0-canary.131"
"@next/swc-win32-x64-msvc" "15.0.0-canary.130" "@next/swc-win32-x64-msvc" "15.0.0-canary.131"
sharp "^0.33.4" sharp "^0.33.4"
node-abi@^3.3.0: node-abi@^3.3.0:

Loading…
Cancel
Save