diff --git a/apps/mobile/packages/core_localization/lib/src/l10n/en.i18n.json b/apps/mobile/packages/core_localization/lib/src/l10n/en.i18n.json index beef30fb..0ba97bd4 100644 --- a/apps/mobile/packages/core_localization/lib/src/l10n/en.i18n.json +++ b/apps/mobile/packages/core_localization/lib/src/l10n/en.i18n.json @@ -521,7 +521,8 @@ "compliance": "COMPLIANCE", "level_up": "LEVEL UP", "finance": "FINANCE", - "support": "SUPPORT" + "support": "SUPPORT", + "settings": "SETTINGS" }, "menu_items": { "personal_info": "Personal Info", @@ -543,7 +544,8 @@ "timecard": "Timecard", "faqs": "FAQs", "privacy_security": "Privacy & Security", - "messages": "Messages" + "messages": "Messages", + "language": "Language" }, "bank_account_page": { "title": "Bank Account", diff --git a/apps/mobile/packages/core_localization/lib/src/l10n/es.i18n.json b/apps/mobile/packages/core_localization/lib/src/l10n/es.i18n.json index 80df41d0..6ce171fc 100644 --- a/apps/mobile/packages/core_localization/lib/src/l10n/es.i18n.json +++ b/apps/mobile/packages/core_localization/lib/src/l10n/es.i18n.json @@ -521,7 +521,8 @@ "compliance": "CUMPLIMIENTO", "level_up": "MEJORAR NIVEL", "finance": "FINANZAS", - "support": "SOPORTE" + "support": "SOPORTE", + "settings": "AJUSTES" }, "menu_items": { "personal_info": "Información Personal", @@ -543,7 +544,8 @@ "timecard": "Tarjeta de Tiempo", "faqs": "Preguntas Frecuentes", "privacy_security": "Privacidad y Seguridad", - "messages": "Mensajes" + "messages": "Mensajes", + "language": "Idioma" }, "bank_account_page": { "title": "Cuenta Bancaria", diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart index 69a954b9..96b98016 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/pages/staff_profile_page.dart @@ -8,14 +8,11 @@ import 'package:krow_domain/krow_domain.dart'; import '../blocs/profile_cubit.dart'; import '../blocs/profile_state.dart'; -import '../widgets/language_selector_bottom_sheet.dart'; import '../widgets/logout_button.dart'; import '../widgets/profile_header.dart'; -import '../widgets/profile_menu_grid.dart'; -import '../widgets/profile_menu_item.dart'; import '../widgets/reliability_score_bar.dart'; import '../widgets/reliability_stats_card.dart'; -import '../widgets/section_title.dart'; +import '../widgets/sections/index.dart'; /// The main Staff Profile page. /// @@ -49,7 +46,6 @@ class StaffProfilePage extends StatelessWidget { @override Widget build(BuildContext context) { - final i18n = Translations.of(context).staff.profile; final ProfileCubit cubit = Modular.get(); // Load profile data on first build @@ -60,7 +56,7 @@ class StaffProfilePage extends StatelessWidget { return Scaffold( body: BlocConsumer( bloc: cubit, - listener: (context, state) { + listener: (BuildContext context, ProfileState state) { if (state.status == ProfileStatus.signedOut) { Modular.to.toGetStartedPage(); } else if (state.status == ProfileStatus.error && @@ -72,7 +68,7 @@ class StaffProfilePage extends StatelessWidget { ); } }, - builder: (context, state) { + builder: (BuildContext context, ProfileState state) { // Show loading spinner if status is loading if (state.status == ProfileStatus.loading) { return const Center(child: CircularProgressIndicator()); @@ -95,7 +91,7 @@ class StaffProfilePage extends StatelessWidget { ); } - final profile = state.profile; + final Staff? profile = state.profile; if (profile == null) { return const Center(child: CircularProgressIndicator()); } @@ -103,7 +99,7 @@ class StaffProfilePage extends StatelessWidget { return SingleChildScrollView( padding: const EdgeInsets.only(bottom: UiConstants.space16), child: Column( - children: [ + children: [ ProfileHeader( fullName: profile.name, level: _mapStatusToLevel(profile.status), @@ -117,7 +113,7 @@ class StaffProfilePage extends StatelessWidget { horizontal: UiConstants.space5, ), child: Column( - children: [ + children: [ ReliabilityStatsCard( totalShifts: profile.totalShifts, averageRating: profile.averageRating, @@ -130,105 +126,15 @@ class StaffProfilePage extends StatelessWidget { reliabilityScore: profile.reliabilityScore, ), const SizedBox(height: UiConstants.space6), - SectionTitle(i18n.sections.onboarding), - ProfileMenuGrid( - crossAxisCount: 3, - - children: [ - ProfileMenuItem( - icon: UiIcons.user, - label: i18n.menu_items.personal_info, - onTap: () => Modular.to.toPersonalInfo(), - ), - ProfileMenuItem( - icon: UiIcons.phone, - label: i18n.menu_items.emergency_contact, - onTap: () => Modular.to.toEmergencyContact(), - ), - ProfileMenuItem( - icon: UiIcons.briefcase, - label: i18n.menu_items.experience, - onTap: () => Modular.to.toExperience(), - ), - ], - ), + const OnboardingSection(), const SizedBox(height: UiConstants.space6), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SectionTitle(i18n.sections.compliance), - ProfileMenuGrid( - crossAxisCount: 3, - children: [ - ProfileMenuItem( - icon: UiIcons.file, - label: i18n.menu_items.tax_forms, - onTap: () => Modular.to.toTaxForms(), - ), - ], - ), - ], - ), + const ComplianceSection(), const SizedBox(height: UiConstants.space6), - SectionTitle(i18n.sections.finance), - ProfileMenuGrid( - crossAxisCount: 3, - children: [ - ProfileMenuItem( - icon: UiIcons.building, - label: i18n.menu_items.bank_account, - onTap: () => Modular.to.toBankAccount(), - ), - ProfileMenuItem( - icon: UiIcons.creditCard, - label: i18n.menu_items.payments, - onTap: () => Modular.to.toPayments(), - ), - ProfileMenuItem( - icon: UiIcons.clock, - label: i18n.menu_items.timecard, - onTap: () => Modular.to.toTimeCard(), - ), - ], - ), + const FinanceSection(), const SizedBox(height: UiConstants.space6), - SectionTitle( - i18n.header.title.contains("Perfil") ? "Soporte" : "Support", - ), - ProfileMenuGrid( - crossAxisCount: 3, - children: [ - ProfileMenuItem( - icon: UiIcons.helpCircle, - label: i18n.header.title.contains("Perfil") ? "Preguntas Frecuentes" : "FAQs", - onTap: () => Modular.to.toFaqs(), - ), - ProfileMenuItem( - icon: UiIcons.shield, - label: i18n.header.title.contains("Perfil") ? "Privacidad" : "Privacy & Security", - onTap: () => Modular.to.toPrivacySecurity(), - ), - ], - ), + const SupportSection(), const SizedBox(height: UiConstants.space6), - SectionTitle( - i18n.header.title.contains("Perfil") ? "Ajustes" : "Settings", - ), - ProfileMenuGrid( - crossAxisCount: 3, - children: [ - ProfileMenuItem( - icon: UiIcons.globe, - label: i18n.header.title.contains("Perfil") ? "Idioma" : "Language", - onTap: () { - showModalBottomSheet( - context: context, - builder: (context) => const LanguageSelectorBottomSheet(), - ); - }, - ), - ], - ), + const SettingsSection(), const SizedBox(height: UiConstants.space6), LogoutButton( onTap: () => _onSignOut(cubit, state), diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart new file mode 100644 index 00000000..a3a5211a --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart @@ -0,0 +1,39 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; + +import '../profile_menu_grid.dart'; +import '../profile_menu_item.dart'; +import '../section_title.dart'; + +/// Widget displaying the compliance section of the staff profile. +/// +/// This section contains menu items for tax forms and other compliance-related documents. +class ComplianceSection extends StatelessWidget { + /// Creates a [ComplianceSection]. + const ComplianceSection({super.key}); + + @override + Widget build(BuildContext context) { + final TranslationsStaffProfileEn i18n = Translations.of(context).staff.profile; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SectionTitle(i18n.sections.compliance), + ProfileMenuGrid( + crossAxisCount: 3, + children: [ + ProfileMenuItem( + icon: UiIcons.file, + label: i18n.menu_items.tax_forms, + onTap: () => Modular.to.toTaxForms(), + ), + ], + ), + ], + ); + } +} diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/finance_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/finance_section.dart new file mode 100644 index 00000000..73db7355 --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/finance_section.dart @@ -0,0 +1,48 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; + +import '../profile_menu_grid.dart'; +import '../profile_menu_item.dart'; +import '../section_title.dart'; + +/// Widget displaying the finance section of the staff profile. +/// +/// This section contains menu items for bank account, payments, and timecard information. +class FinanceSection extends StatelessWidget { + /// Creates a [FinanceSection]. + const FinanceSection({super.key}); + + @override + Widget build(BuildContext context) { + final TranslationsStaffProfileEn i18n = Translations.of(context).staff.profile; + + return Column( + children: [ + SectionTitle(i18n.sections.finance), + ProfileMenuGrid( + crossAxisCount: 3, + children: [ + ProfileMenuItem( + icon: UiIcons.building, + label: i18n.menu_items.bank_account, + onTap: () => Modular.to.toBankAccount(), + ), + ProfileMenuItem( + icon: UiIcons.creditCard, + label: i18n.menu_items.payments, + onTap: () => Modular.to.toPayments(), + ), + ProfileMenuItem( + icon: UiIcons.clock, + label: i18n.menu_items.timecard, + onTap: () => Modular.to.toTimeCard(), + ), + ], + ), + ], + ); + } +} diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/index.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/index.dart new file mode 100644 index 00000000..967a4dac --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/index.dart @@ -0,0 +1,5 @@ +export 'compliance_section.dart'; +export 'finance_section.dart'; +export 'onboarding_section.dart'; +export 'settings_section.dart'; +export 'support_section.dart'; diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart new file mode 100644 index 00000000..2d9201e3 --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart @@ -0,0 +1,49 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; + +import '../profile_menu_grid.dart'; +import '../profile_menu_item.dart'; +import '../section_title.dart'; + +/// Widget displaying the onboarding section of the staff profile. +/// +/// This section contains menu items for personal information, emergency contact, +/// and work experience setup. +class OnboardingSection extends StatelessWidget { + /// Creates an [OnboardingSection]. + const OnboardingSection({super.key}); + + @override + Widget build(BuildContext context) { + final TranslationsStaffProfileEn i18n = Translations.of(context).staff.profile; + + return Column( + children: [ + SectionTitle(i18n.sections.onboarding), + ProfileMenuGrid( + crossAxisCount: 3, + children: [ + ProfileMenuItem( + icon: UiIcons.user, + label: i18n.menu_items.personal_info, + onTap: () => Modular.to.toPersonalInfo(), + ), + ProfileMenuItem( + icon: UiIcons.phone, + label: i18n.menu_items.emergency_contact, + onTap: () => Modular.to.toEmergencyContact(), + ), + ProfileMenuItem( + icon: UiIcons.briefcase, + label: i18n.menu_items.experience, + onTap: () => Modular.to.toExperience(), + ), + ], + ), + ], + ); + } +} diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/settings_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/settings_section.dart new file mode 100644 index 00000000..5fa0b4f5 --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/settings_section.dart @@ -0,0 +1,47 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; + +import '../language_selector_bottom_sheet.dart'; +import '../profile_menu_grid.dart'; +import '../profile_menu_item.dart'; +import '../section_title.dart'; + +/// Widget displaying the settings section of the staff profile. +/// +/// This section contains menu items for language selection. +class SettingsSection extends StatelessWidget { + /// Creates a [SettingsSection]. + const SettingsSection({super.key}); + + @override + Widget build(BuildContext context) { + final TranslationsStaffProfileEn i18n = Translations.of( + context, + ).staff.profile; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + SectionTitle(i18n.sections.settings), + ProfileMenuGrid( + crossAxisCount: 3, + children: [ + ProfileMenuItem( + icon: UiIcons.globe, + label: i18n.menu_items.language, + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) => + const LanguageSelectorBottomSheet(), + ); + }, + ), + ], + ), + ], + ); + } +} diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/support_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/support_section.dart new file mode 100644 index 00000000..f547c340 --- /dev/null +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/support_section.dart @@ -0,0 +1,46 @@ +import 'package:core_localization/core_localization.dart'; +import 'package:design_system/design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; + +import '../profile_menu_grid.dart'; +import '../profile_menu_item.dart'; +import '../section_title.dart'; + +/// Widget displaying the support section of the staff profile. +/// +/// This section contains menu items for FAQs and privacy & security settings. +class SupportSection extends StatelessWidget { + /// Creates a [SupportSection]. + const SupportSection({super.key}); + + @override + Widget build(BuildContext context) { + final TranslationsStaffProfileEn i18n = Translations.of( + context, + ).staff.profile; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SectionTitle(i18n.sections.support), + ProfileMenuGrid( + crossAxisCount: 3, + children: [ + ProfileMenuItem( + icon: UiIcons.helpCircle, + label: i18n.menu_items.faqs, + onTap: () => Modular.to.toFaqs(), + ), + ProfileMenuItem( + icon: UiIcons.shield, + label: i18n.menu_items.privacy_security, + onTap: () => Modular.to.toPrivacySecurity(), + ), + ], + ), + ], + ); + } +}