Compare commits

..

4 Commits

27 changed files with 415 additions and 1400 deletions

View File

@ -12,8 +12,7 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
//Smart Power Clamp //Smart Power Clamp
class SmartPowerDeviceControl extends StatelessWidget class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayout {
with HelperResponsiveLayout {
final String deviceId; final String deviceId;
const SmartPowerDeviceControl({super.key, required this.deviceId}); const SmartPowerDeviceControl({super.key, required this.deviceId});
@ -146,11 +145,8 @@ class SmartPowerDeviceControl extends StatelessWidget
children: [ children: [
IconButton( IconButton(
icon: const Icon(Icons.arrow_left), icon: const Icon(Icons.arrow_left),
onPressed: blocProvider.currentPage <= 0 onPressed: () {
? null blocProvider.add(SmartPowerArrowPressedEvent(-1));
: () {
blocProvider
.add(SmartPowerArrowPressedEvent(-1));
pageController.previousPage( pageController.previousPage(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut, curve: Curves.easeInOut,
@ -169,11 +165,8 @@ class SmartPowerDeviceControl extends StatelessWidget
), ),
IconButton( IconButton(
icon: const Icon(Icons.arrow_right), icon: const Icon(Icons.arrow_right),
onPressed: blocProvider.currentPage >= 3 onPressed: () {
? null blocProvider.add(SmartPowerArrowPressedEvent(1));
: () {
blocProvider
.add(SmartPowerArrowPressedEvent(1));
pageController.nextPage( pageController.nextPage(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut, curve: Curves.easeInOut,
@ -202,8 +195,8 @@ class SmartPowerDeviceControl extends StatelessWidget
blocProvider.add(SelectDateEvent(context: context)); blocProvider.add(SelectDateEvent(context: context));
blocProvider.add(FilterRecordsByDateEvent( blocProvider.add(FilterRecordsByDateEvent(
selectedDate: blocProvider.dateTime!, selectedDate: blocProvider.dateTime!,
viewType: blocProvider viewType:
.views[blocProvider.currentIndex])); blocProvider.views[blocProvider.currentIndex]));
}, },
widget: blocProvider.dateSwitcher(), widget: blocProvider.dateSwitcher(),
chartData: blocProvider.energyDataList.isNotEmpty chartData: blocProvider.energyDataList.isNotEmpty

View File

@ -1,7 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/auth/model/user_model.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_event.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart'; import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_status.dart';
@ -12,8 +14,11 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
class EditUserDialog extends StatefulWidget { class EditUserDialog extends StatefulWidget {
final String? userId; final RolesUserModel? user;
const EditUserDialog({super.key, this.userId}); const EditUserDialog({
super.key,
this.user,
});
@override @override
_EditUserDialogState createState() => _EditUserDialogState(); _EditUserDialogState createState() => _EditUserDialogState();
@ -28,10 +33,11 @@ class _EditUserDialogState extends State<EditUserDialog> {
create: (BuildContext context) => UsersBloc() create: (BuildContext context) => UsersBloc()
// ..add(const LoadCommunityAndSpacesEvent()) // ..add(const LoadCommunityAndSpacesEvent())
..add(const RoleEvent()) ..add(const RoleEvent())
..add(GetUserByIdEvent(uuid: widget.userId)), ..add(GetUserByIdEvent(uuid: widget.user!.uuid)),
child: BlocConsumer<UsersBloc, UsersState>(listener: (context, state) { child: BlocConsumer<UsersBloc, UsersState>(listener: (context, state) {
if (state is SpacesLoadedState) { if (state is SpacesLoadedState) {
BlocProvider.of<UsersBloc>(context).add(GetUserByIdEvent(uuid: widget.userId)); BlocProvider.of<UsersBloc>(context)
.add(GetUserByIdEvent(uuid: widget.user!.uuid));
} }
}, builder: (context, state) { }, builder: (context, state) {
final _blocRole = BlocProvider.of<UsersBloc>(context); final _blocRole = BlocProvider.of<UsersBloc>(context);
@ -39,7 +45,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
return Dialog( return Dialog(
child: Container( child: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20))),
width: 900, width: 900,
child: Column( child: Column(
children: [ children: [
@ -68,7 +75,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
children: [ children: [
_buildStep1Indicator(1, "Basics", _blocRole), _buildStep1Indicator(1, "Basics", _blocRole),
_buildStep2Indicator(2, "Spaces", _blocRole), _buildStep2Indicator(2, "Spaces", _blocRole),
_buildStep3Indicator(3, "Role & Permissions", _blocRole), _buildStep3Indicator(
3, "Role & Permissions", _blocRole),
], ],
), ),
), ),
@ -86,7 +94,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
children: [ children: [
const SizedBox(height: 10), const SizedBox(height: 10),
Expanded( Expanded(
child: _getFormContent(widget.userId), child: _getFormContent(widget.user!),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
], ],
@ -116,13 +124,14 @@ class _EditUserDialogState extends State<EditUserDialog> {
if (currentStep < 3) { if (currentStep < 3) {
currentStep++; currentStep++;
if (currentStep == 2) { if (currentStep == 2) {
_blocRole.add(CheckStepStatus(isEditUser: true)); _blocRole
.add(CheckStepStatus(isEditUser: true));
} else if (currentStep == 3) { } else if (currentStep == 3) {
_blocRole.add(const CheckSpacesStepStatus()); _blocRole.add(const CheckSpacesStepStatus());
} }
} else { } else {
_blocRole _blocRole.add(EditInviteUsers(
.add(EditInviteUsers(context: context, userId: widget.userId!)); context: context, userId: widget.user!.uuid));
} }
}); });
}, },
@ -131,7 +140,8 @@ class _EditUserDialogState extends State<EditUserDialog> {
style: TextStyle( style: TextStyle(
color: (_blocRole.isCompleteSpaces == false || color: (_blocRole.isCompleteSpaces == false ||
_blocRole.isCompleteBasics == false || _blocRole.isCompleteBasics == false ||
_blocRole.isCompleteRolePermissions == false) && _blocRole.isCompleteRolePermissions ==
false) &&
currentStep == 3 currentStep == 3
? ColorsManager.grayColor ? ColorsManager.grayColor
: ColorsManager.secondaryColor), : ColorsManager.secondaryColor),
@ -146,15 +156,15 @@ class _EditUserDialogState extends State<EditUserDialog> {
})); }));
} }
Widget _getFormContent(userid) { Widget _getFormContent(RolesUserModel user) {
switch (currentStep) { switch (currentStep) {
case 1: case 1:
return BasicsView( return BasicsView(
userId: userid, userId: user.uuid,
); );
case 2: case 2:
return SpacesAccessView( return SpacesAccessView(
userId: userid, userId: user.uuid,
); );
case 3: case 3:
return const RolesAndPermission(); return const RolesAndPermission();
@ -166,6 +176,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
int step3 = 0; int step3 = 0;
Widget _buildStep1Indicator(int step, String label, UsersBloc bloc) { Widget _buildStep1Indicator(int step, String label, UsersBloc bloc) {
final isCurrentStep = currentStep == step;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
setState(() { setState(() {
@ -189,7 +200,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
child: Row( child: Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
currentStep == step isCurrentStep
? Assets.currentProcessIcon ? Assets.currentProcessIcon
: bloc.isCompleteBasics == false : bloc.isCompleteBasics == false
? Assets.wrongProcessIcon ? Assets.wrongProcessIcon
@ -204,8 +215,11 @@ class _EditUserDialogState extends State<EditUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: isCurrentStep
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight:
isCurrentStep ? FontWeight.bold : FontWeight.normal,
), ),
), ),
], ],
@ -229,6 +243,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
} }
Widget _buildStep2Indicator(int step, String label, UsersBloc bloc) { Widget _buildStep2Indicator(int step, String label, UsersBloc bloc) {
final isCurrentStep = currentStep == step;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
setState(() { setState(() {
@ -248,7 +263,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
child: Row( child: Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
currentStep == step isCurrentStep
? Assets.currentProcessIcon ? Assets.currentProcessIcon
: bloc.isCompleteSpaces == false : bloc.isCompleteSpaces == false
? Assets.wrongProcessIcon ? Assets.wrongProcessIcon
@ -263,8 +278,11 @@ class _EditUserDialogState extends State<EditUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: isCurrentStep
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight:
isCurrentStep ? FontWeight.bold : FontWeight.normal,
), ),
), ),
], ],
@ -288,6 +306,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
} }
Widget _buildStep3Indicator(int step, String label, UsersBloc bloc) { Widget _buildStep3Indicator(int step, String label, UsersBloc bloc) {
final isCurrentStep = currentStep == step;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
setState(() { setState(() {
@ -306,7 +325,7 @@ class _EditUserDialogState extends State<EditUserDialog> {
child: Row( child: Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
currentStep == step isCurrentStep
? Assets.currentProcessIcon ? Assets.currentProcessIcon
: bloc.isCompleteRolePermissions == false : bloc.isCompleteRolePermissions == false
? Assets.wrongProcessIcon ? Assets.wrongProcessIcon
@ -321,8 +340,11 @@ class _EditUserDialogState extends State<EditUserDialog> {
label, label,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: currentStep == step ? ColorsManager.blackColor : ColorsManager.greyColor, color: isCurrentStep
fontWeight: currentStep == step ? FontWeight.bold : FontWeight.normal, ? ColorsManager.blackColor
: ColorsManager.greyColor,
fontWeight:
isCurrentStep ? FontWeight.bold : FontWeight.normal,
), ),
), ),
], ],

View File

@ -19,6 +19,7 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart'; import 'package:syncrow_web/utils/style.dart';
class UsersPage extends StatelessWidget { class UsersPage extends StatelessWidget {
UsersPage({super.key}); UsersPage({super.key});
@ -451,8 +452,8 @@ class UsersPage extends StatelessWidget {
), ),
Row( Row(
children: [ children: [
user.isEnabled != false if (user.isEnabled != false)
? actionButton( actionButton(
isActive: true, isActive: true,
title: "Edit", title: "Edit",
onTap: () { onTap: () {
@ -463,19 +464,17 @@ class UsersPage extends StatelessWidget {
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
return EditUserDialog( return EditUserDialog(user: user);
userId: user.uuid);
}, },
).then((v) { ).then((v) {
if (v != null) {
if (v != null) { if (v != null) {
_blocRole.add(const GetUsers()); _blocRole.add(const GetUsers());
} }
}
}); });
}, },
) )
: actionButton( else
actionButton(
title: "Edit", title: "Edit",
), ),
actionButton( actionButton(

View File

@ -1,6 +0,0 @@
class SpaceConnectionModel {
final String from;
final String to;
const SpaceConnectionModel({required this.from, required this.to});
}

View File

@ -1,61 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/models/space_connection_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class SpacesConnectionsArrowPainter extends CustomPainter {
final List<SpaceConnectionModel> connections;
final Map<String, Offset> positions;
final double cardWidth = 150.0;
final double cardHeight = 90.0;
final Set<String> highlightedUuids;
SpacesConnectionsArrowPainter({
required this.connections,
required this.positions,
required this.highlightedUuids,
});
@override
void paint(Canvas canvas, Size size) {
for (final connection in connections) {
final isSelected = highlightedUuids.contains(connection.from) ||
highlightedUuids.contains(connection.to);
final paint = Paint()
..color = isSelected
? ColorsManager.blackColor
: ColorsManager.blackColor.withValues(alpha: 0.5)
..strokeWidth = 2.0
..style = PaintingStyle.stroke;
final from = positions[connection.from];
final to = positions[connection.to];
if (from != null && to != null) {
final startPoint =
Offset(from.dx + cardWidth / 2, from.dy + cardHeight - 10);
final endPoint = Offset(to.dx + cardWidth / 2, to.dy);
final path = Path()..moveTo(startPoint.dx, startPoint.dy);
final controlPoint1 = Offset(startPoint.dx, startPoint.dy + 20);
final controlPoint2 = Offset(endPoint.dx, endPoint.dy - 60);
path.cubicTo(controlPoint1.dx, controlPoint1.dy, controlPoint2.dx,
controlPoint2.dy, endPoint.dx, endPoint.dy);
canvas.drawPath(path, paint);
final circlePaint = Paint()
..color = isSelected
? ColorsManager.blackColor
: ColorsManager.blackColor.withValues(alpha: 0.5)
..style = PaintingStyle.fill
..blendMode = BlendMode.srcIn;
canvas.drawCircle(endPoint, 4, circlePaint);
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

View File

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/create_community/presentation/create_community_dialog.dart';
abstract final class SpaceManagementCommunityDialogHelper {
static void showCreateDialog(BuildContext context) {
showDialog<void>(
context: context,
builder: (_) => CreateCommunityDialog(
title: const SelectableText('Community Name'),
onCreateCommunity: (community) {
context.read<CommunitiesBloc>().add(
InsertCommunity(community),
);
context.read<CommunitiesTreeSelectionBloc>().add(
SelectCommunityEvent(community: community),
);
},
),
);
}
}

View File

@ -1,280 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/models/space_connection_model.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/painters/spaces_connections_arrow_painter.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/space_card_widget.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/space_cell.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/community_model.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/space_model.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart';
class CommunityStructureCanvas extends StatefulWidget {
const CommunityStructureCanvas({
required this.community,
required this.selectedSpace,
super.key,
});
final CommunityModel community;
final SpaceModel? selectedSpace;
@override
State<CommunityStructureCanvas> createState() => _CommunityStructureCanvasState();
}
class _CommunityStructureCanvasState extends State<CommunityStructureCanvas>
with SingleTickerProviderStateMixin {
final Map<String, Offset> _positions = {};
final double _cardWidth = 150.0;
final double _cardHeight = 90.0;
final double _horizontalSpacing = 150.0;
final double _verticalSpacing = 120.0;
late TransformationController _transformationController;
late AnimationController _animationController;
@override
void initState() {
_transformationController = TransformationController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 150),
);
super.initState();
}
@override
void didUpdateWidget(covariant CommunityStructureCanvas oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.selectedSpace?.uuid != oldWidget.selectedSpace?.uuid) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
_animateToSpace(widget.selectedSpace);
}
});
}
}
@override
void dispose() {
_transformationController.dispose();
_animationController.dispose();
super.dispose();
}
Set<String> _getAllDescendantUuids(SpaceModel space) {
final uuids = <String>{};
for (final child in space.children) {
uuids.add(child.uuid);
uuids.addAll(_getAllDescendantUuids(child));
}
return uuids;
}
void _runAnimation(Matrix4 target) {
final animation = Matrix4Tween(
begin: _transformationController.value,
end: target,
).animate(_animationController);
void listener() {
_transformationController.value = animation.value;
}
animation.addListener(listener);
_animationController.forward(from: 0).whenCompleteOrCancel(() {
animation.removeListener(listener);
});
}
void _animateToSpace(SpaceModel? space) {
if (space == null) {
_runAnimation(Matrix4.identity());
return;
}
final position = _positions[space.uuid];
if (position == null) return;
const scale = 1.5;
final viewSize = context.size;
if (viewSize == null) return;
final x = -position.dx * scale + (viewSize.width / 2) - (_cardWidth * scale / 2);
final y =
-position.dy * scale + (viewSize.height / 2) - (_cardHeight * scale / 2);
final matrix = Matrix4.identity()
..translate(x, y)
..scale(scale);
_runAnimation(matrix);
}
void _onSpaceTapped(SpaceModel? space) {
context.read<CommunitiesTreeSelectionBloc>().add(
SelectSpaceEvent(community: widget.community, space: space),
);
}
void _resetSelectionAndZoom() {
context.read<CommunitiesTreeSelectionBloc>().add(
SelectSpaceEvent(
community: widget.community,
space: null,
),
);
}
void _calculateLayout(
List<SpaceModel> spaces,
int depth,
Map<int, double> levelXOffset,
) {
for (final space in spaces) {
double childSubtreeWidth = 0;
if (space.children.isNotEmpty) {
_calculateLayout(space.children, depth + 1, levelXOffset);
final firstChildPos = _positions[space.children.first.uuid];
final lastChildPos = _positions[space.children.last.uuid];
if (firstChildPos != null && lastChildPos != null) {
childSubtreeWidth = (lastChildPos.dx + _cardWidth) - firstChildPos.dx;
}
}
final currentX = levelXOffset.putIfAbsent(depth, () => 0.0);
double? x;
if (space.children.isNotEmpty) {
final firstChildPos = _positions[space.children.first.uuid]!;
x = firstChildPos.dx + (childSubtreeWidth - _cardWidth) / 2;
} else {
x = currentX;
}
if (x < currentX) {
final shiftX = currentX - x;
_shiftSubtree(space, shiftX);
final keysToShift = levelXOffset.keys.where((d) => d > depth).toList();
for (final key in keysToShift) {
levelXOffset[key] = levelXOffset[key]! + shiftX;
}
x += shiftX;
}
final y = depth * (_verticalSpacing + _cardHeight);
_positions[space.uuid] = Offset(x, y);
levelXOffset[depth] = x + _cardWidth + _horizontalSpacing;
}
}
void _shiftSubtree(SpaceModel space, double shiftX) {
if (_positions.containsKey(space.uuid)) {
_positions[space.uuid] = _positions[space.uuid]!.translate(shiftX, 0);
}
for (final child in space.children) {
_shiftSubtree(child, shiftX);
}
}
List<Widget> _buildTreeWidgets() {
_positions.clear();
final community = widget.community;
_calculateLayout(community.spaces, 0, {});
final selectedSpace = widget.selectedSpace;
final highlightedUuids = <String>{};
if (selectedSpace != null) {
highlightedUuids.add(selectedSpace.uuid);
highlightedUuids.addAll(_getAllDescendantUuids(selectedSpace));
}
final widgets = <Widget>[];
final connections = <SpaceConnectionModel>[];
_generateWidgets(community.spaces, widgets, connections, highlightedUuids);
return [
CustomPaint(
painter: SpacesConnectionsArrowPainter(
connections: connections,
positions: _positions,
highlightedUuids: highlightedUuids,
),
child: Stack(alignment: AlignmentDirectional.center, children: widgets),
),
];
}
void _generateWidgets(
List<SpaceModel> spaces,
List<Widget> widgets,
List<SpaceConnectionModel> connections,
Set<String> highlightedUuids,
) {
for (final space in spaces) {
final position = _positions[space.uuid];
if (position == null) continue;
final isHighlighted = highlightedUuids.contains(space.uuid);
final hasNoSelectedSpace = widget.selectedSpace == null;
widgets.add(
Positioned(
left: position.dx,
top: position.dy,
width: _cardWidth,
height: _cardHeight,
child: SpaceCardWidget(
buildSpaceContainer: () {
return Opacity(
opacity: hasNoSelectedSpace || isHighlighted ? 1.0 : 0.5,
child: Tooltip(
message: space.spaceName,
preferBelow: false,
child: SpaceCell(
onTap: () => _onSpaceTapped(space),
icon: space.icon,
name: space.spaceName,
),
),
);
},
onTap: () => SpaceDetailsDialogHelper.showCreate(context),
),
),
);
for (final child in space.children) {
connections.add(
SpaceConnectionModel(from: space.uuid, to: child.uuid),
);
}
_generateWidgets(space.children, widgets, connections, highlightedUuids);
}
}
@override
Widget build(BuildContext context) {
final treeWidgets = _buildTreeWidgets();
return InteractiveViewer(
transformationController: _transformationController,
boundaryMargin: EdgeInsets.symmetric(
horizontal: MediaQuery.sizeOf(context).width * 0.3,
vertical: MediaQuery.sizeOf(context).height * 0.3,
),
minScale: 0.5,
maxScale: 3.0,
constrained: false,
child: GestureDetector(
onTap: _resetSelectionAndZoom,
child: SizedBox(
width: MediaQuery.sizeOf(context).width * 5,
height: MediaQuery.sizeOf(context).height * 5,
child: Stack(children: treeWidgets),
),
),
);
}
}

View File

@ -1,50 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class CommunityTemplateCell extends StatelessWidget {
const CommunityTemplateCell({
super.key,
required this.onTap,
required this.title,
});
final void Function() onTap;
final Widget title;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Column(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: AspectRatio(
aspectRatio: 2.0,
child: Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: const BorderSide(
width: 4,
strokeAlign: BorderSide.strokeAlignOutside,
color: ColorsManager.borderColor,
),
borderRadius: BorderRadius.circular(5),
),
),
),
),
),
DefaultTextStyle(
style: context.textTheme.bodyLarge!.copyWith(
color: ColorsManager.blackColor,
),
child: title,
),
],
),
);
}
}

View File

@ -1,43 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CreateSpaceButton extends StatelessWidget {
const CreateSpaceButton({super.key});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => SpaceDetailsDialogHelper.showCreate(context),
child: Container(
height: 60,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.grey.withValues(alpha: 0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
),
],
),
child: Center(
child: Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
color: ColorsManager.boxColor,
shape: BoxShape.circle,
),
child: const Icon(
Icons.add,
color: Colors.blue,
),
),
),
),
);
}
}

View File

@ -1,33 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class PlusButtonWidget extends StatelessWidget {
final Offset offset;
final void Function() onButtonTap;
const PlusButtonWidget({
super.key,
required this.offset,
required this.onButtonTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onButtonTap,
child: Container(
width: 30,
height: 30,
decoration: const BoxDecoration(
color: ColorsManager.spaceColor,
shape: BoxShape.circle,
),
child: const Icon(
Icons.add,
color: ColorsManager.whiteColors,
size: 20,
),
),
);
}
}

View File

@ -1,44 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/plus_button_widget.dart';
class SpaceCardWidget extends StatefulWidget {
final void Function() onTap;
final Widget Function() buildSpaceContainer;
const SpaceCardWidget({
required this.onTap,
required this.buildSpaceContainer,
super.key,
});
@override
State<SpaceCardWidget> createState() => _SpaceCardWidgetState();
}
class _SpaceCardWidgetState extends State<SpaceCardWidget> {
bool isHovered = false;
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => setState(() => isHovered = true),
onExit: (_) => setState(() => isHovered = false),
child: SizedBox(
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
widget.buildSpaceContainer(),
if (isHovered)
Positioned(
bottom: 0,
child: PlusButtonWidget(
offset: Offset.zero,
onButtonTap: widget.onTap,
),
),
],
),
),
);
}
}

