use crate::RecordId;
use crate::components::{Alert, AlertSeverity};
use crate::order::list::OrderSideBarWrapper;
use leptos::prelude::*;
use leptos_router::hooks::use_params_map;
use super::order_details::OrderDetails;
use crate::order::order_model::OrderFull;
#[server]
pub async fn fetch_user_order(order_id: RecordId) -> Result<OrderFull, ServerFnError> {
let user = crate::session::get_user().await?;
let db = crate::db::db_init().await?;
if order_id.table().to_string() != "order" {
return Err(ServerFnError::ServerError("Invalid order ID".into()));
}
let mut order_req = match user.is_admin {
Some(true) => {
db.query(
r#"
SELECT *,
user.* as user_full,
user.* as delivery_details,
(SELECT * from only payments WHERE order = $parent.id LIMIT 1) as payment
FROM ONLY $order_id
LIMIT 1;
"#,
)
.bind(("order_id", order_id))
.await?
}
_ => {
db.query(
r#"
SELECT *,
user.* as user_full,
user.* as delivery_details,
(SELECT * from only payments WHERE order = $parent.id LIMIT 1) as payment
FROM ONLY $order_id
WHERE user = $user_id
LIMIT 1;
"#,
)
.bind(("order_id", order_id))
.bind(("user_id", user.id))
.await?
}
};
let order: Option<OrderFull> = order_req.take(0)?;
let order: OrderFull = match order {
Some(o) => o,
None => return Err(ServerFnError::ServerError("Order not found".into())),
};
Ok(order)
}
#[server]
pub async fn fetch_admin_order(order_id: String) -> Result<OrderFull, ServerFnError> {
let user = crate::session::get_user().await?;
if user.is_admin != Some(true) {
return Err(ServerFnError::ServerError("Unauthorized".into()));
}
let db = crate::db::db_init().await?;
let mut order_req = db
.query("SELECT * FROM type::thing('order', $order_id) FETCH items, user;")
.bind(("order_id", order_id))
.await?;
let orders = order_req.take::<Vec<OrderFull>>(0)?;
if orders.is_empty() {
return Err(ServerFnError::ServerError("Order not found".into()));
}
Ok(orders[0].clone())
}
#[server]
pub async fn update_order_admin(order: OrderFull) -> Result<(), ServerFnError> {
let user = crate::session::get_user().await?;
if user.is_admin != Some(true) {
return Err(ServerFnError::ServerError("Unauthorized".into()));
}
let db = crate::db::db_init().await?;
let _: Option<OrderFull> = db
.update(("order", order.id.key().to_string()))
.content(serde_json::json!({
"courier": order.courier,
"tracking_number": order.tracking_number,
"shipped": order.shipped,
"client_received": order.client_received,
"done": order.done,
}))
.await?;
Ok(())
}
#[component]
pub fn UserOrderView() -> impl IntoView {
let params = use_params_map();
let order_id = move || params.read().get("order_id").unwrap_or_default();
let order_resource = Resource::new(
move || {
let key = order_id();
let out: RecordId = RecordId::from_table_key("order", &key);
out
},
fetch_user_order,
);
view! {
<Suspense fallback=move || {
view! {
<div class="">
<div class="text-center text-neutral-500 dark:text-neutral-400">
"Loading order..."
</div>
</div>
}
}>
{move || {
order_resource
.get()
.map(|order_result| {
match order_result {
Ok(order) => {
view! { <OrderDetails order=order is_admin=false /> }.into_any()
}
Err(err) => {
view! {
<Alert severity=AlertSeverity::Error>
"Error loading order: " {err.to_string()}
</Alert>
}
.into_any()
}
}
})
}}
</Suspense>
}
}
#[component]
pub fn OrderUserPage() -> impl IntoView {
view! {
<OrderSideBarWrapper>
<UserOrderView />
</OrderSideBarWrapper>
}
}