Strings quase feitas

This commit is contained in:
2026-03-18 16:20:18 +00:00
parent 7f80ed47f3
commit 6322e8d798
8 changed files with 324 additions and 228 deletions

View File

@@ -1,84 +1,170 @@
enum AppLanguage { pt, en, es }
class AppStrings { class AppStrings {
static AppLanguage _currentLanguage = AppLanguage.pt;
static void setLanguage(String language) {
if (language == 'English') {
_currentLanguage = AppLanguage.en;
} else if (language == 'Español') {
_currentLanguage = AppLanguage.es;
} else {
_currentLanguage = AppLanguage.pt;
}
}
static String get _lang => _currentLanguage.name;
static String _get(Map<String, String> values) => values[_lang] ?? values['pt']!;
// Main Screen // Main Screen
static const String complete = "COMPLETO"; static String get complete => _get({'pt': "COMPLETO", 'en': "COMPLETE", 'es': "COMPLETO"});
static const String steps = "PASSOS"; static String get steps => _get({'pt': "PASSOS", 'en': "STEPS", 'es': "PASOS"});
static const String bpm = "BPM"; static String get bpm => _get({'pt': "BPM", 'en': "BPM", 'es': "BPM"});
static const String kcal = "K/CAL"; static String get kcal => _get({'pt': "K/CAL", 'en': "K/CAL", 'es': "K/CAL"});
static const String mapPreview = "MAPA"; static String get mapPreview => _get({'pt': "MAPA", 'en': "MAP", 'es': "MAPA"});
static const String settings = "Configurações"; static String get settings => _get({'pt': "Configurações", 'en': "Settings", 'es': "Configuración"});
static const String groups = "Grupos"; static String get groups => _get({'pt': "Grupos", 'en': "Groups", 'es': "Grupos"});
static const String history = "Histórico"; static String get history => _get({'pt': "Histórico", 'en': "History", 'es': "Historial"});
static const String notifications = "Notificações"; static String get notifications => _get({'pt': "Notificações", 'en': "Notifications", 'es': "Notificaciones"});
static const String profile = "Perfil"; static String get profile => _get({'pt': "Perfil", 'en': "Profile", 'es': "Perfil"});
static const String welcome = "Bem-vindo"; static String get welcome => _get({'pt': "Bem-vindo", 'en': "Welcome", 'es': "Bienvenido"});
static const String myActivities = "Minhas Atividades"; static String get myActivities => _get({'pt': "Minhas Atividades", 'en': "My Activities", 'es': "Mis Actividades"});
static const String bestDistance = "Melhor Distância"; static String get bestDistance => _get({'pt': "Melhor Distância", 'en': "Best Distance", 'es': "Mejor Distancia"});
static const String bestSpeed = "Velocidade Máxima"; static String get bestSpeed => _get({'pt': "Velocidade Máxima", 'en': "Max Speed", 'es': "Velocidad Máxima"});
static const String connectDevice = "Conectar Dispositivo"; static String get connectDevice => _get({'pt': "Conectar Dispositivo", 'en': "Connect Device", 'es': "Conectar Dispositivo"});
static const String viewMap = "Ver Mapa"; static String get viewMap => _get({'pt': "Ver Mapa", 'en': "View Map", 'es': "Ver Mapa"});
static const String dailyGoal = "Meta Diária"; static String get dailyGoal => _get({'pt': "Meta Diária", 'en': "Daily Goal", 'es': "Meta Diaria"});
static const String startTraining = "INICIAR TREINO"; static String get startTraining => _get({'pt': "INICIAR TREINO", 'en': "START TRAINING", 'es': "INICIAR ENTRENAMIENTO"});
static String get generalActivity => _get({'pt': "ATIVIDADE GERAL", 'en': "GENERAL ACTIVITY", 'es': "ACTIVIDAD GENERAL"});
static String get personalRecords => _get({'pt': "RECORDS PESSOAIS", 'en': "PERSONAL RECORDS", 'es': "RÉCORDS PERSONALES"});
static String get stepsToday => _get({'pt': "passos hoje", 'en': "steps today", 'es': "pasos hoy"});
static String get setGoal => _get({'pt': "DEFINIR META", 'en': "SET GOAL", 'es': "DEFINIR META"});
static String get distance => _get({'pt': "DISTÂNCIA", 'en': "DISTANCE", 'es': "DISTANCIA"});
static String get time => _get({'pt': "TEMPO", 'en': "TIME", 'es': "TIEMPO"});
// Bluetooth Screen // Bluetooth Screen
static const String bluetoothTitle = "DISPOSITIVOS"; static String get bluetoothTitle => _get({'pt': "DISPOSITIVOS", 'en': "DEVICES", 'es': "DISPOSITIVOS"});
static const String bluetoothConnect = "CONECTAR BLUETOOTH"; static String get bluetoothConnect => _get({'pt': "CONECTAR BLUETOOTH", 'en': "CONNECT BLUETOOTH", 'es': "CONECTAR BLUETOOTH"});
static const String stopSearch = "PARAR BUSCA"; static String get stopSearch => _get({'pt': "PARAR BUSCA", 'en': "STOP SEARCH", 'es': "DETENER BÚSQUEDA"});
static const String startSearch = "BUSCAR AGORA"; static String get startSearch => _get({'pt': "BUSCAR AGORA", 'en': "SEARCH NOW", 'es': "BUSCAR AHORA"});
static const String searching = "STATUS: BUSCANDO..."; static String get searching => _get({'pt': "STATUS: BUSCANDO...", 'en': "STATUS: SEARCHING...", 'es': "ESTADO: BUSCANDO..."});
static const String statusReady = "STATUS: PRONTO"; static String get statusReady => _get({'pt': "STATUS: PRONTO", 'en': "STATUS: READY", 'es': "ESTADO: LISTO"});
static const String statusConnected = "STATUS: CONECTADO"; static String get statusConnected => _get({'pt': "STATUS: CONECTADO", 'en': "STATUS: CONNECTED", 'es': "ESTADO: CONECTADO"});
static const String nearbyDevices = "Dispositivos próximos"; static String get nearbyDevices => _get({'pt': "Dispositivos próximos", 'en': "Nearby devices", 'es': "Dispositivos cercanos"});
static const String active = "ATIVO"; static String get active => _get({'pt': "ATIVO", 'en': "ACTIVE", 'es': "ACTIVO"});
static const String startSearchInstruction = "Inicie a busca para conectar"; static String get startSearchInstruction => _get({'pt': "Inicie a busca para conectar", 'en': "Start search to connect", 'es': "Inicie la búsqueda para conectar"});
static const String connect = "CONECTAR"; static String get connect => _get({'pt': "CONECTAR", 'en': "CONNECT", 'es': "CONECTAR"});
static const String noDevicesFound = "Nenhum dispositivo encontrado."; static String get noDevicesFound => _get({'pt': "Nenhum dispositivo encontrado.", 'en': "No devices found.", 'es': "No se encontraron dispositivos."});
static const String foundDevices = "Encontrados"; static String get foundDevices => _get({'pt': "Encontrados", 'en': "Found", 'es': "Encontrados"});
static const String oneDevice = "1 Dispositivo"; static String get oneDevice => _get({'pt': "1 Dispositivo", 'en': "1 Device", 'es': "1 Dispositivo"});
static const String permissionsDenied = "Permissões de Bluetooth negadas."; static String get permissionsDenied => _get({'pt': "Permissões de Bluetooth negadas.", 'en': "Bluetooth permissions denied.", 'es': "Permisos de Bluetooth denegados."});
static const String turnOnBluetooth = static String get turnOnBluetooth => _get({'pt': "Ligue o Bluetooth para buscar dispositivos.", 'en': "Turn on Bluetooth to search for devices.", 'es': "Active el Bluetooth para buscar dispositivos."});
"Ligue o Bluetooth para buscar dispositivos."; static String get scanError => _get({'pt': "Erro ao iniciar scan: ", 'en': "Error starting scan: ", 'es': "Error al iniciar el escaneo: "});
static const String scanError = "Erro ao iniciar scan: "; static String get stopScanError => _get({'pt': "Erro ao parar scan: ", 'en': "Error stopping scan: ", 'es': "Error al detener el escaneo: "});
static const String stopScanError = "Erro ao parar scan: "; static String get defaultDeviceName => _get({'pt': "Dispositivo", 'en': "Device", 'es': "Dispositivo"});
static const String defaultDeviceName = "Dispositivo"; static String get connectingTo => _get({'pt': "Conectando a ", 'en': "Connecting to ", 'es': "Conectando a "});
static const String connectingTo = "Conectando a "; static String get connectedSuccess => _get({'pt': "Conectado com sucesso!", 'en': "Connected successfully!", 'es': "¡Conectado con éxito!"});
static const String connectedSuccess = "Conectado com sucesso!"; static String get connectFail => _get({'pt': "Falha ao conectar: ", 'en': "Failed to connect: ", 'es': "Error al conectar: "});
static const String connectFail = "Falha ao conectar: "; static String get deviceIdPrefix => _get({'pt': "Disp. [", 'en': "Dev. [", 'es': "Disp. ["});
static const String deviceIdPrefix = "Disp. ["; static String get unknownDevice => _get({'pt': "Dispositivo Desconhecido", 'en': "Unknown Device", 'es': "Dispositivo Desconhecido"});
static const String unknownDevice = "Dispositivo Desconhecido"; static String get permissionsNeeded => _get({'pt': "Permissões Necessárias", 'en': "Permissions Needed", 'es': "Permisos Necesarios"});
static String get permissionsDeniedPermanent => _get({
'pt': "As permissões de Bluetooth foram negadas permanentemente. Por favor, habilite-as nas configurações do sistema para continuar.",
'en': "Bluetooth permissions were permanently denied. Please enable them in system settings to continue.",
'es': "Los permisos de Bluetooth han sido denegados permanentemente. Por favor, habilítelos en la configuración del sistema para continuar."
});
// Map Screen // Map Screen
static const String mapTitleTracking = "TRACKING ATIVO"; static String get mapTitleTracking => _get({'pt': "TRACKING ATIVO", 'en': "ACTIVE TRACKING", 'es': "SEGUIMIENTO ACTIVO"});
static const String mapTitlePlanning = "PLANEJAR TRAJETO"; static String get mapTitlePlanning => _get({'pt': "PLANEJAR TRAJETO", 'en': "PLAN ROUTE", 'es': "PLANIFICAR TRAYECTO"});
static const String mapTitleRunning = "CORRIDA"; static String get mapTitleRunning => _get({'pt': "CORRIDA", 'en': "RUN", 'es': "CARRERA"});
static const String mapPace = "RITMO"; static String get mapPace => _get({'pt': "RITMO", 'en': "PACE", 'es': "RITMO"});
static const String mapRoute = "TRAJETO"; static String get mapRoute => _get({'pt': "TRAJETO", 'en': "ROUTE", 'es': "TRAYECTO"});
static const String mapTime = "TEMPO"; static String get mapTime => _get({'pt': "TEMPO", 'en': "TIME", 'es': "TIEMPO"});
static const String kmhUnit = "KM/H"; static String get kmhUnit => _get({'pt': "KM/H", 'en': "KM/H", 'es': "KM/H"});
static const String kmUnit = "KM"; static String get kmUnit => _get({'pt': "KM", 'en': "KM", 'es': "KM"});
static const String metersUnit = "m"; static String get metersUnit => _get({'pt': "m", 'en': "m", 'es': "m"});
static const String planningInstruction = "Toque para definir Início e Fim"; static String get planningInstruction => _get({'pt': "Toque para definir Início e Fim", 'en': "Tap to set Start and Finish", 'es': "Toque para definir Inicio y Fin"});
static const String btnStop = "PARAR"; static String get btnStop => _get({'pt': "PARAR", 'en': "STOP", 'es': "PARAR"});
static const String btnSimulate = "SIMULAR"; static String get btnSimulate => _get({'pt': "SIMULAR", 'en': "SIMULATE", 'es': "SIMULAR"});
static const String btnStartRun = "INICIAR CORRIDA"; static String get btnStartRun => _get({'pt': "INICIAR CORRIDA", 'en': "START RUN", 'es': "INICIAR CARRERA"});
static const String btnStopRun = "PARAR CORRIDA"; static String get btnStopRun => _get({'pt': "PARAR CORRIDA", 'en': "STOP RUN", 'es': "PARAR CARRERA"});
static const String startPoint = "Partida"; static String get startPoint => _get({'pt': "Partida", 'en': "Start", 'es': "Salida"});
static const String finishPoint = "Chegada"; static String get finishPoint => _get({'pt': "Chegada", 'en': "Finish", 'es': "Llegada"});
static const String markDestination = "Marcar Destino"; static String get markDestination => _get({'pt': "Marcar Destino", 'en': "Mark Destination", 'es': "Marcar Destino"});
static const String chooseRoute = "Escolher Rota"; static String get chooseRoute => _get({'pt': "Escolher Rota", 'en': "Choose Route", 'es': "Elegir Ruta"});
static const String confirmDestination = "Confirmar Destino?"; static String get confirmDestination => _get({'pt': "Confirmar Destino?", 'en': "Confirm Destination?", 'es': "¿Confirmar Destino?"});
static const String startRunQuestion = "Iniciar Corrida?"; static String get startRunQuestion => _get({'pt': "Iniciar Corrida?", 'en': "Start Run?", 'es': "¿Iniciar Carrera?"});
static const String startRunDescription = "Deseja começar o monitoramento agora?"; static String get startRunDescription => _get({'pt': "Deseja começar o monitoramento agora?", 'en': "Do you want to start monitoring now?", 'es': "¿Desea comenzar el monitoreo ahora?"});
static const String prepare = "PREPARAR"; static String get prepare => _get({'pt': "PREPARAR", 'en': "PREPARE", 'es': "PREPARAR"});
static const String maxSpeed = "VELOCIDADE MÁX"; static String get maxSpeed => _get({'pt': "VELOCIDADE MÁX", 'en': "MAX SPEED", 'es': "VELOCIDAD MÁXIMA"});
static const String cancel = "Cancelar"; static String get cancel => _get({'pt': "Cancelar", 'en': "Cancel", 'es': "Cancelar"});
static const String yes = "Sim"; static String get yes => _get({'pt': "Sim", 'en': "Yes", 'es': ""});
static const String runFinished = "Corrida Finalizada!"; static String get runFinished => _get({'pt': "Corrida Finalizada!", 'en': "Run Finished!", 'es': "¡Carrera Finalizada!"});
static const String totalDistance = "Distância Total"; static String get totalDistance => _get({'pt': "Distância Total", 'en': "Total Distance", 'es': "Distancia Total"});
static const String totalTime = "Tempo Total"; static String get totalTime => _get({'pt': "Tempo Total", 'en': "Total Time", 'es': "Tiempo Total"});
static const String close = "Fechar"; static String get close => _get({'pt': "Fechar", 'en': "Close", 'es': "Cerrar"});
static String get results => _get({'pt': "Resultados", 'en': "Results", 'es': "Resultados"});
// Auth Screens // Auth Screens
static const String entrar = "ENTRAR"; static String get entrar => _get({'pt': "ENTRAR", 'en': "LOGIN", 'es': "ENTRAR"});
static const String registrar = "REGISTRAR"; static String get registrar => _get({'pt': "REGISTRAR", 'en': "REGISTER", 'es': "REGISTRAR"});
static const String appTitle = "Run Vision Pro"; static String get appTitle => _get({'pt': "Run Vision Pro", 'en': "Run Vision Pro", 'es': "Run Vision Pro"});
// Shared Auth Strings
static String get labelEmail => _get({'pt': "Email", 'en': "Email", 'es': "Email"});
static String get hintEmail => _get({'pt': "seu@email.com", 'en': "your@email.com", 'es': "tu@email.com"});
static String get validatorEmailEmpty => _get({'pt': "Por favor, insira seu email", 'en': "Please enter your email", 'es': "Por favor, introduce tu email"});
static String get validatorEmailInvalid => _get({'pt': "Email inválido", 'en': "Invalid email", 'es': "Email inválido"});
static String get labelPassword => _get({'pt': "Senha", 'en': "Password", 'es': "Contraseña"});
static String get hintPassword => _get({'pt': "••••••••", 'en': "••••••••", 'es': "••••••••"});
static String get validatorPasswordEmpty => _get({'pt': "Por favor, insira sua senha", 'en': "Please enter your password", 'es': "Por favor, introduce tu contraseña"});
static String get validatorPasswordLength => _get({'pt': "Senha deve ter pelo menos 6 caracteres", 'en': "Password must be at least 6 characters", 'es': "La contraseña debe tener al menos 6 caracteres"});
// Registrar Sheet
static String get registerSuccess => _get({'pt': "Conta criada com sucesso! Verifique seu email.", 'en': "Account created successfully! Check your email.", 'es': "¡Cuenta creada con éxito! Revisa tu email."});
static String get registerTitle => _get({'pt': "Registrar", 'en': "Register", 'es': "Registrar"});
static String get labelName => _get({'pt': "Nome", 'en': "Name", 'es': "Nombre"});
static String get hintName => _get({'pt': "Seu nome completo", 'en': "Your full name", 'es': "Tu nombre completo"});
static String get validatorNameEmpty => _get({'pt': "Por favor, insira seu nome", 'en': "Please enter your name", 'es': "Por favor, introduce tu nombre"});
static String get validatorNameLength => _get({'pt': "Nome deve ter pelo menos 3 caracteres", 'en': "Name must be at least 3 characters", 'es': "El nombre debe tener al menos 3 caracteres"});
static String get labelConfirmPassword => _get({'pt': "Confirmar Senha", 'en': "Confirm Password", 'es': "Confirmar Contraseña"});
static String get validatorConfirmPasswordEmpty => _get({'pt': "Por favor, confirme sua senha", 'en': "Please confirm your password", 'es': "Por favor, confirma tu contraseña"});
static String get validatorConfirmPasswordMatch => _get({'pt': "Senhas não coincidem", 'en': "Passwords do not match", 'es': "Las contraseñas no coinciden"});
static String get btnRegister => _get({'pt': "Registrar", 'en': "Register", 'es': "Registrar"});
// Entrar Sheet
static String get loginTitle => _get({'pt': "Entrar", 'en': "Login", 'es': "Entrar"});
static String get loginSuccess => _get({'pt': "Login realizado com sucesso!", 'en': "Login successful!", 'es': "¡Login realizado con éxito!"});
static String get resetPasswordEmailSent => _get({'pt': "Email de redefinição enviado!", 'en': "Reset email sent!", 'es': "¡Email de restablecimiento enviado!"});
static String get forgotPassword => _get({'pt': "Esqueceu a senha?", 'en': "Forgot password?", 'es': "¿Olvidaste la contraseña?"});
static String get btnLogin => _get({'pt': "Entrar", 'en': "Login", 'es': "Entrar"});
// Settings Screen
static String get settingsTitle => _get({'pt': "CONFIGURAÇÕES", 'en': "SETTINGS", 'es': "CONFIGURACIÓN"});
static String get userPlaceholder => _get({'pt': "Usuário", 'en': "User", 'es': "Usuario"});
static String get editProfile => _get({'pt': "Editar perfil", 'en': "Edit profile", 'es': "Editar perfil"});
static String get adjustDateTime => _get({'pt': "Ajustar Data e Hora", 'en': "Adjust Date and Time", 'es': "Ajustar Fecha y Hora"});
static String get nightMode => _get({'pt': "Modo Noturno", 'en': "Night Mode", 'es': "Modo Nocturno"});
static String get language => _get({'pt': "Idioma", 'en': "Language", 'es': "Idioma"});
static String get accessibility => _get({'pt': "Acessibilidade", 'en': "Accessibility", 'es': "Accesibilidad"});
static String get privacySecurity => _get({'pt': "Privacidade e Segurança", 'en': "Privacy and Security", 'es': "Privacidad y Seguridad"});
static String get termsOfUse => _get({'pt': "Termos de Uso", 'en': "Terms of Use", 'es': "Términos de Uso"});
static String get about => _get({'pt': "Sobre", 'en': "About", 'es': "Sobre"});
static String get logout => _get({'pt': "Sair", 'en': "Logout", 'es': "Salir"});
static String get confirmLogout => _get({'pt': "Confirmar Logout", 'en': "Confirm Logout", 'es': "Confirmar Salida"});
static String get confirmLogoutMessage => _get({'pt': "Tem certeza que deseja sair?", 'en': "Are you sure you want to logout?", 'es': "¿Estás seguro de que quieres salir?"});
static String get selectLanguage => _get({'pt': "Selecionar Idioma", 'en': "Select Language", 'es': "Seleccionar Idioma"});
static String get version => _get({'pt': "Versão", 'en': "Version", 'es': "Versión"});
static String get appDescription => _get({'pt': "Aplicativo de corrida com estatísticas e mapas", 'en': "Running app with stats and maps", 'es': "Aplicación de carrera con estadísticas y mapas"});
static String get dateSelected => _get({'pt': "Data selecionada", 'en': "Date selected", 'es': "Fecha seleccionada"});
static String get btnOk => _get({'pt': "OK", 'en': "OK", 'es': "OK"});
static String get btnCancel => _get({'pt': "Cancelar", 'en': "Cancel", 'es': "Cancelar"});
static String get btnDefine => _get({'pt': "DEFINIR", 'en': "DEFINE", 'es': "DEFINIR"});
// Logado Screen
static String get defineDailyGoal => _get({'pt': "Definir Meta Diária", 'en': "Set Daily Goal", 'es': "Definir Meta Diaria"});
static String get customGoal => _get({'pt': "Personalizado", 'en': "Custom", 'es': "Personalizado"});
static String get customGoalTitle => _get({'pt': "Meta Personalizada", 'en': "Custom Goal", 'es': "Meta Personalizada"});
} }