View File

@ -1,85 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class SpaceCell extends StatelessWidget {
final String icon;
final String name;
final VoidCallback? onTap;
const SpaceCell({
super.key,
required this.icon,
required this.name,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
width: 150,
height: 70,
decoration: _containerDecoration(),
child: Row(
children: [
_buildIconContainer(),
const SizedBox(width: 10),
Expanded(
child: Text(
name,
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold,
color: ColorsManager.blackColor,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
),
);
}
Widget _buildIconContainer() {
return Container(
width: 40,
height: double.infinity,
decoration: const BoxDecoration(
color: ColorsManager.spaceColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
bottomLeft: Radius.circular(15),
),
),
child: Center(
child: SvgPicture.asset(
icon,
colorFilter: const ColorFilter.mode(
ColorsManager.whiteColors,
BlendMode.srcIn,
),
width: 24,
height: 24,
),
),
);
}
BoxDecoration _containerDecoration() {
return BoxDecoration(
color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: ColorsManager.lightGrayColor.withValues(alpha: 0.5),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
);
}
}

View File

@ -1,8 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/space_management_community_structure.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/space_management_templates_view.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart';
class SpaceManagementBody extends StatelessWidget { class SpaceManagementBody extends StatelessWidget {
@ -10,21 +6,9 @@ class SpaceManagementBody extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return const Row(
children: [ children: [
const SpaceManagementCommunitiesTree(), SpaceManagementCommunitiesTree(),
Expanded(
child: BlocBuilder<CommunitiesTreeSelectionBloc,
CommunitiesTreeSelectionState>(
buildWhen: (previous, current) =>
previous.selectedCommunity != current.selectedCommunity,
builder: (context, state) => Visibility(
visible: state.selectedCommunity == null,
replacement: const SpaceManagementCommunityStructure(),
child: const SpaceManagementTemplatesView(),
),
),
),
], ],
); );
} }

View File

@ -1,27 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/create_space_button.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
class SpaceManagementCommunityStructure extends StatelessWidget {
const SpaceManagementCommunityStructure({super.key});
@override
Widget build(BuildContext context) {
final selectionBloc = context.watch<CommunitiesTreeSelectionBloc>().state;
final selectedCommunity = selectionBloc.selectedCommunity;
final selectedSpace = selectionBloc.selectedSpace;
const spacer = Spacer(flex: 10);
return Visibility(
visible: selectedCommunity!.spaces.isNotEmpty,
replacement: const Row(
children: [spacer, Expanded(child: CreateSpaceButton()), spacer],
),
child: CommunityStructureCanvas(
community: selectedCommunity,
selectedSpace: selectedSpace,
),
);
}
}

View File

@ -1,50 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/shared/helpers/space_management_community_dialog_helper.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/community_template_cell.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class SpaceManagementTemplatesView extends StatelessWidget {
const SpaceManagementTemplatesView({super.key});
@override
Widget build(BuildContext context) {
return ColoredBox(
color: ColorsManager.whiteColors,
child: GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 400,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 2.0,
),
itemCount: _gridItems(context).length,
itemBuilder: (context, index) {
final model = _gridItems(context)[index];
return CommunityTemplateCell(
onTap: model.onTap,
title: model.title,
);
},
),
);
}
List<_CommunityTemplateModel> _gridItems(BuildContext context) {
return [
_CommunityTemplateModel(
title: const Text('Blank'),
onTap: () => SpaceManagementCommunityDialogHelper.showCreateDialog(context),
),
];
}
}
class _CommunityTemplateModel {
final Widget title;
final void Function() onTap;
_CommunityTemplateModel({
required this.title,
required this.onTap,
});
}

