feat: Implement notification and storage services, geofence management, and BLoC for geofence verification
- Add NotificationService for handling local notifications. - Introduce StorageService for key-value storage using SharedPreferences. - Create DeviceLocation model to represent geographic locations. - Define LocationPermissionStatus enum for managing location permissions. - Implement BackgroundGeofenceService for periodic geofence checks while clocked in. - Develop GeofenceServiceImpl for geofence proximity verification using LocationService. - Create GeofenceResult model to encapsulate geofence check results. - Define GeofenceServiceInterface for geofence service abstraction. - Implement GeofenceBloc to manage geofence verification and background tracking. - Create events and states for GeofenceBloc to handle various geofence scenarios. - Add GeofenceStatusBanner widget to display geofence verification status in the UI.
This commit is contained in:
@@ -926,6 +926,28 @@
|
||||
"submit": "Submit",
|
||||
"success_title": "Break Logged!",
|
||||
"close": "Close"
|
||||
},
|
||||
"geofence": {
|
||||
"service_disabled": "Location services are turned off. Enable them to clock in.",
|
||||
"permission_required": "Location permission is required to clock in.",
|
||||
"permission_denied_forever": "Location was permanently denied. Enable it in Settings.",
|
||||
"open_settings": "Open Settings",
|
||||
"grant_permission": "Grant Permission",
|
||||
"verifying": "Verifying your location...",
|
||||
"too_far_title": "You're Too Far Away",
|
||||
"too_far_desc": "You are $distance away. Move within 500m to clock in.",
|
||||
"verified": "Location Verified",
|
||||
"not_in_range": "You must be at the workplace to clock in.",
|
||||
"timeout_title": "Can't Verify Location",
|
||||
"timeout_desc": "Unable to determine your location. You can still clock in with a note.",
|
||||
"timeout_note_hint": "Why can't your location be verified?",
|
||||
"clock_in_greeting_title": "You're Clocked In!",
|
||||
"clock_in_greeting_body": "Have a great shift. We'll keep track of your location.",
|
||||
"background_left_title": "You've Left the Workplace",
|
||||
"background_left_body": "You appear to be more than 500m from your shift location.",
|
||||
"always_permission_title": "Background Location Needed",
|
||||
"always_permission_desc": "To verify your location during shifts, please allow location access 'Always'.",
|
||||
"retry": "Retry"
|
||||
}
|
||||
},
|
||||
"availability": {
|
||||
@@ -1416,6 +1438,10 @@
|
||||
"application_not_found": "Your application couldn't be found.",
|
||||
"no_active_shift": "You don't have an active shift to clock out from."
|
||||
},
|
||||
"clock_in": {
|
||||
"location_verification_required": "Please wait for location verification before clocking in.",
|
||||
"notes_required_for_timeout": "Please add a note explaining why your location can't be verified."
|
||||
},
|
||||
"generic": {
|
||||
"unknown": "Something went wrong. Please try again.",
|
||||
"no_connection": "No internet connection. Please check your network and try again.",
|
||||
|
||||
@@ -921,6 +921,28 @@
|
||||
"submit": "Enviar",
|
||||
"success_title": "\u00a1Descanso registrado!",
|
||||
"close": "Cerrar"
|
||||
},
|
||||
"geofence": {
|
||||
"service_disabled": "Los servicios de ubicación están desactivados. Actívelos para registrar entrada.",
|
||||
"permission_required": "Se requiere permiso de ubicación para registrar entrada.",
|
||||
"permission_denied_forever": "La ubicación fue denegada permanentemente. Actívela en Configuración.",
|
||||
"open_settings": "Abrir Configuración",
|
||||
"grant_permission": "Otorgar Permiso",
|
||||
"verifying": "Verificando su ubicación...",
|
||||
"too_far_title": "Está Demasiado Lejos",
|
||||
"too_far_desc": "Está a $distance de distancia. Acérquese a 500m para registrar entrada.",
|
||||
"verified": "Ubicación Verificada",
|
||||
"not_in_range": "Debe estar en el lugar de trabajo para registrar entrada.",
|
||||
"timeout_title": "No se Puede Verificar la Ubicación",
|
||||
"timeout_desc": "No se pudo determinar su ubicación. Puede registrar entrada con una nota.",
|
||||
"timeout_note_hint": "¿Por qué no se puede verificar su ubicación?",
|
||||
"clock_in_greeting_title": "¡Entrada Registrada!",
|
||||
"clock_in_greeting_body": "Buen turno. Seguiremos el registro de su ubicación.",
|
||||
"background_left_title": "Ha Salido del Lugar de Trabajo",
|
||||
"background_left_body": "Parece que está a más de 500m de la ubicación de su turno.",
|
||||
"always_permission_title": "Se Necesita Ubicación en Segundo Plano",
|
||||
"always_permission_desc": "Para verificar su ubicación durante los turnos, permita el acceso a la ubicación 'Siempre'.",
|
||||
"retry": "Reintentar"
|
||||
}
|
||||
},
|
||||
"availability": {
|
||||
@@ -1411,6 +1433,10 @@
|
||||
"application_not_found": "No se pudo encontrar tu solicitud.",
|
||||
"no_active_shift": "No tienes un turno activo para registrar salida."
|
||||
},
|
||||
"clock_in": {
|
||||
"location_verification_required": "Por favor, espera la verificaci\u00f3n de ubicaci\u00f3n antes de registrar entrada.",
|
||||
"notes_required_for_timeout": "Por favor, agrega una nota explicando por qu\u00e9 no se puede verificar tu ubicaci\u00f3n."
|
||||
},
|
||||
"generic": {
|
||||
"unknown": "Algo sali\u00f3 mal. Por favor, intenta de nuevo.",
|
||||
"no_connection": "Sin conexi\u00f3n a internet. Por favor, verifica tu red e intenta de nuevo.",
|
||||
|
||||
@@ -35,6 +35,8 @@ String translateErrorKey(String key) {
|
||||
return _translateProfileError(errorType);
|
||||
case 'shift':
|
||||
return _translateShiftError(errorType);
|
||||
case 'clock_in':
|
||||
return _translateClockInError(errorType);
|
||||
case 'generic':
|
||||
return _translateGenericError(errorType);
|
||||
default:
|
||||
@@ -127,6 +129,18 @@ String _translateShiftError(String errorType) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Translates clock-in error keys to localized strings.
|
||||
String _translateClockInError(String errorType) {
|
||||
switch (errorType) {
|
||||
case 'location_verification_required':
|
||||
return t.errors.clock_in.location_verification_required;
|
||||
case 'notes_required_for_timeout':
|
||||
return t.errors.clock_in.notes_required_for_timeout;
|
||||
default:
|
||||
return t.errors.generic.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
String _translateGenericError(String errorType) {
|
||||
switch (errorType) {
|
||||
case 'unknown':
|
||||
|
||||
Reference in New Issue
Block a user