brand theme, allot of features, allot of bug fixes
This commit is contained in:
parent
2ecd1c5b4e
commit
8e6aa6ea8c
@ -78,7 +78,7 @@ class _CollapsibleRoutesSidebarState extends ConsumerState<CollapsibleRoutesSide
|
||||
// On mobile, always show as collapsible
|
||||
if (isMobile) {
|
||||
return Container(
|
||||
color: isDarkMode ? SvrntyColors.almostBlack : Colors.white,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Column(
|
||||
children: [
|
||||
// Header with toggle button
|
||||
@ -125,7 +125,7 @@ class _CollapsibleRoutesSidebarState extends ConsumerState<CollapsibleRoutesSide
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
width: isExpanded ? 300 : 80,
|
||||
color: isDarkMode ? SvrntyColors.almostBlack : Colors.white,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Column(
|
||||
children: [
|
||||
// Header with toggle button
|
||||
|
||||
@ -578,37 +578,39 @@ class _DarkModeMapComponentState extends State<DarkModeMapComponent> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
// Photo button
|
||||
// Photo button (disabled when no delivery selected or warehouse delivery)
|
||||
Expanded(
|
||||
child: _buildBottomActionButton(
|
||||
label: 'Photo',
|
||||
icon: Icons.camera_alt,
|
||||
onPressed: () => widget.onAction?.call('photo'),
|
||||
onPressed: widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
|
||||
? () => widget.onAction?.call('photo')
|
||||
: null,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
// Note button (only enabled if delivery has notes)
|
||||
// Note button (only enabled if delivery has notes and not warehouse)
|
||||
Expanded(
|
||||
child: _buildBottomActionButton(
|
||||
label: 'Note',
|
||||
icon: Icons.note_add,
|
||||
onPressed: _hasNotes()
|
||||
onPressed: _hasNotes() && widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
|
||||
? () => widget.onAction?.call('note')
|
||||
: null,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
// Completed button
|
||||
// Completed button (disabled for warehouse delivery)
|
||||
Expanded(
|
||||
child: _buildBottomActionButton(
|
||||
label: widget.selectedDelivery?.delivered == true ? 'Undo' : 'Completed',
|
||||
icon: widget.selectedDelivery?.delivered == true ? Icons.undo : Icons.check_circle,
|
||||
onPressed: widget.selectedDelivery != null
|
||||
onPressed: widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
|
||||
? () => widget.onAction?.call(
|
||||
widget.selectedDelivery!.delivered ? 'uncomplete' : 'complete',
|
||||
)
|
||||
: null,
|
||||
isPrimary: widget.selectedDelivery != null && !widget.selectedDelivery!.delivered,
|
||||
isPrimary: widget.selectedDelivery != null && !widget.selectedDelivery!.delivered && !widget.selectedDelivery!.isWarehouseDelivery,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -145,14 +145,20 @@ class _DeliveryListItemState extends State<DeliveryListItem>
|
||||
: [],
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'${widget.delivery.deliveryIndex + 1}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
child: widget.delivery.isWarehouseDelivery
|
||||
? const Icon(
|
||||
Icons.warehouse,
|
||||
color: Colors.white,
|
||||
size: 32,
|
||||
)
|
||||
: Text(
|
||||
'${widget.delivery.deliveryIndex + 1}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_hasNote())
|
||||
@ -254,14 +260,20 @@ class _DeliveryListItemState extends State<DeliveryListItem>
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'${widget.delivery.deliveryIndex + 1}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
child: widget.delivery.isWarehouseDelivery
|
||||
? const Icon(
|
||||
Icons.warehouse,
|
||||
color: Colors.white,
|
||||
size: 24,
|
||||
)
|
||||
: Text(
|
||||
'${widget.delivery.deliveryIndex + 1}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
@ -36,6 +36,39 @@ class Delivery implements Serializable {
|
||||
required this.name,
|
||||
});
|
||||
|
||||
// Special warehouse ID constant
|
||||
static const int warehouseDeliveryId = -1;
|
||||
|
||||
// Check if this is the warehouse delivery
|
||||
bool get isWarehouseDelivery => id == warehouseDeliveryId;
|
||||
|
||||
// Create a static warehouse delivery item
|
||||
static Delivery createWarehouseDelivery() {
|
||||
return Delivery(
|
||||
id: warehouseDeliveryId,
|
||||
routeFragmentId: -1,
|
||||
deliveryIndex: 999,
|
||||
orders: const [],
|
||||
deliveryAddress: const DeliveryAddress(
|
||||
id: -1,
|
||||
line1: '3550 Rue de Cherbourg Suite 108',
|
||||
line2: '',
|
||||
postalCode: 'G8Y 6S6',
|
||||
city: 'Trois-Rivières',
|
||||
subdivision: 'QC',
|
||||
countryCode: 'CA',
|
||||
latitude: 46.3384605,
|
||||
longitude: -72.6080797,
|
||||
formattedAddress: '3550 Rue de Cherbourg Suite 108, Trois-Rivières, QC G8Y 6S6',
|
||||
),
|
||||
createdAt: DateTime.now().toIso8601String(),
|
||||
delivered: false,
|
||||
hasBeenSkipped: false,
|
||||
isSkipped: false,
|
||||
name: 'Return to Warehouse',
|
||||
);
|
||||
}
|
||||
|
||||
factory Delivery.fromJson(Map<String, dynamic> json) {
|
||||
return Delivery(
|
||||
id: json['id'] as int,
|
||||
|
||||
@ -2,41 +2,41 @@ import '../api/types.dart';
|
||||
|
||||
class DeliveryAddress implements Serializable {
|
||||
final int id;
|
||||
final String line1;
|
||||
final String line2;
|
||||
final String postalCode;
|
||||
final String city;
|
||||
final String subdivision;
|
||||
final String countryCode;
|
||||
final String? line1;
|
||||
final String? line2;
|
||||
final String? postalCode;
|
||||
final String? city;
|
||||
final String? subdivision;
|
||||
final String? countryCode;
|
||||
final double? latitude;
|
||||
final double? longitude;
|
||||
final String formattedAddress;
|
||||
final String? formattedAddress;
|
||||
|
||||
const DeliveryAddress({
|
||||
required this.id,
|
||||
required this.line1,
|
||||
required this.line2,
|
||||
required this.postalCode,
|
||||
required this.city,
|
||||
required this.subdivision,
|
||||
required this.countryCode,
|
||||
this.line1,
|
||||
this.line2,
|
||||
this.postalCode,
|
||||
this.city,
|
||||
this.subdivision,
|
||||
this.countryCode,
|
||||
this.latitude,
|
||||
this.longitude,
|
||||
required this.formattedAddress,
|
||||
this.formattedAddress,
|
||||
});
|
||||
|
||||
factory DeliveryAddress.fromJson(Map<String, dynamic> json) {
|
||||
return DeliveryAddress(
|
||||
id: json['id'] as int,
|
||||
line1: json['line1'] as String,
|
||||
line2: json['line2'] as String,
|
||||
postalCode: json['postalCode'] as String,
|
||||
city: json['city'] as String,
|
||||
subdivision: json['subdivision'] as String,
|
||||
countryCode: json['countryCode'] as String,
|
||||
line1: json['line1'] as String?,
|
||||
line2: json['line2'] as String?,
|
||||
postalCode: json['postalCode'] as String?,
|
||||
city: json['city'] as String?,
|
||||
subdivision: json['subdivision'] as String?,
|
||||
countryCode: json['countryCode'] as String?,
|
||||
latitude: json['latitude'] as double?,
|
||||
longitude: json['longitude'] as double?,
|
||||
formattedAddress: json['formattedAddress'] as String,
|
||||
formattedAddress: json['formattedAddress'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -292,6 +292,11 @@ class _DeliveriesPageState extends ConsumerState<DeliveriesPage> {
|
||||
String action,
|
||||
String? token,
|
||||
) async {
|
||||
// Prevent any actions on warehouse delivery except map navigation
|
||||
if (delivery.isWarehouseDelivery && action != 'map') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (token == null) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
ToastHelper.showError(context, l10n.authenticationRequired);
|
||||
@ -621,7 +626,7 @@ class DeliveryCard extends StatelessWidget {
|
||||
const SizedBox(height: 12),
|
||||
if (delivery.deliveryAddress != null)
|
||||
Text(
|
||||
delivery.deliveryAddress!.formattedAddress,
|
||||
delivery.deliveryAddress!.formattedAddress ?? '',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@ -520,6 +520,7 @@ class _RoutesPageState extends ConsumerState<RoutesPage> {
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.deliveryRoutes),
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: (routesData.isLoading || allDeliveriesData.isLoading)
|
||||
|
||||
@ -98,7 +98,18 @@ final deliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, rout
|
||||
},
|
||||
);
|
||||
|
||||
return result.whenSuccess((deliveries) => deliveries) ?? [];
|
||||
// Log error if API call failed
|
||||
result.whenError((error) {
|
||||
print('ERROR fetching deliveries for route $routeFragmentId: ${error.message}');
|
||||
if (error.originalException != null) {
|
||||
print('Original exception: ${error.originalException}');
|
||||
}
|
||||
});
|
||||
|
||||
final deliveries = result.whenSuccess((deliveries) => deliveries) ?? [];
|
||||
|
||||
// Always append the warehouse delivery at the end
|
||||
return [...deliveries, Delivery.createWarehouseDelivery()];
|
||||
});
|
||||
|
||||
/// Provider to get all deliveries from all routes
|
||||
|
||||
@ -177,7 +177,7 @@ class MaterialTheme {
|
||||
return const ColorScheme(
|
||||
brightness: Brightness.dark,
|
||||
primary: Color(0xffDF2D45), // Svrnty Crimson Red
|
||||
surfaceTint: Color(0xffFF6B7D),
|
||||
surfaceTint: Color(0xff4ADE80), // Success Green tint
|
||||
onPrimary: Color(0xffffffff),
|
||||
primaryContainer: Color(0xff9C1A29),
|
||||
onPrimaryContainer: Color(0xffFFE0E5),
|
||||
@ -185,15 +185,15 @@ class MaterialTheme {
|
||||
onSecondary: Color(0xffffffff),
|
||||
secondaryContainer: Color(0xff3A4958),
|
||||
onSecondaryContainer: Color(0xffD0DCE8),
|
||||
tertiary: Color(0xff5A8FA8), // Svrnty Teal variant
|
||||
onTertiary: Color(0xffffffff),
|
||||
tertiaryContainer: Color(0xff1D2C39),
|
||||
onTertiaryContainer: Color(0xffBFD5E3),
|
||||
tertiary: Color(0xff4ADE80), // Svrnty Success Green - Light
|
||||
onTertiary: Color(0xff14532D), // Dark green for contrast
|
||||
tertiaryContainer: Color(0xff15803D), // Svrnty Forest Dark Green
|
||||
onTertiaryContainer: Color(0xffDCFCE7), // Light green tint
|
||||
error: Color(0xffFF6B6B),
|
||||
onError: Color(0xff4C0707),
|
||||
errorContainer: Color(0xff93000A),
|
||||
onErrorContainer: Color(0xffFEE2E2),
|
||||
surface: Color(0xff0A0C10), // Svrnty Dark Background
|
||||
surface: Color(0xff0C1410), // Svrnty Dark Green Background
|
||||
onSurface: Color(0xffF0F0F2),
|
||||
onSurfaceVariant: Color(0xffBFC3C8),
|
||||
outline: Color(0xff9CA3AF), // Enhanced contrast for dark mode
|
||||
@ -210,17 +210,17 @@ class MaterialTheme {
|
||||
onSecondaryFixed: Color(0xff06080C),
|
||||
secondaryFixedDim: Color(0xff506576),
|
||||
onSecondaryFixedVariant: Color(0xff3A4958),
|
||||
tertiaryFixed: Color(0xffBFD5E3),
|
||||
onTertiaryFixed: Color(0xff001219),
|
||||
tertiaryFixedDim: Color(0xff5A8FA8),
|
||||
onTertiaryFixedVariant: Color(0xff1D2C39),
|
||||
surfaceDim: Color(0xff0A0C10),
|
||||
surfaceBright: Color(0xff404244),
|
||||
surfaceContainerLowest: Color(0xff040507),
|
||||
surfaceContainerLow: Color(0xff0F1114),
|
||||
surfaceContainer: Color(0xff14161A),
|
||||
surfaceContainerHigh: Color(0xff1F2228),
|
||||
surfaceContainerHighest: Color(0xff2A2D34),
|
||||
tertiaryFixed: Color(0xffDCFCE7), // Light green container
|
||||
onTertiaryFixed: Color(0xff14532D), // Dark green text
|
||||
tertiaryFixedDim: Color(0xff4ADE80), // Success green
|
||||
onTertiaryFixedVariant: Color(0xff15803D), // Forest green
|
||||
surfaceDim: Color(0xff0A110E), // Darker forest green
|
||||
surfaceBright: Color(0xff1F2D25), // Brighter green tint
|
||||
surfaceContainerLowest: Color(0xff070D0A), // Deepest green
|
||||
surfaceContainerLow: Color(0xff141B18), // Low green
|
||||
surfaceContainer: Color(0xff18221D), // Mid forest green
|
||||
surfaceContainerHigh: Color(0xff1D2822), // High green
|
||||
surfaceContainerHighest: Color(0xff222F29), // Highest green tint
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
BIN
screenshot_forest_green_theme.png
Normal file
BIN
screenshot_forest_green_theme.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 309 KiB |
Loading…
Reference in New Issue
Block a user