From e15bbf0b15867fea32e5d1226c821cfb3198ef4c Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 29 Jun 2023 18:01:09 +0200 Subject: [PATCH] (feat) re-make event reservation item view --- .../events/event-reservation-item.tsx | 97 +++++++++++++++++++ .../src/javascript/models/reservation.ts | 30 +++++- .../templates/admin/members/edit.html | 38 ++------ app/frontend/templates/dashboard/events.html | 42 ++------ app/views/api/members/show.json.jbuilder | 4 + config/locales/app.logged.en.yml | 12 +++ config/locales/app.logged.fr.yml | 12 +++ 7 files changed, 170 insertions(+), 65 deletions(-) create mode 100644 app/frontend/src/javascript/components/events/event-reservation-item.tsx diff --git a/app/frontend/src/javascript/components/events/event-reservation-item.tsx b/app/frontend/src/javascript/components/events/event-reservation-item.tsx new file mode 100644 index 000000000..cc3cc89e3 --- /dev/null +++ b/app/frontend/src/javascript/components/events/event-reservation-item.tsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { react2angular } from 'react2angular'; +import { Reservation } from '../../models/reservation'; +import FormatLib from '../../lib/format'; +import { IApplication } from '../../models/application'; + +declare const Application: IApplication; + +interface EventReservationItemProps { + reservation: Reservation; +} + +/** + * event reservation item component + */ +export const EventReservationItem: React.FC = ({ reservation }) => { + const { t } = useTranslation('logged'); + + /** + * Return the formatted localized date of the event + */ + const formatDate = (): string => { + return `${FormatLib.date(reservation.start_at)} ${FormatLib.time(reservation.start_at)} - ${FormatLib.time(reservation.end_at)}`; + }; + + /** + * Build the ticket for event price category user reservation + */ + const buildTicket = (ticket) => { + return ( + <> +
{t('app.logged.event_reservation_item.NUMBER_of_NAME_places_reserved', { NUMBER: ticket.booked, NAME: ticket.price_category.name })}
+ {reservation.booking_users_attributes.filter(u => u.event_price_category_id === ticket.event_price_category_id).map(u => { + return ( +
{u.name}
+ ); + })} + + ); + }; + + /** + * Return the pre-registration status + */ + const preRegistrationStatus = () => { + if (!reservation.validated_at && !reservation.canceled_at && !reservation.is_paid) { + return t('app.logged.event_reservation_item.in_the_process_of_validation'); + } else if (reservation.validated_at && !reservation.canceled_at && !reservation.is_paid) { + return t('app.logged.event_reservation_item.settle_your_payment'); + } else if (reservation.is_paid && !reservation.canceled_at) { + return t('app.logged.event_reservation_item.paid'); + } else if (reservation.canceled_at) { + return t('app.logged.event_reservation_item.paid'); + } + }; + + return ( +
+
+
{t('app.logged.event_reservation_item.event')}
+
{reservation.event_title}
+ {reservation.event_type === 'family' && + {t('app.logged.event_reservation_item.family')} + } + {reservation.event_type === 'nominative' && + {t('app.logged.event_reservation_item.nominative')} + } + {reservation.event_pre_registration && + {t('app.logged.event_reservation_item.pre_registration')} + } + {formatDate()} +
+
+
+
{t('app.logged.event_reservation_item.NUMBER_normal_places_reserved', { NUMBER: reservation.nb_reserve_places })}
+ {reservation.booking_users_attributes.filter(u => !u.event_price_category_id).map(u => { + return ( +
{u.name}
+ ); + })} + {reservation.tickets.map(ticket => { + return buildTicket(ticket); + })} +
+ {reservation.event_pre_registration && +
+
{t('app.logged.event_reservation_item.tracking_your_reservation')}
+ {preRegistrationStatus()} +
+ } +
+
+ ); +}; + +Application.Components.component('eventReservationItem', react2angular(EventReservationItem, ['reservation'])); diff --git a/app/frontend/src/javascript/models/reservation.ts b/app/frontend/src/javascript/models/reservation.ts index db950a40d..f5abfe7b9 100644 --- a/app/frontend/src/javascript/models/reservation.ts +++ b/app/frontend/src/javascript/models/reservation.ts @@ -30,7 +30,7 @@ export interface Reservation { name: string }, nb_reserve_places?: number, - tickets_attributes?: { + tickets_attributes?: Array<{ event_price_category_id: number, event_price_category?: { id: number, @@ -40,18 +40,38 @@ export interface Reservation { name: string } }, - booked: boolean, + booked: number, created_at?: TDateISO - }, + }>, + tickets?: Array<{ + event_price_category_id: number, + event_price_category?: { + id: number, + price_category_id: number, + price_category: { + id: number, + name: string + } + }, + booked: number, + created_at?: TDateISO + }>, total_booked_seats?: number, created_at?: TDateISO, - booking_users_attributes?: { + booking_users_attributes?: Array<{ id: number, name: string, event_price_category_id: number, booked_id: number, booked_type: string, - } + }>, + start_at: TDateISO, + end_at: TDateISO, + event_type?: string, + event_title?: string, + event_pre_registration?: boolean + validated_at?: TDateISO, + is_paid?: boolean, } export interface ReservationIndexFilter extends ApiFilter { diff --git a/app/frontend/templates/admin/members/edit.html b/app/frontend/templates/admin/members/edit.html index 752bffe3a..287a61911 100644 --- a/app/frontend/templates/admin/members/edit.html +++ b/app/frontend/templates/admin/members/edit.html @@ -207,29 +207,11 @@

{{ 'app.admin.members_edit.next_events' | translate }}

-
    -
  • - {{r.reservable.title}} - {{ r.start_at | amDateFormat:'LLL' }} - {{ r.end_at | amDateFormat:'LT' }} - -
    - {{ 'app.admin.members_edit.NUMBER_full_price_tickets_reserved' }} - -
    - {{bu.name}} - {{bu.name}} -
    -
    - -
    - {{ 'app.admin.members_edit.NUMBER_NAME_tickets_reserved' }} - -
    - {{bu.name}} - {{bu.name}} -
    -
    -
  • -
+
+
+ +
+
{{ 'app.admin.members_edit.no_upcoming_events' }}
@@ -240,11 +222,11 @@

{{ 'app.admin.members_edit.passed_events' | translate }}

-
    -
  • - {{r.reservable.title}} - {{ r.start_at | amDateFormat:'LLL' }} - {{ r.end_at | amDateFormat:'LT' }} -
  • -
+
+
+ +
+
{{ 'app.admin.members_edit.no_passed_events' }}
diff --git a/app/frontend/templates/dashboard/events.html b/app/frontend/templates/dashboard/events.html index 9af91bd8f..c632dafa8 100644 --- a/app/frontend/templates/dashboard/events.html +++ b/app/frontend/templates/dashboard/events.html @@ -16,33 +16,11 @@

{{ 'app.logged.dashboard.events.your_next_events' | translate }}

-
    -
  • - {{r.reservable.title}} - - - {{ r.start_at | amDateFormat:'LLL' }} - {{ r.end_at | amDateFormat:'LT' }} -
    - - {{ 'app.logged.dashboard.events.NUMBER_normal_places_reserved' }} - - -
    - {{bu.name}} -
    - -
    - - {{ 'app.logged.dashboard.events.NUMBER_of_NAME_places_reserved' }} - - -
    - {{bu.name}} -
    -
    -
  • -
+
+
+ +
+
{{ 'app.logged.dashboard.events.no_events_to_come' }}
@@ -53,11 +31,11 @@

{{ 'app.logged.dashboard.events.your_previous_events' | translate }}

-
    -
  • - {{r.reservable.title}} - {{ r.start_at | amDateFormat:'LLL' }} - {{ r.end_at | amDateFormat:'LT' }} -
  • -
+
+
+ +
+
{{ 'app.logged.dashboard.events.no_passed_events' }}
diff --git a/app/views/api/members/show.json.jbuilder b/app/views/api/members/show.json.jbuilder index 051b19718..28bdadf3f 100644 --- a/app/views/api/members/show.json.jbuilder +++ b/app/views/api/members/show.json.jbuilder @@ -85,6 +85,10 @@ json.events_reservations @member.reservations.where(reservable_type: 'Event').jo json.reservable sr.reservation.reservable json.reservable_type 'Event' json.event_type sr.reservation.reservable.event_type + json.event_title sr.reservation.reservable.title + json.event_pre_registration sr.reservation.reservable.pre_registration + json.validated_at sr.validated_at + json.is_paid sr.reservation.invoice_items.count.positive? json.canceled_at sr.canceled_at json.booking_users_attributes sr.reservation.booking_users.order(booked_type: :desc) do |bu| json.id bu.id diff --git a/config/locales/app.logged.en.yml b/config/locales/app.logged.en.yml index f284fbc5d..8698bc923 100644 --- a/config/locales/app.logged.en.yml +++ b/config/locales/app.logged.en.yml @@ -37,6 +37,18 @@ en: edit_profile: "Change my data" after_edition_info_html: "Once your data are up to date, click on the synchronization button below, or disconnect then reconnect for your changes to take effect." sync_profile: "Sync my profile" + event_reservation_item: + event: "Event" + family: "Family" + nominative: "Nominative" + pre_registration: "Pre-registration" + NUMBER_normal_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{normal place reserved} other{normal places reserved}}" + NUMBER_of_NAME_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{of {NAME} place reserved} other{of {NAME} places reserved}}" + tracking_your_reservation: "Tracking your reservation" + in_the_process_of_validation: "In the process of validation" + settle_your_payment: "Come to the reception desk to settle" + paid: "Paid" + canceled: "Canceled" dashboard: #dashboard: public profile profile: diff --git a/config/locales/app.logged.fr.yml b/config/locales/app.logged.fr.yml index 24550f9d1..f9a41a3e9 100644 --- a/config/locales/app.logged.fr.yml +++ b/config/locales/app.logged.fr.yml @@ -37,6 +37,18 @@ fr: edit_profile: "Modifier mes données" after_edition_info_html: "Une fois que vos données sont à jour, cliquez sur le bouton de synchronisation ci-dessous, ou déconnectez-vous puis reconnectez-vous pour que vos changements prennent effet." sync_profile: "Synchroniser mon profil" + event_reservation_item: + event: 'Événement' + family: 'Famille' + nominative: 'Nominatif' + pre_registration: 'Pré-inscription' + NUMBER_normal_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{place normale réservée} other{places normales réservées}}" + NUMBER_of_NAME_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{place {NAME} réservée} other{places {NAME} réservées}}" + tracking_your_reservation: "Suivi de votre réservation" + in_the_process_of_validation: "En cours de validation" + settle_your_payment: "Venez régler à l'accueil" + paid: "Payé" + canceled: "Annulé" dashboard: #dashboard: public profile profile: