Merge branch 'dev' into Roles_&_Permissions

This commit is contained in:
mohammad
2025-01-06 15:32:38 +03:00
77 changed files with 1012 additions and 934 deletions

View File

@ -0,0 +1,60 @@
name: Azure Static Web Apps CI/CD
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- main
jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
submodules: true
lfs: false
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.2' # Specify the Flutter version you want to use
- name: Install dependencies
run: flutter pub get
- name: Build Flutter Web App
run: flutter build web --release --dart-define=FLAVOR=production
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_BUSH_01E607F10 }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: "/build/web" # App source code path
api_location: "" # Api source code path - optional
output_location: "/build/web" # Built app content directory - optional
###### End of Repository/Build Configurations ######
close_pull_request_job:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_BUSH_01E607F10 }}
action: "close"

View File

@ -11,7 +11,7 @@ import 'package:syncrow_web/pages/common/filter/filter_widget.dart';
import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart'; import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart'; import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart'; // import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/app_enum.dart'; import 'package:syncrow_web/utils/constants/app_enum.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -27,8 +27,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
final isLargeScreen = isLargeScreenSize(context); final isLargeScreen = isLargeScreenSize(context);
final isSmallScreen = isSmallScreenSize(context); final isSmallScreen = isSmallScreenSize(context);
final isHalfMediumScreen = isHafMediumScreenSize(context); final isHalfMediumScreen = isHafMediumScreenSize(context);
final padding = final padding = isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
isLargeScreen ? const EdgeInsets.all(30) : const EdgeInsets.all(15);
return WebScaffold( return WebScaffold(
enableMenuSidebar: false, enableMenuSidebar: false,
@ -40,8 +39,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
), ),
rightBody: const NavigateHomeGridView(), rightBody: const NavigateHomeGridView(),
scaffoldBody: BlocProvider( scaffoldBody: BlocProvider(
create: (BuildContext context) => create: (BuildContext context) => AccessBloc()..add(FetchTableData()),
AccessBloc()..add(FetchTableData()),
child: BlocConsumer<AccessBloc, AccessState>( child: BlocConsumer<AccessBloc, AccessState>(
listener: (context, state) {}, listener: (context, state) {},
builder: (context, state) { builder: (context, state) {
@ -95,14 +93,11 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
return [ return [
item.passwordName, item.passwordName,
item.passwordType.value, item.passwordType.value,
accessBloc accessBloc.timestampToDate(item.effectiveTime),
.timestampToDate(item.effectiveTime), accessBloc.timestampToDate(item.invalidTime),
accessBloc
.timestampToDate(item.invalidTime),
item.deviceName.toString(), item.deviceName.toString(),
item.authorizerEmail.toString(), item.authorizerEmail.toString(),
accessBloc accessBloc.timestampToDate(item.invalidTime),
.timestampToDate(item.invalidTime),
item.passwordStatus.value, item.passwordStatus.value,
]; ];
}).toList(), }).toList(),
@ -113,8 +108,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
}))); })));
} }
Wrap _buildVisitorAdminPasswords( Wrap _buildVisitorAdminPasswords(BuildContext context, AccessBloc accessBloc) {
BuildContext context, AccessBloc accessBloc) {
return Wrap( return Wrap(
spacing: 10, spacing: 10,
runSpacing: 10, runSpacing: 10,
@ -140,23 +134,22 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
borderRadius: 8, borderRadius: 8,
child: Text( child: Text(
'Create Visitor Password ', 'Create Visitor Password ',
style: context.textTheme.titleSmall! style: context.textTheme.titleSmall!.copyWith(color: Colors.white, fontSize: 12),
.copyWith(color: Colors.white, fontSize: 12),
)),
),
Container(
width: 133,
height: 42,
decoration: containerDecoration,
child: DefaultButton(
borderRadius: 8,
backgroundColor: ColorsManager.whiteColors,
child: Text(
'Admin Password',
style: context.textTheme.titleSmall!
.copyWith(color: Colors.black, fontSize: 12),
)), )),
), ),
// Container(
// width: 133,
// height: 42,
// decoration: containerDecoration,
// child: DefaultButton(
// borderRadius: 8,
// backgroundColor: ColorsManager.whiteColors,
// child: Text(
// 'Admin Password',
// style: context.textTheme.titleSmall!
// .copyWith(color: Colors.black, fontSize: 12),
// )),
// ),
], ],
); );
} }
@ -179,10 +172,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -200,10 +191,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -232,8 +221,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
onSearch: () { onSearch: () {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex: selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -261,10 +249,8 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
description: '', description: '',
onSubmitted: (value) { onSubmitted: (value) {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
accessBloc.emailAuthorizer.text.toLowerCase(), selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
selectedTabIndex:
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));
@ -288,8 +274,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout {
onSearch: () { onSearch: () {
accessBloc.add(FilterDataEvent( accessBloc.add(FilterDataEvent(
emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(), emailAuthorizer: accessBloc.emailAuthorizer.text.toLowerCase(),
selectedTabIndex: selectedTabIndex: BlocProvider.of<AccessBloc>(context).selectedIndex,
BlocProvider.of<AccessBloc>(context).selectedIndex,
passwordName: accessBloc.passwordName.text.toLowerCase(), passwordName: accessBloc.passwordName.text.toLowerCase(),
startTime: accessBloc.effectiveTimeTimeStamp, startTime: accessBloc.effectiveTimeTimeStamp,
endTime: accessBloc.expirationTimeTimeStamp)); endTime: accessBloc.expirationTimeTimeStamp));

View File

@ -31,8 +31,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
////////////////////////////// forget password ////////////////////////////////// ////////////////////////////// forget password //////////////////////////////////
final TextEditingController forgetEmailController = TextEditingController(); final TextEditingController forgetEmailController = TextEditingController();
final TextEditingController forgetPasswordController = final TextEditingController forgetPasswordController = TextEditingController();
TextEditingController();
final TextEditingController forgetOtp = TextEditingController(); final TextEditingController forgetOtp = TextEditingController();
final forgetFormKey = GlobalKey<FormState>(); final forgetFormKey = GlobalKey<FormState>();
final forgetEmailKey = GlobalKey<FormState>(); final forgetEmailKey = GlobalKey<FormState>();
@ -49,12 +48,12 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
return; return;
} }
_remainingTime = 1; _remainingTime = 1;
add(UpdateTimerEvent( add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
remainingTime: _remainingTime, isButtonEnabled: false));
try { try {
forgetEmailValidate = ''; forgetEmailValidate = '';
_remainingTime = (await AuthenticationAPI.sendOtp( _remainingTime = (await AuthenticationAPI.sendOtp(
email: forgetEmailController.text, regionUuid: regionUuid))!; email: forgetEmailController.text,
))!;
} on DioException catch (e) { } on DioException catch (e) {
if (e.response!.statusCode == 400) { if (e.response!.statusCode == 400) {
final errorData = e.response!.data; final errorData = e.response!.data;
@ -86,8 +85,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
_timer?.cancel(); _timer?.cancel();
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true)); add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
} else { } else {
add(UpdateTimerEvent( add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
remainingTime: _remainingTime, isButtonEnabled: false));
} }
}); });
} }
@ -97,8 +95,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(const TimerState(isButtonEnabled: true, remainingTime: 0)); emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
} }
Future<void> changePassword( Future<void> changePassword(ChangePasswordEvent event, Emitter<AuthState> emit) async {
ChangePasswordEvent event, Emitter<AuthState> emit) async {
emit(LoadingForgetState()); emit(LoadingForgetState());
try { try {
var response = await AuthenticationAPI.verifyOtp( var response = await AuthenticationAPI.verifyOtp(
@ -114,8 +111,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
} }
} on DioException catch (e) { } on DioException catch (e) {
final errorData = e.response!.data; final errorData = e.response!.data;
String errorMessage = String errorMessage = errorData['error']['message'] ?? 'something went wrong';
errorData['error']['message'] ?? 'something went wrong';
validate = errorMessage; validate = errorMessage;
emit(AuthInitialState()); emit(AuthInitialState());
} }
@ -129,16 +125,14 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
} }
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) { void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
emit(TimerState( emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime));
isButtonEnabled: event.isButtonEnabled,
remainingTime: event.remainingTime));
} }
///////////////////////////////////// login ///////////////////////////////////// ///////////////////////////////////// login /////////////////////////////////////
final TextEditingController loginEmailController = TextEditingController(); final TextEditingController loginEmailController = TextEditingController();
final TextEditingController loginPasswordController = TextEditingController(); final TextEditingController loginPasswordController = TextEditingController();
final loginFormKey = GlobalKey<FormState>(); final loginFormKey = GlobalKey<FormState>();
bool isChecked = false; bool isChecked = true;
bool obscureText = true; bool obscureText = true;
String newPassword = ''; String newPassword = '';
String maskedEmail = ''; String maskedEmail = '';
@ -146,7 +140,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
String validate = ''; String validate = '';
String forgetValidate = ''; String forgetValidate = '';
String forgetEmailValidate = ''; String forgetEmailValidate = '';
String regionUuid = ''; // String regionUuid = '';
static Token token = Token.emptyConstructor(); static Token token = Token.emptyConstructor();
static UserModel? user; static UserModel? user;
bool showValidationMessage = false; bool showValidationMessage = false;
@ -163,9 +157,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
token = await AuthenticationAPI.loginWithEmail( token = await AuthenticationAPI.loginWithEmail(
model: LoginWithEmailModel( model: LoginWithEmailModel(
email: event.username, email: event.username,
password: event.password, password: event.password,
regionUuid: event.regionUuid), ),
); );
} catch (failure) { } catch (failure) {
validate = 'Invalid Credentials!'; validate = 'Invalid Credentials!';
@ -175,8 +169,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
if (token.accessTokenIsNotEmpty) { if (token.accessTokenIsNotEmpty) {
FlutterSecureStorage storage = const FlutterSecureStorage(); FlutterSecureStorage storage = const FlutterSecureStorage();
await storage.write( await storage.write(key: Token.loginAccessTokenKey, value: token.accessToken);
key: Token.loginAccessTokenKey, value: token.accessToken);
const FlutterSecureStorage().write( const FlutterSecureStorage().write(
key: UserModel.userUuidKey, key: UserModel.userUuidKey,
value: Token.decodeToken(token.accessToken)['uuid'].toString()); value: Token.decodeToken(token.accessToken)['uuid'].toString());
@ -334,14 +327,12 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
static Future<String> getTokenAndValidate() async { static Future<String> getTokenAndValidate() async {
try { try {
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
final firstLaunch = await SharedPreferencesHelper.readBoolFromSP( final firstLaunch =
StringsManager.firstLaunch) ?? await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true;
true;
if (firstLaunch) { if (firstLaunch) {
storage.deleteAll(); storage.deleteAll();
} }
await SharedPreferencesHelper.saveBoolToSP( await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false);
StringsManager.firstLaunch, false);
final value = await storage.read(key: Token.loginAccessTokenKey) ?? ''; final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
if (value.isEmpty) { if (value.isEmpty) {
return 'Token not found'; return 'Token not found';
@ -376,7 +367,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
Future selectRegion(SelectRegionEvent event, Emitter<AuthState> emit) async { Future selectRegion(SelectRegionEvent event, Emitter<AuthState> emit) async {
try { try {
emit(AuthLoading()); emit(AuthLoading());
regionUuid = event.val; // regionUuid = event.val;
add(CheckEnableEvent()); add(CheckEnableEvent());
emit(AuthInitialState()); emit(AuthInitialState());
} catch (e) { } catch (e) {
@ -394,9 +385,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
final String formattedTime = [ final String formattedTime = [
if (days > 0) '${days}d', // Append 'd' for days if (days > 0) '${days}d', // Append 'd' for days
if (days > 0 || hours > 0) if (days > 0 || hours > 0)
hours hours.toString().padLeft(2, '0'), // Show hours if there are days or hours
.toString()
.padLeft(2, '0'), // Show hours if there are days or hours
minutes.toString().padLeft(2, '0'), minutes.toString().padLeft(2, '0'),
seconds.toString().padLeft(2, '0'), seconds.toString().padLeft(2, '0'),
].join(':'); ].join(':');
@ -411,8 +400,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(AuthLoading()); emit(AuthLoading());
checkValidate = isChecked == true && checkValidate = isChecked == true &&
loginPasswordController.text.isNotEmpty && loginPasswordController.text.isNotEmpty &&
loginEmailController.text.isNotEmpty && loginEmailController.text.isNotEmpty;
regionUuid != '';
emit(LoginInitial()); emit(LoginInitial());
return checkValidate; return checkValidate;
} }

View File

@ -10,16 +10,16 @@ abstract class AuthEvent extends Equatable {
class LoginButtonPressed extends AuthEvent { class LoginButtonPressed extends AuthEvent {
final String username; final String username;
final String password; final String password;
final String regionUuid; // final String regionUuid;
const LoginButtonPressed({ const LoginButtonPressed({
required this.username, required this.username,
required this.password, required this.password,
required this.regionUuid, // required this.regionUuid,
}); });
@override @override
List<Object> get props => [username, password, regionUuid]; List<Object> get props => [username, password];
} }
class CheckBoxEvent extends AuthEvent { class CheckBoxEvent extends AuthEvent {
@ -49,13 +49,9 @@ class UpdateTimerEvent extends AuthEvent {
const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled}); const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled});
} }
class ChangePasswordEvent extends AuthEvent { class ChangePasswordEvent extends AuthEvent {}
} class SendOtpEvent extends AuthEvent {}
class SendOtpEvent extends AuthEvent {
}
class PasswordVisibleEvent extends AuthEvent { class PasswordVisibleEvent extends AuthEvent {
final bool? newValue; final bool? newValue;

View File

@ -1,19 +1,19 @@
class LoginWithEmailModel { class LoginWithEmailModel {
final String email; final String email;
final String password; final String password;
final String regionUuid; // final String regionUuid;
LoginWithEmailModel({ LoginWithEmailModel({
required this.email, required this.email,
required this.password, required this.password,
required this.regionUuid, // required this.regionUuid,
}); });
factory LoginWithEmailModel.fromJson(Map<String, dynamic> json) { factory LoginWithEmailModel.fromJson(Map<String, dynamic> json) {
return LoginWithEmailModel( return LoginWithEmailModel(
email: json['email'], email: json['email'],
password: json['password'], password: json['password'],
regionUuid: json['regionUuid'], // regionUuid: json['regionUuid'],
); );
} }
@ -21,7 +21,7 @@ class LoginWithEmailModel {
return { return {
'email': email, 'email': email,
'password': password, 'password': password,
'regionUuid': regionUuid, // 'regionUuid': regionUuid,
}; };
} }
} }

View File

@ -124,18 +124,18 @@ class ForgetPasswordWebPage extends StatelessWidget {
.copyWith(fontSize: 14, fontWeight: FontWeight.w400), .copyWith(fontSize: 14, fontWeight: FontWeight.w400),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Column( // Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.start,
children: [ // children: [
const SizedBox(height: 10), // const SizedBox(height: 10),
Form( // Form(
key: forgetBloc.forgetRegionKey, // key: forgetBloc.forgetRegionKey,
child: SizedBox( // child: SizedBox(
child: // child:
_buildDropdownField(context, forgetBloc, size))) // _buildDropdownField(context, forgetBloc, size)))
], // ],
), // ),
const SizedBox(height: 20), const SizedBox(height: 20),
Form( Form(
key: forgetBloc.forgetEmailKey, key: forgetBloc.forgetEmailKey,
@ -459,9 +459,9 @@ class ForgetPasswordWebPage extends StatelessWidget {
), ),
); );
}).toList(), }).toList(),
value: loginBloc.regionList!.any((region) => region.id == loginBloc.regionUuid) // value: loginBloc.regionList!.any((region) => region.id == loginBloc.regionUuid)
? loginBloc.regionUuid // ? loginBloc.regionUuid
: null, // : null,
onChanged: (String? value) { onChanged: (String? value) {
if (value != null) { if (value != null) {
loginBloc.add(SelectRegionEvent(val: value)); loginBloc.add(SelectRegionEvent(val: value));

View File

@ -6,7 +6,7 @@ import 'package:go_router/go_router.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_event.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_event.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_state.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_state.dart';
import 'package:syncrow_web/pages/auth/model/region_model.dart'; // import 'package:syncrow_web/pages/auth/model/region_model.dart';
import 'package:syncrow_web/pages/auth/view/forget_password_page.dart'; import 'package:syncrow_web/pages/auth/view/forget_password_page.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
@ -112,44 +112,44 @@ class LoginMobilePage extends StatelessWidget {
color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold), color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
Column( // Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.start,
children: [ // children: [
Text( // Text(
"Country/Region", // "Country/Region",
style: Theme.of(context).textTheme.bodySmall, // style: Theme.of(context).textTheme.bodySmall,
), // ),
SizedBox( // SizedBox(
child: DropdownButtonFormField<String>( // child: DropdownButtonFormField<String>(
validator: loginBloc.validateRegion, // validator: loginBloc.validateRegion,
icon: const Icon( // icon: const Icon(
Icons.keyboard_arrow_down_outlined, // Icons.keyboard_arrow_down_outlined,
), // ),
decoration: textBoxDecoration()!.copyWith( // decoration: textBoxDecoration()!.copyWith(
hintText: null, // hintText: null,
), // ),
hint: const Align( // hint: const Align(
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Text( // child: Text(
'Select your region/country', // 'Select your region/country',
textAlign: TextAlign.center, // textAlign: TextAlign.center,
), // ),
), // ),
isDense: true, // isDense: true,
style: const TextStyle(color: Colors.black), // style: const TextStyle(color: Colors.black),
items: loginBloc.regionList!.map((RegionModel region) { // items: loginBloc.regionList!.map((RegionModel region) {
return DropdownMenuItem<String>( // return DropdownMenuItem<String>(
value: region.name, // value: region.name,
child: Text(region.name), // child: Text(region.name),
); // );
}).toList(), // }).toList(),
onChanged: (String? value) {}, // onChanged: (String? value) {},
), // ),
) // )
], // ],
), // ),
const SizedBox(height: 20.0), // const SizedBox(height: 20.0),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -207,7 +207,10 @@ class LoginMobilePage extends StatelessWidget {
}, },
child: Text( child: Text(
"Forgot Password?", "Forgot Password?",
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.blackColor),
), ),
), ),
], ],
@ -276,7 +279,6 @@ class LoginMobilePage extends StatelessWidget {
if (loginBloc.loginFormKey.currentState!.validate()) { if (loginBloc.loginFormKey.currentState!.validate()) {
loginBloc.add( loginBloc.add(
LoginButtonPressed( LoginButtonPressed(
regionUuid: '',
username: loginBloc.loginEmailController.text, username: loginBloc.loginEmailController.text,
password: loginBloc.loginPasswordController.text, password: loginBloc.loginPasswordController.text,
), ),

View File

@ -155,16 +155,16 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
children: <Widget>[ children: <Widget>[
const SizedBox(height: 40), const SizedBox(height: 40),
Text('Login', style: Theme.of(context).textTheme.headlineLarge), Text('Login', style: Theme.of(context).textTheme.headlineLarge),
SizedBox(height: size.height * 0.03), // SizedBox(height: size.height * 0.03),
_buildDropdownField(context, loginBloc, size), // _buildDropdownField(context, loginBloc, size),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
_buildEmailField(context, loginBloc), _buildEmailField(context, loginBloc),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
_buildPasswordField(context, loginBloc), _buildPasswordField(context, loginBloc),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildForgotPassword(context), _buildForgotPassword(context),
const SizedBox(height: 20), // const SizedBox(height: 20),
_buildCheckbox(context, loginBloc, size), // _buildCheckbox(context, loginBloc, size),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
_buildSignInButton(context, loginBloc, size), _buildSignInButton(context, loginBloc, size),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
@ -219,11 +219,11 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
), ),
); );
}).toList(), }).toList(),
value: loginBloc.regionList!.any( // value: loginBloc.regionList!.any(
(region) => region.id == loginBloc.regionUuid, // (region) => region.id == loginBloc.regionUuid,
) // )
? loginBloc.regionUuid // ? loginBloc.regionUuid
: null, // : null,
onChanged: (String? value) { onChanged: (String? value) {
if (value != null) { if (value != null) {
loginBloc.add(CheckEnableEvent()); loginBloc.add(CheckEnableEvent());
@ -462,7 +462,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
onPressed: () { onPressed: () {
if (loginBloc.loginFormKey.currentState!.validate()) { if (loginBloc.loginFormKey.currentState!.validate()) {
loginBloc.add(LoginButtonPressed( loginBloc.add(LoginButtonPressed(
regionUuid: loginBloc.regionUuid, // regionUuid: loginBloc.regionUuid,
username: loginBloc.loginEmailController.text, username: loginBloc.loginEmailController.text,
password: loginBloc.loginPasswordController.text, password: loginBloc.loginPasswordController.text,
)); ));

View File

@ -8,7 +8,7 @@ import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/ba
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_fan_speed.dart'; import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_fan_speed.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
@ -26,7 +26,8 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
return BlocProvider( return BlocProvider(
create: (context) => AcBloc(deviceId: devicesIds.first)..add(AcFetchBatchStatusEvent(devicesIds)), create: (context) =>
AcBloc(deviceId: devicesIds.first)..add(AcFetchBatchStatusEvent(devicesIds)),
child: BlocBuilder<AcBloc, AcsState>( child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) { builder: (context, state) {
if (state is ACStatusLoaded) { if (state is ACStatusLoaded) {
@ -98,7 +99,8 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo
), ),
Text( Text(
'h', 'h',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor), style:
context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
), ),
Text( Text(
'30', '30',
@ -107,7 +109,9 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)), Text('m',
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.blackColor)),
IconButton( IconButton(
onPressed: () {}, onPressed: () {},
icon: const Icon( icon: const Icon(
@ -138,7 +142,7 @@ class AcDeviceBatchControlView extends StatelessWidget with HelperResponsiveLayo
)); ));
}, },
), ),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5), // FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<AcBloc>().add(AcFactoryResetEvent( context.read<AcBloc>().add(AcFactoryResetEvent(

View File

@ -6,7 +6,7 @@ import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_e
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_state.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/ceiling_state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_space_type.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_space_type.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presense_nobody_time.dart';
@ -110,7 +110,7 @@ class CeilingSensorBatchControlView extends StatelessWidget with HelperResponsiv
), ),
), ),
), ),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 4), // FirmwareUpdateWidget(deviceId: devicesIds.first, version: 4),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<CeilingSensorBloc>().add( context.read<CeilingSensorBloc>().add(

