diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json index ce5481ed9..a0b3a2245 100644 --- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -2,7 +2,16 @@ "images" : [ { "filename" : "appstore.png", - "idiom" : "universal" + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" } ], "info" : { diff --git a/lib/data/core/extensions/date_formatter.dart b/lib/data/core/extensions/date_formatter.dart index fe3e2f279..484c88001 100644 --- a/lib/data/core/extensions/date_formatter.dart +++ b/lib/data/core/extensions/date_formatter.dart @@ -10,9 +10,10 @@ extension DateExtension on DateTime { String toMonthYear() { return DateFormat("MMMM, yyyy").format(this); } + String toDateWithoutYear(BuildContext context) { - final today= DateUtils.dateOnly(DateTime.now()); - if(isAtSameMomentAs(today)){ + final today = DateUtils.dateOnly(DateTime.now()); + if (isAtSameMomentAs(today)) { return context.l10n.dateFormatter_today; } return DateFormat("MMMM d, EEE").format(this); diff --git a/lib/data/core/mixin/input_validation.dart b/lib/data/core/mixin/input_validation.dart index 853fab3bd..5851d833c 100644 --- a/lib/data/core/mixin/input_validation.dart +++ b/lib/data/core/mixin/input_validation.dart @@ -10,4 +10,10 @@ mixin InputValidationMixin { email.length >= 4 && email.contains('@') && email.contains('.'); + + bool validPhoneNumber(String? number) { + String pattern = r'(^(?:[+0]9)?[0-9]{10}$)'; + RegExp regExp = RegExp(pattern); + return number != null && regExp.hasMatch(number); + } } diff --git a/lib/data/core/utils/date_formatter.dart b/lib/data/core/utils/date_formatter.dart index 7d653d505..b3be382cf 100644 --- a/lib/data/core/utils/date_formatter.dart +++ b/lib/data/core/utils/date_formatter.dart @@ -86,22 +86,23 @@ class DateFormatter { } } - String showBirthdays({required DateTime dateTime,required String name}){ + String showBirthdays({required DateTime dateTime, required String name}) { final today = DateTime.now().dateOnly; - if(dateTime.dateOnly.isAtSameMomentAs(today)){ + if (dateTime.dateOnly.isAtSameMomentAs(today)) { return _localization.present_birthday_text(name); - }else{ + } else { return "${_localization.upcoming_birthday_text(name)} ${getDateRepresentation(dateTime)}🎉"; } } - String showAnniversaries({required DateTime dateTime,required String name, int? number}){ + String showAnniversaries( + {required DateTime dateTime, required String name, int? number}) { final today = DateTime.now().dateOnly; - final difference= dateTime.difference(today); - int yearDifference= (difference.inDays/365).floor(); - if(dateTime.dateOnly.isAtSameMomentAs(today)){ + final difference = dateTime.difference(today); + int yearDifference = (difference.inDays / 365).floor(); + if (dateTime.dateOnly.isAtSameMomentAs(today)) { return _localization.present_anniversary_text(name, yearDifference); - }else{ + } else { return "${_localization.upcoming_anniversary_text(name, yearDifference)} ${getDateRepresentation(dateTime)}🎉"; } } diff --git a/lib/data/l10n/app_en.arb b/lib/data/l10n/app_en.arb index 0975b8a2a..982aed999 100644 --- a/lib/data/l10n/app_en.arb +++ b/lib/data/l10n/app_en.arb @@ -420,6 +420,7 @@ "fill_require_details_error": "Please fill required details!", "invalid_date_selection_error": "Please select valid date", "apply_leave_minimum_one_hour_error": "Please apply leave for minimum half day", + "invalid_mobile_number_error":"Please enter valid phone number", "add_member_employee_exists_error": "Member already exists!", "leave_already_applied_error_message": "Leave request has been already applied!", "provide_required_information": "Please provide the required information to continue", diff --git a/lib/ui/admin/home/home_screen/admin_home_screen.dart b/lib/ui/admin/home/home_screen/admin_home_screen.dart index 20596541f..a6881145a 100644 --- a/lib/ui/admin/home/home_screen/admin_home_screen.dart +++ b/lib/ui/admin/home/home_screen/admin_home_screen.dart @@ -39,8 +39,8 @@ class AdminHomeScreenPage extends StatelessWidget { create: (context) => getIt()..add(FetchWhoIsOutCardLeaves())), BlocProvider( - create: (context) => getIt() - ..add(FetchCelebrations(DateTime.now()))), + create: (context) => + getIt()..add(FetchCelebrations())), ], child: const AdminHomeScreen(), ); @@ -84,7 +84,6 @@ class _AdminHomeScreenState extends State { children: [ const WhoIsOutCard(), const EventCard(), - const SizedBox( height: 20, ), diff --git a/lib/ui/admin/home/home_screen/widget/request_list.dart b/lib/ui/admin/home/home_screen/widget/request_list.dart index 0f6425fc8..5e5a46903 100644 --- a/lib/ui/admin/home/home_screen/widget/request_list.dart +++ b/lib/ui/admin/home/home_screen/widget/request_list.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localization.dart'; import 'package:go_router/go_router.dart'; import 'package:projectunity/data/core/extensions/context_extension.dart'; import 'package:sticky_headers/sticky_headers.dart'; diff --git a/lib/ui/shared/events/bloc/celebrations_bloc.dart b/lib/ui/shared/events/bloc/celebrations_bloc.dart index 689395ff3..e7b3efc3b 100644 --- a/lib/ui/shared/events/bloc/celebrations_bloc.dart +++ b/lib/ui/shared/events/bloc/celebrations_bloc.dart @@ -17,18 +17,17 @@ class CelebrationsBloc extends Bloc { List employees = []; List allBirthdayEvents = []; List allAnniversaryEvents = []; - List currentWeekBday=[]; - List currentWeekAnniversaries=[]; + List currentWeekBday = []; + List currentWeekAnniversaries = []; - CelebrationsBloc(this._employeeRepo) - : super(CelebrationsState(currentWeek: DateTime.now())) { + CelebrationsBloc(this._employeeRepo) : super(const CelebrationsState()) { on(_fetchEvent); on(_showAllBirthdays); on(_showAllAnniversaries); } - Future _fetchEvent(FetchCelebrations event, - Emitter emit) async { + Future _fetchEvent( + FetchCelebrations event, Emitter emit) async { try { emit(state.copyWith(status: Status.loading)); employees = _employeeRepo.allEmployees @@ -37,33 +36,37 @@ class CelebrationsBloc extends Bloc { employees = employees.map((e) { if (e.dateOfBirth != null) { final birthdate = e.dateOfBirth!.convertToUpcomingDay(); - final Event event = - Event(name: e.name, dateTime: birthdate, imageUrl: e.imageUrl); + final Event event = Event( + name: e.name, + dateTime: DateUtils.dateOnly(birthdate), + imageUrl: e.imageUrl); allBirthdayEvents.add(event); } final joiningDate = e.dateOfJoining.convertToUpcomingDay(); - final Event event = - Event(name: e.name, dateTime: joiningDate, imageUrl: e.imageUrl); + final Event event = Event( + name: e.name, + dateTime: DateUtils.dateOnly(joiningDate), + imageUrl: e.imageUrl); allAnniversaryEvents.add(event); return e; }).toList(); allBirthdayEvents.sort((a, b) => a.dateTime.compareTo(b.dateTime)); allAnniversaryEvents.sort((a, b) => a.dateTime.compareTo(b.dateTime)); - currentWeekBday = _getBirthdays(); - currentWeekAnniversaries = _getAnniversaries(); - emit(state - .copyWith(status: Status.success, birthdays: currentWeekBday, - anniversaries:currentWeekAnniversaries)); + currentWeekAnniversaries = _getAnniversaries(); + emit(state.copyWith( + status: Status.success, + birthdays: currentWeekBday, + anniversaries: currentWeekAnniversaries)); } on Exception { emit( state.copyWith(status: Status.error, error: firestoreFetchDataError)); } } - void _showAllBirthdays(ShowBirthdaysEvent event, - Emitter emit) { + void _showAllBirthdays( + ShowBirthdaysEvent event, Emitter emit) { bool showAllBirthdays = !state.showAllBdays; if (showAllBirthdays) { emit(state.copyWith( @@ -74,8 +77,8 @@ class CelebrationsBloc extends Bloc { } } - void _showAllAnniversaries(ShowAnniversariesEvent event, - Emitter emit) { + void _showAllAnniversaries( + ShowAnniversariesEvent event, Emitter emit) { bool allAnniversaries = !state.showAllAnniversaries; if (allAnniversaries) { emit(state.copyWith( @@ -90,16 +93,16 @@ class CelebrationsBloc extends Bloc { List _getBirthdays() { final List birthdays = allBirthdayEvents.where((event) { - return event.dateTime.isDateInCurrentWeek( - DateUtils.dateOnly(DateTime.now())); + return event.dateTime + .isDateInCurrentWeek(DateUtils.dateOnly(DateTime.now())); }).toList(); return birthdays; } List _getAnniversaries() { final List anniversaries = allAnniversaryEvents.where((event) { - return event.dateTime.isDateInCurrentWeek( - DateUtils.dateOnly(DateTime.now())); + return event.dateTime + .isDateInCurrentWeek(DateUtils.dateOnly(DateTime.now())); }).toList(); return anniversaries; } diff --git a/lib/ui/shared/events/bloc/celebrations_event.dart b/lib/ui/shared/events/bloc/celebrations_event.dart index 3e65e9517..e5e5c9839 100644 --- a/lib/ui/shared/events/bloc/celebrations_event.dart +++ b/lib/ui/shared/events/bloc/celebrations_event.dart @@ -1,9 +1,7 @@ -abstract class CelebrationEvent{} +abstract class CelebrationEvent {} -class FetchCelebrations extends CelebrationEvent{ - final DateTime dateTime; - FetchCelebrations( this.dateTime); - } +class FetchCelebrations extends CelebrationEvent {} - class ShowBirthdaysEvent extends CelebrationEvent{} -class ShowAnniversariesEvent extends CelebrationEvent{} \ No newline at end of file +class ShowBirthdaysEvent extends CelebrationEvent {} + +class ShowAnniversariesEvent extends CelebrationEvent {} diff --git a/lib/ui/shared/events/bloc/celebrations_state.dart b/lib/ui/shared/events/bloc/celebrations_state.dart index f46ae3d1d..22b6f1284 100644 --- a/lib/ui/shared/events/bloc/celebrations_state.dart +++ b/lib/ui/shared/events/bloc/celebrations_state.dart @@ -1,19 +1,16 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import '../../../../data/core/utils/bloc_status.dart'; -import '../../../../data/model/employee/employee.dart'; import '../model/event.dart'; part 'celebrations_state.freezed.dart'; @freezed -class CelebrationsState with _$CelebrationsState{ - const factory CelebrationsState({ - @Default(Status.initial) Status status, - required DateTime currentWeek, - @Default(false) bool showAllBdays, - @Default(false) bool showAllAnniversaries, - @Default([]) List birthdays, - @Default([]) List anniversaries, - String? error -})= _CelebrationsState; -} \ No newline at end of file +class CelebrationsState with _$CelebrationsState { + const factory CelebrationsState( + {@Default(Status.initial) Status status, + @Default(false) bool showAllBdays, + @Default(false) bool showAllAnniversaries, + @Default([]) List birthdays, + @Default([]) List anniversaries, + String? error}) = _CelebrationsState; +} diff --git a/lib/ui/shared/events/bloc/celebrations_state.freezed.dart b/lib/ui/shared/events/bloc/celebrations_state.freezed.dart index 23dd360d2..7e71d380d 100644 --- a/lib/ui/shared/events/bloc/celebrations_state.freezed.dart +++ b/lib/ui/shared/events/bloc/celebrations_state.freezed.dart @@ -17,7 +17,6 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$CelebrationsState { Status get status => throw _privateConstructorUsedError; - DateTime get currentWeek => throw _privateConstructorUsedError; bool get showAllBdays => throw _privateConstructorUsedError; bool get showAllAnniversaries => throw _privateConstructorUsedError; List get birthdays => throw _privateConstructorUsedError; @@ -37,7 +36,6 @@ abstract class $CelebrationsStateCopyWith<$Res> { @useResult $Res call( {Status status, - DateTime currentWeek, bool showAllBdays, bool showAllAnniversaries, List birthdays, @@ -59,7 +57,6 @@ class _$CelebrationsStateCopyWithImpl<$Res, $Val extends CelebrationsState> @override $Res call({ Object? status = null, - Object? currentWeek = null, Object? showAllBdays = null, Object? showAllAnniversaries = null, Object? birthdays = null, @@ -71,10 +68,6 @@ class _$CelebrationsStateCopyWithImpl<$Res, $Val extends CelebrationsState> ? _value.status : status // ignore: cast_nullable_to_non_nullable as Status, - currentWeek: null == currentWeek - ? _value.currentWeek - : currentWeek // ignore: cast_nullable_to_non_nullable - as DateTime, showAllBdays: null == showAllBdays ? _value.showAllBdays : showAllBdays // ignore: cast_nullable_to_non_nullable @@ -109,7 +102,6 @@ abstract class _$$CelebrationsStateImplCopyWith<$Res> @useResult $Res call( {Status status, - DateTime currentWeek, bool showAllBdays, bool showAllAnniversaries, List birthdays, @@ -129,7 +121,6 @@ class __$$CelebrationsStateImplCopyWithImpl<$Res> @override $Res call({ Object? status = null, - Object? currentWeek = null, Object? showAllBdays = null, Object? showAllAnniversaries = null, Object? birthdays = null, @@ -141,10 +132,6 @@ class __$$CelebrationsStateImplCopyWithImpl<$Res> ? _value.status : status // ignore: cast_nullable_to_non_nullable as Status, - currentWeek: null == currentWeek - ? _value.currentWeek - : currentWeek // ignore: cast_nullable_to_non_nullable - as DateTime, showAllBdays: null == showAllBdays ? _value.showAllBdays : showAllBdays // ignore: cast_nullable_to_non_nullable @@ -174,7 +161,6 @@ class __$$CelebrationsStateImplCopyWithImpl<$Res> class _$CelebrationsStateImpl implements _CelebrationsState { const _$CelebrationsStateImpl( {this.status = Status.initial, - required this.currentWeek, this.showAllBdays = false, this.showAllAnniversaries = false, final List birthdays = const [], @@ -187,8 +173,6 @@ class _$CelebrationsStateImpl implements _CelebrationsState { @JsonKey() final Status status; @override - final DateTime currentWeek; - @override @JsonKey() final bool showAllBdays; @override @@ -217,7 +201,7 @@ class _$CelebrationsStateImpl implements _CelebrationsState { @override String toString() { - return 'CelebrationsState(status: $status, currentWeek: $currentWeek, showAllBdays: $showAllBdays, showAllAnniversaries: $showAllAnniversaries, birthdays: $birthdays, anniversaries: $anniversaries, error: $error)'; + return 'CelebrationsState(status: $status, showAllBdays: $showAllBdays, showAllAnniversaries: $showAllAnniversaries, birthdays: $birthdays, anniversaries: $anniversaries, error: $error)'; } @override @@ -226,8 +210,6 @@ class _$CelebrationsStateImpl implements _CelebrationsState { (other.runtimeType == runtimeType && other is _$CelebrationsStateImpl && (identical(other.status, status) || other.status == status) && - (identical(other.currentWeek, currentWeek) || - other.currentWeek == currentWeek) && (identical(other.showAllBdays, showAllBdays) || other.showAllBdays == showAllBdays) && (identical(other.showAllAnniversaries, showAllAnniversaries) || @@ -243,7 +225,6 @@ class _$CelebrationsStateImpl implements _CelebrationsState { int get hashCode => Object.hash( runtimeType, status, - currentWeek, showAllBdays, showAllAnniversaries, const DeepCollectionEquality().hash(_birthdays), @@ -261,7 +242,6 @@ class _$CelebrationsStateImpl implements _CelebrationsState { abstract class _CelebrationsState implements CelebrationsState { const factory _CelebrationsState( {final Status status, - required final DateTime currentWeek, final bool showAllBdays, final bool showAllAnniversaries, final List birthdays, @@ -271,8 +251,6 @@ abstract class _CelebrationsState implements CelebrationsState { @override Status get status; @override - DateTime get currentWeek; - @override bool get showAllBdays; @override bool get showAllAnniversaries; diff --git a/lib/ui/shared/events/celebrations_event_card.dart b/lib/ui/shared/events/celebrations_event_card.dart index ca3e2afd9..104dfb771 100644 --- a/lib/ui/shared/events/celebrations_event_card.dart +++ b/lib/ui/shared/events/celebrations_event_card.dart @@ -1,12 +1,8 @@ -import 'package:collection/collection.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:projectunity/data/configs/theme.dart'; import 'package:projectunity/data/core/extensions/context_extension.dart'; import 'package:projectunity/data/core/extensions/date_formatter.dart'; -import 'package:projectunity/data/core/extensions/date_time.dart'; import 'package:projectunity/data/core/extensions/widget_extension.dart'; import 'package:projectunity/data/core/utils/date_formatter.dart'; import 'package:projectunity/ui/shared/events/bloc/celebrations_bloc.dart'; @@ -17,7 +13,6 @@ import 'package:projectunity/ui/widget/error_snack_bar.dart'; import 'package:projectunity/ui/widget/user_profile_image.dart'; import '../../../data/core/utils/bloc_status.dart'; -import '../../../data/model/employee/employee.dart'; import '../../../style/app_text_style.dart'; import 'model/event.dart'; @@ -61,23 +56,23 @@ class _EventCardState extends State { if (state.status == Status.loading) { return const AppCircularProgressIndicator(); } else if (state.status == Status.success) { - - return Column( - children: [ - EventsList( - header: "🎂 ${context.l10n.birthdays_tag} 🎂 ", - events: state.birthdays, - expanded: state.showAllBdays, - isAnniversary: false, - ), - EventsList( - header: "🎊 ${context.l10n.work_anniversaries_tag} 🎊 ", - events: state.anniversaries, - expanded: state.showAllAnniversaries, - isAnniversary: true, - ) - ], - ); + return Column( + children: [ + EventsList( + header: "🎂 ${context.l10n.birthdays_tag} 🎂 ", + events: state.birthdays, + expanded: state.showAllBdays, + isAnniversary: false, + ), + EventsList( + header: + "🎊 ${context.l10n.work_anniversaries_tag} 🎊 ", + events: state.anniversaries, + expanded: state.showAllAnniversaries, + isAnniversary: true, + ) + ], + ); } return const SizedBox(); }, @@ -112,7 +107,7 @@ class EventsList extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.only(left: 16.0,right: 16,bottom: 16), + padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -122,7 +117,7 @@ class EventsList extends StatelessWidget { Text( header, style: AppTextStyle.style18.copyWith( - color: context.colorScheme.textPrimary, + color: context.colorScheme.primary, fontWeight: FontWeight.w700), ), Container( @@ -157,20 +152,22 @@ class EventsList extends StatelessWidget { }) ], ), - const SizedBox(height: 16,), - events.isEmpty? - const EmptyCelebrationCard(): Column( - children: - events.map((event) { - return expanded - ? AllEventCard( - imageUrl: event.imageUrl, - name: event.name, - date: event.dateTime) - : CurrentWeekEventCard( - event: event, isAnniversary: isAnniversary); - }).toList(), + const SizedBox( + height: 16, ), + events.isEmpty + ? const EmptyCelebrationCard() + : Column( + children: events.map((event) { + return expanded + ? AllEventCard( + imageUrl: event.imageUrl, + name: event.name, + date: event.dateTime) + : CurrentWeekEventCard( + event: event, isAnniversary: isAnniversary); + }).toList(), + ), ], ), ); @@ -189,7 +186,7 @@ class CurrentWeekEventCard extends StatelessWidget { return Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(16), - margin: const EdgeInsets.symmetric( vertical: 8), + margin: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: context.colorScheme.containerLow, borderRadius: AppTheme.commonBorderRadius), @@ -258,7 +255,10 @@ class EmptyCelebrationCard extends StatelessWidget { @override Widget build(BuildContext context) { - return Text(context.l10n.no_event_text,style: AppTextStyle.style16.copyWith(color: context.colorScheme.textSecondary),); + return Text( + context.l10n.no_event_text, + style: AppTextStyle.style16 + .copyWith(color: context.colorScheme.textSecondary), + ); } } - diff --git a/lib/ui/shared/events/model/event.dart b/lib/ui/shared/events/model/event.dart index dd6620515..31f0dd97c 100644 --- a/lib/ui/shared/events/model/event.dart +++ b/lib/ui/shared/events/model/event.dart @@ -1,11 +1,12 @@ -import 'package:flutter/material.dart'; +import 'package:equatable/equatable.dart'; -class Event { +class Event extends Equatable { final String name; final String? imageUrl; - DateTime dateTime; + final DateTime dateTime; - Event({required this.name, required this.dateTime, this.imageUrl}) { - dateTime = DateUtils.dateOnly(dateTime); - } + const Event({required this.name, required this.dateTime, this.imageUrl}); + + @override + List get props => [name, imageUrl, dateTime]; } diff --git a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_bloc.dart b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_bloc.dart index 7862c75c3..a81bca6e9 100644 --- a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_bloc.dart +++ b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_bloc.dart @@ -26,6 +26,7 @@ class EmployeeEditProfileBloc : super(const EmployeeEditProfileState()) { on(_init); on(_validName); + on(_validNumber); on(_changeDateOfBirth); on(_changeGender); on(_updateEmployeeDetails); @@ -51,6 +52,15 @@ class EmployeeEditProfileBloc } } + void _validNumber(EditProfileNumberChangedEvent event, + Emitter emit) { + if (validPhoneNumber(event.number)) { + emit(state.copyWith(numberError: false)); + } else { + emit(state.copyWith(numberError: true)); + } + } + void _changeDateOfBirth(EditProfileChangeDateOfBirthEvent event, Emitter emit) { emit(state.changeDateOfBirth(dateOfBirth: event.dateOfBirth)); diff --git a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_event.dart b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_event.dart index 895e2bb91..6da078b45 100644 --- a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_event.dart +++ b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_event.dart @@ -24,6 +24,15 @@ class EditProfileNameChangedEvent extends EditProfileEvent { List get props => [name]; } +class EditProfileNumberChangedEvent extends EditProfileEvent { + final String number; + + EditProfileNumberChangedEvent({required this.number}); + + @override + List get props => [number]; +} + class EditProfileChangeDateOfBirthEvent extends EditProfileEvent { final DateTime? dateOfBirth; diff --git a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_state.dart b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_state.dart index f5d904efe..eb2c7bfec 100644 --- a/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_state.dart +++ b/lib/ui/shared/profile/edit_profile/bloc/employee_edit_profile_state.dart @@ -8,6 +8,7 @@ class EmployeeEditProfileState extends Equatable { final Gender? gender; final DateTime? dateOfBirth; final bool nameError; + final bool numberError; final String? error; final String? imageURL; @@ -17,15 +18,17 @@ class EmployeeEditProfileState extends Equatable { this.status = Status.initial, this.error, this.nameError = false, + this.numberError = false, this.imageURL, }); - bool get isDataValid => !nameError; + bool get isDataValid => !nameError && !numberError; EmployeeEditProfileState copyWith({ Gender? gender, DateTime? dateOfBirth, bool? nameError, + bool? numberError, String? error, Status? status, String? imageURL, @@ -35,6 +38,7 @@ class EmployeeEditProfileState extends Equatable { dateOfBirth: dateOfBirth ?? this.dateOfBirth, error: error, nameError: nameError ?? this.nameError, + numberError: numberError ?? this.numberError, status: status ?? this.status, imageURL: imageURL ?? this.imageURL); } @@ -44,6 +48,7 @@ class EmployeeEditProfileState extends Equatable { status: status, dateOfBirth: dateOfBirth, nameError: nameError, + numberError: numberError, error: error, gender: gender, imageURL: imageURL, @@ -55,6 +60,7 @@ class EmployeeEditProfileState extends Equatable { status: status, dateOfBirth: dateOfBirth, nameError: nameError, + numberError: numberError, error: error, gender: gender, imageURL: imageURL, @@ -63,5 +69,5 @@ class EmployeeEditProfileState extends Equatable { @override List get props => - [gender, dateOfBirth, status, nameError, error, imageURL]; + [gender, dateOfBirth, status, nameError, numberError, error, imageURL]; } diff --git a/lib/ui/shared/profile/edit_profile/widget/profile_form.dart b/lib/ui/shared/profile/edit_profile/widget/profile_form.dart index 92add4b51..2f74cd024 100644 --- a/lib/ui/shared/profile/edit_profile/widget/profile_form.dart +++ b/lib/ui/shared/profile/edit_profile/widget/profile_form.dart @@ -72,11 +72,23 @@ class ProfileForm extends StatelessWidget { FieldTitle(title: localization.employee_gender_tag), const GenderSelection(), FieldTitle(title: localization.employee_mobile_tag), - FieldEntry( - keyboardType: TextInputType.phone, - controller: phoneNumberController, - hintText: localization.admin_home_add_member_mobile_number_hint_text, - ), + BlocBuilder( + buildWhen: (previous, current) => + previous.numberError != current.numberError, + builder: (context, state) { + return FieldEntry( + maxLength: 13, + errorText: state.numberError + ? context.l10n.invalid_mobile_number_error + : null, + keyboardType: TextInputType.phone, + controller: phoneNumberController, + hintText: + localization.admin_home_add_member_mobile_number_hint_text, + onChanged: (value) => + bloc.add(EditProfileNumberChangedEvent(number: value)), + ); + }), FieldTitle(title: localization.employee_address_tag), FieldEntry( maxLine: 3, diff --git a/lib/ui/space/edit_space/edit_space_screen.dart b/lib/ui/space/edit_space/edit_space_screen.dart index da23a7019..f6bafcef7 100644 --- a/lib/ui/space/edit_space/edit_space_screen.dart +++ b/lib/ui/space/edit_space/edit_space_screen.dart @@ -243,13 +243,13 @@ class _OrgLogoView extends StatelessWidget { style: IconButton.styleFrom( fixedSize: const Size(45, 45), side: BorderSide( - color: context.colorScheme.containerNormal, width: 3), + color: context.colorScheme.textDisable, width: 3), backgroundColor: context.colorScheme.surface), onPressed: onButtonTap, icon: Icon( Icons.edit, size: 20, - color: context.colorScheme.containerHigh, + color: context.colorScheme.textDisable, ), ) ], diff --git a/lib/ui/user/home/home_screen/user_home_screen.dart b/lib/ui/user/home/home_screen/user_home_screen.dart index 7ff27a57e..d0ae0c8c3 100644 --- a/lib/ui/user/home/home_screen/user_home_screen.dart +++ b/lib/ui/user/home/home_screen/user_home_screen.dart @@ -4,6 +4,8 @@ import 'package:flutter_gen/gen_l10n/app_localization.dart'; import 'package:go_router/go_router.dart'; import 'package:projectunity/data/core/extensions/context_extension.dart'; import 'package:projectunity/style/app_page.dart'; +import 'package:projectunity/ui/shared/events/bloc/celebrations_bloc.dart'; +import 'package:projectunity/ui/shared/events/bloc/celebrations_event.dart'; import 'package:projectunity/ui/shared/events/celebrations_event_card.dart'; import 'package:projectunity/ui/shared/who_is_out_card/bloc/who_is_out_card_event.dart'; import 'package:projectunity/ui/user/home/home_screen/bloc/user_home_event.dart'; @@ -37,6 +39,8 @@ class UserHomeScreenPage extends StatelessWidget { BlocProvider( create: (_) => getIt()..add(FetchWhoIsOutCardLeaves())), + BlocProvider( + create: (_) => getIt()..add(FetchCelebrations())), ], child: const UserHomeScreen(), ); @@ -79,7 +83,7 @@ class _UserHomeScreenState extends State { body: ListView( children: [ const WhoIsOutCard(), - const EventCard(), + const EventCard(), BlocConsumer( buildWhen: (previous, current) => current is! UserHomeErrorState, diff --git a/lib/ui/widget/pick_profile_image/pick_user_profile_image.dart b/lib/ui/widget/pick_profile_image/pick_user_profile_image.dart index 3255b2a46..6fb528c8a 100644 --- a/lib/ui/widget/pick_profile_image/pick_user_profile_image.dart +++ b/lib/ui/widget/pick_profile_image/pick_user_profile_image.dart @@ -42,7 +42,7 @@ class ProfileImage extends StatelessWidget { children: [ CircleAvatar( radius: 70, - backgroundColor: context.colorScheme.containerNormal, + backgroundColor: context.colorScheme.containerHigh, child: BlocConsumer( listener: (context, state) { if (state.isPickImageDone && state.pickedImage != null) { @@ -79,7 +79,7 @@ class ProfileImage extends StatelessWidget { mini: true, child: Icon( Icons.edit, - color: context.colorScheme.containerHigh, + color: context.colorScheme.textDisable, )), ], ), diff --git a/test/unit_test/shared/events/celebration_event_bloc_test.dart b/test/unit_test/shared/events/celebration_event_bloc_test.dart new file mode 100644 index 000000000..7eb66766c --- /dev/null +++ b/test/unit_test/shared/events/celebration_event_bloc_test.dart @@ -0,0 +1,126 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:projectunity/data/core/extensions/date_time.dart'; +import 'package:projectunity/data/core/utils/bloc_status.dart'; +import 'package:projectunity/data/model/employee/employee.dart'; +import 'package:projectunity/data/repo/employee_repo.dart'; +import 'package:projectunity/ui/shared/events/bloc/celebrations_bloc.dart'; +import 'package:projectunity/ui/shared/events/bloc/celebrations_event.dart'; +import 'package:projectunity/ui/shared/events/bloc/celebrations_state.dart'; +import 'package:projectunity/ui/shared/events/model/event.dart'; + +import '../../admin/home/home_screen/admin_home_bloc_test.mocks.dart'; + +@GenerateMocks([EmployeeRepo]) +void main() { + late EmployeeRepo employeeRepo; + late CelebrationsBloc celebrationsBloc; + const CelebrationsState celebrationsState = CelebrationsState(); + Employee employee1 = Employee( + uid: "123", + role: Role.employee, + name: "dummy tester", + employeeId: "CA-1000", + email: "dummy.t@canopas.com", + designation: "Application Tester", + dateOfJoining: DateTime.now().dateOnly, + level: "SW-L2", + gender: Gender.male, + dateOfBirth: DateTime.now().dateOnly, + address: "california", + phone: "+1 000000-0000"); + Employee employee2 = Employee( + uid: "123", + role: Role.employee, + name: "dummy tester", + employeeId: "CA-1000", + email: "dummy.t@canopas.com", + designation: "Application Tester", + dateOfJoining: DateTime.now().add(const Duration(days: 7)).dateOnly, + level: "SW-L2", + gender: Gender.male, + dateOfBirth: DateTime.now().add(const Duration(days: 7)).dateOnly, + ); + + Event event = Event( + name: employee1.name, + dateTime: employee1.dateOfBirth!.convertToUpcomingDay(), + imageUrl: employee1.imageUrl); + Event event2 = Event( + name: employee2.name, + dateTime: employee2.dateOfBirth!.convertToUpcomingDay(), + imageUrl: employee2.imageUrl); + + setUp(() { + employeeRepo = MockEmployeeRepo(); + celebrationsBloc = CelebrationsBloc(employeeRepo); + }); + + group("All tests of events", () { + test("Initial status test", () { + expect(celebrationsBloc.state, celebrationsState); + }); + + test("Test FetchCelebrations- emit loading state and then success state", + () { + when(employeeRepo.allEmployees).thenReturn([employee1, employee2]); + celebrationsBloc.add(FetchCelebrations()); + expectLater( + celebrationsBloc.stream, + emitsInOrder([ + const CelebrationsState(status: Status.loading), + CelebrationsState( + status: Status.success, + birthdays: [event], + anniversaries: [event]), + ]), + ); + }); + + test("Test ShowBirthdaysEvent- emit success state with all the birthdays", + () { + when(employeeRepo.allEmployees).thenReturn([employee1, employee2]); + celebrationsBloc.add(FetchCelebrations()); + celebrationsBloc.add(ShowBirthdaysEvent()); + + final successState = CelebrationsState( + status: Status.success, birthdays: [event], anniversaries: [event]); + final allBdayState = successState.copyWith( + showAllBdays: !celebrationsState.showAllBdays, + birthdays: [event, event2], + anniversaries: [event]); + expectLater( + celebrationsBloc.stream, + emitsInOrder([ + const CelebrationsState(status: Status.loading), + successState, + allBdayState + ]), + ); + }); + + test( + "Test ShowAnniversariesEvent- emit success state with all the anniversary", + () { + when(employeeRepo.allEmployees).thenReturn([employee1, employee2]); + celebrationsBloc.add(FetchCelebrations()); + celebrationsBloc.add(ShowAnniversariesEvent()); + + final successState = CelebrationsState( + status: Status.success, birthdays: [event], anniversaries: [event]); + final allAnniversariesState = successState.copyWith( + showAllAnniversaries: !celebrationsState.showAllAnniversaries, + birthdays: [event], + anniversaries: [event, event2]); + expectLater( + celebrationsBloc.stream, + emitsInOrder([ + const CelebrationsState(status: Status.loading), + successState, + allAnniversariesState + ]), + ); + }); + }); +}