From 025b5f49b0e035fcdfeffc26c3ddf2bbf496aa60 Mon Sep 17 00:00:00 2001 From: fuad sano Date: Tue, 5 May 2026 11:07:44 +0300 Subject: [PATCH 1/5] refactor splash setup screen for improved navigation and code clarity Co-authored-by: Copilot --- lib/screens/splash_setup_screen.dart | 176 +++++++++++++-------------- 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/lib/screens/splash_setup_screen.dart b/lib/screens/splash_setup_screen.dart index 3e5e507..efe4323 100644 --- a/lib/screens/splash_setup_screen.dart +++ b/lib/screens/splash_setup_screen.dart @@ -20,7 +20,6 @@ class _SplashSetupScreenState extends State with SingleTicker late AnimationController _animationController; late Animation _fadeAnimation; - @override void initState() { super.initState(); @@ -38,7 +37,8 @@ class _SplashSetupScreenState extends State with SingleTicker _animationController.forward(); } else { if (mounted) { - Navigator.of(context).pushReplacement( + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (_) => const LoginScreen()), ); } @@ -53,7 +53,8 @@ class _SplashSetupScreenState extends State with SingleTicker _q2Controller.text, ); if (mounted) { - Navigator.of(context).pushReplacement( + Navigator.pushReplacement( + context, PageRouteBuilder( transitionDuration: const Duration(milliseconds: 600), pageBuilder: (_, __, ___) => const DashboardScreen(), @@ -107,98 +108,95 @@ class _SplashSetupScreenState extends State with SingleTicker ); } - Widget _buildInitializeButton() { - return Container( - width: double.infinity, - height: 64, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - gradient: LinearGradient( - colors: [AppTheme.primaryBlue, AppTheme.primaryBlue.withBlue(255)], - ), - boxShadow: [ - BoxShadow( - color: AppTheme.primaryBlue.withOpacity(0.3), - blurRadius: 15, - offset: const Offset(0, 8), - ) - ], - ), - child: ElevatedButton( - onPressed: _submitSetup, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.transparent, - shadowColor: Colors.transparent, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Text('INITIALIZE SYSTEM', style: TextStyle(fontWeight: FontWeight.w900, letterSpacing: 2)), - SizedBox(width: 12), - Icon(Icons.arrow_forward_rounded, size: 20), + Widget _buildInitializeButton() => Container( + width: double.infinity, + height: 64, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + gradient: LinearGradient( + colors: [AppTheme.primaryBlue, AppTheme.primaryBlue.withBlue(255)], + ), + boxShadow: [ + BoxShadow( + color: AppTheme.primaryBlue.withOpacity(0.3), + blurRadius: 15, + offset: const Offset(0, 8), + ) ], ), - ), - ); - } - - Widget _buildLogo() { - return Column( - children: [ - Container( - padding: const EdgeInsets.all(28), - decoration: BoxDecoration( - color: AppTheme.primaryBlue.withOpacity(0.1), - borderRadius: BorderRadius.circular(32), - border: Border.all(color: AppTheme.primaryBlue.withOpacity(0.2)), + child: ElevatedButton( + onPressed: _submitSetup, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.transparent, + shadowColor: Colors.transparent, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Text('INITIALIZE SYSTEM', style: TextStyle(fontWeight: FontWeight.w900, letterSpacing: 2)), + SizedBox(width: 12), + Icon(Icons.arrow_forward_rounded, size: 20), + ], ), - child: const Icon(Icons.wallet_rounded, size: 64, color: AppTheme.primaryBlue), - ), - const SizedBox(height: 24), - const Text( - 'DUBE BOOK', - style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: AppTheme.textPrimary, letterSpacing: 6), - ), - const SizedBox(height: 4), - Text( - 'PROFESSIONAL SHOP ASSISTANT', - style: TextStyle(fontSize: 10, color: AppTheme.textSecondary, letterSpacing: 2, fontWeight: FontWeight.w900), ), - ], - ); - } + ); - Widget _buildInputSection() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('SECURE SETUP', style: TextStyle(color: AppTheme.textSecondary.withOpacity(0.5), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 2)), - const SizedBox(height: 16), - _buildField(_passwordController, 'Create Master Password', Icons.lock_rounded, true), - const SizedBox(height: 32), - Text('RECOVERY QUESTIONS', style: TextStyle(color: AppTheme.textSecondary.withOpacity(0.5), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 2)), - const SizedBox(height: 16), - _buildField(_q1Controller, 'In which city were you born?', Icons.location_city_rounded, false), - const SizedBox(height: 16), - _buildField(_q2Controller, 'What year did your shop open?', Icons.calendar_today_rounded, false, isNumber: true), - ], - ); - } - Widget _buildField(TextEditingController controller, String label, IconData icon, bool obscure, {bool isNumber = false}) { - return TextFormField( - controller: controller, - obscureText: obscure, - keyboardType: isNumber ? TextInputType.number : TextInputType.text, - style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w600), - decoration: InputDecoration( - labelText: label, - prefixIcon: Icon(icon, color: AppTheme.primaryBlue, size: 22), - ), - validator: (v) => v!.isEmpty ? 'This information is required' : null, - ); - } + Widget _buildLogo() => Column( + children: [ + Container( + padding: const EdgeInsets.all(28), + decoration: BoxDecoration( + color: AppTheme.primaryBlue.withOpacity(0.1), + borderRadius: BorderRadius.circular(32), + border: Border.all(color: AppTheme.primaryBlue.withOpacity(0.2)), + ), + child: const Icon(Icons.wallet_rounded, size: 64, color: AppTheme.primaryBlue), + ), + const SizedBox(height: 24), + const Text( + 'DUBE BOOK', + style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: AppTheme.textPrimary, letterSpacing: 6), + ), + const SizedBox(height: 4), + Text( + 'PROFESSIONAL SHOP ASSISTANT', + style: TextStyle(fontSize: 10, color: AppTheme.textSecondary, letterSpacing: 2, fontWeight: FontWeight.w900), + ), + ], + ); + + + Widget _buildInputSection() => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('SECURE SETUP', style: TextStyle(color: AppTheme.textSecondary.withOpacity(0.5), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 2)), + const SizedBox(height: 16), + _buildField(_passwordController, 'Create Master Password', Icons.lock_rounded, true), + const SizedBox(height: 32), + Text('RECOVERY QUESTIONS', style: TextStyle(color: AppTheme.textSecondary.withOpacity(0.5), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 2)), + const SizedBox(height: 16), + _buildField(_q1Controller, 'In which city were you born?', Icons.location_city_rounded, false), + const SizedBox(height: 16), + _buildField(_q2Controller, 'What year did your shop open?', Icons.calendar_today_rounded, false, isNumber: true), + ], + ); + + + Widget _buildField(TextEditingController controller, String label, IconData icon, bool obscure, {bool isNumber = false}) => + TextFormField( + controller: controller, + obscureText: obscure, + keyboardType: isNumber ? TextInputType.number : TextInputType.text, + style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w600), + decoration: InputDecoration( + labelText: label, + prefixIcon: Icon(icon, color: AppTheme.primaryBlue, size: 22), + ), + validator: (v) => v!.isEmpty ? 'This information is required' : null, + ); + @override void dispose() { From 849d7ae2b6a8faa678e248f2046a58c465b61e4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 May 2026 05:19:08 +0000 Subject: [PATCH 2/5] Localize splash setup PIN copy Co-authored-by: mroxygen2024 <164843890+mroxygen2024@users.noreply.github.com> --- lib/l10n/app_am.arb | 3 +++ lib/l10n/app_en.arb | 3 +++ lib/l10n/app_localizations.dart | 18 ++++++++++++++++++ lib/l10n/app_localizations_am.dart | 9 +++++++++ lib/l10n/app_localizations_en.dart | 9 +++++++++ lib/l10n/app_localizations_om.dart | 9 +++++++++ lib/l10n/app_om.arb | 3 +++ lib/screens/splash_setup_screen.dart | 6 +++--- 8 files changed, 57 insertions(+), 3 deletions(-) diff --git a/lib/l10n/app_am.arb b/lib/l10n/app_am.arb index a1ee383..7b49618 100644 --- a/lib/l10n/app_am.arb +++ b/lib/l10n/app_am.arb @@ -25,6 +25,7 @@ "secureSetup": "ደህንነት ማዋቀር", "masterPassword": "ዋና የይለፍ ቃል", + "createPinLabel": "ባለ 4-አሃዝ PIN ይፍጠሩ", "recoveryQuestions": "የማግኛ ጥያቄዎች", "birthCity": "የትውልድ ከተማ", "openingYear": "የመክፈቻ ዓመት (ኢትዮጵያ)", @@ -32,6 +33,8 @@ "dataSecureNote": "መረጃዎ በዚህ መሣሪያ ላይ ብቻ ተከማችቷል።", "passwordRequired": "የይለፍ ቃል ያስፈልጋል", "passwordMinLength": "ቢያንስ 4 ቁምፊዎች መሆን አለበት", + "pinExactDigits": "PIN በትክክል 4 አሃዞች መሆን አለበት", + "pinNumericOnly": "PIN ቁጥር ብቻ መሆን አለበት", "birthCityRequired": "የትውልድ ከተማ ያስፈልጋል", "yearRequired": "ዓመት ያስፈልጋል", "yearExactDigits": "በትክክል 4 አሃዞች መሆን አለበት", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 02742de..510c66e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -25,6 +25,7 @@ "secureSetup": "SECURE SETUP", "masterPassword": "Master Password", + "createPinLabel": "Create 4-Digit PIN", "recoveryQuestions": "RECOVERY QUESTIONS", "birthCity": "Birth City", "openingYear": "Opening Year (Ethiopian)", @@ -32,6 +33,8 @@ "dataSecureNote": "Your data is stored securely on this device only.", "passwordRequired": "Password is required", "passwordMinLength": "Must be at least 4 characters", + "pinExactDigits": "PIN must be exactly 4 digits", + "pinNumericOnly": "PIN must be numeric", "birthCityRequired": "Birth city is required", "yearRequired": "Year is required", "yearExactDigits": "Must be exactly 4 digits", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 4452a16..c37fbd8 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -226,6 +226,12 @@ abstract class AppLocalizations { /// **'Master Password'** String get masterPassword; + /// No description provided for @createPinLabel. + /// + /// In en, this message translates to: + /// **'Create 4-Digit PIN'** + String get createPinLabel; + /// No description provided for @recoveryQuestions. /// /// In en, this message translates to: @@ -268,6 +274,18 @@ abstract class AppLocalizations { /// **'Must be at least 4 characters'** String get passwordMinLength; + /// No description provided for @pinExactDigits. + /// + /// In en, this message translates to: + /// **'PIN must be exactly 4 digits'** + String get pinExactDigits; + + /// No description provided for @pinNumericOnly. + /// + /// In en, this message translates to: + /// **'PIN must be numeric'** + String get pinNumericOnly; + /// No description provided for @birthCityRequired. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_am.dart b/lib/l10n/app_localizations_am.dart index 823debf..62ff6e8 100644 --- a/lib/l10n/app_localizations_am.dart +++ b/lib/l10n/app_localizations_am.dart @@ -71,6 +71,9 @@ class AppLocalizationsAm extends AppLocalizations { @override String get masterPassword => 'ዋና የይለፍ ቃል'; + @override + String get createPinLabel => 'ባለ 4-አሃዝ PIN ይፍጠሩ'; + @override String get recoveryQuestions => 'የማግኛ ጥያቄዎች'; @@ -92,6 +95,12 @@ class AppLocalizationsAm extends AppLocalizations { @override String get passwordMinLength => 'ቢያንስ 4 ቁምፊዎች መሆን አለበት'; + @override + String get pinExactDigits => 'PIN በትክክል 4 አሃዞች መሆን አለበት'; + + @override + String get pinNumericOnly => 'PIN ቁጥር ብቻ መሆን አለበት'; + @override String get birthCityRequired => 'የትውልድ ከተማ ያስፈልጋል'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 844e124..98f05c6 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -71,6 +71,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get masterPassword => 'Master Password'; + @override + String get createPinLabel => 'Create 4-Digit PIN'; + @override String get recoveryQuestions => 'RECOVERY QUESTIONS'; @@ -93,6 +96,12 @@ class AppLocalizationsEn extends AppLocalizations { @override String get passwordMinLength => 'Must be at least 4 characters'; + @override + String get pinExactDigits => 'PIN must be exactly 4 digits'; + + @override + String get pinNumericOnly => 'PIN must be numeric'; + @override String get birthCityRequired => 'Birth city is required'; diff --git a/lib/l10n/app_localizations_om.dart b/lib/l10n/app_localizations_om.dart index d833384..8ea50fb 100644 --- a/lib/l10n/app_localizations_om.dart +++ b/lib/l10n/app_localizations_om.dart @@ -71,6 +71,9 @@ class AppLocalizationsOm extends AppLocalizations { @override String get masterPassword => 'Jecha Darbii Jalqabaa'; + @override + String get createPinLabel => 'PIN Lakkoofsa 4 Uumi'; + @override String get recoveryQuestions => 'GAAFFILEE DEEBISUU'; @@ -93,6 +96,12 @@ class AppLocalizationsOm extends AppLocalizations { @override String get passwordMinLength => 'Yoo xiqqaate arfii 4 ta\'uu qaba'; + @override + String get pinExactDigits => 'PIN lakkoofsa 4 qofa ta\'uu qaba'; + + @override + String get pinNumericOnly => 'PIN lakkoofsa qofa ta\'uu qaba'; + @override String get birthCityRequired => 'Magaalaan dhalootaa barbaachisaadha'; diff --git a/lib/l10n/app_om.arb b/lib/l10n/app_om.arb index 195eecd..1837bf8 100644 --- a/lib/l10n/app_om.arb +++ b/lib/l10n/app_om.arb @@ -25,6 +25,7 @@ "secureSetup": "QINDAA'INA NAGEENYA", "masterPassword": "Jecha Darbii Jalqabaa", + "createPinLabel": "PIN Lakkoofsa 4 Uumi", "recoveryQuestions": "GAAFFILEE DEEBISUU", "birthCity": "Magaalaa Dhalootaa", "openingYear": "Bara Banamsaa (Itoophiyaa)", @@ -32,6 +33,8 @@ "dataSecureNote": "Daataan keessan meeshaa kana qofa irratti kuufame.", "passwordRequired": "Jechni darbii barbaachisaadha", "passwordMinLength": "Yoo xiqqaate arfii 4 ta'uu qaba", + "pinExactDigits": "PIN lakkoofsa 4 qofa ta'uu qaba", + "pinNumericOnly": "PIN lakkoofsa qofa ta'uu qaba", "birthCityRequired": "Magaalaan dhalootaa barbaachisaadha", "yearRequired": "Barri barbaachisaadha", "yearExactDigits": "Lakkoofsa 4 qofa ta'uu qaba", diff --git a/lib/screens/splash_setup_screen.dart b/lib/screens/splash_setup_screen.dart index b08e4ae..9bf30ae 100644 --- a/lib/screens/splash_setup_screen.dart +++ b/lib/screens/splash_setup_screen.dart @@ -306,14 +306,14 @@ class _SplashSetupScreenState extends State with SingleTicker const SizedBox(height: 16), _buildField( _passwordController, - 'Create 4-Digit PIN', + l.createPinLabel, Icons.password_rounded, true, isNumber: true, validator: (v) { if (v == null || v.isEmpty) return l.passwordRequired; - if (v.length != 4) return 'PIN must be exactly 4 digits'; - if (int.tryParse(v) == null) return 'PIN must be numeric'; + if (v.length != 4) return l.pinExactDigits; + if (int.tryParse(v) == null) return l.pinNumericOnly; return null; }, ), From 4ceee0b0906740e9f76cb086f173892cf5c6813b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 May 2026 05:20:15 +0000 Subject: [PATCH 3/5] Refine splash setup PIN icon Co-authored-by: mroxygen2024 <164843890+mroxygen2024@users.noreply.github.com> --- lib/screens/splash_setup_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/splash_setup_screen.dart b/lib/screens/splash_setup_screen.dart index 9bf30ae..947f3fa 100644 --- a/lib/screens/splash_setup_screen.dart +++ b/lib/screens/splash_setup_screen.dart @@ -307,7 +307,7 @@ class _SplashSetupScreenState extends State with SingleTicker _buildField( _passwordController, l.createPinLabel, - Icons.password_rounded, + Icons.pin_rounded, true, isNumber: true, validator: (v) { From 73c2c472534a018eb60bd482fca0719d3b1a2113 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 May 2026 05:21:12 +0000 Subject: [PATCH 4/5] Polish splash setup field icons Co-authored-by: mroxygen2024 <164843890+mroxygen2024@users.noreply.github.com> --- lib/screens/splash_setup_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/screens/splash_setup_screen.dart b/lib/screens/splash_setup_screen.dart index 947f3fa..3a214a6 100644 --- a/lib/screens/splash_setup_screen.dart +++ b/lib/screens/splash_setup_screen.dart @@ -307,7 +307,7 @@ class _SplashSetupScreenState extends State with SingleTicker _buildField( _passwordController, l.createPinLabel, - Icons.pin_rounded, + Icons.dialpad_rounded, true, isNumber: true, validator: (v) { @@ -329,7 +329,7 @@ class _SplashSetupScreenState extends State with SingleTicker _buildField( _q1Controller, l.birthCity, - Icons.location_on_rounded, + Icons.location_city_rounded, false, validator: (v) => v!.isEmpty ? l.birthCityRequired : null, ), From 56f7534a4e8d79ea67d8d3bf7145226cb525920e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 May 2026 05:22:08 +0000 Subject: [PATCH 5/5] Use lock icon for setup PIN Co-authored-by: mroxygen2024 <164843890+mroxygen2024@users.noreply.github.com> --- lib/screens/splash_setup_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/splash_setup_screen.dart b/lib/screens/splash_setup_screen.dart index 3a214a6..a832b31 100644 --- a/lib/screens/splash_setup_screen.dart +++ b/lib/screens/splash_setup_screen.dart @@ -307,7 +307,7 @@ class _SplashSetupScreenState extends State with SingleTicker _buildField( _passwordController, l.createPinLabel, - Icons.dialpad_rounded, + Icons.lock_rounded, true, isNumber: true, validator: (v) {