mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 21:24:55 +00:00
Compare commits
14 Commits
SP-1713-Im
...
SP-1474-FE
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a2fb7ffca | |||
| 479aa4a091 | |||
| 03a6c5474b | |||
| 5f30a5a61b | |||
| 0712e6d64b | |||
| 1f82e84115 | |||
| 23c3bf11f9 | |||
| 5201a65a97 | |||
| e4cc5fce50 | |||
| 8dea89db0e | |||
| ad5ada9d55 | |||
| 7172a0e3fb | |||
| 78898968e8 | |||
| 666c64231f |
@ -38,9 +38,9 @@ class RangeOfAqiValue extends Equatable {
|
||||
factory RangeOfAqiValue.fromJson(Map<String, dynamic> json) {
|
||||
return RangeOfAqiValue(
|
||||
type: json['type'] as String,
|
||||
min: (json['min'] as num).toDouble(),
|
||||
average: (json['average'] as num).toDouble(),
|
||||
max: (json['max'] as num).toDouble(),
|
||||
min: (json['min'] as num? ?? 0).toDouble(),
|
||||
average: (json['average'] as num? ?? 0).toDouble(),
|
||||
max: (json['max'] as num? ?? 0).toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -24,11 +24,13 @@ abstract final class FetchAirQualityDataHelper {
|
||||
}) {
|
||||
final date = context.read<AnalyticsDatePickerBloc>().state.monthlyDate;
|
||||
final aqiType = context.read<AirQualityDistributionBloc>().state.selectedAqiType;
|
||||
if (shouldFetchAnalyticsDevices) {
|
||||
loadAnalyticsDevices(
|
||||
context,
|
||||
communityUuid: communityUuid,
|
||||
spaceUuid: spaceUuid,
|
||||
);
|
||||
}
|
||||
loadRangeOfAqi(
|
||||
context,
|
||||
spaceUuid: spaceUuid,
|
||||
|
||||
@ -23,6 +23,7 @@ abstract final class RangeOfAqiChartsHelper {
|
||||
return titlesData.copyWith(
|
||||
bottomTitles: titlesData.bottomTitles.copyWith(
|
||||
sideTitles: titlesData.bottomTitles.sideTitles.copyWith(
|
||||
reservedSize: 36,
|
||||
getTitlesWidget: (value, meta) => Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 20.0),
|
||||
child: Text(
|
||||
@ -40,6 +41,7 @@ abstract final class RangeOfAqiChartsHelper {
|
||||
reservedSize: 70,
|
||||
interval: 50,
|
||||
maxIncluded: false,
|
||||
minIncluded: true,
|
||||
getTitlesWidget: (value, meta) {
|
||||
final text = value >= 300 ? '301+' : value.toInt().toString();
|
||||
return Padding(
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/air_quality_end_side_widget.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart_box.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_legend.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_box.dart';
|
||||
|
||||
class AirQualityView extends StatelessWidget {
|
||||
@ -20,6 +21,10 @@ class AirQualityView extends StatelessWidget {
|
||||
child: Column(
|
||||
spacing: 32,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: height * 0.1,
|
||||
child: const AqiLegend(),
|
||||
),
|
||||
SizedBox(
|
||||
height: height * 1.2,
|
||||
child: const AirQualityEndSideWidget(),
|
||||
@ -40,7 +45,7 @@ class AirQualityView extends StatelessWidget {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: _padding,
|
||||
height: height * 1.1,
|
||||
height: height * 1.2,
|
||||
child: const Column(
|
||||
children: [
|
||||
Expanded(
|
||||
@ -52,8 +57,9 @@ class AirQualityView extends StatelessWidget {
|
||||
child: Column(
|
||||
spacing: 20,
|
||||
children: [
|
||||
Expanded(child: RangeOfAqiChartBox()),
|
||||
Expanded(child: AqiDistributionChartBox()),
|
||||
Expanded(flex: 2, child: AqiLegend()),
|
||||
Expanded(flex: 12, child: RangeOfAqiChartBox()),
|
||||
Expanded(flex: 12, child: AqiDistributionChartBox()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -32,8 +32,13 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
}
|
||||
|
||||
List<BarChartGroupData> _buildBarGroups() {
|
||||
return List.generate(chartData.length, (index) {
|
||||
final data = chartData[index];
|
||||
final groups = <BarChartGroupData>[];
|
||||
for (var i = 0; i < chartData.length; i++) {
|
||||
final data = chartData[i];
|
||||
final isAllZero = data.data.every((d) => d.percentage == 0);
|
||||
if (isAllZero) {
|
||||
continue;
|
||||
}
|
||||
final stackItems = <BarChartRodData>[];
|
||||
double currentY = 0;
|
||||
var isFirstElement = true;
|
||||
@ -56,13 +61,15 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
currentY += percentageData.percentage + _rodStackItemsSpacing;
|
||||
isFirstElement = false;
|
||||
}
|
||||
|
||||
return BarChartGroupData(
|
||||
x: index,
|
||||
groups.add(
|
||||
BarChartGroupData(
|
||||
x: i,
|
||||
barRods: stackItems,
|
||||
groupVertically: true,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
BarTouchData _barTouchData(BuildContext context) {
|
||||
@ -73,6 +80,7 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
color: ColorsManager.semiTransparentBlack,
|
||||
),
|
||||
tooltipRoundedRadius: 16,
|
||||
maxContentWidth: 500,
|
||||
tooltipPadding: const EdgeInsets.all(8),
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
final data = chartData[group.x];
|
||||
@ -81,10 +89,13 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
|
||||
final textStyle = context.textTheme.bodySmall?.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 8,
|
||||
fontSize: 11,
|
||||
);
|
||||
|
||||
for (final percentageData in data.data) {
|
||||
if (percentageData.percentage == 0) {
|
||||
continue;
|
||||
}
|
||||
final percentage = percentageData.percentage.toStringAsFixed(1);
|
||||
final type = percentageData.type[0].toUpperCase() +
|
||||
percentageData.type.substring(1).replaceAll('_', ' ');
|
||||
@ -98,7 +109,7 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
DateFormat('dd/MM/yyyy').format(data.date),
|
||||
context.textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 9,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textAlign: TextAlign.start,
|
||||
@ -118,7 +129,6 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
final leftTitles = titlesData.leftTitles.copyWith(
|
||||
sideTitles: titlesData.leftTitles.sideTitles.copyWith(
|
||||
reservedSize: 70,
|
||||
interval: 20,
|
||||
maxIncluded: false,
|
||||
minIncluded: true,
|
||||
getTitlesWidget: (value, meta) => Padding(
|
||||
@ -140,7 +150,7 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
|
||||
final bottomTitles = AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
showTitles: chartData.isNotEmpty,
|
||||
getTitlesWidget: (value, _) => FittedBox(
|
||||
alignment: AlignmentDirectional.bottomCenter,
|
||||
fit: BoxFit.scaleDown,
|
||||
@ -148,7 +158,7 @@ class AqiDistributionChart extends StatelessWidget {
|
||||
chartData[value.toInt()].date.day.toString(),
|
||||
style: context.textTheme.bodySmall?.copyWith(
|
||||
color: ColorsManager.lightGreyColor,
|
||||
fontSize: 8,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -19,7 +19,7 @@ class AqiDistributionChartTitle extends StatelessWidget {
|
||||
children: [
|
||||
ChartsLoadingWidget(isLoading: isLoading),
|
||||
const Expanded(
|
||||
flex: 3,
|
||||
flex: 4,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
@ -28,7 +28,9 @@ class AqiDistributionChartTitle extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
FittedBox(
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: FittedBox(
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
fit: BoxFit.scaleDown,
|
||||
child: AqiTypeDropdown(
|
||||
@ -47,6 +49,7 @@ class AqiDistributionChartTitle extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/helpers/range_of_aqi_charts_helper.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/chart_informative_cell.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class AqiLegend extends StatelessWidget {
|
||||
const AqiLegend({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsetsDirectional.all(20),
|
||||
decoration: subSectionContainerDecoration.copyWith(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16,
|
||||
children: RangeOfAqiChartsHelper.gradientData.map((e) {
|
||||
return Flexible(
|
||||
flex: 4,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fill,
|
||||
child: ChartInformativeCell(
|
||||
color: e.$1,
|
||||
title: FittedBox(
|
||||
fit: BoxFit.fill,
|
||||
child: Text(e.$2),
|
||||
),
|
||||
height: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -47,19 +47,29 @@ class AqiLocationInfoCell extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional.bottomEnd,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.all(10),
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: 120,
|
||||
alignment: AlignmentDirectional.bottomCenter,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: SvgPicture.asset(
|
||||
svgPath,
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.bottomStart,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.bottomEnd,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.all(10),
|
||||
child: Text(
|
||||
value,
|
||||
style: context.textTheme.bodySmall?.copyWith(
|
||||
color: ColorsManager.vividBlue.withValues(alpha: 0.7),
|
||||
color: ColorsManager.vividBlue.withValues(
|
||||
alpha: 0.7,
|
||||
),
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 24,
|
||||
),
|
||||
@ -67,16 +77,7 @@ class AqiLocationInfoCell extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional.bottomStart,
|
||||
child: SizedBox.square(
|
||||
dimension: MediaQuery.sizeOf(context).width * 0.45,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.bottomStart,
|
||||
child: SvgPicture.asset(svgPath),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -7,16 +7,18 @@ class ChartInformativeCell extends StatelessWidget {
|
||||
required this.title,
|
||||
required this.color,
|
||||
this.hasBorder = false,
|
||||
this.height,
|
||||
});
|
||||
|
||||
final Widget title;
|
||||
final Color color;
|
||||
final bool hasBorder;
|
||||
final double? height;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: MediaQuery.sizeOf(context).height * 0.0385,
|
||||
height: height ?? MediaQuery.sizeOf(context).height * 0.0385,
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 12,
|
||||
|
||||
@ -179,7 +179,10 @@ class _DynamicTableState extends State<DynamicTable> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmptyState() => Column(
|
||||
Widget _buildEmptyState() => Container(
|
||||
height: widget.size.height,
|
||||
color: ColorsManager.whiteColors,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
@ -203,7 +206,9 @@ class _DynamicTableState extends State<DynamicTable> {
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: widget.size.height * 0.5),
|
||||
],
|
||||
),
|
||||
);
|
||||
Widget _buildSelectAllCheckbox() {
|
||||
return Container(
|
||||
|
||||
120
lib/pages/visitor_password/view/access_type_radio_group.dart
Normal file
120
lib/pages/visitor_password/view/access_type_radio_group.dart
Normal file
@ -0,0 +1,120 @@
|
||||
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 = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
73
lib/pages/visitor_password/view/responsive_fields_row.dart
Normal file
73
lib/pages/visitor_password/view/responsive_fields_row.dart
Normal file
@ -0,0 +1,73 @@
|
||||
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 visitor’s 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 visitor’s email address.',
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
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);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -9,8 +9,11 @@ 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_event.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/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/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
@ -21,7 +24,10 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
var text = Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black, fontSize: 13);
|
||||
var text = Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.black, fontSize: 13);
|
||||
return BlocProvider(
|
||||
create: (context) => VisitorPasswordBloc(),
|
||||
child: BlocListener<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
@ -35,7 +41,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
title: 'Sent Successfully',
|
||||
widgeta: Column(
|
||||
children: [
|
||||
if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty)
|
||||
if (visitorBloc
|
||||
.passwordStatus!.failedOperations.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
const Text('Failed Devices'),
|
||||
@ -45,7 +52,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
itemCount: visitorBloc.passwordStatus!.failedOperations.length,
|
||||
itemCount: visitorBloc
|
||||
.passwordStatus!.failedOperations.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.all(5),
|
||||
@ -53,14 +61,17 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
height: 45,
|
||||
child: Center(
|
||||
child: Text(visitorBloc
|
||||
.passwordStatus!.failedOperations[index].deviceUuid)),
|
||||
.passwordStatus!
|
||||
.failedOperations[index]
|
||||
.deviceUuid)),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (visitorBloc.passwordStatus!.successOperations.isNotEmpty)
|
||||
if (visitorBloc
|
||||
.passwordStatus!.successOperations.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
const Text('Success Devices'),
|
||||
@ -70,15 +81,18 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
itemCount: visitorBloc.passwordStatus!.successOperations.length,
|
||||
itemCount: visitorBloc
|
||||
.passwordStatus!.successOperations.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.all(5),
|
||||
decoration: containerDecoration,
|
||||
height: 45,
|
||||
child: Center(
|
||||
child: Text(visitorBloc.passwordStatus!
|
||||
.successOperations[index].deviceUuid)),
|
||||
child: Text(visitorBloc
|
||||
.passwordStatus!
|
||||
.successOperations[index]
|
||||
.deviceUuid)),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -89,7 +103,6 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
))
|
||||
.then((v) {
|
||||
Navigator.of(context).pop(true);
|
||||
|
||||
});
|
||||
} else if (state is FailedState) {
|
||||
visitorBloc.stateDialog(
|
||||
@ -102,15 +115,16 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
builder: (BuildContext context, VisitorPasswordState state) {
|
||||
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||
bool isRepeat = state is IsRepeatState ? state.repeat : visitorBloc.repeat;
|
||||
bool isRepeat =
|
||||
state is IsRepeatState ? state.repeat : visitorBloc.repeat;
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
title: Text(
|
||||
'Create visitor password',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineLarge!
|
||||
.copyWith(fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black),
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 24,
|
||||
color: Colors.black),
|
||||
),
|
||||
content: state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
@ -121,34 +135,11 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
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 visitor’s email address.',
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
NameAndEmailFields(
|
||||
nameController: visitorBloc.userNameController,
|
||||
emailController: visitorBloc.emailController,
|
||||
nameValidator: visitorBloc.validate,
|
||||
emailValidator: visitorBloc.validateEmail,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
@ -156,104 +147,40 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
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)
|
||||
AccessTypeRadioGroup(
|
||||
selectedType: state is PasswordTypeSelected
|
||||
? state.selectedType
|
||||
: visitorBloc.accessTypeSelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
: null,
|
||||
accessTypeSelected:
|
||||
visitorBloc.accessTypeSelected,
|
||||
onTypeSelected: (value) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.add(SelectPasswordType(value));
|
||||
}
|
||||
},
|
||||
visitorBloc: visitorBloc,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
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')
|
||||
|
||||
if (visitorBloc.accessTypeSelected ==
|
||||
'Online Password')
|
||||
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',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
),
|
||||
if (visitorBloc.accessTypeSelected == 'Offline Password')
|
||||
if (visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
Text(
|
||||
'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).textTheme.bodySmall!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
@ -271,9 +198,11 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
)
|
||||
],
|
||||
),
|
||||
visitorBloc.accessTypeSelected == 'Dynamic Password'
|
||||
? const SizedBox()
|
||||
: Column(
|
||||
if (visitorBloc.accessTypeSelected ==
|
||||
'Dynamic Password')
|
||||
const SizedBox()
|
||||
else
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
@ -291,123 +220,148 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
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)
|
||||
UsageFrequencyRadioGroup(
|
||||
selectedFrequency:
|
||||
state is UsageFrequencySelected
|
||||
? state.selectedFrequency
|
||||
: visitorBloc.usageFrequencySelected,
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
: null,
|
||||
usageFrequencySelected:
|
||||
visitorBloc.usageFrequencySelected,
|
||||
onFrequencySelected: (value) {
|
||||
context
|
||||
.read<VisitorPasswordBloc>()
|
||||
.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
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password')
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password')
|
||||
Text(
|
||||
'Within the validity period, each device can be unlocked only once.',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: ColorsManager.grayColor, fontSize: 9),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
),
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password')
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
Text(
|
||||
'Within the validity period, each device can be unlocked only once, and the maximum validity period is 6 hours',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: ColorsManager.grayColor, fontSize: 9),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
),
|
||||
|
||||
// Periodic
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password')
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
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.',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: ColorsManager.grayColor, fontSize: 9),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
),
|
||||
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password')
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password')
|
||||
Text(
|
||||
'Within the validity period, there is no limit to the number of times each device can be unlocked.',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: ColorsManager.grayColor, fontSize: 9),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
if ((visitorBloc.usageFrequencySelected != 'One-Time' ||
|
||||
visitorBloc.accessTypeSelected != 'Offline Password') &&
|
||||
if ((visitorBloc.usageFrequencySelected !=
|
||||
'One-Time' ||
|
||||
visitorBloc.accessTypeSelected !=
|
||||
'Offline Password') &&
|
||||
(visitorBloc.usageFrequencySelected != ''))
|
||||
DateTimeWebWidget(
|
||||
isRequired: true,
|
||||
title: 'Access Period',
|
||||
size: size,
|
||||
endTime: () {
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
visitorBloc.add(SelectTimeEvent(context: context, isEffective: false));
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(SelectTimeEvent(
|
||||
context: context,
|
||||
isEffective: false));
|
||||
} else {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(context: context, isStart: false, isRepeat: false));
|
||||
visitorBloc.add(
|
||||
SelectTimeVisitorPassword(
|
||||
context: context,
|
||||
isStart: false,
|
||||
isRepeat: false));
|
||||
}
|
||||
},
|
||||
startTime: () {
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
visitorBloc.add(
|
||||
SelectTimeEvent(context: context, isEffective: true));
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(SelectTimeEvent(
|
||||
context: context,
|
||||
isEffective: true));
|
||||
} else {
|
||||
visitorBloc.add(SelectTimeVisitorPassword(
|
||||
context: context, isStart: true, isRepeat: false));
|
||||
visitorBloc.add(
|
||||
SelectTimeVisitorPassword(
|
||||
context: context,
|
||||
isStart: true,
|
||||
isRepeat: false));
|
||||
}
|
||||
},
|
||||
firstString: (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password')
|
||||
firstString: (visitorBloc
|
||||
.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
? visitorBloc.effectiveTime
|
||||
: visitorBloc.startTimeAccess.toString(),
|
||||
secondString: (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' && visitorBloc.accessTypeSelected == 'Offline Password')
|
||||
: visitorBloc.startTimeAccess
|
||||
.toString(),
|
||||
secondString: (visitorBloc
|
||||
.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
? visitorBloc.expirationTime
|
||||
: visitorBloc.endTimeAccess.toString(),
|
||||
icon: Assets.calendarIcon),
|
||||
const SizedBox(height: 10,),
|
||||
Text(visitorBloc.accessPeriodValidate,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: ColorsManager.red),),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
visitorBloc.accessPeriodValidate,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
@ -431,7 +385,10 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
Text(
|
||||
'Within the validity period, each device can be unlocked only once.',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 9),
|
||||
@ -439,8 +396,10 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password')
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password')
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Column(
|
||||
@ -451,7 +410,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: CupertinoSwitch(
|
||||
value: visitorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
visitorBloc.add(ToggleRepeatEvent());
|
||||
visitorBloc
|
||||
.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
@ -459,12 +419,16 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password')
|
||||
isRepeat ? const RepeatWidget() : const SizedBox(),
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password')
|
||||
isRepeat
|
||||
? const RepeatWidget()
|
||||
: const SizedBox(),
|
||||
Container(
|
||||
decoration: containerDecoration,
|
||||
width: size.width / 9,
|
||||
width: size.width / 6,
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
@ -472,21 +436,27 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AddDeviceDialog(
|
||||
selectedDeviceIds: visitorBloc.selectedDevices,
|
||||
selectedDeviceIds:
|
||||
visitorBloc.selectedDevices,
|
||||
);
|
||||
},
|
||||
).then((listDevice) {
|
||||
if (listDevice != null) {
|
||||
visitorBloc.selectedDevices = listDevice;
|
||||
visitorBloc.selectedDevices =
|
||||
listDevice;
|
||||
}
|
||||
});
|
||||
},
|
||||
borderRadius: 8,
|
||||
child: Text(
|
||||
'+ Add Device',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.whiteColors,
|
||||
color:
|
||||
ColorsManager.whiteColors,
|
||||
fontSize: 12),
|
||||
),
|
||||
),
|
||||
@ -525,30 +495,37 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
onPressed: () {
|
||||
if (visitorBloc.forgetFormKey.currentState!.validate()) {
|
||||
if (visitorBloc.selectedDevices.isNotEmpty) {
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
} else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
if (visitorBloc.expirationTime != 'End Time' &&
|
||||
visitorBloc.effectiveTime != 'Start Time') {
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message: 'Please select Access Period to continue',
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else if(
|
||||
visitorBloc.endTimeAccess.toString()!='End Time'
|
||||
&&visitorBloc.startTimeAccess.toString()!='Start Time') {
|
||||
} else if (visitorBloc.endTimeAccess.toString() !=
|
||||
'End Time' &&
|
||||
visitorBloc.startTimeAccess.toString() !=
|
||||
'Start Time') {
|
||||
if (visitorBloc.effectiveTimeTimeStamp != null &&
|
||||
visitorBloc.expirationTimeTimeStamp != null) {
|
||||
if (isRepeat == true) {
|
||||
if (visitorBloc.expirationTime != 'End Time' &&
|
||||
visitorBloc.effectiveTime != 'Start Time' &&
|
||||
visitorBloc.selectedDays.isNotEmpty) {
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
setPasswordFunction(
|
||||
context, size, visitorBloc);
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
@ -562,13 +539,15 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message: 'Please select Access Period to continue',
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message: 'Please select Access Period to continue',
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else {
|
||||
@ -615,7 +594,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
content: SizedBox(
|
||||
height: size.height * 0.25,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(), // Display a loading spinner
|
||||
child:
|
||||
CircularProgressIndicator(), // Display a loading spinner
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -639,7 +619,10 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
Text(
|
||||
'Set Password',
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineLarge!
|
||||
.copyWith(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
@ -689,37 +672,45 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password') {
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password') {
|
||||
visitorBloc.add(OnlineOneTimePasswordEvent(
|
||||
context: context,
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
));
|
||||
}
|
||||
else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Online Password') {
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password') {
|
||||
visitorBloc.add(OnlineMultipleTimePasswordEvent(
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(),
|
||||
invalidTime: visitorBloc.expirationTimeTimeStamp.toString(),
|
||||
effectiveTime:
|
||||
visitorBloc.effectiveTimeTimeStamp.toString(),
|
||||
invalidTime:
|
||||
visitorBloc.expirationTimeTimeStamp.toString(),
|
||||
));
|
||||
}
|
||||
else if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(OfflineOneTimePasswordEvent(
|
||||
context: context,
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
));
|
||||
}
|
||||
else if (visitorBloc.usageFrequencySelected == 'Periodic' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(OfflineMultipleTimePasswordEvent(
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
effectiveTime: visitorBloc.effectiveTimeTimeStamp.toString(),
|
||||
invalidTime: visitorBloc.expirationTimeTimeStamp.toString(),
|
||||
effectiveTime:
|
||||
visitorBloc.effectiveTimeTimeStamp.toString(),
|
||||
invalidTime:
|
||||
visitorBloc.expirationTimeTimeStamp.toString(),
|
||||
));
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user