View File

@ -6,11 +6,10 @@ import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_bloc.dar
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.dart';
import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart'; import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class CurtainBatchStatusView extends StatelessWidget class CurtainBatchStatusView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const CurtainBatchStatusView({super.key, required this.devicesIds}); const CurtainBatchStatusView({super.key, required this.devicesIds});
final List<String> devicesIds; final List<String> devicesIds;
@ -18,8 +17,8 @@ class CurtainBatchStatusView extends StatelessWidget
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => CurtainBloc(deviceId: devicesIds.first) create: (context) =>
..add(CurtainFetchBatchStatus(devicesIds)), CurtainBloc(deviceId: devicesIds.first)..add(CurtainFetchBatchStatus(devicesIds)),
child: BlocBuilder<CurtainBloc, CurtainState>( child: BlocBuilder<CurtainBloc, CurtainState>(
builder: (context, state) { builder: (context, state) {
if (state is CurtainStatusLoading) { if (state is CurtainStatusLoading) {
@ -68,7 +67,7 @@ class CurtainBatchStatusView extends StatelessWidget
)); ));
}, },
), ),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5), // FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<CurtainBloc>().add( context.read<CurtainBloc>().add(

View File

@ -4,11 +4,10 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_re
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_bloc.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_bloc.dart';
import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class DoorLockBatchControlView extends StatelessWidget class DoorLockBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const DoorLockBatchControlView({super.key, required this.devicesIds}); const DoorLockBatchControlView({super.key, required this.devicesIds});
final List<String> devicesIds; final List<String> devicesIds;
@ -18,17 +17,17 @@ class DoorLockBatchControlView extends StatelessWidget
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
height: 140, // height: 140,
child: FirmwareUpdateWidget( // child: FirmwareUpdateWidget(
deviceId: devicesIds.first, // deviceId: devicesIds.first,
version: 12, // version: 12,
), // ),
), // ),
const SizedBox( // const SizedBox(
width: 12, // width: 12,
), // ),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,

