working card for existing reservation
This commit is contained in:
@@ -27,6 +27,8 @@ manage-courts = Courts
|
|||||||
back-to-calendar = Back to calendar
|
back-to-calendar = Back to calendar
|
||||||
add-booking = New Booking
|
add-booking = New Booking
|
||||||
edit-booking = Edit Booking
|
edit-booking = Edit Booking
|
||||||
|
booking-details = Booking details
|
||||||
|
edit = Edit
|
||||||
date = Date
|
date = Date
|
||||||
hour = Hour
|
hour = Hour
|
||||||
booking-color = Colour
|
booking-color = Colour
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ manage-courts = Kurty
|
|||||||
back-to-calendar = Späť na kalendár
|
back-to-calendar = Späť na kalendár
|
||||||
add-booking = Nová rezervácia
|
add-booking = Nová rezervácia
|
||||||
edit-booking = Upraviť rezerváciu
|
edit-booking = Upraviť rezerváciu
|
||||||
|
booking-details = Detail rezervácie
|
||||||
|
edit = Upraviť
|
||||||
date = Dátum
|
date = Dátum
|
||||||
hour = Hodina
|
hour = Hodina
|
||||||
booking-color = Farba
|
booking-color = Farba
|
||||||
|
|||||||
58
ht_booking/assets/views/admin/booking_detail.html
Normal file
58
ht_booking/assets/views/admin/booking_detail.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ t(key="booking-details", lang=lang) }}{% endblock title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="mx-auto max-w-md">
|
||||||
|
<div class="mb-4 flex items-center justify-between">
|
||||||
|
<h1 class="text-2xl font-bold">{{ t(key="booking-details", lang=lang) }}</h1>
|
||||||
|
<a href="/admin?court={{ court_id }}&week={{ date }}" class="btn btn-ghost btn-sm">« {{ t(key="back-to-calendar", lang=lang) }}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card border border-base-300 bg-base-100 shadow-sm">
|
||||||
|
<div class="card-body gap-0">
|
||||||
|
<dl class="divide-y divide-base-300">
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="court-label", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{{ court_name }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="date", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{{ date_label }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="hour", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{{ hour_label }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="booking-color", lang=lang) }}</dt>
|
||||||
|
<dd class="flex items-center gap-2">
|
||||||
|
<span class="inline-block h-5 w-8 rounded border border-base-300" style="background-color: {{ color }}"></span>
|
||||||
|
<span class="text-sm font-medium">{{ color }}</span>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="booking-name", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{{ name }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="booking-title", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{% if title %}{{ title }}{% else %}<span class="opacity-40">—</span>{% endif %}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="booking-contact", lang=lang) }}</dt>
|
||||||
|
<dd class="text-right text-sm font-medium">{% if contact %}{{ contact }}{% else %}<span class="opacity-40">—</span>{% endif %}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between gap-4 py-2">
|
||||||
|
<dt class="text-sm opacity-70">{{ t(key="booking-note", lang=lang) }}</dt>
|
||||||
|
<dd class="whitespace-pre-line text-right text-sm font-medium">{% if note %}{{ note }}{% else %}<span class="opacity-40">—</span>{% endif %}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
<div class="flex items-center gap-2 pt-4">
|
||||||
|
<a href="/admin/booking/{{ booking_id }}/edit" class="btn btn-neutral">{{ t(key="edit", lang=lang) }}</a>
|
||||||
|
<a href="/admin?court={{ court_id }}&week={{ date }}" class="btn btn-ghost">{{ t(key="back-to-calendar", lang=lang) }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
@@ -421,6 +421,50 @@ pub async fn booking_create(
|
|||||||
Ok(Redirect::to(&format!("/admin?court={}&week={}", form.court_id, form.date)).into_response())
|
Ok(Redirect::to(&format!("/admin?court={}&week={}", form.court_id, form.date)).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read-only detail card for an existing booking. Clicking a booking in the
|
||||||
|
/// calendar lands here first, so a stray click can never change anything; the
|
||||||
|
/// card's "Edit" button is the only way through to the editable form.
|
||||||
|
#[debug_handler]
|
||||||
|
pub async fn booking_view(
|
||||||
|
_auth: AdminAuth,
|
||||||
|
ViewEngine(v): ViewEngine<TeraView>,
|
||||||
|
State(ctx): State<AppContext>,
|
||||||
|
jar: CookieJar,
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
) -> Result<Response> {
|
||||||
|
let lang = current_lang(&jar);
|
||||||
|
let booking = bookings::Entity::find_by_id(id)
|
||||||
|
.one(&ctx.db)
|
||||||
|
.await?
|
||||||
|
.ok_or(Error::NotFound)?;
|
||||||
|
let court_name = courts::Entity::find_by_id(booking.court_id)
|
||||||
|
.one(&ctx.db)
|
||||||
|
.await?
|
||||||
|
.and_then(|c| c.name)
|
||||||
|
.unwrap_or_else(|| format!("Court {}", booking.court_id));
|
||||||
|
|
||||||
|
format::render().view(
|
||||||
|
&v,
|
||||||
|
"admin/booking_detail.html",
|
||||||
|
data!({
|
||||||
|
"lang": lang,
|
||||||
|
"is_admin": true,
|
||||||
|
"logged_in": true,
|
||||||
|
"court_id": booking.court_id,
|
||||||
|
"court_name": court_name,
|
||||||
|
"date": booking.date.format("%Y-%m-%d").to_string(),
|
||||||
|
"date_label": booking.date.format("%d %b %Y").to_string(),
|
||||||
|
"hour_label": format!("{:02}:00 – {:02}:00", booking.hour, booking.hour + 1),
|
||||||
|
"color": booking.color,
|
||||||
|
"name": booking.name,
|
||||||
|
"title": booking.title.unwrap_or_default(),
|
||||||
|
"contact": booking.contact.unwrap_or_default(),
|
||||||
|
"note": booking.note.unwrap_or_default(),
|
||||||
|
"booking_id": id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
#[debug_handler]
|
||||||
pub async fn booking_edit(
|
pub async fn booking_edit(
|
||||||
_auth: AdminAuth,
|
_auth: AdminAuth,
|
||||||
@@ -515,7 +559,8 @@ pub fn routes() -> Routes {
|
|||||||
.add("/courts/{id}/delete", post(delete_court))
|
.add("/courts/{id}/delete", post(delete_court))
|
||||||
.add("/booking", get(booking_new))
|
.add("/booking", get(booking_new))
|
||||||
.add("/booking", post(booking_create))
|
.add("/booking", post(booking_create))
|
||||||
.add("/booking/{id}", get(booking_edit))
|
.add("/booking/{id}", get(booking_view))
|
||||||
|
.add("/booking/{id}/edit", get(booking_edit))
|
||||||
.add("/booking/{id}", post(booking_update))
|
.add("/booking/{id}", post(booking_update))
|
||||||
.add("/booking/{id}/delete", post(booking_delete))
|
.add("/booking/{id}/delete", post(booking_delete))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user