fix phone dashboard
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class AppBackButton extends StatelessWidget {
|
||||
final String fallbackRoute;
|
||||
final Color? color;
|
||||
|
||||
const AppBackButton({
|
||||
super.key,
|
||||
required this.fallbackRoute,
|
||||
this.color,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios_new_rounded, color: color),
|
||||
onPressed: () {
|
||||
if (context.canPop()) {
|
||||
context.pop();
|
||||
return;
|
||||
}
|
||||
context.go(fallbackRoute);
|
||||
},
|
||||
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ class ErrorView extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
@@ -19,7 +21,7 @@ class ErrorView extends StatelessWidget {
|
||||
Text(
|
||||
message,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: Color(0xFF6B7280)),
|
||||
style: TextStyle(color: cs.onSurfaceVariant),
|
||||
),
|
||||
if (onRetry != null) ...[
|
||||
const SizedBox(height: 16),
|
||||
|
||||
@@ -9,9 +9,12 @@ class LoadingList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Shimmer.fromColors(
|
||||
baseColor: const Color(0xFFE5E7EB),
|
||||
highlightColor: const Color(0xFFF9FAFB),
|
||||
baseColor: isDark ? const Color(0xFF2F3145) : const Color(0xFFE5E7EB),
|
||||
highlightColor:
|
||||
isDark ? const Color(0xFF3A3C54) : const Color(0xFFF9FAFB),
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: count,
|
||||
@@ -19,7 +22,7 @@ class LoadingList extends StatelessWidget {
|
||||
itemBuilder: (_, _) => Container(
|
||||
height: itemHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: isDark ? const Color(0xFF28293A) : Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -12,6 +12,8 @@ class ReservationCard extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final fmt = DateFormat('MMM d, yyyy');
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
return Card(
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
@@ -39,34 +41,44 @@ class ReservationCard extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
reservation.customer!.fullName,
|
||||
style: const TextStyle(
|
||||
fontSize: 13, color: Color(0xFF6B7280)),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.calendar_today,
|
||||
size: 14, color: Color(0xFF9CA3AF)),
|
||||
Icon(
|
||||
Icons.calendar_today,
|
||||
size: 14,
|
||||
color: cs.onSurfaceVariant.withValues(alpha: 0.8),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'${fmt.format(reservation.startDate)} → ${fmt.format(reservation.endDate)}',
|
||||
style: const TextStyle(
|
||||
fontSize: 13, color: Color(0xFF6B7280)),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.attach_money,
|
||||
size: 14, color: Color(0xFF9CA3AF)),
|
||||
Icon(
|
||||
Icons.attach_money,
|
||||
size: 14,
|
||||
color: cs.onSurfaceVariant.withValues(alpha: 0.8),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'\$${(reservation.totalAmount / 100).toStringAsFixed(2)}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF111928),
|
||||
color: cs.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
@@ -6,6 +6,8 @@ class StatCard extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
final String? subtitle;
|
||||
final double? change;
|
||||
final String? footerLabel;
|
||||
|
||||
const StatCard({
|
||||
super.key,
|
||||
@@ -14,10 +16,14 @@ class StatCard extends StatelessWidget {
|
||||
required this.icon,
|
||||
required this.color,
|
||||
this.subtitle,
|
||||
this.change,
|
||||
this.footerLabel,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
return Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -40,30 +46,62 @@ class StatCard extends StatelessWidget {
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF111928),
|
||||
color: cs.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF6B7280),
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
if (subtitle != null) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
subtitle!,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF9CA3AF),
|
||||
color: cs.onSurfaceVariant.withValues(alpha: 0.85),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (change != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'${change! >= 0 ? '+' : ''}${change!.toStringAsFixed(1)}%',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: change! > 0
|
||||
? const Color(0xFF0E9F6E)
|
||||
: change! < 0
|
||||
? const Color(0xFFE02424)
|
||||
: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
if (footerLabel != null) ...[
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
footerLabel!,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: cs.onSurfaceVariant.withValues(alpha: 0.85),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -12,6 +12,8 @@ class VehicleCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
return Card(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: InkWell(
|
||||
@@ -44,9 +46,9 @@ class VehicleCard extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
vehicle.licensePlate,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF6B7280),
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -66,13 +68,15 @@ class VehicleCard extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF3F4F6),
|
||||
color: cs.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
vehicle.category,
|
||||
style: const TextStyle(
|
||||
fontSize: 11, color: Color(0xFF6B7280)),
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user