Compare commits
No commits in common. "84cd97bc5c9c1cea241a7d468f7ec41b1d09b6a7" and "4627f9540a0f663e13dadcd807788c211e7ba90d" have entirely different histories.
84cd97bc5c
...
4627f9540a
3
crates/app/.gitignore
vendored
3
crates/app/.gitignore
vendored
@ -1,4 +1 @@
|
|||||||
/target
|
/target
|
||||||
|
|
||||||
# Tailwind CSS CLI
|
|
||||||
tailwindcss
|
|
@ -1,11 +0,0 @@
|
|||||||
## Pré-requis
|
|
||||||
|
|
||||||
- Récupérer le binaire TailwindCSS : https://tailwindcss.com/blog/standalone-cli
|
|
||||||
|
|
||||||
## Dev
|
|
||||||
|
|
||||||
- Lancer tailwindcss en mode watch dans un deuxième terminal :
|
|
||||||
```bash
|
|
||||||
./tailwindcss -i css/input.css -o assets/css/style.css --watch
|
|
||||||
```
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
@ -2,27 +2,26 @@ mod templates;
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use askama::Template;
|
|
||||||
use askama_axum::IntoResponse;
|
use askama_axum::IntoResponse;
|
||||||
use axum::http::{StatusCode, Uri};
|
use templates::{hello::HelloResponse, index::GetIndexResponse};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
||||||
async fn fallback(uri: Uri) -> (StatusCode, String) {
|
async fn root() -> impl IntoResponse {
|
||||||
(StatusCode::NOT_FOUND, format!("No route for {uri}"))
|
return GetIndexResponse {}.into_response();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
async fn hello() -> impl IntoResponse {
|
||||||
#[template(path = "index.html")]
|
return HelloResponse {
|
||||||
pub struct GetIndexResponse;
|
name: "Theo".to_string(),
|
||||||
|
}
|
||||||
async fn root() -> impl IntoResponse {
|
.into_response();
|
||||||
GetIndexResponse {}.into_response()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_router(assets_path: &Path) -> axum::Router {
|
pub fn get_router(assets_path: &Path) -> axum::Router {
|
||||||
axum::Router::new()
|
let router = axum::Router::new()
|
||||||
.nest_service("/assets", ServeDir::new(assets_path))
|
.nest_service("/assets", ServeDir::new(assets_path))
|
||||||
.route("/", axum::routing::get(root))
|
.route("/", axum::routing::get(root))
|
||||||
.merge(templates::get_routes())
|
.route("/hello", axum::routing::get(hello));
|
||||||
.fallback(fallback)
|
|
||||||
|
router
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ async fn main() {
|
|||||||
let router = get_router(assets_path.as_path());
|
let router = get_router(assets_path.as_path());
|
||||||
|
|
||||||
// TODO: select port based on available port (or ask in CLI)
|
// TODO: select port based on available port (or ask in CLI)
|
||||||
let listener = tokio::net::TcpListener::bind("localhost:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
println!("Listening on: http://{}", listener.local_addr().unwrap());
|
|
||||||
axum::serve(listener, router).await.unwrap();
|
axum::serve(listener, router).await.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,7 @@
|
|||||||
use askama::Template;
|
use askama::Template;
|
||||||
use askama_axum::IntoResponse;
|
|
||||||
use axum::{routing, Router};
|
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "hello.html")]
|
#[template(path = "hello.html")]
|
||||||
struct HelloResponse {
|
pub struct HelloResponse {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn hello() -> impl IntoResponse {
|
|
||||||
HelloResponse {
|
|
||||||
name: "Theo".to_string(),
|
|
||||||
}.into_response()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_routes() -> Router {
|
|
||||||
Router::new()
|
|
||||||
.route("/", routing::get(hello))
|
|
||||||
}
|
|
||||||
|
5
crates/app/src/templates/index.rs
Normal file
5
crates/app/src/templates/index.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
use askama::Template;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "index.html")]
|
||||||
|
pub struct GetIndexResponse;
|
@ -1,8 +1,2 @@
|
|||||||
use axum::Router;
|
pub mod hello;
|
||||||
|
pub mod index;
|
||||||
mod hello;
|
|
||||||
|
|
||||||
pub fn get_routes() -> Router {
|
|
||||||
Router::new()
|
|
||||||
.nest("/hello", hello::get_routes())
|
|
||||||
}
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
|
||||||
module.exports = {
|
|
||||||
content: [
|
|
||||||
'./templates/**/*.html',
|
|
||||||
'./css/**/*.css',
|
|
||||||
],
|
|
||||||
theme: {
|
|
||||||
extend: {},
|
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +1,13 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="fr" class="h-full">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{{ title }}{% endblock %}</title>
|
<title>{% block title %}{{ title }}{% endblock %}</title>
|
||||||
|
|
||||||
<script src="/assets/js/htmx.min.js"></script>
|
<script src="/assets/js/htmx.min.js"></script>
|
||||||
<script src="//unpkg.com/alpinejs" defer></script>
|
|
||||||
<link href="/assets/css/style.css" rel="stylesheet">
|
|
||||||
|
|
||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class="h-full">
|
<body>
|
||||||
<div class="min-h-full">
|
{% block body %}{% endblock %}
|
||||||
{% block nav %}
|
|
||||||
{% include "layout/nav.html" %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block body %}{% endblock %}
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,24 +3,20 @@
|
|||||||
{% block title %}Pharma Libre{% endblock %}
|
{% block title %}Pharma Libre{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="py-10">
|
|
||||||
|
<div>
|
||||||
<header>
|
<header>
|
||||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
<h1>Pharma Libre</h1>
|
||||||
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900">Dashboard</h1>
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8">
|
<div
|
||||||
<!-- Your content -->
|
id="hello"
|
||||||
<div
|
hx-get="/hello"
|
||||||
id="hello"
|
hx-target="this"
|
||||||
hx-get="/hello"
|
hx-trigger="load"
|
||||||
hx-target="this"
|
hx-swap="outerHTML"
|
||||||
hx-trigger="load"
|
>
|
||||||
hx-swap="outerHTML"
|
Loading...
|
||||||
>
|
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
<nav
|
|
||||||
class="border-b border-gray-200 bg-white"
|
|
||||||
x-data="{ menuOpen: false }"
|
|
||||||
>
|
|
||||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
||||||
<div class="flex h-16 justify-between">
|
|
||||||
<div class="flex">
|
|
||||||
{% include "layout/nav/logo.html" %}
|
|
||||||
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
|
|
||||||
{% include "layout/nav/desktop/menu-items.html" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hidden sm:ml-6 sm:flex sm:items-center">
|
|
||||||
{% include "layout/nav/desktop/notifications-button.html" %}
|
|
||||||
{% include "layout/nav/desktop/profile.html" %}
|
|
||||||
</div>
|
|
||||||
<div class="-mr-2 flex items-center sm:hidden">
|
|
||||||
{% include "layout/nav/mobile/menu-button.html" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Mobile menu, show/hide based on menu state. -->
|
|
||||||
<div
|
|
||||||
class="sm:hidden" id="mobile-menu"
|
|
||||||
x-show="menuOpen"
|
|
||||||
x-cloak
|
|
||||||
>
|
|
||||||
<div class="space-y-1 pb-3 pt-2">
|
|
||||||
{% include "layout/nav/mobile/menu-items.html" %}
|
|
||||||
</div>
|
|
||||||
<div class="border-t border-gray-200 pb-3 pt-4">
|
|
||||||
<div class="flex items-center px-4">
|
|
||||||
{% include "layout/nav/mobile/profile.html" %}
|
|
||||||
{% include "layout/nav/mobile/notifications-button.html" %}
|
|
||||||
</div>
|
|
||||||
<div class="mt-3 space-y-1">
|
|
||||||
{% include "layout/nav/mobile/profile-items.html" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
@ -1,22 +0,0 @@
|
|||||||
<!-- Current: "border-indigo-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" -->
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="inline-flex items-center border-b-2 border-indigo-500 px-1 pt-1 text-sm font-medium text-gray-900"
|
|
||||||
aria-current="page"
|
|
||||||
>Dashboard</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700"
|
|
||||||
>Team</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700"
|
|
||||||
>Projects</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700"
|
|
||||||
>Calendar</a
|
|
||||||
>
|
|
@ -1,6 +0,0 @@
|
|||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="relative rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
||||||
>
|
|
||||||
{% include "layout/nav/notifications-icon.html" %}
|
|
||||||
</button>
|
|
@ -1,38 +0,0 @@
|
|||||||
<div
|
|
||||||
class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
|
||||||
role="menu"
|
|
||||||
id="profile-dropdown"
|
|
||||||
aria-orientation="vertical"
|
|
||||||
aria-labelledby="user-menu-button"
|
|
||||||
tabindex="-1"
|
|
||||||
x-show="profileOpen"
|
|
||||||
x-on:click.outside="profileOpen = false"
|
|
||||||
x-cloak
|
|
||||||
x-transition
|
|
||||||
>
|
|
||||||
<!-- Active: "bg-gray-100", Not Active: "" -->
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-sm text-gray-700"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
id="user-menu-item-0"
|
|
||||||
>Your Profile</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-sm text-gray-700"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
id="user-menu-item-1"
|
|
||||||
>Settings</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-sm text-gray-700"
|
|
||||||
role="menuitem"
|
|
||||||
tabindex="-1"
|
|
||||||
id="user-menu-item-2"
|
|
||||||
>Sign out</a
|
|
||||||
>
|
|
||||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||||||
<!-- Profile dropdown -->
|
|
||||||
<div
|
|
||||||
class="relative ml-3"
|
|
||||||
x-data="{ profileOpen: false }"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="relative flex max-w-xs items-center rounded-full bg-white text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
||||||
id="user-menu-button"
|
|
||||||
aria-controls="profile-dropdown"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
x-on:click="profileOpen = ! profileOpen"
|
|
||||||
>
|
|
||||||
<span class="absolute -inset-1.5"></span>
|
|
||||||
<span class="sr-only">Open user menu</span>
|
|
||||||
<img
|
|
||||||
class="h-8 w-8 rounded-full"
|
|
||||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% include "layout/nav/desktop/profile-dropdown.html" %}
|
|
||||||
</div>
|
|
@ -1,4 +0,0 @@
|
|||||||
<div class="flex flex-shrink-0 items-center">
|
|
||||||
<img class="block h-8 w-auto lg:hidden" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
|
||||||
<img class="hidden h-8 w-auto lg:block" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
|
||||||
</div>
|
|
@ -1,43 +0,0 @@
|
|||||||
<!-- Mobile menu button -->
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="relative inline-flex items-center justify-center rounded-md bg-white p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
||||||
aria-controls="mobile-menu"
|
|
||||||
x-on:click="menuOpen = ! menuOpen"
|
|
||||||
x-bind:aria-expanded="menuOpen"
|
|
||||||
>
|
|
||||||
<span class="absolute -inset-0.5"></span>
|
|
||||||
<span class="sr-only">Open main menu</span>
|
|
||||||
<!-- Menu open: "hidden", Menu closed: "block" -->
|
|
||||||
<svg
|
|
||||||
class="h-6 w-6"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
x-bind:class="menuOpen ? 'hidden' : 'block'"
|
|
||||||
x-bind:aria-hidden="menuOpen"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<!-- Menu open: "block", Menu closed: "hidden" -->
|
|
||||||
<svg
|
|
||||||
class="h-6 w-6"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
x-bind:class="menuOpen ? 'block' : 'hidden'"
|
|
||||||
x-bind:aria-hidden="! menuOpen"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M6 18L18 6M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
@ -1,22 +0,0 @@
|
|||||||
<!-- Current: "border-indigo-500 bg-indigo-50 text-indigo-700", Default: "border-transparent text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" -->
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block border-l-4 border-indigo-500 bg-indigo-50 py-2 pl-3 pr-4 text-base font-medium text-indigo-700"
|
|
||||||
aria-current="page"
|
|
||||||
>Dashboard</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800"
|
|
||||||
>Team</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800"
|
|
||||||
>Projects</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800"
|
|
||||||
>Calendar</a
|
|
||||||
>
|
|
@ -1,6 +0,0 @@
|
|||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="relative ml-auto flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
||||||
>
|
|
||||||
{% include "layout/nav/notifications-icon.html" %}
|
|
||||||
</button>
|
|
@ -1,15 +0,0 @@
|
|||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800"
|
|
||||||
>Your Profile</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800"
|
|
||||||
>Settings</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800"
|
|
||||||
>Sign out</a
|
|
||||||
>
|
|
@ -1,11 +0,0 @@
|
|||||||
<div class="flex-shrink-0">
|
|
||||||
<img
|
|
||||||
class="h-10 w-10 rounded-full"
|
|
||||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="ml-3">
|
|
||||||
<div class="text-base font-medium text-gray-800">Tom Cook</div>
|
|
||||||
<div class="text-sm font-medium text-gray-500">tom@example.com</div>
|
|
||||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||||||
<span class="absolute -inset-1.5"></span>
|
|
||||||
<span class="sr-only">View notifications</span>
|
|
||||||
<svg
|
|
||||||
class="h-6 w-6"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
Loading…
Reference in New Issue
Block a user