View File

@ -6,17 +6,15 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_
import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_state.dart';
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart'; import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class GarageDoorBatchControlView extends StatelessWidget class GarageDoorBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final List<String> deviceIds; final List<String> deviceIds;
const GarageDoorBatchControlView({Key? key, required this.deviceIds}) const GarageDoorBatchControlView({Key? key, required this.deviceIds}) : super(key: key);
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -39,8 +37,7 @@ class GarageDoorBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, GarageDoorStatusModel status) {
BuildContext context, GarageDoorStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context); final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
@ -75,10 +72,10 @@ class GarageDoorBatchControlView extends StatelessWidget
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<GarageDoorBloc>().add( context.read<GarageDoorBloc>().add(

View File

@ -3,11 +3,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/gateway/bloc/gate_way_bloc.dart'; import 'package:syncrow_web/pages/device_managment/gateway/bloc/gate_way_bloc.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class GatewayBatchControlView extends StatelessWidget class GatewayBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const GatewayBatchControlView({super.key, required this.gatewayIds}); const GatewayBatchControlView({super.key, required this.gatewayIds});
final List<String> gatewayIds; final List<String> gatewayIds;
@ -24,14 +23,13 @@ class GatewayBatchControlView extends StatelessWidget
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
height: 140, // height: 140,
child: FirmwareUpdateWidget( // child: FirmwareUpdateWidget(deviceId: gatewayIds.first, version: 2)),
deviceId: gatewayIds.first, version: 2)), // const SizedBox(
const SizedBox( // width: 12,
width: 12, // ),
),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,
@ -40,8 +38,7 @@ class GatewayBatchControlView extends StatelessWidget
context.read<GateWayBloc>().add( context.read<GateWayBloc>().add(
GateWayFactoryReset( GateWayFactoryReset(
deviceId: gatewayIds.first, deviceId: gatewayIds.first,
factoryReset: factoryReset: FactoryResetModel(devicesUuid: gatewayIds),
FactoryResetModel(devicesUuid: gatewayIds),
), ),
); );
}, },

View File

@ -4,7 +4,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_re
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_bloc.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
class MainDoorSensorBatchView extends StatelessWidget { class MainDoorSensorBatchView extends StatelessWidget {
const MainDoorSensorBatchView({super.key, required this.devicesIds}); const MainDoorSensorBatchView({super.key, required this.devicesIds});
@ -16,17 +16,17 @@ class MainDoorSensorBatchView extends StatelessWidget {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
height: 140, // height: 140,
child: FirmwareUpdateWidget( // child: FirmwareUpdateWidget(
deviceId: devicesIds.first, // deviceId: devicesIds.first,
version: 12, // version: 12,
), // ),
), // ),
const SizedBox( // const SizedBox(
width: 12, // width: 12,
), // ),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,

View File

@ -4,16 +4,14 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_re
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart';
import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class OneGangGlassSwitchBatchControlView extends StatelessWidget class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final List<String> deviceIds; final List<String> deviceIds;
const OneGangGlassSwitchBatchControlView( const OneGangGlassSwitchBatchControlView({required this.deviceIds, super.key});
{required this.deviceIds, super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -36,8 +34,7 @@ class OneGangGlassSwitchBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, OneGangGlassStatusModel status) {
BuildContext context, OneGangGlassStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context); final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
@ -71,10 +68,10 @@ class OneGangGlassSwitchBatchControlView extends StatelessWidget
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<OneGangGlassSwitchBloc>().add( context.read<OneGangGlassSwitchBloc>().add(

View File

@ -6,12 +6,11 @@ import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_lig
import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_light_switch_state.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/bloc/wall_light_switch_state.dart';
import 'package:syncrow_web/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart'; import 'package:syncrow_web/pages/device_managment/one_gang_switch/models/wall_light_status_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class WallLightBatchControlView extends StatelessWidget class WallLightBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const WallLightBatchControlView({super.key, required this.deviceIds}); const WallLightBatchControlView({super.key, required this.deviceIds});
final List<String> deviceIds; final List<String> deviceIds;
@ -27,8 +26,7 @@ class WallLightBatchControlView extends StatelessWidget
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is WallLightSwitchStatusLoaded) { } else if (state is WallLightSwitchStatusLoaded) {
return _buildStatusControls(context, state.status); return _buildStatusControls(context, state.status);
} else if (state is WallLightSwitchError || } else if (state is WallLightSwitchError || state is WallLightSwitchControlError) {
state is WallLightSwitchControlError) {
return const Center(child: Text('Error fetching status')); return const Center(child: Text('Error fetching status'));
} else { } else {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@ -38,8 +36,7 @@ class WallLightBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, WallLightStatusModel status) {
BuildContext context, WallLightStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context); final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
@ -74,15 +71,14 @@ class WallLightBatchControlView extends StatelessWidget
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<WallLightSwitchBloc>().add(WallLightFactoryReset( context.read<WallLightSwitchBloc>().add(WallLightFactoryReset(
deviceId: status.uuid, deviceId: status.uuid, factoryReset: FactoryResetModel(devicesUuid: deviceIds)));
factoryReset: FactoryResetModel(devicesUuid: deviceIds)));
}, },
), ),
], ],

View File

@ -6,21 +6,19 @@ import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_
import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_state.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_state.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_batch_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class PowerClampBatchControlView extends StatelessWidget class PowerClampBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final List<String> deviceIds; final List<String> deviceIds;
const PowerClampBatchControlView({Key? key, required this.deviceIds}) const PowerClampBatchControlView({Key? key, required this.deviceIds}) : super(key: key);
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SmartPowerBloc(deviceId: deviceIds.first) create: (context) =>
..add(SmartPowerFetchBatchEvent(deviceIds)), SmartPowerBloc(deviceId: deviceIds.first)..add(SmartPowerFetchBatchEvent(deviceIds)),
child: BlocBuilder<SmartPowerBloc, SmartPowerState>( child: BlocBuilder<SmartPowerBloc, SmartPowerState>(
builder: (context, state) { builder: (context, state) {
if (state is SmartPowerLoading) { if (state is SmartPowerLoading) {
@ -37,18 +35,17 @@ class PowerClampBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, PowerClampBatchModel status) {
BuildContext context, PowerClampBatchModel status) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
// height: 140, // // height: 140,
child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)), // child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)),
const SizedBox( // const SizedBox(
width: 12, // width: 12,
), // ),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,

View File

@ -1,128 +1,128 @@
import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; // import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; // import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; // import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/utils/color_manager.dart'; // import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; // import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; // import 'package:syncrow_web/utils/extension/build_context_x.dart';
class FirmwareUpdateWidget extends StatefulWidget { // class FirmwareUpdateWidget extends StatefulWidget {
const FirmwareUpdateWidget({super.key, required this.deviceId, required this.version}); // const FirmwareUpdateWidget({super.key, required this.deviceId, required this.version});
final String deviceId; // final String deviceId;
final int version; // final int version;
@override // @override
State<FirmwareUpdateWidget> createState() => _FirmwareUpdateWidgetState(); // State<FirmwareUpdateWidget> createState() => _FirmwareUpdateWidgetState();
} // }
class _FirmwareUpdateWidgetState extends State<FirmwareUpdateWidget> { // class _FirmwareUpdateWidgetState extends State<FirmwareUpdateWidget> {
bool _showConfirmation = false; // bool _showConfirmation = false;
void _toggleConfirmation() { // void _toggleConfirmation() {
setState(() { // setState(() {
_showConfirmation = !_showConfirmation; // _showConfirmation = !_showConfirmation;
}); // });
} // }
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return DeviceControlsContainer( // return DeviceControlsContainer(
child: _showConfirmation // child: _showConfirmation
? Column( // ? Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ // children: [
Column( // Column(
children: [ // children: [
Text( // Text(
'Firmware Update', // 'Firmware Update',
style: context.textTheme.titleMedium!.copyWith( // style: context.textTheme.titleMedium!.copyWith(
fontWeight: FontWeight.bold, // fontWeight: FontWeight.bold,
color: ColorsManager.blackColor, // color: ColorsManager.blackColor,
), // ),
), // ),
Text( // Text(
'Are you sure?', // 'Are you sure?',
style: context.textTheme.bodySmall!.copyWith( // style: context.textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, // color: ColorsManager.grayColor,
), // ),
), // ),
], // ],
), // ),
Row( // Row(
children: [ // children: [
Flexible( // Flexible(
child: DefaultButton( // child: DefaultButton(
height: 20, // height: 20,
elevation: 0, // elevation: 0,
padding: 0, // padding: 0,
onPressed: _toggleConfirmation, // onPressed: _toggleConfirmation,
backgroundColor: ColorsManager.greyColor, // backgroundColor: ColorsManager.greyColor,
child: Text( // child: Text(
'Cancel', // 'Cancel',
style: context.textTheme.bodyMedium!.copyWith( // style: context.textTheme.bodyMedium!.copyWith(
color: ColorsManager.blackColor, // color: ColorsManager.blackColor,
fontWeight: FontWeight.w400, // fontWeight: FontWeight.w400,
fontSize: 12, // fontSize: 12,
), // ),
), // ),
), // ),
), // ),
const SizedBox(width: 8), // const SizedBox(width: 8),
Flexible( // Flexible(
child: DefaultButton( // child: DefaultButton(
height: 20, // height: 20,
elevation: 0, // elevation: 0,
padding: 0, // padding: 0,
onPressed: () { // onPressed: () {
_toggleConfirmation(); // _toggleConfirmation();
}, // },
backgroundColor: ColorsManager.primaryColor, // backgroundColor: ColorsManager.primaryColor,
child: Text( // child: Text(
'Update', // 'Update',
style: context.textTheme.bodyMedium!.copyWith( // style: context.textTheme.bodyMedium!.copyWith(
color: ColorsManager.whiteColors, // color: ColorsManager.whiteColors,
fontWeight: FontWeight.w400, // fontWeight: FontWeight.w400,
fontSize: 12, // fontSize: 12,
), // ),
), // ),
), // ),
), // ),
], // ],
), // ),
], // ],
) // )
: GestureDetector( // : GestureDetector(
onTap: _toggleConfirmation, // onTap: _toggleConfirmation,
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ // children: [
ClipOval( // ClipOval(
child: Container( // child: Container(
color: ColorsManager.whiteColors, // color: ColorsManager.whiteColors,
height: 60, // height: 60,
width: 60, // width: 60,
child: Padding( // child: Padding(
padding: const EdgeInsets.all(12.0), // padding: const EdgeInsets.all(12.0),
child: SvgPicture.asset( // child: SvgPicture.asset(
Assets.firmware, // Assets.firmware,
fit: BoxFit.cover, // fit: BoxFit.cover,
), // ),
), // ),
), // ),
), // ),
Text( // Text(
'Firmware Update', // 'Firmware Update',
style: context.textTheme.titleMedium!.copyWith( // style: context.textTheme.titleMedium!.copyWith(
fontWeight: FontWeight.w400, // fontWeight: FontWeight.w400,
color: ColorsManager.blackColor, // color: ColorsManager.blackColor,
), // ),
), // ),
], // ],
), // ),
), // ),
); // );
} // }
} // }

