From b29351a3aa44d67fe1ce81bea151f0a59ff84cc4 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Tue, 24 Feb 2026 15:13:06 -0500 Subject: [PATCH] refactor: Replace attire option 'icon' field with 'description' across the schema and data models, and update the UI to display the new description. --- .../lib/src/entities/profile/attire_item.dart | 16 ++-- .../attire_repository_impl.dart | 26 ++++--- .../src/presentation/widgets/attire_grid.dart | 78 ++++++++----------- .../connector/attireOption/mutations.gql | 8 +- .../connector/attireOption/queries.gql | 6 +- backend/dataconnect/schema/attireOption.gql | 2 +- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart b/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart index e9a56519..adcb0874 100644 --- a/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart +++ b/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart @@ -4,23 +4,23 @@ import 'package:equatable/equatable.dart'; /// /// Attire items are specific clothing or equipment required for jobs. class AttireItem extends Equatable { - /// Creates an [AttireItem]. const AttireItem({ required this.id, required this.label, - this.iconName, + this.description, this.imageUrl, this.isMandatory = false, }); + /// Unique identifier of the attire item. final String id; /// Display name of the item. final String label; - /// Name of the icon to display (mapped in UI). - final String? iconName; + /// Optional description for the attire item. + final String? description; /// URL of the reference image. final String? imageUrl; @@ -29,5 +29,11 @@ class AttireItem extends Equatable { final bool isMandatory; @override - List get props => [id, label, iconName, imageUrl, isMandatory]; + List get props => [ + id, + label, + description, + imageUrl, + isMandatory, + ]; } diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart index 704dab96..3cdd0d94 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart @@ -8,26 +8,30 @@ import '../../domain/repositories/attire_repository.dart'; /// /// Delegates data access to [DataConnectService]. class AttireRepositoryImpl implements AttireRepository { - /// Creates an [AttireRepositoryImpl]. AttireRepositoryImpl({DataConnectService? service}) - : _service = service ?? DataConnectService.instance; + : _service = service ?? DataConnectService.instance; + /// The Data Connect service. final DataConnectService _service; @override Future> getAttireOptions() async { return _service.run(() async { - final QueryResult result = - await _service.connector.listAttireOptions().execute(); + final QueryResult result = await _service + .connector + .listAttireOptions() + .execute(); return result.data.attireOptions - .map((ListAttireOptionsAttireOptions e) => AttireItem( - id: e.itemId, - label: e.label, - iconName: e.icon, - imageUrl: e.imageUrl, - isMandatory: e.isMandatory ?? false, - )) + .map( + (ListAttireOptionsAttireOptions e) => AttireItem( + id: e.itemId, + label: e.label, + description: e.description, + imageUrl: e.imageUrl, + isMandatory: e.isMandatory ?? false, + ), + ) .toList(); }); } diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_grid.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_grid.dart index e917a4c1..dc4a0c9e 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_grid.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_grid.dart @@ -5,7 +5,6 @@ import 'package:core_localization/core_localization.dart'; import 'package:krow_domain/krow_domain.dart'; class AttireGrid extends StatelessWidget { - const AttireGrid({ super.key, required this.items, @@ -53,7 +52,9 @@ class AttireGrid extends StatelessWidget { ) { return Container( decoration: BoxDecoration( - color: isSelected ? UiColors.primary.withOpacity(0.1) : Colors.transparent, + color: isSelected + ? UiColors.primary.withOpacity(0.1) + : Colors.transparent, borderRadius: UiConstants.radiusSm, border: Border.all( color: isSelected ? UiColors.primary : UiColors.border, @@ -67,19 +68,17 @@ class AttireGrid extends StatelessWidget { top: UiConstants.space2, left: UiConstants.space2, child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 2, - ), + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: UiColors.destructive, // Red borderRadius: UiConstants.radiusSm, ), child: Text( t.staff_profile_attire.status.required, - style: UiTypography.body3m.copyWith( // 12px Medium -> Bold + style: UiTypography.body3m.copyWith( + // 12px Medium -> Bold fontWeight: FontWeight.bold, - fontSize: 9, + fontSize: 9, color: UiColors.white, ), ), @@ -97,11 +96,7 @@ class AttireGrid extends StatelessWidget { shape: BoxShape.circle, ), child: const Center( - child: Icon( - UiIcons.check, - color: UiColors.white, - size: 12, - ), + child: Icon(UiIcons.check, color: UiColors.white, size: 12), ), ), ), @@ -119,26 +114,34 @@ class AttireGrid extends StatelessWidget { height: 80, width: 80, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: BorderRadius.circular( + UiConstants.radiusBase, + ), image: DecorationImage( image: NetworkImage(item.imageUrl!), fit: BoxFit.cover, ), ), ) - : Icon( - _getIcon(item.iconName), + : const Icon( + UiIcons.shirt, size: 48, - color: UiColors.textPrimary, // Was charcoal + color: UiColors.iconSecondary, ), const SizedBox(height: UiConstants.space2), Text( item.label, textAlign: TextAlign.center, - style: UiTypography.body2m.copyWith( - color: UiColors.textPrimary, - ), + style: UiTypography.body2m.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( color: hasPhoto ? UiColors.primary : UiColors.border, ), - borderRadius: BorderRadius.circular(UiConstants.radiusBase), + borderRadius: BorderRadius.circular( + UiConstants.radiusBase, + ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -169,7 +174,9 @@ class AttireGrid extends StatelessWidget { height: 12, child: CircularProgressIndicator( strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(UiColors.primary), + valueColor: AlwaysStoppedAnimation( + UiColors.primary, + ), ), ) else if (hasPhoto) @@ -189,10 +196,12 @@ class AttireGrid extends StatelessWidget { isUploading ? '...' : hasPhoto - ? t.staff_profile_attire.status.added - : t.staff_profile_attire.status.add_photo, + ? t.staff_profile_attire.status.added + : t.staff_profile_attire.status.add_photo, 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; - } - } } diff --git a/backend/dataconnect/connector/attireOption/mutations.gql b/backend/dataconnect/connector/attireOption/mutations.gql index 59f4f7f9..8ff9f197 100644 --- a/backend/dataconnect/connector/attireOption/mutations.gql +++ b/backend/dataconnect/connector/attireOption/mutations.gql @@ -1,7 +1,7 @@ mutation createAttireOption( $itemId: String! $label: String! - $icon: String + $description: String $imageUrl: String $isMandatory: Boolean $vendorId: UUID @@ -10,7 +10,7 @@ mutation createAttireOption( data: { itemId: $itemId label: $label - icon: $icon + description: $description imageUrl: $imageUrl isMandatory: $isMandatory vendorId: $vendorId @@ -22,7 +22,7 @@ mutation updateAttireOption( $id: UUID! $itemId: String $label: String - $icon: String + $description: String $imageUrl: String $isMandatory: Boolean $vendorId: UUID @@ -32,7 +32,7 @@ mutation updateAttireOption( data: { itemId: $itemId label: $label - icon: $icon + description: $description imageUrl: $imageUrl isMandatory: $isMandatory vendorId: $vendorId diff --git a/backend/dataconnect/connector/attireOption/queries.gql b/backend/dataconnect/connector/attireOption/queries.gql index 76ce2817..311fe9da 100644 --- a/backend/dataconnect/connector/attireOption/queries.gql +++ b/backend/dataconnect/connector/attireOption/queries.gql @@ -3,7 +3,7 @@ query listAttireOptions @auth(level: USER) { id itemId label - icon + description imageUrl isMandatory vendorId @@ -16,7 +16,7 @@ query getAttireOptionById($id: UUID!) @auth(level: USER) { id itemId label - icon + description imageUrl isMandatory vendorId @@ -39,7 +39,7 @@ query filterAttireOptions( id itemId label - icon + description imageUrl isMandatory vendorId diff --git a/backend/dataconnect/schema/attireOption.gql b/backend/dataconnect/schema/attireOption.gql index 2c09a410..8edf8254 100644 --- a/backend/dataconnect/schema/attireOption.gql +++ b/backend/dataconnect/schema/attireOption.gql @@ -2,7 +2,7 @@ type AttireOption @table(name: "attire_options") { id: UUID! @default(expr: "uuidV4()") itemId: String! label: String! - icon: String + description: String imageUrl: String isMandatory: Boolean