mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
create visitor password
This commit is contained in:
@ -56,8 +56,8 @@ class MyApp extends StatelessWidget {
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||
useMaterial3: true, // Enable Material 3
|
||||
),
|
||||
// home: VisitorPasswordDialog()
|
||||
home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
home: VisitorPasswordDialog()
|
||||
// home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
|
||||
width: 100,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
onTap:state is TimerState && !state.isButtonEnabled && state.remainingTime!=1?null: () {
|
||||
forgetBloc.add(StartTimerEvent());
|
||||
},
|
||||
child: Text(
|
||||
@ -326,13 +326,6 @@ class ForgetPasswordWebPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ SizedBox(child: Text(forgetBloc.forgetValidate,
|
||||
style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -11,13 +11,17 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
on<SelectUsageFrequency>(selectUsageFrequency);
|
||||
on<SelectPasswordType>(selectAccessType);
|
||||
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
||||
on<ToggleRepeatEvent>(toggleRepeat);
|
||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||
|
||||
}
|
||||
final TextEditingController userNameController = TextEditingController();
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
|
||||
String accessTypeSelected='';
|
||||
String usageFrequencySelected='';
|
||||
String accessTypeSelected='Offline Password';
|
||||
String usageFrequencySelected='One-Time';
|
||||
|
||||
bool repeat = false;
|
||||
|
||||
int? effectiveTimeTimeStamp;
|
||||
int? expirationTimeTimeStamp;
|
||||
@ -27,13 +31,11 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
|
||||
selectAccessType(SelectPasswordType event, Emitter<VisitorPasswordState> emit) {
|
||||
accessTypeSelected=event.type;
|
||||
print(accessTypeSelected);
|
||||
emit(PasswordTypeSelected(event.type));
|
||||
}
|
||||
|
||||
selectUsageFrequency(SelectUsageFrequency event, Emitter<VisitorPasswordState> emit) {
|
||||
usageFrequencySelected=event.usageType;
|
||||
print(usageFrequencySelected);
|
||||
emit(UsageFrequencySelected(event.usageType));
|
||||
}
|
||||
|
||||
@ -104,4 +106,36 @@ class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordStat
|
||||
}
|
||||
|
||||
|
||||
bool toggleRepeat(ToggleRepeatEvent event, Emitter<VisitorPasswordState> emit) {
|
||||
emit(LoadingInitialState());
|
||||
repeat = !repeat;
|
||||
emit(IsRepeatState(repeat: repeat));
|
||||
return repeat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Map<String, String>> days = [
|
||||
{"day": "Sun", "key": "Sun"},
|
||||
{"day": "Mon", "key": "Mon"},
|
||||
{"day": "Tue", "key": "Tue"},
|
||||
{"day": "Wed", "key": "Wed"},
|
||||
{"day": "Thu", "key": "Thu"},
|
||||
{"day": "Fri", "key": "Fri"},
|
||||
{"day": "Sat", "key": "Sat"},
|
||||
];
|
||||
|
||||
List<String> selectedDays = [];
|
||||
|
||||
Future<void> toggleDaySelection(ToggleDaySelectionEvent event, Emitter<VisitorPasswordState> emit,)async {
|
||||
emit(LoadingInitialState());
|
||||
if (selectedDays.contains(event.key)) {
|
||||
selectedDays.remove(event.key);
|
||||
} else {
|
||||
selectedDays.add(event.key);
|
||||
}
|
||||
emit(ChangeTimeState());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -34,3 +34,16 @@ class SelectTimeVisitorPassword extends VisitorPasswordEvent {
|
||||
@override
|
||||
List<Object> get props => [context,isStart];
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ToggleDaySelectionEvent extends VisitorPasswordEvent {
|
||||
final String key;
|
||||
|
||||
const ToggleDaySelectionEvent({required this.key});
|
||||
@override
|
||||
List<Object> get props => [key];
|
||||
}
|
||||
|
||||
|
||||
class ToggleRepeatEvent extends VisitorPasswordEvent {}
|
||||
|
@ -29,4 +29,16 @@ class UsageFrequencySelected extends VisitorPasswordState {
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedFrequency];
|
||||
}
|
||||
}
|
||||
|
||||
class IsRepeatState extends VisitorPasswordState {
|
||||
final bool repeat;
|
||||
const IsRepeatState({required this.repeat});
|
||||
|
||||
@override
|
||||
List<Object> get props => [repeat];
|
||||
|
||||
}
|
||||
|
||||
class LoadingInitialState extends VisitorPasswordState {}
|
||||
class ChangeTimeState extends VisitorPasswordState {}
|
||||
|
81
lib/pages/visitor_password/view/repeat_widget.dart
Normal file
81
lib/pages/visitor_password/view/repeat_widget.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/date_time_widget.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class RepeatWidget extends StatelessWidget {
|
||||
const RepeatWidget({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
return BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
builder: (context, state) {
|
||||
final smartDoorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
smartDoorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString: smartDoorBloc.startTime,
|
||||
secondString: smartDoorBloc.endTime,
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Container(
|
||||
width: size.width * 0.8,
|
||||
height: size.height * 0.06, // Adjust height as needed
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: smartDoorBloc.days.map((day) {
|
||||
return Container(
|
||||
width: size.width* 0.09,
|
||||
child: CheckboxListTile(
|
||||
title: Text(
|
||||
day['day']!,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: smartDoorBloc.selectedDays.contains(day['key'])
|
||||
? Colors.black
|
||||
: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
value: smartDoorBloc.selectedDays.contains(day['key']),
|
||||
onChanged: (bool? value) {
|
||||
if (value != null) {
|
||||
smartDoorBloc.add(ToggleDaySelectionEvent(key: day['key']!));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/custom_web_textfield.dart';
|
||||
@ -6,9 +7,10 @@ import 'package:syncrow_web/pages/common/default_button.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/view/repeat_widget.dart';
|
||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
|
||||
class VisitorPasswordDialog extends StatelessWidget {
|
||||
const VisitorPasswordDialog({super.key});
|
||||
|
||||
@ -18,19 +20,20 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
return BlocProvider(
|
||||
create: (context) => VisitorPasswordBloc(),
|
||||
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
builder: (context, state) {
|
||||
builder: (BuildContext context, VisitorPasswordState state) {
|
||||
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||
bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat;
|
||||
return AlertDialog(
|
||||
title: const Text('Create visitor password'),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
controller:visitorBloc.userNameController ,
|
||||
controller: visitorBloc.userNameController,
|
||||
isRequired: true,
|
||||
textFieldName: 'User Name',
|
||||
description: '',
|
||||
@ -40,7 +43,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CustomWebTextField(
|
||||
controller:visitorBloc.emailController ,
|
||||
controller: visitorBloc.emailController,
|
||||
isRequired: true,
|
||||
textFieldName: 'Email Address',
|
||||
description: 'The password will be sent to the visitor’s email address.',
|
||||
@ -48,11 +51,9 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: size.height * 0.02), // Add spacing
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
@ -69,13 +70,13 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: size.width*0.15,
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Offline Password'),
|
||||
value: 'Offline Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
@ -84,46 +85,43 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width*0.15,
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Online Password'),
|
||||
value: 'Online Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width*0.15,
|
||||
width: size.width * 0.15,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('Dynamic Password'),
|
||||
value: 'Dynamic Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
@ -146,11 +144,10 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
value: 'One-Time',
|
||||
groupValue: (state is UsageFrequencySelected)
|
||||
? state.selectedFrequency
|
||||
: 'One-Time',
|
||||
: visitorBloc.usageFrequencySelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>()
|
||||
.add(SelectUsageFrequency(value));
|
||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -162,59 +159,80 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
value: 'Periodic',
|
||||
groupValue: (state is UsageFrequencySelected)
|
||||
? state.selectedFrequency
|
||||
: 'Periodic1',
|
||||
: visitorBloc.usageFrequencySelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context.read<VisitorPasswordBloc>()
|
||||
.add(SelectUsageFrequency(value));
|
||||
context.read<VisitorPasswordBloc>().add(SelectUsageFrequency(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
visitorBloc.accessTypeSelected=='Dynamic Password' ?
|
||||
SizedBox():
|
||||
|
||||
DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString:BlocProvider.of<VisitorPasswordBloc>(context).startTime ,
|
||||
secondString:BlocProvider.of<VisitorPasswordBloc>(context).endTime ,
|
||||
) ,
|
||||
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false));
|
||||
},
|
||||
startTime: () {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: true));
|
||||
},
|
||||
firstString: visitorBloc.startTime,
|
||||
secondString: visitorBloc.endTime,
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Devices'),
|
||||
],
|
||||
),
|
||||
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||
visitorBloc.usageFrequencySelected=='Periodic'&&visitorBloc.accessTypeSelected=='Offline Password'?
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Text('Repeat'),
|
||||
trailing: Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: visitorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
visitorBloc.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
):const SizedBox(),
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width*0.2,
|
||||
child: const DefaultButton(
|
||||
borderRadius: 8,
|
||||
child:Text('+ Add Device'),)),
|
||||
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
borderRadius: 8,
|
||||
child: Text('+ Add Device'),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -222,22 +240,27 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
actions: <Widget>[
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width*0.2,
|
||||
child: DefaultButton(
|
||||
borderRadius: 8,
|
||||
onPressed:() {},
|
||||
backgroundColor: Colors.white,
|
||||
child:Text('Cancel',style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!,),)),
|
||||
|
||||
width: size.width * 0.2,
|
||||
child: DefaultButton(
|
||||
borderRadius: 8,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
},
|
||||
backgroundColor: Colors.white,
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: Theme.of(context).textTheme.bodyMedium!,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width*0.2,
|
||||
child: const DefaultButton(
|
||||
borderRadius: 8,
|
||||
child:Text('Ok'),)),
|
||||
|
||||
decoration: containerDecoration,
|
||||
width: size.width * 0.2,
|
||||
child: const DefaultButton(
|
||||
borderRadius: 8,
|
||||
child: Text('Ok'),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
@ -245,4 +268,3 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user