View File

@ -32,7 +32,7 @@ class CommunitiesTreeSelectionBloc
) { ) {
emit( emit(
CommunitiesTreeSelectionState( CommunitiesTreeSelectionState(
selectedCommunity: event.community, selectedCommunity: null,
selectedSpace: event.space, selectedSpace: event.space,
), ),
); );

View File

@ -8,7 +8,7 @@ sealed class CommunitiesTreeSelectionEvent extends Equatable {
} }
final class SelectCommunityEvent extends CommunitiesTreeSelectionEvent { final class SelectCommunityEvent extends CommunitiesTreeSelectionEvent {
final CommunityModel community; final CommunityModel? community;
const SelectCommunityEvent({required this.community}); const SelectCommunityEvent({required this.community});
@override @override
@ -17,9 +17,8 @@ final class SelectCommunityEvent extends CommunitiesTreeSelectionEvent {
final class SelectSpaceEvent extends CommunitiesTreeSelectionEvent { final class SelectSpaceEvent extends CommunitiesTreeSelectionEvent {
final SpaceModel? space; final SpaceModel? space;
final CommunityModel community;
const SelectSpaceEvent({required this.space, required this.community}); const SelectSpaceEvent({required this.space});
@override @override
List<Object?> get props => [space]; List<Object?> get props => [space];

View File

@ -30,7 +30,7 @@ class SpaceManagementCommunitiesTreeSpaceTile extends StatelessWidget {
initiallyExpanded: spaceIsExpanded, initiallyExpanded: spaceIsExpanded,
onExpansionChanged: (expanded) {}, onExpansionChanged: (expanded) {},
onItemSelected: () => context.read<CommunitiesTreeSelectionBloc>().add( onItemSelected: () => context.read<CommunitiesTreeSelectionBloc>().add(
SelectSpaceEvent(community: community, space: space), SelectSpaceEvent(space: space),
), ),
children: space.children children: space.children
.map( .map(

View File

@ -1,8 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/shared/helpers/space_management_community_dialog_helper.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/widgets/space_management_sidebar_add_community_button.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/widgets/space_management_sidebar_add_community_button.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/create_community/presentation/create_community_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart'; import 'package:syncrow_web/utils/style.dart';
@ -40,7 +41,7 @@ class SpaceManagementSidebarHeader extends StatelessWidget {
if (isSelected) { if (isSelected) {
_clearSelection(context); _clearSelection(context);
} else { } else {
SpaceManagementCommunityDialogHelper.showCreateDialog(context); _showCreateCommunityDialog(context);
} }
} }
@ -49,4 +50,19 @@ class SpaceManagementSidebarHeader extends StatelessWidget {
const ClearCommunitiesTreeSelectionEvent(), const ClearCommunitiesTreeSelectionEvent(),
); );
} }
void _showCreateCommunityDialog(BuildContext context) => showDialog<void>(
context: context,
builder: (_) => CreateCommunityDialog(
title: const Text('Community Name'),
onCreateCommunity: (community) {
context.read<CommunitiesBloc>().add(
InsertCommunity(community),
);
context.read<CommunitiesTreeSelectionBloc>().add(
SelectCommunityEvent(community: community),
);
},
),
);
} }

View File

@ -53,7 +53,7 @@ class RemoteCreateCommunityService implements CreateCommunityService {
return _defaultErrorMessage; return _defaultErrorMessage;
} }
final error = body['error'] as Map<String, dynamic>?; final error = body['error'] as Map<String, dynamic>?;
final errorMessage = error?['message'] as String? ?? ''; final errorMessage = error?['error'] as String? ?? '';
return errorMessage; return errorMessage;
} }

