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",
|
"accessUser": "Ali Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01",
|
"startTime": "2023-08-01",
|
||||||
|
"endTime": "2023-08-02",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -12,8 +13,9 @@
|
|||||||
}, {
|
}, {
|
||||||
"accessUser": "oamr Doe",
|
"accessUser": "oamr Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01",
|
"startTime": "2023-08-01",
|
||||||
"accessibleDevice": "Smart Door",
|
"endTime": "2023-08-05",
|
||||||
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
"authorizationTime": "2023-08-01 10:00 AM",
|
"authorizationTime": "2023-08-01 10:00 AM",
|
||||||
@ -22,7 +24,8 @@
|
|||||||
}, {
|
}, {
|
||||||
"accessUser": "John Doe",
|
"accessUser": "John Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01",
|
"startTime": "2023-08-01",
|
||||||
|
"endTime": "2023-08-10",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -34,7 +37,8 @@
|
|||||||
{
|
{
|
||||||
"accessUser": "John Doe",
|
"accessUser": "John Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01",
|
"startTime": "2023-08-01",
|
||||||
|
"endTime": "2023-10-10",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -45,7 +49,8 @@
|
|||||||
{
|
{
|
||||||
"accessUser": "John Doe",
|
"accessUser": "John Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01",
|
"startTime": "2023-03-01",
|
||||||
|
"endTime": "2023-05-10",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -56,7 +61,8 @@
|
|||||||
{
|
{
|
||||||
"accessUser": "John Doe",
|
"accessUser": "John Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01 ",
|
"startTime": "2023-07-01",
|
||||||
|
"endTime": "2023-08-10",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -66,7 +72,8 @@
|
|||||||
}, {
|
}, {
|
||||||
"accessUser": "John Doe",
|
"accessUser": "John Doe",
|
||||||
"accessType": "Admin",
|
"accessType": "Admin",
|
||||||
"accessPeriod": "2023-08-01 ",
|
"startTime": "2023-01-01",
|
||||||
|
"endTime": "2023-09-05",
|
||||||
"accessibleDevice": "Smart Door",
|
"accessibleDevice": "Smart Door",
|
||||||
"authorizationSource": "System",
|
"authorizationSource": "System",
|
||||||
"authorizer": "Jane Smith",
|
"authorizer": "Jane Smith",
|
||||||
@ -77,7 +84,8 @@
|
|||||||
{
|
{
|
||||||
"accessUser": "Alice Johnson",
|
"accessUser": "Alice Johnson",
|
||||||
"accessType": "User",
|
"accessType": "User",
|
||||||
"accessPeriod": "2023-08-01 to 2023-08-31",
|
"startTime": "2023-08-01",
|
||||||
|
"endTime": "2023-08-10",
|
||||||
"accessibleDevice": "Smart Lock",
|
"accessibleDevice": "Smart Lock",
|
||||||
"authorizationSource": "Admin",
|
"authorizationSource": "Admin",
|
||||||
"authorizer": "John Doe",
|
"authorizer": "John Doe",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
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/access_management/view/access_management.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/view/login_page.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/bloc/home_bloc.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/visitor_password/view/visitor_password_dialog.dart';
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.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
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // Set up color scheme
|
||||||
useMaterial3: true, // Enable Material 3
|
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: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_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/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/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> {
|
class AccessBloc extends Bloc<AccessEvent, AccessState> {
|
||||||
AccessBloc() : super((AccessInitial())) {
|
AccessBloc() : super((AccessInitial())) {
|
||||||
on<FetchTableData>(_onFetchTableData);
|
on<FetchTableData>(_onFetchTableData);
|
||||||
|
on<TabChangedEvent>(selectFilterTap);
|
||||||
|
on<SelectTime>(selectTime);
|
||||||
|
on<FilterDataEvent>(_filterData);
|
||||||
|
on<ResetSearch>(resetSearch);
|
||||||
}
|
}
|
||||||
String startTime = 'Start Time';
|
String startTime = 'Start Time';
|
||||||
String endTime = 'End 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(
|
Future<void> _onFetchTableData(
|
||||||
FetchTableData event, Emitter<AccessState> emit) async {
|
FetchTableData event, Emitter<AccessState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(AccessLoaded());
|
emit(AccessLoaded());
|
||||||
List<AccessManagModel> data = await AccessMangApi().fetchInfo();
|
data = await AccessMangApi().fetchVisitorPassword();
|
||||||
print('objectwww888888${data[0].accessPeriod}');
|
emit(TableLoaded(data));
|
||||||
|
|
||||||
emit(TableLoaded(data));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(e.toString()));
|
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:equatable/equatable.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
abstract class AccessEvent extends Equatable {
|
abstract class AccessEvent extends Equatable {
|
||||||
const AccessEvent();
|
const AccessEvent();
|
||||||
@ -8,4 +9,32 @@ abstract class AccessEvent extends Equatable {
|
|||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
class FetchTableData extends AccessEvent {}
|
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: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 {
|
abstract class AccessState extends Equatable {
|
||||||
const AccessState();
|
const AccessState();
|
||||||
@ -21,7 +21,7 @@ class FailedState extends AccessState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TableLoaded extends AccessState {
|
class TableLoaded extends AccessState {
|
||||||
final List<AccessManagModel> data;
|
final List<PasswordModel> data;
|
||||||
|
|
||||||
const TableLoaded(this.data);
|
const TableLoaded(this.data);
|
||||||
|
|
||||||
@ -29,3 +29,12 @@ class TableLoaded extends AccessState {
|
|||||||
List<Object> get props => [data];
|
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_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/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/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/snack_bar.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';
|
||||||
|
|
||||||
@ -35,16 +35,15 @@ class AccessManagementPage extends StatelessWidget {
|
|||||||
.copyWith(color: Colors.white),
|
.copyWith(color: Colors.white),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
scaffoldBody: BlocProvider(
|
scaffoldBody: BlocProvider(create: (BuildContext context) => AccessBloc()..add(FetchTableData()),
|
||||||
create: (BuildContext context) => AccessBloc()..add(FetchTableData() ),
|
child: BlocConsumer<AccessBloc, AccessState>(listener: (context, state) {
|
||||||
child: BlocConsumer<AccessBloc, AccessState>(
|
|
||||||
listener: (context, state) {
|
|
||||||
if (state is FailedState) {
|
if (state is FailedState) {
|
||||||
// CustomSnackBar.displaySnackBar(
|
// CustomSnackBar.displaySnackBar(
|
||||||
// state.errorMessage
|
// state.errorMessage
|
||||||
// );
|
// );
|
||||||
}
|
}
|
||||||
}, builder: (context, state) {
|
}, builder: (context, state) {
|
||||||
|
final accessBloc = BlocProvider.of<AccessBloc>(context);
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.all(30),
|
padding: EdgeInsets.all(30),
|
||||||
height: size.height,
|
height: size.height,
|
||||||
@ -53,233 +52,294 @@ class AccessManagementPage extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: size.width * 0.3,
|
|
||||||
height: size.height * 0.05,
|
height: size.height * 0.05,
|
||||||
|
width:size.width * 0.26 ,
|
||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
child: const Row(
|
child: Center(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
child: ListView.builder(
|
||||||
children: [
|
scrollDirection: Axis.horizontal,
|
||||||
Text('All'),
|
itemCount: BlocProvider.of<AccessBloc>(context).tabs.length,
|
||||||
Text('To Be Effective (0)'),
|
itemBuilder: (context, index) {
|
||||||
Text('Effective (0)'),
|
final isSelected = index ==
|
||||||
Text('Expired'),
|
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(
|
const SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.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: [
|
children: [
|
||||||
Text(''),
|
const Text('Password Name'),
|
||||||
Container(
|
Container(
|
||||||
|
width: size.width * 0.15,
|
||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
|
child: TextFormField(
|
||||||
child: DefaultButton(child: Text('Search'),borderRadius: 9)),
|
controller: accessBloc.passwordName,
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
decoration: textBoxDecoration()!
|
||||||
|
.copyWith(hintText: 'Please enter'),
|
||||||
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(width: 10,),
|
width: 15,
|
||||||
SizedBox(
|
),
|
||||||
width: size.width*0.06,
|
Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(''),
|
const Text('Access Time'),
|
||||||
Container(
|
Container(
|
||||||
decoration: containerDecoration,
|
width: size.width * 0.25,
|
||||||
child: DefaultButton(
|
padding: EdgeInsets.all(10),
|
||||||
backgroundColor: ColorsManager.whiteColors,borderRadius: 9,
|
decoration: containerDecoration,
|
||||||
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 ,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
Row(
|
||||||
Container(
|
mainAxisAlignment:
|
||||||
color: ColorsManager.boxColor,
|
MainAxisAlignment.spaceBetween,
|
||||||
child: Row(
|
children: [
|
||||||
children: [
|
InkWell(
|
||||||
_buildTableHeaderCell('Access User'),
|
onTap: () {
|
||||||
_buildTableHeaderCell('Access Type'),
|
accessBloc.add(SelectTime(context: context, isStart: true));
|
||||||
_buildTableHeaderCell('Access Period'),
|
},
|
||||||
_buildTableHeaderCell('Accessible Device'),
|
child: Text(BlocProvider.of<AccessBloc>(context).startTime)
|
||||||
_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(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
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) {
|
Widget _buildTableHeaderCell(String title) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
border: Border.symmetric(vertical: BorderSide(color: ColorsManager.boxDivider))
|
border: Border.symmetric(
|
||||||
),
|
vertical: BorderSide(color: ColorsManager.boxDivider))),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@ -292,12 +352,21 @@ Widget _buildTableHeaderCell(String title) {
|
|||||||
Widget _buildTableCell(String content) {
|
Widget _buildTableCell(String content) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
height: 80,
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.symmetric(horizontal: BorderSide(color: ColorsManager.boxDivider))
|
border: Border(
|
||||||
|
bottom: BorderSide( // <--- right side
|
||||||
|
color: ColorsManager.boxDivider,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
alignment: Alignment.centerLeft,
|
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 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/model/access_manag_model.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:syncrow_web/pages/auth/model/user_model.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/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
|
|
||||||
class AccessMangApi{
|
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
|
Future<List<PasswordModel>> fetchVisitorPassword() async {
|
||||||
final List<dynamic> jsonList = json.decode(jsonString);
|
try {
|
||||||
print('jsonList=${jsonList.runtimeType}');
|
final response = await HTTPService().get(
|
||||||
print('jsonList=${jsonList}');
|
path: ApiEndpoints.visitorPassword,
|
||||||
// Convert the list of JSON objects to a list of AccessManagModel instances
|
showServerMessage: true,
|
||||||
final List<AccessManagModel> accessList = jsonList.map((item) => AccessManagModel.fromJson(item)).toList();
|
expectedResponseModel: (json) {
|
||||||
|
List<dynamic> jsonData = json;
|
||||||
return accessList;
|
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;
|
return 30;
|
||||||
} on DioError catch (e) {
|
} on DioException catch (e) {
|
||||||
|
|
||||||
if (e.response != null) {
|
if (e.response != null) {
|
||||||
if (e.response!.statusCode == 400) {
|
if (e.response!.statusCode == 400) {
|
||||||
// Handle 400 Bad Request
|
// Handle 400 Bad Request
|
||||||
@ -64,7 +63,6 @@ class AuthenticationAPI {
|
|||||||
int cooldown = errorData['data']['cooldown'] ?? 1;
|
int cooldown = errorData['data']['cooldown'] ?? 1;
|
||||||
return cooldown;
|
return cooldown;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
debugPrint('Error: ${e.response!.statusCode} - ${e.response!.statusMessage}');
|
debugPrint('Error: ${e.response!.statusCode} - ${e.response!.statusMessage}');
|
||||||
return 1;
|
return 1;
|
||||||
@ -73,7 +71,6 @@ class AuthenticationAPI {
|
|||||||
debugPrint('Error: ${e.message}');
|
debugPrint('Error: ${e.message}');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Unexpected Error: $e');
|
debugPrint('Unexpected Error: $e');
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -9,5 +9,6 @@ abstract class ApiEndpoints {
|
|||||||
static const String sendOtp = '$baseUrl/authentication/user/send-otp';
|
static const String sendOtp = '$baseUrl/authentication/user/send-otp';
|
||||||
static const String verifyOtp = '$baseUrl/authentication/user/verify-otp';
|
static const String verifyOtp = '$baseUrl/authentication/user/verify-otp';
|
||||||
static const String getRegion = '$baseUrl/region';
|
static const String getRegion = '$baseUrl/region';
|
||||||
|
static const String visitorPassword = '$baseUrl/visitor-password';
|
||||||
static const String getUser = '$baseUrl/user/{userUuid}';
|
static const String getUser = '$baseUrl/user/{userUuid}';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user