diff --git a/frontend/angular.json b/frontend/angular.json index af7e532..fcd0379 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -53,6 +53,9 @@ }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "proxyConfig": "proxy.conf.json" + }, "configurations": { "production": { "browserTarget": "App-frontend:build:production" diff --git a/frontend/proxy.conf.json b/frontend/proxy.conf.json new file mode 100644 index 0000000..06d074f --- /dev/null +++ b/frontend/proxy.conf.json @@ -0,0 +1,7 @@ +{ + "/api": { + "target": "http://localhost:3000", + "secure": false, + "logLevel": "debug" + } +} diff --git a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css index ad4c534..1c12ceb 100644 --- a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css +++ b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css @@ -1081,4 +1081,106 @@ .gc-popup-btn-primary:hover { background: #185abc; box-shadow: 0 1px 3px rgba(60,64,67,0.3), 0 2px 6px 2px rgba(60,64,67,0.15); +} + +.gc-popup-btn-primary:disabled { + background: #a8c7fa; + cursor: not-allowed; + box-shadow: none; +} + +/* ── Loading bar ── */ +.gc-loading-bar { + height: 3px; + width: 100%; + background: #e8f0fe; + overflow: hidden; + flex-shrink: 0; +} + +.gc-loading-bar__inner { + height: 100%; + width: 40%; + background: #1a73e8; + border-radius: 2px; + animation: gc-loading-slide 1.2s ease-in-out infinite; +} + +@keyframes gc-loading-slide { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(350%); } +} + +/* ── Error banner ── */ +.gc-error-banner { + background: #fce8e6; + color: #c5221f; + font-size: 13px; + padding: 8px 16px; + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + border-bottom: 1px solid #f5c6c5; +} + +/* ── Date display in sidebar ── */ +.gc-date-display { + padding: 4px 8px; +} + +.gc-date-display__label { + font-size: 12px; + color: #5f6368; + font-weight: 500; + line-height: 1.4; +} + +/* ── Activity dot (color circle instead of avatar) ── */ +.gc-activity-dot { + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; + margin-top: 4px; +} + +/* ── Empty reservas text ── */ +.gc-empty-reservas { + font-size: 12px; + color: #9aa0a6; + padding: 8px; + text-align: center; + margin: 0; +} + +/* ── Popup feedback messages ── */ +.gc-popup-error { + background: #fce8e6; + color: #c5221f; + font-size: 12px; + padding: 6px 10px; + border-radius: 4px; + margin-top: 8px; + display: flex; + align-items: center; + gap: 4px; +} + +.gc-popup-success { + background: #e6f4ea; + color: #1e8e3e; + font-size: 12px; + padding: 6px 10px; + border-radius: 4px; + margin-top: 8px; + display: flex; + align-items: center; + gap: 4px; + animation: gc-fade-in 0.2s ease; +} + +@keyframes gc-fade-in { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } } \ No newline at end of file diff --git a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html index 39b74fa..e048bfe 100644 --- a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html +++ b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html @@ -1,6 +1,6 @@
- +
- +
- - + +
-

Junio de 2026

+

{{ monthLabel() | titlecase }}

-
- + - +
- +
- -
JM
+ +
JO
+ + @if (reservasService.isLoading()) { +
+
+
+ } +
- +
- - - - +
Mis Espacios keyboard_arrow_up
-
- - -
- +
- Actividad de Reservas + Reservas del día keyboard_arrow_up
- @for (act of recentActivities(); track act.title) { + @if (reservasService.reservas().length === 0 && !reservasService.isLoading()) { +

Sin reservas para este día.

+ } + @for (r of reservasService.reservas(); track r.id) {
- user +
- {{ act.title }} - {{ act.detail }} - {{ act.time }} + {{ r.resourceName }} + {{ r.startTime }} – {{ r.endTime }} + {{ r.author }}
} @@ -162,17 +153,22 @@ - +
- + + @if (reservasService.error()) { +
+ error_outline + {{ reservasService.error() }} +
+ } + +
-
GMT-04
- -
@for (res of filteredResources(); track res.id; let idx = $index) {
@@ -186,11 +182,11 @@
- +
- +
@for (time of timeSlots; track time) {
@@ -199,16 +195,13 @@ }
- -
+ +
-
- @for (res of filteredResources(); track res.id; let colIdx = $index) {
@@ -216,34 +209,17 @@
@if (isSlotOccupied(res.name, time)) { - -
-
Reservado / Ocupado
-
{{ time }} - {{ getEndTime(time) }}
+ +
+
{{ getReservaForSlot(res.name, time)?.author || 'Reservado' }}
+
{{ time }} – {{ getEndTime(time) }}
} @else { - - - @if (res.name === 'OFICINA FLEX A1' && time === '12:00') { -
- emp - emp -
- } @else if (res.name === 'OFICINA FLEX A1' && time === '13:30') { -
- emp -
- } @else { - -
+ +
} - } - - + @if (selectedSlot()?.resource?.id === res.id && selectedSlot()?.time === time) {
@@ -253,28 +229,45 @@

{{ res.name }}

+
schedule
- Martes, 16 de Junio + {{ activeDateLabel() | titlecase }} {{ time }} – {{ getEndTime(time) }}
room - Capacidad máxima: {{ res.capacity }} personas + Capacidad: {{ res.capacity }} personas
info_outline {{ res.type }}
+ + + @if (confirmError()) { +
+ error + {{ confirmError() }} +
+ } + @if (confirmSuccess()) { +
+ check_circle + ¡Reserva guardada en Supabase! +
+ }
- +
} @@ -298,29 +291,17 @@
- +