add ready ui
This commit is contained in:
@@ -210,6 +210,14 @@ async fn main() -> Result<(), StartError> {
|
||||
"/:id/packagelist/item/:id/unpack",
|
||||
post(trip_item_packagelist_set_unpack_htmx),
|
||||
)
|
||||
.route(
|
||||
"/:id/packagelist/item/:id/ready",
|
||||
post(trip_item_packagelist_set_ready_htmx),
|
||||
)
|
||||
.route(
|
||||
"/:id/packagelist/item/:id/unready",
|
||||
post(trip_item_packagelist_set_unready_htmx),
|
||||
)
|
||||
.route("/:id/state/:id", post(trip_state_set))
|
||||
.route("/:id/total_weight", get(trip_total_weight_htmx))
|
||||
.route("/:id/type/:id/add", get(trip_type_add))
|
||||
@@ -1194,7 +1202,7 @@ async fn trip_item_packagelist_set_pack_htmx(
|
||||
message: format!("an item with id {item_id} does not exist"),
|
||||
}))?;
|
||||
|
||||
Ok(view::trip::packagelist::TripPackageListRow::build(
|
||||
Ok(view::trip::packagelist::TripPackageListRowReady::build(
|
||||
trip_id, &item,
|
||||
))
|
||||
}
|
||||
@@ -1220,7 +1228,57 @@ async fn trip_item_packagelist_set_unpack_htmx(
|
||||
message: format!("an item with id {item_id} does not exist"),
|
||||
}))?;
|
||||
|
||||
Ok(view::trip::packagelist::TripPackageListRow::build(
|
||||
Ok(view::trip::packagelist::TripPackageListRowReady::build(
|
||||
trip_id, &item,
|
||||
))
|
||||
}
|
||||
|
||||
async fn trip_item_packagelist_set_ready_htmx(
|
||||
State(state): State<AppState>,
|
||||
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
trip_item_set_state(
|
||||
&state,
|
||||
trip_id,
|
||||
item_id,
|
||||
models::trips::TripItemStateKey::Ready,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let item = models::trips::TripItem::find(&state.database_pool, trip_id, item_id)
|
||||
.await?
|
||||
.ok_or(Error::Request(RequestError::NotFound {
|
||||
message: format!("an item with id {item_id} does not exist"),
|
||||
}))?;
|
||||
|
||||
Ok(view::trip::packagelist::TripPackageListRowUnready::build(
|
||||
trip_id, &item,
|
||||
))
|
||||
}
|
||||
|
||||
async fn trip_item_packagelist_set_unready_htmx(
|
||||
State(state): State<AppState>,
|
||||
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
trip_item_set_state(
|
||||
&state,
|
||||
trip_id,
|
||||
item_id,
|
||||
models::trips::TripItemStateKey::Ready,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// note that this cannot fail due to a missing item, as trip_item_set_state would already
|
||||
// return 404. but error handling cannot hurt ;)
|
||||
let item = models::trips::TripItem::find(&state.database_pool, trip_id, item_id)
|
||||
.await?
|
||||
.ok_or(Error::Request(RequestError::NotFound {
|
||||
message: format!("an item with id {item_id} does not exist"),
|
||||
}))?;
|
||||
|
||||
Ok(view::trip::packagelist::TripPackageListRowUnready::build(
|
||||
trip_id, &item,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ use uuid::Uuid;
|
||||
|
||||
use crate::models;
|
||||
|
||||
pub struct TripPackageListRow;
|
||||
pub struct TripPackageListRowReady;
|
||||
|
||||
impl TripPackageListRow {
|
||||
impl TripPackageListRowReady {
|
||||
pub fn build(trip_id: Uuid, item: &models::trips::TripItem) -> Markup {
|
||||
html!(
|
||||
li
|
||||
@@ -79,9 +79,85 @@ impl TripPackageListRow {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TripPackageListCategoryBlock;
|
||||
pub struct TripPackageListRowUnready;
|
||||
|
||||
impl TripPackageListCategoryBlock {
|
||||
impl TripPackageListRowUnready {
|
||||
pub fn build(trip_id: Uuid, item: &models::trips::TripItem) -> Markup {
|
||||
html!(
|
||||
li
|
||||
."flex"
|
||||
."flex-row"
|
||||
."justify-between"
|
||||
."items-stretch"
|
||||
."bg-green-50"[item.ready]
|
||||
."bg-red-50"[!item.ready]
|
||||
."hover:bg-white"[!item.ready]
|
||||
."h-full"
|
||||
{
|
||||
span
|
||||
."p-2"
|
||||
{
|
||||
(item.item.name)
|
||||
}
|
||||
@if item.ready {
|
||||
a
|
||||
href={
|
||||
"/trips/" (trip_id)
|
||||
"/items/" (item.item.id)
|
||||
"/unready"
|
||||
}
|
||||
hx-post={
|
||||
"/trips/" (trip_id)
|
||||
"/packagelist/item/"
|
||||
(item.item.id) "/unready"
|
||||
}
|
||||
hx-target="closest li"
|
||||
hx-swap="outerHTML"
|
||||
."flex"
|
||||
."flex-row"
|
||||
."aspect-square"
|
||||
{
|
||||
span
|
||||
."mdi"
|
||||
."m-auto"
|
||||
."text-xl"
|
||||
."mdi-check"
|
||||
{}
|
||||
}
|
||||
} @else {
|
||||
a
|
||||
href={
|
||||
"/trips/" (trip_id)
|
||||
"/items/" (item.item.id)
|
||||
"/ready"
|
||||
}
|
||||
hx-post={
|
||||
"/trips/" (trip_id)
|
||||
"/packagelist/item/"
|
||||
(item.item.id) "/ready"
|
||||
}
|
||||
hx-target="closest li"
|
||||
hx-swap="outerHTML"
|
||||
."flex"
|
||||
."flex-row"
|
||||
."aspect-square"
|
||||
{
|
||||
span
|
||||
."mdi"
|
||||
."m-auto"
|
||||
."text-xl"
|
||||
."mdi-checkbox-blank-outline"
|
||||
{}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TripPackageListCategoryBlockReady;
|
||||
|
||||
impl TripPackageListCategoryBlockReady {
|
||||
pub fn build(trip: &models::trips::Trip, category: &models::trips::TripCategory) -> Markup {
|
||||
let empty = !category
|
||||
.items
|
||||
@@ -125,8 +201,8 @@ impl TripPackageListCategoryBlock {
|
||||
."flex"
|
||||
."flex-col"
|
||||
{
|
||||
@for item in category.items.as_ref().unwrap() {
|
||||
(TripPackageListRow::build(trip.id, item))
|
||||
@for item in category.items.as_ref().unwrap().iter().filter(|item| item.picked) {
|
||||
(TripPackageListRowReady::build(trip.id, item))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,6 +211,61 @@ impl TripPackageListCategoryBlock {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TripPackageListCategoryBlockUnready;
|
||||
|
||||
impl TripPackageListCategoryBlockUnready {
|
||||
pub fn build(trip: &models::trips::Trip, category: &models::trips::TripCategory) -> Markup {
|
||||
let empty = !category
|
||||
.items
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|item| item.picked);
|
||||
|
||||
html!(
|
||||
div
|
||||
."inline-block"
|
||||
."w-full"
|
||||
."mb-5"
|
||||
."border"
|
||||
."border-2"
|
||||
."border-gray-300"
|
||||
."opacity-30"[empty]
|
||||
{
|
||||
div
|
||||
."bg-gray-100"
|
||||
."border-b-2"
|
||||
."border-gray-300"
|
||||
."p-3"
|
||||
{
|
||||
h3 { (category.category.name) }
|
||||
}
|
||||
@if empty {
|
||||
div
|
||||
."flex"
|
||||
."p-1"
|
||||
{
|
||||
span
|
||||
."text-sm"
|
||||
."m-auto"
|
||||
{
|
||||
"no items picked"
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
ul
|
||||
."flex"
|
||||
."flex-col"
|
||||
{
|
||||
@for item in category.items.as_ref().unwrap().iter().filter(|item| item.picked) {
|
||||
(TripPackageListRowUnready::build(trip.id, item))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
pub struct TripPackageList;
|
||||
|
||||
impl TripPackageList {
|
||||
@@ -147,6 +278,14 @@ impl TripPackageList {
|
||||
// .iter()
|
||||
// .all(|item| !item.picked || item.packed)
|
||||
// });
|
||||
let has_unready_items: bool = trip.categories.as_ref().unwrap().iter().any(|category| {
|
||||
category
|
||||
.items
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|item| item.picked && !item.ready)
|
||||
});
|
||||
html!(
|
||||
div
|
||||
."p-8"
|
||||
@@ -183,12 +322,25 @@ impl TripPackageList {
|
||||
"Finish packing"
|
||||
}
|
||||
}
|
||||
div
|
||||
."columns-3"
|
||||
."gap-5"
|
||||
{
|
||||
@for category in trip.categories() {
|
||||
(TripPackageListCategoryBlock::build(trip, category))
|
||||
@if has_unready_items {
|
||||
p { "There are items that are not yet ready, get them!"}
|
||||
div
|
||||
."columns-3"
|
||||
."gap-5"
|
||||
{
|
||||
@for category in trip.categories() {
|
||||
(TripPackageListCategoryBlockUnready::build(trip, category))
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
p { "All items are ready, pack the following things:" }
|
||||
div
|
||||
."columns-3"
|
||||
."gap-5"
|
||||
{
|
||||
@for category in trip.categories() {
|
||||
(TripPackageListCategoryBlockReady::build(trip, category))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user