Commit Graph
22 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 646e44d126 fix: location preference bug and service detail 404
- When professional accepts 'both' modes, add office/delivery toggle so
  the patient can explicitly choose instead of defaulting to delivery.
  Reset _bookAsDelivery when a professional is selected; office-only
  professionals still force office, delivery-only force delivery.
- Fix 'sin servicio' on ServiceView: getServiceForUser was calling
  /users/:professionalId using the professionals-table UUID (not user UUID),
  returning 404 and setting service=null. Use the embedded professionals.users
  data from findById instead.
- Convert ServiceView to StatefulWidget; fetch in initState to avoid
  re-fetching on every parent rebuild.
- Remove client-side FCM notification from _requestService; backend
  create() now notifies the professional directly with the server key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 09:33:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 735d8c2ba0 fix: corregir flujo completo de servicio y geocodificación
- Service.fromJson: lat/lng con Decimal de Prisma llegaban como string y
  el cast 'as num?' lanzaba TypeError silencioso → lista de servicios vacía.
  Mismo patrón que average_score, fix: double.tryParse(?.toString())
- service_status: agregar enumToStringService que mapea el enum de Flutter
  al string que espera el DTO del backend ('pending','accepted', etc.).
  changeServiceStatus enviaba el índice entero → @IsEnum rechazaba → el
  profesional no podía aceptar ni rechazar solicitudes
- maps_service: agregar MapsService.reverseGeocode que usa el Geocoder del
  Maps JS SDK ya cargado, sin requerir la Geocoding API habilitada por separado
- dashboard_view: _reverseGeocode usa el JS Geocoder en vez del endpoint HTTP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 09:15:59 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8296b5a3ea fix: corregir payload de solicitud de servicio al backend
- day: usar formato ISO 8601 "yyyy-MM-dd" — @IsDateString() rechazaba
  el formato de DateTime.toString() que usa espacio en vez de T
- location_preference: enviar string "office"/"delivery" con la clave
  correcta — se enviaba 'location' con un entero (enum index)
- Construir el payload directamente en vez de usar Service.toDocument()
  que no coincide con CreateServiceDto

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 08:54:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 462d47d182 fix: mostrar dirección del consultorio en InfoWindow del marcador del mapa
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 08:51:59 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6c248e1f98 fix: corregir flujo de agendamiento del paciente
- calendar_view: separar carga del profesional (1 vez) de la carga de
  servicios (por cada cambio de día), eliminando re-fetches innecesarios
- calendar_view: usar DateTime local en vez de UTC para evitar desfase
  de fecha en zonas horarias (Colombia UTC-5)
- calendar_view: excluir explícitamente cancelled/denied en _isOccupied
  y refactorizar los 4 tipos de card en un único método _slotCard
- dashboard_view: usar slotDurationMinutes del profesional en range1Hour2
  en vez de 2 horas hardcodeadas, respetando la duración real del slot

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 08:38:32 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5fdc87dad7 feat: marcadores de consultorios en mapa + fix ciudad inicial
- Muestra marcadores azules en el mapa para profesionales con coordenadas
  reales y modalidad presencial (office/both), filtrados por ciudad del paciente.
  Tocar un marcador navega directamente al calendario del profesional.
- Agrega tabla de coordenadas hardcodeadas para 30 ciudades colombianas como
  fallback inmediato en _centerOnUserCity, evitando que el mapa cargue en
  Medellín cuando la Geocoding API no está habilitada en el proyecto GCP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 08:09:47 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 66f861601f feat: inicializar mapa en ciudad del usuario antes de GPS
_initMaps ahora geocodifica la ciudad del perfil del usuario (_centerOnUserCity)
antes de mostrar el mapa. Así el mapa arranca en Bucaramanga si el usuario
es de Bucaramanga, y el autocomplete ya tiene coordenadas correctas desde
el primer keystroke, sin esperar GPS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 21:06:30 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 cfd1c23fe3 fix: autocomplete muestra resultados de Medellín para usuario en Bucaramanga
Default _mapCenter era Medellín (nuevo fallback neutro) pero se usaba como
bias de coordenadas en el autocomplete antes de que GPS/geocoding terminara.
Ahora:
- _mapPositioned=false hasta que GPS o _centerOnUserCity actualice el centro
- Autocomplete omite parámetro location hasta que _mapPositioned=true
- Mientras tanto, la ciudad del usuario se agrega al query de texto para biasear

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 21:06:11 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 495502cfc1 fix: no exigir dirección cuando profesional solo atiende en consultorio
- _requestService: omite validación de dirección si locationPreferences=office
- Usa la dirección y coordenadas del consultorio del profesional en ese caso
- Botón y warnings de ciudad deshabilitados solo en modo domicilio/ambos
- Tarjeta inferior muestra dirección del consultorio cuando es office-only
- location_preference del servicio refleja correctamente office vs delivery

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 21:04:18 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 953196df1a fix: autocomplete muestra Bogotá para usuario en Bucaramanga
- _mapCenter default cambiado de Bogotá a coordenadas más neutras
- Cuando GPS no está disponible/denegado, _centerOnUserCity() geocodifica
  la ciudad del perfil del usuario y centra el mapa ahí
