mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-23 11:47:57 +00:00
added devices
This commit is contained in:
@@ -1,59 +1,97 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class StatefulTextField extends StatefulWidget {
|
||||
const StatefulTextField(
|
||||
{super.key,
|
||||
required this.title,
|
||||
this.hintText = 'Please enter',
|
||||
required this.width,
|
||||
this.elevation = 0,
|
||||
required this.controller,
|
||||
this.onSubmitted});
|
||||
const StatefulTextField({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.hintText = 'Please enter',
|
||||
required this.width,
|
||||
this.elevation,
|
||||
required this.controller,
|
||||
this.onSubmitted,
|
||||
this.boxDecoration,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.padding,
|
||||
this.icon,
|
||||
this.hintColor,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String hintText;
|
||||
final double width;
|
||||
final double elevation;
|
||||
final double? elevation;
|
||||
final TextEditingController controller;
|
||||
final Function? onSubmitted;
|
||||
final BoxDecoration? boxDecoration;
|
||||
final double? borderRadius;
|
||||
final double? height;
|
||||
final double? padding;
|
||||
final IconData? icon;
|
||||
final Color? hintColor;
|
||||
|
||||
@override
|
||||
State<StatefulTextField> createState() => _StatefulTextFieldState();
|
||||
}
|
||||
|
||||
class _StatefulTextFieldState extends State<StatefulTextField> {
|
||||
@override
|
||||
void dispose() {
|
||||
widget.controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: CustomTextField(
|
||||
title: widget.title,
|
||||
controller: widget.controller,
|
||||
hintText: widget.hintText,
|
||||
width: widget.width,
|
||||
elevation: widget.elevation,
|
||||
onSubmittedFun: widget.onSubmitted),
|
||||
return CustomTextField(
|
||||
title: widget.title,
|
||||
controller: widget.controller,
|
||||
hintText: widget.hintText,
|
||||
width: widget.width,
|
||||
elevation: widget.elevation,
|
||||
onSubmittedFun: widget.onSubmitted,
|
||||
boxDecoration: widget.boxDecoration,
|
||||
borderRadius: widget.borderRadius,
|
||||
height: widget.height,
|
||||
padding: widget.padding,
|
||||
icon: widget.icon,
|
||||
hintColor: widget.hintColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTextField extends StatelessWidget {
|
||||
const CustomTextField(
|
||||
{super.key,
|
||||
required this.title,
|
||||
required this.controller,
|
||||
this.hintText = 'Please enter',
|
||||
required this.width,
|
||||
this.elevation = 0,
|
||||
this.onSubmittedFun});
|
||||
const CustomTextField({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.controller,
|
||||
this.hintText = 'Please enter',
|
||||
required this.width,
|
||||
this.elevation,
|
||||
this.onSubmittedFun,
|
||||
this.boxDecoration,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.padding,
|
||||
this.icon,
|
||||
this.hintColor,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final double width;
|
||||
final double elevation;
|
||||
final double? elevation;
|
||||
final Function? onSubmittedFun;
|
||||
final BoxDecoration? boxDecoration;
|
||||
final double? borderRadius;
|
||||
final double? height;
|
||||
final double? padding;
|
||||
final IconData? icon;
|
||||
final Color? hintColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -71,26 +109,21 @@ class CustomTextField extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Material(
|
||||
elevation: elevation,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
elevation: elevation ?? 0,
|
||||
borderRadius: BorderRadius.circular(borderRadius ?? 8),
|
||||
child: Container(
|
||||
width: width,
|
||||
height: 45,
|
||||
decoration: containerDecoration,
|
||||
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// ),
|
||||
height: height ?? 45,
|
||||
decoration: boxDecoration ?? containerDecoration,
|
||||
child: TextFormField(
|
||||
controller: controller,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
hintStyle: const TextStyle(fontSize: 12),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
hintStyle: TextStyle(fontSize: 12, color: hintColor ?? ColorsManager.blackColor),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: padding ?? 10),
|
||||
border: InputBorder.none,
|
||||
suffixIcon: icon != null ? Icon(icon, color: ColorsManager.greyColor) : null,
|
||||
),
|
||||
onFieldSubmitted: (_) {
|
||||
onSubmittedFun!();
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_spa
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/enum/device_types.dart';
|
||||
|
||||
class AllDevicesModel {
|
||||
/*
|
||||
@@ -100,12 +101,8 @@ class AllDevicesModel {
|
||||
this.spaces,
|
||||
});
|
||||
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
||||
room = (json['room'] != null && (json['room'] is Map))
|
||||
? DevicesModelRoom.fromJson(json['room'])
|
||||
: null;
|
||||
unit = (json['unit'] != null && (json['unit'] is Map))
|
||||
? DevicesModelUnit.fromJson(json['unit'])
|
||||
: null;
|
||||
room = (json['room'] != null && (json['room'] is Map)) ? DevicesModelRoom.fromJson(json['room']) : null;
|
||||
unit = (json['unit'] != null && (json['unit'] is Map)) ? DevicesModelUnit.fromJson(json['unit']) : null;
|
||||
community = (json['community'] != null && (json['community'] is Map))
|
||||
? DeviceCommunityModel.fromJson(json['community'])
|
||||
: null;
|
||||
@@ -117,7 +114,7 @@ class AllDevicesModel {
|
||||
categoryName = json['categoryName']?.toString();
|
||||
createTime = int.tryParse(json['createTime']?.toString() ?? '');
|
||||
gatewayId = json['gatewayId']?.toString();
|
||||
icon = json['icon'] ?? _getDefaultIcon(productType);
|
||||
icon = json['icon'] ?? getDefaultIcon(productType);
|
||||
ip = json['ip']?.toString();
|
||||
lat = json['lat']?.toString();
|
||||
localKey = json['localKey']?.toString();
|
||||
@@ -134,38 +131,88 @@ class AllDevicesModel {
|
||||
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
||||
productName = json['productName']?.toString();
|
||||
if (json['spaces'] != null && json['spaces'] is List) {
|
||||
spaces = (json['spaces'] as List)
|
||||
.map((space) => DeviceSpaceModel.fromJson(space))
|
||||
.toList();
|
||||
spaces = (json['spaces'] as List).map((space) => DeviceSpaceModel.fromJson(space)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
String _getDefaultIcon(String? productType) {
|
||||
switch (productType) {
|
||||
case 'LightBulb':
|
||||
return Assets.lightBulb;
|
||||
case 'CeilingSensor':
|
||||
case 'WallSensor':
|
||||
return Assets.sensors;
|
||||
case 'AC':
|
||||
return Assets.ac;
|
||||
case 'DoorLock':
|
||||
return Assets.doorLock;
|
||||
case 'Curtain':
|
||||
return Assets.curtain;
|
||||
case '3G':
|
||||
case '2G':
|
||||
case '1G':
|
||||
return Assets.gangSwitch;
|
||||
case 'Gateway':
|
||||
return Assets.gateway;
|
||||
case 'WH':
|
||||
return Assets.blackLogo;
|
||||
case 'DS':
|
||||
return Assets.sensors;
|
||||
default:
|
||||
return Assets.logo;
|
||||
String getDefaultIcon(String? productType) {
|
||||
/*
|
||||
AC
|
||||
GD
|
||||
3G
|
||||
3G
|
||||
GW
|
||||
DL
|
||||
WPS
|
||||
CPS
|
||||
AC
|
||||
CPS
|
||||
WPS
|
||||
GW
|
||||
AC
|
||||
CUR
|
||||
DS
|
||||
1GT
|
||||
2GT
|
||||
3GT
|
||||
1G
|
||||
1G
|
||||
2G
|
||||
2G
|
||||
DS
|
||||
WH
|
||||
1GT
|
||||
2GT
|
||||
3GT
|
||||
GD
|
||||
WL
|
||||
WL
|
||||
3G
|
||||
CUR
|
||||
GW
|
||||
PC
|
||||
PC
|
||||
SOS
|
||||
|
||||
*/
|
||||
DeviceType type = devicesTypesMap[productType] ?? DeviceType.Other;
|
||||
String tempIcon = '';
|
||||
if (type == DeviceType.LightBulb) {
|
||||
tempIcon = Assets.lightBulb;
|
||||
} else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
|
||||
tempIcon = Assets.sensors;
|
||||
} else if (type == DeviceType.AC) {
|
||||
tempIcon = Assets.ac;
|
||||
} else if (type == DeviceType.DoorLock) {
|
||||
tempIcon = Assets.doorLock;
|
||||
} else if (type == DeviceType.Curtain) {
|
||||
tempIcon = Assets.curtain;
|
||||
} else if (type == DeviceType.ThreeGang) {
|
||||
tempIcon = Assets.gangSwitch;
|
||||
} else if (type == DeviceType.Gateway) {
|
||||
tempIcon = Assets.gateway;
|
||||
} else if (type == DeviceType.OneGang) {
|
||||
tempIcon = Assets.oneGang;
|
||||
} else if (type == DeviceType.TwoGang) {
|
||||
tempIcon = Assets.twoGang;
|
||||
} else if (type == DeviceType.WH) {
|
||||
tempIcon = Assets.waterHeater;
|
||||
} else if (type == DeviceType.DS) {
|
||||
// tempIcon = Assets.mainDoor;
|
||||
} else if (type == DeviceType.OneTouch) {
|
||||
// tempIcon = Assets.oneGang;
|
||||
} else if (type == DeviceType.TowTouch) {
|
||||
// tempIcon = Assets.twoGang;
|
||||
} else if (type == DeviceType.GarageDoor) {
|
||||
//tempIcon = Assets.;
|
||||
} else if (type == DeviceType.ThreeTouch) {
|
||||
// tempIcon = Assets.gang3touch;
|
||||
} else if (type == DeviceType.WaterLeak) {
|
||||
tempIcon = Assets.waterLeakNormal;
|
||||
} else {
|
||||
tempIcon = Assets.logoHorizontal;
|
||||
}
|
||||
return tempIcon;
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@@ -271,4 +318,23 @@ class AllDevicesModel {
|
||||
productName.hashCode ^
|
||||
batteryLevel.hashCode;
|
||||
}
|
||||
|
||||
Map<String, DeviceType> devicesTypesMap = {
|
||||
"AC": DeviceType.AC,
|
||||
"GW": DeviceType.Gateway,
|
||||
"CPS": DeviceType.CeilingSensor,
|
||||
"DL": DeviceType.DoorLock,
|
||||
"WPS": DeviceType.WallSensor,
|
||||
"3G": DeviceType.ThreeGang,
|
||||
"2G": DeviceType.TwoGang,
|
||||
"1G": DeviceType.OneGang,
|
||||
"CUR": DeviceType.Curtain,
|
||||
"WH": DeviceType.WH,
|
||||
"DS": DeviceType.DS,
|
||||
"1GT": DeviceType.OneTouch,
|
||||
"2GT": DeviceType.TowTouch,
|
||||
"3GT": DeviceType.ThreeTouch,
|
||||
"GD": DeviceType.GarageDoor,
|
||||
"WL": DeviceType.WaterLeak,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_managment_body.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/routines_view.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
@@ -76,29 +74,30 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
||||
);
|
||||
}),
|
||||
rightBody: const NavigateHomeGridView(),
|
||||
scaffoldBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(builder: (context, state) {
|
||||
if (state is SelectedTabState && state.selectedTab) {
|
||||
return const RoutinesView();
|
||||
}
|
||||
if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
||||
return const CreateNewRoutineView();
|
||||
}
|
||||
|
||||
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
builder: (context, deviceState) {
|
||||
if (deviceState is DeviceManagementLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (deviceState is DeviceManagementLoaded || deviceState is DeviceManagementFiltered) {
|
||||
final devices =
|
||||
(deviceState as dynamic).devices ?? (deviceState as DeviceManagementFiltered).filteredDevices;
|
||||
|
||||
return DeviceManagementBody(devices: devices);
|
||||
} else {
|
||||
return const Center(child: Text('Error fetching Devices'));
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
scaffoldBody: CreateNewRoutineView(),
|
||||
// BlocBuilder<SwitchTabsBloc, SwitchTabsState>(builder: (context, state) {
|
||||
// if (state is SelectedTabState && state.selectedTab) {
|
||||
// return const RoutinesView();
|
||||
// }
|
||||
// if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
||||
// return const CreateNewRoutineView();
|
||||
// }
|
||||
//
|
||||
// return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
// builder: (context, deviceState) {
|
||||
// if (deviceState is DeviceManagementLoading) {
|
||||
// return const Center(child: CircularProgressIndicator());
|
||||
// } else if (deviceState is DeviceManagementLoaded || deviceState is DeviceManagementFiltered) {
|
||||
// final devices =
|
||||
// (deviceState as dynamic).devices ?? (deviceState as DeviceManagementFiltered).filteredDevices;
|
||||
//
|
||||
// return DeviceManagementBody(devices: devices);
|
||||
// } else {
|
||||
// return const Center(child: Text('Error fetching Devices'));
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
// }),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'routine_event.dart';
|
||||
part 'routine_state.dart';
|
||||
|
||||
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
RoutineBloc() : super(RoutineInitial()) {
|
||||
on<RoutineEvent>((event, emit) {
|
||||
// TODO: implement event handler
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
part of 'routine_bloc.dart';
|
||||
|
||||
@immutable
|
||||
sealed class RoutineEvent {}
|
||||
@@ -0,0 +1,6 @@
|
||||
part of 'routine_bloc.dart';
|
||||
|
||||
@immutable
|
||||
sealed class RoutineState {}
|
||||
|
||||
final class RoutineInitial extends RoutineState {}
|
||||
@@ -1,10 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/conditions_routines_devices_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_search_and_buttons.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CreateNewRoutineView extends StatelessWidget {
|
||||
const CreateNewRoutineView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
return Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const RoutineSearchAndButtons(),
|
||||
const SizedBox(height: 20),
|
||||
Flexible(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Card(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: const ConditionsRoutinesDevicesView()),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Card(
|
||||
margin: EdgeInsets.zero,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
topRight: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 2,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.dialogBlueTitle,
|
||||
),
|
||||
Expanded(
|
||||
child: Card(
|
||||
margin: EdgeInsets.zero,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(15),
|
||||
bottomRight: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/search_bar_condition_title.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ConditionsRoutinesDevicesView extends StatelessWidget {
|
||||
const ConditionsRoutinesDevicesView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const ConditionTitleAndSearchBar(),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
DraggableCard(
|
||||
imagePath: Assets.tabToRun,
|
||||
title: 'Tab to run',
|
||||
),
|
||||
DraggableCard(
|
||||
imagePath: Assets.map,
|
||||
title: 'Location',
|
||||
),
|
||||
DraggableCard(
|
||||
imagePath: Assets.weather,
|
||||
title: 'Weather',
|
||||
),
|
||||
DraggableCard(
|
||||
imagePath: Assets.schedule,
|
||||
title: 'Schedule',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const TitleRoutine(
|
||||
title: 'Conditions',
|
||||
subtitle: '(THEN)',
|
||||
),
|
||||
const Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
DraggableCard(
|
||||
imagePath: Assets.notification,
|
||||
title: 'Send Notification',
|
||||
),
|
||||
DraggableCard(
|
||||
imagePath: Assets.delay,
|
||||
title: 'Delay the action',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const TitleRoutine(
|
||||
title: 'Routines',
|
||||
subtitle: '(THEN)',
|
||||
),
|
||||
const TitleRoutine(
|
||||
title: 'Devices',
|
||||
subtitle: '',
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => DeviceManagementBloc()
|
||||
..add(
|
||||
FetchDevices(),
|
||||
),
|
||||
child: BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
builder: (context, state) {
|
||||
if (state is DeviceManagementLoaded) {
|
||||
return Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: state.devices
|
||||
.map((device) => DraggableCard(
|
||||
imagePath: device.getDefaultIcon(device.productType),
|
||||
title: device.name ?? '',
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class DraggableCard extends StatelessWidget {
|
||||
const DraggableCard({
|
||||
super.key,
|
||||
required this.imagePath,
|
||||
required this.title,
|
||||
this.titleColor,
|
||||
});
|
||||
|
||||
final String imagePath;
|
||||
final String title;
|
||||
final Color? titleColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
color: ColorsManager.whiteColors,
|
||||
child: SizedBox(
|
||||
height: 123,
|
||||
width: 90,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 50,
|
||||
width: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.CircleImageBackground,
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
border: Border.all(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: imagePath.contains('.svg')
|
||||
? SvgPicture.asset(
|
||||
imagePath,
|
||||
)
|
||||
: Image.network(imagePath),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: context.textTheme.bodySmall?.copyWith(
|
||||
color: titleColor ?? ColorsManager.blackColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class RoutineSearchAndButtons extends StatelessWidget {
|
||||
const RoutineSearchAndButtons({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return Wrap(
|
||||
runSpacing: 16,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 12,
|
||||
crossAxisAlignment: WrapCrossAlignment.end,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32),
|
||||
child: StatefulTextField(
|
||||
title: 'Routine Name',
|
||||
height: 40,
|
||||
controller: TextEditingController(),
|
||||
hintText: 'Please enter the name',
|
||||
boxDecoration: containerWhiteDecoration,
|
||||
elevation: 0,
|
||||
borderRadius: 15,
|
||||
width: 450,
|
||||
),
|
||||
),
|
||||
(constraints.maxWidth <= 1000)
|
||||
? const SizedBox()
|
||||
: SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
borderColor: ColorsManager.greyColor,
|
||||
backgroundColor: ColorsManager.boxColor,
|
||||
child: const Text(
|
||||
'Settings',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (constraints.maxWidth > 1000)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
borderColor: ColorsManager.greyColor,
|
||||
backgroundColor: ColorsManager.boxColor,
|
||||
child: const Text(
|
||||
'Cancel',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.blackColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
backgroundColor: ColorsManager.primaryColor,
|
||||
child: const Text(
|
||||
'Save',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.whiteColors,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
if (constraints.maxWidth <= 1000)
|
||||
Wrap(
|
||||
runSpacing: 12,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
borderColor: ColorsManager.greyColor,
|
||||
backgroundColor: ColorsManager.boxColor,
|
||||
child: const Text(
|
||||
'Settings',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
borderColor: ColorsManager.greyColor,
|
||||
backgroundColor: ColorsManager.boxColor,
|
||||
child: const Text(
|
||||
'Cancel',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.blackColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () {},
|
||||
borderRadius: 15,
|
||||
elevation: 0,
|
||||
backgroundColor: ColorsManager.primaryColor,
|
||||
child: const Text(
|
||||
'Save',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.whiteColors,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class TitleRoutine extends StatelessWidget {
|
||||
const TitleRoutine({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String subtitle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: context.textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: context.textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLayout {
|
||||
const ConditionTitleAndSearchBar({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
final isSmall = isSmallScreenSize(context);
|
||||
return isMedium || isSmall
|
||||
? Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
const TitleRoutine(title: 'Conditions', subtitle: '(IF)'),
|
||||
StatefulTextField(
|
||||
title: '',
|
||||
width: 250,
|
||||
height: 40,
|
||||
hintText: 'Search',
|
||||
elevation: 0,
|
||||
borderRadius: 15,
|
||||
icon: Icons.search,
|
||||
hintColor: ColorsManager.grayColor,
|
||||
boxDecoration: BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
controller: TextEditingController(),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
const TitleRoutine(title: 'Conditions', subtitle: '(IF)'),
|
||||
StatefulTextField(
|
||||
title: '',
|
||||
width: 250,
|
||||
height: 40,
|
||||
hintText: 'Search',
|
||||
elevation: 0,
|
||||
borderRadius: 15,
|
||||
icon: Icons.search,
|
||||
hintColor: ColorsManager.grayColor,
|
||||
boxDecoration: BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
controller: TextEditingController(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,6 @@ abstract class ColorsManager {
|
||||
static const Color blue4 = Color(0xFF001E7E);
|
||||
static const Color textGreen = Color(0xFF008905);
|
||||
static const Color yaGreen = Color(0xFFFFBF44);
|
||||
static const Color CircleImageBackground = Color(0xFFF4F4F4);
|
||||
}
|
||||
//background: #background: #5D5D5D;
|
||||
|
||||
|
||||
@@ -192,4 +192,22 @@ class Assets {
|
||||
|
||||
//assets/icons/sos_normal.svg
|
||||
static const String sosNormal = 'assets/icons/sos_normal.svg';
|
||||
|
||||
//assets/icons/routine/tab_to_run.svg
|
||||
static const String tabToRun = 'assets/icons/routine/tab_to_run.svg';
|
||||
|
||||
//assets/icons/routine/schedule.svg
|
||||
static const String schedule = 'assets/icons/routine/schedule.svg';
|
||||
|
||||
//assets/icons/routine/map.svg
|
||||
static const String map = 'assets/icons/routine/map.svg';
|
||||
|
||||
//assets/icons/routine/weather.svg
|
||||
static const String weather = 'assets/icons/routine/weather.svg';
|
||||
|
||||
//assets/icons/routine/notification.svg
|
||||
static const String notification = 'assets/icons/routine/notification.svg';
|
||||
|
||||
//assets/icons/routine/delay.svg
|
||||
static const String delay = 'assets/icons/routine/delay.svg';
|
||||
}
|
||||
|
||||
@@ -11,9 +11,13 @@ enum DeviceType {
|
||||
CeilingSensor,
|
||||
WallSensor,
|
||||
WH,
|
||||
DoorSensor,
|
||||
DS,
|
||||
OneTouch,
|
||||
TowTouch,
|
||||
ThreeTouch,
|
||||
GarageDoor,
|
||||
WaterLeak,
|
||||
DoorSensor,
|
||||
Other,
|
||||
}
|
||||
/*
|
||||
|
||||
+19
-13
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'color_manager.dart';
|
||||
|
||||
InputDecoration? textBoxDecoration({bool suffixIcon = false}) =>
|
||||
InputDecoration(
|
||||
InputDecoration? textBoxDecoration({bool suffixIcon = false}) => InputDecoration(
|
||||
focusColor: ColorsManager.grayColor,
|
||||
suffixIcon: suffixIcon ? const Icon(Icons.search) : null,
|
||||
hintText: 'Search',
|
||||
@@ -30,14 +30,20 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false}) =>
|
||||
),
|
||||
);
|
||||
|
||||
BoxDecoration containerDecoration = BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 5), // changes position of shadow
|
||||
),
|
||||
],
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)));
|
||||
BoxDecoration containerDecoration = BoxDecoration(boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 5), // changes position of shadow
|
||||
),
|
||||
], color: ColorsManager.boxColor, borderRadius: const BorderRadius.all(Radius.circular(10)));
|
||||
|
||||
BoxDecoration containerWhiteDecoration = BoxDecoration(boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 5), // changes position of shadow
|
||||
),
|
||||
], color: ColorsManager.whiteColors, borderRadius: const BorderRadius.all(Radius.circular(15)));
|
||||
|
||||
Reference in New Issue
Block a user