View File

@ -41,8 +41,11 @@ class CreateCommunityDialog extends StatelessWidget {
); );
onCreateCommunity.call(community); onCreateCommunity.call(community);
break; break;
case CreateCommunityFailure(): case CreateCommunityFailure(:final message):
Navigator.of(context).pop(); Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
break; break;
default: default:
break; break;

View File

@ -1,11 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_details_dialog.dart';
abstract final class SpaceDetailsDialogHelper {
static void showCreate(BuildContext context) {
showDialog<void>(
context: context,
builder: (context) => const SpaceDetailsDialog(),
);
}
}

View File

@ -1,12 +0,0 @@
import 'package:flutter/material.dart';
class SpaceDetailsDialog extends StatelessWidget {
const SpaceDetailsDialog({super.key});
@override
Widget build(BuildContext context) {
return const Dialog(
child: Text('Create Space'),
);
}
}

View File

@ -1,120 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
class AccessTypeRadioGroup extends StatelessWidget {
final String? selectedType;
final String? accessTypeSelected;
final Function(String) onTypeSelected;
final VisitorPasswordBloc visitorBloc;
const AccessTypeRadioGroup({
super.key,
required this.selectedType,
required this.accessTypeSelected,
required this.onTypeSelected,
required this.visitorBloc,
});
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final text = Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 13);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Access Type', style: text),
],
),
const SizedBox(height: 8),
if (size.width < 800)
Column(
children: [
_buildRadioTile(
context,
'Online Password',
selectedType ?? accessTypeSelected,
onTypeSelected,
),
const SizedBox(height: 8),
_buildRadioTile(
context,
'Offline Password',
selectedType ?? accessTypeSelected,
onTypeSelected,
),
],
)
else
Row(
children: [
Expanded(
flex: 2,
child: Row(
children: [
_buildRadioTile(
context,
'Online Password',
selectedType ?? accessTypeSelected,
onTypeSelected,
width: size.width * 0.12,
),
_buildRadioTile(
context,
'Offline Password',
selectedType ?? accessTypeSelected,
onTypeSelected,
width: size.width * 0.12,
),
],
),
),
const Spacer(flex: 2),
],
),
],
);
}
Widget _buildRadioTile(
BuildContext context,
String value,
String? groupValue,
Function(String) onChanged, {
double? width,
}) {
return SizedBox(
width: width,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text(value,
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,
fontSize: 13,
)),
value: value,
groupValue: groupValue,
onChanged: (value) {
if (value != null) {
onChanged(value);
if (value == 'Dynamic Password') {
visitorBloc.usageFrequencySelected = '';
}
}
},
),
);
}
}

