diff --git a/frontend-changes.md b/frontend-changes.md index 275e357..602ea70 100644 --- a/frontend-changes.md +++ b/frontend-changes.md @@ -1,248 +1,363 @@ -# Frontend Changes - User Reservation Form +# Frontend Changes - Liberatorie Feature ## Overview -This document describes the frontend changes implemented for the new user reservation form feature. This feature allows logged-in users to submit reservations (Prenotazione) with their personal data automatically loaded from their UtenteApp profile. +This document describes the frontend changes made to implement the "Liberatorie" (waivers) feature in the user booking form. This feature allows users to view and accept required waivers associated with facilities before submitting a booking. -## Files Created +## Date -### 1. `src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue` - -**Purpose**: Vue template for the user reservation form. - -**Features**: - -- Responsive form layout using Bootstrap grid system -- Two main sections: Booking Details and User Data -- Booking Details section includes: - - Date/time inputs (oraInizio, oraFine) using `datetime-local` HTML5 input type - - Disabled stato field pre-set to "RICHIESTA" - - Required struttura dropdown selection - - Optional fields: motivoEvento, numeroPartecipanti, noteUtente -- User Data section displays: - - Personal information (nome, cognome, luogoNascita, dataNascita, residente) in read-only format - - Radio button toggle between "privato" and "societa" user types - - Conditional display of company data when "societa" is selected -- Form validation with visual feedback -- Submit and Reset action buttons with proper disabled states -- Loading spinner while fetching initial data - -**Location**: `/prenotazione/nuova` route - -### 2. `src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts` - -**Purpose**: TypeScript component logic using Vue 3 Composition API. - -**Key Features**: - -- Reactive state management with refs: - - `prenotazione`: Form data model - - `currentUser`: Current logged-in user's UtenteApp data - - `userType`: Radio button state ('privato' or 'societa') - - `strutturas`: Available facilities list - - `isSaving`: Form submission state - - `isLoading`: Initial data loading state -- Services integration: - - PrenotazioneService: For creating reservations - - UtenteAppService: For fetching current user data - - StrutturaService: For loading facilities list - - AlertService: For displaying success/error messages -- Form validation using Vuelidate with required validation on struttura field -- `initData()`: Fetches current user and struttura list on component mount -- `save()`: Validates and submits the reservation form -- `resetForm()`: Clears form data while preserving user information -- Date/time handling using `useDateFormat` composable -- Automatic initialization of stato field to "RICHIESTA" -- Automatic assignment of current user to prenotazione.utente - -**Dependencies**: - -- Vue 3 (Composition API) -- Vuelidate (form validation) -- Vue Router (navigation) -- Vue I18n (internationalization) +2025-12-12 ## Files Modified -### 3. `src/main/webapp/app/entities/utente-app/utente-app.service.ts` +### 1. TypeScript Component -**Changes**: Added `getCurrentUser()` method. +**File:** `src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts` -**Method Signature**: +#### Changes Made: + +**Imports Added (lines 10-18):** + +- `LiberatoriaService` - Service for managing waiver acceptances +- `ModelloLiberatoriaService` - Service for managing waiver templates +- `ILiberatoria` and `Liberatoria` - Liberatoria model interface and class +- `IModelloLiberatoria` - ModelloLiberatoria model interface + +**Service Injections Added (lines 40-47):** + +- `liberatoriaService` - Injected service for Liberatoria CRUD operations +- `modelloLiberatoriaService` - Injected service for ModelloLiberatoria CRUD operations +- `modelloLiberatorias` - Ref array to store all waiver templates +- `userLiberatorias` - Ref array to store user's accepted waivers +- `isLoadingLiberatorie` - Ref boolean for loading state +- `selectedModello` - Ref for the currently selected waiver template in modal + +**Computed Properties Added (lines 71-96):** + +- `liberatorieStatus` - Computed property that: + - Filters ModelloLiberatoria by selected struttura + - Maps each template to include acceptance status + - Returns array with structure: `{ modello, liberatoria, isAccepted }` +- `allLiberatorieAccepted` - Computed property that: + - Returns true if no waivers required OR all waivers are accepted + - Used for form validation + +**Data Loading Function Added (lines 98-119):** + +- `loadLiberatorieData()` - Async function that: + - Fetches all ModelloLiberatoria records + - Fetches all Liberatoria records + - Filters Liberatoria by current user ID (client-side filtering) + - Handles loading states and errors + +**initData() Modified (lines 121-142):** + +- Added call to `loadLiberatorieData()` after fetching user and strutture +- Ensures liberatorie data is loaded on component mount + +**Return Statement Updated (lines 155-179):** + +- Added all new refs and computed properties to expose them to the template: + - `liberatoriaService` + - `modelloLiberatoriaService` + - `modelloLiberatorias` + - `userLiberatorias` + - `isLoadingLiberatorie` + - `selectedModello` + - `liberatorieStatus` + - `allLiberatorieAccepted` + +**Methods Added (lines 181-254):** + +1. **`save()` Modified (lines 182-211):** + - Added validation check for liberatorie acceptance + - Blocks form submission if `!allLiberatorieAccepted` + - Shows error message to user if waivers not accepted + +2. **`showLiberatoriaModal()` Added (lines 213-216):** + - Sets selected waiver template + - Opens modal using ref + +3. **`closeLiberatoriaModal()` Added (lines 218-221):** + - Clears selected waiver template + - Closes modal + +4. **`acceptLiberatoria()` Added (lines 223-253):** + - Creates new Liberatoria instance + - Sets `accettata` to current date + - Associates with current user and selected template + - Calls backend API to create record + - Updates local state with new acceptance + - Closes modal and shows success message + - Handles errors gracefully + +--- + +### 2. Vue Template + +**File:** `src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue` + +#### Changes Made: + +**Liberatorie Section Added (lines 223-273):** + +- New card section with title "Liberatorie" +- Conditional rendering based on `v-if="prenotazione.struttura"` - only shows when facility is selected +- Three states handled: + 1. **Loading State** (lines 229-233): Shows spinner while fetching data + 2. **No Waivers State** (lines 235-237): Shows info alert when no waivers required + 3. **Waivers List State** (lines 239-266): Displays list of waivers with: + - Green badge + check icon for accepted waivers + - Yellow badge + warning icon for pending waivers + - Clickable link to open modal for pending waivers + - Acceptance date for accepted waivers (formatted in Italian) +- Warning alert (lines 268-271): Shows when not all waivers are accepted + +**Modal Added (lines 290-337):** + +- Bootstrap Vue modal with ref `liberatoriaModal` +- Large size (`size="lg"`) +- Closes on hidden event +- **Modal Header (lines 292-294):** + - Displays waiver template name +- **Modal Body (lines 296-326):** + - Shows waiver text in bordered container with pre-wrap formatting (lines 298-303) + - Download button for attached document if present (lines 305-316) + - Acceptance statement with user's full name (lines 318-325) + - Italian text: "Il sottoscritto {nome} {cognome} presa visione della documentazione proposta accetta le condizioni ivi indicate" +- **Modal Footer (lines 328-336):** + - Cancel button - closes modal + - Accept button - calls `acceptLiberatoria()` method + - Both buttons disabled during save operation + +**Submit Button Updated (line 281):** + +- Added `!allLiberatorieAccepted` to disabled condition +- Button now disabled if: validation fails OR saving OR not all waivers accepted + +--- + +### 3. Internationalization + +**File:** `src/main/webapp/i18n/it/prenotazione.json` + +#### Changes Made: + +**New Translation Keys Added (lines 41-46):** + +- `liberatorie`: "Liberatorie" - Section title +- `noLiberatorieRequired`: "Nessuna liberatoria richiesta per questa struttura" - Info message +- `liberatorieWarning`: "È necessario accettare tutte le liberatorie richieste prima di inviare la prenotazione" - Warning message +- `liberatorieRequired`: "Devi accettare tutte le liberatorie richieste" - Error message +- `acceptanceStatement`: "Dichiarazione di accettazione" - Modal acceptance statement label +- `accept`: "Accetta" - Accept button text + +--- + +## Feature Functionality + +### User Flow + +1. **User navigates to new booking form** (`/prenotazione/nuova`) +2. **Form loads with existing sections:** + - Booking Details (struttura selection, dates, participants, etc.) + - User Data (personal information display) +3. **User selects a facility (struttura)** +4. **Liberatorie section appears** (if facility has associated waivers) +5. **System displays waiver status:** + - ✅ Green check = already accepted + - ⚠️ Warning icon + clickable link = pending acceptance +6. **User clicks on pending waiver link** +7. **Modal opens showing:** + - Waiver name + - Waiver text content + - Document download link (if available) + - Acceptance statement with user's name +8. **User clicks "Accetta" button** +9. **System creates Liberatoria record** with: + - Current timestamp (`accettata`) + - User reference + - Waiver template reference +10. **Modal closes automatically** +11. **Liberatorie section updates** - waiver now shows as accepted +12. **User can submit form** once all waivers are accepted + +### Validation Logic + +**Form submission is blocked if:** + +- Standard Vuelidate validation fails (struttura is required) +- Not all required waivers are accepted (`!allLiberatorieAccepted`) + +**Visual feedback:** + +- Submit button is disabled when waivers are pending +- Warning alert appears in Liberatorie section +- Error message shown if user attempts to submit without all acceptances + +### Data Management + +**Client-Side Filtering:** + +- All ModelloLiberatoria records fetched on load +- All user's Liberatoria records fetched on load +- Filtered in `liberatorieStatus` computed property based on selected struttura + +**State Updates:** + +- When waiver is accepted, new Liberatoria is added to `userLiberatorias` array +- Computed property `liberatorieStatus` automatically recalculates +- UI updates reactively without page reload + +**Reactive Behavior:** + +- Changing struttura selection automatically updates displayed waivers +- No additional API calls needed (data is pre-loaded) + +--- + +## Technical Details + +### Dependencies + +- **Services:** LiberatoriaService, ModelloLiberatoriaService +- **Models:** ILiberatoria, Liberatoria, IModelloLiberatoria +- **Vue:** Composition API with ref, computed +- **Bootstrap Vue Next:** b-modal component +- **Vuelidate:** Form validation +- **Font Awesome:** Icons (check, exclamation-triangle, download) + +### API Endpoints Used + +- `GET /api/modello-liberatorias` - Fetch all waiver templates +- `GET /api/liberatorias` - Fetch all waiver acceptances +- `POST /api/liberatorias` - Create new waiver acceptance + +### Data Structures + +**liberatorieStatus (computed property):** ```typescript -getCurrentUser(): Promise +[ + { + modello: IModelloLiberatoria, // Waiver template + liberatoria: ILiberatoria | null, // User's acceptance (null if not accepted) + isAccepted: boolean // True if accepted + }, + ... +] ``` -**Purpose**: Fetches the currently logged-in user's UtenteApp data from the backend endpoint `api/utente-apps/current`. - -**Implementation**: Returns a Promise that resolves with the IUtenteApp data or rejects with an error. - -**Note**: This assumes the backend has implemented the corresponding endpoint. If the endpoint doesn't exist yet, it will need to be created on the backend side. - -### 4. `src/main/webapp/app/router/entities.ts` - -**Changes**: - -- Added import statement for `PrenotazioneFormUser` component (line 19) -- Added new route definition for the user reservation form (lines 147-152) - -**New Route**: +**Liberatoria creation:** ```typescript { - path: 'prenotazione/nuova', - name: 'PrenotazioneFormUser', - component: PrenotazioneFormUser, - meta: { authorities: [Authority.USER] }, + accettata: Date, // Current timestamp + utente: IUtenteApp, // Current user + modelloLiberatoria: IModelloLiberatoria // Selected template } ``` -**Access**: Route is protected and requires USER authority. Accessible at `/prenotazione/nuova`. +--- -### 5. `src/main/webapp/i18n/it/prenotazione.json` +## Performance Considerations -**Changes**: Added `userForm` section with Italian translations (lines 30-41). +### Current Implementation (Client-Side Filtering) -**New Translation Keys**: +- **Advantages:** + - No backend changes required + - Works immediately + - Simple implementation +- **Disadvantages:** + - Fetches ALL ModelloLiberatoria (could be many) + - Fetches ALL Liberatoria (could be thousands) + - Network overhead on initial load + - Client-side filtering overhead -- `userForm.title`: "Nuova Prenotazione" -- `userForm.bookingDetails`: "Dettagli Prenotazione" -- `userForm.userData`: "Dati Utente" -- `userForm.userType`: "Tipo Utente" -- `userForm.privato`: "Privato" -- `userForm.societa`: "Società" -- `userForm.personalData`: "Dati Personali" -- `userForm.companyData`: "Dati Società" -- `userForm.submit`: "Invia Prenotazione" -- `userForm.reset`: "Ripristina" +### Future Optimization (Backend Filtering) -## Usage Instructions +For production environments with large datasets, consider adding backend endpoints: -### Accessing the Form +- `GET /api/modello-liberatorias?strutturaId={id}` - Filter templates by facility +- `GET /api/liberatorias?utenteId={id}` - Filter acceptances by user -1. Log in to the application as a user -2. Navigate to `/prenotazione/nuova` or use the router link: - ```vue - - Nuova Prenotazione - - ``` +--- -### Using the Form +## Edge Cases Handled -1. The form automatically loads your user data from the backend -2. Fill in the booking details: - - Select start date/time (oraInizio) - - Select end date/time (oraFine) - - Select a facility (struttura) - **required field** - - Optionally add: event reason, number of participants, user notes -3. Review your personal data displayed below the form -4. Select user type (Privato/Società) to show/hide company information -5. Click "Invia Prenotazione" to submit or "Ripristina" to reset the form -6. Upon successful submission, you'll be redirected to the reservations list +1. **No Struttura Selected:** Liberatorie section remains hidden +2. **Struttura with No Waivers:** Shows "Nessuna liberatoria richiesta" message +3. **Struttura Changed:** Computed property automatically updates displayed waivers +4. **User Already Accepted Some Waivers:** Shows correct status for each +5. **API Failures:** Error messages displayed via alert service +6. **Modal State Management:** selectedModello cleared on close to prevent stale data +7. **Concurrent Operations:** isSaving flag prevents multiple simultaneous actions -### Form Validation - -- The struttura (facility) field is required -- Form cannot be submitted until a facility is selected -- Visual feedback shows validation state (valid/invalid borders) -- Submit button is disabled when form is invalid or saving - -## Technical Notes - -### State Management - -- Component uses local reactive state (no global store required) -- Form data is bound to `prenotazione` reactive ref -- User type toggle uses `userType` reactive ref - -### Data Flow - -1. Component mounts → `initData()` is called -2. Fetch current user from `api/utente-apps/current` -3. Fetch facilities list from `api/strutturas` -4. Display user data in read-only fields -5. User fills form and submits -6. Validate form with Vuelidate -7. POST to `api/prenotaziones` with PrenotazioneService -8. Show success/error message via AlertService -9. Redirect to reservations list on success - -### Error Handling - -- If current user fetch fails: Display error message and disable form -- If struttura list fetch fails: Display error and disable struttura field -- If form submission fails: Display HTTP error message via AlertService -- All errors are handled gracefully with user-friendly messages - -### Backend Requirements - -The frontend expects the following backend endpoint to exist: - -**Endpoint**: `GET /api/utente-apps/current` - -**Purpose**: Returns the UtenteApp entity for the currently logged-in user. - -**Response**: JSON object matching IUtenteApp interface. - -**Authentication**: Requires authenticated user session. - -If this endpoint doesn't exist yet, it needs to be implemented on the backend. The implementation should: - -1. Get the current authenticated user from Spring Security context -2. Query the UtenteApp repository by username -3. Return the matching UtenteApp entity as JSON - -## Testing Recommendations - -### Manual Testing - -1. Test with a logged-in user who has complete UtenteApp data -2. Test with a user missing some optional fields (nome, cognome, etc.) -3. Test form submission with valid data -4. Test form validation (try submitting without selecting struttura) -5. Test the reset button functionality -6. Test the privato/società radio button toggle -7. Test error scenarios (backend unavailable, invalid data) - -### Edge Cases to Consider - -- User with no UtenteApp record (should show error) -- Empty struttura list (should show appropriate message) -- Network failures during submission -- Very long text in noteUtente field -- Invalid date/time selections +--- ## Browser Compatibility -- Uses HTML5 `datetime-local` input type (supported in modern browsers) -- Falls back to text input in older browsers -- Tested with: Chrome, Firefox, Safari, Edge (recent versions) +- **Date Formatting:** Uses `toLocaleDateString('it-IT')` for Italian date format +- **Modal:** Bootstrap Vue Next modals compatible with modern browsers +- **Icons:** Font Awesome icons render correctly in all modern browsers + +--- + +## Testing Recommendations + +### Manual Testing Checklist + +- [ ] Form loads successfully +- [ ] Liberatorie section hidden when no struttura selected +- [ ] Liberatorie section appears when struttura selected +- [ ] Correct waivers displayed for each struttura +- [ ] Accepted waivers show green check +- [ ] Pending waivers show warning icon and link +- [ ] Clicking pending waiver opens modal +- [ ] Modal displays waiver name, text, and document +- [ ] Acceptance statement shows correct user name +- [ ] Accept button creates Liberatoria +- [ ] Modal closes after acceptance +- [ ] Waiver status updates to accepted +- [ ] Submit button disabled when waivers pending +- [ ] Error message shown when trying to submit without acceptances +- [ ] Form submits successfully when all waivers accepted +- [ ] Changing struttura updates waiver list + +### Integration Testing + +- Test with strutture that have 0, 1, and multiple waivers +- Test with users who have already accepted some waivers +- Test API error scenarios (network failure, server error) +- Test modal close on Escape key +- Test keyboard navigation + +--- + +## Known Limitations + +1. **No Backend Filtering:** All records fetched and filtered client-side +2. **No Date Validation:** ModelloLiberatoria `validoDal`/`validoAl` not currently enforced +3. **No Versioning:** No tracking of which version of waiver was accepted +4. **No Revocation:** Users cannot revoke acceptances +5. **Document Type Assumption:** Download link assumes PDF extension + +--- ## Future Enhancements -Potential improvements for future iterations: +1. **Backend Optimization:** Add filtered query endpoints +2. **Date Validation:** Filter by validity period +3. **Versioning:** Track waiver template versions +4. **Revocation Feature:** Allow users to revoke and re-accept +5. **Document Preview:** Inline PDF viewer +6. **Audit Trail:** Show full acceptance history +7. **Notifications:** Email confirmation of waiver acceptance -1. Add calendar widget for better date/time selection UX -2. Add facility availability checking before submission -3. Show facility details/images when selected -4. Add file upload for additional documents -5. Implement draft saving (auto-save functionality) -6. Add confirmation dialog before submission -7. Show booking conflicts/warnings -8. Add email notification preferences -9. Implement multi-step wizard for complex bookings -10. Add booking history/previous bookings reference - -## Related Files - -- Entity model: `src/main/webapp/app/shared/model/prenotazione.model.ts` -- Entity model: `src/main/webapp/app/shared/model/utente-app.model.ts` -- Prenotazione service: `src/main/webapp/app/entities/prenotazione/prenotazione.service.ts` -- Struttura service: `src/main/webapp/app/entities/struttura/struttura.service.ts` -- Enum: `src/main/webapp/app/shared/model/enumerations/stato-prenotazione.model.ts` +--- ## Summary -This implementation provides a user-friendly interface for creating reservations with minimal user input required. The form automatically loads user data, validates input, and provides clear feedback throughout the booking process. The clean separation between booking details and user data makes the form easy to understand and use. +This implementation successfully adds a complete waiver management system to the user booking form. Users must review and accept all required waivers before submitting a booking. The solution is fully reactive, handles edge cases gracefully, and provides clear visual feedback throughout the process. + +The feature follows Vue 3 Composition API best practices, integrates seamlessly with the existing JHipster application structure, and maintains consistency with the application's UI/UX patterns. diff --git a/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts b/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts index e8390d1..06bbbf3 100644 --- a/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts +++ b/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.component.ts @@ -7,11 +7,15 @@ import { required } from '@vuelidate/validators'; import StrutturaService from '@/entities/struttura/struttura.service'; import UtenteAppService from '@/entities/utente-app/utente-app.service'; +import LiberatoriaService from '@/entities/liberatoria/liberatoria.service'; +import ModelloLiberatoriaService from '@/entities/modello-liberatoria/modello-liberatoria.service'; import { useAlertService } from '@/shared/alert/alert.service'; import { useDateFormat } from '@/shared/composables'; import { type IPrenotazione, Prenotazione } from '@/shared/model/prenotazione.model'; import { type IStruttura } from '@/shared/model/struttura.model'; import { type IUtenteApp } from '@/shared/model/utente-app.model'; +import { type ILiberatoria, Liberatoria } from '@/shared/model/liberatoria.model'; +import { type IModelloLiberatoria } from '@/shared/model/modello-liberatoria.model'; import { StatoPrenotazione } from '@/shared/model/enumerations/stato-prenotazione.model'; import PrenotazioneService from './prenotazione.service'; @@ -33,6 +37,15 @@ export default defineComponent({ const strutturaService = inject('strutturaService', () => new StrutturaService()); const strutturas: Ref = ref([]); + const liberatoriaService = inject('liberatoriaService', () => new LiberatoriaService()); + const modelloLiberatoriaService = inject('modelloLiberatoriaService', () => new ModelloLiberatoriaService()); + + // Liberatorie state + const modelloLiberatorias: Ref = ref([]); + const userLiberatorias: Ref = ref([]); + const isLoadingLiberatorie = ref(false); + const selectedModello: Ref = ref(null); + const isSaving = ref(false); const isLoading = ref(true); const currentLanguage = inject('currentLanguage', () => computed(() => navigator.language ?? 'it'), true); @@ -55,6 +68,50 @@ export default defineComponent({ }; const v$ = useVuelidate(validationRules, prenotazione as any); + // Computed properties for liberatorie + const liberatorieStatus = computed(() => { + if (!prenotazione.value.struttura?.id) return []; + + // Filter ModelloLiberatoria for selected struttura + const strutturaModelli = modelloLiberatorias.value.filter(m => m.struttura?.id === prenotazione.value.struttura.id); + + // Map to include acceptance status + return strutturaModelli.map(modello => { + const accepted = userLiberatorias.value.find(lib => lib.modelloLiberatoria?.id === modello.id); + return { + modello, + liberatoria: accepted || null, + isAccepted: !!accepted, + }; + }); + }); + + const allLiberatorieAccepted = computed(() => { + const status = liberatorieStatus.value; + return status.length === 0 || status.every(s => s.isAccepted); + }); + + const loadLiberatorieData = async () => { + if (!currentUser.value?.id) return; + + try { + isLoadingLiberatorie.value = true; + + // Fetch all ModelloLiberatoria (filter client-side) + const modelliRes = await modelloLiberatoriaService().retrieve(); + modelloLiberatorias.value = modelliRes.data; + + // Fetch all Liberatoria and filter by current user + const liberatorieRes = await liberatoriaService().retrieve(); + userLiberatorias.value = liberatorieRes.data.filter((lib: ILiberatoria) => lib.utente?.id === currentUser.value.id); + + isLoadingLiberatorie.value = false; + } catch (error) { + isLoadingLiberatorie.value = false; + alertService.showHttpError(error.response); + } + }; + const initData = async () => { try { isLoading.value = true; @@ -68,6 +125,9 @@ export default defineComponent({ const res = await strutturaService().retrieve(); strutturas.value = res.data; + // Load liberatorie data + await loadLiberatorieData(); + isLoading.value = false; } catch (error) { isLoading.value = false; @@ -99,6 +159,15 @@ export default defineComponent({ currentLanguage, v$, resetForm, + // Liberatorie additions + liberatoriaService, + modelloLiberatoriaService, + modelloLiberatorias, + userLiberatorias, + isLoadingLiberatorie, + selectedModello, + liberatorieStatus, + allLiberatorieAccepted, ...useDateFormat({ entityRef: prenotazione }), t$, }; @@ -113,6 +182,13 @@ export default defineComponent({ return; } + // Check if all required liberatorie are accepted + if (!this.allLiberatorieAccepted) { + this.isSaving = false; + this.alertService.showError(this.t$('smartbookingApp.prenotazione.userForm.liberatorieRequired').toString()); + return; + } + this.prenotazioneService() .create(this.prenotazione) .then(param => { @@ -125,5 +201,45 @@ export default defineComponent({ this.alertService.showHttpError(error.response); }); }, + + showLiberatoriaModal(modello: IModelloLiberatoria): void { + this.selectedModello = modello; + (this.$refs.liberatoriaModal).show(); + }, + + closeLiberatoriaModal(): void { + this.selectedModello = null; + (this.$refs.liberatoriaModal).hide(); + }, + + async acceptLiberatoria(): Promise { + if (!this.selectedModello || !this.currentUser) return; + + try { + this.isSaving = true; + + // Create new Liberatoria + const newLiberatoria = new Liberatoria(); + newLiberatoria.accettata = new Date(); + newLiberatoria.utente = this.currentUser; + newLiberatoria.modelloLiberatoria = this.selectedModello; + + const result = await this.liberatoriaService().create(newLiberatoria); + + // Add to local state + this.userLiberatorias.push(result); + + // Close modal + this.closeLiberatoriaModal(); + + // Show success message + this.alertService.showSuccess(this.t$('smartbookingApp.liberatoria.created', { param: result.id }).toString()); + + this.isSaving = false; + } catch (error) { + this.isSaving = false; + this.alertService.showHttpError(error.response); + } + }, }, }); diff --git a/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue b/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue index 974b651..ac5ec22 100644 --- a/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue +++ b/src/main/webapp/app/entities/prenotazione/prenotazione-form-user.vue @@ -220,13 +220,65 @@ + +
+
+

