refactor: Update UI theme and shift details layout for improved consistency

This commit is contained in:
Achintha Isuru
2026-02-16 13:09:10 -05:00
parent e6b512ee84
commit 2a0b39926a
2 changed files with 231 additions and 224 deletions

View File

@@ -40,7 +40,7 @@ class UiTheme {
dividerTheme: const DividerThemeData(
color: UiColors.separatorPrimary,
space: 1,
thickness: 1,
thickness: 0.5,
),
// Card Theme

View File

@@ -72,9 +72,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
return Container(
padding: const EdgeInsets.symmetric(vertical: UiConstants.space3),
decoration: BoxDecoration(
color: UiColors.background,
borderRadius: BorderRadius.circular(UiConstants.radiusMdValue),
border: Border.all(color: UiColors.border),
color: UiColors.bgThird,
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
child: Column(
children: [
@@ -104,8 +103,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
return Container(
padding: const EdgeInsets.all(UiConstants.space3),
decoration: BoxDecoration(
color: UiColors.background,
borderRadius: BorderRadius.circular(UiConstants.radiusMdValue),
color: UiColors.bgThird,
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
child: Column(
children: [
@@ -184,229 +183,265 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
children: [
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Role & Client Section
Row(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: UiConstants.space4,
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: UiColors.background,
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: UiConstants.space4,
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: UiColors.background,
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
),
border: Border.all(color: UiColors.border),
),
border: Border.all(color: UiColors.border),
),
child: const Center(
child: Icon(
UiIcons.briefcase,
color: UiColors.primary,
size: 24,
child: const Center(
child: Icon(
UiIcons.briefcase,
color: UiColors.primary,
size: 24,
),
),
),
),
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
displayShift.title,
style:
UiTypography.headline1b.textPrimary,
),
Text(
displayShift.clientName,
style:
UiTypography.body1m.textSecondary,
),
Text(
displayShift.locationAddress,
style:
UiTypography.body2r.textSecondary,
),
],
),
),
],
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
const Divider(height: 1, thickness: 0.5),
// Date Section
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
i18n.shift_date,
style: UiTypography
.titleUppercase4b
.textSecondary,
),
const SizedBox(height: UiConstants.space2),
Row(
children: [
const Icon(
UiIcons.calendar,
size: 20,
color: UiColors.primary,
),
const SizedBox(width: UiConstants.space2),
Text(
displayShift.title,
_formatDate(displayShift.date),
style:
UiTypography.headline1b.textPrimary,
),
Text(
displayShift.clientName,
style: UiTypography.body1m.textSecondary,
),
Text(
displayShift.locationAddress,
style: UiTypography.body2r.textSecondary,
UiTypography.headline5m.textPrimary,
),
],
),
),
],
],
),
),
const SizedBox(height: UiConstants.space6),
// Date Section
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
i18n.shift_date,
style:
UiTypography.titleUppercase4b.textSecondary,
),
const SizedBox(height: UiConstants.space2),
Row(
children: [
const Icon(
UiIcons.calendar,
size: 20,
color: UiColors.primary,
),
const SizedBox(width: UiConstants.space2),
Text(
_formatDate(displayShift.date),
style: UiTypography.headline5m.textPrimary,
),
],
),
],
),
const SizedBox(height: UiConstants.space6),
const Divider(height: 1, thickness: 0.5),
// Stats Row (New)
Row(
children: [
Expanded(
child: _buildStatCard(
UiIcons.dollar,
"\$${estimatedTotal.toStringAsFixed(0)}",
"Total",
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Row(
children: [
Expanded(
child: _buildStatCard(
UiIcons.dollar,
"\$${estimatedTotal.toStringAsFixed(0)}",
"Total",
),
),
),
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildStatCard(
UiIcons.dollar,
"\$${displayShift.hourlyRate.toStringAsFixed(0)}",
"Hourly Rate",
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildStatCard(
UiIcons.dollar,
"\$${displayShift.hourlyRate.toStringAsFixed(0)}",
"Hourly Rate",
),
),
),
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildStatCard(
UiIcons.clock,
"${duration.toStringAsFixed(1)}",
"Hours",
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildStatCard(
UiIcons.clock,
duration.toStringAsFixed(1),
"Hours",
),
),
),
],
],
),
),
const SizedBox(height: UiConstants.space6),
const Divider(height: 1, thickness: 0.5),
// Time Section (New)
Row(
children: [
Expanded(
child: _buildTimeBox(
"CLOCK IN TIME",
displayShift.startTime,
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Row(
children: [
Expanded(
child: _buildTimeBox(
"CLOCK IN TIME",
displayShift.startTime,
),
),
),
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildTimeBox(
"CLOCK OUT TIME",
displayShift.endTime,
const SizedBox(width: UiConstants.space4),
Expanded(
child: _buildTimeBox(
"CLOCK OUT TIME",
displayShift.endTime,
),
),
),
],
],
),
),
const SizedBox(height: UiConstants.space6),
const Divider(height: 1, thickness: 0.5),
// Location Section (New with Map)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"LOCATION",
style:
UiTypography.titleUppercase4b.textSecondary,
),
const SizedBox(height: UiConstants.space3),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
displayShift.location.isEmpty
? "TBD"
: displayShift.location,
style: UiTypography.title1m.textPrimary,
overflow: TextOverflow.ellipsis,
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"LOCATION",
style: UiTypography
.titleUppercase4b
.textSecondary,
),
const SizedBox(height: UiConstants.space3),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
displayShift.location.isEmpty
? "TBD"
: displayShift.location,
style: UiTypography.title1m.textPrimary,
overflow: TextOverflow.ellipsis,
),
),
),
const SizedBox(width: UiConstants.space3),
OutlinedButton.icon(
onPressed: () {
ScaffoldMessenger.of(
context,
).showSnackBar(
SnackBar(
content: Text(
displayShift!
.locationAddress
.isNotEmpty
? displayShift!.locationAddress
: displayShift!.location,
const SizedBox(width: UiConstants.space3),
OutlinedButton.icon(
onPressed: () {
ScaffoldMessenger.of(
context,
).showSnackBar(
SnackBar(
content: Text(
displayShift!
.locationAddress
.isNotEmpty
? displayShift!
.locationAddress
: displayShift!.location,
),
duration: const Duration(
seconds: 3,
),
),
duration: const Duration(seconds: 3),
);
},
icon: const Icon(
UiIcons.navigation,
size: UiConstants.iconXs,
),
label: const Text("Get direction"),
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textPrimary,
side: const BorderSide(
color: UiColors.border,
),
);
},
icon: const Icon(
UiIcons.navigation,
size: UiConstants.iconXs,
),
label: const Text("Get direction"),
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textPrimary,
side: const BorderSide(
color: UiColors.border,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
),
),
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
vertical: 0,
),
minimumSize: const Size(0, 32),
),
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
vertical: 0,
),
minimumSize: const Size(0, 32),
),
),
],
),
const SizedBox(height: UiConstants.space3),
ShiftLocationMap(
shift: displayShift,
height: 160,
borderRadius: UiConstants.radiusBase,
),
],
],
),
const SizedBox(height: UiConstants.space3),
ShiftLocationMap(
shift: displayShift,
height: 160,
borderRadius: UiConstants.radiusBase,
),
],
),
),
const SizedBox(height: UiConstants.space8),
const Divider(height: 1, thickness: 0.5),
// Description / Instructions
if ((displayShift.description ?? '').isNotEmpty) ...[
Text(
i18n.job_description,
style:
UiTypography.titleUppercase4b.textSecondary,
Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
i18n.job_description,
style: UiTypography
.titleUppercase4b
.textSecondary,
),
const SizedBox(height: UiConstants.space2),
Text(
displayShift.description!,
style: UiTypography.body2r.textSecondary,
),
],
),
),
const SizedBox(height: UiConstants.space2),
Text(
displayShift.description!,
style: UiTypography.body2r.textSecondary,
),
const SizedBox(height: UiConstants.space8),
],
],
),
),
),
// Bottom Action Bar
Container(
padding: EdgeInsets.fromLTRB(
@@ -421,7 +456,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
border: Border(top: BorderSide(color: UiColors.border)),
boxShadow: [
BoxShadow(
color: UiColors.black.withValues(alpha: 0.05),
color: UiColors.popupShadow.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, -4),
),
@@ -628,46 +663,18 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
}
if (status == 'open' || status == 'available') {
return Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () => _declineShift(context, shift.id),
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textSecondary,
padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
side: const BorderSide(color: UiColors.border),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
),
child: Text(
i18n.decline,
style: UiTypography.body2b.textSecondary,
),
),
return ElevatedButton(
onPressed: () => _bookShift(context, shift),
style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary,
foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
const SizedBox(width: UiConstants.space4),
Expanded(
child: ElevatedButton(
onPressed: () => _bookShift(context, shift),
style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary,
foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
elevation: 0,
),
child: Text(i18n.apply_now, style: UiTypography.body2b.white),
),
),
],
elevation: 0,
),
child: Text(i18n.apply_now, style: UiTypography.body2b.white),
);
}