diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index 8b706a6..47e22fa 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -9,7 +9,7 @@ import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/lights_view.dart'; -import 'package:syncrow_app/features/devices/view/widgets/screens/screens_view.dart'; +import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switches.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; @@ -26,7 +26,8 @@ class DevicesCubit extends Cubit { devices: [ ACModel( name: "Living Room AC", - id: '0', + id: 0, + functions: [], status: false, temperature: 20, fanSpeed: 0, @@ -42,7 +43,8 @@ class DevicesCubit extends Cubit { ), ACModel( name: "Master Bedroom AC", - id: '1', + id: 1, + functions: [], status: false, temperature: 20, fanSpeed: 0, @@ -58,7 +60,8 @@ class DevicesCubit extends Cubit { ), ACModel( name: "Kitchen AC", - id: '2', + id: 2, + functions: [], status: false, temperature: 20, fanSpeed: 0, @@ -74,7 +77,8 @@ class DevicesCubit extends Cubit { ), ACModel( name: "Bathroom AC", - id: '3', + id: 3, + functions: [], status: false, temperature: 20, fanSpeed: 0, @@ -98,7 +102,8 @@ class DevicesCubit extends Cubit { devices: [ LightModel( name: "Living Room Light", - id: '0', + id: 0, + functions: [], status: false, color: 0, brightness: 20, @@ -115,7 +120,8 @@ class DevicesCubit extends Cubit { ), LightModel( name: "Master Bedroom Light", - id: '1', + id: 1, + functions: [], status: false, color: 2, brightness: 40, @@ -132,7 +138,8 @@ class DevicesCubit extends Cubit { ), LightModel( name: "Kitchen Light", - id: '2', + id: 2, + functions: [], status: false, color: 1, brightness: 60, @@ -149,7 +156,8 @@ class DevicesCubit extends Cubit { ), LightModel( name: "Bathroom Light", - id: '3', + id: 3, + functions: [], status: false, color: 3, brightness: 80, @@ -166,7 +174,8 @@ class DevicesCubit extends Cubit { ), LightModel( name: "Balcony Light", - id: '4', + id: 4, + functions: [], status: false, color: 4, brightness: 100, @@ -198,7 +207,8 @@ class DevicesCubit extends Cubit { devices: [ CurtainModel( openPercentage: 10, - id: "1", + id: 1, + functions: [], name: "Living Room Curtain", status: false, type: DeviceType.Curtain, @@ -207,7 +217,8 @@ class DevicesCubit extends Cubit { ), CurtainModel( openPercentage: 20, - id: "2", + id: 2, + functions: [], name: "Master Bedroom Curtain", status: false, type: DeviceType.Curtain, @@ -222,10 +233,10 @@ class DevicesCubit extends Cubit { ), DevicesCategoryModel( devices: [], - icon: Assets.iconsScreen, - name: 'Screens', - type: DeviceType.Screens, - page: const ScreensView(), + icon: Assets.icons3GangSwitch, + name: 'Bedroom Lights', + type: DeviceType.ThreeGang, + page: const LightSwitchesView(), ), DevicesCategoryModel( devices: [], diff --git a/lib/features/devices/model/ac_model.dart b/lib/features/devices/model/ac_model.dart index 737118d..3476d59 100644 --- a/lib/features/devices/model/ac_model.dart +++ b/lib/features/devices/model/ac_model.dart @@ -1,4 +1,5 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/function_model.dart'; class ACModel extends DeviceModel { late double temperature; @@ -23,6 +24,7 @@ class ACModel extends DeviceModel { required super.status, required super.image, required super.timer, + required super.functions, }); Map toJson() { @@ -40,6 +42,12 @@ class ACModel extends DeviceModel { } factory ACModel.fromJson(Map json) { + List func = []; + if (json['functions'] != null) { + json['functions'].forEach((v) { + func.add(FunctionModel.fromJson(v)); + }); + } return ACModel( id: json['id'], name: json['name'], @@ -52,6 +60,7 @@ class ACModel extends DeviceModel { timer: json['timer'], coolTo: json['coolTo'], bounds: Bounds.fromJson(json['bounds']), + functions: func, ); } } diff --git a/lib/features/devices/model/curtain_model.dart b/lib/features/devices/model/curtain_model.dart index 6abc311..e693871 100644 --- a/lib/features/devices/model/curtain_model.dart +++ b/lib/features/devices/model/curtain_model.dart @@ -1,4 +1,5 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/function_model.dart'; class CurtainModel extends DeviceModel { late int openPercentage; @@ -11,6 +12,7 @@ class CurtainModel extends DeviceModel { required super.status, required super.image, required super.timer, + required super.functions, }); Map toJson() { @@ -26,6 +28,12 @@ class CurtainModel extends DeviceModel { } factory CurtainModel.fromJson(Map json) { + List func = []; + if (json['functions'] != null) { + json['functions'].forEach((v) { + func.add(FunctionModel.fromJson(v)); + }); + } return CurtainModel( id: json['id'], name: json['name'], @@ -34,6 +42,7 @@ class CurtainModel extends DeviceModel { timer: json['timer'], type: json['type'], image: json['image'], + functions: func, ); } } diff --git a/lib/features/devices/model/device_control_model.dart b/lib/features/devices/model/device_control_model.dart new file mode 100644 index 0000000..8f9edf7 --- /dev/null +++ b/lib/features/devices/model/device_control_model.dart @@ -0,0 +1,27 @@ +class DeviceControlModel { + String? deviceId; + String? code; + bool? value; + + DeviceControlModel({ + required this.deviceId, + required this.code, + required this.value, + }); + + factory DeviceControlModel.fromJson(Map json) { + return DeviceControlModel( + deviceId: json['deviceId'], + code: json['code'], + value: json['value'], + ); + } + + Map toJson() { + return { + 'deviceId': deviceId, + 'code': code, + 'value': value, + }; + } +} diff --git a/lib/features/devices/model/device_model.dart b/lib/features/devices/model/device_model.dart index 2c327f9..78fb291 100644 --- a/lib/features/devices/model/device_model.dart +++ b/lib/features/devices/model/device_model.dart @@ -1,17 +1,19 @@ +import 'package:syncrow_app/features/devices/model/function_model.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; -abstract class DeviceModel { - final String? id; +class DeviceModel { + final int? id; final String? name; final DeviceType? type; bool? status; final String? image; final double? timer; - late final String icon; bool isSelected = false; + late List functions; + DeviceModel({ required this.id, required this.name, @@ -19,6 +21,7 @@ abstract class DeviceModel { required this.status, required this.image, required this.timer, + required this.functions, }) { switch (type) { case DeviceType.AC: diff --git a/lib/features/devices/model/function_model.dart b/lib/features/devices/model/function_model.dart new file mode 100644 index 0000000..c187b32 --- /dev/null +++ b/lib/features/devices/model/function_model.dart @@ -0,0 +1,42 @@ +//{ +// "code": "switch_1", +// "desc": "switch 1", +// "name": "switch 1", +// "type": "Boolean", +// "values": "{}" +// } +class FunctionModel { + String? code; + String? desc; + String? name; + String? type; + String? values; + + FunctionModel({ + required this.code, + required this.desc, + required this.name, + required this.type, + required this.values, + }); + + factory FunctionModel.fromJson(Map json) { + return FunctionModel( + code: json['code'], + desc: json['desc'], + name: json['name'], + type: json['type'], + values: json['values'], + ); + } + + Map toJson() { + return { + 'code': code, + 'desc': desc, + 'name': name, + 'type': type, + 'values': values, + }; + } +} diff --git a/lib/features/devices/model/light_model.dart b/lib/features/devices/model/light_model.dart index ab2f258..7de5ffa 100644 --- a/lib/features/devices/model/light_model.dart +++ b/lib/features/devices/model/light_model.dart @@ -1,4 +1,5 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/function_model.dart'; class LightModel extends DeviceModel { late double brightness; @@ -19,6 +20,7 @@ class LightModel extends DeviceModel { required super.status, required super.image, required super.timer, + required super.functions, }); Map toJson() { @@ -37,6 +39,12 @@ class LightModel extends DeviceModel { } factory LightModel.fromJson(Map json) { + List func = []; + if (json['functions'] != null) { + json['functions'].forEach((v) { + func.add(FunctionModel.fromJson(v)); + }); + } return LightModel( id: json['id'], name: json['name'], @@ -48,6 +56,7 @@ class LightModel extends DeviceModel { type: json['type'], image: json['image'], recentColors: json['recentColors'], + functions: func, ); } } diff --git a/lib/features/devices/view/devices_view.dart b/lib/features/devices/view/devices_view.dart index 69358a1..18dc389 100644 --- a/lib/features/devices/view/devices_view.dart +++ b/lib/features/devices/view/devices_view.dart @@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart'; -class CategoriesView extends StatelessWidget { - const CategoriesView({super.key}); +class DevicesView extends StatelessWidget { + const DevicesView({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/features/devices/view/widgets/lights_switches/light_switche.dart b/lib/features/devices/view/widgets/lights_switches/light_switche.dart new file mode 100644 index 0000000..cabb568 --- /dev/null +++ b/lib/features/devices/view/widgets/lights_switches/light_switche.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class LightSwitch extends StatefulWidget { + const LightSwitch({ + super.key, + }); + + @override + State createState() => _LightSwitchState(); +} + +class _LightSwitchState extends State { + bool isOn = false; + + @override + Widget build(BuildContext context) { + return InkWell( + overlayColor: MaterialStateProperty.all(Colors.transparent), + onTap: () { + setState(() { + isOn = !isOn; + }); + }, + child: Stack( + alignment: isOn ? Alignment.topCenter : Alignment.bottomCenter, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(100.0)), + color: isOn + ? ColorsManager.primaryColorWithOpacity + : ColorsManager.switchOffColor, + ), + width: 60, + height: 115, + ), + Padding( + padding: const EdgeInsets.all(5.0), + child: SizedBox.square( + dimension: 60, + child: SvgPicture.asset( + isOn ? Assets.iconsLightSwitchOn : Assets.iconsLightSwitchOff, + fit: BoxFit.fill, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/lights_switches/light_switches.dart b/lib/features/devices/view/widgets/lights_switches/light_switches.dart new file mode 100644 index 0000000..95e91e3 --- /dev/null +++ b/lib/features/devices/view/widgets/lights_switches/light_switches.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/app_layout/bloc/nav_cubit.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/function_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/ACs/category_view_app_bar.dart'; +import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switches_body.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/constants.dart'; + +class LightSwitchesView extends StatelessWidget { + const LightSwitchesView({super.key}); + + @override + Widget build(BuildContext context) { + return AnnotatedRegion( + value: SystemUiOverlayStyle( + statusBarColor: ColorsManager.primaryColor.withOpacity(0.5), + statusBarIconBrightness: Brightness.light, + ), + child: SafeArea( + child: Scaffold( + backgroundColor: ColorsManager.backgroundColor, + extendBodyBehindAppBar: true, + extendBody: true, + appBar: const CategoryViewAppBar(), + body: BlocBuilder( + builder: (context, state) { + return Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + Assets.imagesBackground, + ), + fit: BoxFit.cover, + opacity: 0.4, + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: Constants.appBarHeight, + left: Constants.defaultPadding, + right: Constants.defaultPadding, + bottom: Constants.bottomNavBarHeight, + ), + child: LightSwitchesBody( + device: DeviceModel( + id: 2, + name: 'Bedroom Light', + type: DeviceType.Lights, + status: true, + timer: 0, + image: '', + functions: [ + FunctionModel( + code: 'switch_1', + desc: 'switch 1', + name: 'switch 1', + type: 'Boolean', + values: '{}'), + FunctionModel( + code: 'switch_2', + desc: 'switch 2', + name: 'switch 2', + type: 'Boolean', + values: '{}'), + FunctionModel( + code: 'switch_3', + desc: 'switch 3', + name: 'switch 3', + type: 'Boolean', + values: '{}'), + ]), + ), + ), + ); + }, + )), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/lights_switches/light_switches_body.dart b/lib/features/devices/view/widgets/lights_switches/light_switches_body.dart new file mode 100644 index 0000000..2c915b2 --- /dev/null +++ b/lib/features/devices/view/widgets/lights_switches/light_switches_body.dart @@ -0,0 +1,202 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switche.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class LightSwitchesBody extends StatelessWidget { + const LightSwitchesBody({ + super.key, + required this.device, + }); + + final DeviceModel device; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Expanded(child: SizedBox.shrink()), + const Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LightSwitch(), + LightSwitch(), + LightSwitch(), + ], + ), + Expanded( + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Card( + elevation: 3, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + child: InkWell( + onTap: () {}, + child: Stack( + alignment: Alignment.center, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(100), + ), + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + ), + child: Center( + child: BodySmall( + text: "On", + style: context.bodyMedium.copyWith( + color: + ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), + ), + ), + const SizedBox(height: 10), + BodySmall( + text: "All On", + style: context.bodyMedium.copyWith( + color: ColorsManager.textPrimaryColor, + ), + ), + ], + ), + const SizedBox( + width: 20, + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Card( + elevation: 3, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + child: InkWell( + onTap: () {}, + child: Stack( + alignment: Alignment.center, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(100), + ), + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + ), + child: Center( + child: Icon( + Icons.access_time, + color: ColorsManager.primaryColorWithOpacity, + size: 25, + ), + ), + ), + ], + ), + ), + ), + const SizedBox(height: 10), + BodySmall( + text: "Timer", + style: context.bodyMedium.copyWith( + color: ColorsManager.textPrimaryColor, + ), + ), + ], + ), + const SizedBox( + width: 20, + ), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Card( + elevation: 3, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + child: InkWell( + onTap: () {}, + child: Stack( + alignment: Alignment.center, + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(100), + ), + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + ), + child: Center( + child: BodySmall( + text: "Off", + style: context.bodyMedium.copyWith( + color: + ColorsManager.primaryColorWithOpacity, + fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), + ), + ), + const SizedBox(height: 10), + BodySmall( + text: "All Off", + style: context.bodyMedium.copyWith( + color: ColorsManager.textPrimaryColor, + ), + ), + ], + ), + ], + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/devices/view/widgets/screens/screens_view.dart b/lib/features/devices/view/widgets/screens/screens_view.dart deleted file mode 100644 index fe19fc8..0000000 --- a/lib/features/devices/view/widgets/screens/screens_view.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/material.dart'; - -class ScreensView extends StatelessWidget { - const ScreensView({super.key}); - - @override - Widget build(BuildContext context) { - return const Placeholder(); - } -} diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 72246f3..90d49a2 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -4,6 +4,7 @@ class Assets { static const String assetsIconsSettings = 'assets/icons/settings.svg'; static const String fontsAftikaRegular = 'assets/fonts/AftikaRegular.ttf'; + static const String icons3GangSwitch = 'assets/icons/3GangSwitch.svg'; static const String iconsAC = 'assets/icons/AC.svg'; static const String iconsActive = 'assets/icons/active.svg'; static const String iconsAutomatedClock = 'assets/icons/automated_clock.svg'; @@ -37,6 +38,8 @@ class Assets { static const String iconsLayout = 'assets/icons/Layout.svg'; static const String iconsLayoutFill = 'assets/icons/Layout-fill.svg'; static const String iconsLight = 'assets/icons/Light.svg'; + static const String iconsLightSwitchOff = 'assets/icons/lightSwitchOff.svg'; + static const String iconsLightSwitchOn = 'assets/icons/lightSwitchOn.svg'; static const String iconsLock = 'assets/icons/lock.svg'; static const String iconsLogo = 'assets/icons/logo.png'; static const String iconsMenu = 'assets/icons/Menu.svg'; @@ -52,6 +55,8 @@ class Assets { static const String iconsSummerMode = 'assets/icons/summer_mode.svg'; static const String iconsSunnyMode = 'assets/icons/sunnyMode.svg'; static const String iconsSustainability = 'assets/icons/sustainability.svg'; + static const String iconsVector = 'assets/icons/Vector.svg'; + static const String iconsVector1 = 'assets/icons/Vector-1.svg'; static const String iconsVoltMeter = 'assets/icons/volt-meter.svg'; static const String iconsWindyMode = 'assets/icons/windyMode.svg'; static const String iconsWinter = 'assets/icons/Winter.svg'; diff --git a/lib/navigation/router.dart b/lib/navigation/router.dart index 2888538..49647e9 100644 --- a/lib/navigation/router.dart +++ b/lib/navigation/router.dart @@ -25,7 +25,7 @@ class Router { case Routes.devicesRoute: return MaterialPageRoute( - builder: (_) => const CategoriesView(), settings: settings); + builder: (_) => const DevicesView(), settings: settings); case Routes.profileRoute: return MaterialPageRoute( diff --git a/lib/utils/resource_manager/color_manager.dart b/lib/utils/resource_manager/color_manager.dart index 10022fd..6675670 100644 --- a/lib/utils/resource_manager/color_manager.dart +++ b/lib/utils/resource_manager/color_manager.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; abstract class ColorsManager { static const Color textPrimaryColor = Color(0xFF5D5D5D); + static const Color switchOffColor = Color(0x7F8D99AE); static const Color primaryColor = Color(0xFF0030CB); static Color primaryColorWithOpacity = const Color(0xFF023DFE).withOpacity(0.6); diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index 8a67e03..4156ab1 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -19,6 +19,6 @@ enum DeviceType { Lights, Door, Curtain, - Screens, + ThreeGang, Gateway, }