Refactor widgets & imports; add krow_domain

Add local krow_domain dependency to client, staff apps and client home package. Numerous UI/widget cleanups across features: add const where applicable, use explicit List<Widget> types and List<Widget>.generate, add super.key to constructors, tighten BlocProvider generics, replace some Containers with SizedBox, and simplify InputDecoration/Border constructors. Fix API error handler to return a const UnknownException. Update internal imports to package-style paths (staff_home, staff_payments, staff_main repository interface) and normalize Flutter imports (use material.dart). Add missing braces for early returns in tax form pages. Mostly formatting and small API/typing refactors with no behavioral changes intended.
This commit is contained in:
Achintha Isuru
2026-03-18 10:27:31 -04:00
parent e471fd12f2
commit 9ee8467632
34 changed files with 128 additions and 151 deletions

View File

@@ -33,8 +33,9 @@ dependencies:
client_create_order: client_create_order:
path: ../../packages/features/client/orders/create_order path: ../../packages/features/client/orders/create_order
krow_core: krow_core:
path: ../../packages/core path: ../../packages/core
krow_domain:
path: ../../packages/domain
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
flutter_modular: ^6.3.2 flutter_modular: ^6.3.2
flutter_bloc: ^8.1.3 flutter_bloc: ^8.1.3

View File

@@ -28,6 +28,8 @@ dependencies:
path: ../../packages/features/staff/staff_main path: ../../packages/features/staff/staff_main
krow_core: krow_core:
path: ../../packages/core path: ../../packages/core
krow_domain:
path: ../../packages/domain
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
flutter_modular: ^6.3.0 flutter_modular: ^6.3.0
firebase_core: ^4.4.0 firebase_core: ^4.4.0

View File

@@ -97,7 +97,7 @@ mixin ApiErrorHandler {
); );
case DioExceptionType.cancel: case DioExceptionType.cancel:
return UnknownException( return const UnknownException(
technicalMessage: 'Request cancelled', technicalMessage: 'Request cancelled',
); );

View File

