<!--
  Thanks for contributing!

Provide a description of your changes below and a general summary in the
title

Please look at the following checklist to ensure that your PR can be
accepted quickly:
-->


## Type of Change

<!--- Put an `x` in all the boxes that apply: -->

- [x]  New feature (non-breaking change which adds functionality)
- [x] 🛠️ Bug fix (non-breaking change which fixes an issue)
- [ ]  Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] 🧹 Code refactor
- [ ]  Build configuration change
- [ ] 📝 Documentation
- [ ] 🗑️ Chore
This commit is contained in:
Faris Armoush
2025-06-30 15:57:06 +03:00
committed by GitHub
4 changed files with 63 additions and 18 deletions

View File

@ -62,9 +62,9 @@ class CurtainModuleItems extends StatelessWidget with HelperResponsiveLayout {
BlocProvider.of<CurtainModuleBloc>(context), BlocProvider.of<CurtainModuleBloc>(context),
child: BuildScheduleView( child: BuildScheduleView(
deviceUuid: deviceId, deviceUuid: deviceId,
category: 'timer', category: 'Timer',
code: 'control', code: 'control',
countdownCode: 'timer', countdownCode: 'Timer',
deviceType: 'CUR_2', deviceType: 'CUR_2',
), ),
)); ));

View File

@ -34,7 +34,8 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
return Dialog( return Dialog(
child: Container( child: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20))),
width: 900, width: 900,
child: Column( child: Column(
children: [ children: [
@ -63,7 +64,8 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
children: [ children: [
_buildStep1Indicator(1, "Basics", _blocRole), _buildStep1Indicator(1, "Basics", _blocRole),
_buildStep2Indicator(2, "Spaces", _blocRole), _buildStep2Indicator(2, "Spaces", _blocRole),
_buildStep3Indicator(3, "Role & Permissions", _blocRole), _buildStep3Indicator(
3, "Role & Permissions", _blocRole),
], ],
), ),
), ),
@ -105,18 +107,32 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
), ),
InkWell( InkWell(
onTap: () { onTap: () {
final isBasicsStep = currentStep == 1;
if (isBasicsStep) {
// Validate the form first
final isValid = _blocRole.formKey.currentState
?.validate() ??
false;
if (!isValid)
return; // Stop if form is not valid
}
_blocRole.add(const CheckEmailEvent()); _blocRole.add(const CheckEmailEvent());
setState(() { setState(() {
if (currentStep < 3) { if (currentStep < 3) {
currentStep++; currentStep++;
if (currentStep == 2) { if (currentStep == 2) {
_blocRole.add(const CheckStepStatus(isEditUser: false)); _blocRole.add(const CheckStepStatus(
isEditUser: false));
} else if (currentStep == 3) { } else if (currentStep == 3) {
_blocRole.add(const CheckSpacesStepStatus()); _blocRole
.add(const CheckSpacesStepStatus());
} }
} else { } else {
_blocRole.add(SendInviteUsers(context: context)); _blocRole
.add(SendInviteUsers(context: context));
} }
}); });
}, },
@ -124,8 +140,11 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
currentStep < 3 ? "Next" : "Save", currentStep < 3 ? "Next" : "Save",
style: TextStyle( style: TextStyle(
color: (_blocRole.isCompleteSpaces == false || color: (_blocRole.isCompleteSpaces == false ||
_blocRole.isCompleteBasics == false || _blocRole.isCompleteBasics ==
_blocRole.isCompleteRolePermissions == false) && false ||
_blocRole
.isCompleteRolePermissions ==
false) &&
currentStep == 3 currentStep == 3
? ColorsManager.grayColor ? ColorsManager.grayColor
: ColorsManager.secondaryColor), : ColorsManager.secondaryColor),
@ -143,7 +162,7 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
Widget _getFormContent() { Widget _getFormContent() {
switch (currentStep) { switch (currentStep) {
case 1: case 1:
return const BasicsView( return BasicsView(
userId: '', userId: '',
); );
case 2: case 2:
@ -196,8 +215,12 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: currentStep == step
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight: currentStep == step
? FontWeight.bold
: FontWeight.normal,
), ),
), ),
], ],
@ -260,8 +283,12 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: currentStep == step
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight: currentStep == step
? FontWeight.bold
: FontWeight.normal,
), ),
), ),
], ],
@ -318,8 +345,12 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: currentStep == step
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight: currentStep == step
? FontWeight.bold
: FontWeight.normal,
), ),
), ),
], ],

View File

@ -1,9 +1,12 @@
import 'dart:async';
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:intl_phone_field/countries.dart'; import 'package:intl_phone_field/countries.dart';
import 'package:intl_phone_field/country_picker_dialog.dart'; import 'package:intl_phone_field/country_picker_dialog.dart';
import 'package:intl_phone_field/intl_phone_field.dart'; import 'package:intl_phone_field/intl_phone_field.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -11,7 +14,9 @@ import 'package:syncrow_web/utils/style.dart';
class BasicsView extends StatelessWidget { class BasicsView extends StatelessWidget {
final String? userId; final String? userId;
const BasicsView({super.key, this.userId = ''}); Timer? _debounce;
BasicsView({super.key, this.userId = ''});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<UsersBloc, UsersState>(builder: (context, state) { return BlocBuilder<UsersBloc, UsersState>(builder: (context, state) {
@ -21,6 +26,7 @@ class BasicsView extends StatelessWidget {
} }
return Form( return Form(
key: _blocRole.formKey, key: _blocRole.formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
@ -208,6 +214,14 @@ class BasicsView extends StatelessWidget {
fontSize: 12, fontSize: 12,
color: ColorsManager.textGray), color: ColorsManager.textGray),
), ),
onChanged: (value) {
if (_debounce?.isActive ?? false) _debounce!.cancel();
_debounce = Timer(const Duration(milliseconds: 800), () {
_blocRole.add(const CheckEmailEvent());
});
},
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Enter Email Address'; return 'Enter Email Address';