simulacion de estados y flujo de notificacion, modificacion de estilos en todas las vistas
This commit is contained in:
@@ -75,95 +75,170 @@ class _MyHouseScreenState extends State<MyHouseScreen> {
|
||||
if (_casa == null) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.background,
|
||||
appBar: AppBar(title: const Text('Mi casa')),
|
||||
body: const Center(child: Text('No tienes un domicilio registrado.')),
|
||||
body: Column(
|
||||
children: [
|
||||
_buildPageHeader(context, showEdit: false),
|
||||
const Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'No tienes un domicilio registrado.',
|
||||
style: TextStyle(fontSize: 15, color: AppTheme.textSecondary),
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildAddressButton(context),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.background,
|
||||
appBar: AppBar(
|
||||
title: const Text('Mi casa'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
onPressed: () => _mostrarEditarDireccion(context),
|
||||
tooltip: 'Editar dirección',
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(child: _buildPageHeader(context, showEdit: true)),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
const AppSectionTitle(title: 'Domicilio registrado'),
|
||||
_CasaCard(casa: _casa!),
|
||||
const SizedBox(height: 20),
|
||||
const AppSectionTitle(title: 'Mapa del Sector (Restringido)'),
|
||||
_MapaColoniaRestringido(
|
||||
colonia: _casa!.colonia,
|
||||
lat: _casa!.lat,
|
||||
lng: _casa!.lng,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const AppSectionTitle(title: 'Radio de alerta'),
|
||||
_RadioAlertaCard(
|
||||
radioActual: _casa!.radioAlertaMetros,
|
||||
onChanged: (v) => setState(
|
||||
() => _casa = _casa!.copyWith(radioAlertaMetros: v),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const AppSectionTitle(title: 'Notificaciones'),
|
||||
_NotificacionesCard(
|
||||
casa: _casa!,
|
||||
onAlertaCercanaChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(alertaCercana: v)),
|
||||
onAlertaMediaChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(alertaMedia: v)),
|
||||
onRecordatorioChanged: (v) => setState(
|
||||
() => _casa = _casa!.copyWith(recordatorioDiario: v),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const AppSectionTitle(title: 'Horario del camión'),
|
||||
_HorarioCard(),
|
||||
const SizedBox(height: 24),
|
||||
]),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(child: _buildAddressButton(context)),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPageHeader(BuildContext context, {required bool showEdit}) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
20,
|
||||
MediaQuery.of(context).padding.top + 12,
|
||||
20,
|
||||
24,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xFF4A0E26), Color(0xFF9B1B4A)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(28),
|
||||
bottomRight: Radius.circular(28),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
_CasaCard(casa: _casa!),
|
||||
const SizedBox(height: 16),
|
||||
const AppSectionTitle(title: 'Mapa del Sector (Restringido)'),
|
||||
_MapaColoniaRestringido(
|
||||
colonia: _casa!.colonia,
|
||||
lat: _casa!.lat,
|
||||
lng: _casa!.lng,
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.home_outlined,
|
||||
color: Colors.white,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const AppSectionTitle(title: 'Radio de alerta'),
|
||||
_RadioAlertaCard(
|
||||
radioActual: _casa!.radioAlertaMetros,
|
||||
onChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(radioAlertaMetros: v)),
|
||||
const SizedBox(width: 14),
|
||||
const Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Mi Casa',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
'Domicilio registrado',
|
||||
style: TextStyle(fontSize: 13, color: Colors.white70),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const AppSectionTitle(title: 'Notificaciones'),
|
||||
_NotificacionesCard(
|
||||
casa: _casa!,
|
||||
onAlertaCercanaChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(alertaCercana: v)),
|
||||
onAlertaMediaChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(alertaMedia: v)),
|
||||
onRecordatorioChanged: (v) =>
|
||||
setState(() => _casa = _casa!.copyWith(recordatorioDiario: v)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const AppSectionTitle(title: 'Horario del camión'),
|
||||
_HorarioCard(),
|
||||
const SizedBox(height: 16),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
if (showEdit)
|
||||
GestureDetector(
|
||||
onTap: () => _mostrarEditarDireccion(context),
|
||||
child: Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.edit_outlined,
|
||||
color: Colors.white,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAddressButton(BuildContext context) {
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 12, 24, 96),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () async {
|
||||
final added = await context.push<bool>('/add-address');
|
||||
if (added == true && mounted) {
|
||||
setState(() => _isLoading = true);
|
||||
_cargarDomicilio();
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppTheme.radiusLg),
|
||||
border: Border.all(color: AppTheme.primaryMid),
|
||||
boxShadow: AppTheme.softShadow,
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add_home_outlined,
|
||||
color: AppTheme.primary,
|
||||
size: 20,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Agregar otra dirección',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppTheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
icon: const Icon(Icons.add_home_outlined, size: 20),
|
||||
label: const Text('Agregar otra dirección'),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -191,64 +266,82 @@ class _CasaCard extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppTheme.radiusLg),
|
||||
border: Border.all(color: AppTheme.primaryMid, width: 0.8),
|
||||
border: Border.all(color: AppTheme.border, width: 0.5),
|
||||
boxShadow: AppTheme.softShadow,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(AppTheme.radiusLg - 0.5),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.primaryLight,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.home_outlined,
|
||||
color: AppTheme.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Container(width: 3, color: AppTheme.primary),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
casa.alias,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppTheme.textPrimary,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.primaryLight,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.home_outlined,
|
||||
color: AppTheme.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
casa.alias,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppTheme.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
AppStatusBadge.green(
|
||||
casa.activa ? 'Activa' : 'Inactiva',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
AppStatusBadge.green(casa.activa ? 'Activa' : 'Inactiva'),
|
||||
],
|
||||
const SizedBox(height: 14),
|
||||
const Divider(color: AppTheme.borderLight),
|
||||
const SizedBox(height: 10),
|
||||
_DetailRow(
|
||||
icon: Icons.location_on_outlined,
|
||||
text: casa.direccionCompleta,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_DetailRow(
|
||||
icon: Icons.radar_outlined,
|
||||
text:
|
||||
'Alerta a ${casa.radioAlertaMetros} m de distancia',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
const Divider(color: AppTheme.borderLight),
|
||||
const SizedBox(height: 10),
|
||||
_DetailRow(
|
||||
icon: Icons.location_on_outlined,
|
||||
text: casa.direccionCompleta,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_DetailRow(
|
||||
icon: Icons.radar_outlined,
|
||||
text: 'Alerta a ${casa.radioAlertaMetros} m de distancia',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -263,14 +356,16 @@ class _MapaColoniaRestringido extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final center = kColoniaCenter(colonia);
|
||||
final center =
|
||||
kColoniasCoordinates[colonia] ?? const LatLng(20.5222, -100.8123);
|
||||
final pin = (lat != null && lng != null) ? LatLng(lat!, lng!) : center;
|
||||
|
||||
return Container(
|
||||
height: 200,
|
||||
height: 220,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(AppTheme.radiusLg),
|
||||
border: Border.all(color: AppTheme.border, width: 1),
|
||||
boxShadow: AppTheme.softShadow,
|
||||
),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: FlutterMap(
|
||||
|
||||
Reference in New Issue
Block a user