mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-27 06:47:55 +00:00
Merge branch 'dev' of https://github.com/SyncrowIOT/syncrow-app into feat/refactor
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class EnergyConsumptionPage extends StatefulWidget {
|
||||
final List<dynamic> chartData;
|
||||
final double totalConsumption;
|
||||
final String date;
|
||||
|
||||
EnergyConsumptionPage({
|
||||
required this.chartData,
|
||||
required this.totalConsumption,
|
||||
required this.date,
|
||||
});
|
||||
|
||||
@override
|
||||
_EnergyConsumptionPageState createState() => _EnergyConsumptionPageState();
|
||||
}
|
||||
|
||||
class _EnergyConsumptionPageState extends State<EnergyConsumptionPage> {
|
||||
late List<dynamic> _chartData;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_chartData = widget.chartData;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 19),
|
||||
child: LineChart(
|
||||
LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
handleBuiltInTouches: true,
|
||||
touchSpotThreshold: 2,
|
||||
getTouchLineEnd: (barData, spotIndex) {
|
||||
return 10.0;
|
||||
},
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
getTooltipColor: (touchTooltipItem) => Colors.white,
|
||||
tooltipRoundedRadius: 10.0,
|
||||
tooltipPadding: const EdgeInsets.all(8.0),
|
||||
tooltipBorder: BorderSide(color: Colors.grey, width: 1),
|
||||
getTooltipItems: (List<LineBarSpot> touchedSpots) {
|
||||
return touchedSpots.map((spot) {
|
||||
return LineTooltipItem(
|
||||
'${spot.x},\n ${spot.y.toStringAsFixed(2)} kWh',
|
||||
const TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
)),
|
||||
titlesData: FlTitlesData(
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
),
|
||||
),
|
||||
leftTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
),
|
||||
),
|
||||
rightTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
),
|
||||
),
|
||||
topTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 70,
|
||||
getTitlesWidget: (value, meta) {
|
||||
int index = value.toInt();
|
||||
if (index >= 0 && index < _chartData.length) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: RotatedBox(
|
||||
quarterTurns: -1,
|
||||
child: Text(_chartData[index].time,
|
||||
style: TextStyle(fontSize: 10)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
drawVerticalLine: true,
|
||||
horizontalInterval: 1,
|
||||
verticalInterval: 1,
|
||||
getDrawingVerticalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
dashArray: [8, 8],
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
dashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
drawHorizontalLine: false,
|
||||
),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
preventCurveOvershootingThreshold: 0.1,
|
||||
curveSmoothness: 0.5,
|
||||
preventCurveOverShooting: true,
|
||||
aboveBarData: BarAreaData(),
|
||||
spots: _chartData
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => FlSpot(
|
||||
entry.key.toDouble(), entry.value.consumption))
|
||||
.toList(),
|
||||
isCurved: true,
|
||||
color: ColorsManager.chart.withOpacity(0.6),
|
||||
show: true,
|
||||
shadow: Shadow(color: Colors.black12),
|
||||
belowBarData: BarAreaData(
|
||||
show: true,
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
ColorsManager.chart.withOpacity(0.5),
|
||||
Colors.blue.withOpacity(0.1),
|
||||
],
|
||||
begin: Alignment.center,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
dotData: FlDotData(
|
||||
show: false,
|
||||
),
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 2,
|
||||
),
|
||||
],
|
||||
borderData: FlBorderData(
|
||||
show: false,
|
||||
border: Border.all(
|
||||
color: Color(0xff023DFE).withOpacity(0.7),
|
||||
width: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EnergyData {
|
||||
EnergyData(this.time, this.consumption);
|
||||
final String time;
|
||||
final double consumption;
|
||||
}
|
||||
//
|
||||
@@ -0,0 +1,239 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_info_card.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'power_chart.dart';
|
||||
|
||||
class PowerClampCard extends StatelessWidget {
|
||||
final bool? isGeneral;
|
||||
final String? title;
|
||||
final String? totalCurrent;
|
||||
final String? totalActiveGeneral;
|
||||
final String? totalCurrentGeneral;
|
||||
final String? totalFrequencyGeneral;
|
||||
final String? totalVoltage;
|
||||
final String? totalActive;
|
||||
final String? totalFrequency;
|
||||
final String? dateTimeSelected;
|
||||
final String? totalFactor;
|
||||
final Widget? dateSwitcher;
|
||||
final String? formattedDate;
|
||||
final String? phaseType;
|
||||
|
||||
final String? energyConsumption;
|
||||
final Function()? selectDateEvent;
|
||||
final List<EnergyData>? chartData;
|
||||
final BuildContext? context;
|
||||
|
||||
const PowerClampCard({
|
||||
Key? key,
|
||||
this.isGeneral,
|
||||
this.title,
|
||||
this.totalCurrent,
|
||||
this.totalActiveGeneral,
|
||||
this.dateTimeSelected,
|
||||
this.totalCurrentGeneral,
|
||||
this.totalFrequencyGeneral,
|
||||
this.totalVoltage,
|
||||
this.phaseType,
|
||||
this.totalActive,
|
||||
this.totalFrequency,
|
||||
this.totalFactor,
|
||||
this.dateSwitcher,
|
||||
this.formattedDate,
|
||||
this.selectDateEvent,
|
||||
this.chartData,
|
||||
this.context,
|
||||
this.energyConsumption,
|
||||
//nConsumption
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultContainer(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 5, right: 5, top: 10, bottom: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text('Energy usage'),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: title!,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: energyConsumption!,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
const BodySmall(text: 'kWh')
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
isGeneral == true
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.powerActiveIcon,
|
||||
title: 'Active',
|
||||
value: '$totalActiveGeneral',
|
||||
unit: ' w',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.voltMeterIcon,
|
||||
title: 'Current',
|
||||
value: '$totalCurrentGeneral',
|
||||
unit: ' A',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.frequencyIcon,
|
||||
title: 'Frequency',
|
||||
value: '$totalFrequencyGeneral',
|
||||
unit: ' Hz',
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.voltageIcon,
|
||||
title: 'Voltage',
|
||||
value: '${double.parse(totalVoltage!) / 10}',
|
||||
unit: ' V',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.voltMeterIcon,
|
||||
title: 'Current',
|
||||
value: '$totalCurrent',
|
||||
unit: ' A',
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.powerActiveIcon,
|
||||
title: 'Active Power',
|
||||
value: '$totalActive',
|
||||
unit: ' w',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.speedoMeter,
|
||||
title: 'Power Factor',
|
||||
value: '$totalFactor',
|
||||
unit: '',
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: isGeneral == true
|
||||
? 'Total consumption'
|
||||
: phaseType!,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Text(
|
||||
dateTimeSelected!,
|
||||
style: const TextStyle(
|
||||
fontSize: 8, fontWeight: FontWeight.w400),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Row(
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: '1000.00 ',
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700),
|
||||
BodyMedium(
|
||||
text: 'kWh',
|
||||
fontSize: 8,
|
||||
fontWeight: FontWeight.w700),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
child: EnergyConsumptionPage(
|
||||
chartData: chartData!.isNotEmpty
|
||||
? chartData!
|
||||
: [
|
||||
EnergyData('12:00 AM', 4.0),
|
||||
EnergyData('01:00 AM', 3.5),
|
||||
EnergyData('02:00 AM', 3.8),
|
||||
EnergyData('03:00 AM', 3.2),
|
||||
EnergyData('04:00 AM', 4.0),
|
||||
EnergyData('05:00 AM', 3.4),
|
||||
EnergyData('06:00 AM', 3.2),
|
||||
EnergyData('07:00 AM', 3.5),
|
||||
EnergyData('08:00 AM', 3.8),
|
||||
EnergyData('09:00 AM', 3.6),
|
||||
EnergyData('10:00 AM', 3.9),
|
||||
EnergyData('11:00 AM', 4.0),
|
||||
],
|
||||
totalConsumption: chartData!
|
||||
.fold(0, (sum, data) => sum + data.consumption),
|
||||
date: '10/08/2024',
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
DefaultContainer(
|
||||
padding: EdgeInsets.all(0),
|
||||
color: ColorsManager.grayBox,
|
||||
child: SizedBox(
|
||||
child: dateSwitcher,
|
||||
)),
|
||||
InkWell(
|
||||
onTap: selectDateEvent,
|
||||
child: DefaultContainer(
|
||||
color: ColorsManager.grayBox,
|
||||
child: SizedBox(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Text(formattedDate!),
|
||||
),
|
||||
)),
|
||||
),
|
||||
],
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class PowerClampPage extends StatefulWidget {
|
||||
final DeviceModel? device;
|
||||
|
||||
const PowerClampPage({super.key, this.device});
|
||||
|
||||
@override
|
||||
State<PowerClampPage> createState() => _PowerClampPageState();
|
||||
}
|
||||
|
||||
class _PowerClampPageState extends State<PowerClampPage> {
|
||||
final PageController _pageController = PageController();
|
||||
int _currentPage = 0;
|
||||
static const int _pageCount = 4;
|
||||
late PowerClampModel model;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_pageController.addListener(_handlePageChange);
|
||||
model = _initialPowerClampModel();
|
||||
}
|
||||
|
||||
void _handlePageChange() {
|
||||
int nextPage = _pageController.page?.round() ?? 0;
|
||||
if (_currentPage != nextPage) {
|
||||
setState(() {
|
||||
_currentPage = nextPage;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.removeListener(_handlePageChange);
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Power Clamp',
|
||||
child: BlocProvider(
|
||||
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
|
||||
..add(const PowerClampInitial()),
|
||||
child: BlocBuilder<PowerClampBloc, PowerClampState>(
|
||||
builder: (context, state) {
|
||||
final blocProvider = context.read<PowerClampBloc>();
|
||||
List<EnergyData> chartData = [];
|
||||
|
||||
if (state is UpdateState) {
|
||||
model = state.powerClampModel;
|
||||
} else if (state is EnergyDataState) {
|
||||
chartData = state.energyData;
|
||||
} else if (state is FilterRecordsState) {
|
||||
chartData = state.filteredRecords;
|
||||
}
|
||||
|
||||
if (state is PowerClampLoadingState) {
|
||||
return const Center(
|
||||
child: DefaultContainer(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Flexible(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
blocProvider.add(const PowerClampInitial());
|
||||
},
|
||||
child: PageView(controller: _pageController, children: [
|
||||
_buildPowerClampCard(
|
||||
phaseType: '',
|
||||
title: 'Total Energy \nConsumption',
|
||||
phase: model.status.general,
|
||||
isGeneral: true,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
title: 'Phase A Energy \nConsumption',
|
||||
phaseType: 'Phase A consumption',
|
||||
phase: model.status.phaseA,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
title: 'Phase B Energy \nConsumption',
|
||||
phaseType: 'Phase B consumption',
|
||||
phase: model.status.phaseB,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
title: 'Phase C Energy \nConsumption',
|
||||
phaseType: 'Phase C consumption',
|
||||
phase: model.status.phaseC,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
_buildPageIndicator(),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
PowerClampModel _initialPowerClampModel() {
|
||||
return PowerClampModel(
|
||||
productType: '',
|
||||
productUuid: '',
|
||||
status: PowerStatus(
|
||||
phaseA: Phase(dataPoints: _emptyDataPoints()),
|
||||
phaseB: Phase(dataPoints: _emptyDataPoints()),
|
||||
phaseC: Phase(dataPoints: _emptyDataPoints()),
|
||||
general: Phase(dataPoints: _emptyDataPoints()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<DataPoint> _emptyDataPoints() {
|
||||
return [
|
||||
DataPoint(
|
||||
code: '',
|
||||
customName: '',
|
||||
dpId: 0,
|
||||
time: 0,
|
||||
type: '',
|
||||
value: 0,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildPowerClampCards(PowerClampModel model,
|
||||
List<EnergyData> chartData, PowerClampBloc blocProvider) {
|
||||
return [
|
||||
_buildPowerClampCard(
|
||||
phaseType: '',
|
||||
title: 'Total Energy \nConsumption',
|
||||
phase: model.status.general,
|
||||
isGeneral: true,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase A consumption',
|
||||
title: 'Phase A Energy \nConsumption',
|
||||
phase: model.status.phaseA,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase B consumption',
|
||||
title: 'Phase B Energy \nConsumption',
|
||||
phase: model.status.phaseB,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
_buildPowerClampCard(
|
||||
phaseType: 'Phase C consumption',
|
||||
title: 'Phase C Energy \nConsumption',
|
||||
phase: model.status.phaseC,
|
||||
chartData: chartData,
|
||||
blocProvider: blocProvider,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _buildPowerClampCard({
|
||||
required String title,
|
||||
required String phaseType,
|
||||
required Phase phase,
|
||||
bool isGeneral = false,
|
||||
required List<EnergyData> chartData,
|
||||
required PowerClampBloc blocProvider,
|
||||
}) {
|
||||
return PowerClampCard(
|
||||
dateTimeSelected:
|
||||
'${blocProvider.dateTime!.day}/${blocProvider.dateTime!.month}/${blocProvider.dateTime!.year} ${blocProvider.endChartDate}',
|
||||
energyConsumption: _getValueOrNA(phase.dataPoints, isGeneral ? 0 : 5),
|
||||
title: title,
|
||||
phaseType: phaseType,
|
||||
isGeneral: isGeneral,
|
||||
dateSwitcher: blocProvider.dateSwitcher(),
|
||||
formattedDate: blocProvider.formattedDate,
|
||||
selectDateEvent: () {
|
||||
blocProvider.add(SelectDateEvent(context: context));
|
||||
},
|
||||
totalActiveGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||
totalCurrentGeneral:
|
||||
isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||
totalFrequencyGeneral:
|
||||
isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
|
||||
totalFactor: !isGeneral ? _getValueOrNA(phase.dataPoints, 3) : null,
|
||||
totalActive: !isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||
totalCurrent: !isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||
totalVoltage: !isGeneral ? _getValueOrNA(phase.dataPoints, 0) : null,
|
||||
chartData: chartData,
|
||||
context: context,
|
||||
);
|
||||
}
|
||||
|
||||
String _getValueOrNA(List<DataPoint> dataPoints, int index) {
|
||||
return dataPoints.length > index
|
||||
? dataPoints[index].value.toString()
|
||||
: 'N/A';
|
||||
}
|
||||
|
||||
Widget _buildPageIndicator() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(_pageCount, (index) {
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
height: 10.0,
|
||||
width: _currentPage == index ? 10.0 : 10.0,
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
_currentPage == index ? Colors.grey : ColorsManager.greyColor,
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_bloc.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
|
||||
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
|
||||
// import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
// import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
|
||||
// import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
|
||||
// import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
|
||||
// import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
// import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
// class PowerClampTestPage extends StatefulWidget {
|
||||
// late final DeviceModel? device;
|
||||
|
||||
// PowerClampTestPage({super.key, this.device});
|
||||
|
||||
// @override
|
||||
// _PowerClampTestPageState createState() => _PowerClampTestPageState();
|
||||
// }
|
||||
|
||||
// class _PowerClampTestPageState extends State<PowerClampTestPage> {
|
||||
// final PageController _pageController = PageController();
|
||||
// int _currentPage = 0;
|
||||
// final int _pageCount = 4;
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// _pageController.addListener(() {
|
||||
// int nextPage = _pageController.page?.round() ?? 0;
|
||||
// if (_currentPage != nextPage) {
|
||||
// setState(() {
|
||||
// _currentPage = nextPage;
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// @override
|
||||
// void dispose() {
|
||||
// _pageController.dispose();
|
||||
// super.dispose();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return DefaultScaffold(
|
||||
// title: 'Power Clamp',
|
||||
// child: BlocProvider(
|
||||
// create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
|
||||
// ..add(const PowerClampInitial()),
|
||||
// child: BlocBuilder<PowerClampBloc, PowerClampState>(
|
||||
// builder: (context, state) {
|
||||
// final _blocProvider = BlocProvider.of<PowerClampBloc>(context);
|
||||
// PowerClampModel model = PowerClampModel(
|
||||
// productType: '',
|
||||
// productUuid: '',
|
||||
// status: PowerStatus(
|
||||
// phaseA: Phase(
|
||||
// dataPoints: [
|
||||
// DataPoint(
|
||||
// code: '',
|
||||
// customName: '',
|
||||
// dpId: 0,
|
||||
// time: 0,
|
||||
// type: '',
|
||||
// value: 0),
|
||||
// ],
|
||||
// ),
|
||||
// phaseB: Phase(
|
||||
// dataPoints: [
|
||||
// DataPoint(
|
||||
// code: '',
|
||||
// customName: '',
|
||||
// dpId: 0,
|
||||
// time: 0,
|
||||
// type: '',
|
||||
// value: 0),
|
||||
// ],
|
||||
// ),
|
||||
// phaseC: Phase(
|
||||
// dataPoints: [
|
||||
// DataPoint(
|
||||
// code: '',
|
||||
// customName: '',
|
||||
// dpId: 0,
|
||||
// time: 0,
|
||||
// type: '',
|
||||
// value: 0),
|
||||
// ],
|
||||
// ),
|
||||
// general: Phase(
|
||||
// dataPoints: [
|
||||
// DataPoint(
|
||||
// code: '',
|
||||
// customName: '',
|
||||
// dpId: 0,
|
||||
// time: 0,
|
||||
// type: '',
|
||||
// value: 0),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// List<EnergyData> chartData = [];
|
||||
|
||||
// if (state is UpdateState) {
|
||||
// model = state.powerClampModel;
|
||||
// } else if (state is EnergyDataState) {
|
||||
// chartData = state.energyData;
|
||||
// }
|
||||
// return state is PowerClampLoadingState
|
||||
// ? const Center(
|
||||
// child: DefaultContainer(
|
||||
// width: 50,
|
||||
// height: 50,
|
||||
// child: CircularProgressIndicator()),
|
||||
// )
|
||||
// : Column(
|
||||
// children: [
|
||||
// Flexible(
|
||||
// child: RefreshIndicator(
|
||||
// onRefresh: () async {
|
||||
// _blocProvider.add(const PowerClampInitial());
|
||||
// },
|
||||
// child: PageView(
|
||||
// controller: _pageController,
|
||||
// children: [
|
||||
// PowerClampCard(
|
||||
// energyConsumption:
|
||||
// model.status.general.dataPoints.length > 0
|
||||
// ? model.status.general.dataPoints[0].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// title: 'Total Energy \nConsumption',
|
||||
// isGeneral: true,
|
||||
// dateSwitcher: Container(),
|
||||
// formattedDate: _blocProvider.formattedDate,
|
||||
// selectDateEvent: () {
|
||||
// _blocProvider.add(
|
||||
// SelectDateEvent(context: context));
|
||||
// },
|
||||
// totalFrequencyGeneral:
|
||||
// model.status.general.dataPoints.length > 4
|
||||
// ? model.status.general.dataPoints[4].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalActiveGeneral:
|
||||
// model.status.general.dataPoints.length > 2
|
||||
// ? model.status.general.dataPoints[2].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalCurrentGeneral:
|
||||
// model.status.general.dataPoints.length > 1
|
||||
// ? model.status.general.dataPoints[1].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalVoltage:
|
||||
// model.status.general.dataPoints.length > 0
|
||||
// ? model.status.general.dataPoints[0].value.toString()
|
||||
// : 'N/A',
|
||||
// chartData: chartData,
|
||||
// context: context),
|
||||
|
||||
|
||||
|
||||
// PowerClampCard(
|
||||
// energyConsumption:
|
||||
// model.status.phaseA.dataPoints.length > 5
|
||||
// ? model.status.phaseA.dataPoints[5].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// title: 'Phase A Energy \nConsumption',
|
||||
// dateSwitcher: _blocProvider.dateSwitcher(),
|
||||
// formattedDate: _blocProvider.formattedDate,
|
||||
// selectDateEvent: () {
|
||||
// _blocProvider.add(
|
||||
// SelectDateEvent(context: context));
|
||||
// },
|
||||
// totalFactor: model.status.phaseA.dataPoints.length > 3
|
||||
// ? model.status.phaseA.dataPoints[3].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalActive: model.status.phaseA.dataPoints.length > 2
|
||||
// ? model.status.phaseA.dataPoints[2].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalCurrent:
|
||||
// model.status.phaseA.dataPoints.length > 1
|
||||
// ? model.status.phaseA.dataPoints[1]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalVoltage:
|
||||
// model.status.phaseA.dataPoints.length > 0
|
||||
// ? model.status.phaseA.dataPoints[0]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// chartData: chartData,
|
||||
// context: context),
|
||||
|
||||
|
||||
// PowerClampCard(
|
||||
// energyConsumption:
|
||||
// model.status.phaseB.dataPoints.length > 5
|
||||
// ? model.status.phaseB.dataPoints[5].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// title: 'Phase B Energy \nConsumption',
|
||||
// dateSwitcher: _blocProvider.dateSwitcher(),
|
||||
// formattedDate: _blocProvider.formattedDate,
|
||||
// selectDateEvent: () {
|
||||
// _blocProvider.add(
|
||||
// SelectDateEvent(context: context));
|
||||
// },
|
||||
// totalFactor: model.status.phaseA.dataPoints.length > 3
|
||||
// ? model.status.phaseB.dataPoints[3].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalActive: model.status.phaseB.dataPoints.length > 2
|
||||
// ? model.status.phaseB.dataPoints[2].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalCurrent:
|
||||
// model.status.phaseB.dataPoints.length > 1
|
||||
// ? model.status.phaseB.dataPoints[1]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalVoltage:
|
||||
// model.status.phaseB.dataPoints.length > 0
|
||||
// ? model.status.phaseB.dataPoints[0]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// chartData: chartData,
|
||||
// context: context),
|
||||
|
||||
|
||||
// PowerClampCard(
|
||||
// energyConsumption:
|
||||
// model.status.phaseC.dataPoints.length > 5
|
||||
// ? model.status.phaseC.dataPoints[5].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// title: 'Phase A Energy \nConsumption',
|
||||
// dateSwitcher: _blocProvider.dateSwitcher(),
|
||||
// formattedDate: _blocProvider.formattedDate,
|
||||
// selectDateEvent: () {
|
||||
// _blocProvider.add(
|
||||
// SelectDateEvent(context: context));
|
||||
// },
|
||||
// totalFactor: model.status.phaseC.dataPoints.length > 3
|
||||
// ? model.status.phaseC.dataPoints[3].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalActive: model.status.phaseC.dataPoints.length > 2
|
||||
// ? model.status.phaseC.dataPoints[2].value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalCurrent:
|
||||
// model.status.phaseC.dataPoints.length > 1
|
||||
// ? model.status.phaseC.dataPoints[1]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// totalVoltage:
|
||||
// model.status.phaseC.dataPoints.length > 0
|
||||
// ? model.status.phaseC.dataPoints[0]
|
||||
// .value
|
||||
// .toString()
|
||||
// : 'N/A',
|
||||
// chartData: chartData,
|
||||
// context: context),
|
||||
|
||||
// ]),
|
||||
// ),
|
||||
// ),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 10.0),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: List.generate(_pageCount, (index) {
|
||||
// return AnimatedContainer(
|
||||
// duration: const Duration(milliseconds: 300),
|
||||
// margin:
|
||||
// const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
// height: 10.0,
|
||||
// width: _currentPage == index
|
||||
// ? 10.0
|
||||
// : 10.0, // Change width for current page
|
||||
// decoration: BoxDecoration(
|
||||
// color: _currentPage == index
|
||||
// ? Colors
|
||||
// .grey // Use a different color for the active indicator
|
||||
// : ColorsManager.greyColor,
|
||||
// borderRadius: BorderRadius.circular(5.0),
|
||||
// ),
|
||||
// );
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class PowerClampInfoCard extends StatelessWidget {
|
||||
final String iconPath;
|
||||
final String title;
|
||||
final String value;
|
||||
final String unit;
|
||||
|
||||
const PowerClampInfoCard({
|
||||
Key? key,
|
||||
required this.iconPath,
|
||||
required this.title,
|
||||
required this.value,
|
||||
required this.unit,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
color: ColorsManager.grayBox,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: SvgPicture.asset(
|
||||
iconPath,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 8,
|
||||
text: title,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 15,
|
||||
text: value,
|
||||
),
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 8,
|
||||
text: unit,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,108 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class RoomPage extends StatelessWidget {
|
||||
class RoomPage extends StatefulWidget {
|
||||
const RoomPage({super.key, required this.room});
|
||||
|
||||
final SubSpaceModel room;
|
||||
|
||||
@override
|
||||
_RoomPageState createState() => _RoomPageState();
|
||||
}
|
||||
|
||||
class _RoomPageState extends State<RoomPage> {
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
List<dynamic> _filteredDevices = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_filteredDevices = widget.room.devices ?? [];
|
||||
_searchController.addListener(_filterDevices);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.removeListener(_filterDevices);
|
||||
_searchController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _filterDevices() {
|
||||
final query = _searchController.text.toLowerCase();
|
||||
setState(() {
|
||||
_filteredDevices = widget.room.devices!
|
||||
.where((device) => device.type!.toLowerCase().contains(query))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 1.5,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: room.devices!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return RoomPageSwitch(device: room.devices![index]);
|
||||
},
|
||||
),
|
||||
return Column(
|
||||
children: [
|
||||
if (widget.room.devices!.isNotEmpty)
|
||||
TextFormField(
|
||||
controller: _searchController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search',
|
||||
hintStyle: const TextStyle(
|
||||
color: ColorsManager.textGray,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400),
|
||||
prefixIcon: Container(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
margin: const EdgeInsets.all(10.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.searchIcon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
_filteredDevices.isNotEmpty
|
||||
? Expanded(
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 1.5,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
itemCount: _filteredDevices.length,
|
||||
itemBuilder: (context, index) {
|
||||
return RoomPageSwitch(device: _filteredDevices[index]);
|
||||
},
|
||||
),
|
||||
)
|
||||
: widget.room.devices!.isNotEmpty
|
||||
? const Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
'No Results Found',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400),
|
||||
)),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.d
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_touch/three_touch_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_Interface.dart';
|
||||
@@ -171,6 +172,13 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
DoorSensorScreen(device: device)));
|
||||
|
||||
case DeviceType.PC:
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
PowerClampPage(device: device)));
|
||||
|
||||
case DeviceType.OneTouch:
|
||||
Navigator.push(
|
||||
context,
|
||||
|
||||
@@ -40,13 +40,10 @@ class SceneListview extends StatelessWidget {
|
||||
sceneName: scene.name,
|
||||
),
|
||||
);
|
||||
context
|
||||
.read<SmartSceneSelectBloc>()
|
||||
.add(const SmartSceneClearEvent());
|
||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||
FetchSceneTasksEvent(
|
||||
sceneId: scene.id, isAutomation: false));
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||
|
||||
/// the state to set the scene type must be after the fetch
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
@@ -59,11 +56,13 @@ class SceneListview extends StatelessWidget {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Image.asset(
|
||||
child: Image.memory(
|
||||
height: 32,
|
||||
width: 32,
|
||||
Assets.assetsIconsLogo,
|
||||
scene.iconInBytes,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||
height: 32, width: 32, fit: BoxFit.fill, Assets.assetsIconsLogo),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
||||
@@ -13,7 +13,9 @@ import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_wi
|
||||
import 'package:syncrow_app/features/devices/view/widgets/water_heater/wh_wizard.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class WizardPage extends StatelessWidget {
|
||||
final List<DevicesCategoryModel> groupsList;
|
||||
@@ -21,126 +23,212 @@ class WizardPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 1.5,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
shrinkWrap: true,
|
||||
itemCount: groupsList.length,
|
||||
itemBuilder: (_, index) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (groupsList[index].name == 'AC') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const ACsView()));
|
||||
}
|
||||
if (groupsList[index].name == '3G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const ThreeGangWizard()));
|
||||
}
|
||||
if (groupsList[index].name == '2G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const TwoGangWizard()));
|
||||
}
|
||||
if (groupsList[index].name == '1G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const OneGangWizard()));
|
||||
}
|
||||
if (groupsList[index].name == 'WH') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const WHWizard()));
|
||||
}
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
List<DevicesCategoryModel> _filteredGroups = groupsList;
|
||||
|
||||
if (groupsList[index].name == '1GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const OneTouchWizard()));
|
||||
}
|
||||
void _filterGroups(String query) {
|
||||
_filteredGroups = groupsList
|
||||
.where((group) =>
|
||||
group.name!.toLowerCase().contains(query.toLowerCase()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (groupsList[index].name == '2GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const TwoTouchWizard()));
|
||||
}
|
||||
|
||||
if (groupsList[index].name == '3GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const ThreeTouchWizard()));
|
||||
}
|
||||
|
||||
if (groupsList[index].name == 'GD') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const GarageWizard()));
|
||||
}
|
||||
if (groupsList[index].name == 'CUR') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
const CurtainsWizard()));
|
||||
}
|
||||
},
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
groupsList[index].icon!,
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
if (groupsList.isNotEmpty)
|
||||
TextFormField(
|
||||
controller: _searchController,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_filterGroups(value);
|
||||
});
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search',
|
||||
hintStyle: const TextStyle(
|
||||
color: ColorsManager.textGray,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400),
|
||||
prefixIcon: Container(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
margin: const EdgeInsets.all(10.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.searchIcon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
// CustomSwitch(
|
||||
],
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: BodyLarge(
|
||||
text: groupsList[index].name!,
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
height: 0,
|
||||
fontSize: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
),
|
||||
_filteredGroups.isNotEmpty
|
||||
? Expanded(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
GridView.builder(
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 1.5,
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: _filteredGroups.length,
|
||||
itemBuilder: (_, index) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (_filteredGroups[index].name == 'AC') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const ACsView()));
|
||||
}
|
||||
if (_filteredGroups[index].name == '3G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const ThreeGangWizard()));
|
||||
}
|
||||
if (_filteredGroups[index].name == '2G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const TwoGangWizard()));
|
||||
}
|
||||
if (_filteredGroups[index].name == '1G') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const OneGangWizard()));
|
||||
}
|
||||
if (_filteredGroups[index].name == 'WH') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const WHWizard()));
|
||||
}
|
||||
|
||||
if (_filteredGroups[index].name == '1GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const OneTouchWizard()));
|
||||
}
|
||||
|
||||
if (_filteredGroups[index].name == '2GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const TwoTouchWizard()));
|
||||
}
|
||||
|
||||
if (_filteredGroups[index].name == '3GT') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const ThreeTouchWizard()));
|
||||
}
|
||||
|
||||
if (_filteredGroups[index].name == 'GD') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const GarageWizard()));
|
||||
}
|
||||
if (_filteredGroups[index].name == 'CUR') {
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1,
|
||||
animation2) =>
|
||||
const CurtainsWizard()));
|
||||
}
|
||||
},
|
||||
child: DefaultContainer(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
_filteredGroups[index].icon!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
],
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: BodyLarge(
|
||||
text: _filteredGroups[index].name!,
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
height: 0,
|
||||
fontSize: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: const Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
'No Results Found',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user