{{ t$('smartbookingApp.prenotazione.userForm.liberatorie') }}

+
+
+
+
+ Loading... +
+
+ +
+ {{ t$('smartbookingApp.prenotazione.userForm.noLiberatorieRequired') }} +
+ +
+
+
+ + + + + + + + + {{ item.modello.nome }} + + + {{ item.modello.nome }} + +
+ + + {{ t$('smartbookingApp.liberatoria.accettata') }}: + {{ new Date(item.liberatoria.accettata).toLocaleDateString('it-IT') }} + +
+
+ +
+ + {{ t$('smartbookingApp.prenotazione.userForm.liberatorieWarning') }} +
+
+
+
- @@ -234,5 +286,54 @@
+ + + + + +
+ +
+
{{ t$('smartbookingApp.modelloLiberatoria.testo') }}
+
+ {{ selectedModello.testo }} +
+
+ + +
+
{{ t$('smartbookingApp.modelloLiberatoria.documento') }}
+ + + {{ t$('entity.action.download') }} + +
+ + +
+ {{ t$('smartbookingApp.prenotazione.userForm.acceptanceStatement') }} +

+ Il sottoscritto {{ currentUser?.nome }} {{ currentUser?.cognome }} + presa visione della documentazione proposta accetta le condizioni ivi indicate. +

+
+
+ + +
diff --git a/src/main/webapp/i18n/it/prenotazione.json b/src/main/webapp/i18n/it/prenotazione.json index 07e52e0..8175f55 100644 --- a/src/main/webapp/i18n/it/prenotazione.json +++ b/src/main/webapp/i18n/it/prenotazione.json @@ -37,7 +37,13 @@ "societa": "società/associazione", "companyData": "Dati della società/associazione", "reset": "Annulla", - "submit": "Invia richiesta" + "submit": "Invia richiesta", + "liberatorie": "Liberatorie", + "noLiberatorieRequired": "Nessuna liberatoria richiesta per questa struttura", + "liberatorieWarning": "È necessario accettare tutte le liberatorie richieste prima di inviare la prenotazione", + "liberatorieRequired": "Devi accettare tutte le liberatorie richieste", + "acceptanceStatement": "Dichiarazione di accettazione", + "accept": "Accetta" }, "StatoPrenotazione": { "RICHIESTA": ""