feat: enhance staff home page with new widgets and improved UI consistency
This commit is contained in:
@@ -35,4 +35,9 @@ extension HomeNavigator on IModularNavigator {
|
|||||||
pushNamed('/shifts?tab=$tab');
|
pushNamed('/shifts?tab=$tab');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Navigates to the settings page.
|
||||||
|
void pushSettings() {
|
||||||
|
pushNamed('/settings');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ import 'package:staff_home/src/presentation/widgets/worker/benefits_widget.dart'
|
|||||||
import 'package:staff_home/src/presentation/widgets/worker/improve_yourself_widget.dart';
|
import 'package:staff_home/src/presentation/widgets/worker/improve_yourself_widget.dart';
|
||||||
import 'package:staff_home/src/presentation/widgets/worker/more_ways_widget.dart';
|
import 'package:staff_home/src/presentation/widgets/worker/more_ways_widget.dart';
|
||||||
|
|
||||||
|
/// The home page for the staff worker application.
|
||||||
|
///
|
||||||
|
/// This page displays the worker's dashboard including today's shifts,
|
||||||
|
/// tomorrow's shifts, recommended shifts, benefits, and other relevant
|
||||||
|
/// information. It follows Clean Architecture principles with state
|
||||||
|
/// managed by [HomeCubit].
|
||||||
/// The home page for the staff worker application.
|
/// The home page for the staff worker application.
|
||||||
///
|
///
|
||||||
/// This page displays the worker's dashboard including today's shifts,
|
/// This page displays the worker's dashboard including today's shifts,
|
||||||
@@ -27,6 +33,7 @@ import 'package:staff_home/src/presentation/widgets/worker/more_ways_widget.dart
|
|||||||
/// information. It follows Clean Architecture principles with state
|
/// information. It follows Clean Architecture principles with state
|
||||||
/// managed by [HomeCubit].
|
/// managed by [HomeCubit].
|
||||||
class WorkerHomePage extends StatelessWidget {
|
class WorkerHomePage extends StatelessWidget {
|
||||||
|
/// Creates a [WorkerHomePage].
|
||||||
const WorkerHomePage({super.key});
|
const WorkerHomePage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -37,19 +44,18 @@ class WorkerHomePage extends StatelessWidget {
|
|||||||
final sectionsI18n = i18n.sections;
|
final sectionsI18n = i18n.sections;
|
||||||
final emptyI18n = i18n.empty_states;
|
final emptyI18n = i18n.empty_states;
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider<HomeCubit>(
|
||||||
create: (_) => Modular.get<HomeCubit>()..loadShifts(),
|
create: (context) => Modular.get<HomeCubit>()..loadShifts(),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: UiColors.background,
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.only(bottom: 100),
|
padding: const EdgeInsets.only(bottom: UiConstants.space6),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const HomeHeader(),
|
const HomeHeader(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: const EdgeInsets.symmetric(horizontal: UiConstants.space4),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
BlocBuilder<HomeCubit, HomeState>(
|
BlocBuilder<HomeCubit, HomeState>(
|
||||||
@@ -61,23 +67,23 @@ class WorkerHomePage extends StatelessWidget {
|
|||||||
return PlaceholderBanner(
|
return PlaceholderBanner(
|
||||||
title: bannersI18n.complete_profile_title,
|
title: bannersI18n.complete_profile_title,
|
||||||
subtitle: bannersI18n.complete_profile_subtitle,
|
subtitle: bannersI18n.complete_profile_subtitle,
|
||||||
bg: Colors.blue[50]!,
|
bg: UiColors.bgHighlight,
|
||||||
accent: Colors.blue,
|
accent: UiColors.primary,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Modular.to.pushWorkerProfile();
|
Modular.to.pushWorkerProfile();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: UiConstants.space6),
|
||||||
PlaceholderBanner(
|
PlaceholderBanner(
|
||||||
title: bannersI18n.availability_title,
|
title: bannersI18n.availability_title,
|
||||||
subtitle: bannersI18n.availability_subtitle,
|
subtitle: bannersI18n.availability_subtitle,
|
||||||
bg: Colors.orange[50]!,
|
bg: UiColors.accent.withOpacity(0.1),
|
||||||
accent: Colors.orange,
|
accent: UiColors.accent,
|
||||||
onTap: () => Modular.to.pushAvailability(),
|
onTap: () => Modular.to.pushAvailability(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: UiConstants.space6),
|
||||||
|
|
||||||
// Auto Match Toggle
|
// Auto Match Toggle
|
||||||
BlocBuilder<HomeCubit, HomeState>(
|
BlocBuilder<HomeCubit, HomeState>(
|
||||||
@@ -94,7 +100,7 @@ class WorkerHomePage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: UiConstants.space6),
|
||||||
|
|
||||||
// Quick Actions
|
// Quick Actions
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -2,49 +2,43 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Widget for displaying an empty state message, using design system tokens.
|
||||||
class EmptyStateWidget extends StatelessWidget {
|
class EmptyStateWidget extends StatelessWidget {
|
||||||
|
/// The message to display.
|
||||||
final String message;
|
final String message;
|
||||||
|
/// Optional action link label.
|
||||||
final String? actionLink;
|
final String? actionLink;
|
||||||
|
/// Optional action callback.
|
||||||
final VoidCallback? onAction;
|
final VoidCallback? onAction;
|
||||||
|
|
||||||
const EmptyStateWidget({
|
/// Creates an [EmptyStateWidget].
|
||||||
super.key,
|
const EmptyStateWidget({super.key, required this.message, this.actionLink, this.onAction});
|
||||||
required this.message,
|
|
||||||
this.actionLink,
|
|
||||||
this.onAction,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(UiConstants.space4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFFF1F3F5),
|
color: UiColors.bgSecondary,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
message,
|
message,
|
||||||
style: const TextStyle(
|
style: UiTypography.body2r.copyWith(color: UiColors.mutedForeground),
|
||||||
color: UiColors.mutedForeground,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (actionLink != null)
|
if (actionLink != null)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: onAction,
|
onTap: onAction,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: UiConstants.space2),
|
||||||
child: Text(
|
child: Text(
|
||||||
actionLink!,
|
actionLink!,
|
||||||
style: const TextStyle(
|
style: UiTypography.body2m.copyWith(color: UiColors.primary),
|
||||||
color: UiColors.primary,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_modular/flutter_modular.dart';
|
|
||||||
import 'package:lucide_icons/lucide_icons.dart';
|
|
||||||
|
|
||||||
import 'package:design_system/design_system.dart';
|
|
||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Header widget for the staff home page, using design system tokens.
|
||||||
class HomeHeader extends StatelessWidget {
|
class HomeHeader extends StatelessWidget {
|
||||||
|
/// Creates a [HomeHeader].
|
||||||
const HomeHeader({super.key});
|
const HomeHeader({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final headerI18n = t.staff.home.header;
|
final headerI18n = t.staff.home.header;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(20, 24, 20, 16),
|
padding: EdgeInsets.fromLTRB(
|
||||||
child: Row(
|
UiConstants.space4,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
UiConstants.space4,
|
||||||
children: [
|
UiConstants.space4,
|
||||||
Row(
|
UiConstants.space3,
|
||||||
|
),
|
||||||
|
child:Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: 48,
|
width: 48,
|
||||||
@@ -25,12 +26,12 @@ class HomeHeader extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: UiColors.primary.withValues(alpha: 0.2),
|
color: UiColors.primary.withOpacity(0.2),
|
||||||
width: 2,
|
width: 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: UiColors.primary.withValues(alpha: 0.1),
|
backgroundColor: UiColors.primary.withOpacity(0.1),
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'K',
|
'K',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@@ -40,83 +41,22 @@ class HomeHeader extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: UiConstants.space3),
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
headerI18n.welcome_back,
|
headerI18n.welcome_back,
|
||||||
style: const TextStyle(
|
style: UiTypography.body3r.copyWith(color: UiColors.mutedForeground),
|
||||||
color: UiColors.mutedForeground,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
headerI18n.user_name_placeholder,
|
headerI18n.user_name_placeholder,
|
||||||
style: const TextStyle(
|
style: UiTypography.headline4m,
|
||||||
color: UiColors.foreground,
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => Modular.to.pushMessages(),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
_buildHeaderIcon(LucideIcons.bell),
|
|
||||||
const Positioned(
|
|
||||||
top: -2,
|
|
||||||
right: -2,
|
|
||||||
child: CircleAvatar(
|
|
||||||
radius: 8,
|
|
||||||
backgroundColor: Color(0xFFF04444),
|
|
||||||
child: Text(
|
|
||||||
'2',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => Modular.to.pushWorkerProfile(),
|
|
||||||
child: _buildHeaderIcon(LucideIcons.settings),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildHeaderIcon(IconData icon) {
|
|
||||||
return Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: const Offset(0, 1),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Icon(icon, color: UiColors.mutedForeground, size: 20),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ import 'package:design_system/design_system.dart';
|
|||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Card widget for displaying pending payment information, using design system tokens.
|
||||||
class PendingPaymentCard extends StatelessWidget {
|
class PendingPaymentCard extends StatelessWidget {
|
||||||
|
/// Creates a [PendingPaymentCard].
|
||||||
const PendingPaymentCard({super.key});
|
const PendingPaymentCard({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -15,15 +18,15 @@ class PendingPaymentCard extends StatelessWidget {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => Modular.to.pushPayments(),
|
onTap: () => Modular.to.pushPayments(),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(UiConstants.space4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [Colors.blue[50]!.withValues(alpha: 0.5), Colors.blue[50]!],
|
colors: [UiColors.primary.withOpacity(0.08), UiColors.primary.withOpacity(0.04)],
|
||||||
begin: Alignment.centerLeft,
|
begin: Alignment.centerLeft,
|
||||||
end: Alignment.centerRight,
|
end: Alignment.centerRight,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||||
border: Border.all(color: Colors.blue[100]!.withValues(alpha: 0.5)),
|
border: Border.all(color: UiColors.primary.withOpacity(0.12)),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
@@ -35,35 +38,28 @@ class PendingPaymentCard extends StatelessWidget {
|
|||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Color(0xFFE8F0FF),
|
color: UiColors.bgHighlight,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
LucideIcons.dollarSign,
|
LucideIcons.dollarSign,
|
||||||
color: Color(0xFF0047FF),
|
color: UiColors.primary,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: UiConstants.space3),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
pendingI18n.title,
|
pendingI18n.title,
|
||||||
style: const TextStyle(
|
style: UiTypography.body1b,
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 14,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
pendingI18n.subtitle,
|
pendingI18n.subtitle,
|
||||||
style: const TextStyle(
|
style: UiTypography.body3r.copyWith(color: UiColors.mutedForeground),
|
||||||
fontSize: 12,
|
|
||||||
color: UiColors.mutedForeground,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -72,20 +68,16 @@ class PendingPaymentCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'\$285.00',
|
'\$285.00',
|
||||||
style: TextStyle(
|
style: UiTypography.headline4m,
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 18,
|
|
||||||
color: Color(0xFF0047FF),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: UiConstants.space2),
|
||||||
Icon(
|
Icon(
|
||||||
LucideIcons.chevronRight,
|
LucideIcons.chevronRight,
|
||||||
color: Color(0xFF94A3B8),
|
color: UiColors.mutedForeground,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,61 +3,58 @@ import 'package:lucide_icons/lucide_icons.dart';
|
|||||||
|
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Banner widget for placeholder actions, using design system tokens.
|
||||||
class PlaceholderBanner extends StatelessWidget {
|
class PlaceholderBanner extends StatelessWidget {
|
||||||
|
/// Banner title
|
||||||
final String title;
|
final String title;
|
||||||
|
/// Banner subtitle
|
||||||
final String subtitle;
|
final String subtitle;
|
||||||
|
/// Banner background color
|
||||||
final Color bg;
|
final Color bg;
|
||||||
|
/// Banner accent color
|
||||||
final Color accent;
|
final Color accent;
|
||||||
|
/// Optional tap callback
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
const PlaceholderBanner({
|
/// Creates a [PlaceholderBanner].
|
||||||
super.key,
|
const PlaceholderBanner({super.key, required this.title, required this.subtitle, required this.bg, required this.accent, this.onTap});
|
||||||
required this.title,
|
|
||||||
required this.subtitle,
|
|
||||||
required this.bg,
|
|
||||||
required this.accent,
|
|
||||||
this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(UiConstants.space4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: bg,
|
color: bg,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||||
border: Border.all(color: accent.withValues(alpha: 0.3)),
|
border: Border.all(color: accent.withOpacity(0.3)),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8),
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
padding: const EdgeInsets.all(UiConstants.space2),
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: UiColors.bgBanner,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: Icon(LucideIcons.star, color: accent, size: 20),
|
child: Icon(LucideIcons.sparkles, color: accent, size: 20),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: UiConstants.space3),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: UiTypography.body1b,
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
subtitle,
|
subtitle,
|
||||||
style: const TextStyle(
|
style: UiTypography.body3r.copyWith(color: UiColors.mutedForeground),
|
||||||
fontSize: 12,
|
|
||||||
color: UiColors.mutedForeground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,17 +2,18 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Widget for a quick action button on the home page, using design system tokens.
|
||||||
class QuickActionItem extends StatelessWidget {
|
class QuickActionItem extends StatelessWidget {
|
||||||
|
/// The icon to display.
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
|
/// The label for the action.
|
||||||
final String label;
|
final String label;
|
||||||
|
/// The callback when tapped.
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
|
|
||||||
const QuickActionItem({
|
/// Creates a [QuickActionItem].
|
||||||
super.key,
|
const QuickActionItem({super.key, required this.icon, required this.label, required this.onTap});
|
||||||
required this.icon,
|
|
||||||
required this.label,
|
|
||||||
required this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -21,16 +22,16 @@ class QuickActionItem extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: 50,
|
width: 64,
|
||||||
height: 50,
|
height: 64,
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(UiConstants.space4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: UiColors.bgBanner,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
||||||
border: Border.all(color: const Color(0xFFF1F5F9)),
|
border: Border.all(color: UiColors.bgSecondary),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
color: UiColors.foreground.withOpacity(0.05),
|
||||||
blurRadius: 4,
|
blurRadius: 4,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
),
|
),
|
||||||
@@ -38,14 +39,10 @@ class QuickActionItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Icon(icon, color: UiColors.primary, size: 24),
|
child: Icon(icon, color: UiColors.primary, size: 24),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: UiConstants.space2),
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
style: const TextStyle(
|
style: UiTypography.body3r.copyWith(color: UiColors.foreground),
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,32 +3,29 @@ import 'package:lucide_icons/lucide_icons.dart';
|
|||||||
|
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Section header widget for home page sections, using design system tokens.
|
||||||
class SectionHeader extends StatelessWidget {
|
class SectionHeader extends StatelessWidget {
|
||||||
|
/// Section title
|
||||||
final String title;
|
final String title;
|
||||||
|
/// Optional action label
|
||||||
final String? action;
|
final String? action;
|
||||||
|
/// Optional action callback
|
||||||
final VoidCallback? onAction;
|
final VoidCallback? onAction;
|
||||||
|
|
||||||
const SectionHeader({
|
/// Creates a [SectionHeader].
|
||||||
super.key,
|
const SectionHeader({super.key, required this.title, this.action, this.onAction});
|
||||||
required this.title,
|
|
||||||
this.action,
|
|
||||||
this.onAction,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 12),
|
padding: const EdgeInsets.only(bottom: UiConstants.space3),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: UiTypography.headline4m,
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: UiColors.foreground,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (action != null)
|
if (action != null)
|
||||||
if (onAction != null)
|
if (onAction != null)
|
||||||
@@ -38,11 +35,7 @@ class SectionHeader extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
action!,
|
action!,
|
||||||
style: const TextStyle(
|
style: UiTypography.body2m.copyWith(color: UiColors.primary),
|
||||||
color: UiColors.primary,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Icon(
|
const Icon(
|
||||||
LucideIcons.chevronRight,
|
LucideIcons.chevronRight,
|
||||||
@@ -56,19 +49,15 @@ class SectionHeader extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: UiColors.primary.withValues(alpha: 0.08),
|
color: UiColors.primary.withOpacity(0.08),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: UiColors.primary.withValues(alpha: 0.2),
|
color: UiColors.primary.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
action!,
|
action!,
|
||||||
style: const TextStyle(
|
style: UiTypography.body3r.copyWith(color: UiColors.primary),
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: UiColors.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,33 +3,33 @@ import 'package:lucide_icons/lucide_icons.dart';
|
|||||||
|
|
||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
|
|
||||||
|
/// Toggle widget for auto-match feature, using design system tokens.
|
||||||
class AutoMatchToggle extends StatefulWidget {
|
class AutoMatchToggle extends StatefulWidget {
|
||||||
|
/// Whether auto-match is enabled.
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
|
/// Callback when toggled.
|
||||||
final ValueChanged<bool> onToggle;
|
final ValueChanged<bool> onToggle;
|
||||||
|
|
||||||
const AutoMatchToggle({
|
/// Creates an [AutoMatchToggle].
|
||||||
super.key,
|
const AutoMatchToggle({super.key, required this.enabled, required this.onToggle});
|
||||||
required this.enabled,
|
|
||||||
required this.onToggle,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AutoMatchToggle> createState() => _AutoMatchToggleState();
|
State<AutoMatchToggle> createState() => _AutoMatchToggleState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AutoMatchToggleState extends State<AutoMatchToggle>
|
class _AutoMatchToggleState extends State<AutoMatchToggle> with SingleTickerProviderStateMixin {
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final i18n = t.staff.home.auto_match;
|
final i18n = t.staff.home.auto_match;
|
||||||
|
final Color primary = Theme.of(context).colorScheme.primary;
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
gradient: widget.enabled
|
gradient: widget.enabled
|
||||||
? const LinearGradient(
|
? LinearGradient(
|
||||||
colors: [Color(0xFF0032A0), Color(0xFF0047CC)],
|
colors: [primary, primary.withOpacity(0.8)],
|
||||||
begin: Alignment.centerLeft,
|
begin: Alignment.centerLeft,
|
||||||
end: Alignment.centerRight,
|
end: Alignment.centerRight,
|
||||||
)
|
)
|
||||||
@@ -39,7 +39,7 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
|||||||
boxShadow: widget.enabled
|
boxShadow: widget.enabled
|
||||||
? [
|
? [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: const Color(0xFF0032A0).withValues(alpha: 0.3),
|
color: primary.withOpacity(0.3),
|
||||||
blurRadius: 10,
|
blurRadius: 10,
|
||||||
offset: const Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
),
|
),
|
||||||
@@ -58,15 +58,13 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
|||||||
height: 40,
|
height: 40,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: widget.enabled
|
color: widget.enabled
|
||||||
? Colors.white.withValues(alpha: 0.2)
|
? Colors.white.withOpacity(0.2)
|
||||||
: const Color(0xFF0032A0).withValues(alpha: 0.1),
|
: primary.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
LucideIcons.zap,
|
LucideIcons.zap,
|
||||||
color: widget.enabled
|
color: widget.enabled ? Colors.white : primary,
|
||||||
? Colors.white
|
|
||||||
: const Color(0xFF0032A0),
|
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -78,18 +76,14 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
|||||||
i18n.title,
|
i18n.title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: widget.enabled
|
color: widget.enabled ? Colors.white : const Color(0xFF0F172A),
|
||||||
? Colors.white
|
|
||||||
: const Color(0xFF0F172A),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
widget.enabled ? i18n.finding_shifts : i18n.get_matched,
|
widget.enabled ? i18n.finding_shifts : i18n.get_matched,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: widget.enabled
|
color: widget.enabled ? const Color(0xFFF8E08E) : Colors.grey.shade500,
|
||||||
? const Color(0xFFF8E08E)
|
|
||||||
: Colors.grey.shade500,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import 'dart:math' as math;
|
|||||||
|
|
||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Widget for displaying staff benefits, using design system tokens.
|
||||||
class BenefitsWidget extends StatelessWidget {
|
class BenefitsWidget extends StatelessWidget {
|
||||||
|
/// Creates a [BenefitsWidget].
|
||||||
const BenefitsWidget({super.key});
|
const BenefitsWidget({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -14,12 +17,12 @@ class BenefitsWidget extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: Colors.grey.shade100),
|
border: Border.all(color: Theme.of(context).dividerColor),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.05),
|
||||||
blurRadius: 2,
|
blurRadius: 2,
|
||||||
offset: const Offset(0, 1),
|
offset: const Offset(0, 1),
|
||||||
),
|
),
|
||||||
@@ -32,10 +35,7 @@ class BenefitsWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
i18n.title,
|
i18n.title,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Color(0xFF0F172A),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () => Modular.to.pushNamed('/benefits'),
|
onTap: () => Modular.to.pushNamed('/benefits'),
|
||||||
@@ -43,16 +43,12 @@ class BenefitsWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
i18n.view_all,
|
i18n.view_all,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(color: Theme.of(context).colorScheme.primary),
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Color(0xFF0032A0),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Icon(
|
Icon(
|
||||||
LucideIcons.chevronRight,
|
LucideIcons.chevronRight,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: Color(0xFF0032A0),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -67,19 +63,19 @@ class BenefitsWidget extends StatelessWidget {
|
|||||||
label: i18n.items.sick_days,
|
label: i18n.items.sick_days,
|
||||||
current: 10,
|
current: 10,
|
||||||
total: 40,
|
total: 40,
|
||||||
color: const Color(0xFF0A39DF),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
_BenefitItem(
|
_BenefitItem(
|
||||||
label: i18n.items.vacation,
|
label: i18n.items.vacation,
|
||||||
current: 40,
|
current: 40,
|
||||||
total: 40,
|
total: 40,
|
||||||
color: const Color(0xFF0A39DF),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
_BenefitItem(
|
_BenefitItem(
|
||||||
label: i18n.items.holidays,
|
label: i18n.items.holidays,
|
||||||
current: 24,
|
current: 24,
|
||||||
total: 24,
|
total: 24,
|
||||||
color: const Color(0xFF0A39DF),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
|
|
||||||
|
/// Widget for displaying self-improvement resources, using design system tokens.
|
||||||
class ImproveYourselfWidget extends StatelessWidget {
|
class ImproveYourselfWidget extends StatelessWidget {
|
||||||
|
/// Creates an [ImproveYourselfWidget].
|
||||||
const ImproveYourselfWidget({super.key});
|
const ImproveYourselfWidget({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final i18n = t.staff.home.improve;
|
final i18n = t.staff.home.improve;
|
||||||
@@ -12,16 +15,14 @@ class ImproveYourselfWidget extends StatelessWidget {
|
|||||||
'id': 'training',
|
'id': 'training',
|
||||||
'title': i18n.items.training.title,
|
'title': i18n.items.training.title,
|
||||||
'description': i18n.items.training.description,
|
'description': i18n.items.training.description,
|
||||||
'image':
|
'image': 'https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?w=400&h=300&fit=crop',
|
||||||
'https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?w=400&h=300&fit=crop',
|
|
||||||
'page': i18n.items.training.page,
|
'page': i18n.items.training.page,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 'podcast',
|
'id': 'podcast',
|
||||||
'title': i18n.items.podcast.title,
|
'title': i18n.items.podcast.title,
|
||||||
'description': i18n.items.podcast.description,
|
'description': i18n.items.podcast.description,
|
||||||
'image':
|
'image': 'https://images.unsplash.com/photo-1478737270239-2f02b77fc618?w=400&h=300&fit=crop',
|
||||||
'https://images.unsplash.com/photo-1478737270239-2f02b77fc618?w=400&h=300&fit=crop',
|
|
||||||
'page': i18n.items.podcast.page,
|
'page': i18n.items.podcast.page,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -31,11 +32,7 @@ class ImproveYourselfWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
i18n.title,
|
i18n.title,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF0F172A),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
@@ -56,12 +53,12 @@ class ImproveYourselfWidget extends StatelessWidget {
|
|||||||
width: 160,
|
width: 160,
|
||||||
margin: const EdgeInsets.only(right: 12),
|
margin: const EdgeInsets.only(right: 12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: Colors.grey.shade100),
|
border: Border.all(color: Theme.of(context).dividerColor),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.05),
|
||||||
blurRadius: 2,
|
blurRadius: 2,
|
||||||
offset: const Offset(0, 1),
|
offset: const Offset(0, 1),
|
||||||
),
|
),
|
||||||
@@ -78,7 +75,7 @@ class ImproveYourselfWidget extends StatelessWidget {
|
|||||||
item['image']!,
|
item['image']!,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
errorBuilder: (context, error, stackTrace) => Container(
|
errorBuilder: (context, error, stackTrace) => Container(
|
||||||
color: Colors.grey.shade200,
|
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
Icons.image_not_supported,
|
Icons.image_not_supported,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@@ -93,11 +90,7 @@ class ImproveYourselfWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
item['title']!,
|
item['title']!,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF0F172A),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Widget for displaying more ways to use Krow, using design system tokens.
|
||||||
class MoreWaysToUseKrowWidget extends StatelessWidget {
|
class MoreWaysToUseKrowWidget extends StatelessWidget {
|
||||||
|
/// Creates a [MoreWaysToUseKrowWidget].
|
||||||
const MoreWaysToUseKrowWidget({super.key});
|
const MoreWaysToUseKrowWidget({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final i18n = t.staff.home.more_ways;
|
final i18n = t.staff.home.more_ways;
|
||||||
@@ -11,15 +15,13 @@ class MoreWaysToUseKrowWidget extends StatelessWidget {
|
|||||||
{
|
{
|
||||||
'id': 'benefits',
|
'id': 'benefits',
|
||||||
'title': i18n.items.benefits.title,
|
'title': i18n.items.benefits.title,
|
||||||
'image':
|
'image': 'https://images.unsplash.com/photo-1481627834876-b7833e8f5570?w=400&h=300&fit=crop',
|
||||||
'https://images.unsplash.com/photo-1481627834876-b7833e8f5570?w=400&h=300&fit=crop',
|
|
||||||
'page': i18n.items.benefits.page,
|
'page': i18n.items.benefits.page,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 'refer',
|
'id': 'refer',
|
||||||
'title': i18n.items.refer.title,
|
'title': i18n.items.refer.title,
|
||||||
'image':
|
'image': 'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?w=400&h=300&fit=crop',
|
||||||
'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?w=400&h=300&fit=crop',
|
|
||||||
'page': i18n.items.refer.page,
|
'page': i18n.items.refer.page,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -29,11 +31,7 @@ class MoreWaysToUseKrowWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
i18n.title,
|
i18n.title,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF0F172A),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
@@ -54,12 +52,12 @@ class MoreWaysToUseKrowWidget extends StatelessWidget {
|
|||||||
width: 160,
|
width: 160,
|
||||||
margin: const EdgeInsets.only(right: 12),
|
margin: const EdgeInsets.only(right: 12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: Colors.grey.shade100),
|
border: Border.all(color: Theme.of(context).dividerColor),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withValues(alpha: 0.05),
|
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.05),
|
||||||
blurRadius: 2,
|
blurRadius: 2,
|
||||||
offset: const Offset(0, 1),
|
offset: const Offset(0, 1),
|
||||||
),
|
),
|
||||||
@@ -76,7 +74,7 @@ class MoreWaysToUseKrowWidget extends StatelessWidget {
|
|||||||
item['image']!,
|
item['image']!,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
errorBuilder: (context, error, stackTrace) => Container(
|
errorBuilder: (context, error, stackTrace) => Container(
|
||||||
color: Colors.grey.shade200,
|
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
Icons.image_not_supported,
|
Icons.image_not_supported,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@@ -88,11 +86,7 @@ class MoreWaysToUseKrowWidget extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Text(
|
child: Text(
|
||||||
item['title']!,
|
item['title']!,
|
||||||
style: const TextStyle(
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF0F172A),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user