mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
visitor password
This commit is contained in:
@ -43,8 +43,7 @@ class MyApp extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
textTheme: const TextTheme(
|
textTheme: const TextTheme(
|
||||||
bodySmall: TextStyle(
|
bodySmall: TextStyle(fontSize: 13, color: ColorsManager.whiteColors, fontWeight: FontWeight.bold),
|
||||||
fontSize: 13, color: ColorsManager.whiteColors, fontWeight: FontWeight.bold),
|
|
||||||
bodyMedium: TextStyle(color: Colors.black87, fontSize: 14),
|
bodyMedium: TextStyle(color: Colors.black87, fontSize: 14),
|
||||||
bodyLarge: TextStyle(fontSize: 16, color: Colors.white),
|
bodyLarge: TextStyle(fontSize: 16, color: Colors.white),
|
||||||
headlineSmall: TextStyle(color: Colors.black87, fontSize: 18),
|
headlineSmall: TextStyle(color: Colors.black87, fontSize: 18),
|
||||||
@ -58,8 +57,8 @@ class MyApp extends StatelessWidget {
|
|||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||||
useMaterial3: true, // Enable Material 3
|
useMaterial3: true, // Enable Material 3
|
||||||
),
|
),
|
||||||
home: VisitorPasswordDialog()
|
// home: VisitorPasswordDialog()
|
||||||
// isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
home:isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
|
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/bloc/access_state.dart';
|
import 'package:syncrow_web/pages/access_management/bloc/access_state.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/date_time_widget.dart';
|
||||||
import 'package:syncrow_web/pages/common/default_button.dart';
|
import 'package:syncrow_web/pages/common/default_button.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/assets.dart';
|
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
@ -122,42 +121,19 @@ class AccessManagementPage extends StatelessWidget {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 15,
|
width: 15,
|
||||||
),
|
),
|
||||||
Column(
|
DateTimeWebWidget(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
isRequired: false,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
title: 'Access Time',
|
||||||
children: [
|
size: size,
|
||||||
const Text('Access Time'),
|
endTime: () {
|
||||||
Container(
|
accessBloc.add(SelectTime(context: context, isStart: false));
|
||||||
width: size.width * 0.25,
|
},
|
||||||
padding: EdgeInsets.all(10),
|
startTime: () {
|
||||||
decoration: containerDecoration,
|
accessBloc.add(SelectTime(context: context, isStart: true));
|
||||||
child: Column(
|
},
|
||||||
children: [
|
firstString:BlocProvider.of<AccessBloc>(context).startTime ,
|
||||||
Row(
|
secondString:BlocProvider.of<AccessBloc>(context).endTime ,
|
||||||
mainAxisAlignment:
|
) ,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
accessBloc.add(SelectTime(context: context, isStart: true));
|
|
||||||
},
|
|
||||||
child: Text(BlocProvider.of<AccessBloc>(context).startTime)
|
|
||||||
),
|
|
||||||
const Icon(Icons.arrow_right_alt),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
accessBloc.add(SelectTime(context: context, isStart: false));
|
|
||||||
},
|
|
||||||
child: Text(BlocProvider.of<AccessBloc>(context).endTime)),
|
|
||||||
SvgPicture.asset(
|
|
||||||
Assets.calendarIcon,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 15,
|
width: 15,
|
||||||
),
|
),
|
||||||
@ -334,6 +310,7 @@ class AccessManagementPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Widget _buildTableHeaderCell(String title) {
|
Widget _buildTableHeaderCell(String title) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
67
lib/pages/common/custom_web_textfield.dart
Normal file
67
lib/pages/common/custom_web_textfield.dart
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
class CustomWebTextField extends StatelessWidget {
|
||||||
|
const CustomWebTextField({
|
||||||
|
super.key,
|
||||||
|
required this.isRequired,
|
||||||
|
required this.textFieldName,
|
||||||
|
required this.controller,
|
||||||
|
this.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool isRequired;
|
||||||
|
final String textFieldName;
|
||||||
|
final String? description;
|
||||||
|
final TextEditingController? controller;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
if(isRequired)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'* ',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(color: Colors.red),
|
||||||
|
),
|
||||||
|
Text(textFieldName),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
description??'', // ' The password will be sent to the visitor’s email address.',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall!
|
||||||
|
.copyWith(
|
||||||
|
fontSize: 9,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: ColorsManager.textGray),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 7,),
|
||||||
|
Container(
|
||||||
|
decoration: containerDecoration,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
decoration: textBoxDecoration()!
|
||||||
|
.copyWith(hintText: 'Please enter'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
74
lib/pages/common/date_time_widget.dart
Normal file
74
lib/pages/common/date_time_widget.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
|
class DateTimeWebWidget extends StatelessWidget {
|
||||||
|
const DateTimeWebWidget({
|
||||||
|
super.key,
|
||||||
|
required this.size,
|
||||||
|
required this.isRequired,
|
||||||
|
required this.title,
|
||||||
|
required this.startTime,
|
||||||
|
required this.endTime,
|
||||||
|
required this.firstString,
|
||||||
|
required this.secondString,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Size size;
|
||||||
|
final String title;
|
||||||
|
final bool isRequired;
|
||||||
|
final String firstString;
|
||||||
|
final String secondString;
|
||||||
|
final Function()? startTime;
|
||||||
|
final Function()? endTime;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if(isRequired)
|
||||||
|
Text(
|
||||||
|
'* ',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(color: Colors.red),
|
||||||
|
),
|
||||||
|
Text(title??''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 8,),
|
||||||
|
Container(
|
||||||
|
width: size.width * 0.25,
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
decoration: containerDecoration,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: startTime,
|
||||||
|
child: Text(firstString)
|
||||||
|
),
|
||||||
|
const Icon(Icons.arrow_right_alt),
|
||||||
|
InkWell(
|
||||||
|
onTap:endTime,
|
||||||
|
child: Text(secondString)),
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.calendarIcon,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,108 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.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/bloc/visitor_password_state.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||||
|
|
||||||
// Define the BLoC
|
// Define the BLoC
|
||||||
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||||
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
||||||
on<SelectPasswordType>((event, emit) {
|
on<SelectUsageFrequency>(selectUsageFrequency);
|
||||||
// Handle the event and emit the new state
|
on<SelectPasswordType>(selectAccessType);
|
||||||
emit(PasswordTypeSelected(event.type));
|
on<SelectTimeVisitorPassword>(selectTimeVisitorPassword);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
final TextEditingController userNameController = TextEditingController();
|
||||||
|
final TextEditingController emailController = TextEditingController();
|
||||||
|
|
||||||
|
String accessTypeSelected='';
|
||||||
|
String usageFrequencySelected='';
|
||||||
|
|
||||||
|
|
||||||
|
int? effectiveTimeTimeStamp;
|
||||||
|
int? expirationTimeTimeStamp;
|
||||||
|
|
||||||
|
String startTime = 'Start Time';
|
||||||
|
String endTime = 'End Time';
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> selectTimeVisitorPassword(SelectTimeVisitorPassword event, Emitter<VisitorPasswordState> emit) async {
|
||||||
|
final DateTime? picked = await showDatePicker(
|
||||||
|
context: event.context,
|
||||||
|
initialDate: DateTime.now(),
|
||||||
|
firstDate: DateTime(2015, 8),
|
||||||
|
lastDate: DateTime(2101),
|
||||||
|
);
|
||||||
|
if (picked != null) {
|
||||||
|
final TimeOfDay? timePicked = await showTimePicker(
|
||||||
|
context: event.context,
|
||||||
|
initialTime: TimeOfDay.now(),
|
||||||
|
|
||||||
|
builder: (context, child) {
|
||||||
|
return Theme(
|
||||||
|
data: ThemeData.light().copyWith(
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: ColorsManager.primaryColor,
|
||||||
|
onSurface: Colors.black,
|
||||||
|
),
|
||||||
|
buttonTheme: const ButtonThemeData(
|
||||||
|
colorScheme: ColorScheme.light(
|
||||||
|
primary: Colors.green,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: child!,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (timePicked != null) {
|
||||||
|
final selectedDateTime = DateTime(
|
||||||
|
picked.year,
|
||||||
|
picked.month,
|
||||||
|
picked.day,
|
||||||
|
timePicked.hour,
|
||||||
|
timePicked.minute,
|
||||||
|
);
|
||||||
|
final selectedTimestamp = DateTime(
|
||||||
|
selectedDateTime.year,
|
||||||
|
selectedDateTime.month,
|
||||||
|
selectedDateTime.day,
|
||||||
|
selectedDateTime.hour,
|
||||||
|
selectedDateTime.minute,
|
||||||
|
).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds
|
||||||
|
if (event.isStart) {
|
||||||
|
if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.');
|
||||||
|
} else {
|
||||||
|
startTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||||
|
effectiveTimeTimeStamp = selectedTimestamp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) {
|
||||||
|
CustomSnackBar.displaySnackBar('Expiration Time cannot be earlier than Effective Time.');
|
||||||
|
} else {
|
||||||
|
endTime = selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds
|
||||||
|
expirationTimeTimeStamp = selectedTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// emit(AccessInitial());
|
||||||
|
// emit(TableLoaded(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
abstract class VisitorPasswordEvent extends Equatable {
|
abstract class VisitorPasswordEvent extends Equatable {
|
||||||
const VisitorPasswordEvent(
|
const VisitorPasswordEvent();
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
@ -21,3 +16,21 @@ class SelectPasswordType extends VisitorPasswordEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [type];
|
List<Object> get props => [type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SelectUsageFrequency extends VisitorPasswordEvent {
|
||||||
|
final String usageType;
|
||||||
|
|
||||||
|
const SelectUsageFrequency(this.usageType);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [usageType];
|
||||||
|
}
|
||||||
|
class SelectTimeVisitorPassword extends VisitorPasswordEvent {
|
||||||
|
final BuildContext context;
|
||||||
|
final bool isStart;
|
||||||
|
|
||||||
|
const SelectTimeVisitorPassword({ required this.context,required this.isStart});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [context,isStart];
|
||||||
|
}
|
||||||
|
@ -16,8 +16,17 @@ class VisitorPasswordInitial extends VisitorPasswordState {}
|
|||||||
class PasswordTypeSelected extends VisitorPasswordState {
|
class PasswordTypeSelected extends VisitorPasswordState {
|
||||||
final String selectedType;
|
final String selectedType;
|
||||||
|
|
||||||
PasswordTypeSelected(this.selectedType);
|
const PasswordTypeSelected(this.selectedType);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [selectedType];
|
List<Object> get props => [selectedType];
|
||||||
|
}
|
||||||
|
|
||||||
|
class UsageFrequencySelected extends VisitorPasswordState {
|
||||||
|
final String selectedFrequency;
|
||||||
|
|
||||||
|
const UsageFrequencySelected(this.selectedFrequency);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [selectedFrequency];
|
||||||
}
|
}
|
@ -1,86 +1,54 @@
|
|||||||
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/common/custom_web_textfield.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/date_time_widget.dart';
|
||||||
|
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_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.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/bloc/visitor_password_state.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
|
|
||||||
class VisitorPasswordDialog extends StatelessWidget {
|
class VisitorPasswordDialog extends StatelessWidget {
|
||||||
const VisitorPasswordDialog({super.key});
|
const VisitorPasswordDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => VisitorPasswordBloc(),
|
create: (context) => VisitorPasswordBloc(),
|
||||||
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Create visitor password'),
|
title: const Text('Create visitor password'),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: ListBody(
|
child: ListBody(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
flex: 2,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
child: CustomWebTextField(
|
||||||
children: [
|
controller:visitorBloc.userNameController ,
|
||||||
Row(
|
isRequired: true,
|
||||||
children: [
|
textFieldName: 'User Name',
|
||||||
Text(
|
description: '',
|
||||||
'* ',
|
),
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium!
|
|
||||||
.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
const Text('User Name'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: size.width * 0.15,
|
|
||||||
decoration: containerDecoration,
|
|
||||||
child: TextFormField(
|
|
||||||
style: TextStyle(color: Colors.black),
|
|
||||||
decoration: textBoxDecoration()!
|
|
||||||
.copyWith(hintText: 'Please enter'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
SizedBox(width: size.width * 0.05), // Add spacing between columns
|
const Spacer(),
|
||||||
Column(
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
flex: 2,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
child: CustomWebTextField(
|
||||||
children: [
|
controller:visitorBloc.emailController ,
|
||||||
Row(
|
isRequired: true,
|
||||||
children: [
|
textFieldName: 'Email Address',
|
||||||
Text(
|
description: 'The password will be sent to the visitor’s email address.',
|
||||||
'* ',
|
),
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium!
|
|
||||||
.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
const Text('Email Address'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: size.width * 0.15,
|
|
||||||
decoration: containerDecoration,
|
|
||||||
child: TextFormField(
|
|
||||||
style: TextStyle(color: Colors.black),
|
|
||||||
decoration: textBoxDecoration()!
|
|
||||||
.copyWith(hintText: 'Please enter'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: size.height * 0.02), // Add spacing
|
SizedBox(height: size.height * 0.02), // Add spacing
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -101,25 +69,22 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 200,
|
width: size.width*0.15,
|
||||||
child: RadioListTile<String>(
|
child: RadioListTile<String>(
|
||||||
title: Text('Offline Password'),
|
title: const Text('Offline Password'),
|
||||||
value: 'Offline Password',
|
value: 'Offline Password',
|
||||||
groupValue: (state is PasswordTypeSelected)
|
groupValue: (state is PasswordTypeSelected)
|
||||||
? state.selectedType
|
? state.selectedType
|
||||||
: 'Offline Password',
|
: 'Offline Password',
|
||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
context
|
context.read<VisitorPasswordBloc>().add(SelectPasswordType(value));
|
||||||
.read<VisitorPasswordBloc>()
|
|
||||||
.add(SelectPasswordType(value));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 200,
|
width: size.width*0.15,
|
||||||
|
|
||||||
child: RadioListTile<String>(
|
child: RadioListTile<String>(
|
||||||
title: Text('Online Password'),
|
title: Text('Online Password'),
|
||||||
value: 'Online Password',
|
value: 'Online Password',
|
||||||
@ -136,10 +101,9 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 200,
|
width: size.width*0.15,
|
||||||
|
|
||||||
child: RadioListTile<String>(
|
child: RadioListTile<String>(
|
||||||
title: Text('Dynamic Password'),
|
title: const Text('Dynamic Password'),
|
||||||
value: 'Dynamic Password',
|
value: 'Dynamic Password',
|
||||||
groupValue: (state is PasswordTypeSelected)
|
groupValue: (state is PasswordTypeSelected)
|
||||||
? state.selectedType
|
? state.selectedType
|
||||||
@ -180,32 +144,29 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
child: RadioListTile<String>(
|
child: RadioListTile<String>(
|
||||||
title: const Text('One-Time'),
|
title: const Text('One-Time'),
|
||||||
value: 'One-Time',
|
value: 'One-Time',
|
||||||
groupValue: (state is PasswordTypeSelected)
|
groupValue: (state is UsageFrequencySelected)
|
||||||
? state.selectedType
|
? state.selectedFrequency
|
||||||
: 'One-Time',
|
: 'One-Time',
|
||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
context
|
context.read<VisitorPasswordBloc>()
|
||||||
.read<VisitorPasswordBloc>()
|
.add(SelectUsageFrequency(value));
|
||||||
.add(SelectPasswordType(value));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 200,
|
width: 200,
|
||||||
|
|
||||||
child: RadioListTile<String>(
|
child: RadioListTile<String>(
|
||||||
title: Text('Periodic'),
|
title: const Text('Periodic'),
|
||||||
value: 'Periodic',
|
value: 'Periodic',
|
||||||
groupValue: (state is PasswordTypeSelected)
|
groupValue: (state is UsageFrequencySelected)
|
||||||
? state.selectedType
|
? state.selectedFrequency
|
||||||
: 'Periodic',
|
: 'Periodic1',
|
||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
context
|
context.read<VisitorPasswordBloc>()
|
||||||
.read<VisitorPasswordBloc>()
|
.add(SelectUsageFrequency(value));
|
||||||
.add(SelectPasswordType(value));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -214,73 +175,69 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
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 ,
|
||||||
|
) ,
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'* ',
|
'* ',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(color: Colors.red),
|
.copyWith(color: Colors.red),
|
||||||
),
|
),
|
||||||
const Text('Access Period'),
|
const Text('Access Devices'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
const Text('Within the validity period, each device can be unlocked only once.'),
|
||||||
children: <Widget>[
|
Container(
|
||||||
SizedBox(
|
decoration: containerDecoration,
|
||||||
width: 200,
|
width: size.width*0.2,
|
||||||
child: RadioListTile<String>(
|
child: const DefaultButton(
|
||||||
title: const Text('One-Time'),
|
borderRadius: 8,
|
||||||
value: 'One-Time',
|
child:Text('+ Add Device'),)),
|
||||||
groupValue: (state is PasswordTypeSelected)
|
|
||||||
? state.selectedType
|
|
||||||
: 'One-Time',
|
|
||||||
onChanged: (String? value) {
|
|
||||||
if (value != null) {
|
|
||||||
context
|
|
||||||
.read<VisitorPasswordBloc>()
|
|
||||||
.add(SelectPasswordType(value));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 200,
|
|
||||||
|
|
||||||
child: RadioListTile<String>(
|
|
||||||
title: Text('Periodic'),
|
|
||||||
value: 'Periodic',
|
|
||||||
groupValue: (state is PasswordTypeSelected)
|
|
||||||
? state.selectedType
|
|
||||||
: 'Periodic',
|
|
||||||
onChanged: (String? value) {
|
|
||||||
if (value != null) {
|
|
||||||
context
|
|
||||||
.read<VisitorPasswordBloc>()
|
|
||||||
.add(SelectPasswordType(value));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
actionsAlignment: MainAxisAlignment.center,
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
Container(
|
||||||
child: const Text('Approve'),
|
decoration: containerDecoration,
|
||||||
onPressed: () {
|
width: size.width*0.2,
|
||||||
Navigator.of(context).pop();
|
child: DefaultButton(
|
||||||
},
|
borderRadius: 8,
|
||||||
),
|
onPressed:() {},
|
||||||
|
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'),)),
|
||||||
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -288,3 +245,4 @@ class VisitorPasswordDialog extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Decoration containerDecoration = BoxDecoration(
|
|||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.withOpacity(0.5),
|
color: Colors.grey.withOpacity(0.5),
|
||||||
spreadRadius: 5,
|
spreadRadius: 5,
|
||||||
blurRadius: 7,
|
blurRadius: 8,
|
||||||
offset: Offset(0,
|
offset: Offset(0,
|
||||||
3), // changes position of shadow
|
3), // changes position of shadow
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user