From 0aa0aebbad5a433721551c679b885b8e30397677 Mon Sep 17 00:00:00 2001 From: Florian Briand Date: Tue, 24 Sep 2024 17:39:57 +0200 Subject: [PATCH] chore: Remove app crate --- crates/app/.gitignore | 4 - crates/app/Cargo.toml | 33 - crates/app/README.md | 44 - crates/app/askama.toml | 6 - crates/app/assets/css/style.css | 1345 ----------------- crates/app/assets/js/alpinejs@3.14.1.min.js | 5 - crates/app/assets/js/flowbite@2.5.1.min.js | 2 - crates/app/assets/js/htmx@2.0.1.min.js | 1 - crates/app/css/input.css | 3 - crates/app/src/components/base.html | 23 - .../app/src/components/navbar/menu-item.html | 18 - crates/app/src/components/navbar/navbar.html | 50 - crates/app/src/components/skeletons/card.html | 22 - .../src/components/skeletons/menu-items.html | 4 - .../src/components/skeletons/page-title.html | 1 - crates/app/src/lib.rs | 47 - crates/app/src/main.rs | 90 -- crates/app/src/menu.rs | 28 - crates/app/src/pages/cps.html | 43 - crates/app/src/pages/cps.rs | 12 - crates/app/src/pages/debug.html | 72 - crates/app/src/pages/debug.rs | 48 - crates/app/src/pages/home.html | 43 - crates/app/src/pages/home.rs | 12 - crates/app/src/pages/mod.rs | 14 - crates/app/tailwind.config.js | 12 - 26 files changed, 1982 deletions(-) delete mode 100644 crates/app/.gitignore delete mode 100644 crates/app/Cargo.toml delete mode 100644 crates/app/README.md delete mode 100644 crates/app/askama.toml delete mode 100644 crates/app/assets/css/style.css delete mode 100644 crates/app/assets/js/alpinejs@3.14.1.min.js delete mode 100644 crates/app/assets/js/flowbite@2.5.1.min.js delete mode 100644 crates/app/assets/js/htmx@2.0.1.min.js delete mode 100644 crates/app/css/input.css delete mode 100644 crates/app/src/components/base.html delete mode 100644 crates/app/src/components/navbar/menu-item.html delete mode 100644 crates/app/src/components/navbar/navbar.html delete mode 100644 crates/app/src/components/skeletons/card.html delete mode 100644 crates/app/src/components/skeletons/menu-items.html delete mode 100644 crates/app/src/components/skeletons/page-title.html delete mode 100644 crates/app/src/lib.rs delete mode 100644 crates/app/src/main.rs delete mode 100644 crates/app/src/menu.rs delete mode 100644 crates/app/src/pages/cps.html delete mode 100644 crates/app/src/pages/cps.rs delete mode 100644 crates/app/src/pages/debug.html delete mode 100644 crates/app/src/pages/debug.rs delete mode 100644 crates/app/src/pages/home.html delete mode 100644 crates/app/src/pages/home.rs delete mode 100644 crates/app/src/pages/mod.rs delete mode 100644 crates/app/tailwind.config.js diff --git a/crates/app/.gitignore b/crates/app/.gitignore deleted file mode 100644 index 60f12af..0000000 --- a/crates/app/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target - -# Tailwind CSS CLI -tailwindcss \ No newline at end of file diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml deleted file mode 100644 index c864b62..0000000 --- a/crates/app/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "app" -version = "0.1.0" -edition = "2021" - -[dependencies] -askama = "0.12.1" -askama_axum = "0.4.0" -axum.workspace = true -axum-htmx = { version = "0.6", features = ["auto-vary"] } -futures = "0.3.30" -listenfd = "1.0.1" -notify = "6.1.1" -sea-orm = { workspace = true, features = [ - # Same `ASYNC_RUNTIME` and `DATABASE_DRIVER` as in the migration crate - "sqlx-sqlite", - "runtime-tokio-rustls", - "macros", -] } -serde = { version = "1.0.204", features = ["derive"] } -thiserror.workspace = true -tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } -tower-http = { version = "0.5.2", features = ["fs"] } -tower-livereload = "0.9.3" - -entity = { path = "../../entity" } -migration = { path = "../../migration" } -utils = { path = "../utils" } - -[dev-dependencies] -cargo-watch = "8.5.1" -systemfd = "0.4.0" -sea-orm-cli.workspace = true diff --git a/crates/app/README.md b/crates/app/README.md deleted file mode 100644 index 3c5cf9b..0000000 --- a/crates/app/README.md +++ /dev/null @@ -1,44 +0,0 @@ -## Pré-requis - -- Récupérer le binaire TailwindCSS : https://tailwindcss.com/blog/standalone-cli - -## Configuration - -> Astuce : lorsqu'on exécute directement la crate `App` à des fins de développement, le système de configuration n'utilisera pas l'éventuel fichier `.env` situé à la racine du workspace Rust. Pour éviter de dupliquer le fichier `.env`, il est possible de créer un lien symbolique vers le fichier `.env` de la crate `App` : - -```bash -cd crates/app -ln -s ../../.env .env -``` - -## Exécution - -- Lancer tailwindcss en mode watch dans un terminal : -```bash -./tailwindcss -i css/input.css -o assets/css/style.css --watch -``` - -- Lancer le serveur web dans un autre terminal : -```bash -cargo run --bin app -``` - -## Rechargement automatique (_auto-reload_) - -Pour le projet `app`, nous utilisons en plus de `cargo-watch` ses librairies : -- [`systemfd`](https://github.com/mitsuhiko/systemfd) permet de redémarrer un serveur sans interrompre les connexions en cours, il transmet le descripteur de fichier du socket à une nouvelle instance du serveur (exemple: `cargo watch -x run` --> `systemfd --no-pid -s http::3000 -- cargo watch -x run`). Si le port est déjà pris il en prendra un autre. -- [`listenfd`](https://github.com/mitsuhiko/listenfd) permet, côté _Rust_, de démarrer un serveur en utilisant des connexions déjà ouvertes. - -Pour notre application voici la commande à lancer : - -```bash -systemfd --no-pid -s http::3000 -- cargo watch -x 'run --bin app' -``` - -## Chargement à chaud (_livereload_) - -Pour que notre navigateur rafraîchisse automatique notre page lorsque le serveur a été recompilé, nous utilisons la librairie [`tower-livereload`](https://github.com/leotaku/tower-livereload). - -A chaque changement, que ça soit sur du code en _Rust_, _HTML_, _CSS_ ou _JS_ alors le navigateur va recharger entièrement la page. - -En Rust, il n'existe pas encore d'outil de _Hot Reload_ complet et intégré comme on en trouve dans d'autres environnements de développement web, comme pour _Node.js_. diff --git a/crates/app/askama.toml b/crates/app/askama.toml deleted file mode 100644 index e00fe7b..0000000 --- a/crates/app/askama.toml +++ /dev/null @@ -1,6 +0,0 @@ -[general] -# Directories to search for templates, relative to the crate root. -dirs = [ - "src/pages", - "src/components", -] diff --git a/crates/app/assets/css/style.css b/crates/app/assets/css/style.css deleted file mode 100644 index e2769fc..0000000 --- a/crates/app/assets/css/style.css +++ /dev/null @@ -1,1345 +0,0 @@ -/* -! tailwindcss v3.4.7 | MIT License | https://tailwindcss.com -*/ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::after { - --tw-content: ''; -} - -/* -1. Use a consistent sensible line-height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -3. Use a more readable tab size. -4. Use the user's configured `sans` font-family by default. -5. Use the user's configured `sans` font-feature-settings by default. -6. Use the user's configured `sans` font-variation-settings by default. -7. Disable tap highlights on iOS -*/ - -html, -:host { - line-height: 1.5; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -moz-tab-size: 4; - /* 3 */ - -o-tab-size: 4; - tab-size: 4; - /* 3 */ - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - /* 4 */ - font-feature-settings: normal; - /* 5 */ - font-variation-settings: normal; - /* 6 */ - -webkit-tap-highlight-color: transparent; - /* 7 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -1. Add the correct height in Firefox. -2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) -3. Ensure horizontal rules are visible by default. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font-family by default. -2. Use the user's configured `mono` font-feature-settings by default. -3. Use the user's configured `mono` font-variation-settings by default. -4. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-feature-settings: normal; - /* 2 */ - font-variation-settings: normal; - /* 3 */ - font-size: 1em; - /* 4 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* -1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) -3. Remove gaps between table borders by default. -*/ - -table { - text-indent: 0; - /* 1 */ - border-color: inherit; - /* 2 */ - border-collapse: collapse; - /* 3 */ -} - -/* -1. Change the font styles in all browsers. -2. Remove the margin in Firefox and Safari. -3. Remove default padding in all browsers. -*/ - -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-feature-settings: inherit; - /* 1 */ - font-variation-settings: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - font-weight: inherit; - /* 1 */ - line-height: inherit; - /* 1 */ - letter-spacing: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -input:where([type='button']), -input:where([type='reset']), -input:where([type='submit']) { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-moz-focusring { - outline: auto; -} - -/* -Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Change font properties to `inherit` in Safari. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Reset default styling for dialogs. -*/ - -dialog { - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -textarea { - resize: vertical; -} - -/* -1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) -2. Set the default placeholder color to the user's configured gray 400 color. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -:disabled { - cursor: default; -} - -/* -1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) -2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) - This can trigger a poorly considered lint error in some tools but is included by design. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - /* 1 */ - vertical-align: middle; - /* 2 */ -} - -/* -Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden] { - display: none; -} - -*, ::before, ::after { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - -::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; -} - -.z-50 { - z-index: 50; -} - -.mx-auto { - margin-left: auto; - margin-right: auto; -} - -.my-4 { - margin-top: 1rem; - margin-bottom: 1rem; -} - -.mb-1 { - margin-bottom: 0.25rem; -} - -.mb-2 { - margin-bottom: 0.5rem; -} - -.mb-2\.5 { - margin-bottom: 0.625rem; -} - -.mb-4 { - margin-bottom: 1rem; -} - -.me-3 { - margin-inline-end: 0.75rem; -} - -.mt-3 { - margin-top: 0.75rem; -} - -.mt-4 { - margin-top: 1rem; -} - -.mb-5 { - margin-bottom: 1.25rem; -} - -.block { - display: block; -} - -.flex { - display: flex; -} - -.inline-flex { - display: inline-flex; -} - -.table { - display: table; -} - -.grid { - display: grid; -} - -.hidden { - display: none; -} - -.h-10 { - height: 2.5rem; -} - -.h-2 { - height: 0.5rem; -} - -.h-2\.5 { - height: 0.625rem; -} - -.h-32 { - height: 8rem; -} - -.h-4 { - height: 1rem; -} - -.h-48 { - height: 12rem; -} - -.h-5 { - height: 1.25rem; -} - -.h-7 { - height: 1.75rem; -} - -.h-8 { - height: 2rem; -} - -.h-96 { - height: 24rem; -} - -.h-full { - height: 100%; -} - -.min-h-full { - min-height: 100%; -} - -.w-10 { - width: 2.5rem; -} - -.w-32 { - width: 8rem; -} - -.w-48 { - width: 12rem; -} - -.w-5 { - width: 1.25rem; -} - -.w-8 { - width: 2rem; -} - -.w-full { - width: 100%; -} - -.max-w-3xl { - max-width: 48rem; -} - -.max-w-7xl { - max-width: 80rem; -} - -.max-w-screen-xl { - max-width: 1280px; -} - -.max-w-sm { - max-width: 24rem; -} - -@keyframes pulse { - 50% { - opacity: .5; - } -} - -.animate-pulse { - animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; -} - -.list-none { - list-style-type: none; -} - -.grid-cols-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); -} - -.flex-col { - flex-direction: column; -} - -.flex-wrap { - flex-wrap: wrap; -} - -.items-center { - align-items: center; -} - -.justify-center { - justify-content: center; -} - -.justify-between { - justify-content: space-between; -} - -.gap-4 { - gap: 1rem; -} - -.space-x-3 > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 0; - margin-right: calc(0.75rem * var(--tw-space-x-reverse)); - margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); -} - -.divide-y > :not([hidden]) ~ :not([hidden]) { - --tw-divide-y-reverse: 0; - border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); - border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); -} - -.divide-gray-100 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(243 244 246 / var(--tw-divide-opacity)); -} - -.self-center { - align-self: center; -} - -.truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.whitespace-nowrap { - white-space: nowrap; -} - -.rounded { - border-radius: 0.25rem; -} - -.rounded-full { - border-radius: 9999px; -} - -.rounded-lg { - border-radius: 0.5rem; -} - -.border { - border-width: 1px; -} - -.border-2 { - border-width: 2px; -} - -.border-b { - border-bottom-width: 1px; -} - -.border-dashed { - border-style: dashed; -} - -.border-gray-100 { - --tw-border-opacity: 1; - border-color: rgb(243 244 246 / var(--tw-border-opacity)); -} - -.border-gray-200 { - --tw-border-opacity: 1; - border-color: rgb(229 231 235 / var(--tw-border-opacity)); -} - -.border-gray-300 { - --tw-border-opacity: 1; - border-color: rgb(209 213 219 / var(--tw-border-opacity)); -} - -.bg-blue-700 { - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity)); -} - -.bg-gray-200 { - --tw-bg-opacity: 1; - background-color: rgb(229 231 235 / var(--tw-bg-opacity)); -} - -.bg-gray-300 { - --tw-bg-opacity: 1; - background-color: rgb(209 213 219 / var(--tw-bg-opacity)); -} - -.bg-gray-50 { - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity)); -} - -.bg-gray-800 { - --tw-bg-opacity: 1; - background-color: rgb(31 41 55 / var(--tw-bg-opacity)); -} - -.bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.bg-blue-600 { - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); -} - -.p-2 { - padding: 0.5rem; -} - -.p-4 { - padding: 1rem; -} - -.p-6 { - padding: 1.5rem; -} - -.px-3 { - padding-left: 0.75rem; - padding-right: 0.75rem; -} - -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - -.px-5 { - padding-left: 1.25rem; - padding-right: 1.25rem; -} - -.px-6 { - padding-left: 1.5rem; - padding-right: 1.5rem; -} - -.py-10 { - padding-top: 2.5rem; - padding-bottom: 2.5rem; -} - -.py-12 { - padding-top: 3rem; - padding-bottom: 3rem; -} - -.py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.py-2\.5 { - padding-top: 0.625rem; - padding-bottom: 0.625rem; -} - -.py-3 { - padding-top: 0.75rem; - padding-bottom: 0.75rem; -} - -.py-4 { - padding-top: 1rem; - padding-bottom: 1rem; -} - -.py-8 { - padding-top: 2rem; - padding-bottom: 2rem; -} - -.text-left { - text-align: left; -} - -.text-center { - text-align: center; -} - -.text-2xl { - font-size: 1.5rem; - line-height: 2rem; -} - -.text-3xl { - font-size: 1.875rem; - line-height: 2.25rem; -} - -.text-base { - font-size: 1rem; - line-height: 1.5rem; -} - -.text-sm { - font-size: 0.875rem; - line-height: 1.25rem; -} - -.text-xl { - font-size: 1.25rem; - line-height: 1.75rem; -} - -.text-xs { - font-size: 0.75rem; - line-height: 1rem; -} - -.font-bold { - font-weight: 700; -} - -.font-light { - font-weight: 300; -} - -.font-medium { - font-weight: 500; -} - -.font-semibold { - font-weight: 600; -} - -.uppercase { - text-transform: uppercase; -} - -.leading-tight { - line-height: 1.25; -} - -.tracking-tight { - letter-spacing: -0.025em; -} - -.text-gray-200 { - --tw-text-opacity: 1; - color: rgb(229 231 235 / var(--tw-text-opacity)); -} - -.text-gray-500 { - --tw-text-opacity: 1; - color: rgb(107 114 128 / var(--tw-text-opacity)); -} - -.text-gray-700 { - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); -} - -.text-gray-900 { - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.shadow { - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.hover\:bg-gray-100:hover { - --tw-bg-opacity: 1; - background-color: rgb(243 244 246 / var(--tw-bg-opacity)); -} - -.hover\:bg-blue-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity)); -} - -.focus\:outline-none:focus { - outline: 2px solid transparent; - outline-offset: 2px; -} - -.focus\:ring-2:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-4:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-gray-200:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(229 231 235 / var(--tw-ring-opacity)); -} - -.focus\:ring-gray-300:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity)); -} - -.focus\:ring-blue-300:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(147 197 253 / var(--tw-ring-opacity)); -} - -@media (min-width: 640px) { - .sm\:max-w-md { - max-width: 28rem; - } - - .sm\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .sm\:p-8 { - padding: 2rem; - } - - .sm\:px-6 { - padding-left: 1.5rem; - padding-right: 1.5rem; - } -} - -@media (min-width: 768px) { - .md\:order-1 { - order: 1; - } - - .md\:order-2 { - order: 2; - } - - .md\:me-0 { - margin-inline-end: 0px; - } - - .md\:mt-0 { - margin-top: 0px; - } - - .md\:flex { - display: flex; - } - - .md\:hidden { - display: none; - } - - .md\:h-64 { - height: 16rem; - } - - .md\:w-auto { - width: auto; - } - - .md\:flex-row { - flex-direction: row; - } - - .md\:space-x-0 > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 0; - margin-right: calc(0px * var(--tw-space-x-reverse)); - margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse))); - } - - .md\:space-x-8 > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 0; - margin-right: calc(2rem * var(--tw-space-x-reverse)); - margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse))); - } - - .md\:space-y-5 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1.25rem * var(--tw-space-y-reverse)); - } - - .md\:border-0 { - border-width: 0px; - } - - .md\:bg-transparent { - background-color: transparent; - } - - .md\:bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - } - - .md\:p-0 { - padding: 0px; - } - - .md\:p-6 { - padding: 1.5rem; - } - - .md\:text-2xl { - font-size: 1.5rem; - line-height: 2rem; - } - - .md\:text-blue-700 { - --tw-text-opacity: 1; - color: rgb(29 78 216 / var(--tw-text-opacity)); - } - - .md\:hover\:bg-transparent:hover { - background-color: transparent; - } - - .md\:hover\:text-blue-700:hover { - --tw-text-opacity: 1; - color: rgb(29 78 216 / var(--tw-text-opacity)); - } -} - -@media (min-width: 1024px) { - .lg\:mt-5 { - margin-top: 1.25rem; - } - - .lg\:grid-cols-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .lg\:px-8 { - padding-left: 2rem; - padding-right: 2rem; - } -} - -.rtl\:space-x-reverse:where([dir="rtl"], [dir="rtl"] *) > :not([hidden]) ~ :not([hidden]) { - --tw-space-x-reverse: 1; -} - -.rtl\:text-right:where([dir="rtl"], [dir="rtl"] *) { - text-align: right; -} - -@media (prefers-color-scheme: dark) { - .dark\:divide-gray-600 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(75 85 99 / var(--tw-divide-opacity)); - } - - .dark\:border { - border-width: 1px; - } - - .dark\:border-gray-600 { - --tw-border-opacity: 1; - border-color: rgb(75 85 99 / var(--tw-border-opacity)); - } - - .dark\:border-gray-700 { - --tw-border-opacity: 1; - border-color: rgb(55 65 81 / var(--tw-border-opacity)); - } - - .dark\:bg-gray-700 { - --tw-bg-opacity: 1; - background-color: rgb(55 65 81 / var(--tw-bg-opacity)); - } - - .dark\:bg-gray-800 { - --tw-bg-opacity: 1; - background-color: rgb(31 41 55 / var(--tw-bg-opacity)); - } - - .dark\:bg-gray-900 { - --tw-bg-opacity: 1; - background-color: rgb(17 24 39 / var(--tw-bg-opacity)); - } - - .dark\:bg-blue-600 { - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); - } - - .dark\:text-gray-200 { - --tw-text-opacity: 1; - color: rgb(229 231 235 / var(--tw-text-opacity)); - } - - .dark\:text-gray-400 { - --tw-text-opacity: 1; - color: rgb(156 163 175 / var(--tw-text-opacity)); - } - - .dark\:text-gray-600 { - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity)); - } - - .dark\:text-gray-700 { - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); - } - - .dark\:text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - } - - .dark\:hover\:bg-gray-600:hover { - --tw-bg-opacity: 1; - background-color: rgb(75 85 99 / var(--tw-bg-opacity)); - } - - .dark\:hover\:bg-gray-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(55 65 81 / var(--tw-bg-opacity)); - } - - .dark\:hover\:bg-blue-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity)); - } - - .dark\:hover\:text-white:hover { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - } - - .dark\:focus\:ring-gray-600:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity)); - } - - .dark\:focus\:ring-blue-800:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(30 64 175 / var(--tw-ring-opacity)); - } -} - -@media (min-width: 768px) { - @media (prefers-color-scheme: dark) { - .md\:dark\:bg-gray-900 { - --tw-bg-opacity: 1; - background-color: rgb(17 24 39 / var(--tw-bg-opacity)); - } - - .md\:dark\:text-blue-500 { - --tw-text-opacity: 1; - color: rgb(59 130 246 / var(--tw-text-opacity)); - } - - .md\:dark\:hover\:bg-transparent:hover { - background-color: transparent; - } - - .md\:dark\:hover\:text-blue-500:hover { - --tw-text-opacity: 1; - color: rgb(59 130 246 / var(--tw-text-opacity)); - } - } -} diff --git a/crates/app/assets/js/alpinejs@3.14.1.min.js b/crates/app/assets/js/alpinejs@3.14.1.min.js deleted file mode 100644 index 2ca4827..0000000 --- a/crates/app/assets/js/alpinejs@3.14.1.min.js +++ /dev/null @@ -1,5 +0,0 @@ -(()=>{var rt=!1,nt=!1,U=[],it=-1;function qt(e){Cn(e)}function Cn(e){U.includes(e)||U.push(e),Tn()}function Ee(e){let t=U.indexOf(e);t!==-1&&t>it&&U.splice(t,1)}function Tn(){!nt&&!rt&&(rt=!0,queueMicrotask(Rn))}function Rn(){rt=!1,nt=!0;for(let e=0;ee.effect(t,{scheduler:r=>{ot?qt(r):r()}}),st=e.raw}function at(e){D=e}function Gt(e){let t=()=>{};return[n=>{let i=D(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),L(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=D(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>L(i)}var Jt=[],Yt=[],Xt=[];function Zt(e){Xt.push(e)}function ee(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Yt.push(t))}function Ae(e){Jt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function ct(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function Qt(e){if(e._x_cleanups)for(;e._x_cleanups.length;)e._x_cleanups.pop()()}var lt=new MutationObserver(pt),ut=!1;function le(){lt.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ut=!0}function ft(){Mn(),lt.disconnect(),ut=!1}var ce=[];function Mn(){let e=lt.takeRecords();ce.push(()=>e.length>0&&pt(e));let t=ce.length;queueMicrotask(()=>{if(ce.length===t)for(;ce.length>0;)ce.shift()()})}function _(e){if(!ut)return e();ft();let t=e();return le(),t}var dt=!1,Se=[];function er(){dt=!0}function tr(){dt=!1,pt(Se),Se=[]}function pt(e){if(dt){Se=Se.concat(e);return}let t=new Set,r=new Set,n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.add(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.add(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{ct(s,o)}),n.forEach((o,s)=>{Jt.forEach(a=>a(s,o))});for(let o of r)t.has(o)||Yt.forEach(s=>s(o));t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.has(o)||o.isConnected&&(delete o._x_ignoreSelf,delete o._x_ignore,Xt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function Ce(e){return F(j(e))}function P(e,t,r){return e._x_dataStack=[t,...j(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function j(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?j(e.host):e.parentNode?j(e.parentNode):[]}function F(e){return new Proxy({objects:e},Nn)}var Nn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Dn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Dn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Pn(n,i),s=>mt(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Pn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function mt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),mt(e[t[0]],t.slice(1),r)}}var rr={};function y(e,t){rr[e]=t}function ue(e,t){return Object.entries(rr).forEach(([r,n])=>{let i=null;function o(){if(i)return i;{let[s,a]=_t(t);return i={interceptor:Re,...s},ee(t,a),i}}Object.defineProperty(e,`$${r}`,{get(){return n(t,o())},enumerable:!1})}),e}function nr(e,t,r,...n){try{return r(...n)}catch(i){te(i,e,t)}}function te(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} - -${r?'Expression: "'+r+`" - -`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function De(e){let t=Me;Me=!1;let r=e();return Me=t,r}function M(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return ir(...e)}var ir=gt;function or(e){ir=e}function gt(e,t){let r={};ue(r,e);let n=[r,...j(e)],i=typeof t=="function"?In(n,t):Ln(n,t,e);return nr.bind(null,e,t,i)}function In(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(F([n,...e]),i);Ne(r,o)}}var ht={};function kn(e,t){if(ht[e])return ht[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return te(s,t,e),Promise.resolve()}})();return ht[e]=o,o}function Ln(e,t,r){let n=kn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=F([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>te(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>te(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>te(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var bt="x-";function C(e=""){return bt+e}function sr(e){bt=e}var Pe={};function d(e,t){return Pe[e]=t,{before(r){if(!Pe[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=W.indexOf(r);W.splice(n>=0?n:W.indexOf("DEFAULT"),0,e)}}}function ar(e){return Object.keys(Pe).includes(e)}function de(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=wt(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(ur((o,s)=>n[o]=s)).filter(dr).map(jn(n,r)).sort(Fn).map(o=>$n(e,o))}function wt(e){return Array.from(e).map(ur()).filter(t=>!dr(t))}var xt=!1,fe=new Map,cr=Symbol();function lr(e){xt=!0;let t=Symbol();cr=t,fe.set(t,[]);let r=()=>{for(;fe.get(t).length;)fe.get(t).shift()();fe.delete(t)},n=()=>{xt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Gt(e);return t.push(i),[{Alpine:B,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:M.bind(M,e)},()=>t.forEach(a=>a())]}function $n(e,t){let r=()=>{},n=Pe[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),xt?fe.get(cr).push(n):n())};return s.runCleanups=o,s}var Ie=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),ke=e=>e;function ur(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=fr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var fr=[];function re(e){fr.push(e)}function dr({name:e}){return pr().test(e)}var pr=()=>new RegExp(`^${bt}([^:^.]+)\\b`);function jn(e,t){return({name:r,value:n})=>{let i=r.match(pr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var yt="DEFAULT",W=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",yt,"teleport"];function Fn(e,t){let r=W.indexOf(e.type)===-1?yt:e.type,n=W.indexOf(t.type)===-1?yt:t.type;return W.indexOf(r)-W.indexOf(n)}function G(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function T(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>T(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)T(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var mr=!1;function _r(){mr&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),mr=!0,document.body||E("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` - - - - - {% block head %}{% endblock %} - - -
- {% block body %}{% endblock %} -
- - -{% endif %} diff --git a/crates/app/src/components/navbar/menu-item.html b/crates/app/src/components/navbar/menu-item.html deleted file mode 100644 index fe0a264..0000000 --- a/crates/app/src/components/navbar/menu-item.html +++ /dev/null @@ -1,18 +0,0 @@ -{% set selected = item.id == current %} -
  • - - {{ item.label }} - -
  • diff --git a/crates/app/src/components/navbar/navbar.html b/crates/app/src/components/navbar/navbar.html deleted file mode 100644 index 227de77..0000000 --- a/crates/app/src/components/navbar/navbar.html +++ /dev/null @@ -1,50 +0,0 @@ -{% macro navbar(current) %} - -{% let items=crate::menu::get_menu_items() %} - - -{% endmacro %} diff --git a/crates/app/src/components/skeletons/card.html b/crates/app/src/components/skeletons/card.html deleted file mode 100644 index 79178da..0000000 --- a/crates/app/src/components/skeletons/card.html +++ /dev/null @@ -1,22 +0,0 @@ -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - Loading... -
    diff --git a/crates/app/src/components/skeletons/menu-items.html b/crates/app/src/components/skeletons/menu-items.html deleted file mode 100644 index b4fc630..0000000 --- a/crates/app/src/components/skeletons/menu-items.html +++ /dev/null @@ -1,4 +0,0 @@ -
    -
    -
    -
    \ No newline at end of file diff --git a/crates/app/src/components/skeletons/page-title.html b/crates/app/src/components/skeletons/page-title.html deleted file mode 100644 index 0ced82c..0000000 --- a/crates/app/src/components/skeletons/page-title.html +++ /dev/null @@ -1 +0,0 @@ -
    diff --git a/crates/app/src/lib.rs b/crates/app/src/lib.rs deleted file mode 100644 index a04e6ea..0000000 --- a/crates/app/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::path::PathBuf; - -use axum::http::{StatusCode, Uri}; -use axum_htmx::AutoVaryLayer; -use sea_orm::DatabaseConnection; -use thiserror::Error; -use tower_http::services::ServeDir; - -use ::utils::config::{load_config, ConfigError}; - -pub mod db; - -mod menu; -mod pages; - -async fn fallback(uri: Uri) -> (StatusCode, String) { - (StatusCode::NOT_FOUND, format!("No route for {uri}")) -} - -#[derive(Error, Debug)] -pub enum InitError { - #[error(transparent)] - ConfigError(#[from] ConfigError), -} - -pub fn init() -> Result<(), InitError> { - load_config(None)?; - Ok(()) -} - -#[derive(Clone)] -pub struct AppState { - db_connection: DatabaseConnection, -} - -pub async fn get_router(assets_path: PathBuf) -> axum::Router<()> { - let db_connection = db::get_connection().await.unwrap(); - let state: AppState = AppState { db_connection }; - - axum::Router::new() - .nest_service("/assets", ServeDir::new(assets_path)) - .merge(pages::get_routes()) - .fallback(fallback) - .with_state(state) - // The AutoVaryLayer is used to avoid cache issues with htmx (cf: https://github.com/robertwayne/axum-htmx?tab=readme-ov-file#auto-caching-management) - .layer(AutoVaryLayer) -} diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs deleted file mode 100644 index e7ddc98..0000000 --- a/crates/app/src/main.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::path::{Path, PathBuf}; -use std::{env, io}; - -use axum::body::Body; -use axum::http::Request; -use listenfd::ListenFd; -use notify::Watcher; -use thiserror::Error; -use tokio::net::TcpListener; -use tower_livereload::predicate::Predicate; -use tower_livereload::LiveReloadLayer; - -use ::app::{get_router, init, InitError}; - -#[derive(Error, Debug)] -pub enum AppError { - #[error("Unable to bind to TCP listener")] - TCPListener(#[from] std::io::Error), - #[error("Error with the notify watcher")] - NotifyWatcher(#[from] notify::Error), - #[error("Missing environment variable {var}")] - MissingEnvVar { var: &'static str }, - #[error("Error with the database connection")] - DatabaseConnection(#[from] sea_orm::DbErr), - #[error("Error while initialising the app")] - Initialisation(#[from] InitError), -} - -/// Nous filtrons les requêtes de `htmx` pour ne pas inclure le script _JS_ qui gère le rechargement -/// Voir https://github.com/leotaku/tower-livereload/pull/3 -#[derive(Copy, Clone)] -struct NotHtmxPredicate; -impl Predicate> for NotHtmxPredicate { - fn check(&mut self, req: &Request) -> bool { - !(req.headers().contains_key("hx-request")) - } -} - -const DEFAULT_LISTENER: &str = "localhost:3000"; -async fn get_tcp_listener() -> Result { - let mut listenfd = ListenFd::from_env(); - - match listenfd.take_tcp_listener(0)? { - // if we are given a tcp listener on listen fd 0, we use that one - Some(listener) => { - listener.set_nonblocking(true)?; - Ok(TcpListener::from_std(listener)?) - } - // otherwise fall back to local listening - None => Ok(TcpListener::bind(DEFAULT_LISTENER).await?), - } -} - -fn get_livereload_layer( - templates_paths: Vec, -) -> Result, notify::Error> { - let livereload = LiveReloadLayer::new(); - let reloader = livereload.reloader(); - let mut watcher = notify::recommended_watcher(move |_| reloader.reload())?; - for templates_path in templates_paths { - watcher.watch(templates_path.as_path(), notify::RecursiveMode::Recursive)?; - } - Ok(livereload.request_predicate::(NotHtmxPredicate)) -} - -#[tokio::main] -async fn main() -> Result<(), AppError> { - init()?; - - let manifest_dir = env::var("CARGO_MANIFEST_DIR").map_err(|_| AppError::MissingEnvVar { - var: "CARGO_MANIFEST_DIR", - })?; - let assets_path = Path::new(&manifest_dir).join("assets"); - let templates_paths = vec![ - Path::new(&manifest_dir).join("src/pages"), - Path::new(&manifest_dir).join("src/components"), - ]; - - let livereload_layer = - get_livereload_layer(templates_paths).map_err(AppError::NotifyWatcher)?; - let router = get_router(assets_path).await.layer(livereload_layer); - - let listener: TcpListener = get_tcp_listener().await.map_err(AppError::TCPListener)?; - let local_addr = listener.local_addr().map_err(AppError::TCPListener)?; - println!("Listening on: http://{}", local_addr); - - // Run the server with the router - axum::serve(listener, router.into_make_service()).await?; - Ok(()) -} diff --git a/crates/app/src/menu.rs b/crates/app/src/menu.rs deleted file mode 100644 index dc73752..0000000 --- a/crates/app/src/menu.rs +++ /dev/null @@ -1,28 +0,0 @@ -pub struct MenuItem { - pub id: String, - pub label: String, - pub href: String, -} - -/// Get the menu items -/// This function is the central place to define the menu items -/// It can be used directly in templates, for example in the `navbar` component to render the menu -pub fn get_menu_items() -> Vec { - vec![ - MenuItem { - id: "home".to_string(), - label: "Accueil".to_string(), - href: "/".to_string(), - }, - MenuItem { - id: "cps".to_string(), - label: "CPS".to_string(), - href: "/cps".to_string(), - }, - MenuItem { - id: "debug".to_string(), - label: "DEBUG".to_string(), - href: "/debug".to_string(), - }, - ] -} diff --git a/crates/app/src/pages/cps.html b/crates/app/src/pages/cps.html deleted file mode 100644 index 5e9da53..0000000 --- a/crates/app/src/pages/cps.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base.html" %} -{% import "navbar/navbar.html" as navbar -%} - -{% block title %}Pharma Libre - CPS{% endblock %} - -{% block body %} -{% call navbar::navbar(current="cps") %} -
    - -
    -
    -
    A
    -
    -
    B
    -
    C
    -
    D
    -
    E
    -
    -
    -
    -
    -{% endblock %} diff --git a/crates/app/src/pages/cps.rs b/crates/app/src/pages/cps.rs deleted file mode 100644 index 2a56bb6..0000000 --- a/crates/app/src/pages/cps.rs +++ /dev/null @@ -1,12 +0,0 @@ -use askama_axum::Template; -use axum_htmx::HxRequest; - -#[derive(Template)] -#[template(path = "cps.html")] -pub struct CpsTemplate { - hx_request: bool, -} - -pub async fn cps(HxRequest(hx_request): HxRequest) -> CpsTemplate { - CpsTemplate { hx_request } -} diff --git a/crates/app/src/pages/debug.html b/crates/app/src/pages/debug.html deleted file mode 100644 index 8b35d9c..0000000 --- a/crates/app/src/pages/debug.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends "base.html" %} -{% import "navbar/navbar.html" as navbar -%} - -{% block title %}Pharma Libre - Debug{% endblock %} - -{% block body %} -{% call navbar::navbar(current="debug") %} -
    - -
    -
    -
    -
    -

    - Base de données -

    -

    - Données extraites de la base de donnée à des fins de debug -

    - - - - - - - - - - - - - - - - - -
    - ID - - Value -
    - db_ping_status - - {{ db_ping_status }} -
    - debug_entries_count - - {{ debug_entries_count }} -
    -
    - -
    -
    -
    -
    -
    -
    -{% endblock %} \ No newline at end of file diff --git a/crates/app/src/pages/debug.rs b/crates/app/src/pages/debug.rs deleted file mode 100644 index 5b505da..0000000 --- a/crates/app/src/pages/debug.rs +++ /dev/null @@ -1,48 +0,0 @@ -use askama_axum::Template; -use axum::{extract::State, routing}; - -use ::entity::{debug, debug::Entity as DebugEntity}; -use axum_htmx::HxRequest; -use sea_orm::*; - -use crate::AppState; - -async fn get_debug_entries(db: &DatabaseConnection) -> Result, DbErr> { - DebugEntity::find().all(db).await -} - -async fn add_random_debug_entry(State(AppState { db_connection }): State) { - let random_entry = debug::ActiveModel { - title: Set("Random title".to_string()), - text: Set("Random text".to_string()), - ..Default::default() - }; - random_entry.insert(&db_connection).await.unwrap(); -} - -#[derive(Template)] -#[template(path = "debug.html")] -struct GetDebugTemplate { - hx_request: bool, - db_ping_status: bool, - debug_entries_count: usize, -} - -async fn debug( - HxRequest(hx_request): HxRequest, - State(AppState { db_connection }): State, -) -> GetDebugTemplate { - let db_ping_status = db_connection.ping().await.is_ok(); - let debug_entries = get_debug_entries(&db_connection).await.unwrap(); - GetDebugTemplate { - hx_request, - db_ping_status, - debug_entries_count: debug_entries.len(), - } -} - -pub fn get_routes() -> axum::Router { - axum::Router::new() - .route("/", routing::get(debug)) - .route("/add_random", routing::post(add_random_debug_entry)) -} diff --git a/crates/app/src/pages/home.html b/crates/app/src/pages/home.html deleted file mode 100644 index abe6fd4..0000000 --- a/crates/app/src/pages/home.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base.html" %} -{% import "navbar/navbar.html" as navbar -%} - -{% block title %}Pharma Libre - Accueil{% endblock %} - -{% block body %} -{% call navbar::navbar(current="home") %} -
    - -
    -
    -
    -
    A
    -
    B
    -
    C
    -
    D
    -
    -
    E
    -
    -
    -
    -{% endblock %} diff --git a/crates/app/src/pages/home.rs b/crates/app/src/pages/home.rs deleted file mode 100644 index 150cf22..0000000 --- a/crates/app/src/pages/home.rs +++ /dev/null @@ -1,12 +0,0 @@ -use askama_axum::Template; -use axum_htmx::HxRequest; - -#[derive(Template)] -#[template(path = "home.html")] -pub struct GetHomeTemplate { - hx_request: bool, -} - -pub async fn home(HxRequest(hx_request): HxRequest) -> GetHomeTemplate { - GetHomeTemplate { hx_request } -} diff --git a/crates/app/src/pages/mod.rs b/crates/app/src/pages/mod.rs deleted file mode 100644 index 24fd408..0000000 --- a/crates/app/src/pages/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -use axum::{routing, Router}; - -use crate::AppState; - -mod cps; -mod debug; -mod home; - -pub fn get_routes() -> Router { - Router::new() - .route("/", routing::get(home::home)) - .route("/cps", routing::get(cps::cps)) - .nest("/debug", debug::get_routes()) -} diff --git a/crates/app/tailwind.config.js b/crates/app/tailwind.config.js deleted file mode 100644 index 1c13bfe..0000000 --- a/crates/app/tailwind.config.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: [ - './src/**/*.html', - './css/**/*.css', - ], - theme: { - extend: {}, - }, - plugins: [], -} -