@@ -26,10 +26,10 @@ class InvoicesListSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
UiShimmerBox( UiShimmerBox(
width: 64, width: 64,
height: 22, height: 22,
@@ -47,10 +47,10 @@ class InvoicesListSkeleton extends StatelessWidget {
const SizedBox(height: UiConstants.space3), const SizedBox(height: UiConstants.space3),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
const Column( const Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
UiShimmerLine(width: 80, height: 10), UiShimmerLine(width: 80, height: 10),
SizedBox(height: UiConstants.space1), SizedBox(height: UiConstants.space1),
UiShimmerLine(width: 100, height: 20), UiShimmerLine(width: 100, height: 20),

View File

@@ -14,20 +14,20 @@ class ShiftCardSkeleton extends StatelessWidget {
borderRadius: UiConstants.radiusLg, borderRadius: UiConstants.radiusLg,
), ),
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
child: Column( child: Column(
children: [ children: <Widget>[
// Shift header // Shift header
Padding( Padding(
padding: const EdgeInsets.all(UiConstants.space4), padding: const EdgeInsets.all(UiConstants.space4),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
const UiShimmerLine(width: 180, height: 16), const UiShimmerLine(width: 180, height: 16),
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
const UiShimmerLine(width: 120, height: 12), const UiShimmerLine(width: 120, height: 12),
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
Row( Row(
children: [ children: <Widget>[
const UiShimmerLine(width: 80, height: 12), const UiShimmerLine(width: 80, height: 12),
const Spacer(), const Spacer(),
UiShimmerBox( UiShimmerBox(
@@ -47,7 +47,7 @@ class ShiftCardSkeleton extends StatelessWidget {
horizontal: UiConstants.space3, horizontal: UiConstants.space3,
).copyWith(bottom: UiConstants.space3), ).copyWith(bottom: UiConstants.space3),
child: const Column( child: const Column(
children: [ children: <Widget>[
UiShimmerListItem(), UiShimmerListItem(),
UiShimmerListItem(), UiShimmerListItem(),
], ],

View File

@@ -1,25 +1,21 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:client_home/src/presentation/blocs/client_home_bloc.dart'; import 'package:client_home/src/presentation/blocs/client_home_bloc.dart';
import 'package:client_home/src/presentation/blocs/client_home_event.dart'; import 'package:client_home/src/presentation/blocs/client_home_event.dart';
import 'package:client_home/src/presentation/blocs/client_home_state.dart'; import 'package:client_home/src/presentation/blocs/client_home_state.dart';
import 'package:client_home/src/presentation/widgets/dashboard_widget_builder.dart'; import 'package:client_home/src/presentation/widgets/dashboard_widget_builder.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
/// Widget that displays the home dashboard in edit mode with drag-and-drop support. /// Widget that displays the home dashboard in edit mode with drag-and-drop support.
/// ///
/// Allows users to reorder and rearrange dashboard widgets. /// Allows users to reorder and rearrange dashboard widgets.
class ClientHomeEditModeBody extends StatelessWidget { class ClientHomeEditModeBody extends StatelessWidget {
/// Creates a [ClientHomeEditModeBody].
const ClientHomeEditModeBody({required this.state, super.key});
/// The current home state. /// The current home state.
final ClientHomeState state; final ClientHomeState state;
/// Creates a [ClientHomeEditModeBody].
const ClientHomeEditModeBody({
required this.state,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ReorderableListView( return ReorderableListView(
@@ -30,18 +26,15 @@ class ClientHomeEditModeBody extends StatelessWidget {
100, 100,
), ),
onReorder: (int oldIndex, int newIndex) { onReorder: (int oldIndex, int newIndex) {
BlocProvider.of<ClientHomeBloc>(context) BlocProvider.of<ClientHomeBloc>(
.add(ClientHomeWidgetReordered(oldIndex, newIndex)); context,
).add(ClientHomeWidgetReordered(oldIndex, newIndex));
}, },
children: state.widgetOrder.map((String id) { children: state.widgetOrder.map((String id) {
return Container( return Container(
key: ValueKey<String>(id), key: ValueKey<String>(id),
margin: const EdgeInsets.only(bottom: UiConstants.space4), margin: const EdgeInsets.only(bottom: UiConstants.space4),
child: DashboardWidgetBuilder( child: DashboardWidgetBuilder(id: id, state: state, isEditMode: true),
id: id,
state: state,
isEditMode: true,
),
); );
}).toList(), }).toList(),
); );

View File

@@ -10,7 +10,7 @@ class ClientHomeHeaderSkeleton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return UiShimmer( return const UiShimmer(
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB( padding: const EdgeInsets.fromLTRB(
UiConstants.space4, UiConstants.space4,
@@ -18,14 +18,14 @@ class ClientHomeHeaderSkeleton extends StatelessWidget {
UiConstants.space4, UiConstants.space4,
UiConstants.space3, UiConstants.space3,
), ),
child: Row( child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: const <Widget>[
Row( const Row(
children: <Widget>[ children: const <Widget>[
const UiShimmerCircle(size: UiConstants.space10), const UiShimmerCircle(size: UiConstants.space10),
const SizedBox(width: UiConstants.space3), const SizedBox(width: UiConstants.space3),
Column( const Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[ children: const <Widget>[
UiShimmerLine(width: 80, height: 12), UiShimmerLine(width: 80, height: 12),
@@ -35,7 +35,7 @@ class ClientHomeHeaderSkeleton extends StatelessWidget {
), ),
], ],
), ),
Row( const Row(
spacing: UiConstants.space2, spacing: UiConstants.space2,
children: const <Widget>[ children: const <Widget>[
UiShimmerBox(width: 36, height: 36), UiShimmerBox(width: 36, height: 36),

View File

@@ -10,7 +10,7 @@ class ReorderSectionSkeleton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return const Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[ children: const <Widget>[
UiShimmerSectionHeader(), UiShimmerSectionHeader(),

View File

@@ -20,7 +20,8 @@ dependencies:
path: ../../../design_system path: ../../../design_system
core_localization: core_localization:
path: ../../../core_localization path: ../../../core_localization
krow_domain: ^0.0.1 krow_domain:
path: ../../../domain
krow_core: krow_core:
path: ../../../core path: ../../../core

View File

@@ -13,7 +13,7 @@ class HubsPageSkeleton extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return UiShimmer( return UiShimmer(
child: Column( child: Column(
children: List.generate(5, (int index) { children: List<Widget>.generate(5, (int index) {
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: UiConstants.space3), padding: const EdgeInsets.only(bottom: UiConstants.space3),
child: Container( child: Container(
@@ -23,7 +23,7 @@ class HubsPageSkeleton extends StatelessWidget {
), ),
padding: const EdgeInsets.all(UiConstants.space4), padding: const EdgeInsets.all(UiConstants.space4),
child: Row( child: Row(
children: [ children: <Widget>[
// Leading icon placeholder // Leading icon placeholder
UiShimmerBox( UiShimmerBox(
width: 52, width: 52,
@@ -35,7 +35,7 @@ class HubsPageSkeleton extends StatelessWidget {
const Expanded( const Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
UiShimmerLine(width: 160, height: 16), UiShimmerLine(width: 160, height: 16),
SizedBox(height: UiConstants.space2), SizedBox(height: UiConstants.space2),
UiShimmerLine(width: 200, height: 12), UiShimmerLine(width: 200, height: 12),

View File

@@ -24,7 +24,7 @@ class _PerformanceReportPageState extends State<PerformanceReportPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider<PerformanceBloc>(
create: (BuildContext context) => Modular.get<PerformanceBloc>() create: (BuildContext context) => Modular.get<PerformanceBloc>()
..add(LoadPerformanceReport(startDate: _startDate, endDate: _endDate)), ..add(LoadPerformanceReport(startDate: _startDate, endDate: _endDate)),
child: Scaffold( child: Scaffold(

View File

@@ -15,7 +15,7 @@ class ReportDetailSkeleton extends StatelessWidget {
return UiShimmer( return UiShimmer(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: [ children: <Widget>[
// Header area (matches the blue header with back button + title) // Header area (matches the blue header with back button + title)
Container( Container(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@@ -26,12 +26,12 @@ class ReportDetailSkeleton extends StatelessWidget {
), ),
color: UiColors.primary, color: UiColors.primary,
child: Row( child: Row(
children: [ children: <Widget>[
const UiShimmerCircle(size: UiConstants.space10), const UiShimmerCircle(size: UiConstants.space10),
const SizedBox(width: UiConstants.space3), const SizedBox(width: UiConstants.space3),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
UiShimmerBox( UiShimmerBox(
width: 140, width: 140,
height: 18, height: 18,
@@ -57,10 +57,10 @@ class ReportDetailSkeleton extends StatelessWidget {
const EdgeInsets.symmetric(horizontal: UiConstants.space5), const EdgeInsets.symmetric(horizontal: UiConstants.space5),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
// Summary stat cards row // Summary stat cards row
const Row( const Row(
children: [ children: <Widget>[
Expanded(child: UiShimmerStatsCard()), Expanded(child: UiShimmerStatsCard()),
SizedBox(width: UiConstants.space3), SizedBox(width: UiConstants.space3),
Expanded(child: UiShimmerStatsCard()), Expanded(child: UiShimmerStatsCard()),
@@ -78,14 +78,14 @@ class ReportDetailSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
const UiShimmerLine(width: 140, height: 14), const UiShimmerLine(width: 140, height: 14),
const SizedBox(height: UiConstants.space8), const SizedBox(height: UiConstants.space8),
Expanded( Expanded(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(7, (int index) { children: List<Widget>.generate(7, (int index) {
// Varying bar heights for visual interest // Varying bar heights for visual interest
final double height = final double height =
40.0 + (index * 17 % 120); 40.0 + (index * 17 % 120);
@@ -113,20 +113,20 @@ class ReportDetailSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
const UiShimmerLine(width: 160, height: 14), const UiShimmerLine(width: 160, height: 14),
const SizedBox(height: UiConstants.space6), const SizedBox(height: UiConstants.space6),
...List.generate(3, (int index) { ...List<Widget>.generate(3, (int index) {
return Padding( return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
bottom: UiConstants.space5, bottom: UiConstants.space5,
), ),
child: Column( child: Column(
children: [ children: <Widget>[
const Row( const Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceBetween, MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
UiShimmerLine(width: 100, height: 12), UiShimmerLine(width: 100, height: 12),
UiShimmerLine(width: 60, height: 12), UiShimmerLine(width: 60, height: 12),
], ],

View File

@@ -17,10 +17,10 @@ class MetricCardSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
// Icon + label row // Icon + label row
Row( const Row(
children: [ children: <Widget>[
const UiShimmerCircle(size: UiConstants.space6), const UiShimmerCircle(size: UiConstants.space6),
const SizedBox(width: UiConstants.space2), const SizedBox(width: UiConstants.space2),
const Expanded( const Expanded(

View File

@@ -22,7 +22,7 @@ class MetricsGridSkeleton extends StatelessWidget {
mainAxisSpacing: UiConstants.space3, mainAxisSpacing: UiConstants.space3,
crossAxisSpacing: UiConstants.space3, crossAxisSpacing: UiConstants.space3,
childAspectRatio: 1.32, childAspectRatio: 1.32,
children: List.generate(6, (int index) { children: List<Widget>.generate(6, (int index) {
return const MetricCardSkeleton(); return const MetricCardSkeleton();
}), }),
), ),

View File

@@ -10,7 +10,7 @@ class EditProfilePage extends StatefulWidget {
} }
class _EditProfilePageState extends State<EditProfilePage> { class _EditProfilePageState extends State<EditProfilePage> {
final _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late TextEditingController _firstNameController; late TextEditingController _firstNameController;
late TextEditingController _lastNameController; late TextEditingController _lastNameController;
late TextEditingController _emailController; late TextEditingController _emailController;
@@ -50,11 +50,11 @@ class _EditProfilePageState extends State<EditProfilePage> {
key: _formKey, key: _formKey,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Center( Center(
child: Stack( child: Stack(
children: [ children: <Widget>[
CircleAvatar( const CircleAvatar(
radius: 50, radius: 50,
backgroundColor: UiColors.bgSecondary, backgroundColor: UiColors.bgSecondary,
child: const Icon(UiIcons.user, size: 40, color: UiColors.primary), child: const Icon(UiIcons.user, size: 40, color: UiColors.primary),

View File

@@ -180,7 +180,7 @@ class _NotificationsSettingsCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<ClientSettingsBloc, ClientSettingsState>( return BlocBuilder<ClientSettingsBloc, ClientSettingsState>(
builder: (context, state) { builder: (BuildContext context, ClientSettingsState state) {
return Card( return Card(
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@@ -202,7 +202,7 @@ class _NotificationsSettingsCard extends StatelessWidget {
icon: UiIcons.bell, icon: UiIcons.bell,
title: context.t.client_settings.preferences.push, title: context.t.client_settings.preferences.push,
value: state.pushEnabled, value: state.pushEnabled,
onChanged: (val) => onChanged: (bool val) =>
ReadContext(context).read<ClientSettingsBloc>().add( ReadContext(context).read<ClientSettingsBloc>().add(
ClientSettingsNotificationToggled( ClientSettingsNotificationToggled(
type: 'push', type: 'push',
@@ -214,7 +214,7 @@ class _NotificationsSettingsCard extends StatelessWidget {
icon: UiIcons.mail, icon: UiIcons.mail,
title: context.t.client_settings.preferences.email, title: context.t.client_settings.preferences.email,
value: state.emailEnabled, value: state.emailEnabled,
onChanged: (val) => onChanged: (bool val) =>
ReadContext(context).read<ClientSettingsBloc>().add( ReadContext(context).read<ClientSettingsBloc>().add(
ClientSettingsNotificationToggled( ClientSettingsNotificationToggled(
type: 'email', type: 'email',
@@ -226,7 +226,7 @@ class _NotificationsSettingsCard extends StatelessWidget {
icon: UiIcons.phone, icon: UiIcons.phone,
title: context.t.client_settings.preferences.sms, title: context.t.client_settings.preferences.sms,
value: state.smsEnabled, value: state.smsEnabled,
onChanged: (val) => onChanged: (bool val) =>
ReadContext(context).read<ClientSettingsBloc>().add( ReadContext(context).read<ClientSettingsBloc>().add(
ClientSettingsNotificationToggled( ClientSettingsNotificationToggled(
type: 'sms', type: 'sms',
@@ -244,10 +244,6 @@ class _NotificationsSettingsCard extends StatelessWidget {
} }
class _NotificationToggle extends StatelessWidget { class _NotificationToggle extends StatelessWidget {
final IconData icon;
final String title;
final bool value;
final ValueChanged<bool> onChanged;
const _NotificationToggle({ const _NotificationToggle({
required this.icon, required this.icon,
@@ -255,14 +251,18 @@ class _NotificationToggle extends StatelessWidget {
required this.value, required this.value,
required this.onChanged, required this.onChanged,
}); });
final IconData icon;
final String title;
final bool value;
final ValueChanged<bool> onChanged;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
Row( Row(
children: [ children: <Widget>[
Icon(icon, size: 20, color: UiColors.iconSecondary), Icon(icon, size: 20, color: UiColors.iconSecondary),
const SizedBox(width: UiConstants.space3), const SizedBox(width: UiConstants.space3),
Text(title, style: UiTypography.footnote1m.textPrimary), Text(title, style: UiTypography.footnote1m.textPrimary),

View File

@@ -1,10 +1,9 @@
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:staff_home/src/presentation/widgets/home_page/home_page_skeleton/quick_actions_skeleton.dart';
import 'quick_actions_skeleton.dart'; import 'package:staff_home/src/presentation/widgets/home_page/home_page_skeleton/recommended_section_skeleton.dart';
import 'recommended_section_skeleton.dart'; import 'package:staff_home/src/presentation/widgets/home_page/home_page_skeleton/shift_section_skeleton.dart';
import 'shift_section_skeleton.dart'; import 'package:staff_home/src/presentation/widgets/home_page/home_page_skeleton/skeleton_divider.dart';
import 'skeleton_divider.dart';
/// Shimmer loading skeleton for the staff home page. /// Shimmer loading skeleton for the staff home page.
/// ///

View File

@@ -1,7 +1,6 @@
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:staff_home/src/presentation/widgets/home_page/home_page_skeleton/shift_card_skeleton.dart';
import 'shift_card_skeleton.dart';
/// Skeleton for a shift section (section header + 2 shift card placeholders). /// Skeleton for a shift section (section header + 2 shift card placeholders).
class ShiftSectionSkeleton extends StatelessWidget { class ShiftSectionSkeleton extends StatelessWidget {

View File

@@ -1,7 +1,6 @@
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:staff_home/src/presentation/widgets/home_page/section_header.dart';
import 'section_header.dart';
/// A common layout widget for home page sections. /// A common layout widget for home page sections.
/// ///

View File

@@ -1,8 +1,7 @@
import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart'; import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import 'package:staff_payments/src/data/repositories/payments_repository_impl.dart'; import 'package:staff_payments/src/data/repositories/payments_repository_impl.dart';
import 'package:staff_payments/src/domain/repositories/payments_repository.dart'; import 'package:staff_payments/src/domain/repositories/payments_repository.dart';
import 'package:staff_payments/src/domain/usecases/get_payment_chart_usecase.dart'; import 'package:staff_payments/src/domain/usecases/get_payment_chart_usecase.dart';

View File

@@ -27,7 +27,7 @@ class EarlyPayPage extends StatelessWidget {
border: Border.all(color: UiColors.primary.withValues(alpha: 0.1)), border: Border.all(color: UiColors.primary.withValues(alpha: 0.1)),
), ),
child: Column( child: Column(
children: [ children: <Widget>[
Text( Text(
context.t.staff_payments.early_pay.available_label, context.t.staff_payments.early_pay.available_label,
style: UiTypography.body2m.textSecondary, style: UiTypography.body2m.textSecondary,
@@ -65,13 +65,13 @@ class EarlyPayPage extends StatelessWidget {
border: Border.all(color: UiColors.separatorPrimary), border: Border.all(color: UiColors.separatorPrimary),
), ),
child: Row( child: Row(
children: [ children: <Widget>[
const Icon(UiIcons.bank, size: 24, color: UiColors.primary), const Icon(UiIcons.bank, size: 24, color: UiColors.primary),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Text('Chase Bank', style: UiTypography.body2b.textPrimary), Text('Chase Bank', style: UiTypography.body2b.textPrimary),
Text('Ending in 4321', style: UiTypography.footnote2r.textSecondary), Text('Ending in 4321', style: UiTypography.footnote2r.textSecondary),
], ],

View File

@@ -18,13 +18,13 @@ class PaymentItemSkeleton extends StatelessWidget {
borderRadius: UiConstants.radiusLg, borderRadius: UiConstants.radiusLg,
), ),
child: const Row( child: const Row(
children: [ children: <Widget>[
UiShimmerCircle(size: 40), UiShimmerCircle(size: 40),
SizedBox(width: UiConstants.space3), SizedBox(width: UiConstants.space3),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
UiShimmerLine(width: 140, height: 14), UiShimmerLine(width: 140, height: 14),
SizedBox(height: UiConstants.space2), SizedBox(height: UiConstants.space2),
UiShimmerLine(width: 100, height: 12), UiShimmerLine(width: 100, height: 12),

View File

@@ -16,12 +16,12 @@ class PaymentsPageSkeleton extends StatelessWidget {
return UiShimmer( return UiShimmer(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: [ children: <Widget>[
// Header section with gradient // Header section with gradient
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: <Color>[
UiColors.primary, UiColors.primary,
UiColors.primary.withValues(alpha: 0.8), UiColors.primary.withValues(alpha: 0.8),
], ],
@@ -37,7 +37,7 @@ class PaymentsPageSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
// Title placeholder // Title placeholder
const UiShimmerLine(width: 120, height: 24), const UiShimmerLine(width: 120, height: 24),
const SizedBox(height: UiConstants.space6), const SizedBox(height: UiConstants.space6),
@@ -45,7 +45,7 @@ class PaymentsPageSkeleton extends StatelessWidget {
// Balance center // Balance center
const Center( const Center(
child: Column( child: Column(
children: [ children: <Widget>[
UiShimmerLine(width: 100, height: 14), UiShimmerLine(width: 100, height: 14),
SizedBox(height: UiConstants.space1), SizedBox(height: UiConstants.space1),
UiShimmerLine(width: 160, height: 36), UiShimmerLine(width: 160, height: 36),
@@ -73,7 +73,7 @@ class PaymentsPageSkeleton extends StatelessWidget {
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
// Earnings graph placeholder // Earnings graph placeholder
UiShimmerBox( UiShimmerBox(
width: double.infinity, width: double.infinity,
@@ -83,10 +83,10 @@ class PaymentsPageSkeleton extends StatelessWidget {
const SizedBox(height: UiConstants.space6), const SizedBox(height: UiConstants.space6),
// Quick stats row // Quick stats row
Row( const Row(
children: [ children: <Widget>[
Expanded(child: UiShimmerStatsCard()), Expanded(child: UiShimmerStatsCard()),
const SizedBox(width: UiConstants.space3), SizedBox(width: UiConstants.space3),
Expanded(child: UiShimmerStatsCard()), Expanded(child: UiShimmerStatsCard()),
], ],
), ),
@@ -99,7 +99,7 @@ class PaymentsPageSkeleton extends StatelessWidget {
// Payment history items // Payment history items
UiShimmerList( UiShimmerList(
itemCount: 4, itemCount: 4,
itemBuilder: (index) => const PaymentItemSkeleton(), itemBuilder: (int index) => const PaymentItemSkeleton(),
), ),
], ],
), ),

View File

@@ -26,9 +26,9 @@ class MenuSectionSkeleton extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
// Section title placeholder // Section title placeholder
Padding( const Padding(
padding: const EdgeInsets.only(left: UiConstants.space1), padding: EdgeInsets.only(left: UiConstants.space1),
child: const UiShimmerLine(width: 100, height: 12), child: UiShimmerLine(width: 100, height: 12),
), ),
const SizedBox(height: UiConstants.space3), const SizedBox(height: UiConstants.space3),
// Menu items grid // Menu items grid

View File

@@ -25,18 +25,18 @@ class ProfileHeaderSkeleton extends StatelessWidget {
bottom: Radius.circular(UiConstants.space6), bottom: Radius.circular(UiConstants.space6),
), ),
), ),
child: SafeArea( child: const SafeArea(
bottom: false, bottom: false,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
// Avatar placeholder // Avatar placeholder
const UiShimmerCircle(size: 112), UiShimmerCircle(size: 112),
const SizedBox(height: UiConstants.space4), SizedBox(height: UiConstants.space4),
// Name placeholder // Name placeholder
const UiShimmerLine(width: 160, height: 20), UiShimmerLine(width: 160, height: 20),
const SizedBox(height: UiConstants.space2), SizedBox(height: UiConstants.space2),
// Level badge placeholder // Level badge placeholder
const UiShimmerBox(width: 100, height: 24), UiShimmerBox(width: 100, height: 24),
], ],
), ),
), ),

View File

@@ -26,13 +26,11 @@ class ProfilePageSkeleton extends StatelessWidget {
// Content offset to overlap the header bottom radius // Content offset to overlap the header bottom radius
Transform.translate( Transform.translate(
offset: const Offset(0, -UiConstants.space6), offset: const Offset(0, -UiConstants.space6),
child: Padding( child: const Padding(
padding: const EdgeInsets.symmetric( padding: EdgeInsets.symmetric(horizontal: UiConstants.space5),
horizontal: UiConstants.space5,
),
child: Column( child: Column(
spacing: UiConstants.space6, spacing: UiConstants.space6,
children: const <Widget>[ children: <Widget>[
// Reliability stats row (5 items) // Reliability stats row (5 items)
ReliabilityStatsSkeleton(), ReliabilityStatsSkeleton(),

View File

@@ -5,6 +5,7 @@ import 'package:core_localization/core_localization.dart';
/// Widget for certificate metadata input fields (name, issuer, number). /// Widget for certificate metadata input fields (name, issuer, number).
class CertificateMetadataFields extends StatelessWidget { class CertificateMetadataFields extends StatelessWidget {
const CertificateMetadataFields({ const CertificateMetadataFields({
super.key,
required this.nameController, required this.nameController,
required this.issuerController, required this.issuerController,
required this.numberController, required this.numberController,
@@ -32,9 +33,7 @@ class CertificateMetadataFields extends StatelessWidget {
enabled: isNewCertificate, enabled: isNewCertificate,
decoration: InputDecoration( decoration: InputDecoration(
hintText: t.staff_certificates.upload_modal.name_hint, hintText: t.staff_certificates.upload_modal.name_hint,
border: OutlineInputBorder( border: OutlineInputBorder(borderRadius: UiConstants.radiusLg),
borderRadius: UiConstants.radiusLg,
),
), ),
), ),
const SizedBox(height: UiConstants.space4), const SizedBox(height: UiConstants.space4),
@@ -50,27 +49,20 @@ class CertificateMetadataFields extends StatelessWidget {
enabled: isNewCertificate, enabled: isNewCertificate,
decoration: InputDecoration( decoration: InputDecoration(
hintText: t.staff_certificates.upload_modal.issuer_hint, hintText: t.staff_certificates.upload_modal.issuer_hint,
border: OutlineInputBorder( border: OutlineInputBorder(borderRadius: UiConstants.radiusLg),
borderRadius: UiConstants.radiusLg,
),
), ),
), ),
const SizedBox(height: UiConstants.space4), const SizedBox(height: UiConstants.space4),
// Certificate Number Field // Certificate Number Field
Text( Text('Certificate Number', style: UiTypography.body2m.textPrimary),
'Certificate Number',
style: UiTypography.body2m.textPrimary,
),
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
TextField( TextField(
controller: numberController, controller: numberController,
enabled: isNewCertificate, enabled: isNewCertificate,
decoration: InputDecoration( decoration: InputDecoration(
hintText: 'Enter number if applicable', hintText: 'Enter number if applicable',
border: OutlineInputBorder( border: OutlineInputBorder(borderRadius: UiConstants.radiusLg),
borderRadius: UiConstants.radiusLg,
),
), ),
), ),
], ],

View File

@@ -8,6 +8,7 @@ import '../../blocs/certificate_upload/certificate_upload_cubit.dart';
/// Widget for attestation checkbox and action buttons in certificate upload form. /// Widget for attestation checkbox and action buttons in certificate upload form.
class CertificateUploadActions extends StatelessWidget { class CertificateUploadActions extends StatelessWidget {
const CertificateUploadActions({ const CertificateUploadActions({
super.key,
required this.isAttested, required this.isAttested,
required this.isFormValid, required this.isFormValid,
required this.isUploading, required this.isUploading,
@@ -34,10 +35,9 @@ class CertificateUploadActions extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Checkbox( Checkbox(
value: isAttested, value: isAttested,
onChanged: (bool? val) => onChanged: (bool? val) => BlocProvider.of<CertificateUploadCubit>(
BlocProvider.of<CertificateUploadCubit>(context).setAttested( context,
val ?? false, ).setAttested(val ?? false),
),
activeColor: UiColors.primary, activeColor: UiColors.primary,
), ),
Expanded( Expanded(
@@ -54,17 +54,11 @@ class CertificateUploadActions extends StatelessWidget {
onPressed: isFormValid ? onUploadPressed : null, onPressed: isFormValid ? onUploadPressed : null,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary, backgroundColor: UiColors.primary,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: UiConstants.space4),
vertical: UiConstants.space4, shape: RoundedRectangleBorder(borderRadius: UiConstants.radiusLg),
),
shape: RoundedRectangleBorder(
borderRadius: UiConstants.radiusLg,
),
), ),
child: isUploading child: isUploading
? const CircularProgressIndicator( ? const CircularProgressIndicator(color: Colors.white)
color: Colors.white,
)
: Text( : Text(
t.staff_certificates.upload_modal.save, t.staff_certificates.upload_modal.save,
style: UiTypography.body1m.white, style: UiTypography.body1m.white,
@@ -87,9 +81,7 @@ class CertificateUploadActions extends StatelessWidget {
), ),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: UiConstants.radiusLg, borderRadius: UiConstants.radiusLg,
side: const BorderSide( side: const BorderSide(color: UiColors.destructive),
color: UiColors.destructive,
),
), ),
), ),
), ),

View File

@@ -6,6 +6,7 @@ import 'package:core_localization/core_localization.dart';
/// Widget for selecting certificate expiry date. /// Widget for selecting certificate expiry date.
class ExpiryDateField extends StatelessWidget { class ExpiryDateField extends StatelessWidget {
const ExpiryDateField({ const ExpiryDateField({
super.key,
required this.selectedDate, required this.selectedDate,
required this.onTap, required this.onTap,
}); });

View File

@@ -12,23 +12,23 @@ class CertificatesHeaderSkeleton extends StatelessWidget {
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(UiConstants.space5), padding: const EdgeInsets.all(UiConstants.space5),
decoration: const BoxDecoration(color: UiColors.primary), decoration: const BoxDecoration(color: UiColors.primary),
child: SafeArea( child: const SafeArea(
bottom: false, bottom: false,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
const SizedBox(height: UiConstants.space4), SizedBox(height: UiConstants.space4),
const UiShimmerCircle(size: 64), UiShimmerCircle(size: 64),
const SizedBox(height: UiConstants.space3), SizedBox(height: UiConstants.space3),
UiShimmerLine( UiShimmerLine(
width: 120, width: 120,
height: 14, height: 14,
), ),
const SizedBox(height: UiConstants.space2), SizedBox(height: UiConstants.space2),
UiShimmerLine( UiShimmerLine(
width: 80, width: 80,
height: 12, height: 12,
), ),
const SizedBox(height: UiConstants.space6), SizedBox(height: UiConstants.space6),
], ],
), ),
), ),

View File

@@ -178,8 +178,9 @@ class _FormI9PageState extends State<FormI9Page> {
} }
}, },
builder: (BuildContext context, FormI9State state) { builder: (BuildContext context, FormI9State state) {
if (state.status == FormI9Status.success) if (state.status == FormI9Status.success) {
return _buildSuccessView(i18n); return _buildSuccessView(i18n);
}
return Scaffold( return Scaffold(
backgroundColor: UiColors.background, backgroundColor: UiColors.background,

View File

@@ -180,8 +180,9 @@ class _FormW4PageState extends State<FormW4Page> {
} }
}, },
builder: (BuildContext context, FormW4State state) { builder: (BuildContext context, FormW4State state) {
if (state.status == FormW4Status.success) if (state.status == FormW4Status.success) {
return _buildSuccessView(i18n); return _buildSuccessView(i18n);
}
return Scaffold( return Scaffold(
backgroundColor: UiColors.background, backgroundColor: UiColors.background,

View File

@@ -39,11 +39,11 @@ class TappableRow extends StatelessWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: UiConstants.space3, spacing: UiConstants.space3,
children: [ children: <Widget>[
FieldLabel(text: i18n.locations_label), FieldLabel(text: i18n.locations_label),
GestureDetector( GestureDetector(
onTap: enabled ? onTap : null, onTap: enabled ? onTap : null,
child: Container( child: SizedBox(
width: double.infinity, width: double.infinity,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[

View File

@@ -1,7 +1,6 @@
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import 'package:staff_main/src/domain/repositories/staff_main_repository_interface.dart';
import '../../domain/repositories/staff_main_repository_interface.dart';
/// V2 API implementation of [StaffMainRepositoryInterface]. /// V2 API implementation of [StaffMainRepositoryInterface].
/// ///