- El autocomplete usa _mapCenter como bias → resultados ahora corresponden
  a la ciudad del usuario, no a Bogotá hardcodeado

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 20:48:32 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 54f9cc272e fix: 4 audit findings in professionals location flow
- Clear button (✕) now resets _cityMismatch and _detectedCity so banner and CTA unblock
- _citiesMatch: replace bidirectional contains with equality + word-prefix check to prevent 'Cali' matching 'Calima'
- ProfessionalsProvider: track _currentUserId to reset state on user change (cross-user leak)
- ProfessionalsProvider: store _lastSearch so setLocationContext preserves active search term

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 20:47:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f26b3d3c03 feat: dashboard city validation + professionals by location
- Professionals filtered by user city + proximity (lat/lng) to selected address
- ProfessionalsProvider: setLocationContext(city, lat, lng) updates filter and reloads
- Dashboard: detect city mismatch after reverse geocode, block booking if wrong city
- Dashboard: autocomplete biased toward user's city
- Dashboard: setLocationContext called before navigating to professionals list
- Dashboard: keyboard no longer shifts map layout on tablet (MediaQuery viewInsets=0)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 20:36:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 fac4135835 fix: navbar StatefulWidget + dashboard colores dinamicos
- Navbar: convertir a StatefulWidget, un solo nivel de build,
  usa context.watch en lugar de Consumer anidados
- Iconos sol/luna y campana siempre visibles con color explicito
- Dashboard: barra busqueda, sugerencias y tarjeta inferior
  ahora respetan isDark (cardBg, textColor, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 09:16:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9c61a35747 feat: validacion ciudad disponible en dashboard
- CitiesProvider.isCityAvailable() y findMatchingCity() con comparacion flexible
- Al mover el mapa extrae la ciudad del geocodificado inverso
- Si la ciudad no esta en la lista muestra aviso amarillo y bloquea solicitud
- Boton de solicitar deshabilitado cuando ciudad no esta disponible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 08:38:01 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d5be8d6f6b fix: autocompletado de direcciones
- Quitar replaceAll(' ', '_') que rompia la query
- Pasar coordenadas actuales del mapa como location bias
- Soportar formatted_address y description en respuesta
- Manejar results o predictions como clave raiz

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 08:33:19 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1fd29bbfdd fix: getFormatTime retorna String? — agregar fallback vacio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 08:25:29 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9cde46b88a fix: resolver conflicto ServiceStatus y tipo nullable en dashboard
- hide ServiceStatus de geolocator para evitar conflicto con modelo propio
- usar _selectedHour! en getFormatTime (ya esta guardado por null-check previo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 08:23:36 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 e56807b75e feat: rediseño dashboard estilo InDrive con mapa completo
Mapa ocupa toda la pantalla, pin central fijo, barra de busqueda
flotante con autocomplete, tarjeta inferior para profesional/fecha.
Al mover el mapa hace geocodificacion inversa y actualiza la direccion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 08:18:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 863546f0fc feat: Google Maps location picker in dashboard
- LocationPickerDialog: detecta ubicación del dispositivo, pin draggable,
  reverse geocoding para obtener dirección y ciudad
- Dashboard: campo de dirección abre el mapa al tocar
- index.html: carga Maps JS API (key pendiente de configurar)
- pubspec: google_maps_flutter + geolocator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 07:52:01 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c8e5d481ed fix: handle null city for phone-registered users in dashboard
user.city is null for users registered via OTP — null assertion caused
crash showing grey DashboardLayout background.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 07:37:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 60216fd0e3 feat: migrate Firebase → NestJS REST API backend
Replace all Firebase SDK (Auth, Firestore, Storage) with HTTP calls
to backend.prosapp.co/api/v1:

- New ApiService singleton (JWT token, GET/POST/PATCH/DELETE/upload)
- auth_provider: Firebase Auth → /auth/login, /auth/register, /auth/phone/*
- services_provider + calendar_services_provider → /services endpoints
- professional_provider + professionals_provider → /professional-info, /users/professionals
- profile_form_provider + professional_form_provider → /users/me, /storage/upload
- cities/professions/settings providers → /cities, /professions, /settings
- firebase_chat_repository → polling via /chats endpoints (3s interval)
- firebase_score_repository → polling via /comments endpoints (10s interval)
- professional_detail_provider → /users/:id + /professional-info/:id
- dashboard_view: Firestore.add → POST /services
- chat_view + rating_view: FirebaseAuth.uid → AuthProvider.user.id
- Models: Timestamp → String for createdAt fields
- google_fonts upgraded to ^8.1.0 (Dart 3.12 compat)
- Remove firebase_core, firebase_auth, cloud_firestore, firebase_storage from pubspec

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 15:53:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 15175c1b91 replace: swap prosappweb content for prosapp_web_app (more complete version)
prosapp_web_app has chat, dashboard, calendar, support, 13 providers and
Fluro URL routing. Keep Dockerfile + nginx.conf from previous prosappweb.
Upgrade google_fonts 6.2.1 → 8.1.0 (Dart 3.12 compat fix).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 15:26:32 -05:00