mirror of
https://github.com/Djeeberjr/fw-anwesenheit.git
synced 2025-07-02 17:14:17 +00:00
switched to svelte 5
front gets a bit to complex to do in vanilla
This commit is contained in:
parent
bccf019c11
commit
d764e9699b
@ -1,40 +1,17 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
|
<head>
|
||||||
<head>
|
<meta charset="UTF-8" />
|
||||||
<meta charset="UTF-8" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
<link rel="shortcut icon" href="/favicon.ico" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
<link rel="manifest" href="/site.webmanifest" />
|
<title>Anwesenheit</title>
|
||||||
<title>Anwesenheit</title>
|
</head>
|
||||||
</head>
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
<body class="bg-gradient-to-br from-blue-100 to-indigo-200 min-h-screen flex flex-col items-center justify-start py-10">
|
<script type="module" src="/src/main.ts"></script>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
</body>
|
||||||
<div class="text-center space-y-6 mb-10">
|
|
||||||
<h1 class="text-3xl sm:text-4xl font-bold text-gray-800">
|
|
||||||
Anwesenheit
|
|
||||||
</div>
|
|
||||||
<a class="px-6 py-3 text-lg font-semibold text-white bg-indigo-600 rounded-2xl shadow-md hover:bg-indigo-700 transition"
|
|
||||||
href="/api/csv" download="anwesenheit.csv">
|
|
||||||
Download CSV
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="pt-6">
|
|
||||||
<h2 class="ID" >ID mapping</h2>
|
|
||||||
|
|
||||||
<table id="mappingTable">
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Nachname</th>
|
|
||||||
<th>Vorname</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
1144
web/package-lock.json
generated
1144
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,15 +5,20 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "~5.7.2",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
"vite": "^6.2.0"
|
"@tsconfig/svelte": "^5.0.4",
|
||||||
|
"svelte": "^5.28.1",
|
||||||
|
"svelte-check": "^4.1.6",
|
||||||
|
"typescript": "~5.8.3",
|
||||||
|
"vite": "^6.3.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.4",
|
"@tailwindcss/vite": "^4.1.7",
|
||||||
"tailwindcss": "^4.1.4"
|
"tailwindcss": "^4.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
web/src/App.svelte
Normal file
23
web/src/App.svelte
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import IDTable from "./lib/IDTable.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main
|
||||||
|
class="bg-gradient-to-br from-blue-100 to-indigo-200 min-h-screen flex flex-col items-center justify-start py-10"
|
||||||
|
>
|
||||||
|
<div class="text-center space-y-6 mb-10">
|
||||||
|
<h1 class="text-3xl sm:text-4xl font-bold text-gray-800">Anwesenheit</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="px-6 py-3 text-lg font-semibold text-white bg-indigo-600 rounded-2xl shadow-md hover:bg-indigo-700 transition"
|
||||||
|
href="/api/csv"
|
||||||
|
download="anwesenheit.csv"
|
||||||
|
>
|
||||||
|
Download CSV
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="py-3">
|
||||||
|
<IDTable />
|
||||||
|
</div>
|
||||||
|
</main>
|
@ -1,4 +1,2 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
#mappingTable{
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
export interface IdMapping {
|
export interface IDMapping {
|
||||||
id_map: IDMap
|
id_map: IDMap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11,19 +11,6 @@ export interface Name {
|
|||||||
last: string,
|
last: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestMappings(): Promise<IdMapping> {
|
|
||||||
let req = await fetch("/api/mapping");
|
|
||||||
|
|
||||||
if (req.status != 200) {
|
|
||||||
console.error(await req.text());
|
|
||||||
return { id_map: {} };
|
|
||||||
}
|
|
||||||
|
|
||||||
let mappings: IdMapping = await req.json();
|
|
||||||
|
|
||||||
return mappings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function addMapping(id: string, firstName: string, lastName: string) {
|
export async function addMapping(id: string, firstName: string, lastName: string) {
|
||||||
let req = await fetch("/api/mapping", {
|
let req = await fetch("/api/mapping", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -39,7 +26,7 @@ export async function addMapping(id: string, firstName: string, lastName: string
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.status != 200){
|
if (req.status != 200) {
|
||||||
console.error(await req.text())
|
console.error(await req.text())
|
||||||
}
|
}
|
||||||
}
|
}
|
45
web/src/lib/IDTable.svelte
Normal file
45
web/src/lib/IDTable.svelte
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import type { IDMapping } from "./IDMapping";
|
||||||
|
let data: IDMapping | undefined = $state();
|
||||||
|
|
||||||
|
let rows = $derived(
|
||||||
|
data
|
||||||
|
? Object.entries(data.id_map).map(([id, value]) => ({
|
||||||
|
id,
|
||||||
|
...value,
|
||||||
|
}))
|
||||||
|
: [],
|
||||||
|
);
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
let res = await fetch("/api/mapping");
|
||||||
|
|
||||||
|
data = await res.json();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if data == null}
|
||||||
|
Loading
|
||||||
|
{:else}
|
||||||
|
<div class="bg-indigo-500 p-2 rounded-2xl overflow-x-auto">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left pr-5">ID</th>
|
||||||
|
<th class="text-left pr-5">Nachname</th>
|
||||||
|
<th class="text-left pr-5">Vorname</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="">
|
||||||
|
{#each rows as row}
|
||||||
|
<tr class="even:bg-indigo-600">
|
||||||
|
<td class="whitespace-nowrap pr-5">{row.id}</td>
|
||||||
|
<td class="whitespace-nowrap pr-5">{row.last}</td>
|
||||||
|
<td class="whitespace-nowrap pr-5">{row.first}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/if}
|
@ -1,26 +1,9 @@
|
|||||||
import './style.css'
|
import { mount } from "svelte"
|
||||||
import { IDMap, Name, requestMappings } from './idMapping'
|
import "./app.css"
|
||||||
|
import App from "./App.svelte"
|
||||||
|
|
||||||
function createTableRow(a: string, b: string, c: string): HTMLTableRowElement {
|
const app = mount(App, {
|
||||||
const tr = document.createElement('tr');
|
target: document.getElementById('app')!,
|
||||||
[a, b, c].forEach(value => {
|
|
||||||
const td = document.createElement('td');
|
|
||||||
td.textContent = value;
|
|
||||||
tr.appendChild(td);
|
|
||||||
});
|
|
||||||
return tr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function orderByFirstName(obj: IDMap): { id: string, name: Name }[] {
|
|
||||||
return Object.entries(obj)
|
|
||||||
.sort(([, a], [, b]) => a.first.localeCompare(b.first))
|
|
||||||
.map(([id, { first, last }]) => ({ id, name: { first, last } }));
|
|
||||||
}
|
|
||||||
|
|
||||||
requestMappings().then(r => {
|
|
||||||
orderByFirstName(r.id_map).forEach(e => {
|
|
||||||
let row = createTableRow(e.id, e.name.last, e.name.first);
|
|
||||||
document.querySelector("#mappingTable")?.appendChild(row);
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export default app
|
||||||
|
1
web/src/vite-env.d.ts
vendored
1
web/src/vite-env.d.ts
vendored
@ -1 +1,2 @@
|
|||||||
|
/// <reference types="svelte" />
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
7
web/svelte.config.js
Normal file
7
web/svelte.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
}
|
20
web/tsconfig.app.json
Normal file
20
web/tsconfig.app.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
/**
|
||||||
|
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||||
|
* Disable checkJs if you'd like to use dynamic types in JS.
|
||||||
|
* Note that setting allowJs false does not prevent the use
|
||||||
|
* of JS in `.svelte` files.
|
||||||
|
*/
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
|
||||||
|
}
|
@ -1,24 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"files": [],
|
||||||
"target": "ES2020",
|
"references": [
|
||||||
"useDefineForClassFields": true,
|
{ "path": "./tsconfig.app.json" },
|
||||||
"module": "ESNext",
|
{ "path": "./tsconfig.node.json" }
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
]
|
||||||
"skipLibCheck": true,
|
|
||||||
|
|
||||||
/* Bundler mode */
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"moduleDetection": "force",
|
|
||||||
"noEmit": true,
|
|
||||||
|
|
||||||
/* Linting */
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"noUncheckedSideEffectImports": true
|
|
||||||
},
|
|
||||||
"include": ["src"]
|
|
||||||
}
|
}
|
||||||
|
25
web/tsconfig.node.json
Normal file
25
web/tsconfig.node.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
import { defineConfig } from "vite"
|
import { defineConfig } from "vite"
|
||||||
import tailwindcss from "@tailwindcss/vite"
|
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||||
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
tailwindcss(),
|
tailwindcss(),
|
||||||
|
svelte()
|
||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user