From 34fbc2f3de71873e15358a9fcc3aaefdb8225b29 Mon Sep 17 00:00:00 2001 From: Antoine Pelletier Date: Mon, 24 Aug 2026 13:02:01 +0200 Subject: [PATCH] feat: public calendar --- .cargo/config.toml | 12 + .gitignore | 3 +- .../src/components/admin/ReservationCard.vue | 4 +- .../{admin => reservation}/BikeCalendar.vue | 40 +- .../reservation/ReservationDetails.vue | 10 +- frontend/src/lib/api.d.ts | 1803 +++++++++-------- frontend/src/locales/en.yml | 28 +- frontend/src/locales/fr.yml | 28 +- frontend/src/services/api/reservations.ts | 19 + frontend/src/utils/types.ts | 10 + frontend/src/views/AdminView.vue | 2 +- frontend/src/views/CalendarView.vue | 26 +- src/api/reservations.rs | 37 +- src/core/controller/reservations.rs | 24 +- src/core/models/reservation.rs | 27 + 15 files changed, 1135 insertions(+), 938 deletions(-) create mode 100644 .cargo/config.toml rename frontend/src/components/{admin => reservation}/BikeCalendar.vue (86%) diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..39e7df8 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,12 @@ +# Development overrides for the app configuration. `cargo run` and `cargo test` +# inject these into the process environment; the `config` crate reads them last, +# so they win over `config.yml` without it having to be edited. +# +# The `cargagep` client exists on Hydra but has no matching redirect uri, so we +# borrow the one registered for `trust`. Drop this file once `cargagep` is +# properly registered and `config.yml` takes over again. +# +# `force = false`: a value given on the command line still takes precedence, +# APP__OIDC__CLIENT_ID=other cargo run +[env] +APP__OIDC__CLIENT_ID = { value = "trust", force = false } diff --git a/.gitignore b/.gitignore index d2ecd1b..e16256e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target config.yml config.yaml -/LEGACY \ No newline at end of file +/LEGACY +summary.ai \ No newline at end of file diff --git a/frontend/src/components/admin/ReservationCard.vue b/frontend/src/components/admin/ReservationCard.vue index 1b16225..25e714e 100644 --- a/frontend/src/components/admin/ReservationCard.vue +++ b/frontend/src/components/admin/ReservationCard.vue @@ -24,7 +24,9 @@ const setStatus = useSetReservationStatus() /** Kept in step with the state machine drawn on the backend enum */ const TRANSITIONS: Record = { requested: ['approved', 'refused'], - approved: ['ongoing', 'cancelled'], + // No "start" here on purpose: a reservation becomes `ongoing` on its own, not + // by an admin pressing a button. The backend still allows the transition. + approved: ['cancelled'], ongoing: ['archived', 'cancelled'], refused: [], cancelled: [], diff --git a/frontend/src/components/admin/BikeCalendar.vue b/frontend/src/components/reservation/BikeCalendar.vue similarity index 86% rename from frontend/src/components/admin/BikeCalendar.vue rename to frontend/src/components/reservation/BikeCalendar.vue index 17e19df..c0969d0 100644 --- a/frontend/src/components/admin/BikeCalendar.vue +++ b/frontend/src/components/reservation/BikeCalendar.vue @@ -21,15 +21,19 @@ import { DialogTitle, } from '@/components/ui/dialog' import { Badge } from '@/components/ui/badge' -import { unitLabel, type Bike, type Reservation } from '@/utils/types' +import { unitLabel, type Bike, type CalendarReservation } from '@/utils/types' -const props = defineProps<{ reservations: Reservation[]; bikes: Bike[] }>() +// Takes the narrow shape the public calendar receives; a full `Reservation` +// satisfies it too, so the admin page keeps passing its own list unchanged. +const props = defineProps<{ reservations: CalendarReservation[]; bikes: Bike[] }>() const { locale } = useI18n() -const FIRST_HOUR = 7 -const LAST_HOUR = 20 -const HOUR_HEIGHT = 44 +// The whole day, 00:00 to 23:59. 24 rows at 44px would make the card very tall, +// hence the shorter row. +const FIRST_HOUR = 0 +const LAST_HOUR = 24 +const HOUR_HEIGHT = 32 const weekStart = ref(startOfWeek(new Date())) const selectedBike = ref('all') @@ -140,18 +144,18 @@ function blocksFor(day: Date, bike: Bike): Block[] {
- {{ $t('admin.calendar.title') }} - {{ $t('admin.calendar.intro') }} + {{ $t('calendar.title') }} + {{ $t('calendar.intro') }}
- {{ $t('admin.calendar.bike') }} + {{ $t('calendar.bike') }}