91 Commits

Author SHA1 Message Date
niggl fac25ca67b refactor: remove signin step and related buttons from signup process 2025-04-07 13:25:42 +02:00
philipp d11f22f5f8 larger qr code 2025-03-24 11:01:22 +01:00
philipp 42f2a5ba21 hide signup progress on first step 2025-03-24 11:01:17 +01:00
philipp 31cd1a61ad hide darkmode toggle for now 2025-03-24 11:01:02 +01:00
philipp 9f63e3a77a theme 2025-03-24 10:45:21 +01:00
philipp 4c5499d050 drop the countdown for now 2025-03-24 10:45:14 +01:00
philipp 497a108647 wip 2025-03-24 10:45:03 +01:00
philipp 38e6c145e2 sample qr code 2025-03-24 10:31:58 +01:00
philipp 828cc0547e agb check state 2025-03-24 10:29:06 +01:00
philipp c3248099c6 autofocus + more signup logic 2025-03-24 10:26:05 +01:00
niggl 2aa8c4178a more 2025-03-23 00:53:46 +01:00
niggl 52b8db4a5a more flow 2025-03-23 00:51:23 +01:00
niggl 012a0043b3 feat: final state 2025-03-23 00:48:58 +01:00
niggl 625c0c3ed2 show basic idea 2025-03-23 00:38:53 +01:00
niggl a3e800aa94 chore: Reinit svelte 2025-03-22 23:15:56 +01:00
niggl 399b7b0798 chore: Ignore legacy code 2025-03-22 23:13:07 +01:00
niggl 0de50822cd Merge branch 'main' of git.odit.services:lfk/kiosk
Build latest image / build-container (push) Failing after 18s
2025-03-22 23:10:31 +01:00
niggl 0177c50651 refactor(ci): Switch to actions 2025-03-22 23:08:06 +01:00
philipp f7575f46e4 🚀Bumped version to 1.1.0 2024-12-16 17:32:09 +01:00
philipp a8d90d4882 feat: email 2024-12-16 17:31:56 +01:00
philipp a2ffa5055e 2025 2024-12-16 17:31:49 +01:00
philipp b969932582 chore(deps): bump all 2024-12-16 17:31:36 +01:00
niggl 72ace57cb3 Merge branch 'main' of git.odit.services:lfk/kiosk
ci/woodpecker/push/build Pipeline was successful
2023-11-06 20:07:16 +01:00
niggl 16f9228390 feat(ci)!: Switch to woodpecker 2023-11-06 20:06:59 +01:00
philipp 16d15f7242 🚀Bumped version to 1.0.0
continuous-integration/drone/push Build is passing
2023-04-19 18:27:56 +02:00
philipp 115767c656 feat: footer
continuous-integration/drone/push Build is passing
2023-04-19 18:27:33 +02:00
philipp bb3c801908 feat: prevent F1 + F5 2023-04-19 18:27:27 +02:00
philipp e512325115 refactor: drop footer 2023-04-19 18:27:12 +02:00
philipp aa7d2dbe1b 🚀Bumped version to 0.6.0
continuous-integration/drone/push Build is passing
2023-04-19 18:07:26 +02:00
philipp 01cd8d4b78 add chrome kiosk command to readme
continuous-integration/drone/push Build is passing
2023-04-19 18:07:15 +02:00
philipp c7c1c6dc41 refactor!: cleanup userdata localstorage + components
continuous-integration/drone/push Build is passing
2023-04-19 18:06:13 +02:00
philipp bf8b351b64 feat!: move to single route application for kiosk mode
continuous-integration/drone/push Build is passing
2023-04-19 18:02:33 +02:00
philipp 58830c5db3 🚀Bumped version to 0.5.0
continuous-integration/drone/push Build is passing
2023-04-19 17:07:08 +02:00
philipp 066e67c64f feat(registration): support next input element with ENTER key
continuous-integration/drone/push Build is passing
2023-04-19 17:06:55 +02:00
philipp 5f5b03a8a0 feat(registration): disabled done button for 7.5s
continuous-integration/drone/push Build is passing
2023-04-19 17:04:36 +02:00
philipp cbfbd92d0e feat(registration): autofocus input fields + done button
continuous-integration/drone/push Build is passing
2023-04-19 16:58:35 +02:00
philipp 418fe7773f feat(registration): disable text select
continuous-integration/drone/push Build is passing
2023-04-19 16:58:08 +02:00
niggl 4b6e11d8d2 🚀Bumped version to 0.4.4
continuous-integration/drone/push Build is passing
2023-04-19 13:08:38 +02:00
niggl 0698038523 fix(registration): Added missing dark styling 2023-04-19 13:08:29 +02:00
niggl 297b88016b 🚀Bumped version to 0.4.3
continuous-integration/drone/push Build is passing
2023-04-19 13:04:53 +02:00
niggl 8959223016 fix(href): replaced location.replace with goto 2023-04-19 13:04:44 +02:00
niggl a3e437d966 🚀Bumped version to 0.4.2
continuous-integration/drone/push Build is passing
2023-04-19 13:00:04 +02:00
niggl 19c9fa339b fix(hrefs): Fixed relative locations 2023-04-19 12:59:52 +02:00
niggl 8017f009e4 🚀Bumped version to 0.4.1
continuous-integration/drone/push Build is passing
2023-04-19 12:57:15 +02:00
niggl 482d6387fa Redirects/links relative 2023-04-19 12:57:02 +02:00
niggl ff36691ada fix(userstore): Prefix localstorage keys with kiosk- 2023-04-19 12:56:19 +02:00
niggl 8ec4fc0c83 🚀Bumped version to 0.4.0
continuous-integration/drone/push Build is passing
2023-04-19 12:50:06 +02:00
niggl a07eb4ddf5 Merge pull request 'branding' (#1) from branding into main
continuous-integration/drone/push Build is passing
Reviewed-on: #1
2023-04-19 10:49:18 +00:00
niggl ec6598feb1 Merge branch 'main' into branding
continuous-integration/drone/pr Build is passing
2023-04-19 12:48:26 +02:00
niggl 93872030ed Lockfile 2023-04-19 12:48:09 +02:00
philipp a610c6abd1 chore(deps): update all
continuous-integration/drone/push Build is passing
2023-04-19 12:33:27 +02:00
philipp 0a883ce7fb branding 2023-04-19 12:33:07 +02:00
philipp f2d8ab81e9 🚀Bumped version to 0.3.0
continuous-integration/drone/push Build is passing
2023-04-19 12:16:08 +02:00
philipp c546a96c4d feat(registration): drop privacy checkbox [privacy is linked on page]
continuous-integration/drone/push Build is passing
2023-04-19 12:15:34 +02:00
niggl c82fdf3823 🚀Bumped version to 0.2.0
continuous-integration/drone/push Build is passing
2023-04-19 12:12:29 +02:00
philipp a46a67793c Merge branch 'main' of https://git.odit.services/lfk/kiosk
continuous-integration/drone/push Build is passing
2023-04-19 12:11:12 +02:00
philipp 898d3595a0 feat(registration): cleanup finished page 2023-04-19 12:11:05 +02:00
niggl 3aa6f0473b 🚀Bumped version to 0.1.0
continuous-integration/drone/push Build is passing
2023-04-19 12:10:42 +02:00
niggl 22be68311b typo 2023-04-19 12:10:31 +02:00
niggl 5d7a25e54f updated release hook 2023-04-19 12:10:01 +02:00
niggl 16deab5308 pnpx -> npx
continuous-integration/drone/push Build is passing
2023-04-19 12:08:54 +02:00
niggl 45eb4b0828 Merge branch 'main' of git.odit.services:lfk/kiosk 2023-04-19 12:08:28 +02:00
niggl c0a39bdabe release from main 2023-04-19 12:08:07 +02:00
niggl e25aaf3e5e Moved config into call 2023-04-19 12:07:27 +02:00
niggl d68e88ec9a Updated typing 2023-04-19 12:06:13 +02:00
niggl 1a0f52f31f Added bwip types 2023-04-19 12:05:19 +02:00
philipp 1c5e246095 fix(registration): typo
continuous-integration/drone/push Build is passing
2023-04-19 12:05:13 +02:00
philipp 74970c4c5b Merge branch 'main' of https://git.odit.services/lfk/kiosk
continuous-integration/drone/push Build is passing
2023-04-19 12:05:00 +02:00
philipp fffe290360 fix(a11y): input borders 2023-04-19 12:04:43 +02:00
niggl 3d110e8f48 Moved barcode height to main config
continuous-integration/drone/push Build is passing
2023-04-19 12:03:28 +02:00
niggl 0bd83f8000 Added readme 2023-04-19 12:01:51 +02:00
niggl 910fa3867b pinned dependency 2023-04-19 11:57:47 +02:00
niggl 2e355dbb46 Package project info 2023-04-19 11:57:36 +02:00
niggl d3d0d17b3a Registration feedback logic 2023-04-19 11:55:03 +02:00
niggl 7cecbfe80e Register results 2023-04-19 11:48:34 +02:00
niggl 710cad376e Fix in auth 2023-04-19 11:44:00 +02:00
niggl 5a81cb64f5 Added runnerid as barcode 2023-04-19 11:40:24 +02:00
niggl 09aee15f60 Basic registration page 2023-04-19 11:35:39 +02:00
niggl f98a4fc2b1 Hide error on successfull signin 2023-04-19 11:34:41 +02:00
niggl 7879ca82fd Authed page login logic 2023-04-19 11:26:14 +02:00
niggl c1400c0120 Open footer links in new tab 2023-04-19 11:11:51 +02:00
niggl 8b086c5aa8 Added login error 2023-04-19 11:10:58 +02:00
niggl 078e8dcb9a Added login page with logic 2023-04-19 11:10:48 +02:00
niggl 5ed21bb13d Added basic welcome page 2023-04-19 10:58:18 +02:00
niggl f6dd25c988 Added sample env 2023-04-19 10:38:33 +02:00
niggl 88f36575fb Basic userstore 2023-04-19 10:35:22 +02:00
niggl f927cc916b Added lfk client 2023-04-19 10:35:11 +02:00
niggl e5535f1869 Added dockerfile + compose 2023-04-19 10:22:46 +02:00
niggl 50764bca47 Bump ts 2023-04-19 10:18:56 +02:00
niggl eca9966e29 Added basic drone docker build, build checks and typechecks 2023-04-19 10:15:36 +02:00
niggl abff31aaee Pin dependencies 2023-04-19 10:14:00 +02:00
51 changed files with 3296 additions and 4150 deletions
-13
View File
@@ -1,13 +0,0 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
-20
View File
@@ -1,20 +0,0 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};
+27
View File
@@ -0,0 +1,27 @@
name: Build latest image
on:
push:
branches:
- main
jobs:
build-container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to registry
uses: docker/login-action@v3
with:
registry: registry.odit.services
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ vars.REGISTRY }}/lfk/kiosk:latest
platforms: linux/amd64,linux/arm64
+27
View File
@@ -0,0 +1,27 @@
name: Build release images
on:
push:
tags:
- "*.*.*"
jobs:
build-container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to registry
uses: docker/login-action@v3
with:
registry: registry.odit.services
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ vars.REGISTRY }}/lfk/kiosk:${{ github.ref_name }}
platforms: linux/amd64,linux/arm64
+19 -3
View File
@@ -1,10 +1,26 @@
.DS_Store
node_modules
/build
# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/package
/build
# OS
.DS_Store
Thumbs.db
# Env
.env
.env.*
!.env.example
!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# additional
tmp
-13
View File
@@ -1,13 +0,0 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
-9
View File
@@ -1,9 +0,0 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}
+15
View File
@@ -0,0 +1,15 @@
FROM registry.odit.services/hub/library/node:19.9.0-alpine3.16 AS build
ARG NPM_REGISTRY_URL=registry.npmjs.org
WORKDIR /app
COPY package.json *.config.cjs *.config.js *.config.ts tsconfig.json .npmrc ./
RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
RUN pnpm i
COPY src ./src
COPY static ./static
RUN pnpm build
# final image
FROM registry.odit.services/library/nginx-brotli:3.15 as final
COPY --from=build /app/build /usr/share/nginx/html
-8
View File
@@ -1,8 +0,0 @@
The MIT License (MIT)
Copyright © 2023 ODIT.Services UG (haftungsbeschränkts) - info@odit.services
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+5 -5
View File
@@ -1,6 +1,6 @@
# create-svelte
# sv
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
## Creating a project
@@ -8,10 +8,10 @@ If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
npx sv create
# create a new project in my-app
npm create svelte@latest my-app
npx sv create my-app
```
## Developing
@@ -35,4 +35,4 @@ npm run build
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
+14
View File
@@ -0,0 +1,14 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"style": "default",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src\\app.css",
"baseColor": "slate"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils"
},
"typescript": true
}
+6
View File
@@ -0,0 +1,6 @@
version: "3"
services:
httpd:
build: .
ports:
- 8181:80
+36
View File
@@ -0,0 +1,36 @@
import js from '@eslint/js';
import { includeIgnoreFile } from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import { fileURLToPath } from 'node:url';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';
const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url));
export default ts.config(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
{
languageOptions: {
globals: {
...globals.browser,
...globals.node
}
}
},
{
files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
ignores: ["eslint.config.js", "svelte.config.js"],
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
}
);
+32 -54
View File
@@ -1,68 +1,46 @@
{
"name": "@lfk/kiosk",
"name": "kiosk",
"private": true,
"version": "0.0.1",
"private": false,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write .",
"release": "release-it",
"license:export": "license-exporter --markdown && git stage licenses.md"
"lint": "eslint ."
},
"devDependencies": {
"@odit/license-exporter": "^0.0.12",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "^1.5.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"auto-changelog": "^2.4.0",
"autoprefixer": "^10.4.7",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.14",
"postcss-load-config": "^4.0.1",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"release-it": "^15.10.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"svelte-preprocess": "^4.10.7",
"tailwindcss": "^3.1.5",
"tslib": "^2.4.1",
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"autoprefixer": "^10.4.20",
"bits-ui": "0.22.0",
"clsx": "^2.1.1",
"eslint": "^9.18.0",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"lucide-svelte": "^0.483.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwind-merge": "^3.0.2",
"tailwind-variants": "^1.0.0",
"tailwindcss": "^3.4.17",
"typescript": "^5.0.0",
"vite": "^4.2.0"
"typescript-eslint": "^8.20.0",
"vite": "^6.0.0"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
},
"type": "module",
"dependencies": {
"bwip-js": "^3.4.0"
},
"release-it": {
"git": {
"commit": true,
"requireCleanWorkingDir": false,
"commitMessage": "🚀Bumped version to ${version}",
"requireBranch": "dev",
"push": true,
"tag": true,
"tagName": null,
"tagAnnotation": "${version}"
},
"npm": {
"publish": false
},
"hooks": {
"after:bump": "pnpx auto-changelog --commit-limit false -p -u --hide-credit && pnpm licenses:export && git add CHANGELOG.md licenses.md"
}
},
"volta": {
"node": "19.9.0"
},
"engines": {
"pnpm": "8"
"@lucide/svelte": "^0.483.0",
"mode-watcher": "^0.5.1"
}
}
}
+2172 -3973
View File
File diff suppressed because it is too large Load Diff
-13
View File
@@ -1,13 +0,0 @@
const tailwindcss = require('tailwindcss');
const autoprefixer = require('autoprefixer');
const config = {
plugins: [
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer
]
};
module.exports = config;
+6
View File
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};
+49
View File
@@ -0,0 +1,49 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 72.22% 50.59%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.75rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.3% 48%;
}
}
+2 -1
View File
@@ -1,10 +1,11 @@
// See https://kit.svelte.dev/docs/types#app
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
-4
View File
@@ -1,4 +0,0 @@
/* Write your global styles here, in PostCSS syntax */
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -0,0 +1,25 @@
<script lang="ts">
import { Button as ButtonPrimitive } from "bits-ui";
import { type Events, type Props, buttonVariants } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = Props;
type $$Events = Events;
let className: $$Props["class"] = undefined;
export let variant: $$Props["variant"] = "default";
export let size: $$Props["size"] = "default";
export let builders: $$Props["builders"] = [];
export { className as class };
</script>
<ButtonPrimitive.Root
{builders}
class={cn(buttonVariants({ variant, size, className }))}
type="button"
{...$$restProps}
on:click
on:keydown
>
<slot />
</ButtonPrimitive.Root>
+49
View File
@@ -0,0 +1,49 @@
import { type VariantProps, tv } from "tailwind-variants";
import type { Button as ButtonPrimitive } from "bits-ui";
import Root from "./button.svelte";
const buttonVariants = tv({
base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border-input bg-background hover:bg-accent hover:text-accent-foreground border",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
type Variant = VariantProps<typeof buttonVariants>["variant"];
type Size = VariantProps<typeof buttonVariants>["size"];
type Props = ButtonPrimitive.Props & {
variant?: Variant;
size?: Size;
};
type Events = ButtonPrimitive.Events;
export {
Root,
type Props,
type Events,
//
Root as Button,
type Props as ButtonProps,
type Events as ButtonEvents,
buttonVariants,
};
@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<div class={cn("p-6", className)} {...$$restProps}>
<slot />
</div>
@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLParagraphElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<p class={cn("text-muted-foreground text-sm", className)} {...$$restProps}>
<slot />
</p>
@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<div class={cn("flex items-center p-6 pt-0", className)} {...$$restProps}>
<slot />
</div>
@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<div class={cn("flex flex-col space-y-1.5 p-6 pb-0", className)} {...$$restProps}>
<slot />
</div>
@@ -0,0 +1,21 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { HeadingLevel } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
tag?: HeadingLevel;
};
let className: $$Props["class"] = undefined;
export let tag: $$Props["tag"] = "h3";
export { className as class };
</script>
<svelte:element
this={tag}
class={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...$$restProps}
>
<slot />
</svelte:element>
+16
View File
@@ -0,0 +1,16 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<div
class={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
{...$$restProps}
>
<slot />
</div>
+24
View File
@@ -0,0 +1,24 @@
import Root from "./card.svelte";
import Content from "./card-content.svelte";
import Description from "./card-description.svelte";
import Footer from "./card-footer.svelte";
import Header from "./card-header.svelte";
import Title from "./card-title.svelte";
export {
Root,
Content,
Description,
Footer,
Header,
Title,
//
Root as Card,
Content as CardContent,
Description as CardDescription,
Footer as CardFooter,
Header as CardHeader,
Title as CardTitle,
};
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
@@ -0,0 +1,35 @@
<script lang="ts">
import { Checkbox as CheckboxPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import Minus from "lucide-svelte/icons/minus";
import { cn } from "$lib/utils.js";
type $$Props = CheckboxPrimitive.Props;
type $$Events = CheckboxPrimitive.Events;
let className: $$Props["class"] = undefined;
export let checked: $$Props["checked"] = false;
export { className as class };
</script>
<CheckboxPrimitive.Root
class={cn(
"border-primary ring-offset-background focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground peer box-content h-4 w-4 shrink-0 rounded-sm border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
className
)}
bind:checked
{...$$restProps}
on:click
>
<CheckboxPrimitive.Indicator
class={cn("flex h-4 w-4 items-center justify-center text-current")}
let:isChecked
let:isIndeterminate
>
{#if isChecked}
<Check class="h-3.5 w-3.5" />
{:else if isIndeterminate}
<Minus class="h-3.5 w-3.5" />
{/if}
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
+6
View File
@@ -0,0 +1,6 @@
import Root from "./checkbox.svelte";
export {
Root,
//
Root as Checkbox,
};
+29
View File
@@ -0,0 +1,29 @@
import Root from "./input.svelte";
export type FormInputEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLInputElement;
};
export type InputEvents = {
blur: FormInputEvent<FocusEvent>;
change: FormInputEvent<Event>;
click: FormInputEvent<MouseEvent>;
focus: FormInputEvent<FocusEvent>;
focusin: FormInputEvent<FocusEvent>;
focusout: FormInputEvent<FocusEvent>;
keydown: FormInputEvent<KeyboardEvent>;
keypress: FormInputEvent<KeyboardEvent>;
keyup: FormInputEvent<KeyboardEvent>;
mouseover: FormInputEvent<MouseEvent>;
mouseenter: FormInputEvent<MouseEvent>;
mouseleave: FormInputEvent<MouseEvent>;
mousemove: FormInputEvent<MouseEvent>;
paste: FormInputEvent<ClipboardEvent>;
input: FormInputEvent<InputEvent>;
wheel: FormInputEvent<WheelEvent>;
};
export {
Root,
//
Root as Input,
};
+42
View File
@@ -0,0 +1,42 @@
<script lang="ts">
import type { HTMLInputAttributes } from "svelte/elements";
import type { InputEvents } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLInputAttributes;
type $$Events = InputEvents;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"] = undefined;
export { className as class };
// Workaround for https://github.com/sveltejs/svelte/issues/9305
// Fixed in Svelte 5, but not backported to 4.x.
export let readonly: $$Props["readonly"] = undefined;
</script>
<input
class={cn(
"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
bind:value
{readonly}
on:blur
on:change
on:click
on:focus
on:focusin
on:focusout
on:keydown
on:keypress
on:keyup
on:mouseover
on:mouseenter
on:mouseleave
on:mousemove
on:paste
on:input
on:wheel|passive
{...$$restProps}
/>
+7
View File
@@ -0,0 +1,7 @@
import Root from "./label.svelte";
export {
Root,
//
Root as Label,
};
+21
View File
@@ -0,0 +1,21 @@
<script lang="ts">
import { Label as LabelPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = LabelPrimitive.Props;
type $$Events = LabelPrimitive.Events;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<LabelPrimitive.Root
class={cn(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
className
)}
{...$$restProps}
on:mousedown
>
<slot />
</LabelPrimitive.Root>
+7
View File
@@ -0,0 +1,7 @@
import Root from "./progress.svelte";
export {
Root,
//
Root as Progress,
};
@@ -0,0 +1,21 @@
<script lang="ts">
import { Progress as ProgressPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = ProgressPrimitive.Props;
let className: $$Props["class"] = undefined;
export let max: $$Props["max"] = 100;
export let value: $$Props["value"] = undefined;
export { className as class };
</script>
<ProgressPrimitive.Root
class={cn("bg-secondary relative h-4 w-full overflow-hidden rounded-full", className)}
{...$$restProps}
>
<div
class="bg-primary h-full w-full flex-1 transition-all"
style={`transform: translateX(-${100 - (100 * (value ?? 0)) / (max ?? 1)}%)`}
></div>
</ProgressPrimitive.Root>
+1
View File
@@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.
+62
View File
@@ -0,0 +1,62 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { cubicOut } from "svelte/easing";
import type { TransitionConfig } from "svelte/transition";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
type FlyAndScaleParams = {
y?: number;
x?: number;
start?: number;
duration?: number;
};
export const flyAndScale = (
node: Element,
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => {
const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform;
const scaleConversion = (
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB;
const percentage = (valueA - minA) / (maxA - minA);
const valueB = percentage * (maxB - minB) + minB;
return valueB;
};
const styleToString = (
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str;
return str + `${key}:${style[key]};`;
}, "");
};
return {
duration: params.duration ?? 200,
delay: 0,
css: (t) => {
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
return styleToString({
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
opacity: t
});
},
easing: cubicOut
};
};
+36
View File
@@ -0,0 +1,36 @@
<script>
import { Button } from "$lib/components/ui/button";
</script>
<div class="container p-4 mx-auto">
<div class="rounded-lg border bg-card text-card-foreground shadow-sm">
<div class="p-6 space-y-4">
<div class="flex items-center justify-between">
<h2 class="text-2xl font-bold">Guide</h2>
</div>
<div class="grid gap-4">
<div class="rounded-md bg-muted p-4">
<h3 class="font-medium mb-2">Where am I?</h3>
<p>
Welcome to the Lauf für Kaya Kiosk application.<br>
This tool helps you with signing up runners an getting them started.
</p>
</div>
<div class="rounded-md bg-muted p-4">
<h3 class="font-medium mb-2">Basic Functions</h3>
<ul class="list-disc pl-5 space-y-1">
<li>Register new participants</li>
<li>Get your personal selfservice token</li>
</ul>
</div>
<div class="rounded-md bg-muted p-4">
<h3 class="font-medium mb-2">Need More Help?</h3>
<p>Contact the event organizers for additional assistance.</p>
</div>
</div>
</div>
</div>
</div>
+33
View File
@@ -0,0 +1,33 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button/index.js";
import * as Card from "$lib/components/ui/card/index.js";
import { Input } from "$lib/components/ui/input/index.js";
import { Label } from "$lib/components/ui/label/index.js";
let { loggedin = $bindable() } = $props();
</script>
<div class="pt-48">
<form
onsubmit={() => {
loggedin = true;
}}
class="flex justify-center items-center overflow-hidden"
>
<Card.Root class="w-full max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Login</Card.Title>
<Card.Description>Please enter kiosk credentials.</Card.Description>
</Card.Header>
<Card.Content class="grid gap-4">
<div class="grid gap-2">
<Label for="password">Token</Label>
<Input id="password" type="password" required autofocus />
</div>
</Card.Content>
<Card.Footer>
<Button class="w-full" type="submit">Sign in</Button>
</Card.Footer>
</Card.Root>
</form>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

+259
View File
@@ -0,0 +1,259 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button/index.js";
import * as Card from "$lib/components/ui/card/index.js";
import Checkbox from "$lib/components/ui/checkbox/checkbox.svelte";
import { Input } from "$lib/components/ui/input";
import { Label } from "$lib/components/ui/label";
import { Progress } from "$lib/components/ui/progress";
import sampleQR from "./sampleqrlfkselfservice.png";
const Steps = {
WELCOME: {
name: "Welcome",
progress: 0,
showback: false,
},
SIGNUP: {
name: "Signup",
progress: 25,
showback: true,
},
SIGNUP_MAIL: {
name: "Signup with Mail",
progress: 50,
showback: true,
},
SIGNUP_AGB_ACCEPT: {
name: "Accept terms",
progress: 75,
showback: true,
},
SIGNUP_SUCCESS: {
name: "Done",
progress: 100,
showback: false,
},
SIGNIN: {
name: "Signin with Barcode",
progress: 100,
showback: false,
},
SIGNIN_MAIL: {
name: "Signin by Mail",
progress: 75,
showback: true,
},
SIGNIN_MAIL_SUCCESS: {
name: "Signin by Mail Success",
progress: 100,
showback: false,
},
} as const;
type StepType = (typeof Steps)[keyof typeof Steps];
let currentStep = $state<StepType>(Steps.WELCOME);
let agbAgreed = $state<boolean>(false);
let email = $state<string>("");
let firstname = $state<string>("");
let lastname = $state<string>("");
let remainingseconds = $state<number>(5);
</script>
<div class="pt-48">
<div class="flex justify-center items-center overflow-hidden">
<Card.Root class="w-full max-w-xl">
<Card.Header>
<Card.Title class="text-2xl">Welcome</Card.Title>
<Card.Description
>Let me guide you through the signup process.</Card.Description
>
{#if currentStep.name !== Steps.WELCOME.name}
<Progress value={currentStep.progress} />
{/if}
</Card.Header>
<Card.Content class="grid gap-4">
{#if currentStep.name == Steps.WELCOME.name}
<div class="grid gap-2">
<Button
autofocus
class="w-full"
on:click={() => {
currentStep = Steps.SIGNUP;
}}>I want to sign up now</Button
>
</div>
<div class="grid gap-2">
<Button
variant="secondary"
class="w-full"
on:click={() => {
currentStep = Steps.SIGNIN;
}}>I already signed up online</Button
>
</div>
{:else if currentStep.name == Steps.SIGNUP.name}
<form
class="grid gap-2"
onsubmit={() => {
currentStep = Steps.SIGNUP_MAIL;
}}
>
<div class="grid gap-2">
<Label for="firstname">Please enter your first name</Label>
<Input
on:keypress={(event) => {
console.log(event.key);
if (event.key === "Enter") {
document.getElementById("lastname")?.focus();
}
}}
bind:value={firstname}
id="firstname"
type="text"
placeholder="Max"
required
autofocus
/>
</div>
<div class="grid gap-2">
<Label for="lastname">Please enter your last name</Label>
<Input
bind:value={lastname}
id="lastname"
type="text"
placeholder="Mustermann"
required
/>
</div>
<Button type="submit" variant="default" class="w-full"
>Continue</Button
>
</form>
{:else if currentStep.name == Steps.SIGNUP_MAIL.name}
<form
class="grid gap-2"
onsubmit={() => {
currentStep = Steps.SIGNUP_AGB_ACCEPT;
}}
>
<div class="grid gap-2">
<Label for="email"
>Enter your email to get an invitation to our selfservice
(optional)</Label
>
<Input
autofocus
id="email"
type="email"
placeholder="m@example.com"
bind:value={email}
/>
</div>
<Button type="submit" variant="default" class="w-full"
>Continue</Button
>
</form>
{:else if currentStep.name == Steps.SIGNUP_AGB_ACCEPT.name}
{#if email !== ""}
By registering, you confirm that {email} is your email
{/if}
<div class="items-top flex space-x-2">
<Checkbox bind:checked={agbAgreed} autofocus id="terms1" />
<div class="grid gap-1.5 leading-none">
<Label
for="terms1"
class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Accept terms and conditions
</Label>
<p class="text-muted-foreground text-sm">
You agree to our Terms of Service and Privacy Policy.
</p>
</div>
</div>
<Button
disabled={!agbAgreed}
variant="default"
class="w-full"
on:click={() => {
currentStep = Steps.SIGNUP_SUCCESS;
}}>Continue</Button
>
{:else if currentStep.name == Steps.SIGNUP_SUCCESS.name}
<p class="text-center">
Alright that's it, just walk up to the next available person and
tell them your name.<br />
You can scan this qr code to login to our selfservice.
<!-- TODO: generate actual qr code -->
<img class="mx-auto h-56" src={sampleQR} alt="" />
</p>
{:else if currentStep.name == Steps.SIGNIN.name}
Just walk up to the next available person and show them your barcode.
{:else if currentStep.name == Steps.SIGNIN_MAIL.name}
<div class="grid gap-2">
<Label for="email"
>No problem, just enter the email address you used to sign up</Label
>
<Input
id="email"
type="email"
placeholder="m@example.com"
bind:value={email}
required
/>
</div>
<div class="grid gap-2">
<Button
class="w-full"
on:click={() => {
console.log("Email: ", email);
currentStep = Steps.SIGNIN_MAIL_SUCCESS;
}}>Continue</Button
>
</div>
{:else if currentStep.name == Steps.SIGNIN_MAIL_SUCCESS.name}
We found your email address, just walk up to the next available person
and tell them your name.
{/if}
</Card.Content>
<Card.Footer class="grid gap-2">
{#if currentStep.showback}
<Button
variant="destructive"
class="w-full"
on:click={() => {
switch (currentStep.name) {
case Steps.SIGNUP.name:
currentStep = Steps.WELCOME;
break;
case Steps.SIGNUP_MAIL.name:
currentStep = Steps.SIGNUP;
break;
case Steps.SIGNUP_AGB_ACCEPT.name:
currentStep = Steps.SIGNUP_MAIL;
break;
case Steps.SIGNIN.name:
currentStep = Steps.WELCOME;
break;
case Steps.SIGNIN_MAIL.name:
currentStep = Steps.SIGNIN;
break;
default:
break;
}
}}>Go Back</Button
>
{/if}
{#if currentStep.progress == 100}
<Button
variant="default"
class="w-full"
on:click={() => {
currentStep = Steps.WELCOME;
}}>Done</Button
>
{/if}
</Card.Footer>
</Card.Root>
</div>
</div>
+51 -3
View File
@@ -1,5 +1,53 @@
<script>
import '../app.postcss';
<script lang="ts">
import "../app.css";
import { ModeWatcher } from "mode-watcher";
import { Button } from "$lib/components/ui/button";
import { Sun, Moon, HelpCircle } from "@lucide/svelte";
import { toggleMode } from "mode-watcher";
import Help from "./(components)/help.svelte";
let { children } = $props();
let showHelp = $state(false);
</script>
<slot />
<ModeWatcher />
<div class="overflow-hidden">
<div
class="fixed top-0 left-0 right-0 z-50 border-b bg-background/80 backdrop-blur-sm"
>
<div class="container flex items-center justify-between py-2">
<h1 class="text-xl font-bold">Lauf für Kaya! Kiosk</h1>
<div class="flex items-center gap-2">
<!-- <Button on:click={toggleMode} variant="outline" size="icon">
<Sun
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<Moon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button> -->
<Button
variant="outline"
size="icon"
on:click={() => (showHelp = !showHelp)}
>
<HelpCircle
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all"
/>
<span class="sr-only">Show help</span>
</Button>
<!-- More buttons can be added here -->
</div>
</div>
</div>
<div class="mt-14">
{#if showHelp}
<Help />
{:else}
<!-- This div adds spacing below the fixed navbar -->
{@render children()}
{/if}
</div>
</div>
-1
View File
@@ -1 +0,0 @@
export const prerender = true;
+11 -2
View File
@@ -1,2 +1,11 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script lang="ts">
import Login from "./(components)/login.svelte";
import Signup from "./(components)/signup.svelte";
let loggedin = $state(false);
</script>
{#if !loggedin}
<Login bind:loggedin />
{:else}
<Signup />
{/if}
+8 -13
View File
@@ -1,23 +1,18 @@
import preprocess from 'svelte-preprocess';
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';
import adapter from "@sveltejs/adapter-static";
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: [
vitePreprocess(),
preprocess({
postcss: true
})
],
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
},
alias: {
"@/*": "./src/lib/*",
}
};
-11
View File
@@ -1,11 +0,0 @@
const config = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {}
},
plugins: []
};
module.exports = config;
+64
View File
@@ -0,0 +1,64 @@
import { fontFamily } from "tailwindcss/defaultTheme";
import type { Config } from "tailwindcss";
const config: Config = {
darkMode: ["class"],
content: ["./src/**/*.{html,js,svelte,ts}"],
safelist: ["dark"],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px"
}
},
extend: {
colors: {
border: "hsl(var(--border) / <alpha-value>)",
input: "hsl(var(--input) / <alpha-value>)",
ring: "hsl(var(--ring) / <alpha-value>)",
background: "hsl(var(--background) / <alpha-value>)",
foreground: "hsl(var(--foreground) / <alpha-value>)",
primary: {
DEFAULT: "hsl(var(--primary) / <alpha-value>)",
foreground: "hsl(var(--primary-foreground) / <alpha-value>)"
},
secondary: {
DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
foreground: "hsl(var(--secondary-foreground) / <alpha-value>)"
},
destructive: {
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)"
},
muted: {
DEFAULT: "hsl(var(--muted) / <alpha-value>)",
foreground: "hsl(var(--muted-foreground) / <alpha-value>)"
},
accent: {
DEFAULT: "hsl(var(--accent) / <alpha-value>)",
foreground: "hsl(var(--accent-foreground) / <alpha-value>)"
},
popover: {
DEFAULT: "hsl(var(--popover) / <alpha-value>)",
foreground: "hsl(var(--popover-foreground) / <alpha-value>)"
},
card: {
DEFAULT: "hsl(var(--card) / <alpha-value>)",
foreground: "hsl(var(--card-foreground) / <alpha-value>)"
}
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)"
},
fontFamily: {
sans: [...fontFamily.sans]
}
}
},
};
export default config;
+4 -2
View File
@@ -8,9 +8,11 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in