View File

@ -18,20 +18,21 @@ class SOSBatchControlView extends StatelessWidget {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
// height: 140, // // height: 140,
child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)), // child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)),
const SizedBox( // const SizedBox(
width: 12, // width: 12,
), // ),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,
child: FactoryResetWidget( child: FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<SosDeviceBloc>().add( context.read<SosDeviceBloc>().add(SosFactoryReset(
SosFactoryReset(deviceId: deviceIds.first, factoryReset: FactoryResetModel(devicesUuid: deviceIds))); deviceId: deviceIds.first,
factoryReset: FactoryResetModel(devicesUuid: deviceIds)));
}, },
), ),
), ),

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart';
import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart'; import 'package:syncrow_web/pages/device_managment/three_g_glass_switch/models/three_gang_glass_switch.dart';
@ -98,10 +98,10 @@ class ThreeGangGlassSwitchBatchControlView extends StatelessWidget with HelperRe
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // adjust the version according to your requirement // version: 12, // adjust the version according to your requirement
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<ThreeGangGlassSwitchBloc>().add( context.read<ThreeGangGlassSwitchBloc>().add(

View File

@ -2,14 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart';
import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class LivingRoomBatchControlsView extends StatelessWidget class LivingRoomBatchControlsView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const LivingRoomBatchControlsView({super.key, required this.deviceIds}); const LivingRoomBatchControlsView({super.key, required this.deviceIds});
final List<String> deviceIds; final List<String> deviceIds;
@ -17,16 +16,15 @@ class LivingRoomBatchControlsView extends StatelessWidget
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => LivingRoomBloc(deviceId: deviceIds.first) create: (context) =>
..add(LivingRoomFetchBatchEvent(deviceIds)), LivingRoomBloc(deviceId: deviceIds.first)..add(LivingRoomFetchBatchEvent(deviceIds)),
child: BlocBuilder<LivingRoomBloc, LivingRoomState>( child: BlocBuilder<LivingRoomBloc, LivingRoomState>(
builder: (context, state) { builder: (context, state) {
if (state is LivingRoomDeviceStatusLoading) { if (state is LivingRoomDeviceStatusLoading) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is LivingRoomDeviceStatusLoaded) { } else if (state is LivingRoomDeviceStatusLoaded) {
return _buildStatusControls(context, state.status); return _buildStatusControls(context, state.status);
} else if (state is LivingRoomDeviceManagementError || } else if (state is LivingRoomDeviceManagementError || state is LivingRoomControlError) {
state is LivingRoomControlError) {
return const Center(child: Text('Error fetching status')); return const Center(child: Text('Error fetching status'));
} else { } else {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@ -36,8 +34,7 @@ class LivingRoomBatchControlsView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, LivingRoomStatusModel status) {
BuildContext context, LivingRoomStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context); final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
@ -102,10 +99,10 @@ class LivingRoomBatchControlsView extends StatelessWidget
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget(callFactoryReset: () { FactoryResetWidget(callFactoryReset: () {
context.read<LivingRoomBloc>().add( context.read<LivingRoomBloc>().add(
LivingRoomFactoryResetEvent( LivingRoomFactoryResetEvent(

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart';
import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart';
@ -16,8 +16,8 @@ class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResp
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => create: (context) => TwoGangGlassSwitchBloc(deviceId: deviceIds.first)
TwoGangGlassSwitchBloc(deviceId: deviceIds.first)..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)), ..add(TwoGangGlassSwitchFetchBatchStatusEvent(deviceIds)),
child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>( child: BlocBuilder<TwoGangGlassSwitchBloc, TwoGangGlassSwitchState>(
builder: (context, state) { builder: (context, state) {
if (state is TwoGangGlassSwitchLoading) { if (state is TwoGangGlassSwitchLoading) {
@ -83,10 +83,10 @@ class TwoGangGlassSwitchBatchControlView extends StatelessWidget with HelperResp
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // adjust the version according to your requirement // version: 12, // adjust the version according to your requirement
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<TwoGangGlassSwitchBloc>().add( context.read<TwoGangGlassSwitchBloc>().add(

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart'; import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart';
import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart'; import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang_switch_event.dart';
@ -10,8 +10,7 @@ import 'package:syncrow_web/pages/device_managment/two_gang_switch/bloc/two_gang
import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart'; import 'package:syncrow_web/pages/device_managment/two_gang_switch/models/two_gang_status_model.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class TwoGangBatchControlView extends StatelessWidget class TwoGangBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const TwoGangBatchControlView({super.key, required this.deviceIds}); const TwoGangBatchControlView({super.key, required this.deviceIds});
final List<String> deviceIds; final List<String> deviceIds;
@ -27,8 +26,7 @@ class TwoGangBatchControlView extends StatelessWidget
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is TwoGangSwitchStatusLoaded) { } else if (state is TwoGangSwitchStatusLoaded) {
return _buildStatusControls(context, state.status); return _buildStatusControls(context, state.status);
} else if (state is TwoGangSwitchError || } else if (state is TwoGangSwitchError || state is TwoGangSwitchControlError) {
state is TwoGangSwitchControlError) {
return const Center(child: Text('Error fetching status')); return const Center(child: Text('Error fetching status'));
} else { } else {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@ -84,10 +82,10 @@ class TwoGangBatchControlView extends StatelessWidget
)); ));
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget(callFactoryReset: () { FactoryResetWidget(callFactoryReset: () {
context.read<TwoGangSwitchBloc>().add( context.read<TwoGangSwitchBloc>().add(
TwoGangFactoryReset( TwoGangFactoryReset(

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart';
import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_bloc.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_bloc.dart';
import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart';
@ -113,7 +113,7 @@ class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLa
), ),
), ),
), ),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 2), // FirmwareUpdateWidget(deviceId: devicesIds.first, version: 2),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () { callFactoryReset: () {
context.read<WallSensorBloc>().add( context.read<WallSensorBloc>().add(

View File

@ -2,15 +2,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart';
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class WaterHEaterBatchControlView extends StatelessWidget class WaterHEaterBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
const WaterHEaterBatchControlView({super.key, required this.deviceIds}); const WaterHEaterBatchControlView({super.key, required this.deviceIds});
final List<String> deviceIds; final List<String> deviceIds;
@ -18,8 +17,8 @@ class WaterHEaterBatchControlView extends StatelessWidget
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => WaterHeaterBloc() create: (context) =>
..add(FetchWaterHeaterBatchStatusEvent(devicesUuid: deviceIds)), WaterHeaterBloc()..add(FetchWaterHeaterBatchStatusEvent(devicesUuid: deviceIds)),
child: BlocBuilder<WaterHeaterBloc, WaterHeaterState>( child: BlocBuilder<WaterHeaterBloc, WaterHeaterState>(
builder: (context, state) { builder: (context, state) {
if (state is WaterHeaterLoadingState) { if (state is WaterHeaterLoadingState) {
@ -36,8 +35,7 @@ class WaterHEaterBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, WaterHeaterStatusModel status) {
BuildContext context, WaterHeaterStatusModel status) {
final isExtraLarge = isExtraLargeScreenSize(context); final isExtraLarge = isExtraLargeScreenSize(context);
final isLarge = isLargeScreenSize(context); final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context); final isMedium = isMediumScreenSize(context);
@ -73,10 +71,10 @@ class WaterHEaterBatchControlView extends StatelessWidget
); );
}, },
), ),
FirmwareUpdateWidget( // FirmwareUpdateWidget(
deviceId: deviceIds.first, // deviceId: deviceIds.first,
version: 12, // version: 12,
), // ),
FactoryResetWidget( FactoryResetWidget(
callFactoryReset: () {}, callFactoryReset: () {},
), ),

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_bloc.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_bloc.dart';
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
@ -10,18 +10,16 @@ import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_st
import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart'; import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class WaterLeakBatchControlView extends StatelessWidget class WaterLeakBatchControlView extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final List<String> deviceIds; final List<String> deviceIds;
const WaterLeakBatchControlView({Key? key, required this.deviceIds}) const WaterLeakBatchControlView({Key? key, required this.deviceIds}) : super(key: key);
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => WaterLeakBloc(deviceIds.first) create: (context) =>
..add(FetchWaterLeakBatchStatusEvent(deviceIds)), WaterLeakBloc(deviceIds.first)..add(FetchWaterLeakBatchStatusEvent(deviceIds)),
child: BlocBuilder<WaterLeakBloc, WaterLeakState>( child: BlocBuilder<WaterLeakBloc, WaterLeakState>(
builder: (context, state) { builder: (context, state) {
if (state is WaterLeakLoadingState) { if (state is WaterLeakLoadingState) {
@ -38,18 +36,17 @@ class WaterLeakBatchControlView extends StatelessWidget
); );
} }
Widget _buildStatusControls( Widget _buildStatusControls(BuildContext context, WaterLeakStatusModel status) {
BuildContext context, WaterLeakStatusModel status) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox( // SizedBox(
width: 170, // width: 170,
height: 140, // height: 140,
child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)), // child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)),
const SizedBox( // const SizedBox(
width: 12, // width: 12,
), // ),
SizedBox( SizedBox(
width: 170, width: 170,
height: 140, height: 140,

View File

@ -91,40 +91,40 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
}, },
color: ColorsManager.primaryColor, color: ColorsManager.primaryColor,
), ),
HomeItemModel( // HomeItemModel(
title: 'Move in', // title: 'Move in',
icon: Assets.moveinIcon, // icon: Assets.moveinIcon,
active: true, // active: false,
onPress: (context) {}, // onPress: (context) {},
color: ColorsManager.primaryColor, // color: ColorsManager.primaryColor,
), // ),
HomeItemModel( // HomeItemModel(
title: 'Construction', // title: 'Construction',
icon: Assets.constructionIcon, // icon: Assets.constructionIcon,
active: false, // active: false,
onPress: (context) {}, // onPress: (context) {},
color: ColorsManager.primaryColor, // color: ColorsManager.primaryColor,
), // ),
HomeItemModel( // HomeItemModel(
title: 'Energy', // title: 'Energy',
icon: Assets.energyIcon, // icon: Assets.energyIcon,
active: false, // active: false,
onPress: (context) {}, // onPress: (context) {},
color: ColorsManager.slidingBlueColor.withOpacity(0.2), // color: ColorsManager.slidingBlueColor.withOpacity(0.2),
), // ),
HomeItemModel( // HomeItemModel(
title: 'Integrations', // title: 'Integrations',
icon: Assets.integrationsIcon, // icon: Assets.integrationsIcon,
active: false, // active: false,
onPress: (context) {}, // onPress: (context) {},
color: ColorsManager.slidingBlueColor.withOpacity(0.2), // color: ColorsManager.slidingBlueColor.withOpacity(0.2),
), // ),
HomeItemModel( // HomeItemModel(
title: 'Asset', // title: 'Asset',
icon: Assets.assetIcon, // icon: Assets.assetIcon,
active: false, // active: false,
onPress: (context) {}, // onPress: (context) {},
color: ColorsManager.slidingBlueColor.withOpacity(0.2), // color: ColorsManager.slidingBlueColor.withOpacity(0.2),
), // ),
]; ];
} }

View File

@ -51,7 +51,7 @@ class HomeWebPage extends StatelessWidget {
height: size.height * 0.6, height: size.height * 0.6,
width: size.width * 0.68, width: size.width * 0.68,
child: GridView.builder( child: GridView.builder(
itemCount: 8, itemCount: 3, //8
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, crossAxisCount: 4,
crossAxisSpacing: 20.0, crossAxisSpacing: 20.0,

View File

@ -758,6 +758,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
thenItems: [], thenItems: [],
selectedFunctions: {}, selectedFunctions: {},
scenes: [], scenes: [],
sceneId: '',
automationId: '',
automations: [], automations: [],
isLoading: false, isLoading: false,
errorMessage: '', errorMessage: '',
@ -1050,7 +1052,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final automationDetails = await SceneApi.getAutomationDetails(event.automationId); final automationDetails = await SceneApi.getAutomationDetails(event.automationId);
final Map<String, Map<String, dynamic>> deviceCards = {}; final Map<String, Map<String, dynamic>> deviceIfCards = {};
final Map<String, Map<String, dynamic>> deviceThenCards = {};
final Map<String, List<DeviceFunctionData>> updatedFunctions = final Map<String, List<DeviceFunctionData>> updatedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
@ -1066,8 +1070,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final deviceId = condition.entityId; final deviceId = condition.entityId;
if (!deviceCards.containsKey(deviceId)) { if (!deviceIfCards.containsKey(deviceId)) {
deviceCards[deviceId] = { deviceIfCards[deviceId] = {
'entityId': condition.entityId, 'entityId': condition.entityId,
'deviceId': condition.entityId, 'deviceId': condition.entityId,
'uniqueCustomId': const Uuid().v4(), 'uniqueCustomId': const Uuid().v4(),
@ -1080,7 +1084,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
}; };
} }
final cardData = deviceCards[deviceId]!; final cardData = deviceIfCards[deviceId]!;
final uniqueCustomId = cardData['uniqueCustomId'].toString(); final uniqueCustomId = cardData['uniqueCustomId'].toString();
if (!updatedFunctions.containsKey(uniqueCustomId)) { if (!updatedFunctions.containsKey(uniqueCustomId)) {
@ -1117,8 +1121,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final deviceId = final deviceId =
action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId; action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId;
if (!deviceCards.containsKey(deviceId)) { if (!deviceThenCards.containsKey(deviceId)) {
deviceCards[deviceId] = { deviceThenCards[deviceId] = {
'entityId': action.entityId, 'entityId': action.entityId,
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, 'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId': const Uuid().v4(), 'uniqueCustomId': const Uuid().v4(),
@ -1140,10 +1144,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
: action.type == 'automation' : action.type == 'automation'
? 'automation' ? 'automation'
: 'action', : 'action',
'icon': action.icon ?? ''
}; };
} }
final cardData = deviceCards[deviceId]!; final cardData = deviceThenCards[deviceId]!;
final uniqueCustomId = cardData['uniqueCustomId'].toString(); final uniqueCustomId = cardData['uniqueCustomId'].toString();
if (!updatedFunctions.containsKey(uniqueCustomId)) { if (!updatedFunctions.containsKey(uniqueCustomId)) {
@ -1192,8 +1197,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
final ifItems = deviceCards.values.where((card) => card['type'] == 'condition').toList(); final ifItems = deviceIfCards.values.where((card) => card['type'] == 'condition').toList();
final thenItems = deviceCards.values final thenItems = deviceThenCards.values
.where((card) => .where((card) =>
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene') card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene')
.toList(); .toList();

View File

@ -101,7 +101,7 @@ class SaveRoutineHelper {
final functions = final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? []; state.selectedFunctions[item['uniqueCustomId']] ?? [];
return ListTile( return ListTile(
leading: item['type'] == 'tap_to_run' leading: item['type'] == 'tap_to_run' || item['type'] == 'scene'
? Image.memory( ? Image.memory(
base64Decode(item['icon']), base64Decode(item['icon']),
width: 22, width: 22,

View File

@ -48,8 +48,7 @@ class RoutineDetailsModel {
spaceUuid: spaceUuid, spaceUuid: spaceUuid,
automationName: name, automationName: name,
decisionExpr: decisionExpr, decisionExpr: decisionExpr,
effectiveTime: effectiveTime: effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
conditions: conditions?.map((c) => c.toCondition()).toList() ?? [], conditions: conditions?.map((c) => c.toCondition()).toList() ?? [],
actions: actions.map((a) => a.toAutomationAction()).toList(), actions: actions.map((a) => a.toAutomationAction()).toList(),
); );
@ -64,8 +63,7 @@ class RoutineDetailsModel {
if (iconId != null) 'iconUuid': iconId, if (iconId != null) 'iconUuid': iconId,
if (showInDevice != null) 'showInDevice': showInDevice, if (showInDevice != null) 'showInDevice': showInDevice,
if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(), if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(),
if (conditions != null) if (conditions != null) 'conditions': conditions!.map((x) => x.toMap()).toList(),
'conditions': conditions!.map((x) => x.toMap()).toList(),
if (type != null) 'type': type, if (type != null) 'type': type,
if (sceneId != null) 'sceneId': sceneId, if (sceneId != null) 'sceneId': sceneId,
if (automationId != null) 'automationId': automationId, if (automationId != null) 'automationId': automationId,
@ -82,12 +80,10 @@ class RoutineDetailsModel {
), ),
iconId: map['iconUuid'], iconId: map['iconUuid'],
showInDevice: map['showInDevice'], showInDevice: map['showInDevice'],
effectiveTime: map['effectiveTime'] != null effectiveTime:
? EffectiveTime.fromMap(map['effectiveTime']) map['effectiveTime'] != null ? EffectiveTime.fromMap(map['effectiveTime']) : null,
: null,
conditions: map['conditions'] != null conditions: map['conditions'] != null
? List<RoutineCondition>.from( ? List<RoutineCondition>.from(map['conditions'].map((x) => RoutineCondition.fromMap(x)))
map['conditions'].map((x) => RoutineCondition.fromMap(x)))
: null, : null,
type: map['type'], type: map['type'],
sceneId: map['sceneId'], sceneId: map['sceneId'],
@ -108,15 +104,16 @@ class RoutineAction {
final RoutineExecutorProperty? executorProperty; final RoutineExecutorProperty? executorProperty;
final String productType; final String productType;
final String? type; final String? type;
final String? icon;
RoutineAction({ RoutineAction(
required this.entityId, {required this.entityId,
required this.actionExecutor, required this.actionExecutor,
required this.productType, required this.productType,
this.executorProperty, this.executorProperty,
this.name, this.name,
this.type, this.type,
}); this.icon});
CreateSceneAction toCreateSceneAction() { CreateSceneAction toCreateSceneAction() {
return CreateSceneAction( return CreateSceneAction(
@ -140,22 +137,21 @@ class RoutineAction {
'actionExecutor': actionExecutor, 'actionExecutor': actionExecutor,
if (type != null) 'type': type, if (type != null) 'type': type,
if (name != null) 'name': name, if (name != null) 'name': name,
if (executorProperty != null) if (executorProperty != null) 'executorProperty': executorProperty!.toMap(),
'executorProperty': executorProperty!.toMap(),
}; };
} }
factory RoutineAction.fromMap(Map<String, dynamic> map) { factory RoutineAction.fromMap(Map<String, dynamic> map) {
return RoutineAction( return RoutineAction(
entityId: map['entityId'] ?? '', entityId: map['entityId'] ?? '',
actionExecutor: map['actionExecutor'] ?? '', actionExecutor: map['actionExecutor'] ?? '',
productType: map['productType'] ?? '', productType: map['productType'] ?? '',
name: map['name'] ?? '', name: map['name'] ?? '',
type: map['type'] ?? '', type: map['type'] ?? '',
executorProperty: map['executorProperty'] != null executorProperty: map['executorProperty'] != null
? RoutineExecutorProperty.fromMap(map['executorProperty']) ? RoutineExecutorProperty.fromMap(map['executorProperty'])
: null, : null,
); icon: map['icon']);
} }
} }

View File

@ -32,18 +32,17 @@ class DraggableCard extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<RoutineBloc, RoutineState>( return BlocBuilder<RoutineBloc, RoutineState>(
builder: (context, state) { builder: (context, state) {
final deviceFunctions = final deviceFunctions = state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
int index = state.thenItems.indexWhere( int index = state.thenItems
(item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
if (index != -1) { if (index != -1) {
return _buildCardContent(context, deviceFunctions, padding: padding); return _buildCardContent(context, deviceFunctions, padding: padding);
} }
int ifIndex = state.ifItems.indexWhere( int ifIndex = state.ifItems
(item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']); .indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
if (ifIndex != -1) { if (ifIndex != -1) {
return _buildCardContent(context, deviceFunctions, padding: padding); return _buildCardContent(context, deviceFunctions, padding: padding);
@ -53,8 +52,7 @@ class DraggableCard extends StatelessWidget {
data: deviceData, data: deviceData,
feedback: Transform.rotate( feedback: Transform.rotate(
angle: -0.1, angle: -0.1,
child: child: _buildCardContent(context, deviceFunctions, padding: padding),
_buildCardContent(context, deviceFunctions, padding: padding),
), ),
childWhenDragging: _buildGreyContainer(), childWhenDragging: _buildGreyContainer(),
child: _buildCardContent(context, deviceFunctions, padding: padding), child: _buildCardContent(context, deviceFunctions, padding: padding),
@ -63,8 +61,7 @@ class DraggableCard extends StatelessWidget {
); );
} }
Widget _buildCardContent( Widget _buildCardContent(BuildContext context, List<DeviceFunctionData> deviceFunctions,
BuildContext context, List<DeviceFunctionData> deviceFunctions,
{EdgeInsetsGeometry? padding}) { {EdgeInsetsGeometry? padding}) {
return Stack( return Stack(
children: [ children: [
@ -93,7 +90,7 @@ class DraggableCard extends StatelessWidget {
), ),
), ),
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: deviceData['type'] == 'tap_to_run' child: deviceData['type'] == 'tap_to_run' || deviceData['type'] == 'scene'
? Image.memory( ? Image.memory(
base64Decode(deviceData['icon']), base64Decode(deviceData['icon']),
) )
@ -162,8 +159,7 @@ class DraggableCard extends StatelessWidget {
} }
String _formatFunctionValue(DeviceFunctionData function) { String _formatFunctionValue(DeviceFunctionData function) {
if (function.functionCode == 'temp_set' || if (function.functionCode == 'temp_set' || function.functionCode == 'temp_current') {
function.functionCode == 'temp_current') {
return '${(function.value / 10).toStringAsFixed(0)}°C'; return '${(function.value / 10).toStringAsFixed(0)}°C';
} else if (function.functionCode.contains('countdown')) { } else if (function.functionCode.contains('countdown')) {
final seconds = function.value.toInt(); final seconds = function.value.toInt();

View File

@ -26,9 +26,7 @@ class ThenContainer extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text('THEN', const Text('THEN', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 16), const SizedBox(height: 16),
state.isLoading && state.isUpdate == true state.isLoading && state.isUpdate == true
? const Center( ? const Center(
@ -41,17 +39,12 @@ class ThenContainer extends StatelessWidget {
state.thenItems.length, state.thenItems.length,
(index) => GestureDetector( (index) => GestureDetector(
onTap: () async { onTap: () async {
if (state.thenItems[index] if (state.thenItems[index]['deviceId'] == 'delay') {
['deviceId'] == final result = await DelayHelper.showDelayPickerDialog(
'delay') { context, state.thenItems[index]);
final result = await DelayHelper
.showDelayPickerDialog(context,
state.thenItems[index]);
if (result != null) { if (result != null) {
context context.read<RoutineBloc>().add(AddToThenContainer({
.read<RoutineBloc>()
.add(AddToThenContainer({
...state.thenItems[index], ...state.thenItems[index],
'imagePath': Assets.delay, 'imagePath': Assets.delay,
'title': 'Delay', 'title': 'Delay',
@ -60,79 +53,58 @@ class ThenContainer extends StatelessWidget {
return; return;
} }
if (state.thenItems[index]['type'] == if (state.thenItems[index]['type'] == 'automation') {
'automation') {
final result = await showDialog<bool>( final result = await showDialog<bool>(
context: context, context: context,
builder: (BuildContext context) => builder: (BuildContext context) => AutomationDialog(
AutomationDialog(
automationName: automationName:
state.thenItems[index] state.thenItems[index]['name'] ?? 'Automation',
['name'] ??
'Automation',
automationId: automationId:
state.thenItems[index] state.thenItems[index]['deviceId'] ?? '',
['deviceId'] ?? uniqueCustomId: state.thenItems[index]
'', ['uniqueCustomId'],
uniqueCustomId:
state.thenItems[index]
['uniqueCustomId'],
), ),
); );
if (result != null) { if (result != null) {
context context.read<RoutineBloc>().add(AddToThenContainer({
.read<RoutineBloc>()
.add(AddToThenContainer({
...state.thenItems[index], ...state.thenItems[index],
'imagePath': 'imagePath': Assets.automation,
Assets.automation, 'title': state.thenItems[index]['name'] ??
'title': state.thenItems[index]['title'],
state.thenItems[index]
['name'] ??
state.thenItems[index]
['title'],
})); }));
} }
return; return;
} }
final result = await DeviceDialogHelper final result = await DeviceDialogHelper.showDeviceDialog(
.showDeviceDialog( context, state.thenItems[index],
context, state.thenItems[index], removeComparetors: true);
removeComparetors: true);
if (result != null) { if (result != null) {
context.read<RoutineBloc>().add( context
AddToThenContainer( .read<RoutineBloc>()
state.thenItems[index])); .add(AddToThenContainer(state.thenItems[index]));
} else if (!['AC', '1G', '2G', '3G'] } else if (!['AC', '1G', '2G', '3G']
.contains(state.thenItems[index] .contains(state.thenItems[index]['productType'])) {
['productType'])) { context
context.read<RoutineBloc>().add( .read<RoutineBloc>()
AddToThenContainer( .add(AddToThenContainer(state.thenItems[index]));
state.thenItems[index]));
} }
}, },
child: DraggableCard( child: DraggableCard(
imagePath: state.thenItems[index] imagePath: state.thenItems[index]['imagePath'] ?? '',
['imagePath'] ?? title: state.thenItems[index]['title'] ?? '',
'',
title: state.thenItems[index]
['title'] ??
'',
deviceData: state.thenItems[index], deviceData: state.thenItems[index],
padding: const EdgeInsets.symmetric( padding:
horizontal: 4, vertical: 8), const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
isFromThen: true, isFromThen: true,
isFromIf: false, isFromIf: false,
onRemove: () { onRemove: () {
context.read<RoutineBloc>().add( context.read<RoutineBloc>().add(RemoveDragCard(
RemoveDragCard( index: index,
index: index, isFromThen: true,
isFromThen: true, key: state.thenItems[index]['uniqueCustomId']));
key: state.thenItems[index]
['uniqueCustomId']));
}, },
), ),
))), ))),
@ -151,9 +123,14 @@ class ThenContainer extends StatelessWidget {
return; return;
} }
if (state.automationId == mutableData['deviceId'] ||
state.sceneId == mutableData['deviceId']) {
return;
}
if (mutableData['type'] == 'automation') { if (mutableData['type'] == 'automation') {
int index = state.thenItems.indexWhere( int index =
(item) => item['deviceId'] == mutableData['deviceId']); state.thenItems.indexWhere((item) => item['deviceId'] == mutableData['deviceId']);
if (index != -1) { if (index != -1) {
return; return;
} }
@ -178,8 +155,8 @@ class ThenContainer extends StatelessWidget {
} }
if (mutableData['type'] == 'tap_to_run' && state.isAutomation) { if (mutableData['type'] == 'tap_to_run' && state.isAutomation) {
int index = state.thenItems.indexWhere( int index =
(item) => item['deviceId'] == mutableData['deviceId']); state.thenItems.indexWhere((item) => item['deviceId'] == mutableData['deviceId']);
if (index != -1) { if (index != -1) {
return; return;
} }
@ -197,8 +174,7 @@ class ThenContainer extends StatelessWidget {
} }
if (mutableData['deviceId'] == 'delay') { if (mutableData['deviceId'] == 'delay') {
final result = final result = await DelayHelper.showDelayPickerDialog(context, mutableData);
await DelayHelper.showDelayPickerDialog(context, mutableData);
if (result != null) { if (result != null) {
context.read<RoutineBloc>().add(AddToThenContainer({ context.read<RoutineBloc>().add(AddToThenContainer({
@ -210,13 +186,11 @@ class ThenContainer extends StatelessWidget {
return; return;
} }
final result = await DeviceDialogHelper.showDeviceDialog( final result = await DeviceDialogHelper.showDeviceDialog(context, mutableData,
context, mutableData,
removeComparetors: true); removeComparetors: true);
if (result != null) { if (result != null) {
context.read<RoutineBloc>().add(AddToThenContainer(mutableData)); context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
} else if (!['AC', '1G', '2G', '3G'] } else if (!['AC', '1G', '2G', '3G'].contains(mutableData['productType'])) {
.contains(mutableData['productType'])) {
context.read<RoutineBloc>().add(AddToThenContainer(mutableData)); context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
} }
}, },

View File

@ -1,9 +1,9 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_state.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart';
import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/product_api.dart';
import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart';
@ -309,8 +309,6 @@ class SpaceManagementBloc
await _api.deleteSpace(communityUuid, parent.uuid!); await _api.deleteSpace(communityUuid, parent.uuid!);
} }
} catch (e) { } catch (e) {
print(
'Error deleting space ${parent.name} (UUID: ${parent.uuid}, Community UUID: $communityUuid): $e');
rethrow; // Decide whether to stop execution or continue rethrow; // Decide whether to stop execution or continue
} }
} }
@ -342,7 +340,6 @@ class SpaceManagementBloc
space.uuid = response?.uuid; space.uuid = response?.uuid;
} }
} catch (e) { } catch (e) {
print('Error creating space ${space.name}: $e');
rethrow; // Stop further execution on failure rethrow; // Stop further execution on failure
} }
} }

View File

@ -1,7 +1,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; // Import for Offset import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; // Import for Offset
abstract class SpaceManagementEvent extends Equatable { abstract class SpaceManagementEvent extends Equatable {
const SpaceManagementEvent(); const SpaceManagementEvent();

View File

@ -1,7 +1,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
abstract class SpaceManagementState extends Equatable { abstract class SpaceManagementState extends Equatable {
const SpaceManagementState(); const SpaceManagementState();

View File

@ -1,5 +1,5 @@
import 'package:syncrow_web/pages/auth/model/region_model.dart'; import 'package:syncrow_web/pages/auth/model/region_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
class CommunityModel { class CommunityModel {
final String uuid; final String uuid;

View File

@ -1,4 +1,4 @@
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
class Connection { class Connection {
final SpaceModel startSpace; final SpaceModel startSpace;

View File

@ -1,7 +1,7 @@
import 'dart:ui'; import 'dart:ui';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';

View File

@ -1,13 +1,13 @@
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:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_state.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/loaded_space_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart';
import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/product_api.dart';
import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart';
import 'package:syncrow_web/web_layout/web_scaffold.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart';

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/counter_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/counter_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';

View File

@ -1,9 +1,9 @@
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:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/create_community/view/create_community_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class BlankCommunityWidget extends StatefulWidget { class BlankCommunityWidget extends StatefulWidget {
@ -72,7 +72,8 @@ class _BlankCommunityWidgetState extends State<BlankCommunityWidget> {
showDialog( showDialog(
context: parentContext, context: parentContext,
builder: (context) => CreateCommunityDialog( builder: (context) => CreateCommunityDialog(
communities: widget.communities, isEditMode: false,
existingCommunityNames: widget.communities.map((community) => community.name).toList(),
onCreateCommunity: (String communityName, String description) { onCreateCommunity: (String communityName, String description) {
parentContext.read<SpaceManagementBloc>().add( parentContext.read<SpaceManagementBloc>().add(
CreateCommunityEvent( CreateCommunityEvent(
@ -84,4 +85,5 @@ class _BlankCommunityWidgetState extends State<BlankCommunityWidget> {
), ),
); );
} }
} }

View File

@ -1,10 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/create_community/view/create_community_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
class CommunityStructureHeader extends StatelessWidget { class CommunityStructureHeader extends StatefulWidget {
final String? communityName; final String? communityName;
final bool isEditingName; final bool isEditingName;
final bool isSave; final bool isSave;
@ -13,19 +15,28 @@ class CommunityStructureHeader extends StatelessWidget {
final VoidCallback onDelete; final VoidCallback onDelete;
final VoidCallback onEditName; final VoidCallback onEditName;
final ValueChanged<String> onNameSubmitted; final ValueChanged<String> onNameSubmitted;
final List<CommunityModel> communities;
final CommunityModel? community;
const CommunityStructureHeader({ const CommunityStructureHeader(
Key? key, {super.key,
required this.communityName, required this.communityName,
required this.isSave, required this.isSave,
required this.isEditingName, required this.isEditingName,
required this.nameController, required this.nameController,
required this.onSave, required this.onSave,
required this.onDelete, required this.onDelete,
required this.onEditName, required this.onEditName,
required this.onNameSubmitted, required this.onNameSubmitted,
}) : super(key: key); this.community,
required this.communities});
@override
State<CommunityStructureHeader> createState() =>
_CommunityStructureHeaderState();
}
class _CommunityStructureHeaderState extends State<CommunityStructureHeader> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
@ -60,47 +71,63 @@ class CommunityStructureHeader extends StatelessWidget {
); );
} }
void _showCreateCommunityDialog(BuildContext parentContext) {
showDialog(
context: parentContext,
builder: (context) => CreateCommunityDialog(
isEditMode: true,
existingCommunityNames:
widget.communities.map((community) => community.name).toList(),
initialName: widget.community?.name ?? '',
onCreateCommunity: (String communityName, String description) {
widget.onNameSubmitted(communityName);
},
),
);
}
Widget _buildCommunityInfo(ThemeData theme, double screenWidth) { Widget _buildCommunityInfo(ThemeData theme, double screenWidth) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Community Structure', 'Community Structure',
style: theme.textTheme.headlineLarge?.copyWith(color: ColorsManager.blackColor), style: theme.textTheme.headlineLarge
?.copyWith(color: ColorsManager.blackColor),
), ),
if (communityName != null) if (widget.communityName != null)
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Row( child: Row(
children: [ children: [
if (!isEditingName) if (!widget.isEditingName)
Flexible( Flexible(
child: Text( child: Text(
communityName!, widget.communityName!,
style: style: theme.textTheme.bodyLarge
theme.textTheme.bodyLarge?.copyWith(color: ColorsManager.blackColor), ?.copyWith(color: ColorsManager.blackColor),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
), ),
), ),
if (isEditingName) if (widget.isEditingName)
SizedBox( SizedBox(
width: screenWidth * 0.1, width: screenWidth * 0.1,
child: TextField( child: TextField(
controller: nameController, controller: widget.nameController,
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
isDense: true, isDense: true,
), ),
style: style: theme.textTheme.bodyLarge
theme.textTheme.bodyLarge?.copyWith(color: ColorsManager.blackColor), ?.copyWith(color: ColorsManager.blackColor),
onSubmitted: onNameSubmitted, onSubmitted: widget.onNameSubmitted,
), ),
), ),
const SizedBox(width: 2), const SizedBox(width: 2),
GestureDetector( GestureDetector(
onTap: onEditName, onTap: () => _showCreateCommunityDialog(context),
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.iconEdit, Assets.iconEdit,
width: 16, width: 16,
@ -110,7 +137,7 @@ class CommunityStructureHeader extends StatelessWidget {
], ],
), ),
), ),
if (isSave) ...[ if (widget.isSave) ...[
const SizedBox(width: 8), const SizedBox(width: 8),
_buildActionButtons(theme), _buildActionButtons(theme),
], ],
@ -127,8 +154,9 @@ class CommunityStructureHeader extends StatelessWidget {
children: [ children: [
_buildButton( _buildButton(
label: "Save", label: "Save",
icon: const Icon(Icons.save, size: 18, color: ColorsManager.spaceColor), icon: const Icon(Icons.save,
onPressed: onSave, size: 18, color: ColorsManager.spaceColor),
onPressed: widget.onSave,
theme: theme), theme: theme),
], ],
); );
@ -159,7 +187,8 @@ class CommunityStructureHeader extends StatelessWidget {
Flexible( Flexible(
child: Text( child: Text(
label, label,
style: theme.textTheme.bodySmall?.copyWith(color: ColorsManager.blackColor), style: theme.textTheme.bodySmall
?.copyWith(color: ColorsManager.blackColor),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
), ),

View File

@ -4,19 +4,19 @@ import 'package:flutter_bloc/flutter_bloc.dart';
// Syncrow project imports // Syncrow project imports
import 'package:syncrow_web/pages/common/buttons/add_space_button.dart'; import 'package:syncrow_web/pages/common/buttons/add_space_button.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/blank_community_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/community_structure_header_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_header_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_space_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/curved_line_painter.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_card_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_card_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_container_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_container_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class CommunityStructureArea extends StatefulWidget { class CommunityStructureArea extends StatefulWidget {
@ -119,7 +119,9 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
CommunityStructureHeader( CommunityStructureHeader(
communities: widget.communities,
communityName: widget.selectedCommunity?.name, communityName: widget.selectedCommunity?.name,
community: widget.selectedCommunity,
isSave: isSave(spaces), isSave: isSave(spaces),
isEditingName: isEditingName, isEditingName: isEditingName,
nameController: _nameController, nameController: _nameController,

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class CurvedLinePainter extends CustomPainter { class CurvedLinePainter extends CustomPainter {

View File

@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/add_device_type_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/icon_selection_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/hoverable_button.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/hoverable_button.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/space_icon_const.dart'; import 'package:syncrow_web/utils/constants/space_icon_const.dart';
@ -133,13 +133,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
isNameFieldInvalid = value.isEmpty; isNameFieldInvalid = value.isEmpty;
if (!isNameFieldInvalid) { if (!isNameFieldInvalid) {
if ((widget.parentSpace?.children.any( if (_isNameConflict(value)) {
(child) => child.name == value) ??
false) ||
(widget.parentSpace?.name == value) ||
(widget.editSpace?.children.any(
(child) => child.name == value) ??
false)) {
isNameFieldExist = true; isNameFieldExist = true;
isOkButtonEnabled = false; isOkButtonEnabled = false;
} else { } else {
@ -387,7 +381,14 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
); );
} }
bool _isNameConflict(String value) {
return (widget.parentSpace?.children.any((child) => child.name == value) ??
false) ||
(widget.parentSpace?.name == value) ||
(widget.editSpace?.parent?.name == value) ||
(widget.editSpace?.children.any((child) => child.name == value) ??
false);
}
String _mapIconToProduct(String uuid, List<ProductModel> products) { String _mapIconToProduct(String uuid, List<ProductModel> products) {
// Find the product with the matching UUID // Find the product with the matching UUID

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/community_structure_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/gradient_canvas_border_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/sidebar_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart';
class LoadedSpaceView extends StatefulWidget { class LoadedSpaceView extends StatefulWidget {
final List<CommunityModel> communities; final List<CommunityModel> communities;

View File

@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/common/search_bar.dart'; import 'package:syncrow_web/common/search_bar.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/community_tile.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_tile_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/style.dart'; import 'package:syncrow_web/utils/style.dart';

View File

@ -0,0 +1,21 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'community_dialog_event.dart';
import 'community_dialog_state.dart';
class CommunityDialogBloc extends Bloc<CommunityDialogEvent, CommunityDialogState> {
final List<String> existingCommunityNames;
CommunityDialogBloc(this.existingCommunityNames)
: super(CommunityDialogInitial()) {
on<ValidateCommunityNameEvent>((event, emit) {
final trimmedName = event.name.trim();
final isNameValid = !existingCommunityNames.contains(trimmedName);
final isNameEmpty = trimmedName.isEmpty;
emit(CommunityNameValidationState(
isNameValid: isNameValid,
isNameEmpty: isNameEmpty,
));
});
}
}

View File

@ -0,0 +1,15 @@
import 'package:equatable/equatable.dart';
abstract class CommunityDialogEvent extends Equatable {
@override
List<Object?> get props => [];
}
class ValidateCommunityNameEvent extends CommunityDialogEvent {
final String name;
ValidateCommunityNameEvent(this.name);
@override
List<Object?> get props => [name];
}

View File

@ -0,0 +1,21 @@
import 'package:equatable/equatable.dart';
abstract class CommunityDialogState extends Equatable {
@override
List<Object?> get props => [];
}
class CommunityDialogInitial extends CommunityDialogState {}
class CommunityNameValidationState extends CommunityDialogState {
final bool isNameValid;
final bool isNameEmpty;
CommunityNameValidationState({
required this.isNameValid,
required this.isNameEmpty,
});
@override
List<Object?> get props => [isNameValid, isNameEmpty];
}

View File

@ -0,0 +1,170 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_event.dart';
import 'package:syncrow_web/pages/spaces_management/create_community/bloc/community_dialog_state.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
class CreateCommunityDialog extends StatelessWidget {
final Function(String name, String description) onCreateCommunity;
final List<String> existingCommunityNames;
final bool isEditMode;
final String? initialName;
const CreateCommunityDialog({
super.key,
required this.onCreateCommunity,
required this.existingCommunityNames,
required this.isEditMode,
this.initialName,
});
@override
Widget build(BuildContext context) {
final nameController =
TextEditingController(text: isEditMode ? initialName : '');
return BlocProvider(
create: (_) => CommunityDialogBloc(existingCommunityNames),
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
backgroundColor: ColorsManager.transparentColor,
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width * 0.3,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: ColorsManager.blackColor.withOpacity(0.25),
blurRadius: 20,
spreadRadius: 5,
offset: const Offset(0, 5),
),
],
),
child: SingleChildScrollView(
child: BlocBuilder<CommunityDialogBloc, CommunityDialogState>(
builder: (context, state) {
bool isNameValid = true;
bool isNameEmpty = false;
if (state is CommunityNameValidationState) {
isNameValid = state.isNameValid;
isNameEmpty = state.isNameEmpty;
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
isEditMode ? 'Edit Community Name' : 'Community Name',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 18),
TextField(
controller: nameController,
onChanged: (value) {
context
.read<CommunityDialogBloc>()
.add(ValidateCommunityNameEvent(value));
},
style: const TextStyle(
color: ColorsManager.blackColor,
),
decoration: InputDecoration(
hintText: 'Please enter the community name',
filled: true,
fillColor: ColorsManager.boxColor,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: isNameValid && !isNameEmpty
? ColorsManager.boxColor
: ColorsManager.red,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: ColorsManager.boxColor,
width: 1.5,
),
),
),
),
if (!isNameValid)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name already exists.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
if (isNameEmpty)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name should not be empty.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CancelButton(
label: 'Cancel',
onPressed: () => Navigator.of(context).pop(),
),
),
const SizedBox(width: 16),
Expanded(
child: DefaultButton(
onPressed: () {
if (isNameValid && !isNameEmpty) {
onCreateCommunity(
nameController.text.trim(),
"",
);
Navigator.of(context).pop();
}
},
backgroundColor: isNameValid && !isNameEmpty
? ColorsManager.secondaryColor
: ColorsManager.lightGrayColor,
borderRadius: 10,
foregroundColor: ColorsManager.whiteColors,
child: const Text('OK'),
),
),
],
),
],
);
},
),
),
),
],
),
),
);
}
}

View File

@ -1,177 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CreateCommunityDialog extends StatefulWidget {
final Function(String name, String description) onCreateCommunity;
final List<CommunityModel> communities;
const CreateCommunityDialog(
{super.key, required this.onCreateCommunity, required this.communities});
@override
CreateCommunityDialogState createState() => CreateCommunityDialogState();
}
class CreateCommunityDialogState extends State<CreateCommunityDialog> {
String enteredName = '';
bool isNameFieldExist = false;
bool isNameEmpty = false;
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
backgroundColor:
ColorsManager.transparentColor, // Transparent for shadow effect
child: Stack(
children: [
// Background container with shadow and rounded corners
Container(
width: screenWidth * 0.3,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: ColorsManager.blackColor.withOpacity(0.25),
blurRadius: 20,
spreadRadius: 5,
offset: const Offset(0, 5),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Community Name',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
// Input field for the community name
TextField(
onChanged: (value) {
setState(() {
enteredName = value.trim();
isNameFieldExist = widget.communities.any(
(community) => community.name == enteredName,
);
if (value.isEmpty) {
isNameEmpty = true;
} else {
isNameEmpty = false;
}
});
},
style: const TextStyle(
color: ColorsManager.blackColor,
),
decoration: InputDecoration(
hintText: 'Please enter the community name',
filled: true,
fillColor: ColorsManager.boxColor,
hintStyle: const TextStyle(
fontSize: 14,
color: ColorsManager.grayBorder,
fontWeight: FontWeight.w400,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor,
width: 1),
borderRadius: BorderRadius.circular(10),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor, width: 1),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor,
width: 1),
),
),
),
if (isNameFieldExist)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name already exists.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
if (isNameEmpty)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name should not be empty.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
const SizedBox(height: 24),
// Action buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CancelButton(
label: 'Cancel',
onPressed: () => Navigator.of(context).pop(),
),
),
const SizedBox(width: 16),
Expanded(
child: DefaultButton(
onPressed: () {
if (enteredName.isNotEmpty && !isNameFieldExist) {
widget.onCreateCommunity(
enteredName,
"",
);
Navigator.of(context).pop();
}
},
backgroundColor: isNameFieldExist || isNameEmpty
? ColorsManager.lightGrayColor
: ColorsManager.secondaryColor,
borderRadius: 10,
foregroundColor: ColorsManager.whiteColors,
child: const Text('OK'),
),
),
],
),
],
),
),
],
),
);
}
}

View File

@ -22,16 +22,16 @@ class AuthenticationAPI {
}) async { }) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.forgetPassword, path: ApiEndpoints.forgetPassword,
body: {"email": email, "password": password,"otpCode": otpCode}, body: {"email": email, "password": password, "otpCode": otpCode},
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) {}); expectedResponseModel: (json) {});
return response; return response;
} }
static Future<int?> sendOtp({required String email, required String regionUuid}) async { static Future<int?> sendOtp({required String email}) async {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.sendOtp, path: ApiEndpoints.sendOtp,
body: {"email": email, "type": "PASSWORD", "regionUuid": regionUuid}, body: {"email": email, "type": "PASSWORD"},
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['data']['cooldown']; return json['data']['cooldown'];

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';

View File

@ -6,6 +6,7 @@ import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart';
import 'package:syncrow_web/pages/routiens/models/routine_model.dart'; import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class SceneApi { class SceneApi {
static final HTTPService _httpService = HTTPService(); static final HTTPService _httpService = HTTPService();
@ -76,7 +77,8 @@ class SceneApi {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.getUnitScenes path: ApiEndpoints.getUnitScenes
.replaceAll('{spaceUuid}', unitId) .replaceAll('{spaceUuid}', unitId)
.replaceAll('{communityUuid}', communityId), .replaceAll('{communityUuid}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
queryParameters: {'showInHomePage': showInDevice}, queryParameters: {'showInHomePage': showInDevice},
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_response_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
import 'package:syncrow_web/utils/constants/temp_const.dart';
class CommunitySpaceManagementApi { class CommunitySpaceManagementApi {
// Community Management APIs // Community Management APIs
@ -15,7 +16,8 @@ class CommunitySpaceManagementApi {
while (hasNext) { while (hasNext) {
await HTTPService().get( await HTTPService().get(
path: ApiEndpoints.getCommunityList, path: ApiEndpoints.getCommunityList
.replaceAll('{projectId}', TempConst.projectId),
queryParameters: {'page': page}, queryParameters: {'page': page},
expectedResponseModel: (json) { expectedResponseModel: (json) {
List<dynamic> jsonData = json['data']; List<dynamic> jsonData = json['data'];
@ -59,7 +61,8 @@ class CommunitySpaceManagementApi {
String name, String description) async { String name, String description) async {
try { try {
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createCommunity, path: ApiEndpoints.createCommunity
.replaceAll('{projectId}', TempConst.projectId),
body: { body: {
'name': name, 'name': name,
'description': description, 'description': description,
@ -79,7 +82,8 @@ class CommunitySpaceManagementApi {
try { try {
final response = await HTTPService().put( final response = await HTTPService().put(
path: ApiEndpoints.updateCommunity path: ApiEndpoints.updateCommunity
.replaceAll('{communityId}', communityId), .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
body: { body: {
'name': name, 'name': name,
}, },
@ -98,7 +102,8 @@ class CommunitySpaceManagementApi {
try { try {
final response = await HTTPService().delete( final response = await HTTPService().delete(
path: ApiEndpoints.deleteCommunity path: ApiEndpoints.deleteCommunity
.replaceAll('{communityId}', communityId), .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success'] ?? false; return json['success'] ?? false;
}, },
@ -113,7 +118,9 @@ class CommunitySpaceManagementApi {
Future<SpacesResponse> fetchSpaces(String communityId) async { Future<SpacesResponse> fetchSpaces(String communityId) async {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.listSpaces.replaceAll('{communityId}', communityId), path: ApiEndpoints.listSpaces
.replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpacesResponse.fromJson(json); return SpacesResponse.fromJson(json);
}, },
@ -139,7 +146,8 @@ class CommunitySpaceManagementApi {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpace path: ApiEndpoints.getSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId), .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpaceModel.fromJson(json); return SpaceModel.fromJson(json);
}, },
@ -175,7 +183,9 @@ class CommunitySpaceManagementApi {
body['parentUuid'] = parentId; body['parentUuid'] = parentId;
} }
final response = await HTTPService().post( final response = await HTTPService().post(
path: ApiEndpoints.createSpace.replaceAll('{communityId}', communityId), path: ApiEndpoints.createSpace
.replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
body: body, body: body,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpaceModel.fromJson(json['data']); return SpaceModel.fromJson(json['data']);
@ -216,7 +226,8 @@ class CommunitySpaceManagementApi {
final response = await HTTPService().put( final response = await HTTPService().put(
path: ApiEndpoints.updateSpace path: ApiEndpoints.updateSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId), .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId),
body: body, body: body,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return SpaceModel.fromJson(json['data']); return SpaceModel.fromJson(json['data']);
@ -234,7 +245,8 @@ class CommunitySpaceManagementApi {
final response = await HTTPService().delete( final response = await HTTPService().delete(
path: ApiEndpoints.deleteSpace path: ApiEndpoints.deleteSpace
.replaceAll('{communityId}', communityId) .replaceAll('{communityId}', communityId)
.replaceAll('{spaceId}', spaceId), .replaceAll('{spaceId}', spaceId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success'] ?? false; return json['success'] ?? false;
}, },
@ -250,7 +262,8 @@ class CommunitySpaceManagementApi {
try { try {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getSpaceHierarchy path: ApiEndpoints.getSpaceHierarchy
.replaceAll('{communityId}', communityId), .replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) { expectedResponseModel: (json) {
print(json); print(json);
final spaceModels = (json['data'] as List) final spaceModels = (json['data'] as List)

View File

@ -4,7 +4,7 @@ import 'package:syncrow_web/pages/auth/view/login_page.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/view/device_managment_page.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/view/device_managment_page.dart';
import 'package:syncrow_web/pages/home/view/home_page.dart'; import 'package:syncrow_web/pages/home/view/home_page.dart';
import 'package:syncrow_web/pages/roles_and_permission/view/roles_and_permission_page.dart'; import 'package:syncrow_web/pages/roles_and_permission/view/roles_and_permission_page.dart';
import 'package:syncrow_web/pages/spaces_management/view/spaces_management_page.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/view/spaces_management_page.dart';
import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart'; import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart';
import 'package:syncrow_web/utils/constants/routes_const.dart'; import 'package:syncrow_web/utils/constants/routes_const.dart';

View File

@ -40,31 +40,31 @@ abstract class ApiEndpoints {
// Space Module // Space Module
static const String createSpace = static const String createSpace =
'/projects/${projectUuid}/communities/{communityId}/spaces'; '/projects/{projectId}/communities/{communityId}/spaces';
static const String listSpaces = static const String listSpaces =
'/projects/${projectUuid}/communities/{communityId}/spaces'; '/projects/{projectId}/communities/{communityId}/spaces';
static const String deleteSpace = static const String deleteSpace =
'/projects/${projectUuid}/communities/{communityId}/spaces/{spaceId}'; '/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
static const String updateSpace = static const String updateSpace =
'/projects/${projectUuid}/communities/{communityId}/spaces/{spaceId}'; '/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
static const String getSpace = static const String getSpace =
'/projects/${projectUuid}/communities/{communityId}/spaces/{spaceId}'; '/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
static const String getSpaceHierarchy = static const String getSpaceHierarchy =
'/projects/${projectUuid}/communities/{communityId}/spaces'; '/projects/{projectId}/communities/{communityId}/spaces';
// Community Module // Community Module
static const String createCommunity = '/projects/${projectUuid}/communities'; static const String createCommunity = '/projects/{projectId}/communities';
static const String getCommunityList = '/projects/${projectUuid}/communities'; static const String getCommunityList = '/projects/{projectId}/communities';
static const String getCommunityById = static const String getCommunityById =
'/projects/${projectUuid}/communities/{communityId}'; '/projects/{projectId}/communities/{communityId}';
static const String updateCommunity = static const String updateCommunity =
'/projects/${projectUuid}/communities/{communityId}'; '/projects/{projectId}/communities/{communityId}';
static const String deleteCommunity = static const String deleteCommunity =
'/projects/${projectUuid}/communities/{communityId}'; '/projects/{projectId}communities/{communityId}';
static const String getUserCommunities = static const String getUserCommunities =
'/projects/${projectUuid}/communities/user/{userUuid}'; '/projects/{projectId}/communities/user/{userUuid}';
static const String createUserCommunity = static const String createUserCommunity =
'/projects/${projectUuid}/communities/user'; '/projects/{projectId}/communities/user';
static const String getDeviceLogsByDate = static const String getDeviceLogsByDate =
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}'; '/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
@ -87,7 +87,7 @@ abstract class ApiEndpoints {
static const String createScene = '/scene/tap-to-run'; static const String createScene = '/scene/tap-to-run';
static const String createAutomation = '/automation'; static const String createAutomation = '/automation';
static const String getUnitScenes = static const String getUnitScenes =
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes'; '/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
static const String getAutomationDetails = static const String getAutomationDetails =
'/automation/details/{automationId}'; '/automation/details/{automationId}';
static const String getScene = '/scene/tap-to-run/{sceneId}'; static const String getScene = '/scene/tap-to-run/{sceneId}';
@ -106,7 +106,8 @@ abstract class ApiEndpoints {
static const String getUserById = '/projects/${projectUuid}/user/{userUuid}'; static const String getUserById = '/projects/${projectUuid}/user/{userUuid}';
static const String editUser = '/invite-user/{inviteUserUuid}'; static const String editUser = '/invite-user/{inviteUserUuid}';
static const String deleteUser = '/invite-user/{inviteUserUuid}'; static const String deleteUser = '/invite-user/{inviteUserUuid}';
static const String changeUserStatus = '/invite-user/{invitedUserUuid}/disable'; static const String changeUserStatus =
'/invite-user/{invitedUserUuid}/disable';
// static const String updateAutomation = '/automation/{automationId}'; // static const String updateAutomation = '/automation/{automationId}';
} }

View File

@ -0,0 +1,3 @@
class TempConst {
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c';
}

View File

@ -76,16 +76,16 @@ class _UserDropdownMenuState extends State<UserDropdownMenu> {
), ),
), ),
items: <PopupMenuEntry>[ items: <PopupMenuEntry>[
PopupMenuItem( // PopupMenuItem(
onTap: () {}, // onTap: () {},
child: ListTile( // child: ListTile(
leading: SvgPicture.asset(Assets.accountSetting), // leading: SvgPicture.asset(Assets.accountSetting),
title: Text( // title: Text(
"Account Settings", // "Account Settings",
style: context.textTheme.bodyMedium, // style: context.textTheme.bodyMedium,
), // ),
), // ),
), // ),
PopupMenuItem( PopupMenuItem(
onTap: () { onTap: () {
context.go(RoutesConst.rolesAndPermissions); context.go(RoutesConst.rolesAndPermissions);
@ -103,7 +103,6 @@ class _UserDropdownMenuState extends State<UserDropdownMenu> {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
final size = MediaQuery.of(context).size;
return AlertDialog( return AlertDialog(
alignment: Alignment.center, alignment: Alignment.center,
content: SizedBox( content: SizedBox(