feat: UI overhaul
All checks were successful
conventional pull request title check / conventional pull request title check (pull_request) Successful in 6s
actionlint check / actionlint check (pull_request) Successful in 20s
conventional commit messages check / conventional commit messages check (pull_request) Successful in 10s
dotenv-linter check / dotenv-linter check (pull_request) Successful in 32s
GitLeaks check / GitLeaks check (pull_request) Successful in 28s
hadolint check / hadolint check (pull_request) Successful in 42s
htmlhint check / htmlhint check (pull_request) Successful in 1m16s
markdownlint check / markdownlint check (pull_request) Successful in 53s
Prettier check / Prettier check (pull_request) Successful in 50s
ShellCheck check / ShellCheck check (pull_request) Successful in 39s
yamllint check / yamllint check (pull_request) Successful in 42s
Stylelint check / Stylelint check (pull_request) Successful in 44s
checkov check / checkov check (pull_request) Successful in 6m52s
Rust check / Rust check (pull_request) Successful in 33m33s
All checks were successful
conventional pull request title check / conventional pull request title check (pull_request) Successful in 6s
actionlint check / actionlint check (pull_request) Successful in 20s
conventional commit messages check / conventional commit messages check (pull_request) Successful in 10s
dotenv-linter check / dotenv-linter check (pull_request) Successful in 32s
GitLeaks check / GitLeaks check (pull_request) Successful in 28s
hadolint check / hadolint check (pull_request) Successful in 42s
htmlhint check / htmlhint check (pull_request) Successful in 1m16s
markdownlint check / markdownlint check (pull_request) Successful in 53s
Prettier check / Prettier check (pull_request) Successful in 50s
ShellCheck check / ShellCheck check (pull_request) Successful in 39s
yamllint check / yamllint check (pull_request) Successful in 42s
Stylelint check / Stylelint check (pull_request) Successful in 44s
checkov check / checkov check (pull_request) Successful in 6m52s
Rust check / Rust check (pull_request) Successful in 33m33s
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
use crate::components::button_secondary::ButtonSecondary;
|
||||
use crate::components::input::Input;
|
||||
use crate::components::input_label::InputLabel;
|
||||
use crate::hooks::use_subtasks_of_task;
|
||||
use crate::models::subtask::NewSubtask;
|
||||
use crate::models::task::Task;
|
||||
@@ -6,146 +9,131 @@ use dioxus::core_macro::{component, rsx};
|
||||
use dioxus::dioxus_core::Element;
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_free_icons::Icon;
|
||||
use dioxus_free_icons::icons::fa_regular_icons::FaSquare;
|
||||
use dioxus_free_icons::icons::fa_solid_icons::{FaListCheck, FaPlus, FaSquareCheck, FaTrashCan};
|
||||
use dioxus_free_icons::icons::fa_solid_icons::{FaGavel, FaListCheck, FaTrashCan};
|
||||
|
||||
#[component]
|
||||
pub(crate) fn SubtasksForm(task: Task) -> Element {
|
||||
let subtasks = use_subtasks_of_task(task.id)?;
|
||||
let mut new_title = use_signal(String::new);
|
||||
rsx! {
|
||||
form {
|
||||
class: "flex flex-row items-center gap-3",
|
||||
onsubmit: move |event| {
|
||||
event.prevent_default();
|
||||
let task = task.clone();
|
||||
async move {
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: task.id,
|
||||
title: event.get("title").first().cloned().and_then(|value| match value {
|
||||
FormValue::Text(value) => Some(value),
|
||||
FormValue::File(_) => None
|
||||
}).unwrap(),
|
||||
is_completed: false
|
||||
};
|
||||
let _ = create_subtask(new_subtask).await;
|
||||
new_title.set(String::new());
|
||||
}
|
||||
},
|
||||
label {
|
||||
r#for: "input_new_title",
|
||||
class: "min-w-6 flex flex-row justify-center items-center",
|
||||
Icon {
|
||||
class: "text-zinc-400/50",
|
||||
icon: FaListCheck,
|
||||
height: 16,
|
||||
width: 16
|
||||
}
|
||||
}
|
||||
div {
|
||||
class: "grow grid grid-cols-6 gap-2",
|
||||
input {
|
||||
name: "title",
|
||||
required: true,
|
||||
value: new_title,
|
||||
r#type: "text",
|
||||
class: "grow py-2 px-3 col-span-5 bg-zinc-800/50 rounded-lg",
|
||||
id: "input_new_title",
|
||||
onchange: move |event| new_title.set(event.value())
|
||||
}
|
||||
button {
|
||||
r#type: "submit",
|
||||
class: "py-2 col-span-1 flex flex-row justify-center items-center bg-zinc-800/50 rounded-lg cursor-pointer",
|
||||
Icon {
|
||||
icon: FaPlus,
|
||||
height: 16,
|
||||
width: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for subtask in subtasks {
|
||||
div {
|
||||
key: "{subtask.id}",
|
||||
div {
|
||||
class: "flex flex-col gap-3",
|
||||
form {
|
||||
class: "flex flex-row items-center gap-3",
|
||||
button {
|
||||
class: "min-w-6 flex flex-row justify-center items-center text-zinc-400/50 cursor-pointer",
|
||||
onclick: {
|
||||
let subtask = subtask.clone();
|
||||
move |_| {
|
||||
let subtask = subtask.clone();
|
||||
async move {
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: subtask.task_id,
|
||||
title: subtask.title.clone(),
|
||||
is_completed: !subtask.is_completed
|
||||
};
|
||||
let _ = edit_subtask(
|
||||
subtask.id,
|
||||
new_subtask
|
||||
).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
if subtask.is_completed {
|
||||
Icon {
|
||||
icon: FaSquareCheck,
|
||||
height: 24,
|
||||
width: 24
|
||||
}
|
||||
} else {
|
||||
Icon {
|
||||
icon: FaSquare,
|
||||
height: 24,
|
||||
width: 24
|
||||
}
|
||||
onsubmit: move |event| {
|
||||
event.prevent_default();
|
||||
let task = task.clone();
|
||||
async move {
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: task.id,
|
||||
title: event.get("new_title").first().cloned().and_then(|value| match value {
|
||||
FormValue::Text(value) => Some(value),
|
||||
FormValue::File(_) => None
|
||||
}).unwrap(),
|
||||
is_completed: false
|
||||
};
|
||||
let _ = create_subtask(new_subtask).await;
|
||||
new_title.set(String::new());
|
||||
}
|
||||
},
|
||||
InputLabel {
|
||||
icon: FaListCheck,
|
||||
r#for: "input_new_title"
|
||||
}
|
||||
div {
|
||||
class: "grow grid grid-cols-6 gap-2",
|
||||
input {
|
||||
class: "grow flex flex-row items-end gap-3",
|
||||
Input {
|
||||
class: "grow",
|
||||
name: "new_title",
|
||||
r#type: "text",
|
||||
class: "grow py-2 px-3 col-span-5 bg-zinc-800/50 rounded-lg",
|
||||
id: "input_title_{subtask.id}",
|
||||
initial_value: subtask.title.clone(),
|
||||
onchange: {
|
||||
let subtask = subtask.clone();
|
||||
move |event: Event<FormData>| {
|
||||
let subtask = subtask.clone();
|
||||
async move {
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: subtask.task_id,
|
||||
title: event.value(),
|
||||
is_completed: subtask.is_completed
|
||||
};
|
||||
if new_subtask.title.is_empty() {
|
||||
let _ = delete_subtask(subtask.id).await;
|
||||
} else {
|
||||
let _ = edit_subtask(
|
||||
subtask.id,
|
||||
new_subtask
|
||||
).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
required: true,
|
||||
value: new_title,
|
||||
onchange: move |event: Event<FormData>| new_title.set(event.value())
|
||||
}
|
||||
ButtonSecondary {
|
||||
r#type: "submit",
|
||||
Icon {
|
||||
icon: FaGavel,
|
||||
height: 16,
|
||||
width: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for subtask in subtasks {
|
||||
div {
|
||||
key: "{subtask.id}",
|
||||
class: "flex flex-row items-center gap-3",
|
||||
button {
|
||||
r#type: "button",
|
||||
class: "py-2 flex flex-row justify-center items-center col-span-1 bg-zinc-800/50 rounded-lg cursor-pointer",
|
||||
class: "mt-1.5 hover:mt-1 hover:pb-0.5 min-w-7 cursor-pointer transition-all duration-150",
|
||||
onclick: {
|
||||
let subtask = subtask.clone();
|
||||
move |_| {
|
||||
let subtask = subtask.clone();
|
||||
async move {
|
||||
let _ = delete_subtask(subtask.id).await;
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: subtask.task_id,
|
||||
title: subtask.title.clone(),
|
||||
is_completed: !subtask.is_completed
|
||||
};
|
||||
let _ = edit_subtask(
|
||||
subtask.id,
|
||||
new_subtask
|
||||
).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
Icon {
|
||||
icon: FaTrashCan,
|
||||
height: 16,
|
||||
width: 16
|
||||
div {
|
||||
class: format!("grow h-7 w-7 mb-[4px] drop-shadow-[0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800)] rounded-full {}",
|
||||
if subtask.is_completed {"bg-gray-600"} else {"border-3 border-gray-600"}
|
||||
)
|
||||
}
|
||||
}
|
||||
div {
|
||||
class: "grow flex flex-row items-end gap-3",
|
||||
Input {
|
||||
class: "grow",
|
||||
name: "title_edit_{subtask.id}",
|
||||
r#type: "text",
|
||||
initial_value: subtask.title.clone(),
|
||||
onchange: {
|
||||
let subtask = subtask.clone();
|
||||
move |event: Event<FormData>| {
|
||||
let subtask = subtask.clone();
|
||||
async move {
|
||||
let new_subtask = NewSubtask {
|
||||
task_id: subtask.task_id,
|
||||
title: event.value(),
|
||||
is_completed: subtask.is_completed
|
||||
};
|
||||
if new_subtask.title.is_empty() {
|
||||
let _ = delete_subtask(subtask.id).await;
|
||||
} else {
|
||||
let _ = edit_subtask(
|
||||
subtask.id,
|
||||
new_subtask
|
||||
).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ButtonSecondary {
|
||||
r#type: "button",
|
||||
onclick: {
|
||||
let subtask = subtask.clone();
|
||||
move |_| {
|
||||
let subtask = subtask.clone();
|
||||
async move {
|
||||
let _ = delete_subtask(subtask.id).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
Icon {
|
||||
icon: FaTrashCan,
|
||||
height: 16,
|
||||
width: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user