Settings finalizadas
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../constants/app_colors.dart';
|
||||
import '../constants/app_strings.dart';
|
||||
import '../services/supabase_service.dart';
|
||||
@@ -16,10 +17,10 @@ class LogadoScreen extends StatefulWidget {
|
||||
|
||||
class _LogadoScreenState extends State<LogadoScreen> {
|
||||
// Estado dinâmico do utilizador
|
||||
double _dailyGoal = 0.0; // 0.0 significa que ainda não foi definida
|
||||
double _dailyGoal = 0.0;
|
||||
double _currentDistance = 0.0;
|
||||
double _bestDistance = 12.4; // Exemplo de recorde
|
||||
double _bestSpeed = 16.8; // Exemplo de recorde
|
||||
double _bestDistance = 12.4;
|
||||
double _bestSpeed = 16.8;
|
||||
int _steps = 0;
|
||||
int _totalTimeMinutes = 0;
|
||||
|
||||
@@ -32,15 +33,38 @@ class _LogadoScreenState extends State<LogadoScreen> {
|
||||
}
|
||||
|
||||
Future<void> _loadUserData() async {
|
||||
// No futuro, aqui buscaríamos os dados reais do Supabase ou Local Storage
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final lastGoalDate = prefs.getString('last_goal_date');
|
||||
final today = DateTime.now().toIso8601String().split('T')[0];
|
||||
|
||||
setState(() {
|
||||
// Simulação de dados carregados
|
||||
_currentDistance = 0.0; // Começa o dia a zero
|
||||
// Reset meta se o dia mudou
|
||||
if (lastGoalDate != today) {
|
||||
_dailyGoal = 0.0;
|
||||
prefs.remove('daily_goal');
|
||||
} else {
|
||||
_dailyGoal = prefs.getDouble('daily_goal') ?? 0.0;
|
||||
}
|
||||
|
||||
// No futuro, estes viriam do Supabase ou histórico local
|
||||
_currentDistance = 0.0;
|
||||
_steps = 0;
|
||||
_totalTimeMinutes = 0;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _saveGoal(double goal) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final today = DateTime.now().toIso8601String().split('T')[0];
|
||||
|
||||
await prefs.setDouble('daily_goal', goal);
|
||||
await prefs.setString('last_goal_date', today);
|
||||
|
||||
setState(() {
|
||||
_dailyGoal = goal;
|
||||
});
|
||||
}
|
||||
|
||||
void _showGoalDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -54,9 +78,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
|
||||
...[5, 10, 15, 20].map((km) => ListTile(
|
||||
title: Text("$km ${AppStrings.kmUnit}", style: const TextStyle(color: Colors.white)),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_dailyGoal = km.toDouble();
|
||||
});
|
||||
_saveGoal(km.toDouble());
|
||||
Navigator.pop(context);
|
||||
},
|
||||
)),
|
||||
@@ -107,9 +129,7 @@ class _LogadoScreenState extends State<LogadoScreen> {
|
||||
onPressed: () {
|
||||
final value = double.tryParse(controller.text);
|
||||
if (value != null && value > 0) {
|
||||
setState(() {
|
||||
_dailyGoal = value;
|
||||
});
|
||||
_saveGoal(value);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
@@ -126,194 +146,187 @@ class _LogadoScreenState extends State<LogadoScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final user = SupabaseService.currentUser;
|
||||
final userName = user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? AppStrings.userPlaceholder;
|
||||
return ValueListenableBuilder<AppLanguage>(
|
||||
valueListenable: AppStrings.languageNotifier,
|
||||
builder: (context, language, child) {
|
||||
final user = SupabaseService.currentUser;
|
||||
final userName = user?.userMetadata?['name'] ?? user?.email?.split('@')[0] ?? AppStrings.userPlaceholder;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Stack(
|
||||
children: [
|
||||
// Background Gradient
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFF2D2D31), AppColors.background],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
// Header Bar
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppStrings.welcome.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
userName,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildIconButton(
|
||||
Icons.bluetooth_audio_rounded,
|
||||
() => Navigator.push(context, MaterialPageRoute(builder: (context) => const BluetoothConnectionScreen())),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_buildIconButton(
|
||||
Icons.settings_rounded,
|
||||
() => Navigator.push(context, MaterialPageRoute(builder: (context) => const SettingsScreen())),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Main Tracking Card (Meta Diária)
|
||||
_buildMainTrackingCard(),
|
||||
|
||||
const SizedBox(height: 30),
|
||||
|
||||
// Personal Bests Section
|
||||
Text(
|
||||
AppStrings.personalRecords,
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildRecordCard(
|
||||
AppStrings.bestDistance,
|
||||
_bestDistance.toStringAsFixed(1),
|
||||
AppStrings.kmUnit,
|
||||
Icons.auto_graph_rounded,
|
||||
AppColors.coral,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
Expanded(
|
||||
child: _buildRecordCard(
|
||||
AppStrings.bestSpeed,
|
||||
_bestSpeed.toStringAsFixed(1),
|
||||
AppStrings.kmhUnit,
|
||||
Icons.speed_rounded,
|
||||
Colors.cyanAccent,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 25),
|
||||
|
||||
// Steps Section (Atividade Geral)
|
||||
Text(
|
||||
AppStrings.generalActivity,
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
_buildWideRecordCard(
|
||||
AppStrings.steps,
|
||||
_steps.toString(),
|
||||
AppStrings.stepsToday,
|
||||
Icons.directions_walk_rounded,
|
||||
AppColors.success,
|
||||
),
|
||||
|
||||
const SizedBox(height: 120), // Espaço para o botão inferior
|
||||
],
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFF2D2D31), AppColors.background],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Bottom Action Button
|
||||
Positioned(
|
||||
bottom: 30,
|
||||
left: 50,
|
||||
right: 50,
|
||||
child: Container(
|
||||
height: 70,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.coral.withValues(alpha: 0.3),
|
||||
blurRadius: 25,
|
||||
spreadRadius: -5,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => const GoogleMapScreen())),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.coral,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
const Icon(Icons.play_arrow_rounded, size: 30),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
AppStrings.startTraining,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 1.5),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppStrings.welcome.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
userName,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildIconButton(
|
||||
Icons.bluetooth_audio_rounded,
|
||||
() => Navigator.push(context, MaterialPageRoute(builder: (context) => const BluetoothConnectionScreen())),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_buildIconButton(
|
||||
Icons.settings_rounded,
|
||||
() => Navigator.push(context, MaterialPageRoute(builder: (context) => const SettingsScreen())),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
_buildMainTrackingCard(),
|
||||
const SizedBox(height: 30),
|
||||
Text(
|
||||
AppStrings.personalRecords,
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildRecordCard(
|
||||
AppStrings.bestDistance,
|
||||
_bestDistance.toStringAsFixed(1),
|
||||
AppStrings.kmUnit,
|
||||
Icons.auto_graph_rounded,
|
||||
AppColors.coral,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
Expanded(
|
||||
child: _buildRecordCard(
|
||||
AppStrings.bestSpeed,
|
||||
_bestSpeed.toStringAsFixed(1),
|
||||
AppStrings.kmhUnit,
|
||||
Icons.speed_rounded,
|
||||
Colors.cyanAccent,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Text(
|
||||
AppStrings.generalActivity,
|
||||
style: const TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w900,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
_buildWideRecordCard(
|
||||
AppStrings.steps,
|
||||
_steps.toString(),
|
||||
AppStrings.stepsToday,
|
||||
Icons.directions_walk_rounded,
|
||||
AppColors.success,
|
||||
),
|
||||
const SizedBox(height: 120),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Positioned(
|
||||
bottom: 30,
|
||||
left: 50,
|
||||
right: 50,
|
||||
child: Container(
|
||||
height: 70,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.coral.withValues(alpha: 0.3),
|
||||
blurRadius: 25,
|
||||
spreadRadius: -5,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => const GoogleMapScreen())),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.coral,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.play_arrow_rounded, size: 30),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
AppStrings.startTraining,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -352,9 +365,25 @@ class _LogadoScreenState extends State<LogadoScreen> {
|
||||
style: const TextStyle(color: Colors.white54, fontWeight: FontWeight.bold, letterSpacing: 1),
|
||||
),
|
||||
if (_dailyGoal > 0)
|
||||
Text(
|
||||
"${(_progress * 100).toInt()}%",
|
||||
style: const TextStyle(color: AppColors.coral, fontWeight: FontWeight.w900),
|
||||
GestureDetector(
|
||||
onTap: _showGoalDialog,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.coral.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"${(_progress * 100).toInt()}%",
|
||||
style: const TextStyle(color: AppColors.coral, fontWeight: FontWeight.w900),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
const Icon(Icons.edit_rounded, color: AppColors.coral, size: 14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user