View File

@ -1,73 +0,0 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
class NameAndEmailFields extends StatelessWidget {
final TextEditingController nameController;
final TextEditingController emailController;
final String? Function(String?)? nameValidator;
final String? Function(String?)? emailValidator;
const NameAndEmailFields({
super.key,
required this.nameController,
required this.emailController,
required this.nameValidator,
required this.emailValidator,
});
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
child: size.width < 800
? Column(
children: [
CustomWebTextField(
validator: nameValidator,
controller: nameController,
isRequired: true,
textFieldName: 'Name',
description: '',
),
const SizedBox(height: 15),
CustomWebTextField(
validator: emailValidator,
controller: emailController,
isRequired: true,
textFieldName: 'Email Address',
description:
'The password will be sent to the visitors email address.',
),
],
)
: Row(
children: [
Expanded(
flex: 2,
child: CustomWebTextField(
validator: nameValidator,
controller: nameController,
isRequired: true,
textFieldName: 'Name',
description: '',
),
),
const Spacer(),
Expanded(
flex: 2,
child: CustomWebTextField(
validator: emailValidator,
controller: emailController,
isRequired: true,
textFieldName: 'Email Address',
description:
'The password will be sent to the visitors email address.',
),
),
const Spacer(),
],
),
);
}
}

View File

@ -1,91 +0,0 @@
import 'package:flutter/material.dart';
class UsageFrequencyRadioGroup extends StatelessWidget {
final String? selectedFrequency;
final String? usageFrequencySelected;
final Function(String) onFrequencySelected;
const UsageFrequencyRadioGroup({
super.key,
required this.selectedFrequency,
required this.usageFrequencySelected,
required this.onFrequencySelected,
});
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final text = Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 13);
return size.width < 600
? Column(
children: [
_buildRadioTile(
context,
'One-Time',
selectedFrequency ?? usageFrequencySelected,
onFrequencySelected,
text: text,
fullWidth: true,
),
const SizedBox(height: 8),
_buildRadioTile(
context,
'Periodic',
selectedFrequency ?? usageFrequencySelected,
onFrequencySelected,
text: text,
fullWidth: true,
),
],
)
: Row(
children: [
_buildRadioTile(
context,
'One-Time',
selectedFrequency ?? usageFrequencySelected,
onFrequencySelected,
width: size.width * 0.12,
text: text,
),
_buildRadioTile(
context,
'Periodic',
selectedFrequency ?? usageFrequencySelected,
onFrequencySelected,
width: size.width * 0.12,
text: text,
),
],
);
}
Widget _buildRadioTile(
BuildContext context,
String value,
String? groupValue,
Function(String) onChanged, {
double? width,
required TextStyle text,
bool fullWidth = false,
}) {
return SizedBox(
width: fullWidth ? double.infinity : width,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text(value, style: text),
value: value,
groupValue: groupValue,
onChanged: (String? value) {
if (value != null) {
onChanged(value);
}
},
),
);
}
}

View File