View File

@@ -77,7 +77,7 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
} else { } else {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text(AppStrings.permissionsDenied), content: Text(AppStrings.permissionsDenied),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
), ),
@@ -93,19 +93,19 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
showDialog( showDialog(
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: const Text("Permissões Necessárias"), title: Text(AppStrings.permissionsNeeded),
content: const Text("As permissões de Bluetooth foram negadas permanentemente. Por favor, habilite-as nas configurações do sistema para continuar."), content: Text(AppStrings.permissionsDeniedPermanent),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Text("CANCELAR"), child: Text(AppStrings.btnCancel),
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
openAppSettings(); openAppSettings();
Navigator.pop(context); Navigator.pop(context);
}, },
child: const Text("CONFIGURAÇÕES"), child: Text(AppStrings.settingsTitle),
), ),
], ],
), ),
@@ -117,7 +117,7 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
if (await FlutterBluePlus.adapterState.first != BluetoothAdapterState.on) { if (await FlutterBluePlus.adapterState.first != BluetoothAdapterState.on) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text(AppStrings.turnOnBluetooth), content: Text(AppStrings.turnOnBluetooth),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
), ),
@@ -174,7 +174,7 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
}); });
FlutterBluePlus.stopScan(); FlutterBluePlus.stopScan();
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text(AppStrings.connectedSuccess), content: Text(AppStrings.connectedSuccess),
backgroundColor: AppColors.success, backgroundColor: AppColors.success,
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
@@ -208,9 +208,9 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
return Scaffold( return Scaffold(
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
appBar: AppBar( appBar: AppBar(
title: const Text( title: Text(
AppStrings.bluetoothTitle, AppStrings.bluetoothTitle,
style: TextStyle( style: const TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
letterSpacing: 2, letterSpacing: 2,
color: Colors.white, color: Colors.white,

View File

@@ -192,17 +192,17 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
title: const Text("Iniciar Corrida?", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), title: Text(AppStrings.startRunQuestion, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
content: const Text("Deseja começar o monitoramento agora?", style: TextStyle(color: Colors.white70)), content: Text(AppStrings.startRunDescription, style: const TextStyle(color: Colors.white70)),
actions: [ actions: [
TextButton(onPressed: () => Navigator.pop(context), child: const Text(AppStrings.cancel, style: TextStyle(color: Colors.white54))), TextButton(onPressed: () => Navigator.pop(context), child: Text(AppStrings.cancel, style: const TextStyle(color: Colors.white54))),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
_startCountdown(); _startCountdown();
}, },
style: ElevatedButton.styleFrom(backgroundColor: AppColors.coral, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15))), style: ElevatedButton.styleFrom(backgroundColor: AppColors.coral, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15))),
child: const Text(AppStrings.yes, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), child: Text(AppStrings.yes, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
), ),
], ],
), ),
@@ -256,7 +256,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
showGeneralDialog( showGeneralDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
barrierLabel: "Resultados", barrierLabel: AppStrings.results,
pageBuilder: (context, anim1, anim2) => const SizedBox(), pageBuilder: (context, anim1, anim2) => const SizedBox(),
transitionBuilder: (context, anim1, anim2, child) { transitionBuilder: (context, anim1, anim2, child) {
return FadeTransition( return FadeTransition(
@@ -279,7 +279,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
child: const Icon(Icons.emoji_events_rounded, color: Colors.white, size: 40), child: const Icon(Icons.emoji_events_rounded, color: Colors.white, size: 40),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
const Text(AppStrings.runFinished, style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.w900, letterSpacing: 1)), Text(AppStrings.runFinished, style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.w900, letterSpacing: 1)),
const SizedBox(height: 30), const SizedBox(height: 30),
Container( Container(
height: 180, height: 180,
@@ -317,7 +317,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
const Divider(color: Colors.white10, height: 25), const Divider(color: Colors.white10, height: 25),
_buildResultRow(AppStrings.totalTime, _formatTime(finalTime)), _buildResultRow(AppStrings.totalTime, _formatTime(finalTime)),
const Divider(color: Colors.white10, height: 25), const Divider(color: Colors.white10, height: 25),
_buildResultRow("VELOCIDADE MÁX", "${finalMaxSpeed.toStringAsFixed(1)} ${AppStrings.kmhUnit}"), _buildResultRow(AppStrings.maxSpeed, "${finalMaxSpeed.toStringAsFixed(1)} ${AppStrings.kmhUnit}"),
const SizedBox(height: 35), const SizedBox(height: 35),
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
@@ -459,7 +459,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Text("PREPARAR", style: TextStyle(color: Colors.white54, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 5)), Text(AppStrings.prepare, style: const TextStyle(color: Colors.white54, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 5)),
const SizedBox(height: 20), const SizedBox(height: 20),
Text("$_countdownValue", style: const TextStyle(color: AppColors.coral, fontSize: 160, fontWeight: FontWeight.w900)), Text("$_countdownValue", style: const TextStyle(color: AppColors.coral, fontSize: 160, fontWeight: FontWeight.w900)),
], ],

View File

@@ -47,12 +47,12 @@ class _LogadoScreenState extends State<LogadoScreen> {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
title: const Text("Definir Meta Diária", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), title: Text(AppStrings.defineDailyGoal, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
...[5, 10, 15, 20].map((km) => ListTile( ...[5, 10, 15, 20].map((km) => ListTile(
title: Text("$km KM", style: const TextStyle(color: Colors.white)), title: Text("$km ${AppStrings.kmUnit}", style: const TextStyle(color: Colors.white)),
onTap: () { onTap: () {
setState(() { setState(() {
_dailyGoal = km.toDouble(); _dailyGoal = km.toDouble();
@@ -63,7 +63,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
const Divider(color: Colors.white10), const Divider(color: Colors.white10),
ListTile( ListTile(
leading: const Icon(Icons.edit_note_rounded, color: AppColors.coral), leading: const Icon(Icons.edit_note_rounded, color: AppColors.coral),
title: const Text("Personalizado", style: TextStyle(color: AppColors.coral, fontWeight: FontWeight.bold)), title: Text(AppStrings.customGoal, style: const TextStyle(color: AppColors.coral, fontWeight: FontWeight.bold)),
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
_showCustomGoalDialog(); _showCustomGoalDialog();
@@ -82,7 +82,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
title: const Text("Meta Personalizada", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), title: Text(AppStrings.customGoalTitle, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
content: TextField( content: TextField(
controller: controller, controller: controller,
keyboardType: const TextInputType.numberWithOptions(decimal: true), keyboardType: const TextInputType.numberWithOptions(decimal: true),
@@ -91,17 +91,17 @@ class _LogadoScreenState extends State<LogadoScreen> {
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Ex: 12.5", hintText: "Ex: 12.5",
hintStyle: const TextStyle(color: Colors.white24), hintStyle: const TextStyle(color: Colors.white24),
suffixText: "KM", suffixText: AppStrings.kmUnit,
suffixStyle: const TextStyle(color: Colors.white54), suffixStyle: const TextStyle(color: Colors.white54),
enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white24)), enabledBorder: const UnderlineInputBorder(borderSide: BorderSide(color: Colors.white24)),
focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: AppColors.coral)), focusedBorder: const UnderlineInputBorder(borderSide: BorderSide(color: AppColors.coral)),
), ),
autofocus: true, autofocus: true,
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Text("CANCELAR", style: TextStyle(color: Colors.white54)), child: Text(AppStrings.btnCancel, style: const TextStyle(color: Colors.white54)),
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
@@ -117,7 +117,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
backgroundColor: AppColors.coral, backgroundColor: AppColors.coral,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
), ),
child: const Text("DEFINIR", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), child: Text(AppStrings.btnDefine, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
), ),
], ],
), ),
@@ -127,7 +127,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = SupabaseService.currentUser; final user = SupabaseService.currentUser;
final userName = user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? 'Corredor'; final userName = user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? AppStrings.userPlaceholder;
return Scaffold( return Scaffold(
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
@@ -210,9 +210,9 @@ class _LogadoScreenState extends State<LogadoScreen> {
const SizedBox(height: 30), const SizedBox(height: 30),
// Personal Bests Section // Personal Bests Section
const Text( Text(
"RECORDS PESSOAIS", AppStrings.personalRecords,
style: TextStyle( style: const TextStyle(
color: Colors.white38, color: Colors.white38,
fontSize: 11, fontSize: 11,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
@@ -247,9 +247,9 @@ class _LogadoScreenState extends State<LogadoScreen> {
const SizedBox(height: 25), const SizedBox(height: 25),
// Steps Section (Atividade Geral) // Steps Section (Atividade Geral)
const Text( Text(
"ATIVIDADE GERAL", AppStrings.generalActivity,
style: TextStyle( style: const TextStyle(
color: Colors.white38, color: Colors.white38,
fontSize: 11, fontSize: 11,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
@@ -260,7 +260,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
_buildWideRecordCard( _buildWideRecordCard(
AppStrings.steps, AppStrings.steps,
_steps.toString(), _steps.toString(),
"passos hoje", AppStrings.stepsToday,
Icons.directions_walk_rounded, Icons.directions_walk_rounded,
AppColors.success, AppColors.success,
), ),
@@ -347,9 +347,9 @@ class _LogadoScreenState extends State<LogadoScreen> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Text(
AppStrings.dailyGoal, AppStrings.dailyGoal,
style: TextStyle(color: Colors.white54, fontWeight: FontWeight.bold, letterSpacing: 1), style: const TextStyle(color: Colors.white54, fontWeight: FontWeight.bold, letterSpacing: 1),
), ),
if (_dailyGoal > 0) if (_dailyGoal > 0)
Text( Text(
@@ -388,9 +388,9 @@ class _LogadoScreenState extends State<LogadoScreen> {
child: const Icon(Icons.add_task_rounded, color: AppColors.coral, size: 40), child: const Icon(Icons.add_task_rounded, color: AppColors.coral, size: 40),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
const Text( Text(
"DEFINIR META", AppStrings.setGoal,
style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w900, letterSpacing: 1), style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w900, letterSpacing: 1),
), ),
], ],
), ),
@@ -399,7 +399,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Text("DISTÂNCIA", style: TextStyle(color: Colors.white38, fontSize: 10, fontWeight: FontWeight.bold, letterSpacing: 2)), Text(AppStrings.distance, style: const TextStyle(color: Colors.white38, fontSize: 10, fontWeight: FontWeight.bold, letterSpacing: 2)),
Text( Text(
_currentDistance.toStringAsFixed(1), _currentDistance.toStringAsFixed(1),
style: const TextStyle(color: Colors.white, fontSize: 48, fontWeight: FontWeight.w900), style: const TextStyle(color: Colors.white, fontSize: 48, fontWeight: FontWeight.w900),
@@ -416,9 +416,9 @@ class _LogadoScreenState extends State<LogadoScreen> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
_buildSimpleStat("PASSOS", "${(_steps / 1000).toStringAsFixed(1)}k"), _buildSimpleStat(AppStrings.steps, "${(_steps / 1000).toStringAsFixed(1)}k"),
const SizedBox(width: 40), const SizedBox(width: 40),
_buildSimpleStat("TEMPO", "${_totalTimeMinutes}m"), _buildSimpleStat(AppStrings.time, "${_totalTimeMinutes}m"),
], ],
) )
], ],

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../constants/app_colors.dart'; import '../constants/app_colors.dart';
import '../constants/app_strings.dart';
import '../services/supabase_service.dart'; import '../services/supabase_service.dart';
class SettingsScreen extends StatefulWidget { class SettingsScreen extends StatefulWidget {
@@ -18,15 +19,15 @@ class _SettingsScreenState extends State<SettingsScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = SupabaseService.currentUser; final user = SupabaseService.currentUser;
final userName = final userName =
user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? 'Usuário'; user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? AppStrings.userPlaceholder;
final userEmail = user?.email ?? 'usuario@exemplo.com'; final userEmail = user?.email ?? 'usuario@exemplo.com';
return Scaffold( return Scaffold(
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
appBar: AppBar( appBar: AppBar(
title: const Text( title: Text(
'CONFIGURAÇÕES', AppStrings.settingsTitle,
style: TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -93,8 +94,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
icon: const Icon(Icons.edit, color: AppColors.buttonColor), icon: const Icon(Icons.edit, color: AppColors.buttonColor),
onPressed: () { onPressed: () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('Editar perfil'), content: Text(AppStrings.editProfile),
backgroundColor: AppColors.buttonColor, backgroundColor: AppColors.buttonColor,
), ),
); );
@@ -116,7 +117,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
children: [ children: [
_buildSettingsItem( _buildSettingsItem(
icon: Icons.schedule, icon: Icons.schedule,
title: 'Ajustar Data e Hora', title: AppStrings.adjustDateTime,
onTap: () { onTap: () {
_showDatePicker(context); _showDatePicker(context);
}, },
@@ -124,7 +125,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.dark_mode, icon: Icons.dark_mode,
title: 'Modo Noturno', title: AppStrings.nightMode,
trailing: Switch( trailing: Switch(
value: _isNightMode, value: _isNightMode,
activeThumbColor: AppColors.buttonColor, activeThumbColor: AppColors.buttonColor,
@@ -138,7 +139,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.language, icon: Icons.language,
title: 'Idioma', title: AppStrings.language,
trailing: Text( trailing: Text(
_selectedLanguage, _selectedLanguage,
style: TextStyle( style: TextStyle(
@@ -153,11 +154,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.accessibility, icon: Icons.accessibility,
title: 'Acessibilidade', title: AppStrings.accessibility,
onTap: () { onTap: () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('Acessibilidade'), content: Text(AppStrings.accessibility),
backgroundColor: AppColors.buttonColor, backgroundColor: AppColors.buttonColor,
), ),
); );
@@ -166,7 +167,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.notifications, icon: Icons.notifications,
title: 'Notificações', title: AppStrings.notifications,
trailing: Switch( trailing: Switch(
value: _notificationsEnabled, value: _notificationsEnabled,
onChanged: (value) { onChanged: (value) {
@@ -180,11 +181,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.privacy_tip, icon: Icons.privacy_tip,
title: 'Privacidade e Segurança', title: AppStrings.privacySecurity,
onTap: () { onTap: () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('Privacidade e Segurança'), content: Text(AppStrings.privacySecurity),
backgroundColor: AppColors.buttonColor, backgroundColor: AppColors.buttonColor,
), ),
); );
@@ -193,11 +194,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.description, icon: Icons.description,
title: 'Termos de Uso', title: AppStrings.termsOfUse,
onTap: () { onTap: () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('Termos de Uso'), content: Text(AppStrings.termsOfUse),
backgroundColor: AppColors.buttonColor, backgroundColor: AppColors.buttonColor,
), ),
); );
@@ -206,7 +207,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildDivider(), _buildDivider(),
_buildSettingsItem( _buildSettingsItem(
icon: Icons.info, icon: Icons.info,
title: 'Sobre', title: AppStrings.about,
onTap: () { onTap: () {
_showAboutDialog(context); _showAboutDialog(context);
}, },
@@ -231,9 +232,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
), ),
child: const Text( child: Text(
'Sair', AppStrings.logout,
style: TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -287,7 +288,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
if (date != null && mounted) { if (date != null && mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Data selecionada: ${date.toString().split(' ')[0]}'), content: Text('${AppStrings.dateSelected}: ${date.toString().split(' ')[0]}'),
backgroundColor: AppColors.buttonColor, backgroundColor: AppColors.buttonColor,
), ),
); );
@@ -300,9 +301,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
title: const Text( title: Text(
'Selecionar Idioma', AppStrings.selectLanguage,
style: TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
), ),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -315,9 +316,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Text( child: Text(
'Cancelar', AppStrings.btnCancel,
style: TextStyle(color: AppColors.buttonColor), style: const TextStyle(color: AppColors.buttonColor),
), ),
), ),
], ],
@@ -332,18 +333,25 @@ class _SettingsScreenState extends State<SettingsScreen> {
value: language, value: language,
groupValue: _selectedLanguage, groupValue: _selectedLanguage,
onChanged: (value) { onChanged: (value) {
setState(() { if (value != null) {
_selectedLanguage = value!; setState(() {
}); _selectedLanguage = value;
Navigator.pop(context); AppStrings.setLanguage(value);
});
Navigator.pop(context);
// Force rebuild of current screen to apply changes
setState(() {});
}
}, },
fillColor: WidgetStateProperty.all(AppColors.buttonColor), fillColor: WidgetStateProperty.all(AppColors.buttonColor),
), ),
onTap: () { onTap: () {
setState(() { setState(() {
_selectedLanguage = language; _selectedLanguage = language;
AppStrings.setLanguage(language);
}); });
Navigator.pop(context); Navigator.pop(context);
setState(() {});
}, },
); );
} }
@@ -353,33 +361,33 @@ class _SettingsScreenState extends State<SettingsScreen> {
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
title: const Text('Sobre', style: TextStyle(color: Colors.white)), title: Text(AppStrings.about, style: const TextStyle(color: Colors.white)),
content: const Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Run Vision Pro', AppStrings.appTitle,
style: TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
SizedBox(height: 8), const SizedBox(height: 8),
Text('Versão: 1.0.0', style: TextStyle(color: Colors.white70)), Text('${AppStrings.version}: 1.0.0', style: const TextStyle(color: Colors.white70)),
SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'Aplicativo de corrida com estatísticas e mapas', AppStrings.appDescription,
style: TextStyle(color: Colors.white70), style: const TextStyle(color: Colors.white70),
), ),
], ],
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Text( child: Text(
'OK', AppStrings.btnOk,
style: TextStyle(color: AppColors.buttonColor), style: const TextStyle(color: AppColors.buttonColor),
), ),
), ),
], ],
@@ -392,20 +400,20 @@ class _SettingsScreenState extends State<SettingsScreen> {
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
backgroundColor: AppColors.backgroundGrey, backgroundColor: AppColors.backgroundGrey,
title: const Text( title: Text(
'Confirmar Logout', AppStrings.confirmLogout,
style: TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
), ),
content: const Text( content: Text(
'Tem certeza que deseja sair?', AppStrings.confirmLogoutMessage,
style: TextStyle(color: Colors.white70), style: const TextStyle(color: Colors.white70),
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: const Text( child: Text(
'Cancelar', AppStrings.btnCancel,
style: TextStyle(color: AppColors.buttonColor), style: const TextStyle(color: AppColors.buttonColor),
), ),
), ),
TextButton( TextButton(
@@ -413,7 +421,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Navigator.pop(context); Navigator.pop(context);
Navigator.pushReplacementNamed(context, '/'); Navigator.pushReplacementNamed(context, '/');
}, },
child: const Text('Sair', style: TextStyle(color: Colors.red)), child: Text(AppStrings.logout, style: const TextStyle(color: Colors.red)),
), ),
], ],
), ),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../constants/app_colors.dart'; import '../constants/app_colors.dart';
import '../constants/app_strings.dart';
import '../services/supabase_service.dart'; import '../services/supabase_service.dart';
import '../screens/logado_screen.dart'; import '../screens/logado_screen.dart';
@@ -33,7 +34,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
// Show success message above the sheet // Show success message above the sheet
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Login realizado com sucesso!'), content: Text(AppStrings.loginSuccess),
backgroundColor: Colors.green, backgroundColor: Colors.green,
), ),
); );
@@ -66,7 +67,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
if (email.isEmpty) { if (email.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Por favor, insira seu email'), content: Text(AppStrings.validatorEmailEmpty),
backgroundColor: Colors.orange, backgroundColor: Colors.orange,
), ),
); );
@@ -82,7 +83,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
// Show success message above the sheet // Show success message above the sheet
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Email de redefinição enviado!'), content: Text(AppStrings.resetPasswordEmailSent),
backgroundColor: Colors.green, backgroundColor: Colors.green,
), ),
); );
@@ -151,7 +152,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
// Title // Title
const Text( const Text(
'Entrar', AppStrings.loginTitle,
style: TextStyle( style: TextStyle(
fontSize: 28, fontSize: 28,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -162,7 +163,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
// Email field // Email field
const Text( const Text(
'Email', AppStrings.labelEmail,
style: TextStyle(fontSize: 16, color: Colors.white70), style: TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@@ -177,16 +178,16 @@ class _EntrarSheetState extends State<EntrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: 'seu@email.com', hintText: AppStrings.hintEmail,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, insira seu email'; return AppStrings.validatorEmailEmpty;
} }
if (!value.contains('@')) { if (!value.contains('@')) {
return 'Email inválido'; return AppStrings.validatorEmailInvalid;
} }
return null; return null;
}, },
@@ -196,7 +197,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
// Password field // Password field
const Text( const Text(
'Senha', AppStrings.labelPassword,
style: TextStyle(fontSize: 16, color: Colors.white70), style: TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@@ -210,16 +211,16 @@ class _EntrarSheetState extends State<EntrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: '••••••••', hintText: AppStrings.hintPassword,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, insira sua senha'; return AppStrings.validatorPasswordEmpty;
} }
if (value.length < 6) { if (value.length < 6) {
return 'Senha deve ter pelo menos 6 caracteres'; return AppStrings.validatorPasswordLength;
} }
return null; return null;
}, },
@@ -245,7 +246,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
color: Colors.white, color: Colors.white,
) )
: const Text( : const Text(
'Entrar', AppStrings.btnLogin,
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@@ -260,7 +261,7 @@ class _EntrarSheetState extends State<EntrarSheet> {
child: TextButton( child: TextButton(
onPressed: _handlePasswordReset, onPressed: _handlePasswordReset,
child: const Text( child: const Text(
'Esqueceu a senha?', AppStrings.forgotPassword,
style: TextStyle(color: Colors.white70, fontSize: 16), style: TextStyle(color: Colors.white70, fontSize: 16),
), ),
), ),

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../services/supabase_service.dart'; import '../services/supabase_service.dart';
import '../constants/app_colors.dart'; import '../constants/app_colors.dart';
import '../constants/app_strings.dart';
import '../screens/logado_screen.dart'; import '../screens/logado_screen.dart';
class RegistrarSheet extends StatefulWidget { class RegistrarSheet extends StatefulWidget {
@@ -39,8 +40,8 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
// Show success message above the sheet // Show success message above the sheet
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('Conta criada com sucesso! Verifique seu email.'), content: Text(AppStrings.registerSuccess),
backgroundColor: Colors.green, backgroundColor: Colors.green,
), ),
); );
@@ -133,9 +134,9 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
const SizedBox(height: 24), const SizedBox(height: 24),
// Title // Title
const Text( Text(
'Registrar', AppStrings.registerTitle,
style: TextStyle( style: const TextStyle(
fontSize: 28, fontSize: 28,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
@@ -144,9 +145,9 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
const SizedBox(height: 32), const SizedBox(height: 32),
// Name field // Name field
const Text( Text(
'Nome', AppStrings.labelName,
style: TextStyle(fontSize: 16, color: Colors.white70), style: const TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
TextFormField( TextFormField(
@@ -158,16 +159,16 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: 'Seu nome completo', hintText: AppStrings.hintName,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, insira seu nome'; return AppStrings.validatorNameEmpty;
} }
if (value.length < 3) { if (value.length < 3) {
return 'Nome deve ter pelo menos 3 caracteres'; return AppStrings.validatorNameLength;
} }
return null; return null;
}, },
@@ -175,9 +176,9 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
const SizedBox(height: 20), const SizedBox(height: 20),
// Email field // Email field
const Text( Text(
'Email', AppStrings.labelEmail,
style: TextStyle(fontSize: 16, color: Colors.white70), style: const TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
TextFormField( TextFormField(
@@ -189,16 +190,16 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: 'seu@email.com', hintText: AppStrings.hintEmail,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, insira seu email'; return AppStrings.validatorEmailEmpty;
} }
if (!value.contains('@')) { if (!value.contains('@')) {
return 'Email inválido'; return AppStrings.validatorEmailInvalid;
} }
return null; return null;
}, },
@@ -206,9 +207,9 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
const SizedBox(height: 20), const SizedBox(height: 20),
// Password field // Password field
const Text( Text(
'Senha', AppStrings.labelPassword,
style: TextStyle(fontSize: 16, color: Colors.white70), style: const TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
TextFormField( TextFormField(
@@ -221,16 +222,16 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: '••••••••', hintText: AppStrings.hintPassword,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, insira sua senha'; return AppStrings.validatorPasswordEmpty;
} }
if (value.length < 6) { if (value.length < 6) {
return 'Senha deve ter pelo menos 6 caracteres'; return AppStrings.validatorPasswordLength;
} }
return null; return null;
}, },
@@ -238,9 +239,9 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
const SizedBox(height: 20), const SizedBox(height: 20),
// Confirm password field // Confirm password field
const Text( Text(
'Confirmar Senha', AppStrings.labelConfirmPassword,
style: TextStyle(fontSize: 16, color: Colors.white70), style: const TextStyle(fontSize: 16, color: Colors.white70),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
TextFormField( TextFormField(
@@ -253,16 +254,16 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none, borderSide: BorderSide.none,
), ),
hintText: '••••••••', hintText: AppStrings.hintPassword,
hintStyle: const TextStyle(color: Colors.white38), hintStyle: const TextStyle(color: Colors.white38),
), ),
style: const TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Por favor, confirme sua senha'; return AppStrings.validatorConfirmPasswordEmpty;
} }
if (value != _passwordController.text) { if (value != _passwordController.text) {
return 'Senhas não coincidem'; return AppStrings.validatorConfirmPasswordMatch;
} }
return null; return null;
}, },
@@ -285,16 +286,16 @@ class _RegistrarSheetState extends State<RegistrarSheet> {
), ),
child: _isLoading child: _isLoading
? const CircularProgressIndicator(color: Colors.white) ? const CircularProgressIndicator(color: Colors.white)
: const Text( : Text(
'Registrar', AppStrings.btnRegister,
style: TextStyle( style: const TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),
), ),
), ),
SizedBox(height: 40), const SizedBox(height: 40),
], ],
), ),
); );

View File

@@ -85,10 +85,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@@ -548,18 +548,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.19" version: "0.12.17"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.0" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@@ -945,10 +945,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.10" version: "0.7.7"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description: