16 Commits

Author SHA1 Message Date
ee6bfbe34c Merge pull request 'merge new features' (#9) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 2m57s
Build Docker image / deploy (push) Successful in 2s
Build Docker image / verify (push) Successful in 1m3s
Reviewed-on: erman/esn-code-scanner-app#9
2025-06-25 14:17:09 +02:00
5ea15fa75c Merge pull request 'UX improvements' (#8) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 1m18s
Build Docker image / deploy (push) Successful in 2s
Build Docker image / verify (push) Successful in 23s
Reviewed-on: erman/esn-code-scanner-app#8
2025-06-24 19:15:46 +02:00
621d2bff2d Merge pull request 'Styling of creator progress' (#7) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 59s
Build Docker image / deploy (push) Successful in 2s
Build Docker image / verify (push) Successful in 23s
Reviewed-on: erman/esn-code-scanner-app#7
2025-06-24 12:45:39 +02:00
f161aa0a3a Merge pull request 'supabase' (#6) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 1m17s
Build Docker image / deploy (push) Successful in 12s
Build Docker image / verify (push) Successful in 31s
Reviewed-on: erman/esn-code-scanner-app#6
2025-06-24 11:29:07 +02:00
617c00e8dc Add deploy and verify
All checks were successful
Build Docker image / build (push) Successful in 2m23s
Build Docker image / deploy (push) Successful in 2s
Build Docker image / verify (push) Successful in 37s
2025-06-24 11:25:40 +02:00
2ca7dc72cb Testing komodo CI
Some checks failed
Build Docker image / build (push) Failing after 5s
2025-06-24 11:15:15 +02:00
d8d2269817 Merge pull request 'Fix google env variables' (#5) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 1m25s
Reviewed-on: erman/esn-code-scanner-app#5
2025-06-22 17:59:20 +02:00
f768ae8d8b Fix double runs
All checks were successful
Build Docker image / build (push) Successful in 1m28s
2025-06-22 17:52:57 +02:00
e2a5fe2190 Merge pull request 'Add mailing prototype' (#4) from supabase into main
Some checks failed
Build Docker image / build (push) Has been cancelled
Reviewed-on: erman/esn-code-scanner-app#4
2025-06-22 17:48:47 +02:00
1ffe7d862f Merge pull request 'Styling' (#3) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 1m49s
Reviewed-on: erman/esn-code-scanner-app#3
2025-06-21 23:36:53 +02:00
fb9a6677e1 Run only on merges
Some checks failed
Build Docker image / build (push) Has been cancelled
2025-06-21 23:36:20 +02:00
aba3369565 Merge pull request 'Fix missing env variable during build time' (#2) from supabase into main
All checks were successful
Build Docker image / build (push) Successful in 2m49s
Reviewed-on: erman/esn-code-scanner-app#2
2025-06-21 22:40:33 +02:00
083a7ce2e5 Don't ignore CI changes
Some checks failed
Build Docker image / build (push) Failing after 5m27s
2025-06-21 22:15:54 +02:00
2bd7edde17 Run actions on closed pulls 2025-06-21 22:13:19 +02:00
4dd35c64e0 Merge pull request 'supabase' (#1) from supabase into main
Reviewed-on: erman/esn-code-scanner-app#1
2025-06-21 22:10:08 +02:00
2bf0394ffc Build release update only once a month
Some checks failed
Build Docker image / build (push) Failing after 5s
2025-05-29 11:08:42 +02:00
12 changed files with 80 additions and 172 deletions

View File

@@ -5,7 +5,7 @@ on:
branches:
- main
schedule:
- cron: "0 22 * * 0" # sunday 22:00
- cron: "0 22 1 * *" # First of every month
jobs:
build:
@@ -46,8 +46,28 @@ jobs:
org.opencontainers.image.revision=${{ env.GITHUB_SHA }}
org.opencontainers.image.vendor=Orebolt.cz
org.opencontainers.image.ref.name=${{ env.GITHUB_REF }}
org.opencontainers.image.title=ScanWave
org.opencontainers.image.title=ESN Code Scanner App
deploy:
needs: build
steps:
- name: Trigger Komodo Deploy
env:
URL: ${{ secrets.KOMODO_URL }}
SECRET: ${{ secrets.KOMODO_SECRET }}
BODY_FILE: ${{ github.event_path }}
run: |
SIG="sha256=$(openssl dgst -sha256 -hmac "$SECRET" "$BODY_FILE" | cut -d' ' -f2)"
curl -fsSL -X POST "$URL" \
-H 'Content-Type: application/json' \
-H "X-Hub-Signature-256: $SIG" \
-H 'X-GitHub-Event: push' \
-H "X-GitHub-Delivery: $GITHUB_RUN_ID.$GITHUB_RUN_NUMBER" \
--data @"$BODY_FILE"
verify:
needs: build
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.24.0
with:

View File

@@ -1,12 +1,12 @@
services:
app:
image: ${DOCKER_REGISTRY}/${DOCKER_USER}/${DOCKER_IMAGE}:latest
image: ${DOCKER_REGISTRY}/${DOCKER_USER}/esn-code-scanner-app:latest
restart: unless-stopped
env_file: .env
labels:
- "traefik.enable=true"
- "traefik.http.routers.scan-wave.rule=Host(`scanwave.orebolt.cz`)"
- "traefik.http.routers.scan-wave.tls.certresolver=leresolver"
- "traefik.http.routers.scan-wave.entrypoints=websecure"
- "traefik.http.services.scan-wave.loadbalancer.server.port=3000"
- "traefik.http.routers.scan-wave.middlewares=hsts"
- "traefik.http.routers.esn-scanner.rule=Host(`scanner.esn.orebolt.cz`)"
- "traefik.http.routers.esn-scanner.tls.certresolver=leresolver"
- "traefik.http.routers.esn-scanner.entrypoints=websecure"
- "traefik.http.services.esn-scanner.loadbalancer.server.port=3000"
- "traefik.http.routers.esn-scanner.middlewares=hsts"

View File

@@ -1,7 +1,7 @@
---
services:
app:
image: ${DOCKER_REGISTRY}/${DOCKER_USER}/${DOCKER_IAMGE}:latest
image: ${DOCKER_REGISTRY}/${DOCKER_USER}/esn-code-scanner-app:latest
restart: unless-stopped
ports:
- "3000:3000"

93
package-lock.json generated
View File

@@ -1,11 +1,11 @@
{
"name": "scan-wave",
"name": "esn-code-scanner",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "scan-wave",
"name": "esn-code-scanner",
"version": "0.0.1",
"dependencies": {
"@supabase/ssr": "^0.6.1",
@@ -18,7 +18,7 @@
"simple-icons": "^15.3.0"
},
"devDependencies": {
"@sveltejs/kit": "^2.22.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
@@ -30,7 +30,7 @@
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"vite-plugin-devtools-json": "^0.2.0"
"vite": "^6.2.6"
}
},
"node_modules/@ampproject/remapping": {
@@ -58,7 +58,6 @@
"os": [
"aix"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -75,7 +74,6 @@
"os": [
"android"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -92,7 +90,6 @@
"os": [
"android"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -109,7 +106,6 @@
"os": [
"android"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -126,7 +122,6 @@
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -143,7 +138,6 @@
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -160,7 +154,6 @@
"os": [
"freebsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -177,7 +170,6 @@
"os": [
"freebsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -194,7 +186,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -211,7 +202,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -228,7 +218,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -245,7 +234,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -262,7 +250,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -279,7 +266,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -296,7 +282,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -313,7 +298,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -330,7 +314,6 @@
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -347,7 +330,6 @@
"os": [
"netbsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -364,7 +346,6 @@
"os": [
"netbsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -381,7 +362,6 @@
"os": [
"openbsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -398,7 +378,6 @@
"os": [
"openbsd"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -415,7 +394,6 @@
"os": [
"sunos"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -432,7 +410,6 @@
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -449,7 +426,6 @@
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -466,7 +442,6 @@
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">=18"
}
@@ -1019,15 +994,15 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.22.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.22.0.tgz",
"integrity": "sha512-DJm0UxVgzXq+1MUfiJK4Ridk7oIQsIets6JwHiEl97sI6nXScfXe+BeqNhzB7jQIVBb3BM51U4hNk8qQxRXBAA==",
"version": "2.21.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.21.0.tgz",
"integrity": "sha512-kvu4h9qXduiPk1Q1oqFKDLFGu/7mslEYbVaqpbBcBxjlRJnvNCFwEvEwKt0Mx9TtSi8J77xRelvJobrGlst4nQ==",
"license": "MIT",
"dependencies": {
"@sveltejs/acorn-typescript": "^1.0.5",
"@types/cookie": "^0.6.0",
"acorn": "^8.14.1",
"cookie": "^0.6.0",
"cookie": "^0.7.0",
"devalue": "^5.1.0",
"esm-env": "^1.2.2",
"kleur": "^4.1.5",
@@ -1035,8 +1010,7 @@
"mrmime": "^2.0.0",
"sade": "^1.8.1",
"set-cookie-parser": "^2.6.0",
"sirv": "^3.0.0",
"vitefu": "^1.0.6"
"sirv": "^3.0.0"
},
"bin": {
"svelte-kit": "svelte-kit.js"
@@ -1045,9 +1019,9 @@
"node": ">=18.13"
},
"peerDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
"svelte": "^4.0.0 || ^5.0.0-next.0",
"vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0"
"vite": "^5.0.3 || ^6.0.0"
}
},
"node_modules/@sveltejs/vite-plugin-svelte": {
@@ -1630,9 +1604,9 @@
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -1796,7 +1770,6 @@
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -2597,7 +2570,6 @@
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -2758,7 +2730,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.8",
"picocolors": "^1.1.1",
@@ -3265,13 +3236,6 @@
"typescript": ">=5.0.0"
}
},
"node_modules/svelte-kit": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/svelte-kit/-/svelte-kit-1.2.0.tgz",
"integrity": "sha512-RRaOHBhpDv4g2v9tcq8iNw055Pt0MlLps6JVA7/40f4KAbtztXSI4T6MZYbHRirO708urfAAMx6Qow+tQfCHug==",
"hasInstallScript": true,
"license": "MIT"
},
"node_modules/tailwindcss": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.7.tgz",
@@ -3312,7 +3276,6 @@
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
"integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
"license": "MIT",
"peer": true,
"dependencies": {
"fdir": "^6.4.4",
"picomatch": "^4.0.2"
@@ -3386,26 +3349,11 @@
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vite": {
"version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
@@ -3475,19 +3423,6 @@
}
}
},
"node_modules/vite-plugin-devtools-json": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/vite-plugin-devtools-json/-/vite-plugin-devtools-json-0.2.0.tgz",
"integrity": "sha512-K7PoaWOEJECZ1n3VbhJXsUAX2PsO0xY7KFMM/Leh7tUev0M5zi+lz+vnVVdCK17IOK9Jp9rdzHXc08cnQirGbg==",
"dev": true,
"license": "MIT",
"dependencies": {
"uuid": "^11.1.0"
},
"peerDependencies": {
"vite": "^2.7.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
}
},
"node_modules/vitefu": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.6.tgz",

View File

@@ -1,5 +1,5 @@
{
"name": "scan-wave",
"name": "esn-code-scanner",
"private": true,
"version": "0.0.1",
"type": "module",
@@ -14,7 +14,7 @@
"lint": "prettier --check ."
},
"devDependencies": {
"@sveltejs/kit": "^2.22.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
@@ -26,7 +26,7 @@
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"vite-plugin-devtools-json": "^0.2.0"
"vite": "^6.2.6"
},
"dependencies": {
"@supabase/ssr": "^0.6.1",

View File

@@ -1,24 +1,20 @@
<script>
import { invalidate } from '$app/navigation';
import { onMount } from 'svelte';
import '../app.css';
import { invalidate } from '$app/navigation'
import { onMount } from 'svelte'
import "../app.css";
let { data, children } = $props();
let { session, supabase } = $derived(data);
let { data, children } = $props()
let { session, supabase } = $derived(data)
onMount(() => {
const { data } = supabase.auth.onAuthStateChange((_, newSession) => {
if (newSession?.expires_at !== session?.expires_at) {
invalidate('supabase:auth');
}
});
onMount(() => {
const { data } = supabase.auth.onAuthStateChange((_, newSession) => {
if (newSession?.expires_at !== session?.expires_at) {
invalidate('supabase:auth')
}
})
return () => data.subscription.unsubscribe();
});
return () => data.subscription.unsubscribe()
})
</script>
<svelte:head>
<title>ScanWave</title>
</svelte:head>
{@render children()}
{@render children()}

View File

@@ -3,7 +3,7 @@
<div class="mb-8">
<img class="w-32 h-auto" src="/qr-code.png" alt="">
</div>
<h1 class="text-3xl font-bold text-center mb-2">ScanWave</h1>
<h1 class="text-3xl font-bold text-center mb-2">ESN Scanner App</h1>
<h2 class="text-lg text-gray-600 text-center mb-8">Make entrance to your events a breeze.</h2>
<div class="flex space-x-4 w-full justify-center">
<a href="/private/home" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-full shadow-none border border-gray-300 w-64 text-center transition">

View File

@@ -2,18 +2,13 @@
// Add any navbar logic here if needed
</script>
<nav class="bg-gray-50 border-b border-gray-300 text-gray-900 p-2">
<div class="container max-w-2xl mx-auto p-2">
<div class="flex items-center justify-between">
<div class="font-bold text-lg">ScanWave</div>
<ul class="flex space-x-4">
<li><a href="/private/home" class="hover:underline">Home</a></li>
<li><a href="/private/scanner" class="hover:underline">Scanner</a></li>
<li><a href="/private/events" class="hover:underline">Events</a></li>
</ul>
</div>
</div>
<nav class="bg-white border-b border-gray-300 text-gray-900 p-4 flex items-center justify-between">
<div class="font-bold text-lg">ESN Scanner</div>
<ul class="flex space-x-4">
<li><a href="/private/home" class="hover:underline">Home</a></li>
<li><a href="/private/scanner" class="hover:underline">Scanner</a></li>
<li><a href="/private/events" class="hover:underline">Events</a></li>
</ul>
</nav>
<div class="container max-w-2xl mx-auto p-2 bg-white">

View File

@@ -3,5 +3,6 @@ export async function load({ locals }) {
.from('events')
.select('*')
.order('date', { ascending: false });
console.log('events', events);
return { events };
}

View File

@@ -7,45 +7,13 @@
};
</script>
<h1 class="mt-2 mb-4 text-center text-2xl font-bold">User Profile</h1>
<div class="mb-4 rounded border border-gray-300 bg-white p-6">
<div class="flex flex-col gap-2">
<div class="flex items-center gap-3 mb-4">
<div class="h-12 w-12 rounded-full bg-gray-200 flex items-center justify-center text-xl font-bold text-gray-600">
{data.user?.user_metadata.display_name?.[0] ?? "U"}
</div>
<div>
<span class="text-lg font-semibold text-gray-800">{data.user?.user_metadata.display_name}</span>
<div class="text-sm text-gray-500">{data.user?.email}</div>
</div>
</div>
<div class="flex flex-col gap-1">
<div>
<span class="font-medium text-gray-700">Section:</span>
<span class="text-gray-900">{data.user_profile?.section.name ?? "N/A"}</span>
</div>
<div>
<span class="font-medium text-gray-700">Position:</span>
<span class="text-gray-900">{data.user_profile?.section_position ?? "N/A"}</span>
</div>
</div>
<h2 class="text-lg mb-2 mt-4">User guide</h2>
<p class="text-gray-700 text-sm leading-relaxed">
To scan a QR code, head over to Scanner in the top right corner. Click on Start scanning and allow camera permissions.
If you close and open your browser and your camera is stuck, simply refresh the page or click Stop scanning and then Start scanning again.
When you scan a QR code, a request is sent to the server to get the user's personal information and to mark their tickets as scanned.
</p>
<h2 class="text-lg mb-2 mt-4">Administrator guide</h2>
<p class="text-gray-700 text-sm leading-relaxed">
You can view events
</p>
</div>
<div class="user-profile">
<h2 class="mb-2 text-2xl font-bold">Currently logged in</h2>
<p><strong>Username:</strong> {data.user?.user_metadata.display_name}</p>
<p><strong>Email:</strong> {data.user?.email}</p>
<p><strong>Section:</strong> {data.user_profile?.section.name}</p>
<p><strong>Position:</strong> {data.user_profile?.section_position}</p>
</div>
<a
href="/auth/signout"
class="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 bg-red-500 hover:bg-red-600 text-white font-semibold py-3 px-8 rounded-full shadow-none border border-gray-300 transition"
>
Sign out
</a>
<button class="mt-4 rounded bg-red-500 px-4 py-2 text-white hover:bg-red-600">
<a href="/auth/signout">Sign out</a>
</button>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { onMount } from 'svelte';
import {
Html5QrcodeScanner,
type Html5QrcodeResult,
@@ -37,12 +37,6 @@
);
scanner.render(onScanSuccess, onScanFailure);
});
onDestroy(() => {
if (scanner) {
scanner.clear().catch(() => {});
}
});
</script>
<div id="qr-scanner" class="w-full h-full max-w-none overflow-hidden rounded-sm"></div>

View File

@@ -1,8 +1,7 @@
import tailwindcss from '@tailwindcss/vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import devtoolsJson from 'vite-plugin-devtools-json';
export default defineConfig({
plugins: [tailwindcss(), sveltekit(), devtoolsJson()]
plugins: [tailwindcss(), sveltekit()]
});