feat: enhance experience management by introducing ExperienceSkill and Industry enums, refactoring related components
This commit is contained in:
@@ -53,6 +53,7 @@ export 'src/entities/financial/staff_payment.dart';
|
|||||||
export 'src/entities/profile/staff_document.dart';
|
export 'src/entities/profile/staff_document.dart';
|
||||||
export 'src/entities/profile/attire_item.dart';
|
export 'src/entities/profile/attire_item.dart';
|
||||||
export 'src/entities/profile/relationship_type.dart';
|
export 'src/entities/profile/relationship_type.dart';
|
||||||
|
export 'src/entities/profile/industry.dart';
|
||||||
|
|
||||||
// Ratings & Penalties
|
// Ratings & Penalties
|
||||||
export 'src/entities/ratings/staff_rating.dart';
|
export 'src/entities/ratings/staff_rating.dart';
|
||||||
@@ -82,3 +83,4 @@ export 'src/entities/availability/day_availability.dart';
|
|||||||
// Adapters
|
// Adapters
|
||||||
export 'src/adapters/profile/emergency_contact_adapter.dart';
|
export 'src/adapters/profile/emergency_contact_adapter.dart';
|
||||||
export 'src/adapters/profile/experience_adapter.dart';
|
export 'src/adapters/profile/experience_adapter.dart';
|
||||||
|
export 'src/entities/profile/experience_skill.dart';
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
enum ExperienceSkill {
|
||||||
|
foodService('food_service'),
|
||||||
|
bartending('bartending'),
|
||||||
|
eventSetup('event_setup'),
|
||||||
|
hospitality('hospitality'),
|
||||||
|
warehouse('warehouse'),
|
||||||
|
customerService('customer_service'),
|
||||||
|
cleaning('cleaning'),
|
||||||
|
security('security'),
|
||||||
|
retail('retail'),
|
||||||
|
cooking('cooking'),
|
||||||
|
cashier('cashier'),
|
||||||
|
server('server'),
|
||||||
|
barista('barista'),
|
||||||
|
hostHostess('host_hostess'),
|
||||||
|
busser('busser'),
|
||||||
|
driving('driving');
|
||||||
|
|
||||||
|
final String value;
|
||||||
|
const ExperienceSkill(this.value);
|
||||||
|
|
||||||
|
static ExperienceSkill? fromString(String value) {
|
||||||
|
try {
|
||||||
|
return ExperienceSkill.values.firstWhere((e) => e.value == value);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
enum Industry {
|
||||||
|
hospitality('hospitality'),
|
||||||
|
foodService('food_service'),
|
||||||
|
warehouse('warehouse'),
|
||||||
|
events('events'),
|
||||||
|
retail('retail'),
|
||||||
|
healthcare('healthcare'),
|
||||||
|
other('other');
|
||||||
|
|
||||||
|
final String value;
|
||||||
|
const Industry(this.value);
|
||||||
|
|
||||||
|
static Industry? fromString(String value) {
|
||||||
|
try {
|
||||||
|
return Industry.values.firstWhere((e) => e.value == value);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +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:krow_domain/krow_domain.dart';
|
||||||
import 'package:staff_authentication/src/presentation/widgets/common/section_title_subtitle.dart';
|
import 'package:staff_authentication/src/presentation/widgets/common/section_title_subtitle.dart';
|
||||||
import 'package:staff_authentication/staff_authentication.dart';
|
import 'package:staff_authentication/staff_authentication.dart';
|
||||||
|
|
||||||
@@ -17,28 +18,6 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
/// Callback for when industries change.
|
/// Callback for when industries change.
|
||||||
final ValueChanged<List<String>> onIndustriesChanged;
|
final ValueChanged<List<String>> onIndustriesChanged;
|
||||||
|
|
||||||
static const List<String> _allSkillKeys = <String>[
|
|
||||||
'food_service',
|
|
||||||
'bartending',
|
|
||||||
'warehouse',
|
|
||||||
'retail',
|
|
||||||
'events',
|
|
||||||
'customer_service',
|
|
||||||
'cleaning',
|
|
||||||
'security',
|
|
||||||
'driving',
|
|
||||||
'cooking',
|
|
||||||
];
|
|
||||||
|
|
||||||
static const List<String> _allIndustryKeys = <String>[
|
|
||||||
'hospitality',
|
|
||||||
'food_service',
|
|
||||||
'warehouse',
|
|
||||||
'events',
|
|
||||||
'retail',
|
|
||||||
'healthcare',
|
|
||||||
];
|
|
||||||
|
|
||||||
/// Creates a [ProfileSetupExperience] widget.
|
/// Creates a [ProfileSetupExperience] widget.
|
||||||
const ProfileSetupExperience({
|
const ProfileSetupExperience({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -92,15 +71,15 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
Wrap(
|
Wrap(
|
||||||
spacing: UiConstants.space2,
|
spacing: UiConstants.space2,
|
||||||
runSpacing: UiConstants.space2,
|
runSpacing: UiConstants.space2,
|
||||||
children: _allSkillKeys.map((String key) {
|
children: ExperienceSkill.values.map((ExperienceSkill skill) {
|
||||||
final bool isSelected = skills.contains(key);
|
final bool isSelected = skills.contains(skill.value);
|
||||||
// Dynamic translation access
|
// Dynamic translation access
|
||||||
final String label = _getSkillLabel(key);
|
final String label = _getSkillLabel(skill);
|
||||||
|
|
||||||
return UiChip(
|
return UiChip(
|
||||||
label: label,
|
label: label,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
onTap: () => _toggleSkill(skill: key),
|
onTap: () => _toggleSkill(skill: skill.value),
|
||||||
leadingIcon: isSelected ? UiIcons.check : null,
|
leadingIcon: isSelected ? UiIcons.check : null,
|
||||||
variant: UiChipVariant.primary,
|
variant: UiChipVariant.primary,
|
||||||
);
|
);
|
||||||
@@ -118,14 +97,14 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
Wrap(
|
Wrap(
|
||||||
spacing: UiConstants.space2,
|
spacing: UiConstants.space2,
|
||||||
runSpacing: UiConstants.space2,
|
runSpacing: UiConstants.space2,
|
||||||
children: _allIndustryKeys.map((String key) {
|
children: Industry.values.map((Industry industry) {
|
||||||
final bool isSelected = industries.contains(key);
|
final bool isSelected = industries.contains(industry.value);
|
||||||
final String label = _getIndustryLabel(key);
|
final String label = _getIndustryLabel(industry);
|
||||||
|
|
||||||
return UiChip(
|
return UiChip(
|
||||||
label: label,
|
label: label,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
onTap: () => _toggleIndustry(industry: key),
|
onTap: () => _toggleIndustry(industry: industry.value),
|
||||||
leadingIcon: isSelected ? UiIcons.check : null,
|
leadingIcon: isSelected ? UiIcons.check : null,
|
||||||
variant: isSelected
|
variant: isSelected
|
||||||
? UiChipVariant.accent
|
? UiChipVariant.accent
|
||||||
@@ -137,72 +116,74 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getSkillLabel(String key) {
|
String _getSkillLabel(ExperienceSkill skill) {
|
||||||
switch (key) {
|
switch (skill) {
|
||||||
case 'food_service':
|
case ExperienceSkill.foodService:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.food_service;
|
.food_service;
|
||||||
case 'bartending':
|
case ExperienceSkill.bartending:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.bartending;
|
.bartending;
|
||||||
case 'warehouse':
|
case ExperienceSkill.warehouse:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.warehouse;
|
.warehouse;
|
||||||
case 'retail':
|
case ExperienceSkill.retail:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.retail;
|
.retail;
|
||||||
case 'events':
|
// Note: 'events' was removed from enum in favor of 'event_setup' or industry.
|
||||||
|
// Using 'events' translation for eventSetup if available or fallback.
|
||||||
|
case ExperienceSkill.eventSetup:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.events;
|
.events;
|
||||||
case 'customer_service':
|
case ExperienceSkill.customerService:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.customer_service;
|
.customer_service;
|
||||||
case 'cleaning':
|
case ExperienceSkill.cleaning:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.cleaning;
|
.cleaning;
|
||||||
case 'security':
|
case ExperienceSkill.security:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.security;
|
.security;
|
||||||
case 'driving':
|
case ExperienceSkill.driving:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.skills
|
.skills
|
||||||
.driving;
|
.driving;
|
||||||
case 'cooking':
|
case ExperienceSkill.cooking:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
@@ -210,48 +191,48 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
.skills
|
.skills
|
||||||
.cooking;
|
.cooking;
|
||||||
default:
|
default:
|
||||||
return key;
|
return skill.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getIndustryLabel(String key) {
|
String _getIndustryLabel(Industry industry) {
|
||||||
switch (key) {
|
switch (industry) {
|
||||||
case 'hospitality':
|
case Industry.hospitality:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.industries
|
.industries
|
||||||
.hospitality;
|
.hospitality;
|
||||||
case 'food_service':
|
case Industry.foodService:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.industries
|
.industries
|
||||||
.food_service;
|
.food_service;
|
||||||
case 'warehouse':
|
case Industry.warehouse:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.industries
|
.industries
|
||||||
.warehouse;
|
.warehouse;
|
||||||
case 'events':
|
case Industry.events:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.industries
|
.industries
|
||||||
.events;
|
.events;
|
||||||
case 'retail':
|
case Industry.retail:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
.experience
|
.experience
|
||||||
.industries
|
.industries
|
||||||
.retail;
|
.retail;
|
||||||
case 'healthcare':
|
case Industry.healthcare:
|
||||||
return t
|
return t
|
||||||
.staff_authentication
|
.staff_authentication
|
||||||
.profile_setup_page
|
.profile_setup_page
|
||||||
@@ -259,7 +240,7 @@ class ProfileSetupExperience extends StatelessWidget {
|
|||||||
.industries
|
.industries
|
||||||
.healthcare;
|
.healthcare;
|
||||||
default:
|
default:
|
||||||
return key;
|
return industry.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ class ExperienceRepositoryImpl implements ExperienceRepositoryInterface {
|
|||||||
}) : _dataConnect = dataConnect,
|
}) : _dataConnect = dataConnect,
|
||||||
_firebaseAuth = firebaseAuth;
|
_firebaseAuth = firebaseAuth;
|
||||||
|
|
||||||
Future<dc.GetStaffByIdStaff> _getStaff(String staffId) async {
|
Future<dc.GetStaffByIdStaff> _getStaff() async {
|
||||||
final result = await _dataConnect.getStaffById(id: staffId).execute();
|
final user = _firebaseAuth.currentUser;
|
||||||
|
if (user == null) {
|
||||||
|
throw Exception('User not authenticated');
|
||||||
|
}
|
||||||
|
final result = await _dataConnect.getStaffById(id: user.uid).execute();
|
||||||
if (result.data.staff == null) {
|
if (result.data.staff == null) {
|
||||||
throw Exception('Staff profile not found');
|
throw Exception('Staff profile not found');
|
||||||
}
|
}
|
||||||
@@ -24,27 +28,31 @@ class ExperienceRepositoryImpl implements ExperienceRepositoryInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getIndustries(String staffId) async {
|
Future<List<String>> getIndustries() async {
|
||||||
final staff = await _getStaff(staffId);
|
final staff = await _getStaff();
|
||||||
return staff.industries ?? [];
|
return staff.industries ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getSkills(String staffId) async {
|
Future<List<String>> getSkills() async {
|
||||||
final staff = await _getStaff(staffId);
|
final staff = await _getStaff();
|
||||||
return staff.skills ?? [];
|
return staff.skills ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> saveExperience(
|
Future<void> saveExperience(
|
||||||
String staffId,
|
|
||||||
List<String> industries,
|
List<String> industries,
|
||||||
List<String> skills,
|
List<String> skills,
|
||||||
) async {
|
) async {
|
||||||
|
try {
|
||||||
|
final staff = await _getStaff();
|
||||||
await _dataConnect
|
await _dataConnect
|
||||||
.updateStaff(id: staffId)
|
.updateStaff(id: staff.id)
|
||||||
.industries(industries)
|
.industries(industries)
|
||||||
.skills(skills)
|
.skills(skills)
|
||||||
.execute();
|
.execute();
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Failed to save experience: $e');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import 'package:krow_core/core.dart';
|
|
||||||
|
|
||||||
class GetExperienceArguments extends UseCaseArgument {
|
|
||||||
final String staffId;
|
|
||||||
|
|
||||||
GetExperienceArguments({required this.staffId});
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [staffId];
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
import 'package:krow_core/core.dart';
|
import 'package:krow_core/core.dart';
|
||||||
|
|
||||||
class SaveExperienceArguments extends UseCaseArgument {
|
class SaveExperienceArguments extends UseCaseArgument {
|
||||||
final String staffId;
|
|
||||||
final List<String> industries;
|
final List<String> industries;
|
||||||
final List<String> skills;
|
final List<String> skills;
|
||||||
|
|
||||||
SaveExperienceArguments({
|
SaveExperienceArguments({
|
||||||
required this.staffId,
|
|
||||||
required this.industries,
|
required this.industries,
|
||||||
required this.skills,
|
required this.skills,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [staffId, industries, skills];
|
List<Object?> get props => [industries, skills];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
/// Interface for accessing staff experience data.
|
/// Interface for accessing staff experience data.
|
||||||
abstract class ExperienceRepositoryInterface {
|
abstract class ExperienceRepositoryInterface {
|
||||||
/// Fetches the list of industries associated with the staff member.
|
/// Fetches the list of industries associated with the staff member.
|
||||||
Future<List<String>> getIndustries(String staffId);
|
Future<List<String>> getIndustries();
|
||||||
|
|
||||||
/// Fetches the list of skills associated with the staff member.
|
/// Fetches the list of skills associated with the staff member.
|
||||||
Future<List<String>> getSkills(String staffId);
|
Future<List<String>> getSkills();
|
||||||
|
|
||||||
/// Saves the staff member's experience (industries and skills).
|
/// Saves the staff member's experience (industries and skills).
|
||||||
Future<void> saveExperience(
|
Future<void> saveExperience(
|
||||||
String staffId,
|
|
||||||
List<String> industries,
|
List<String> industries,
|
||||||
List<String> skills,
|
List<String> skills,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import 'package:krow_core/core.dart';
|
import 'package:krow_core/core.dart';
|
||||||
import '../arguments/get_experience_arguments.dart';
|
|
||||||
import '../repositories/experience_repository_interface.dart';
|
import '../repositories/experience_repository_interface.dart';
|
||||||
|
|
||||||
/// Use case for fetching staff industries.
|
/// Use case for fetching staff industries.
|
||||||
class GetStaffIndustriesUseCase implements UseCase<GetExperienceArguments, List<String>> {
|
class GetStaffIndustriesUseCase implements NoInputUseCase<List<String>> {
|
||||||
final ExperienceRepositoryInterface _repository;
|
final ExperienceRepositoryInterface _repository;
|
||||||
|
|
||||||
GetStaffIndustriesUseCase(this._repository);
|
GetStaffIndustriesUseCase(this._repository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> call(GetExperienceArguments input) {
|
Future<List<String>> call() {
|
||||||
return _repository.getIndustries(input.staffId);
|
return _repository.getIndustries();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import 'package:krow_core/core.dart';
|
import 'package:krow_core/core.dart';
|
||||||
import '../arguments/get_experience_arguments.dart';
|
|
||||||
import '../repositories/experience_repository_interface.dart';
|
import '../repositories/experience_repository_interface.dart';
|
||||||
|
|
||||||
/// Use case for fetching staff skills.
|
/// Use case for fetching staff skills.
|
||||||
class GetStaffSkillsUseCase implements UseCase<GetExperienceArguments, List<String>> {
|
class GetStaffSkillsUseCase implements NoInputUseCase<List<String>> {
|
||||||
final ExperienceRepositoryInterface _repository;
|
final ExperienceRepositoryInterface _repository;
|
||||||
|
|
||||||
GetStaffSkillsUseCase(this._repository);
|
GetStaffSkillsUseCase(this._repository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> call(GetExperienceArguments input) {
|
Future<List<String>> call() {
|
||||||
return _repository.getSkills(input.staffId);
|
return _repository.getSkills();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ class SaveExperienceUseCase extends UseCase<SaveExperienceArguments, void> {
|
|||||||
@override
|
@override
|
||||||
Future<void> call(SaveExperienceArguments params) {
|
Future<void> call(SaveExperienceArguments params) {
|
||||||
return repository.saveExperience(
|
return repository.saveExperience(
|
||||||
params.staffId,
|
|
||||||
params.industries,
|
params.industries,
|
||||||
params.skills,
|
params.skills,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import '../../domain/arguments/get_experience_arguments.dart';
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
import '../../domain/arguments/save_experience_arguments.dart';
|
import '../../domain/arguments/save_experience_arguments.dart';
|
||||||
import '../../domain/usecases/get_staff_industries_usecase.dart';
|
import '../../domain/usecases/get_staff_industries_usecase.dart';
|
||||||
import '../../domain/usecases/get_staff_skills_usecase.dart';
|
import '../../domain/usecases/get_staff_skills_usecase.dart';
|
||||||
@@ -17,7 +17,7 @@ abstract class ExperienceEvent extends Equatable {
|
|||||||
class ExperienceLoaded extends ExperienceEvent {}
|
class ExperienceLoaded extends ExperienceEvent {}
|
||||||
|
|
||||||
class ExperienceIndustryToggled extends ExperienceEvent {
|
class ExperienceIndustryToggled extends ExperienceEvent {
|
||||||
final String industry;
|
final Industry industry;
|
||||||
const ExperienceIndustryToggled(this.industry);
|
const ExperienceIndustryToggled(this.industry);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -47,10 +47,10 @@ enum ExperienceStatus { initial, loading, success, failure }
|
|||||||
|
|
||||||
class ExperienceState extends Equatable {
|
class ExperienceState extends Equatable {
|
||||||
final ExperienceStatus status;
|
final ExperienceStatus status;
|
||||||
final List<String> selectedIndustries;
|
final List<Industry> selectedIndustries;
|
||||||
final List<String> selectedSkills;
|
final List<String> selectedSkills;
|
||||||
final List<String> availableIndustries;
|
final List<Industry> availableIndustries;
|
||||||
final List<String> availableSkills;
|
final List<ExperienceSkill> availableSkills;
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
|
|
||||||
const ExperienceState({
|
const ExperienceState({
|
||||||
@@ -64,10 +64,10 @@ class ExperienceState extends Equatable {
|
|||||||
|
|
||||||
ExperienceState copyWith({
|
ExperienceState copyWith({
|
||||||
ExperienceStatus? status,
|
ExperienceStatus? status,
|
||||||
List<String>? selectedIndustries,
|
List<Industry>? selectedIndustries,
|
||||||
List<String>? selectedSkills,
|
List<String>? selectedSkills,
|
||||||
List<String>? availableIndustries,
|
List<Industry>? availableIndustries,
|
||||||
List<String>? availableSkills,
|
List<ExperienceSkill>? availableSkills,
|
||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
}) {
|
}) {
|
||||||
return ExperienceState(
|
return ExperienceState(
|
||||||
@@ -93,47 +93,18 @@ class ExperienceState extends Equatable {
|
|||||||
|
|
||||||
// BLoC
|
// BLoC
|
||||||
class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
||||||
static const List<String> _kAllIndustries = [
|
|
||||||
'hospitality',
|
|
||||||
'food_service',
|
|
||||||
'warehouse',
|
|
||||||
'events',
|
|
||||||
'retail',
|
|
||||||
'healthcare',
|
|
||||||
'other',
|
|
||||||
];
|
|
||||||
|
|
||||||
static const List<String> _kAllSkills = [
|
|
||||||
'food_service',
|
|
||||||
'bartending',
|
|
||||||
'event_setup',
|
|
||||||
'hospitality',
|
|
||||||
'warehouse',
|
|
||||||
'customer_service',
|
|
||||||
'cleaning',
|
|
||||||
'security',
|
|
||||||
'retail',
|
|
||||||
'cooking',
|
|
||||||
'cashier',
|
|
||||||
'server',
|
|
||||||
'barista',
|
|
||||||
'host_hostess',
|
|
||||||
'busser',
|
|
||||||
];
|
|
||||||
|
|
||||||
final GetStaffIndustriesUseCase getIndustries;
|
final GetStaffIndustriesUseCase getIndustries;
|
||||||
final GetStaffSkillsUseCase getSkills;
|
final GetStaffSkillsUseCase getSkills;
|
||||||
final SaveExperienceUseCase saveExperience;
|
final SaveExperienceUseCase saveExperience;
|
||||||
final String staffId;
|
|
||||||
|
|
||||||
ExperienceBloc({
|
ExperienceBloc({
|
||||||
required this.getIndustries,
|
required this.getIndustries,
|
||||||
required this.getSkills,
|
required this.getSkills,
|
||||||
required this.saveExperience,
|
required this.saveExperience,
|
||||||
required this.staffId,
|
|
||||||
}) : super(const ExperienceState(
|
}) : super(const ExperienceState(
|
||||||
availableIndustries: _kAllIndustries,
|
availableIndustries: Industry.values,
|
||||||
availableSkills: _kAllSkills,
|
availableSkills: ExperienceSkill.values,
|
||||||
)) {
|
)) {
|
||||||
on<ExperienceLoaded>(_onLoaded);
|
on<ExperienceLoaded>(_onLoaded);
|
||||||
on<ExperienceIndustryToggled>(_onIndustryToggled);
|
on<ExperienceIndustryToggled>(_onIndustryToggled);
|
||||||
@@ -148,15 +119,17 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
|||||||
) async {
|
) async {
|
||||||
emit(state.copyWith(status: ExperienceStatus.loading));
|
emit(state.copyWith(status: ExperienceStatus.loading));
|
||||||
try {
|
try {
|
||||||
final arguments = GetExperienceArguments(staffId: staffId);
|
|
||||||
final results = await Future.wait([
|
final results = await Future.wait([
|
||||||
getIndustries(arguments),
|
getIndustries(),
|
||||||
getSkills(arguments),
|
getSkills(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
status: ExperienceStatus.initial,
|
status: ExperienceStatus.initial,
|
||||||
selectedIndustries: results[0],
|
selectedIndustries: results[0]
|
||||||
|
.map((e) => Industry.fromString(e))
|
||||||
|
.whereType<Industry>()
|
||||||
|
.toList(),
|
||||||
selectedSkills: results[1],
|
selectedSkills: results[1],
|
||||||
));
|
));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -171,7 +144,7 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
|||||||
ExperienceIndustryToggled event,
|
ExperienceIndustryToggled event,
|
||||||
Emitter<ExperienceState> emit,
|
Emitter<ExperienceState> emit,
|
||||||
) {
|
) {
|
||||||
final industries = List<String>.from(state.selectedIndustries);
|
final industries = List<Industry>.from(state.selectedIndustries);
|
||||||
if (industries.contains(event.industry)) {
|
if (industries.contains(event.industry)) {
|
||||||
industries.remove(event.industry);
|
industries.remove(event.industry);
|
||||||
} else {
|
} else {
|
||||||
@@ -211,8 +184,7 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
|||||||
try {
|
try {
|
||||||
await saveExperience(
|
await saveExperience(
|
||||||
SaveExperienceArguments(
|
SaveExperienceArguments(
|
||||||
staffId: staffId,
|
industries: state.selectedIndustries.map((e) => e.value).toList(),
|
||||||
industries: state.selectedIndustries,
|
|
||||||
skills: state.selectedSkills,
|
skills: state.selectedSkills,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
import '../blocs/experience_bloc.dart';
|
import '../blocs/experience_bloc.dart';
|
||||||
import '../widgets/experience_custom_input.dart';
|
import '../widgets/experience_custom_input.dart';
|
||||||
import '../widgets/experience_section_title.dart';
|
import '../widgets/experience_section_title.dart';
|
||||||
@@ -22,37 +23,36 @@ class ExperiencePage extends StatelessWidget {
|
|||||||
class _ExperienceView extends StatelessWidget {
|
class _ExperienceView extends StatelessWidget {
|
||||||
const _ExperienceView();
|
const _ExperienceView();
|
||||||
|
|
||||||
String _getIndustryLabel(dynamic node, String key) {
|
String _getIndustryLabel(dynamic node, Industry industry) {
|
||||||
switch (key) {
|
switch (industry) {
|
||||||
case 'hospitality': return node.hospitality;
|
case Industry.hospitality: return node.hospitality;
|
||||||
case 'food_service': return node.food_service;
|
case Industry.foodService: return node.food_service;
|
||||||
case 'warehouse': return node.warehouse;
|
case Industry.warehouse: return node.warehouse;
|
||||||
case 'events': return node.events;
|
case Industry.events: return node.events;
|
||||||
case 'retail': return node.retail;
|
case Industry.retail: return node.retail;
|
||||||
case 'healthcare': return node.healthcare;
|
case Industry.healthcare: return node.healthcare;
|
||||||
case 'other': return node.other;
|
case Industry.other: return node.other;
|
||||||
default: return key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getSkillLabel(dynamic node, String key) {
|
String _getSkillLabel(dynamic node, ExperienceSkill skill) {
|
||||||
switch (key) {
|
switch (skill) {
|
||||||
case 'food_service': return node.food_service;
|
case ExperienceSkill.foodService: return node.food_service;
|
||||||
case 'bartending': return node.bartending;
|
case ExperienceSkill.bartending: return node.bartending;
|
||||||
case 'event_setup': return node.event_setup;
|
case ExperienceSkill.eventSetup: return node.event_setup;
|
||||||
case 'hospitality': return node.hospitality;
|
case ExperienceSkill.hospitality: return node.hospitality;
|
||||||
case 'warehouse': return node.warehouse;
|
case ExperienceSkill.warehouse: return node.warehouse;
|
||||||
case 'customer_service': return node.customer_service;
|
case ExperienceSkill.customerService: return node.customer_service;
|
||||||
case 'cleaning': return node.cleaning;
|
case ExperienceSkill.cleaning: return node.cleaning;
|
||||||
case 'security': return node.security;
|
case ExperienceSkill.security: return node.security;
|
||||||
case 'retail': return node.retail;
|
case ExperienceSkill.retail: return node.retail;
|
||||||
case 'cooking': return node.cooking;
|
case ExperienceSkill.driving: return node.driving;
|
||||||
case 'cashier': return node.cashier;
|
case ExperienceSkill.cooking: return node.cooking;
|
||||||
case 'server': return node.server;
|
case ExperienceSkill.cashier: return node.cashier;
|
||||||
case 'barista': return node.barista;
|
case ExperienceSkill.server: return node.server;
|
||||||
case 'host_hostess': return node.host_hostess;
|
case ExperienceSkill.barista: return node.barista;
|
||||||
case 'busser': return node.busser;
|
case ExperienceSkill.hostHostess: return node.host_hostess;
|
||||||
default: return key;
|
case ExperienceSkill.busser: return node.busser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +118,10 @@ class _ExperienceView extends StatelessWidget {
|
|||||||
.map(
|
.map(
|
||||||
(s) => UiChip(
|
(s) => UiChip(
|
||||||
label: _getSkillLabel(i18n.skills, s),
|
label: _getSkillLabel(i18n.skills, s),
|
||||||
isSelected: state.selectedSkills.contains(s),
|
isSelected: state.selectedSkills.contains(s.value),
|
||||||
onTap: () => BlocProvider.of<ExperienceBloc>(context)
|
onTap: () => BlocProvider.of<ExperienceBloc>(context)
|
||||||
.add(ExperienceSkillToggled(s)),
|
.add(ExperienceSkillToggled(s.value)),
|
||||||
variant: state.selectedSkills.contains(s)
|
variant: state.selectedSkills.contains(s.value)
|
||||||
? UiChipVariant.primary
|
? UiChipVariant.primary
|
||||||
: UiChipVariant.secondary,
|
: UiChipVariant.secondary,
|
||||||
),
|
),
|
||||||
@@ -147,7 +147,7 @@ class _ExperienceView extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildCustomSkillsList(ExperienceState state, dynamic i18n) {
|
Widget _buildCustomSkillsList(ExperienceState state, dynamic i18n) {
|
||||||
final customSkills = state.selectedSkills
|
final customSkills = state.selectedSkills
|
||||||
.where((s) => !state.availableSkills.contains(s))
|
.where((s) => !state.availableSkills.any((e) => e.value == s))
|
||||||
.toList();
|
.toList();
|
||||||
if (customSkills.isEmpty) return const SizedBox.shrink();
|
if (customSkills.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ class StaffProfileExperienceModule extends Module {
|
|||||||
getIndustries: i.get<GetStaffIndustriesUseCase>(),
|
getIndustries: i.get<GetStaffIndustriesUseCase>(),
|
||||||
getSkills: i.get<GetStaffSkillsUseCase>(),
|
getSkills: i.get<GetStaffSkillsUseCase>(),
|
||||||
saveExperience: i.get<SaveExperienceUseCase>(),
|
saveExperience: i.get<SaveExperienceUseCase>(),
|
||||||
// TODO: Get actual logged in staff ID
|
|
||||||
staffId: 'current-staff-id',
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user