diff --git a/package-lock.json b/package-lock.json
index dace765..a519134 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,7 +27,8 @@
"@eslint/compat": "^1.3.0",
"@eslint/js": "^9.29.0",
"@inlang/paraglide-js": "2.2.0",
- "@lucide/svelte": "^0.518.0",
+ "@internationalized/date": "^3.8.2",
+ "@lucide/svelte": "^0.515.0",
"@playwright/test": "^1.53.1",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/kit": "^2.22.0",
@@ -39,6 +40,7 @@
"@types/dotenv": "^6.1.1",
"@types/node": "^24",
"@types/nodemailer": "^6.4.17",
+ "bits-ui": "^2.8.13",
"clsx": "^2.1.1",
"drizzle-kit": "^0.31.1",
"eslint": "^9.29.0",
@@ -59,9 +61,6 @@
"typescript-eslint": "^8.34.1",
"vite": "^6.3.5",
"vitest": "^3.2.4"
- },
- "engines": {
- "node": ">=24.0.0"
}
},
"node_modules/@adobe/css-tools": {
@@ -1296,6 +1295,34 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz",
+ "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz",
+ "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.2",
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -1408,6 +1435,16 @@
"node": ">=18.0.0"
}
},
+ "node_modules/@internationalized/date": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.2.tgz",
+ "integrity": "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
"node_modules/@isaacs/fs-minipass": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
@@ -1496,9 +1533,9 @@
"license": "Apache-2.0"
},
"node_modules/@lucide/svelte": {
- "version": "0.518.0",
- "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.518.0.tgz",
- "integrity": "sha512-vhSikVKVZnz7eVa70WsWh/ySqdcb7Mn2R/XhG16fCfqgpMKzdu5GCHPRLaHcGaUCaM9cPDMWG8FeBXk0QY1PEg==",
+ "version": "0.515.0",
+ "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.515.0.tgz",
+ "integrity": "sha512-CEAyqcZmNBfYzVgaRmK2RFJP5tnbXxekRyDk0XX/eZQRfsJmkDvmQwXNX8C869BgNeryzmrRyjHhUL6g9ZOHNA==",
"dev": true,
"license": "ISC",
"peerDependencies": {
@@ -2100,6 +2137,16 @@
"vite": "^6.0.0"
}
},
+ "node_modules/@swc/helpers": {
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
+ "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
"node_modules/@tailwindcss/node": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz",
@@ -3102,6 +3149,69 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/bits-ui": {
+ "version": "2.8.13",
+ "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.8.13.tgz",
+ "integrity": "sha512-YC3DiatZzREdbTZR8IuxbQeYg+/MNcyQeuS6Hycl+ufoG7eiV66qICx210plFER9B776FEYSHXSYuQdlvWODpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.1",
+ "@floating-ui/dom": "^1.7.1",
+ "esm-env": "^1.1.2",
+ "runed": "^0.29.1",
+ "svelte-toolbelt": "^0.9.3",
+ "tabbable": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/huntabyte"
+ },
+ "peerDependencies": {
+ "@internationalized/date": "^3.8.1",
+ "svelte": "^5.33.0"
+ }
+ },
+ "node_modules/bits-ui/node_modules/runed": {
+ "version": "0.29.2",
+ "resolved": "https://registry.npmjs.org/runed/-/runed-0.29.2.tgz",
+ "integrity": "sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/huntabyte",
+ "https://github.com/sponsors/tglide"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "esm-env": "^1.0.0"
+ },
+ "peerDependencies": {
+ "svelte": "^5.7.0"
+ }
+ },
+ "node_modules/bits-ui/node_modules/svelte-toolbelt": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.9.3.tgz",
+ "integrity": "sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/huntabyte"
+ ],
+ "dependencies": {
+ "clsx": "^2.1.1",
+ "runed": "^0.29.0",
+ "style-to-object": "^1.0.8"
+ },
+ "engines": {
+ "node": ">=18",
+ "pnpm": ">=8.7.0"
+ },
+ "peerDependencies": {
+ "svelte": "^5.30.2"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -6453,6 +6563,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tailwind-merge": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz",
@@ -6683,6 +6800,13 @@
"typescript": ">=4.8.4"
}
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD"
+ },
"node_modules/tw-animate-css": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.4.tgz",
diff --git a/package.json b/package.json
index fc58abd..fc9511c 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,9 @@
"devDependencies": {
"@eslint/compat": "^1.3.0",
"@eslint/js": "^9.29.0",
- "@lucide/svelte": "^0.518.0",
+ "@inlang/paraglide-js": "2.2.0",
+ "@internationalized/date": "^3.8.2",
+ "@lucide/svelte": "^0.515.0",
"@playwright/test": "^1.53.1",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/kit": "^2.22.0",
@@ -45,9 +47,10 @@
"@tailwindcss/vite": "^4.1.10",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.8",
- "@types/nodemailer": "^6.4.17",
"@types/dotenv": "^6.1.1",
"@types/node": "^24",
+ "@types/nodemailer": "^6.4.17",
+ "bits-ui": "^2.8.13",
"clsx": "^2.1.1",
"drizzle-kit": "^0.31.1",
"eslint": "^9.29.0",
@@ -67,8 +70,7 @@
"typescript": "^5.8.3",
"typescript-eslint": "^8.34.1",
"vite": "^6.3.5",
- "vitest": "^3.2.4",
- "@inlang/paraglide-js": "2.2.0"
+ "vitest": "^3.2.4"
},
"dependencies": {
"@noble/hashes": "^1.8.0",
@@ -85,8 +87,5 @@
"secrets.js-34r7h": "^2.0.2",
"winston": "^3.17.0"
},
- "engines": {
- "node": ">=24.0.0"
- },
"license": "AGPL-3.0"
}
diff --git a/project.inlang/messages/de.json b/project.inlang/messages/de.json
index 240ceac..a06633a 100644
--- a/project.inlang/messages/de.json
+++ b/project.inlang/messages/de.json
@@ -1,5 +1,10 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"welcome": "Willkommen bei OpenReception",
- "poweredBy": "Betrieben von"
+ "poweredBy": "Betrieben von",
+ "i18n": {
+ "label": "Sprache wählen",
+ "search": "Sprache suchen",
+ "notFound": "Sprache nicht gefunden"
+ }
}
diff --git a/project.inlang/messages/en.json b/project.inlang/messages/en.json
index 2e2657a..0f9e789 100644
--- a/project.inlang/messages/en.json
+++ b/project.inlang/messages/en.json
@@ -1,5 +1,10 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"welcome": "Welcome to OpenReception",
- "poweredBy": "Powered by"
+ "poweredBy": "Powered by",
+ "i18n": {
+ "label": "Select Language",
+ "search": "Search Language",
+ "notFound": "Language not found"
+ }
}
diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte
new file mode 100644
index 0000000..4daf453
--- /dev/null
+++ b/src/lib/components/ui/button/button.svelte
@@ -0,0 +1,80 @@
+
+
+
+
+{#if href}
+
+ {@render children?.()}
+
+{:else}
+
+{/if}
diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts
new file mode 100644
index 0000000..fb585d7
--- /dev/null
+++ b/src/lib/components/ui/button/index.ts
@@ -0,0 +1,17 @@
+import Root, {
+ type ButtonProps,
+ type ButtonSize,
+ type ButtonVariant,
+ buttonVariants,
+} from "./button.svelte";
+
+export {
+ Root,
+ type ButtonProps as Props,
+ //
+ Root as Button,
+ buttonVariants,
+ type ButtonProps,
+ type ButtonSize,
+ type ButtonVariant,
+};
diff --git a/src/lib/components/ui/combobox/combobox.svelte b/src/lib/components/ui/combobox/combobox.svelte
new file mode 100644
index 0000000..7c1c6a6
--- /dev/null
+++ b/src/lib/components/ui/combobox/combobox.svelte
@@ -0,0 +1,75 @@
+
+
+