diff --git a/assets/css/main.css b/assets/css/main.css index f9d5fd3..54d5b87 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -13,12 +13,12 @@ --text-xs--line-height: calc(1 / 0.75); --text-sm: 0.875rem; --text-sm--line-height: calc(1.25 / 0.875); + --text-lg: 1.125rem; + --text-lg--line-height: calc(1.75 / 1.125); --text-xl: 1.25rem; --text-xl--line-height: calc(1.75 / 1.25); --text-2xl: 1.5rem; --text-2xl--line-height: calc(2 / 1.5); - --text-3xl: 1.875rem; - --text-3xl--line-height: calc(2.25 / 1.875); --font-weight-bold: 700; --default-font-family: var(--font-sans); --default-mono-font-family: var(--font-mono); @@ -956,9 +956,18 @@ justify-content: flex-end; gap: calc(0.25rem * 2); } + .mt-2 { + margin-top: calc(var(--spacing) * 2); + } .mt-3 { margin-top: calc(var(--spacing) * 3); } + .mr-1 { + margin-right: calc(var(--spacing) * 1); + } + .mr-3 { + margin-right: calc(var(--spacing) * 3); + } .fieldset-legend { margin-bottom: calc(0.25rem * -1); display: flex; @@ -1022,6 +1031,9 @@ .h-\[1\.2em\] { height: 1.2em; } + .h-\[92px\] { + height: 92px; + } .h-full { height: 100%; } @@ -1037,6 +1049,15 @@ .w-56 { width: calc(var(--spacing) * 56); } + .w-\[1\.5em\] { + width: 1.5em; + } + .w-\[1\.6em\] { + width: 1.6em; + } + .w-\[1\.7em\] { + width: 1.7em; + } .w-full { width: 100%; } @@ -1068,6 +1089,12 @@ .flex-wrap { flex-wrap: wrap; } + .items-center { + align-items: center; + } + .justify-center { + justify-content: center; + } .gap-2 { gap: calc(var(--spacing) * 2); } @@ -1100,20 +1127,21 @@ .p-3 { padding: calc(var(--spacing) * 3); } + .p-5 { + padding: calc(var(--spacing) * 5); + } .py-2 { padding-block: calc(var(--spacing) * 2); } - .py-10 { - padding-block: calc(var(--spacing) * 10); - } .pt-3 { padding-top: calc(var(--spacing) * 3); } .pb-6 { padding-bottom: calc(var(--spacing) * 6); } - .pl-10 { - padding-left: calc(var(--spacing) * 10); + .text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); } .text-sm { font-size: var(--text-sm); @@ -1164,6 +1192,10 @@ --btn-color: var(--color-error); --btn-fg: var(--color-error-content); } + .btn-success { + --btn-color: var(--color-success); + --btn-fg: var(--color-success-content); + } .hover\:cursor-pointer { &:hover { @media (hover: hover) { @@ -1189,18 +1221,17 @@ } } } -h1 { - font-size: var(--text-3xl); - line-height: var(--tw-leading, var(--text-3xl--line-height)); -} h2 { - font-size: var(--text-2xl); - line-height: var(--tw-leading, var(--text-2xl--line-height)); -} -h3 { font-size: var(--text-xl); line-height: var(--tw-leading, var(--text-xl--line-height)); } +h3 { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); +} +.desc { + opacity: 80%; +} @layer base { :where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light] { color-scheme: light; diff --git a/src/icons.rs b/src/icons.rs index 34f0ceb..59729fc 100644 --- a/src/icons.rs +++ b/src/icons.rs @@ -2,4 +2,13 @@ mod eye; mod search; pub use eye::eye; +use maud::{Markup, html}; pub use search::search; + +pub fn arrow_left() -> Markup { + html! { + svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256" { + path fill="currentColor" d="M224 128a8 8 0 0 1-8 8H59.31l58.35 58.34a8 8 0 0 1-11.32 11.32l-72-72a8 8 0 0 1 0-11.32l72-72a8 8 0 0 1 11.32 11.32L59.31 120H216a8 8 0 0 1 8 8" {} + } + } +} diff --git a/src/layouts/desktop.rs b/src/layouts/desktop.rs index a1e9f16..8df6ffc 100644 --- a/src/layouts/desktop.rs +++ b/src/layouts/desktop.rs @@ -1,5 +1,7 @@ use maud::{Markup, html}; +use crate::icons; + use super::empty; pub fn desktop_minimal(content: Markup, name: &str) -> Markup { @@ -8,7 +10,7 @@ pub fn desktop_minimal(content: Markup, name: &str) -> Markup { div class="w-56" { (sidebar()) } - div class="w-full overflow-y-auto" { + div class="w-full h-full overflow-y-auto" { (content) } } @@ -17,10 +19,13 @@ pub fn desktop_minimal(content: Markup, name: &str) -> Markup { empty(content, name) } -pub fn desktop(content: Markup, name: &str) -> Markup { +pub fn desktop(content: Markup, name: &str, back_button: bool) -> Markup { let content = html! { - div class="pl-10 py-10 w-full max-w-2xl" { - (content) + div class="flex justify-center" { + div class="p-5 w-full max-w-2xl" { + (header(name, back_button)) + (content) + } } }; @@ -47,3 +52,16 @@ fn sidebar() -> Markup { } } } + +fn header(title: &str, back_button: bool) -> Markup { + html! { + div class="flex items-center mb-5" { + @if back_button { + button onclick="history.back()" class="w-[1.6em] mr-1" { + (icons::arrow_left()) + } + } + h1 class="text-2xl" { (title) } + } + } +} diff --git a/src/pages/exercises.rs b/src/pages/exercises.rs index 8a784ff..11ce287 100644 --- a/src/pages/exercises.rs +++ b/src/pages/exercises.rs @@ -21,17 +21,17 @@ async fn page(State(state): State) -> Result { .await?; let content = html! { - h1 { "Exercises" } a href="/exercises/new" { "new exercise +" } - ul class="list" { + + div class="list" { @for exercise in exercises { - li hx-get={ "/exercises/" (exercise.exercise_id) } hx-target="body" hx-push-url="true" class="list-row" { + a href={"/exercises/" (exercise.exercise_id)} class="list-row" { div {} div { div class="font-bold" { (exercise.name) } div class="text-xs" { (exercise.description) } } - a class="btn btn-square btn-ghost" { + div class="btn btn-square btn-ghost" { div class="size-[1.6em]" { (icons::eye()) } @@ -41,5 +41,5 @@ async fn page(State(state): State) -> Result { } }; - Ok(layouts::desktop(content, "Exercises")) + Ok(layouts::desktop(content, "Browse Exercises", false)) } diff --git a/src/pages/exercises/id.rs b/src/pages/exercises/id.rs index a83fce6..ca97d6c 100644 --- a/src/pages/exercises/id.rs +++ b/src/pages/exercises/id.rs @@ -1,4 +1,4 @@ -use crate::{AppError, layouts, util::AppState}; +use crate::{AppError, layouts, models::exercises::ExerciseFull, util::AppState}; use axum::{ Form, Router, extract::{Path, State}, @@ -26,17 +26,16 @@ async fn page(State(state): State, Path(id): Path) -> Result) -> Result { .collect(); let content = html! { - h1 class="mb-5" { "New Exercise" } - form hx-post="/exercises/new" class="space-y-1" { fieldset class="fieldset" { legend class="fieldset-legend" { "Name" } @@ -49,7 +47,7 @@ async fn page(State(state): State) -> Result { } }; - Ok(layouts::desktop(content, "New Exercise")) + Ok(layouts::desktop(content, "New Exercise", true)) } #[derive(Deserialize, Debug)] diff --git a/src/pages/index.rs b/src/pages/index.rs index d3f3bb1..bd5ebc0 100644 --- a/src/pages/index.rs +++ b/src/pages/index.rs @@ -9,5 +9,5 @@ pub fn routes() -> Router { async fn page() -> Markup { let content = html! {}; - layouts::desktop(content, "Home") + layouts::desktop(content, "Home", false) } diff --git a/src/pages/workouts.rs b/src/pages/workouts.rs index 0315eba..d012d18 100644 --- a/src/pages/workouts.rs +++ b/src/pages/workouts.rs @@ -21,7 +21,6 @@ async fn page(State(state): State) -> Result { .await?; let content = html! { - h1 { "Workouts" } a href="/workouts/new" { "new workout +" } div class="list" { @for workout in workouts { @@ -41,5 +40,5 @@ async fn page(State(state): State) -> Result { } }; - Ok(layouts::desktop(content, "Workouts")) + Ok(layouts::desktop(content, "Browse Workouts", false)) } diff --git a/src/pages/workouts/id.rs b/src/pages/workouts/id.rs index cd0b96d..951624b 100644 --- a/src/pages/workouts/id.rs +++ b/src/pages/workouts/id.rs @@ -45,25 +45,51 @@ async fn page(State(state): State, Path(id): Path) -> Result Markup { + html! { + div class="bg-base-200 p-3 rounded flex" { + div { + h3 { (exercise.name) } + p class="text-sm opacity-50" { (exercise.description) } + } + div class="ml-auto flex items-center" { + @match exercise.exercise_type { + ExerciseVariant::Time => { + div { (exercise.time.unwrap_or(-1))"s" } + }, + ExerciseVariant::Number => { + div { + div { (exercise.sets.unwrap_or(-1)) " sets" } + div { (exercise.reps.unwrap_or(-1)) " reps" } + } + }, + ExerciseVariant::Failure => { + "Failure" + }, + } + } + } + } } async fn delete( @@ -114,7 +140,7 @@ async fn edit( } }; - Ok(layouts::desktop(content, "Edit Exercises")) + Ok(layouts::desktop(content, "Edit Exercises", true)) } #[derive(Deserialize, Debug)] diff --git a/src/pages/workouts/new.rs b/src/pages/workouts/new.rs index bd07fd9..b2f525b 100644 --- a/src/pages/workouts/new.rs +++ b/src/pages/workouts/new.rs @@ -29,8 +29,6 @@ async fn page(State(state): State) -> Result { .await?; let content = html! { - h1 class="mb-5" { "New Workout" } - div x-data="{ exercises: [] }" { form hx-post="/workouts/new" class="space-y-1" { fieldset class="fieldset" { @@ -132,7 +130,7 @@ async fn page(State(state): State) -> Result { }; - Ok(layouts::desktop(content, "New Exercise")) + Ok(layouts::desktop(content, "New Workout", true)) } #[derive(Deserialize, Debug)] diff --git a/tailwind.css b/tailwind.css index d5c2af6..8b49f71 100644 --- a/tailwind.css +++ b/tailwind.css @@ -39,14 +39,14 @@ --noise: 0; } -h1 { - @apply text-3xl -} - h2 { - @apply text-2xl + @apply text-xl } h3 { - @apply text-xl + @apply text-lg +} + +.desc { + @apply opacity-80 }