Convert backend/web from submodule to regular directory
This commit is contained in:
1 parent
102a316d42
commit
0010c92103
89 files changed
+6559
-1
No files matched your search
@@ -0,0 +1,7 @@
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
@@ -0,0 +1,3 @@
|
||||
export function load() {
|
||||
return { title: 'Conversation' };
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
import type { LayoutProps } from './$types';
|
||||
import { page } from '$app/state';
|
||||
import {uiState} from "$lib/state/ui.svelte"
|
||||
import { auth } from '$lib/state/auth.svelte'
|
||||
import Sidebar from "$lib/components/Sidebar.svelte"
|
||||
import { goto } from '$app/navigation'
|
||||
import { onMount } from "svelte";
|
||||
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
|
||||
|
||||
let { data, children }: LayoutProps = $props();
|
||||
|
||||
const handleMenuDesktop = () => {
|
||||
uiState.sidebarDesktopOpen = !uiState.sidebarDesktopOpen
|
||||
if (uiState.sidebarDesktopOpen) {
|
||||
setTimeout(() => { uiState.menuContentVisible = uiState.sidebarDesktopOpen }, 200)
|
||||
} else {
|
||||
uiState.menuContentVisible = uiState.sidebarDesktopOpen
|
||||
}
|
||||
}
|
||||
|
||||
const handleMenuMobile = () => {
|
||||
uiState.sidebarMobileOpen = !uiState.sidebarMobileOpen
|
||||
if (uiState.sidebarMobileOpen) {
|
||||
setTimeout(() => { uiState.menuContentVisible = uiState.sidebarMobileOpen }, 200)
|
||||
} else {
|
||||
uiState.menuContentVisible = uiState.sidebarMobileOpen
|
||||
}
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
if (window.innerWidth < 640) {
|
||||
uiState.menuContentVisible = uiState.sidebarMobileOpen
|
||||
} else {
|
||||
uiState.menuContentVisible = uiState.sidebarDesktopOpen
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
handleResize()
|
||||
if (data.me) {
|
||||
auth.user = data.me
|
||||
themeToLocalStorage(auth.user.theme)
|
||||
applyTheme()
|
||||
auth.status = 'authenticated'
|
||||
} else {
|
||||
auth.status = 'unauthenticated'
|
||||
}
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
if (auth.status == 'unauthenticated') {
|
||||
goto("/login")
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:window onresize={handleResize} />
|
||||
|
||||
<div id="outer" class={[uiState.sidebarDesktopOpen ? "desktopMenuOpen" : "desktopMenuClosed", uiState.sidebarMobileOpen ? "mobileMenuOpen" : "mobileMenuClosed" ]}>
|
||||
<div id="sidebar" class="flex flex-col">
|
||||
<Sidebar {handleMenuDesktop} {handleMenuMobile}/>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div class="flex flex-col h-screen ">
|
||||
<div class={["header", page.data.theme]}>
|
||||
<h1 class="flex">
|
||||
<span class="flex-1">{page.data.title}</span>
|
||||
{#if page.data.back}
|
||||
<span><a href={page.data.back} title="retour"><i class="icon-left-big"></i></a></span>
|
||||
{/if}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="overflow-scroll flex-1 p-2">
|
||||
{@render children()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { userApi } from "$lib/api/endpoints/user"
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
export const load: LayoutLoad = async () => {
|
||||
return {
|
||||
me: await userApi.me()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
@@ -0,0 +1,3 @@
|
||||
export function load() {
|
||||
return { title: 'Historique' };
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,3 @@
|
||||
export function load() {
|
||||
return { title: 'Base de connaissance' };
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
import type { PageProps } from './$types';
|
||||
import { type User } from '$lib/types/api'
|
||||
import { userApi } from '$lib/api/endpoints/user'
|
||||
import FormError from '$lib/components/FormError.svelte';
|
||||
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
|
||||
import { validateEmail } from '$lib/utilities/validators'
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
|
||||
let form : User = $state(data.me)
|
||||
let errors = new SvelteMap<string,string>()
|
||||
|
||||
$effect(()=>{
|
||||
themeToLocalStorage(form.theme)
|
||||
applyTheme()
|
||||
})
|
||||
|
||||
let submitUser = (e: Event) => {
|
||||
e.preventDefault()
|
||||
if (!validateEmail(form.email)) {
|
||||
errors.set("email","Adresse email invalide !")
|
||||
}
|
||||
if (!form.firstname) {
|
||||
errors.set("firstname","Le prénom est obligatoire !")
|
||||
}
|
||||
if (!form.lastname) {
|
||||
errors.set("lastname","Le nom est obligatoire !")
|
||||
}
|
||||
if (errors.size==0) {
|
||||
userApi.update(form.id, form)
|
||||
.then(()=>{ console.log('success')})
|
||||
.catch((err: string)=>{ console.error(err)})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="mb-4 formgroup">
|
||||
<h2>Mon compte</h2>
|
||||
|
||||
<form onsubmit={submitUser} onchange={()=>{errors.clear()}}>
|
||||
|
||||
<label for="email" class="block my-1 flex-1">Email</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
bind:value={form.email}
|
||||
class="textinput"
|
||||
autofocus
|
||||
/>
|
||||
<FormError key="email" errors={errors} />
|
||||
|
||||
<div class="flex">
|
||||
<div class="flex-1 mr-2">
|
||||
<label for="firstname" class="block my-1 flex-1">Prénom</label>
|
||||
<input
|
||||
id="firstname"
|
||||
type="text"
|
||||
bind:value={form.firstname}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="firstname" errors={errors} />
|
||||
</div>
|
||||
|
||||
<div class="flex-1 ml-2">
|
||||
<label for="lastname" class="block my-1 flex-1">Nom</label>
|
||||
<input
|
||||
id="lastname"
|
||||
type="text"
|
||||
bind:value={form.lastname}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="lastname" errors={errors} />
|
||||
</div>
|
||||
</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">
|
||||
<label for="lang" class="block my-1 flex-1">Langue</label>
|
||||
<select bind:value={form.lang} class="textinput">
|
||||
<option value="en">English</option>
|
||||
<option value="fr">Français</option>
|
||||
</select>
|
||||
<FormError key="lang" errors={errors} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="bt w-full">Enregistrer</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mb-4 formgroup">
|
||||
<h2>Canaux de communication</h2>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
import { userApi } from "$lib/api/endpoints/user"
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load: PageLoad = async () => {
|
||||
return {
|
||||
title: 'Profil',
|
||||
me: await userApi.me()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Modèles"
|
||||
href="/settings/models">
|
||||
Modèles
|
||||
<span class="ml-2 opacity-50 text-xs">mistral-medium-latest</span>
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Outils"
|
||||
href="/settings/tools"
|
||||
>
|
||||
Outils
|
||||
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">12</span>
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Skills"
|
||||
href="/settings/skills">
|
||||
Skills
|
||||
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">3</span>
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Canaux de communication"
|
||||
href="/settings/channels"
|
||||
>
|
||||
Canaux de communication
|
||||
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">12</span>
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Bases de connaissance"
|
||||
href="/settings/kb">
|
||||
Bases de connaissance
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Agents"
|
||||
href="/settings/agents">
|
||||
Agents
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Mémoire"
|
||||
href="/settings/memory">
|
||||
Mémoire
|
||||
<span class="ml-2 opacity-50 text-xs">standard</span>
|
||||
</a>
|
||||
|
||||
<a class="bt p-5 text-center"
|
||||
title="Utilisateurs"
|
||||
href="/settings/users">
|
||||
Utilisateurs
|
||||
<span class="ml-2 text-xs bg-red-900 text-red-300 rounded-lg p-1">1</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
export function load() {
|
||||
return { title: 'Paramétrage', theme: "settings" };
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Agents',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Canaux de communication',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Base de connaissance',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Mémoire',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Modèles',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Skills',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Outils',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<div>Modèles</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
export function load() {
|
||||
return {
|
||||
title: 'Paramétrage : Utilisateurs',
|
||||
back: "/settings",
|
||||
theme: "settings"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
Tâches
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
export function load() {
|
||||
return { title: 'Tâches' };
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<script lang="ts">
|
||||
import logo from "$lib/assets/logo-txt.png"
|
||||
import { auth, setToken } from '$lib/state/auth.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { authApi } from "$lib/api/endpoints/auth"
|
||||
|
||||
type Credentials = {
|
||||
email: string
|
||||
validemail: boolean
|
||||
password : string
|
||||
}
|
||||
|
||||
let credentials: Credentials = $state({
|
||||
email: "",
|
||||
password: "",
|
||||
validemail: false
|
||||
})
|
||||
|
||||
const formSubmitEmail = () => {
|
||||
credentials.validemail = true
|
||||
}
|
||||
|
||||
const formSubmitPass = (e: Event) => {
|
||||
e.preventDefault()
|
||||
authApi.login(credentials)
|
||||
.then((res)=>{
|
||||
auth.user = res.user
|
||||
setToken(res.accessToken)
|
||||
goto("/")
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="h-full w-full flex items-center public">
|
||||
<div class="m-auto w-96 max-w-full p-4">
|
||||
<img src={logo} class="h-10 mb-4" alt="logo"/>
|
||||
<h1>Identifiez-vous ...</h1>
|
||||
{#if !credentials.validemail}
|
||||
<form onsubmit={formSubmitEmail}>
|
||||
<div class="flex">
|
||||
<label for="email" class="block mb-2 flex-1">Email</label>
|
||||
<a href="/recover-password" class="text-xs">Mot de passe oublié ?</a>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={credentials.email}
|
||||
class="textinput mr-1"
|
||||
autofocus
|
||||
/>
|
||||
<button class="bt" title="page suivante">
|
||||
<i class="icon-right-big"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="my-4 text-xs">
|
||||
<a href="/register">Pas encore de compte ? Incrivez-vous.</a>
|
||||
</div>
|
||||
|
||||
|
||||
{:else}
|
||||
<form onsubmit={formSubmitPass}>
|
||||
<div class="flex">
|
||||
<label for="email" class="block mb-2 flex-1">Mot de passe</label>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
<input
|
||||
type="password"
|
||||
bind:value={credentials.password}
|
||||
class="textinput mr-1"
|
||||
autofocus
|
||||
/>
|
||||
<button class="bt">
|
||||
Entrer
|
||||
</button>
|
||||
</div>
|
||||
<a href="/login" class="text-xs" onclick={()=>{credentials.validemail=false}}>← Retour</a>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<div class="grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-4">
|
||||
<button class="bt p-5 text-center" title="Connexion avec Google">
|
||||
<i class="icon-google"></i>
|
||||
</button>
|
||||
<button class="bt p-5 text-center" title="Connexion avec Facebook">
|
||||
<i class="icon-facebook"></i>
|
||||
</button>
|
||||
<button class="bt p-5 text-center" title="Connexion avec Github">
|
||||
<i class="icon-github"></i>
|
||||
</button>
|
||||
<button class="bt p-5 text-center" title="Connexion avec Apple">
|
||||
<i class="icon-apple"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,120 @@
|
||||
<script lang="ts">
|
||||
import logo from "$lib/assets/logo-txt.png"
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
import { goto } from '$app/navigation';
|
||||
import { validateEmail } from '$lib/utilities/validators'
|
||||
import FormError from "$lib/components/FormError.svelte";
|
||||
import { authApi } from "$lib/api/endpoints/auth"
|
||||
|
||||
type RegisterForm = {
|
||||
email: string
|
||||
firstname: string
|
||||
lastname: string
|
||||
password : string
|
||||
verifPassword: string
|
||||
}
|
||||
|
||||
let errors = new SvelteMap<string,string>()
|
||||
|
||||
let form: RegisterForm = $state({
|
||||
email: "",
|
||||
firstname: "",
|
||||
lastname: "",
|
||||
password: "",
|
||||
verifPassword: ""
|
||||
})
|
||||
|
||||
const handleSubmit = (e: Event) => {
|
||||
e.preventDefault()
|
||||
errors.clear()
|
||||
|
||||
if (!validateEmail(form.email)) {
|
||||
errors.set("email","Adresse email invalide !")
|
||||
}
|
||||
if (form.password!==form.verifPassword) {
|
||||
errors.set("verifPassword","Les mots de pass ne correspondent pas.")
|
||||
}
|
||||
if (errors.size==0) {
|
||||
|
||||
let data = {
|
||||
method: "password",
|
||||
email: form.email,
|
||||
firstname: form.firstname,
|
||||
lastname: form.lastname,
|
||||
password: form.password
|
||||
}
|
||||
|
||||
authApi.register(data)
|
||||
.then(()=>{ goto("/") })
|
||||
.catch((reason: string)=>{ errors.set("submit","Erreur: "+reason) })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="h-full w-full flex items-center public">
|
||||
<div class="m-auto w-96 max-w-full p-4">
|
||||
<img src={logo} class="h-10 mb-4" alt="logo"/>
|
||||
<h1>Inscription</h1>
|
||||
|
||||
<form onsubmit={handleSubmit} onchange={()=>{errors.clear()}}>
|
||||
|
||||
<label for="email" class="block my-1 flex-1">Email</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
bind:value={form.email}
|
||||
class="textinput"
|
||||
autofocus
|
||||
/>
|
||||
<FormError key="email" errors={errors} />
|
||||
|
||||
|
||||
<label for="firstname" class="block my-1 flex-1">Prénom</label>
|
||||
<input
|
||||
id="firstname"
|
||||
type="text"
|
||||
bind:value={form.firstname}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="firstname" {errors} />
|
||||
|
||||
<label for="lastname" class="block my-1 flex-1">Nom</label>
|
||||
<input
|
||||
id="lastname"
|
||||
type="text"
|
||||
bind:value={form.lastname}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="lastname" {errors} />
|
||||
|
||||
<label for="password" class="block my-1 flex-1">Mot de passe</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
bind:value={form.password}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="password" {errors} />
|
||||
|
||||
<label for="verifpassword" class="block my-1 flex-1">Vérification du mot de passe</label>
|
||||
<input
|
||||
id="verifpassword"
|
||||
type="password"
|
||||
bind:value={form.verifPassword}
|
||||
class="textinput"
|
||||
/>
|
||||
<FormError key="verifPassword" {errors} />
|
||||
|
||||
<button class="bt my-2 w-full ">
|
||||
Enregistrer
|
||||
</button>
|
||||
|
||||
<FormError key="submit" {errors} />
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,2 @@
|
||||
export const ssr = false;
|
||||
export const prerender = false;
|
||||
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import './layout.css';
|
||||
import favicon from '$lib/assets/favicon.svg';
|
||||
import { applyTheme } from '$lib/ui/themeswitcher';
|
||||
import { onMount } from 'svelte';
|
||||
let { children } = $props();
|
||||
|
||||
onMount(()=>{ applyTheme() })
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Lasssistanoque</title>
|
||||
<link rel="icon" href={favicon} />
|
||||
<link rel="stylesheet" href="/assets/fontello/css/fontello.css">
|
||||
</svelte:head>
|
||||
|
||||
{@render children()}
|
||||
@@ -0,0 +1,107 @@
|
||||
@import 'tailwindcss';
|
||||
@plugin '@tailwindcss/forms';
|
||||
@plugin '@tailwindcss/typography';
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
html {
|
||||
@apply h-full;
|
||||
}
|
||||
body {
|
||||
@apply h-full bg-stone-100 text-stone-900 dark:bg-stone-900 dark:text-stone-200;
|
||||
}
|
||||
|
||||
label {
|
||||
@apply text-xs text-stone-600 uppercase dark:text-stone-400;
|
||||
}
|
||||
hr {
|
||||
@apply border-stone-200 dark:border-stone-800;
|
||||
}
|
||||
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;
|
||||
}
|
||||
.bt {
|
||||
@apply cursor-pointer rounded bg-stone-200 px-4 py-2 hover:bg-stone-300 dark:bg-stone-800 dark:hover:bg-stone-700;
|
||||
}
|
||||
.menuitem {
|
||||
@apply text-stone-800 text-stone-950 dark:text-stone-300 hover:dark:text-stone-50;
|
||||
}
|
||||
|
||||
.header {
|
||||
@apply p-2 text-lg;
|
||||
|
||||
h1 {
|
||||
@apply rounded bg-stone-200 px-2 font-bold text-sky-600 dark:bg-stone-800 dark:text-sky-200;
|
||||
}
|
||||
|
||||
&.settings {
|
||||
h1 {
|
||||
@apply rounded border-none bg-sky-200 px-2 text-sky-700 dark:bg-sky-950 dark:text-sky-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.public h1 {
|
||||
@apply mb-4 text-3xl font-bold;
|
||||
}
|
||||
.profile a,
|
||||
.public a {
|
||||
@apply text-sky-500;
|
||||
}
|
||||
|
||||
.formgroup {
|
||||
@apply rounded border border-stone-300 bg-stone-100 p-2 dark:border-stone-700 dark:bg-stone-900;
|
||||
}
|
||||
|
||||
#outer {
|
||||
@apply flex h-full flex-row;
|
||||
}
|
||||
#main {
|
||||
@apply flex w-full flex-col;
|
||||
}
|
||||
#sidebar {
|
||||
@apply min-w-64 border-r border-r-stone-200 transition-all duration-300 dark:border-stone-800;
|
||||
}
|
||||
|
||||
#content {
|
||||
@apply p-2;
|
||||
}
|
||||
#hamburgerDesktop,
|
||||
#hamburgerMobile {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
@media (width >= 640px) {
|
||||
#hamburgerDesktop {
|
||||
@apply inline;
|
||||
}
|
||||
.desktopMenuClosed {
|
||||
#sidebar {
|
||||
@apply w-10 min-w-10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 640px) {
|
||||
#hamburgerMobile {
|
||||
@apply inline;
|
||||
}
|
||||
#main {
|
||||
@apply ml-10;
|
||||
}
|
||||
#sidebar {
|
||||
@apply fixed left-0 h-full w-full bg-stone-100 dark:bg-stone-900;
|
||||
}
|
||||
.mobileMenuClosed {
|
||||
#sidebar {
|
||||
@apply fixed w-10 min-w-10;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user