mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
visitor password
This commit is contained in:
@ -2,7 +2,8 @@
|
||||
{
|
||||
"accessUser": "Ali Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01",
|
||||
"startTime": "2023-08-01",
|
||||
"endTime": "2023-08-02",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -12,8 +13,9 @@
|
||||
}, {
|
||||
"accessUser": "oamr Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"startTime": "2023-08-01",
|
||||
"endTime": "2023-08-05",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
"authorizationTime": "2023-08-01 10:00 AM",
|
||||
@ -22,7 +24,8 @@
|
||||
}, {
|
||||
"accessUser": "John Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01",
|
||||
"startTime": "2023-08-01",
|
||||
"endTime": "2023-08-10",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -34,7 +37,8 @@
|
||||
{
|
||||
"accessUser": "John Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01",
|
||||
"startTime": "2023-08-01",
|
||||
"endTime": "2023-10-10",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -45,7 +49,8 @@
|
||||
{
|
||||
"accessUser": "John Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01",
|
||||
"startTime": "2023-03-01",
|
||||
"endTime": "2023-05-10",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -56,7 +61,8 @@
|
||||
{
|
||||
"accessUser": "John Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01 ",
|
||||
"startTime": "2023-07-01",
|
||||
"endTime": "2023-08-10",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -66,7 +72,8 @@
|
||||
}, {
|
||||
"accessUser": "John Doe",
|
||||
"accessType": "Admin",
|
||||
"accessPeriod": "2023-08-01 ",
|
||||
"startTime": "2023-01-01",
|
||||
"endTime": "2023-09-05",
|
||||
"accessibleDevice": "Smart Door",
|
||||
"authorizationSource": "System",
|
||||
"authorizer": "Jane Smith",
|
||||
@ -77,7 +84,8 @@
|
||||
{
|
||||
"accessUser": "Alice Johnson",
|
||||
"accessType": "User",
|
||||
"accessPeriod": "2023-08-01 to 2023-08-31",
|
||||
"startTime": "2023-08-01",
|
||||
"endTime": "2023-08-10",
|
||||
"accessibleDevice": "Smart Lock",
|
||||
"authorizationSource": "Admin",
|
||||
"authorizer": "John Doe",
|
||||
|
@ -1,10 +1,12 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/access_management/view/access_management.dart';
|
||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
||||
import 'package:syncrow_web/pages/auth/view/login_page.dart';
|
||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
||||
import 'package:syncrow_web/pages/home/view/home_page.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart';
|
||||
import 'package:syncrow_web/services/locator.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
@ -56,7 +58,8 @@ class MyApp extends StatelessWidget {
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||
useMaterial3: true, // Enable Material 3
|
||||
),
|
||||
home: isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
home: VisitorPasswordDialog()
|
||||
// isLoggedIn == 'Success' ? const HomePage() : const LoginPage(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,181 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/model/access_manag_model.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/password_model.dart';
|
||||
import 'package:syncrow_web/services/access_mang_api.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||
|
||||
class AccessBloc extends Bloc<AccessEvent, AccessState> {
|
||||
AccessBloc() : super((AccessInitial())) {
|
||||
on<FetchTableData>(_onFetchTableData);
|
||||
on<TabChangedEvent>(selectFilterTap);
|
||||
on<SelectTime>(selectTime);
|
||||
on<FilterDataEvent>(_filterData);
|
||||
on<ResetSearch>(resetSearch);
|
||||
}
|
||||
String startTime = 'Start Time';
|
||||
String endTime = 'End Time';
|
||||
|
||||
int? effectiveTimeTimeStamp;
|
||||
int? expirationTimeTimeStamp;
|
||||
TextEditingController passwordName= TextEditingController();
|
||||
List<PasswordModel> filteredData = []; // To store filtered data
|
||||
List<PasswordModel> data=[];
|
||||
|
||||
Future<void> _onFetchTableData(
|
||||
FetchTableData event, Emitter<AccessState> emit) async {
|
||||
try {
|
||||
emit(AccessLoaded());
|
||||
List<AccessManagModel> data = await AccessMangApi().fetchInfo();
|
||||
print('objectwww888888${data[0].accessPeriod}');
|
||||
|
||||
emit(TableLoaded(data));
|
||||
data = await AccessMangApi().fetchVisitorPassword();
|
||||
emit(TableLoaded(data));
|
||||
} catch (e) {
|
||||
emit(FailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
int selectedIndex = 0;
|
||||
|
||||
final List<String> tabs = [
|
||||
'All',
|
||||
'To Be Effective (0)',
|
||||
'Effective (0)',
|
||||
'Expired'
|
||||
];
|
||||
|
||||
|
||||
Future selectFilterTap(TabChangedEvent event, Emitter<AccessState> emit) async {
|
||||
try {
|
||||
emit(AccessLoaded());
|
||||
selectedIndex= event.selectedIndex;
|
||||
emit(AccessInitial());
|
||||
emit(TableLoaded(data));
|
||||
|
||||
} catch (e) {
|
||||
emit(FailedState( e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> selectTime(SelectTime event, Emitter<AccessState> 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));
|
||||
}
|
||||
|
||||
Future<void> _filterData(FilterDataEvent event, Emitter<AccessState> emit) async {
|
||||
emit(AccessLoaded());
|
||||
try {
|
||||
// Filter the data based on the provided criteria
|
||||
filteredData = data.where((item) {
|
||||
bool matchesCriteria = true;
|
||||
// Check if the password name should be used for filtering
|
||||
if (event.passwordName != null && event.passwordName!.isNotEmpty) {
|
||||
final bool matchesName = item.passwodName != null &&
|
||||
item.passwodName.contains(event.passwordName!);
|
||||
if (!matchesName) {
|
||||
matchesCriteria = false;
|
||||
}
|
||||
}
|
||||
// Check if the time range should be used for filtering
|
||||
if (event.startTime != null && event.endTime != null) {
|
||||
// Ensure effectiveTime and invalidTime are treated as integers
|
||||
final int? effectiveTime = int.tryParse(item.effectiveTime.toString());
|
||||
final int? invalidTime = int.tryParse(item.invalidTime.toString());
|
||||
if (effectiveTime == null || invalidTime == null) {
|
||||
matchesCriteria = false;
|
||||
} else {
|
||||
final bool matchesStartTime = effectiveTime >= event.startTime!;
|
||||
final bool matchesEndTime = invalidTime <= event.endTime!;
|
||||
if (!matchesStartTime || !matchesEndTime) {
|
||||
matchesCriteria = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchesCriteria;
|
||||
}).toList();
|
||||
print('Filtered data: $filteredData'); // Print to debug filtered data
|
||||
emit(TableLoaded(filteredData));
|
||||
} catch (e) {
|
||||
print('Error occurred during filtering: $e');
|
||||
}
|
||||
}
|
||||
// ResetSearch
|
||||
resetSearch(ResetSearch event, Emitter<AccessState> emit) async{
|
||||
emit(AccessLoaded());
|
||||
startTime = 'Start Time';
|
||||
endTime = 'End Time';
|
||||
passwordName.clear();
|
||||
add(FetchTableData());
|
||||
|
||||
}
|
||||
|
||||
|
||||
DateTime timestampToDateTime(dynamic timestamp) {
|
||||
return DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class AccessEvent extends Equatable {
|
||||
const AccessEvent();
|
||||
@ -8,4 +9,32 @@ abstract class AccessEvent extends Equatable {
|
||||
List<Object> get props => [];
|
||||
}
|
||||
class FetchTableData extends AccessEvent {}
|
||||
class ResetSearch extends AccessEvent {}
|
||||
|
||||
class TabChangedEvent extends AccessEvent {
|
||||
final int selectedIndex;
|
||||
|
||||
const TabChangedEvent(this.selectedIndex);
|
||||
}
|
||||
|
||||
|
||||
class SelectTime extends AccessEvent {
|
||||
final BuildContext context;
|
||||
final bool isStart;
|
||||
const SelectTime({required this.context,required this.isStart});
|
||||
@override
|
||||
List<Object> get props => [context,isStart];
|
||||
}
|
||||
|
||||
|
||||
class FilterDataEvent extends AccessEvent {
|
||||
final String? passwordName;
|
||||
final int? startTime;
|
||||
final int? endTime;
|
||||
|
||||
const FilterDataEvent({
|
||||
this.passwordName,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/access_manag_model.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/password_model.dart';
|
||||
|
||||
abstract class AccessState extends Equatable {
|
||||
const AccessState();
|
||||
@ -21,7 +21,7 @@ class FailedState extends AccessState {
|
||||
}
|
||||
|
||||
class TableLoaded extends AccessState {
|
||||
final List<AccessManagModel> data;
|
||||
final List<PasswordModel> data;
|
||||
|
||||
const TableLoaded(this.data);
|
||||
|
||||
@ -29,3 +29,12 @@ class TableLoaded extends AccessState {
|
||||
List<Object> get props => [data];
|
||||
}
|
||||
|
||||
class TabState extends AccessState {
|
||||
final int selectedIndex;
|
||||
|
||||
const TabState({required this.selectedIndex});
|
||||
}
|
||||
|
||||
class ChangeTimeState extends AccessState {}
|
||||
|
||||
class TimeSelectedState extends AccessState {}
|
||||
|
@ -1,37 +0,0 @@
|
||||
class AccessManagModel {
|
||||
final String accessUser;
|
||||
final String accessType;
|
||||
final String accessPeriod;
|
||||
final String accessibleDevice;
|
||||
final String authorizationSource;
|
||||
final String authorizer;
|
||||
final String authorizationTime;
|
||||
final String accessStatus;
|
||||
final String actions;
|
||||
|
||||
AccessManagModel({
|
||||
required this.accessUser,
|
||||
required this.accessType,
|
||||
required this.accessPeriod,
|
||||
required this.accessibleDevice,
|
||||
required this.authorizationSource,
|
||||
required this.authorizer,
|
||||
required this.authorizationTime,
|
||||
required this.accessStatus,
|
||||
required this.actions,
|
||||
});
|
||||
|
||||
factory AccessManagModel.fromJson(Map<String, dynamic> json) {
|
||||
return AccessManagModel(
|
||||
accessUser: json['accessUser'],
|
||||
accessType: json['accessType'],
|
||||
accessPeriod: json['accessPeriod'],
|
||||
accessibleDevice: json['accessibleDevice'],
|
||||
authorizationSource: json['authorizationSource'],
|
||||
authorizer: json['authorizer'],
|
||||
authorizationTime: json['authorizationTime'],
|
||||
accessStatus: json['accessStatus'],
|
||||
actions: json['actions'],
|
||||
);
|
||||
}
|
||||
}
|
54
lib/pages/access_management/model/password_model.dart
Normal file
54
lib/pages/access_management/model/password_model.dart
Normal file
@ -0,0 +1,54 @@
|
||||
class PasswordModel {
|
||||
final dynamic passwordId;
|
||||
final dynamic invalidTime;
|
||||
final dynamic effectiveTime;
|
||||
final dynamic passwordCreated;
|
||||
final dynamic createdTime;
|
||||
final dynamic passwodName; // New field
|
||||
final dynamic passwordStatus;
|
||||
final dynamic passwordType;
|
||||
final dynamic deviceUuid;
|
||||
|
||||
PasswordModel({
|
||||
this.passwordId,
|
||||
this.invalidTime,
|
||||
this.effectiveTime,
|
||||
this.passwordCreated,
|
||||
this.createdTime,
|
||||
this.passwodName, // New field
|
||||
this.passwordStatus,
|
||||
this.passwordType,
|
||||
this.deviceUuid,
|
||||
});
|
||||
|
||||
factory PasswordModel.fromJson(Map<String, dynamic> json) {
|
||||
return PasswordModel(
|
||||
passwordId: json['passwordId'],
|
||||
invalidTime: json['invalidTime'],
|
||||
effectiveTime: json['effectiveTime'],
|
||||
passwordCreated: json['passwordCreated'],
|
||||
createdTime: json['createdTime'],
|
||||
passwodName: json['passwodName']??'No name', // New field
|
||||
passwordStatus: json['passwordStatus'],
|
||||
passwordType: json['passwordType'],
|
||||
deviceUuid: json['deviceUuid'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'passwordId': passwordId,
|
||||
'invalidTime': invalidTime,
|
||||
'effectiveTime': effectiveTime,
|
||||
'passwordCreated': passwordCreated,
|
||||
'createdTime': createdTime,
|
||||
'passwodName': passwodName, // New field
|
||||
'passwordStatus': passwordStatus,
|
||||
'passwordType': passwordType,
|
||||
'deviceUuid': deviceUuid,
|
||||
};
|
||||
}
|
||||
List<PasswordModel> parsePasswordList(List<dynamic> jsonList) {
|
||||
return jsonList.map((json) => PasswordModel.fromJson(json)).toList();
|
||||
}
|
||||
}
|
@ -5,9 +5,9 @@ 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_state.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/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||
|
||||
@ -35,16 +35,15 @@ class AccessManagementPage extends StatelessWidget {
|
||||
.copyWith(color: Colors.white),
|
||||
),
|
||||
],
|
||||
scaffoldBody: BlocProvider(
|
||||
create: (BuildContext context) => AccessBloc()..add(FetchTableData() ),
|
||||
child: BlocConsumer<AccessBloc, AccessState>(
|
||||
listener: (context, state) {
|
||||
scaffoldBody: BlocProvider(create: (BuildContext context) => AccessBloc()..add(FetchTableData()),
|
||||
child: BlocConsumer<AccessBloc, AccessState>(listener: (context, state) {
|
||||
if (state is FailedState) {
|
||||
// CustomSnackBar.displaySnackBar(
|
||||
// state.errorMessage
|
||||
// );
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final accessBloc = BlocProvider.of<AccessBloc>(context);
|
||||
return Container(
|
||||
padding: EdgeInsets.all(30),
|
||||
height: size.height,
|
||||
@ -53,233 +52,294 @@ class AccessManagementPage extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: size.width * 0.3,
|
||||
height: size.height * 0.05,
|
||||
width:size.width * 0.26 ,
|
||||
decoration: containerDecoration,
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Text('All'),
|
||||
Text('To Be Effective (0)'),
|
||||
Text('Effective (0)'),
|
||||
Text('Expired'),
|
||||
],
|
||||
child: Center(
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: BlocProvider.of<AccessBloc>(context).tabs.length,
|
||||
itemBuilder: (context, index) {
|
||||
final isSelected = index ==
|
||||
BlocProvider.of<AccessBloc>(context).selectedIndex;
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
BlocProvider.of<AccessBloc>(context).add(TabChangedEvent(index));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
border: Border.all(
|
||||
color: isSelected ? Colors.blue : Colors.transparent,
|
||||
width: 2.0,),
|
||||
borderRadius: index == 0
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
bottomLeft: Radius.circular(10))
|
||||
: index == 3
|
||||
? const BorderRadius.only(
|
||||
topRight: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10))
|
||||
: null),
|
||||
padding: const EdgeInsets.only(left: 10,right: 10),
|
||||
child: Center(
|
||||
child: Text(
|
||||
BlocProvider.of<AccessBloc>(context).tabs[index],
|
||||
style: TextStyle(
|
||||
color: isSelected
|
||||
? Colors.blue
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Wrap(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text('User Name'),
|
||||
Container(
|
||||
width: size.width*0.15,
|
||||
decoration: containerDecoration,
|
||||
child: TextFormField(
|
||||
decoration: textBoxDecoration()!
|
||||
.copyWith(hintText: 'Please enter'),
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 15,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Email Address'),
|
||||
Container(
|
||||
width: size.width*0.15,
|
||||
decoration: containerDecoration,
|
||||
child: TextFormField(
|
||||
decoration: textBoxDecoration()!
|
||||
.copyWith(hintText: 'Please enter'),
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 15,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Access Time'),
|
||||
Container(
|
||||
width: size.width*0.18,
|
||||
padding: EdgeInsets.all(10),
|
||||
decoration: containerDecoration,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
InkWell(child: Text(BlocProvider.of<AccessBloc>(context).startTime)),
|
||||
const Icon(Icons.arrow_right_alt),
|
||||
InkWell(child: Text(BlocProvider.of<AccessBloc>(context).endTime)),
|
||||
SvgPicture.asset(
|
||||
Assets.calendarIcon,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 15,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Authorization Source'),
|
||||
Container(
|
||||
width: size.width*0.18,
|
||||
decoration: containerDecoration,
|
||||
child: TextFormField(
|
||||
decoration: textBoxDecoration(),
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 15,),
|
||||
SizedBox(
|
||||
width: size.width*0.06,
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(''),
|
||||
const Text('Password Name'),
|
||||
Container(
|
||||
width: size.width * 0.15,
|
||||
decoration: containerDecoration,
|
||||
|
||||
child: DefaultButton(child: Text('Search'),borderRadius: 9)),
|
||||
child: TextFormField(
|
||||
controller: accessBloc.passwordName,
|
||||
style: TextStyle(color: Colors.black),
|
||||
decoration: textBoxDecoration()!
|
||||
.copyWith(hintText: 'Please enter'),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10,),
|
||||
SizedBox(
|
||||
width: size.width*0.06,
|
||||
child: Column(
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(''),
|
||||
const Text('Access Time'),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
backgroundColor: ColorsManager.whiteColors,borderRadius: 9,
|
||||
child: Text('Reset'
|
||||
,style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),)
|
||||
,),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Wrap(children: [
|
||||
Container(
|
||||
width: size.width*0.15,
|
||||
decoration: containerDecoration,
|
||||
child: const DefaultButton(
|
||||
borderRadius: 8,
|
||||
child: Text('+ Create Visitor Password ')),
|
||||
),
|
||||
const SizedBox(width: 10,),
|
||||
Container(
|
||||
width: size.width*0.12,
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
borderRadius: 8,
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
child: Text('Admin Password'
|
||||
,style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),)
|
||||
))
|
||||
],),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Expanded(
|
||||
child:state is TableLoaded?
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
Container(
|
||||
width: size.width,
|
||||
height:size.height ,
|
||||
width: size.width * 0.25,
|
||||
padding: EdgeInsets.all(10),
|
||||
decoration: containerDecoration,
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
Container(
|
||||
color: ColorsManager.boxColor,
|
||||
child: Row(
|
||||
children: [
|
||||
_buildTableHeaderCell('Access User'),
|
||||
_buildTableHeaderCell('Access Type'),
|
||||
_buildTableHeaderCell('Access Period'),
|
||||
_buildTableHeaderCell('Accessible Device'),
|
||||
_buildTableHeaderCell('Authorization Source'),
|
||||
_buildTableHeaderCell('Authorizer'),
|
||||
_buildTableHeaderCell('Authorization Time'),
|
||||
_buildTableHeaderCell('Access Status'),
|
||||
_buildTableHeaderCell('Actions'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: size.width,
|
||||
color: ColorsManager.whiteColors,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Column(
|
||||
children: state.data.map((item) {
|
||||
return Row(
|
||||
children: [
|
||||
_buildTableCell(item.accessUser),
|
||||
_buildTableCell(item.accessType),
|
||||
_buildTableCell(item.accessPeriod),
|
||||
_buildTableCell(item.accessibleDevice),
|
||||
_buildTableCell(item.authorizationSource),
|
||||
_buildTableCell(item.authorizer),
|
||||
_buildTableCell(item.authorizationTime),
|
||||
_buildTableCell(item.accessStatus),
|
||||
_buildTableCell(item.actions),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
Row(
|
||||
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(
|
||||
width: 15,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: size.width * 0.06,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(''),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
accessBloc.add(FilterDataEvent(
|
||||
passwordName: accessBloc.passwordName.text,
|
||||
startTime: accessBloc.effectiveTimeTimeStamp,
|
||||
endTime: accessBloc.expirationTimeTimeStamp
|
||||
));
|
||||
}, borderRadius: 9,
|
||||
child: const Text('Search'))),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.06,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(''),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
accessBloc.add(ResetSearch());
|
||||
},
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
borderRadius: 9,
|
||||
child: Text(
|
||||
'Reset',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.black),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
):const Center(child: CircularProgressIndicator())
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: size.width * 0.15,
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return const VisitorPasswordDialog();
|
||||
},
|
||||
);
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text('+ Create Visitor Password ')),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
width: size.width * 0.12,
|
||||
decoration: containerDecoration,
|
||||
child: DefaultButton(
|
||||
borderRadius: 8,
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
child: Text(
|
||||
'Admin Password',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.black),
|
||||
)))
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: state is TableLoaded
|
||||
? TableWidget(size, state,accessBloc)
|
||||
: const Center(child: CircularProgressIndicator()))
|
||||
],
|
||||
),
|
||||
);
|
||||
})));
|
||||
}
|
||||
|
||||
Container TableWidget(Size size, TableLoaded state,AccessBloc accessBloc) {
|
||||
return Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
Container(
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
color: ColorsManager.boxColor,
|
||||
child: Row(
|
||||
children: [
|
||||
_buildTableHeaderCell('Password name'),
|
||||
_buildTableHeaderCell(' Password Type'),
|
||||
_buildTableHeaderCell('Start Time'),
|
||||
_buildTableHeaderCell('End Time'),
|
||||
_buildTableHeaderCell('Device Id'),
|
||||
// _buildTableHeaderCell('Authorization Source'),
|
||||
// _buildTableHeaderCell('Authorizer'),
|
||||
_buildTableHeaderCell('Password Created'),
|
||||
// _buildTableHeaderCell('Access Status'),
|
||||
_buildTableHeaderCell('Password Status'),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: size.width,
|
||||
color: ColorsManager.whiteColors,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Column(
|
||||
children: state.data.map((item) {
|
||||
return Row(
|
||||
children: [
|
||||
_buildTableCell(item.passwodName),
|
||||
_buildTableCell(item.passwordType),
|
||||
|
||||
_buildTableCell(accessBloc.timestampToDateTime(item.effectiveTime).toString()),
|
||||
_buildTableCell(accessBloc.timestampToDateTime(item.invalidTime).toString()),
|
||||
_buildTableCell(item.deviceUuid.toString()),
|
||||
// _buildTableCell(item.authorizationSource),
|
||||
// _buildTableCell(item.authorizer),
|
||||
_buildTableCell(item.passwordCreated!=null?accessBloc.timestampToDateTime(item.passwordCreated).toString():'no data'),
|
||||
// _buildTableCell(item.accessStatus),
|
||||
_buildTableCell(item.passwordStatus.toString()),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildTableHeaderCell(String title) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border.symmetric(vertical: BorderSide(color: ColorsManager.boxDivider))
|
||||
),
|
||||
border: Border.symmetric(
|
||||
vertical: BorderSide(color: ColorsManager.boxDivider))),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
@ -292,12 +352,21 @@ Widget _buildTableHeaderCell(String title) {
|
||||
Widget _buildTableCell(String content) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
height: 80,
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border.symmetric(horizontal: BorderSide(color: ColorsManager.boxDivider))
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide( // <--- right side
|
||||
color: ColorsManager.boxDivider,
|
||||
width: 1.0,
|
||||
),
|
||||
)
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(content,style: TextStyle(color: Colors.black,fontSize: 12),),
|
||||
child: Text(
|
||||
content,
|
||||
style: TextStyle(color: Colors.black, fontSize: 12),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
13
lib/pages/visitor_password/bloc/visitor_password_bloc.dart
Normal file
13
lib/pages/visitor_password/bloc/visitor_password_bloc.dart
Normal file
@ -0,0 +1,13 @@
|
||||
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_state.dart';
|
||||
|
||||
// Define the BLoC
|
||||
class VisitorPasswordBloc extends Bloc<VisitorPasswordEvent, VisitorPasswordState> {
|
||||
VisitorPasswordBloc() : super(VisitorPasswordInitial()) {
|
||||
on<SelectPasswordType>((event, emit) {
|
||||
// Handle the event and emit the new state
|
||||
emit(PasswordTypeSelected(event.type));
|
||||
});
|
||||
}
|
||||
}
|
23
lib/pages/visitor_password/bloc/visitor_password_event.dart
Normal file
23
lib/pages/visitor_password/bloc/visitor_password_event.dart
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class VisitorPasswordEvent extends Equatable {
|
||||
const VisitorPasswordEvent(
|
||||
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class SelectPasswordType extends VisitorPasswordEvent {
|
||||
final String type;
|
||||
|
||||
const SelectPasswordType(this.type);
|
||||
|
||||
@override
|
||||
List<Object> get props => [type];
|
||||
}
|
23
lib/pages/visitor_password/bloc/visitor_password_state.dart
Normal file
23
lib/pages/visitor_password/bloc/visitor_password_state.dart
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class VisitorPasswordState extends Equatable {
|
||||
const VisitorPasswordState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class VisitorPasswordInitial extends VisitorPasswordState {}
|
||||
|
||||
|
||||
|
||||
class PasswordTypeSelected extends VisitorPasswordState {
|
||||
final String selectedType;
|
||||
|
||||
PasswordTypeSelected(this.selectedType);
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedType];
|
||||
}
|
290
lib/pages/visitor_password/view/visitor_password_dialog.dart
Normal file
290
lib/pages/visitor_password/view/visitor_password_dialog.dart
Normal file
@ -0,0 +1,290 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_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_state.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class VisitorPasswordDialog extends StatelessWidget {
|
||||
const VisitorPasswordDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) => VisitorPasswordBloc(),
|
||||
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
builder: (context, state) {
|
||||
return AlertDialog(
|
||||
title: const Text('Create visitor password'),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
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
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
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
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Type'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: Text('Offline Password'),
|
||||
value: 'Offline Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
|
||||
child: RadioListTile<String>(
|
||||
title: Text('Online Password'),
|
||||
value: 'Online Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
|
||||
child: RadioListTile<String>(
|
||||
title: Text('Dynamic Password'),
|
||||
value: 'Dynamic Password',
|
||||
groupValue: (state is PasswordTypeSelected)
|
||||
? state.selectedType
|
||||
: 'Offline Password',
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Usage Frequency'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('One-Time'),
|
||||
value: 'One-Time',
|
||||
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));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'* ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Colors.red),
|
||||
),
|
||||
const Text('Access Period'),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: RadioListTile<String>(
|
||||
title: const Text('One-Time'),
|
||||
value: 'One-Time',
|
||||
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));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Approve'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,36 +1,37 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/access_manag_model.dart';
|
||||
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncrow_web/pages/access_management/model/password_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
class AccessMangApi{
|
||||
|
||||
// Future<List<AccessManagModel>> fetchInfo() async {
|
||||
// final response = await HTTPService().get(
|
||||
// path: '/Users/mohammad/StudioProjects/web_auth/assets/demo.json',
|
||||
// showServerMessage: true,
|
||||
// expectedResponseModel: (json) {
|
||||
// print('fetchInfo=$json');
|
||||
// return (json as List).map((item) => AccessManagModel.fromJson(item)).toList();
|
||||
// },
|
||||
// );
|
||||
// return response;
|
||||
// }
|
||||
|
||||
Future<List<AccessManagModel>> fetchInfo() async {
|
||||
// Load the JSON file
|
||||
final jsonString = await rootBundle.loadString('assets/dome.json');
|
||||
|
||||
// Parse the JSON string
|
||||
final List<dynamic> jsonList = json.decode(jsonString);
|
||||
print('jsonList=${jsonList.runtimeType}');
|
||||
print('jsonList=${jsonList}');
|
||||
// Convert the list of JSON objects to a list of AccessManagModel instances
|
||||
final List<AccessManagModel> accessList = jsonList.map((item) => AccessManagModel.fromJson(item)).toList();
|
||||
|
||||
return accessList;
|
||||
Future<List<PasswordModel>> fetchVisitorPassword() async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.visitorPassword,
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json;
|
||||
print('Password List: $json');
|
||||
List<PasswordModel> passwordList = jsonData.map((jsonItem) {
|
||||
return PasswordModel.fromJson(jsonItem);
|
||||
}).toList();
|
||||
return passwordList;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
debugPrint('Error fetching visitor passwords: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -50,8 +50,7 @@ class AuthenticationAPI {
|
||||
}
|
||||
);
|
||||
return 30;
|
||||
} on DioError catch (e) {
|
||||
|
||||
} on DioException catch (e) {
|
||||
if (e.response != null) {
|
||||
if (e.response!.statusCode == 400) {
|
||||
// Handle 400 Bad Request
|
||||
@ -64,7 +63,6 @@ class AuthenticationAPI {
|
||||
int cooldown = errorData['data']['cooldown'] ?? 1;
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
} else {
|
||||
debugPrint('Error: ${e.response!.statusCode} - ${e.response!.statusMessage}');
|
||||
return 1;
|
||||
@ -73,7 +71,6 @@ class AuthenticationAPI {
|
||||
debugPrint('Error: ${e.message}');
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
} catch (e) {
|
||||
debugPrint('Unexpected Error: $e');
|
||||
return 1;
|
||||
|
@ -9,5 +9,6 @@ abstract class ApiEndpoints {
|
||||
static const String sendOtp = '$baseUrl/authentication/user/send-otp';
|
||||
static const String verifyOtp = '$baseUrl/authentication/user/verify-otp';
|
||||
static const String getRegion = '$baseUrl/region';
|
||||
static const String visitorPassword = '$baseUrl/visitor-password';
|
||||
static const String getUser = '$baseUrl/user/{userUuid}';
|
||||
}
|
||||
|
Reference in New Issue
Block a user