refactor: Replace attire option 'icon' field with 'description' across the schema and data models, and update the UI to display the new description.
This commit is contained in:
@@ -4,23 +4,23 @@ import 'package:equatable/equatable.dart';
|
|||||||
///
|
///
|
||||||
/// Attire items are specific clothing or equipment required for jobs.
|
/// Attire items are specific clothing or equipment required for jobs.
|
||||||
class AttireItem extends Equatable {
|
class AttireItem extends Equatable {
|
||||||
|
|
||||||
/// Creates an [AttireItem].
|
/// Creates an [AttireItem].
|
||||||
const AttireItem({
|
const AttireItem({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.label,
|
required this.label,
|
||||||
this.iconName,
|
this.description,
|
||||||
this.imageUrl,
|
this.imageUrl,
|
||||||
this.isMandatory = false,
|
this.isMandatory = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Unique identifier of the attire item.
|
/// Unique identifier of the attire item.
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
/// Display name of the item.
|
/// Display name of the item.
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
/// Name of the icon to display (mapped in UI).
|
/// Optional description for the attire item.
|
||||||
final String? iconName;
|
final String? description;
|
||||||
|
|
||||||
/// URL of the reference image.
|
/// URL of the reference image.
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
@@ -29,5 +29,11 @@ class AttireItem extends Equatable {
|
|||||||
final bool isMandatory;
|
final bool isMandatory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => <Object?>[id, label, iconName, imageUrl, isMandatory];
|
List<Object?> get props => <Object?>[
|
||||||
|
id,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
imageUrl,
|
||||||
|
isMandatory,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,30 @@ import '../../domain/repositories/attire_repository.dart';
|
|||||||
///
|
///
|
||||||
/// Delegates data access to [DataConnectService].
|
/// Delegates data access to [DataConnectService].
|
||||||
class AttireRepositoryImpl implements AttireRepository {
|
class AttireRepositoryImpl implements AttireRepository {
|
||||||
|
|
||||||
/// Creates an [AttireRepositoryImpl].
|
/// Creates an [AttireRepositoryImpl].
|
||||||
AttireRepositoryImpl({DataConnectService? service})
|
AttireRepositoryImpl({DataConnectService? service})
|
||||||
: _service = service ?? DataConnectService.instance;
|
: _service = service ?? DataConnectService.instance;
|
||||||
|
|
||||||
/// The Data Connect service.
|
/// The Data Connect service.
|
||||||
final DataConnectService _service;
|
final DataConnectService _service;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<AttireItem>> getAttireOptions() async {
|
Future<List<AttireItem>> getAttireOptions() async {
|
||||||
return _service.run(() async {
|
return _service.run(() async {
|
||||||
final QueryResult<ListAttireOptionsData, void> result =
|
final QueryResult<ListAttireOptionsData, void> result = await _service
|
||||||
await _service.connector.listAttireOptions().execute();
|
.connector
|
||||||
|
.listAttireOptions()
|
||||||
|
.execute();
|
||||||
return result.data.attireOptions
|
return result.data.attireOptions
|
||||||
.map((ListAttireOptionsAttireOptions e) => AttireItem(
|
.map(
|
||||||
id: e.itemId,
|
(ListAttireOptionsAttireOptions e) => AttireItem(
|
||||||
label: e.label,
|
id: e.itemId,
|
||||||
iconName: e.icon,
|
label: e.label,
|
||||||
imageUrl: e.imageUrl,
|
description: e.description,
|
||||||
isMandatory: e.isMandatory ?? false,
|
imageUrl: e.imageUrl,
|
||||||
))
|
isMandatory: e.isMandatory ?? false,
|
||||||
|
),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:core_localization/core_localization.dart';
|
|||||||
import 'package:krow_domain/krow_domain.dart';
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
|
||||||
class AttireGrid extends StatelessWidget {
|
class AttireGrid extends StatelessWidget {
|
||||||
|
|
||||||
const AttireGrid({
|
const AttireGrid({
|
||||||
super.key,
|
super.key,
|
||||||
required this.items,
|
required this.items,
|
||||||
@@ -53,7 +52,9 @@ class AttireGrid extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isSelected ? UiColors.primary.withOpacity(0.1) : Colors.transparent,
|
color: isSelected
|
||||||
|
? UiColors.primary.withOpacity(0.1)
|
||||||
|
: Colors.transparent,
|
||||||
borderRadius: UiConstants.radiusSm,
|
borderRadius: UiConstants.radiusSm,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? UiColors.primary : UiColors.border,
|
color: isSelected ? UiColors.primary : UiColors.border,
|
||||||
@@ -67,19 +68,17 @@ class AttireGrid extends StatelessWidget {
|
|||||||
top: UiConstants.space2,
|
top: UiConstants.space2,
|
||||||
left: UiConstants.space2,
|
left: UiConstants.space2,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||||
horizontal: 6,
|
|
||||||
vertical: 2,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: UiColors.destructive, // Red
|
color: UiColors.destructive, // Red
|
||||||
borderRadius: UiConstants.radiusSm,
|
borderRadius: UiConstants.radiusSm,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
t.staff_profile_attire.status.required,
|
t.staff_profile_attire.status.required,
|
||||||
style: UiTypography.body3m.copyWith( // 12px Medium -> Bold
|
style: UiTypography.body3m.copyWith(
|
||||||
|
// 12px Medium -> Bold
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
color: UiColors.white,
|
color: UiColors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -97,11 +96,7 @@ class AttireGrid extends StatelessWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: const Center(
|
child: const Center(
|
||||||
child: Icon(
|
child: Icon(UiIcons.check, color: UiColors.white, size: 12),
|
||||||
UiIcons.check,
|
|
||||||
color: UiColors.white,
|
|
||||||
size: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -119,26 +114,34 @@ class AttireGrid extends StatelessWidget {
|
|||||||
height: 80,
|
height: 80,
|
||||||
width: 80,
|
width: 80,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
borderRadius: BorderRadius.circular(
|
||||||
|
UiConstants.radiusBase,
|
||||||
|
),
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: NetworkImage(item.imageUrl!),
|
image: NetworkImage(item.imageUrl!),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Icon(
|
: const Icon(
|
||||||
_getIcon(item.iconName),
|
UiIcons.shirt,
|
||||||
size: 48,
|
size: 48,
|
||||||
color: UiColors.textPrimary, // Was charcoal
|
color: UiColors.iconSecondary,
|
||||||
),
|
),
|
||||||
const SizedBox(height: UiConstants.space2),
|
const SizedBox(height: UiConstants.space2),
|
||||||
Text(
|
Text(
|
||||||
item.label,
|
item.label,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: UiTypography.body2m.copyWith(
|
style: UiTypography.body2m.textPrimary,
|
||||||
color: UiColors.textPrimary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
if (item.description != null)
|
||||||
|
Text(
|
||||||
|
item.description!,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: UiTypography.body3r.textSecondary,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -158,7 +161,9 @@ class AttireGrid extends StatelessWidget {
|
|||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: hasPhoto ? UiColors.primary : UiColors.border,
|
color: hasPhoto ? UiColors.primary : UiColors.border,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
borderRadius: BorderRadius.circular(
|
||||||
|
UiConstants.radiusBase,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -169,7 +174,9 @@ class AttireGrid extends StatelessWidget {
|
|||||||
height: 12,
|
height: 12,
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(UiColors.primary),
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
UiColors.primary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else if (hasPhoto)
|
else if (hasPhoto)
|
||||||
@@ -189,10 +196,12 @@ class AttireGrid extends StatelessWidget {
|
|||||||
isUploading
|
isUploading
|
||||||
? '...'
|
? '...'
|
||||||
: hasPhoto
|
: hasPhoto
|
||||||
? t.staff_profile_attire.status.added
|
? t.staff_profile_attire.status.added
|
||||||
: t.staff_profile_attire.status.add_photo,
|
: t.staff_profile_attire.status.add_photo,
|
||||||
style: UiTypography.body3m.copyWith(
|
style: UiTypography.body3m.copyWith(
|
||||||
color: hasPhoto ? UiColors.primary : UiColors.textSecondary,
|
color: hasPhoto
|
||||||
|
? UiColors.primary
|
||||||
|
: UiColors.textSecondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -217,23 +226,4 @@ class AttireGrid extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
IconData _getIcon(String? name) {
|
|
||||||
switch (name) {
|
|
||||||
case 'footprints':
|
|
||||||
return UiIcons.footprints;
|
|
||||||
case 'scissors':
|
|
||||||
return UiIcons.scissors;
|
|
||||||
case 'user':
|
|
||||||
return UiIcons.user;
|
|
||||||
case 'shirt':
|
|
||||||
return UiIcons.shirt;
|
|
||||||
case 'hardHat':
|
|
||||||
return UiIcons.hardHat;
|
|
||||||
case 'chefHat':
|
|
||||||
return UiIcons.chefHat;
|
|
||||||
default:
|
|
||||||
return UiIcons.help;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
mutation createAttireOption(
|
mutation createAttireOption(
|
||||||
$itemId: String!
|
$itemId: String!
|
||||||
$label: String!
|
$label: String!
|
||||||
$icon: String
|
$description: String
|
||||||
$imageUrl: String
|
$imageUrl: String
|
||||||
$isMandatory: Boolean
|
$isMandatory: Boolean
|
||||||
$vendorId: UUID
|
$vendorId: UUID
|
||||||
@@ -10,7 +10,7 @@ mutation createAttireOption(
|
|||||||
data: {
|
data: {
|
||||||
itemId: $itemId
|
itemId: $itemId
|
||||||
label: $label
|
label: $label
|
||||||
icon: $icon
|
description: $description
|
||||||
imageUrl: $imageUrl
|
imageUrl: $imageUrl
|
||||||
isMandatory: $isMandatory
|
isMandatory: $isMandatory
|
||||||
vendorId: $vendorId
|
vendorId: $vendorId
|
||||||
@@ -22,7 +22,7 @@ mutation updateAttireOption(
|
|||||||
$id: UUID!
|
$id: UUID!
|
||||||
$itemId: String
|
$itemId: String
|
||||||
$label: String
|
$label: String
|
||||||
$icon: String
|
$description: String
|
||||||
$imageUrl: String
|
$imageUrl: String
|
||||||
$isMandatory: Boolean
|
$isMandatory: Boolean
|
||||||
$vendorId: UUID
|
$vendorId: UUID
|
||||||
@@ -32,7 +32,7 @@ mutation updateAttireOption(
|
|||||||
data: {
|
data: {
|
||||||
itemId: $itemId
|
itemId: $itemId
|
||||||
label: $label
|
label: $label
|
||||||
icon: $icon
|
description: $description
|
||||||
imageUrl: $imageUrl
|
imageUrl: $imageUrl
|
||||||
isMandatory: $isMandatory
|
isMandatory: $isMandatory
|
||||||
vendorId: $vendorId
|
vendorId: $vendorId
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ query listAttireOptions @auth(level: USER) {
|
|||||||
id
|
id
|
||||||
itemId
|
itemId
|
||||||
label
|
label
|
||||||
icon
|
description
|
||||||
imageUrl
|
imageUrl
|
||||||
isMandatory
|
isMandatory
|
||||||
vendorId
|
vendorId
|
||||||
@@ -16,7 +16,7 @@ query getAttireOptionById($id: UUID!) @auth(level: USER) {
|
|||||||
id
|
id
|
||||||
itemId
|
itemId
|
||||||
label
|
label
|
||||||
icon
|
description
|
||||||
imageUrl
|
imageUrl
|
||||||
isMandatory
|
isMandatory
|
||||||
vendorId
|
vendorId
|
||||||
@@ -39,7 +39,7 @@ query filterAttireOptions(
|
|||||||
id
|
id
|
||||||
itemId
|
itemId
|
||||||
label
|
label
|
||||||
icon
|
description
|
||||||
imageUrl
|
imageUrl
|
||||||
isMandatory
|
isMandatory
|
||||||
vendorId
|
vendorId
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ type AttireOption @table(name: "attire_options") {
|
|||||||
id: UUID! @default(expr: "uuidV4()")
|
id: UUID! @default(expr: "uuidV4()")
|
||||||
itemId: String!
|
itemId: String!
|
||||||
label: String!
|
label: String!
|
||||||
icon: String
|
description: String
|
||||||
imageUrl: String
|
imageUrl: String
|
||||||
isMandatory: Boolean
|
isMandatory: Boolean
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user