Implement UI/UX enhancements with collapsible routes sidebar and glassmorphic route cards
Adds new components (CollapsibleRoutesSidebar, GlassmorphicRouteCard) and internationalization support. Updates deliveries and routes pages with improved navigation and visual presentation using Material Design 3 principles. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
import 'app_localizations_en.dart';
|
||||
import 'app_localizations_fr.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// Callers can lookup localized strings with an instance of AppLocalizations
|
||||
/// returned by `AppLocalizations.of(context)`.
|
||||
///
|
||||
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
||||
/// `localizationDelegates` list, and the locales they support in the app's
|
||||
/// `supportedLocales` list. For example:
|
||||
///
|
||||
/// ```dart
|
||||
/// import 'l10n/app_localizations.dart';
|
||||
///
|
||||
/// return MaterialApp(
|
||||
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
/// supportedLocales: AppLocalizations.supportedLocales,
|
||||
/// home: MyApplicationHome(),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// ## Update pubspec.yaml
|
||||
///
|
||||
/// Please make sure to update your pubspec.yaml to include the following
|
||||
/// packages:
|
||||
///
|
||||
/// ```yaml
|
||||
/// dependencies:
|
||||
/// # Internationalization support.
|
||||
/// flutter_localizations:
|
||||
/// sdk: flutter
|
||||
/// intl: any # Use the pinned version from flutter_localizations
|
||||
///
|
||||
/// # Rest of dependencies
|
||||
/// ```
|
||||
///
|
||||
/// ## iOS Applications
|
||||
///
|
||||
/// iOS applications define key application metadata, including supported
|
||||
/// locales, in an Info.plist file that is built into the application bundle.
|
||||
/// To configure the locales supported by your app, you’ll need to edit this
|
||||
/// file.
|
||||
///
|
||||
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
||||
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
||||
/// project’s Runner folder.
|
||||
///
|
||||
/// Next, select the Information Property List item, select Add Item from the
|
||||
/// Editor menu, then select Localizations from the pop-up menu.
|
||||
///
|
||||
/// Select and expand the newly-created Localizations item then, for each
|
||||
/// locale your application supports, add a new item and select the locale
|
||||
/// you wish to add from the pop-up menu in the Value field. This list should
|
||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||
/// property.
|
||||
abstract class AppLocalizations {
|
||||
AppLocalizations(String locale)
|
||||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||
|
||||
final String localeName;
|
||||
|
||||
static AppLocalizations of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
||||
}
|
||||
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
|
||||
/// A list of this localizations delegate along with the default localizations
|
||||
/// delegates.
|
||||
///
|
||||
/// Returns a list of localizations delegates containing this delegate along with
|
||||
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
||||
/// and GlobalWidgetsLocalizations.delegate.
|
||||
///
|
||||
/// Additional delegates can be added by appending to this list in
|
||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||
/// of delegates is preferred or required.
|
||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||
<LocalizationsDelegate<dynamic>>[
|
||||
delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
];
|
||||
|
||||
/// A list of this localizations delegate's supported locales.
|
||||
static const List<Locale> supportedLocales = <Locale>[
|
||||
Locale('en'),
|
||||
Locale('fr'),
|
||||
];
|
||||
|
||||
/// No description provided for @appTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Plan B Logistics'**
|
||||
String get appTitle;
|
||||
|
||||
/// No description provided for @appDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delivery Management System'**
|
||||
String get appDescription;
|
||||
|
||||
/// No description provided for @loginWithKeycloak.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Login with Keycloak'**
|
||||
String get loginWithKeycloak;
|
||||
|
||||
/// No description provided for @deliveryRoutes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delivery Routes'**
|
||||
String get deliveryRoutes;
|
||||
|
||||
/// No description provided for @routes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Routes'**
|
||||
String get routes;
|
||||
|
||||
/// No description provided for @deliveries.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Deliveries'**
|
||||
String get deliveries;
|
||||
|
||||
/// No description provided for @settings.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Settings'**
|
||||
String get settings;
|
||||
|
||||
/// No description provided for @profile.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Profile'**
|
||||
String get profile;
|
||||
|
||||
/// No description provided for @logout.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Logout'**
|
||||
String get logout;
|
||||
|
||||
/// No description provided for @completed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Completed'**
|
||||
String get completed;
|
||||
|
||||
/// No description provided for @pending.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Pending'**
|
||||
String get pending;
|
||||
|
||||
/// No description provided for @todo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'To Do'**
|
||||
String get todo;
|
||||
|
||||
/// No description provided for @delivered.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delivered'**
|
||||
String get delivered;
|
||||
|
||||
/// No description provided for @newCustomer.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'New Customer'**
|
||||
String get newCustomer;
|
||||
|
||||
/// No description provided for @items.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count} items'**
|
||||
String items(int count);
|
||||
|
||||
/// No description provided for @moneyCurrency.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{amount} MAD'**
|
||||
String moneyCurrency(double amount);
|
||||
|
||||
/// No description provided for @call.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Call'**
|
||||
String get call;
|
||||
|
||||
/// No description provided for @map.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Map'**
|
||||
String get map;
|
||||
|
||||
/// No description provided for @more.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'More'**
|
||||
String get more;
|
||||
|
||||
/// No description provided for @markAsCompleted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Mark as Completed'**
|
||||
String get markAsCompleted;
|
||||
|
||||
/// No description provided for @markAsUncompleted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Mark as Uncompleted'**
|
||||
String get markAsUncompleted;
|
||||
|
||||
/// No description provided for @uploadPhoto.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Upload Photo'**
|
||||
String get uploadPhoto;
|
||||
|
||||
/// No description provided for @viewDetails.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'View Details'**
|
||||
String get viewDetails;
|
||||
|
||||
/// No description provided for @deliverySuccessful.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delivery marked as completed'**
|
||||
String get deliverySuccessful;
|
||||
|
||||
/// No description provided for @deliveryFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Failed to mark delivery'**
|
||||
String get deliveryFailed;
|
||||
|
||||
/// No description provided for @noDeliveries.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No deliveries'**
|
||||
String get noDeliveries;
|
||||
|
||||
/// No description provided for @noRoutes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No routes available'**
|
||||
String get noRoutes;
|
||||
|
||||
/// No description provided for @error.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Error: {message}'**
|
||||
String error(String message);
|
||||
|
||||
/// No description provided for @retry.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Retry'**
|
||||
String get retry;
|
||||
|
||||
/// No description provided for @authenticationRequired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Authentication required'**
|
||||
String get authenticationRequired;
|
||||
|
||||
/// No description provided for @phoneCall.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Call customer'**
|
||||
String get phoneCall;
|
||||
|
||||
/// No description provided for @navigateToAddress.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Show on map'**
|
||||
String get navigateToAddress;
|
||||
|
||||
/// No description provided for @language.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Language'**
|
||||
String get language;
|
||||
|
||||
/// No description provided for @english.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'English'**
|
||||
String get english;
|
||||
|
||||
/// No description provided for @french.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'French'**
|
||||
String get french;
|
||||
|
||||
/// No description provided for @appVersion.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'App Version'**
|
||||
String get appVersion;
|
||||
|
||||
/// No description provided for @about.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'About'**
|
||||
String get about;
|
||||
|
||||
/// No description provided for @fullName.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{firstName} {lastName}'**
|
||||
String fullName(String firstName, String lastName);
|
||||
|
||||
/// No description provided for @completedDeliveries.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{completed}/{total} completed'**
|
||||
String completedDeliveries(int completed, int total);
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
Future<AppLocalizations> load(Locale locale) {
|
||||
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
||||
}
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) =>
|
||||
<String>['en', 'fr'].contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
||||
|
||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||
// Lookup logic when only language code is specified.
|
||||
switch (locale.languageCode) {
|
||||
case 'en':
|
||||
return AppLocalizationsEn();
|
||||
case 'fr':
|
||||
return AppLocalizationsFr();
|
||||
}
|
||||
|
||||
throw FlutterError(
|
||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||
'an issue with the localizations generation tool. Please file an issue '
|
||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||
'that was used.',
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for English (`en`).
|
||||
class AppLocalizationsEn extends AppLocalizations {
|
||||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'Plan B Logistics';
|
||||
|
||||
@override
|
||||
String get appDescription => 'Delivery Management System';
|
||||
|
||||
@override
|
||||
String get loginWithKeycloak => 'Login with Keycloak';
|
||||
|
||||
@override
|
||||
String get deliveryRoutes => 'Delivery Routes';
|
||||
|
||||
@override
|
||||
String get routes => 'Routes';
|
||||
|
||||
@override
|
||||
String get deliveries => 'Deliveries';
|
||||
|
||||
@override
|
||||
String get settings => 'Settings';
|
||||
|
||||
@override
|
||||
String get profile => 'Profile';
|
||||
|
||||
@override
|
||||
String get logout => 'Logout';
|
||||
|
||||
@override
|
||||
String get completed => 'Completed';
|
||||
|
||||
@override
|
||||
String get pending => 'Pending';
|
||||
|
||||
@override
|
||||
String get todo => 'To Do';
|
||||
|
||||
@override
|
||||
String get delivered => 'Delivered';
|
||||
|
||||
@override
|
||||
String get newCustomer => 'New Customer';
|
||||
|
||||
@override
|
||||
String items(int count) {
|
||||
return '$count items';
|
||||
}
|
||||
|
||||
@override
|
||||
String moneyCurrency(double amount) {
|
||||
return '$amount MAD';
|
||||
}
|
||||
|
||||
@override
|
||||
String get call => 'Call';
|
||||
|
||||
@override
|
||||
String get map => 'Map';
|
||||
|
||||
@override
|
||||
String get more => 'More';
|
||||
|
||||
@override
|
||||
String get markAsCompleted => 'Mark as Completed';
|
||||
|
||||
@override
|
||||
String get markAsUncompleted => 'Mark as Uncompleted';
|
||||
|
||||
@override
|
||||
String get uploadPhoto => 'Upload Photo';
|
||||
|
||||
@override
|
||||
String get viewDetails => 'View Details';
|
||||
|
||||
@override
|
||||
String get deliverySuccessful => 'Delivery marked as completed';
|
||||
|
||||
@override
|
||||
String get deliveryFailed => 'Failed to mark delivery';
|
||||
|
||||
@override
|
||||
String get noDeliveries => 'No deliveries';
|
||||
|
||||
@override
|
||||
String get noRoutes => 'No routes available';
|
||||
|
||||
@override
|
||||
String error(String message) {
|
||||
return 'Error: $message';
|
||||
}
|
||||
|
||||
@override
|
||||
String get retry => 'Retry';
|
||||
|
||||
@override
|
||||
String get authenticationRequired => 'Authentication required';
|
||||
|
||||
@override
|
||||
String get phoneCall => 'Call customer';
|
||||
|
||||
@override
|
||||
String get navigateToAddress => 'Show on map';
|
||||
|
||||
@override
|
||||
String get language => 'Language';
|
||||
|
||||
@override
|
||||
String get english => 'English';
|
||||
|
||||
@override
|
||||
String get french => 'French';
|
||||
|
||||
@override
|
||||
String get appVersion => 'App Version';
|
||||
|
||||
@override
|
||||
String get about => 'About';
|
||||
|
||||
@override
|
||||
String fullName(String firstName, String lastName) {
|
||||
return '$firstName $lastName';
|
||||
}
|
||||
|
||||
@override
|
||||
String completedDeliveries(int completed, int total) {
|
||||
return '$completed/$total completed';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for French (`fr`).
|
||||
class AppLocalizationsFr extends AppLocalizations {
|
||||
AppLocalizationsFr([String locale = 'fr']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'Plan B Logistique';
|
||||
|
||||
@override
|
||||
String get appDescription => 'Systme de Gestion des Livraisons';
|
||||
|
||||
@override
|
||||
String get loginWithKeycloak => 'Connexion avec Keycloak';
|
||||
|
||||
@override
|
||||
String get deliveryRoutes => 'Itinraires de Livraison';
|
||||
|
||||
@override
|
||||
String get routes => 'Itinraires';
|
||||
|
||||
@override
|
||||
String get deliveries => 'Livraisons';
|
||||
|
||||
@override
|
||||
String get settings => 'Paramtres';
|
||||
|
||||
@override
|
||||
String get profile => 'Profil';
|
||||
|
||||
@override
|
||||
String get logout => 'Dconnexion';
|
||||
|
||||
@override
|
||||
String get completed => 'Livr';
|
||||
|
||||
@override
|
||||
String get pending => 'En attente';
|
||||
|
||||
@override
|
||||
String get todo => 'livrer';
|
||||
|
||||
@override
|
||||
String get delivered => 'Livr';
|
||||
|
||||
@override
|
||||
String get newCustomer => 'Nouveau Client';
|
||||
|
||||
@override
|
||||
String items(int count) {
|
||||
return '$count articles';
|
||||
}
|
||||
|
||||
@override
|
||||
String moneyCurrency(double amount) {
|
||||
return '$amount MAD';
|
||||
}
|
||||
|
||||
@override
|
||||
String get call => 'Appeler';
|
||||
|
||||
@override
|
||||
String get map => 'Carte';
|
||||
|
||||
@override
|
||||
String get more => 'Plus';
|
||||
|
||||
@override
|
||||
String get markAsCompleted => 'Marquer comme livr';
|
||||
|
||||
@override
|
||||
String get markAsUncompleted => 'Marquer comme livrer';
|
||||
|
||||
@override
|
||||
String get uploadPhoto => 'Tlcharger une photo';
|
||||
|
||||
@override
|
||||
String get viewDetails => 'Voir les dtails';
|
||||
|
||||
@override
|
||||
String get deliverySuccessful => 'Livraison marque comme complte';
|
||||
|
||||
@override
|
||||
String get deliveryFailed => 'chec du marquage de la livraison';
|
||||
|
||||
@override
|
||||
String get noDeliveries => 'Aucune livraison';
|
||||
|
||||
@override
|
||||
String get noRoutes => 'Aucun itinraire disponible';
|
||||
|
||||
@override
|
||||
String error(String message) {
|
||||
return 'Erreur: $message';
|
||||
}
|
||||
|
||||
@override
|
||||
String get retry => 'Ressayer';
|
||||
|
||||
@override
|
||||
String get authenticationRequired => 'Authentification requise';
|
||||
|
||||
@override
|
||||
String get phoneCall => 'Appeler le client';
|
||||
|
||||
@override
|
||||
String get navigateToAddress => 'Afficher sur la carte';
|
||||
|
||||
@override
|
||||
String get language => 'Langue';
|
||||
|
||||
@override
|
||||
String get english => 'English';
|
||||
|
||||
@override
|
||||
String get french => 'Franais';
|
||||
|
||||
@override
|
||||
String get appVersion => 'Version de l\'application';
|
||||
|
||||
@override
|
||||
String get about => ' propos';
|
||||
|
||||
@override
|
||||
String fullName(String firstName, String lastName) {
|
||||
return '$firstName $lastName';
|
||||
}
|
||||
|
||||
@override
|
||||
String completedDeliveries(int completed, int total) {
|
||||
return '$completed/$total livrs';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user