choix de la timezone dans un select

This commit is contained in:
fabien committed 2026-08-23 13:33:40 +02:00
1 parent 21e96702a0
commit 357bf9b41c
13 files changed
+848 -42

No files matched your search

+53 -25
View File
@@ -8,7 +8,8 @@
"name": "web",
"version": "0.0.1",
"dependencies": {
"oidc-client-ts": "^3.5.0"
"oidc-client-ts": "^3.5.0",
"svelte-select": "^6.0.0"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
@@ -198,6 +199,31 @@
"node": "^20.19.0 || ^22.13.0 || >=24"
}
},
"node_modules/@floating-ui/core": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz",
"integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.12"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz",
"integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.8.0",
"@floating-ui/utils": "^0.2.12"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz",
"integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",
"license": "MIT"
},
"node_modules/@humanfs/core": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
@@ -268,7 +294,6 @@
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -279,7 +304,6 @@
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -290,7 +314,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -300,14 +323,12 @@
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -822,7 +843,6 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.11.tgz",
"integrity": "sha512-LFuZUkjJ9iF7JZye/aG5XM0SFcQ5VyL0oVX4WJ9dc0Va3R3s0OauX1BESVCb+YN/ol8TAfqGDDAQsTG627Y5kw==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
@@ -1259,7 +1279,6 @@
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json-schema": {
@@ -1283,7 +1302,6 @@
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/ws": {
@@ -1446,7 +1464,7 @@
"version": "8.65.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz",
"integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1530,7 +1548,6 @@
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
"integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -1570,7 +1587,6 @@
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
"integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -1580,7 +1596,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -1613,7 +1628,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -1706,7 +1720,6 @@
"version": "5.9.0",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.0.tgz",
"integrity": "sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==",
"dev": true,
"license": "MIT"
},
"node_modules/enhanced-resolve": {
@@ -1894,7 +1907,6 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"dev": true,
"license": "MIT"
},
"node_modules/espree": {
@@ -1932,7 +1944,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.3.0.tgz",
"integrity": "sha512-GQ/7RN8uOtEfNpzZzBMTzW9JBcX42oaSVtPzdF+6cEL8pqIL094iUpr9jzYGn4O4P/1S60dJ6izyT8F4LYARng==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -2164,7 +2175,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.6"
@@ -2595,7 +2605,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"dev": true,
"license": "MIT"
},
"node_modules/locate-path": {
@@ -2618,7 +2627,6 @@
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
@@ -2678,9 +2686,9 @@
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.16",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
"version": "3.3.18",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
"integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
"dev": true,
"funding": [
{
@@ -3211,7 +3219,6 @@
"version": "5.56.8",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.8.tgz",
"integrity": "sha512-PY8LOw7xP6c8IOiVqdo0sbbZVYhXRSfklOQLAUyGBKqjTX0wx/z4l/9J+PmBpmlLnxzEb1NqltxQ5/wZme/Cmg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -3383,6 +3390,28 @@
"node": ">=4"
}
},
"node_modules/svelte-floating-ui": {
"version": "1.5.8",
"resolved": "https://registry.npmjs.org/svelte-floating-ui/-/svelte-floating-ui-1.5.8.tgz",
"integrity": "sha512-dVvJhZ2bT+kQDHlE4Lep8t+sgEc0XD96fXLzAi2DDI2bsaegBbClxXVNMma0C2WsG+n9GJSYx292dTvA8CYRtw==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.5.0",
"@floating-ui/dom": "^1.5.3"
}
},
"node_modules/svelte-select": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/svelte-select/-/svelte-select-6.0.0.tgz",
"integrity": "sha512-WJ1UDw0a1Z3I7oVFgaCS7G9D2rCSmYAPpufNEj/DNuk5Oyb2a5dju6F36o0urBVw9bTE3WkM9cZkI0x+Sfo8Bg==",
"license": "ISC",
"dependencies": {
"svelte-floating-ui": "1.5.8"
},
"peerDependencies": {
"svelte": ">=5"
}
},
"node_modules/tailwindcss": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
@@ -3973,7 +4002,6 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
"dev": true,
"license": "MIT"
}
}
+2 -1
View File
@@ -48,6 +48,7 @@
"esbuild": "^0.25.0"
},
"dependencies": {
"oidc-client-ts": "^3.5.0"
"oidc-client-ts": "^3.5.0",
"svelte-select": "^6.0.0"
}
}
@@ -0,0 +1,5 @@
import { api } from '../client';
export const miscApi = {
listTimezones: () => api.get<string[]>(`/misc/timezones`),
};
+1
View File
@@ -5,6 +5,7 @@ export interface User {
email: string
theme: string
lang: string
timezone: string
_version: string
}
@@ -4,20 +4,24 @@
import type { PageProps } from './$types';
import type { User, Address } from '$lib/types/api'
import { userApi } from '$lib/api/endpoints/user'
import { miscApi } from '$lib/api/endpoints/misc'
import FormError from '$lib/components/FormError.svelte';
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
import { validateEmail } from '$lib/utilities/validators'
import { onMount } from 'svelte';
import { onMount } from 'svelte';
import Select from 'svelte-select/no-styles';
let { data }: PageProps = $props();
let form : User = $state(data.me)
let addresses : Address[] = $state([] as Address[])
let newAddress : Address = $state({} as Address)
let timezones = $state([] as string[])
let errors = new SvelteMap<string,string>()
onMount(async ()=> {
addresses = await userApi.listAddresses(form.id)
timezones = await miscApi.listTimezones()
})
$effect(()=>{
@@ -100,17 +104,8 @@
</div>
<div class="flex">
<div class="flex-1 mr-2">
<label for="theme" class="block my-1 flex-1">Thème</label>
<select bind:value={form.theme} class="textinput">
<option value="auto">Automatic</option>
<option value="dark">Sombre</option>
<option value="light">Clair</option>
</select>
<FormError key="theme" errors={errors} />
</div>
<div class="flex-1 ml-2">
<div class="flex-1 mr-2">
<label for="lang" class="block my-1 flex-1">Langue</label>
<select bind:value={form.lang} class="textinput">
<option value="en">English</option>
@@ -118,6 +113,22 @@
</select>
<FormError key="lang" errors={errors} />
</div>
<div class="flex-1 ml-2">
<label for="lang" class="block my-1 flex-1">Timezone</label>
<Select items={timezones} bind:value={form.timezone}/>
<FormError key="lang" errors={errors} />
</div>
</div>
<div class="flex-1 mr-2">
<label for="theme" class="block my-1 flex-1">Thème</label>
<select bind:value={form.theme} class="textinput">
<option value="auto">Automatique</option>
<option value="dark">Sombre</option>
<option value="light">Clair</option>
</select>
<FormError key="theme" errors={errors} />
</div>
<button class="bt w-full">Enregistrer</button>
@@ -131,7 +142,7 @@
{#each addresses as address (address.id) }
<div class="m-2">
<div class="dark:bg-stone-600 bg-stone-300 rounded flex inline px-2 py-1">
<div class="dark:bg-stone-700 bg-stone-300 rounded flex inline px-2 py-1">
<span class="inline-block w-20">{address.type} : </span>
<span class="font-bold">{address.address}</span>
<button class="ml-4 pointer" onclick={()=>{handleDeleteAddress(address.id)}}>
+135 -3
View File
@@ -21,9 +21,6 @@ h2 {
@apply mb-4 font-bold;
}
.textinput {
@apply w-full rounded bg-white p-1 text-stone-900 dark:bg-stone-700 dark:text-stone-100;
}
.pointer {
@apply cursor-pointer;
}
@@ -105,3 +102,138 @@ h2 {
}
}
}
/* svelte select */
.textinput {
@apply h-8 w-full rounded border-stone-700 bg-white px-2 py-1 text-stone-900 dark:bg-stone-800 dark:text-stone-100;
}
.svelte-select {
@apply relative flex h-8 w-full border-none text-stone-900 dark:bg-stone-800 dark:text-stone-100;
}
.svelte-select .value-container {
@apply relative flex-1;
}
.svelte-select input {
@apply absolute top-0 left-0 m-0 h-8 w-full cursor-default rounded border-stone-700 bg-transparent px-2 py-0 text-sm leading-10 text-stone-100;
}
.svelte-select.focused {
/* @apply border-blue-600; */
}
.svelte-select.disabled {
@apply border-gray-200 bg-gray-200 text-gray-600;
}
.svelte-select.disabled input {
@apply placeholder:text-gray-400 placeholder:opacity-100;
}
.svelte-select > .value-container > .selected-item {
@apply h-8 overflow-x-hidden px-4 leading-8 focus:outline-none;
}
.svelte-select .hide-selected-item {
@apply hidden;
}
.svelte-select .indicators {
@apply pointer-events-none absolute top-0 right-0 bottom-0 flex h-8 translate-y-0 items-center text-gray-200;
}
.svelte-select .icons > * {
@apply transition-colors duration-200 ease-in-out focus:outline-none;
}
.svelte-select .clear-select {
@apply pointer-events-auto;
}
.svelte-select.focused .icons,
.svelte-select .chevron:hover,
.svelte-select .clear-select:hover {
@apply text-gray-600;
}
.svelte-select .clear-select {
@apply h-5 w-9 flex-none px-2 text-gray-300;
}
.svelte-select .chevron {
@apply flex h-5 w-9 border-l-2 pt-0 pr-2 pl-2 text-gray-300;
}
.svelte-select.multi {
@apply h-auto flex-wrap items-stretch pr-9 pl-4;
}
.svelte-select.multi input {
@apply relative m-0 p-0;
}
.svelte-select.error {
@apply border-red-500 bg-white;
}
.a11y-text {
@apply sr-only;
}
.svelte-select-list {
@apply absolute right-0 left-0 z-10 max-h-64 w-full overflow-y-auto rounded-sm border-none bg-stone-50 px-4 shadow-md dark:bg-stone-800;
}
.svelte-select-list .list-group-title {
@apply h-8 cursor-default px-5 text-sm leading-10 font-medium overflow-ellipsis whitespace-nowrap text-gray-400 uppercase;
}
.svelte-select-list .empty {
@apply py-5 text-center text-gray-500;
}
.svelte-select-item {
@apply h-8 cursor-default overflow-hidden px-5 leading-10 overflow-ellipsis whitespace-nowrap text-gray-800;
}
.item.group-item {
@apply px-10;
}
.item.active {
@apply bg-blue-600 text-white dark:bg-blue-900;
}
.item.not-selectable {
@apply text-gray-300;
}
.item.first {
@apply rounded-t-sm;
}
.item.hover:not(.active) {
@apply bg-blue-100 dark:bg-stone-700;
}
.multi input {
flex: 1 1 40px;
}
.multi-item {
@apply mt-1 mr-1 flex h-8 max-w-full cursor-default items-center overflow-hidden rounded-sm border border-gray-200 bg-gray-100 pr-1 pl-1 leading-8 overflow-ellipsis whitespace-nowrap;
}
.multi-item.disabled {
@apply hover:bg-gray-300 hover:text-gray-500;
}
.multi-item-clear {
@apply flex w-5 items-center justify-center;
}
.list-item {
@apply list-none;
}