From e576fb3b4761613dabf8306c92d5301ebc02f05a Mon Sep 17 00:00:00 2001 From: ashrafzarkanisala Date: Thu, 22 Aug 2024 00:09:42 +0300 Subject: [PATCH] push basic layouts and shared widgets --- lib/core/theme/app_theme.dart | 0 lib/main.dart | 66 ++++---- .../view/access_management.dart | 2 +- .../auth/view/forget_password_web_page.dart | 2 +- lib/pages/auth/view/login_mobile_page.dart | 2 +- lib/pages/auth/view/login_web_page.dart | 2 +- .../common/{ => buttons}/default_button.dart | 0 .../common/buttons/search_reset_buttons.dart | 71 +++++++++ .../common/text_field/custom_text_field.dart | 103 ++++++++++++ .../custom_web_textfield.dart | 0 .../widgets/device_managment_body.dart | 86 ++++++---- .../view/add_device_dialog.dart | 150 +++++++----------- .../view/visitor_password_dialog.dart | 4 +- .../responsive_layout_helper.dart | 4 +- 14 files changed, 328 insertions(+), 164 deletions(-) create mode 100644 lib/core/theme/app_theme.dart rename lib/pages/common/{ => buttons}/default_button.dart (100%) create mode 100644 lib/pages/common/buttons/search_reset_buttons.dart create mode 100644 lib/pages/common/text_field/custom_text_field.dart rename lib/pages/common/{ => text_field}/custom_web_textfield.dart (100%) diff --git a/lib/core/theme/app_theme.dart b/lib/core/theme/app_theme.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/main.dart b/lib/main.dart index c9d66e8e..bf63e062 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,8 +5,6 @@ import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; import 'package:syncrow_web/pages/auth/view/login_page.dart'; import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; import 'package:syncrow_web/pages/home/view/home_page.dart'; -import 'package:syncrow_web/pages/visitor_password/view/add_device_dialog.dart'; -import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart'; import 'package:syncrow_web/services/locator.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -32,40 +30,38 @@ class MyApp extends StatelessWidget { BlocProvider(create: (context) => HomeBloc()), ], child: MaterialApp( - debugShowCheckedModeBanner: false, // Hide debug banner - scrollBehavior: const MaterialScrollBehavior().copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.stylus, - PointerDeviceKind.unknown, - }, - ), - theme: ThemeData( - textTheme: const TextTheme( - bodySmall: TextStyle( - fontSize: 13, - color: ColorsManager.whiteColors, - fontWeight: FontWeight.bold), - bodyMedium: TextStyle(color: Colors.black87, fontSize: 14), - bodyLarge: TextStyle(fontSize: 16, color: Colors.white), - headlineSmall: TextStyle(color: Colors.black87, fontSize: 18), - headlineMedium: TextStyle(color: Colors.black87, fontSize: 20), - headlineLarge: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold, - ), + debugShowCheckedModeBanner: false, // Hide debug banner + scrollBehavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.stylus, + PointerDeviceKind.unknown, + }, + ), + theme: ThemeData( + textTheme: const TextTheme( + bodySmall: TextStyle( + fontSize: 13, + color: ColorsManager.whiteColors, + fontWeight: FontWeight.bold), + bodyMedium: TextStyle(color: Colors.black87, fontSize: 14), + bodyLarge: TextStyle(fontSize: 16, color: Colors.white), + headlineSmall: TextStyle(color: Colors.black87, fontSize: 18), + headlineMedium: TextStyle(color: Colors.black87, fontSize: 20), + headlineLarge: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, ), - - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.deepPurple), // Set up color scheme - useMaterial3: true, // Enable Material 3 ), - // home: AddDeviceDialog() - // home:isLoggedIn == 'Success' ? - home: const HomePage() - // : const LoginPage(), - )); + + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.deepPurple), // Set up color scheme + useMaterial3: true, // Enable Material 3 + ), + // home: AddDeviceDialog() + home: isLoggedIn == 'Success' ? const HomePage() : const LoginPage(), + )); } } diff --git a/lib/pages/access_management/view/access_management.dart b/lib/pages/access_management/view/access_management.dart index 137eeeb7..de8dc102 100644 --- a/lib/pages/access_management/view/access_management.dart +++ b/lib/pages/access_management/view/access_management.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/pages/access_management/bloc/access_event.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_state.dart'; import 'package:syncrow_web/pages/common/custom_table.dart'; import 'package:syncrow_web/pages/common/date_time_widget.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/filter/filter_widget.dart'; import 'package:syncrow_web/pages/visitor_password/view/visitor_password_dialog.dart'; import 'package:syncrow_web/utils/color_manager.dart'; diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index a2a939e3..47f0beb7 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -5,7 +5,7 @@ import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_event.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_state.dart'; import 'package:syncrow_web/pages/auth/model/region_model.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/first_layer.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index 98402f59..d2787f04 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -8,7 +8,7 @@ import 'package:syncrow_web/pages/auth/bloc/auth_event.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_state.dart'; import 'package:syncrow_web/pages/auth/model/region_model.dart'; import 'package:syncrow_web/pages/auth/view/forget_password_page.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/pages/home/view/home_page.dart'; diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index b819669e..77c7afba 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -9,7 +9,7 @@ import 'package:syncrow_web/pages/auth/bloc/auth_event.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_state.dart'; import 'package:syncrow_web/pages/auth/model/region_model.dart'; import 'package:syncrow_web/pages/auth/view/forget_password_page.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/first_layer.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; diff --git a/lib/pages/common/default_button.dart b/lib/pages/common/buttons/default_button.dart similarity index 100% rename from lib/pages/common/default_button.dart rename to lib/pages/common/buttons/default_button.dart diff --git a/lib/pages/common/buttons/search_reset_buttons.dart b/lib/pages/common/buttons/search_reset_buttons.dart new file mode 100644 index 00000000..a03b889a --- /dev/null +++ b/lib/pages/common/buttons/search_reset_buttons.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/utils/style.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class SearchResetButtons extends StatelessWidget { + const SearchResetButtons({ + super.key, + required this.onSearch, + required this.onReset, + }); + + final VoidCallback onSearch; + final VoidCallback onReset; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 25), + Center( + child: Container( + height: 43, + width: 100, + decoration: containerDecoration, + child: Center( + child: DefaultButton( + onPressed: onSearch, + borderRadius: 9, + child: const Text('Search'), + ), + ), + ), + ), + ], + ), + const SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 25), + Center( + child: Container( + height: 43, + width: 100, + decoration: containerDecoration, + child: Center( + child: DefaultButton( + backgroundColor: ColorsManager.whiteColors, + borderRadius: 9, + child: Text( + 'Reset', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Colors.black), + ), + onPressed: onReset, + ), + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/lib/pages/common/text_field/custom_text_field.dart b/lib/pages/common/text_field/custom_text_field.dart new file mode 100644 index 00000000..abc26f22 --- /dev/null +++ b/lib/pages/common/text_field/custom_text_field.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/core/extension/build_context_x.dart'; + +class StatefulTextField extends StatefulWidget { + const StatefulTextField({ + super.key, + required this.title, + this.hintText = 'Please enter', + required this.width, + this.elevation = 0, + }); + + final String title; + final String hintText; + final double width; + final double elevation; + + @override + State createState() => _StatefulTextFieldState(); +} + +class _StatefulTextFieldState extends State { + late TextEditingController _controller; + + @override + void initState() { + super.initState(); + _controller = TextEditingController(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CustomTextField( + title: widget.title, + controller: _controller, + hintText: widget.hintText, + width: widget.width, + elevation: widget.elevation, + ); + } +} + +class CustomTextField extends StatelessWidget { + const CustomTextField({ + super.key, + required this.title, + required this.controller, + this.hintText = 'Please enter', + required this.width, + this.elevation = 0, + }); + + final String title; + final TextEditingController controller; + final String hintText; + final double width; + final double elevation; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + title, + style: context.textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w600, + color: const Color(0xff000000), + ), + ), + const SizedBox(height: 8), + Material( + elevation: elevation, + borderRadius: BorderRadius.circular(8), + child: Container( + width: width, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: TextFormField( + controller: controller, + style: const TextStyle(color: Colors.black), + decoration: InputDecoration( + hintText: hintText, + contentPadding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + border: InputBorder.none, + ), + ), + ), + ), + ], + ); + } +} diff --git a/lib/pages/common/custom_web_textfield.dart b/lib/pages/common/text_field/custom_web_textfield.dart similarity index 100% rename from lib/pages/common/custom_web_textfield.dart rename to lib/pages/common/text_field/custom_web_textfield.dart diff --git a/lib/pages/device_managment/widgets/device_managment_body.dart b/lib/pages/device_managment/widgets/device_managment_body.dart index 1b842bbb..1f3b11e1 100644 --- a/lib/pages/device_managment/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/widgets/device_managment_body.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/core/extension/build_context_x.dart'; +import 'package:syncrow_web/pages/common/buttons/search_reset_buttons.dart'; import 'package:syncrow_web/pages/common/filter/filter_widget.dart'; -import 'package:syncrow_web/utils/style.dart'; +import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart'; +import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class DeviceManagementBody extends StatelessWidget { +class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { const DeviceManagementBody({super.key}); @override @@ -24,32 +26,60 @@ class DeviceManagementBody extends StatelessWidget { const SizedBox( height: 20, ), - Wrap( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - 'Community', - style: context.textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.w400, - color: const Color(0xff000000)), - ), - Container( - width: context.screenWidth * 0.15, - margin: const EdgeInsets.only(top: 8), - decoration: containerDecoration, - child: TextFormField( - //: accessBloc.passwordName, - style: const TextStyle(color: Colors.black), - decoration: textBoxDecoration()! - .copyWith(hintText: 'Please enter'), - )), - ], - ), - ], - ) + if (isLargeScreenSize(context)) ...[ + Row( + children: [ + const StatefulTextField( + title: "Community", + width: 200, + elevation: 2, + ), + const SizedBox(width: 20), + const StatefulTextField( + title: "Unit Name", + width: 200, + elevation: 2, + ), + const SizedBox(width: 20), + const StatefulTextField( + title: "Device Name / Product Name", + width: 300, + elevation: 2, + ), + const SizedBox(width: 20), + SearchResetButtons( + onSearch: () {}, + onReset: () {}, + ), + ], + ), + ] else ...[ + Wrap( + spacing: 20, + runSpacing: 10, + children: [ + const StatefulTextField( + title: "Community", + width: 200, + elevation: 2, + ), + const StatefulTextField( + title: "Unit Name", + width: 200, + elevation: 2, + ), + const StatefulTextField( + title: "Device Name / Product Name", + width: 300, + elevation: 2, + ), + SearchResetButtons( + onSearch: () {}, + onReset: () {}, + ), + ], + ), + ], ], ), ); diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index 58e49182..1ab68033 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_web/pages/common/buttons/search_reset_buttons.dart'; import 'package:syncrow_web/pages/common/custom_table.dart'; -import 'package:syncrow_web/pages/common/custom_web_textfield.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart'; @@ -12,7 +13,6 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/const.dart'; import 'package:syncrow_web/utils/style.dart'; - class AddDeviceDialog extends StatelessWidget { const AddDeviceDialog({super.key}); @override @@ -27,8 +27,8 @@ class AddDeviceDialog extends StatelessWidget { backgroundColor: Colors.white, title: const Text('Add Accessible Device'), content: Container( - height: MediaQuery.of(context).size.height/1.7, - width: MediaQuery.of(context).size.width/2, + height: MediaQuery.of(context).size.height / 1.7, + width: MediaQuery.of(context).size.width / 2, child: Padding( padding: const EdgeInsets.all(10.0), child: Column( @@ -36,11 +36,10 @@ class AddDeviceDialog extends StatelessWidget { Container( width: size.width, padding: EdgeInsets.all(15), - decoration:containerDecoration.copyWith( + decoration: containerDecoration.copyWith( color: ColorsManager.worningColor, border: Border.all(color: Color(0xffFFD22F)), - boxShadow: [] - ), + boxShadow: []), child: Row( children: [ SizedBox( @@ -50,12 +49,15 @@ class AddDeviceDialog extends StatelessWidget { width: 15, ), ), - SizedBox(width: 10,), + SizedBox( + width: 10, + ), Text('Only online accessible devices can be added'), ], - ) + )), + SizedBox( + height: 20, ), - SizedBox(height: 20,), Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, @@ -89,93 +91,55 @@ class AddDeviceDialog extends StatelessWidget { description: '', ), ), - const SizedBox(width: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 25), - Center( - child: Container( - height: 43, - width: 100, - decoration: containerDecoration, - child: Center( - child: DefaultButton( - onPressed: () { - visitorBloc.filterDevices(); // Call filter function - }, - borderRadius: 9, - child: const Text('Search'), - ), - ), - ), - ), - - ], + SearchResetButtons( + onSearch: () { + visitorBloc.filterDevices(); + }, + onReset: () { + visitorBloc.deviceNameController.clear(); + visitorBloc.deviceIdController.clear(); + visitorBloc.unitNameController.clear(); + visitorBloc.add(FetchDevice()); + }, ), - const SizedBox(width: 10), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 25), - - Center( - child: Container( - height: 43, - width: 100, - decoration: containerDecoration, - child: Center( - child: DefaultButton( - backgroundColor: ColorsManager.whiteColors, - borderRadius: 9, - child: Text( - 'Reset', - style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black), - ), - onPressed: () { - visitorBloc.deviceNameController.clear(); - visitorBloc.deviceIdController.clear(); - visitorBloc.unitNameController.clear(); - visitorBloc.add(FetchDevice()); // Reset to original list - }, - ), - ), - ), - ), - ], - ), - ], ), const SizedBox(height: 20), Expanded( - child: state is TableLoaded - ? DynamicTable( - cellDecoration: containerDecoration, - selectAll: (p0) { - visitorBloc.selectedDeviceIds.clear(); - for (var item in state.data) { - visitorBloc.add(SelectDeviceEvent(item.uuid)); - } - }, - onRowCheckboxChanged: (index, isSelected) { - final deviceId = state.data[index].uuid; - visitorBloc.add(SelectDeviceEvent(deviceId)); - }, - withCheckBox: true, - size: size*0.5, - headers: const [ 'Device Name', 'Device ID', 'Access Type', 'Unit Name', 'Status'], - data: state.data.map((item) { - return [ - item.name.toString(), - item.uuid.toString(), - item.productType.toString(), - '', - item.online.value.toString(), - ]; - }).toList(), - ) + child: state is TableLoaded + ? DynamicTable( + cellDecoration: containerDecoration, + selectAll: (p0) { + visitorBloc.selectedDeviceIds.clear(); + for (var item in state.data) { + visitorBloc + .add(SelectDeviceEvent(item.uuid)); + } + }, + onRowCheckboxChanged: (index, isSelected) { + final deviceId = state.data[index].uuid; + visitorBloc.add(SelectDeviceEvent(deviceId)); + }, + withCheckBox: true, + size: size * 0.5, + headers: const [ + 'Device Name', + 'Device ID', + 'Access Type', + 'Unit Name', + 'Status' + ], + data: state.data.map((item) { + return [ + item.name.toString(), + item.uuid.toString(), + item.productType.toString(), + '', + item.online.value.toString(), + ]; + }).toList(), + ) : const Center(child: CircularProgressIndicator())) ], ), @@ -201,7 +165,7 @@ class AddDeviceDialog extends StatelessWidget { Container( decoration: containerDecoration, width: size.width * 0.2, - child: DefaultButton( + child: DefaultButton( onPressed: () { Navigator.of(context).pop(); // Close the dialog }, diff --git a/lib/pages/visitor_password/view/visitor_password_dialog.dart b/lib/pages/visitor_password/view/visitor_password_dialog.dart index eadee6dc..949fc76d 100644 --- a/lib/pages/visitor_password/view/visitor_password_dialog.dart +++ b/lib/pages/visitor_password/view/visitor_password_dialog.dart @@ -1,9 +1,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/pages/common/custom_web_textfield.dart'; +import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart'; import 'package:syncrow_web/pages/common/date_time_widget.dart'; -import 'package:syncrow_web/pages/common/default_button.dart'; +import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/info_dialog.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart'; import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart'; diff --git a/lib/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart b/lib/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart index 265bf2cf..fbec8cda 100644 --- a/lib/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart +++ b/lib/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart @@ -7,10 +7,10 @@ mixin HelperResponsiveLayout { bool isMediumScreenSize(BuildContext context) { return MediaQuery.of(context).size.width >= 700 && - MediaQuery.of(context).size.width < 1200; + MediaQuery.of(context).size.width < 1300; } bool isLargeScreenSize(BuildContext context) { - return MediaQuery.of(context).size.width >= 1200; + return MediaQuery.of(context).size.width >= 1300; } }