@ -9,11 +9,8 @@ import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
import 'package:syncrow_web/pages/visitor_password/view/access_type_radio_group.dart';
import 'package:syncrow_web/pages/visitor_password/view/add_device_dialog.dart'; import 'package:syncrow_web/pages/visitor_password/view/add_device_dialog.dart';
import 'package:syncrow_web/pages/visitor_password/view/repeat_widget.dart'; import 'package:syncrow_web/pages/visitor_password/view/repeat_widget.dart';
import 'package:syncrow_web/pages/visitor_password/view/responsive_fields_row.dart';
import 'package:syncrow_web/pages/visitor_password/view/usage_frequency_radio_group.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/style.dart'; import 'package:syncrow_web/utils/style.dart';
@ -24,10 +21,7 @@ class VisitorPasswordDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
var text = Theme.of(context) var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13);
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 13);
return BlocProvider( return BlocProvider(
create: (context) => VisitorPasswordBloc(), create: (context) => VisitorPasswordBloc(),
child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>( child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>(
@ -41,8 +35,7 @@ class VisitorPasswordDialog extends StatelessWidget {
title: 'Sent Successfully', title: 'Sent Successfully',
widgeta: Column( widgeta: Column(
children: [ children: [
if (visitorBloc if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty)
.passwordStatus!.failedOperations.isNotEmpty)
Column( Column(
children: [ children: [
const Text('Failed Devices'), const Text('Failed Devices'),
@ -52,8 +45,7 @@ class VisitorPasswordDialog extends StatelessWidget {
child: ListView.builder( child: ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
itemCount: visitorBloc itemCount: visitorBloc.passwordStatus!.failedOperations.length,
.passwordStatus!.failedOperations.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Container( return Container(
margin: EdgeInsets.all(5), margin: EdgeInsets.all(5),
@ -61,17 +53,14 @@ class VisitorPasswordDialog extends StatelessWidget {
height: 45, height: 45,
child: Center( child: Center(
child: Text(visitorBloc child: Text(visitorBloc
.passwordStatus! .passwordStatus!.failedOperations[index].deviceUuid)),
.failedOperations[index]
.deviceUuid)),
); );
}, },
), ),
), ),
], ],
), ),
if (visitorBloc if (visitorBloc.passwordStatus!.successOperations.isNotEmpty)
.passwordStatus!.successOperations.isNotEmpty)
Column( Column(
children: [ children: [
const Text('Success Devices'), const Text('Success Devices'),
@ -81,18 +70,15 @@ class VisitorPasswordDialog extends StatelessWidget {
child: ListView.builder( child: ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
itemCount: visitorBloc itemCount: visitorBloc.passwordStatus!.successOperations.length,
.passwordStatus!.successOperations.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Container( return Container(
margin: EdgeInsets.all(5), margin: EdgeInsets.all(5),
decoration: containerDecoration, decoration: containerDecoration,
height: 45, height: 45,
child: Center( child: Center(
child: Text(visitorBloc child: Text(visitorBloc.passwordStatus!
.passwordStatus! .successOperations[index].deviceUuid)),
.successOperations[index]
.deviceUuid)),
); );
}, },
), ),
@ -103,6 +89,7 @@ class VisitorPasswordDialog extends StatelessWidget {
)) ))
.then((v) { .then((v) {
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
}); });
} else if (state is FailedState) { } else if (state is FailedState) {
visitorBloc.stateDialog( visitorBloc.stateDialog(
@ -115,16 +102,15 @@ class VisitorPasswordDialog extends StatelessWidget {
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>( child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
builder: (BuildContext context, VisitorPasswordState state) { builder: (BuildContext context, VisitorPasswordState state) {
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context); final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
bool isRepeat = bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat;
state is IsRepeatState ? state.repeat : visitorBloc.repeat;
return AlertDialog( return AlertDialog(
backgroundColor: Colors.white, backgroundColor: Colors.white,
title: Text( title: Text(
'Create visitor password', 'Create visitor password',
style: Theme.of(context).textTheme.headlineLarge!.copyWith( style: Theme.of(context)
fontWeight: FontWeight.w400, .textTheme
fontSize: 24, .headlineLarge!
color: Colors.black), .copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black),
), ),
content: state is LoadingInitialState content: state is LoadingInitialState
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
@ -135,11 +121,34 @@ class VisitorPasswordDialog extends StatelessWidget {
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
child: ListBody( child: ListBody(
children: <Widget>[ children: <Widget>[
NameAndEmailFields( Container(
nameController: visitorBloc.userNameController, child: Row(
emailController: visitorBloc.emailController, children: [
nameValidator: visitorBloc.validate, Expanded(
emailValidator: visitorBloc.validateEmail, flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validate,
controller: visitorBloc.userNameController,
isRequired: true,
textFieldName: 'Name',
description: '',
),
),
const Spacer(),
Expanded(
flex: 2,
child: CustomWebTextField(
validator: visitorBloc.validateEmail,
controller: visitorBloc.emailController,
isRequired: true,
textFieldName: 'Email Address',
description:
'The password will be sent to the visitors email address.',
),
),
const Spacer(),
],
),
), ),
const SizedBox( const SizedBox(
height: 15, height: 15,
@ -147,40 +156,104 @@ class VisitorPasswordDialog extends StatelessWidget {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AccessTypeRadioGroup( Row(
selectedType: state is PasswordTypeSelected children: [
Text(
'* ',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: Colors.red),
),
Text('Access Type', style: text),
],
),
Row(
children: <Widget>[
Expanded(
flex: 2,
child: Row(
children: [
SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text(
'Online Password',
style: text,
),
value: 'Online Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType ? state.selectedType
: null, : visitorBloc.accessTypeSelected,
accessTypeSelected: onChanged: (String? value) {
visitorBloc.accessTypeSelected, if (value != null) {
onTypeSelected: (value) {
context context
.read<VisitorPasswordBloc>() .read<VisitorPasswordBloc>()
.add(SelectPasswordType(value)); .add(SelectPasswordType(value));
}
}, },
visitorBloc: visitorBloc,
), ),
),
if (visitorBloc.accessTypeSelected == SizedBox(
'Online Password') width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text('Offline Password', style: text),
value: 'Offline Password',
groupValue: (state is PasswordTypeSelected)
? state.selectedType
: visitorBloc.accessTypeSelected,
onChanged: (String? value) {
if (value != null) {
context
.read<VisitorPasswordBloc>()
.add(SelectPasswordType(value));
}
},
),
),
// SizedBox(
// width: size.width * 0.12,
// child: RadioListTile<String>(
// contentPadding: EdgeInsets.zero,
// title: Text(
// 'Dynamic Password',
// style: text,
// ),
// value: 'Dynamic Password',
// groupValue: (state is PasswordTypeSelected)
// ? state.selectedType
// : visitorBloc.accessTypeSelected,
// onChanged: (String? value) {
// if (value != null) {
// context
// .read<VisitorPasswordBloc>()
// .add(SelectPasswordType(value));
// visitorBloc.usageFrequencySelected = '';
// }
// },
// ),
// ),
],
)),
const Spacer(
flex: 2,
),
],
),
if (visitorBloc.accessTypeSelected == 'Online Password')
Text( Text(
'Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password', 'Only currently online devices can be selected. It is recommended to use when the device network is stable, and the system randomly generates a digital password',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme
.bodySmall!
.copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: ColorsManager.grayColor, color: ColorsManager.grayColor,
fontSize: 9), fontSize: 9),
), ),
if (visitorBloc.accessTypeSelected == if (visitorBloc.accessTypeSelected == 'Offline Password')
'Offline Password')
Text( Text(
'Unaffected by the online status of the device, you can select online or offline device, and the system randomly generates a digital password', 'Unaffected by the online status of the device, you can select online or offline device, and the system randomly generates a digital password',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme
.bodySmall!
.copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: ColorsManager.grayColor, color: ColorsManager.grayColor,
fontSize: 9), fontSize: 9),
@ -198,11 +271,9 @@ class VisitorPasswordDialog extends StatelessWidget {
) )
], ],
), ),
if (visitorBloc.accessTypeSelected == visitorBloc.accessTypeSelected == 'Dynamic Password'
'Dynamic Password') ? const SizedBox()
const SizedBox() : Column(
else
Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
@ -220,148 +291,123 @@ class VisitorPasswordDialog extends StatelessWidget {
), ),
], ],
), ),
UsageFrequencyRadioGroup( Row(
selectedFrequency: children: <Widget>[
state is UsageFrequencySelected SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text(
'One-Time',
style: text,
),
value: 'One-Time',
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency ? state.selectedFrequency
: null, : visitorBloc.usageFrequencySelected,
usageFrequencySelected: onChanged: (String? value) {
visitorBloc.usageFrequencySelected, if (value != null) {
onFrequencySelected: (value) {
context context
.read<VisitorPasswordBloc>() .read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value)); .add(SelectUsageFrequency(value));
}
}, },
), ),
),
SizedBox(
width: size.width * 0.12,
child: RadioListTile<String>(
contentPadding: EdgeInsets.zero,
title: Text('Periodic', style: text),
value: 'Periodic',
groupValue: (state is UsageFrequencySelected)
? state.selectedFrequency
: visitorBloc.usageFrequencySelected,
onChanged: (String? value) {
if (value != null) {
context.read<VisitorPasswordBloc>()
.add(SelectUsageFrequency(value));
}
},
),
),
],
),
//One-Time //One-Time
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'One-Time' &&
'One-Time' && visitorBloc.accessTypeSelected == 'Online Password')
visitorBloc.accessTypeSelected ==
'Online Password')
Text( Text(
'Within the validity period, each device can be unlocked only once.', 'Within the validity period, each device can be unlocked only once.',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme color: ColorsManager.grayColor, fontSize: 9),
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontSize: 9),
), ),
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'One-Time' &&
'One-Time' && visitorBloc.accessTypeSelected == 'Offline Password')
visitorBloc.accessTypeSelected ==
'Offline Password')
Text( Text(
'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours', 'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme color: ColorsManager.grayColor, fontSize: 9),
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontSize: 9),
), ),
// Periodic // Periodic
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password')
visitorBloc.accessTypeSelected ==
'Offline Password')
Text( Text(
'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.', 'Within the validity period, there is no limit to the number of times each device can be unlocked, and it should be used at least once within 24 hours after the entry into force.',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme color: ColorsManager.grayColor, fontSize: 9),
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontSize: 9),
), ),
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Online Password')
visitorBloc.accessTypeSelected ==
'Online Password')
Text( Text(
'Within the validity period, there is no limit to the number of times each device can be unlocked.', 'Within the validity period, there is no limit to the number of times each device can be unlocked.',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme color: ColorsManager.grayColor, fontSize: 9),
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontSize: 9),
), ),
], ],
), ),
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),
if ((visitorBloc.usageFrequencySelected != if ((visitorBloc.usageFrequencySelected != 'One-Time' ||
'One-Time' || visitorBloc.accessTypeSelected != 'Offline Password') &&
visitorBloc.accessTypeSelected !=
'Offline Password') &&
(visitorBloc.usageFrequencySelected != '')) (visitorBloc.usageFrequencySelected != ''))
DateTimeWebWidget( DateTimeWebWidget(
isRequired: true, isRequired: true,
title: 'Access Period', title: 'Access Period',
size: size, size: size,
endTime: () { endTime: () {
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.accessTypeSelected == visitorBloc.add(SelectTimeEvent(context: context, isEffective: false));
'Offline Password') {
visitorBloc.add(SelectTimeEvent(
context: context,
isEffective: false));
} else { } else {
visitorBloc.add( visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false, isRepeat: false));
SelectTimeVisitorPassword(
context: context,
isStart: false,
isRepeat: false));
} }
}, },
startTime: () { startTime: () {
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.accessTypeSelected ==
'Offline Password') {
visitorBloc.add(SelectTimeEvent(
context: context,
isEffective: true));
} else {
visitorBloc.add( visitorBloc.add(
SelectTimeVisitorPassword( SelectTimeEvent(context: context, isEffective: true));
context: context, } else {
isStart: true, visitorBloc.add(SelectTimeVisitorPassword(
isRepeat: false)); context: context, isStart: true, isRepeat: false));
} }
}, },
firstString: (visitorBloc firstString: (visitorBloc.usageFrequencySelected ==
.usageFrequencySelected == 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password')
'Periodic' &&
visitorBloc.accessTypeSelected ==
'Offline Password')
? visitorBloc.effectiveTime ? visitorBloc.effectiveTime
: visitorBloc.startTimeAccess : visitorBloc.startTimeAccess.toString(),
.toString(), secondString: (visitorBloc.usageFrequencySelected ==
secondString: (visitorBloc 'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password')
.usageFrequencySelected ==
'Periodic' &&
visitorBloc.accessTypeSelected ==
'Offline Password')
? visitorBloc.expirationTime ? visitorBloc.expirationTime
: visitorBloc.endTimeAccess.toString(), : visitorBloc.endTimeAccess.toString(),
icon: Assets.calendarIcon), icon: Assets.calendarIcon),
const SizedBox( const SizedBox(height: 10,),
height: 10, Text(visitorBloc.accessPeriodValidate,
), style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.red),),
Text(
visitorBloc.accessPeriodValidate,
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: ColorsManager.red),
),
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),
@ -385,10 +431,7 @@ class VisitorPasswordDialog extends StatelessWidget {
), ),
Text( Text(
'Within the validity period, each device can be unlocked only once.', 'Within the validity period, each device can be unlocked only once.',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme
.bodySmall!
.copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: ColorsManager.grayColor, color: ColorsManager.grayColor,
fontSize: 9), fontSize: 9),
@ -396,10 +439,8 @@ class VisitorPasswordDialog extends StatelessWidget {
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Online Password')
visitorBloc.accessTypeSelected ==
'Online Password')
SizedBox( SizedBox(
width: 100, width: 100,
child: Column( child: Column(
@ -410,8 +451,7 @@ class VisitorPasswordDialog extends StatelessWidget {
child: CupertinoSwitch( child: CupertinoSwitch(
value: visitorBloc.repeat, value: visitorBloc.repeat,
onChanged: (value) { onChanged: (value) {
visitorBloc visitorBloc.add(ToggleRepeatEvent());
.add(ToggleRepeatEvent());
}, },
applyTheme: true, applyTheme: true,
), ),
@ -419,16 +459,12 @@ class VisitorPasswordDialog extends StatelessWidget {
], ],
), ),
), ),
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Online Password')
visitorBloc.accessTypeSelected == isRepeat ? const RepeatWidget() : const SizedBox(),
'Online Password')
isRepeat
? const RepeatWidget()
: const SizedBox(),
Container( Container(
decoration: containerDecoration, decoration: containerDecoration,
width: size.width / 6, width: size.width / 9,
child: DefaultButton( child: DefaultButton(
onPressed: () { onPressed: () {
showDialog( showDialog(
@ -436,27 +472,21 @@ class VisitorPasswordDialog extends StatelessWidget {
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
return AddDeviceDialog( return AddDeviceDialog(
selectedDeviceIds: selectedDeviceIds: visitorBloc.selectedDevices,
visitorBloc.selectedDevices,
); );
}, },
).then((listDevice) { ).then((listDevice) {
if (listDevice != null) { if (listDevice != null) {
visitorBloc.selectedDevices = visitorBloc.selectedDevices = listDevice;
listDevice;
} }
}); });
}, },
borderRadius: 8, borderRadius: 8,
child: Text( child: Text(
'+ Add Device', '+ Add Device',
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme
.bodySmall!
.copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: color: ColorsManager.whiteColors,
ColorsManager.whiteColors,
fontSize: 12), fontSize: 12),
), ),
), ),
@ -495,37 +525,30 @@ class VisitorPasswordDialog extends StatelessWidget {
onPressed: () { onPressed: () {
if (visitorBloc.forgetFormKey.currentState!.validate()) { if (visitorBloc.forgetFormKey.currentState!.validate()) {
if (visitorBloc.selectedDevices.isNotEmpty) { if (visitorBloc.selectedDevices.isNotEmpty) {
if (visitorBloc.usageFrequencySelected == if (visitorBloc.usageFrequencySelected == 'One-Time' &&
'One-Time' && visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.accessTypeSelected ==
'Offline Password') {
setPasswordFunction(context, size, visitorBloc); setPasswordFunction(context, size, visitorBloc);
} else if (visitorBloc.usageFrequencySelected == } else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password') {
visitorBloc.accessTypeSelected ==
'Offline Password') {
if (visitorBloc.expirationTime != 'End Time' && if (visitorBloc.expirationTime != 'End Time' &&
visitorBloc.effectiveTime != 'Start Time') { visitorBloc.effectiveTime != 'Start Time' ) {
setPasswordFunction(context, size, visitorBloc); setPasswordFunction(context, size, visitorBloc);
} else { }else{
visitorBloc.stateDialog( visitorBloc.stateDialog(
context: context, context: context,
message: message: 'Please select Access Period to continue',
'Please select Access Period to continue',
title: 'Access Period'); title: 'Access Period');
} }
} else if (visitorBloc.endTimeAccess.toString() != } else if(
'End Time' && visitorBloc.endTimeAccess.toString()!='End Time'
visitorBloc.startTimeAccess.toString() != &&visitorBloc.startTimeAccess.toString()!='Start Time') {
'Start Time') {
if (visitorBloc.effectiveTimeTimeStamp != null && if (visitorBloc.effectiveTimeTimeStamp != null &&
visitorBloc.expirationTimeTimeStamp != null) { visitorBloc.expirationTimeTimeStamp != null) {
if (isRepeat == true) { if (isRepeat == true) {
if (visitorBloc.expirationTime != 'End Time' && if (visitorBloc.expirationTime != 'End Time' &&
visitorBloc.effectiveTime != 'Start Time' && visitorBloc.effectiveTime != 'Start Time' &&
visitorBloc.selectedDays.isNotEmpty) { visitorBloc.selectedDays.isNotEmpty) {
setPasswordFunction( setPasswordFunction(context, size, visitorBloc);
context, size, visitorBloc);
} else { } else {
visitorBloc.stateDialog( visitorBloc.stateDialog(
context: context, context: context,
@ -539,15 +562,13 @@ class VisitorPasswordDialog extends StatelessWidget {
} else { } else {
visitorBloc.stateDialog( visitorBloc.stateDialog(
context: context, context: context,
message: message: 'Please select Access Period to continue',
'Please select Access Period to continue',
title: 'Access Period'); title: 'Access Period');
} }
} else { }else{
visitorBloc.stateDialog( visitorBloc.stateDialog(
context: context, context: context,
message: message: 'Please select Access Period to continue',
'Please select Access Period to continue',
title: 'Access Period'); title: 'Access Period');
} }
} else { } else {
@ -594,8 +615,7 @@ class VisitorPasswordDialog extends StatelessWidget {
content: SizedBox( content: SizedBox(
height: size.height * 0.25, height: size.height * 0.25,
child: Center( child: Center(
child: child: CircularProgressIndicator(), // Display a loading spinner
CircularProgressIndicator(), // Display a loading spinner
), ),
), ),
); );
@ -619,10 +639,7 @@ class VisitorPasswordDialog extends StatelessWidget {
), ),
Text( Text(
'Set Password', 'Set Password',
style: Theme.of(context) style: Theme.of(context).textTheme.headlineLarge!.copyWith(
.textTheme
.headlineLarge!
.copyWith(
fontSize: 30, fontSize: 30,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Colors.black, color: Colors.black,
@ -672,45 +689,37 @@ class VisitorPasswordDialog extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
if (visitorBloc.usageFrequencySelected == 'One-Time' && if (visitorBloc.usageFrequencySelected == 'One-Time' &&
visitorBloc.accessTypeSelected == visitorBloc.accessTypeSelected == 'Online Password') {
'Online Password') {
visitorBloc.add(OnlineOneTimePasswordEvent( visitorBloc.add(OnlineOneTimePasswordEvent(
context: context, context: context,
passwordName: visitorBloc.userNameController.text, passwordName: visitorBloc.userNameController.text,
email: visitorBloc.emailController.text, email: visitorBloc.emailController.text,
)); ));
} else if (visitorBloc.usageFrequencySelected == }
'Periodic' && else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == visitorBloc.accessTypeSelected == 'Online Password') {
'Online Password') {
visitorBloc.add(OnlineMultipleTimePasswordEvent( visitorBloc.add(OnlineMultipleTimePasswordEvent(
passwordName: visitorBloc.userNameController.text, passwordName: visitorBloc.userNameController.text,
email: visitorBloc.emailController.text, email: visitorBloc.emailController.text,
effectiveTime: effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(),
visitorBloc.effectiveTimeTimeStamp.toString(), invalidTime: visitorBloc.expirationTimeTimeStamp.toString(),
invalidTime:
visitorBloc.expirationTimeTimeStamp.toString(),
)); ));
} else if (visitorBloc.usageFrequencySelected == }
'One-Time' && else if (visitorBloc.usageFrequencySelected == 'One-Time' &&
visitorBloc.accessTypeSelected == visitorBloc.accessTypeSelected == 'Offline Password') {
'Offline Password') {
visitorBloc.add(OfflineOneTimePasswordEvent( visitorBloc.add(OfflineOneTimePasswordEvent(
context: context, context: context,
passwordName: visitorBloc.userNameController.text, passwordName: visitorBloc.userNameController.text,
email: visitorBloc.emailController.text, email: visitorBloc.emailController.text,
)); ));
} else if (visitorBloc.usageFrequencySelected == }
'Periodic' && else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
visitorBloc.accessTypeSelected == visitorBloc.accessTypeSelected == 'Offline Password') {
'Offline Password') {
visitorBloc.add(OfflineMultipleTimePasswordEvent( visitorBloc.add(OfflineMultipleTimePasswordEvent(
passwordName: visitorBloc.userNameController.text, passwordName: visitorBloc.userNameController.text,
email: visitorBloc.emailController.text, email: visitorBloc.emailController.text,
effectiveTime: effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(),
visitorBloc.effectiveTimeTimeStamp.toString(), invalidTime: visitorBloc.expirationTimeTimeStamp.toString(),
invalidTime:
visitorBloc.expirationTimeTimeStamp.toString(),
)); ));
} }
}, },