diff --git a/assets/images/Overview.svg b/assets/images/Overview.svg new file mode 100644 index 00000000..0abb97f3 --- /dev/null +++ b/assets/images/Overview.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/assets.svg b/assets/images/assets.svg new file mode 100644 index 00000000..905e96b3 --- /dev/null +++ b/assets/images/assets.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/message.svg b/assets/images/message.svg new file mode 100644 index 00000000..21d2c352 --- /dev/null +++ b/assets/images/message.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/requests.svg b/assets/images/requests.svg new file mode 100644 index 00000000..5636ef99 --- /dev/null +++ b/assets/images/requests.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/translations/ar.json b/assets/translations/ar.json index 00882ed4..9964ed98 100644 --- a/assets/translations/ar.json +++ b/assets/translations/ar.json @@ -5,5 +5,9 @@ "password": "كلمة السر", "username" : "اسم المستخدم", "requiredField" : "الحقل مطلوب", - "passwordLengthMessage" : "كلمة السر أقل من 6 خانات" + "passwordLengthMessage" : "كلمة السر أقل من 6 خانات", + "overview" : "نظرة عامة", + "myRequest" : "طلباتي", + "Assets" : "الاصول", + "contactUs": "اتصل بنا" } \ No newline at end of file diff --git a/assets/translations/en.json b/assets/translations/en.json index 9105af01..23d62512 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -5,5 +5,9 @@ "password" : "Password", "username" : "Username", "requiredField" : "Required Field", - "passwordLengthMessage" : "Password length is less than 6 characters" + "passwordLengthMessage" : "Password length is less than 6 characters", + "overview" : "Overview", + "myRequest" : "My Request", + "Assets" : "Assets", + "contactUs": "Contact Us" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index c5286619..bba51090 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,6 +12,7 @@ import 'package:test_sa/new_views/pages/splash_page.dart'; import 'controllers/providers/api/user_provider.dart'; import 'controllers/providers/settings/setting_provider.dart'; +import 'new_views/common_widgets/test screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -61,8 +62,9 @@ class MyApp extends StatelessWidget { ], supportedLocales: const [Locale('en'), Locale('ar')], locale: Locale(settingProvider.language ?? 'en'), - initialRoute: SplashPage.routeName, + initialRoute: TestScreen.id, routes: { + TestScreen.id: (_) => const TestScreen(), SplashPage.routeName: (_) => const SplashPage(), LoginPage.routeName: (_) => const LoginPage(), LandPage.routeName: (_) => const LandPage(), diff --git a/lib/models/enums/translation_keys.dart b/lib/models/enums/translation_keys.dart index 958ac1fa..b14e3e6e 100644 --- a/lib/models/enums/translation_keys.dart +++ b/lib/models/enums/translation_keys.dart @@ -6,4 +6,8 @@ enum TranslationKeys { username, requiredField, passwordLengthMessage, + overview, + myRequest, + Assets, + contactUs } diff --git a/lib/new_views/app_style/app_themes.dart b/lib/new_views/app_style/app_themes.dart index ce9c6829..d12eb48f 100644 --- a/lib/new_views/app_style/app_themes.dart +++ b/lib/new_views/app_style/app_themes.dart @@ -9,6 +9,19 @@ class AppThemes { indicatorColor: AppColor.primary50, scaffoldBackgroundColor: AppColor.backgroundLight, colorScheme: const ColorScheme.light(primary: AppColor.primary50, onPrimary: Colors.white, secondary: Colors.white, onSecondary: AppColor.neutral70), + + floatingActionButtonTheme: const FloatingActionButtonThemeData( + backgroundColor: AppColor.backgroundDark, + ), + bottomNavigationBarTheme: const BottomNavigationBarThemeData( + backgroundColor: AppColor.backgroundLight + ), + appBarTheme: const AppBarTheme( + backgroundColor: AppColor.backgroundLight, + titleTextStyle: TextStyle( + color: AppColor.neutral50 + ) + ) ); static ThemeData darkTheme = ThemeData.dark().copyWith( @@ -17,5 +30,19 @@ class AppThemes { indicatorColor: AppColor.primary50, scaffoldBackgroundColor: AppColor.backgroundDark, colorScheme: const ColorScheme.light(primary: AppColor.primary50, onPrimary: AppColor.neutral60, secondary: AppColor.neutral60, onSecondary: Colors.white), + floatingActionButtonTheme: const FloatingActionButtonThemeData( + backgroundColor: AppColor.primary40 + ), + bottomNavigationBarTheme: const BottomNavigationBarThemeData( + backgroundColor: AppColor.neutral60, + unselectedItemColor: AppColor.neutral10, + selectedItemColor: AppColor.primary70 + ), + appBarTheme: const AppBarTheme( + backgroundColor: AppColor.backgroundDark, + titleTextStyle: TextStyle( + color: AppColor.neutral30 + ) + ) ); } diff --git a/lib/new_views/common_widgets/add_floating_button.dart b/lib/new_views/common_widgets/add_floating_button.dart new file mode 100644 index 00000000..e7efbfba --- /dev/null +++ b/lib/new_views/common_widgets/add_floating_button.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; + +import '../app_style/app_color.dart'; + +class AddFloatingButton extends StatelessWidget { + final VoidCallback onPressed; + const AddFloatingButton({Key key, @required this.onPressed}) : super(key: key); + + @override + Widget build(BuildContext context) { + return FloatingActionButton( + onPressed: onPressed, + child: Icon(Icons.add , color: context.isDark? AppColor.neutral50:AppColor.neutral30, ), + ); + } +} diff --git a/lib/new_views/common_widgets/app_bar/custom_app_bar.dart b/lib/new_views/common_widgets/app_bar/custom_app_bar.dart new file mode 100644 index 00000000..dbf1e5b0 --- /dev/null +++ b/lib/new_views/common_widgets/app_bar/custom_app_bar.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; + +import '../../app_style/app_color.dart'; + +class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { + String title; + CustomAppBar({Key key, this.title}) : super(key: key); + + @override + Widget build(BuildContext context) { + return AppBar( + title: Text(title, style: Theme.of(context).textTheme.displaySmall?.copyWith(fontWeight: FontWeight.w600, color: AppColor.neutral50)), + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, size: 24,), + onPressed: + () { + Navigator.of(context).pop(); + }, + ), + ); + } + + @override + Size get preferredSize => Size.fromHeight(60); + +} \ No newline at end of file diff --git a/lib/new_views/common_widgets/app_bar/home_app_bar.dart b/lib/new_views/common_widgets/app_bar/home_app_bar.dart new file mode 100644 index 00000000..e58852a0 --- /dev/null +++ b/lib/new_views/common_widgets/app_bar/home_app_bar.dart @@ -0,0 +1,51 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:test_sa/new_views/common_widgets/app_bar/user_image.dart'; + +import '../../../models/user.dart'; +import '../../app_style/app_color.dart'; +import 'notification_icon.dart'; + +class HomeAppBar extends StatefulWidget implements PreferredSizeWidget{ + int notificationCount; + String userImage; + HomeAppBar({Key key, this.notificationCount}) : super(key: key); + + @override + State createState() => _AppBarState(); + + @override + Size get preferredSize => const Size.fromHeight(150); +} + +class _AppBarState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 30.0, right: 12, left: 12), + child: PreferredSize( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + UserImage(url: widget.userImage,), + NotificationIcon(notificationCount: 3,) + ], + ), + // SizedBox(height: 15), + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text("welcome," , style: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w500, color: AppColor.neutral20)), + // Text("Engineer name" , style: Theme.of(context).textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.w600)), + // ], + // ) + ], + ), + + ), + ); + } +} diff --git a/lib/new_views/common_widgets/app_bar/notification_icon.dart b/lib/new_views/common_widgets/app_bar/notification_icon.dart new file mode 100644 index 00000000..1db7de74 --- /dev/null +++ b/lib/new_views/common_widgets/app_bar/notification_icon.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +import '../../app_style/app_color.dart'; + +class NotificationIcon extends StatelessWidget { + int notificationCount; + NotificationIcon({Key key, this.notificationCount}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + const Icon(Icons.notifications, size: 36,), + if(notificationCount != null) + Positioned( + right: 0, + child: Container( + height: 20, + width: 20, + padding: EdgeInsets.all(1), + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(10), + ), + child: Text( + notificationCount.toString(), + style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w500,color: AppColor.neutral30), + textAlign: TextAlign.center, + ), + ), + ) + ], + ); + } +} diff --git a/lib/new_views/common_widgets/app_bar/user_image.dart b/lib/new_views/common_widgets/app_bar/user_image.dart new file mode 100644 index 00000000..46f77e92 --- /dev/null +++ b/lib/new_views/common_widgets/app_bar/user_image.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +class UserImage extends StatelessWidget { + String url; + UserImage({Key key, @required this.url}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 48, + width: 48, + child: CircleAvatar( + //backgroundColor: Colors.transparent, + child: Image.network(url??''), + //backgroundImage: NetworkImage(url), + )); + } +} diff --git a/lib/new_views/common_widgets/bottom_nav_bar/home_bottom_nav_bar.dart b/lib/new_views/common_widgets/bottom_nav_bar/home_bottom_nav_bar.dart new file mode 100644 index 00000000..d10ccbb1 --- /dev/null +++ b/lib/new_views/common_widgets/bottom_nav_bar/home_bottom_nav_bar.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:test_sa/extensions/context_extension.dart'; + +import '../../../models/enums/translation_keys.dart'; +import '../../app_style/app_color.dart'; + +class HomeBottomNavigationBar extends StatefulWidget { + final Function(int index) onPressed; + const HomeBottomNavigationBar({Key key, @required this.onPressed}) : super(key: key); + + @override + State createState() => _HomeBottomNavigationBarState(); +} + +class _HomeBottomNavigationBarState extends State { + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + widget.onPressed.call(index); + } + + @override + Widget build(BuildContext context) { + return Material( + elevation: 20, + borderRadius: const BorderRadius.only(topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)), + child: SizedBox( + height: 100, + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(20.0)), + child: BottomNavigationBar( + items: [ + BottomNavigationBarItem( + icon: SvgPicture.asset('assets/images/Overview.svg', width: 24, height: 24, + color: _selectedIndex == 0? AppColor.primary70:AppColor.neutral20), + label: context.translate(TranslationKeys.overview), + ), + BottomNavigationBarItem( + icon: SvgPicture.asset('assets/images/requests.svg', width: 24, height: 24, + color: _selectedIndex == 1? AppColor.primary70:AppColor.neutral20), + label: context.translate(TranslationKeys.myRequest), + ), + BottomNavigationBarItem( + icon: SvgPicture.asset('assets/images/assets.svg',width: 24, height: 24, + color: _selectedIndex == 2? AppColor.primary70:AppColor.neutral20), + label: context.translate(TranslationKeys.myRequest), + ), + BottomNavigationBarItem( + icon: SvgPicture.asset('assets/images/message.svg', width: 24, height: 24, + color: _selectedIndex == 3? AppColor.primary70:AppColor.neutral20), + label: context.translate(TranslationKeys.contactUs), + ), + ], + currentIndex: _selectedIndex, + type: BottomNavigationBarType.fixed, + unselectedFontSize: 14, + unselectedLabelStyle: const TextStyle(height: 2), + selectedLabelStyle: const TextStyle(height: 2), + selectedItemColor: AppColor.primary70, + unselectedItemColor: AppColor.neutral20, + onTap: _onItemTapped, + ), + ), + ), + ); + } +} diff --git a/lib/new_views/common_widgets/app_bar.dart b/lib/new_views/common_widgets/pagination_bar.dart similarity index 100% rename from lib/new_views/common_widgets/app_bar.dart rename to lib/new_views/common_widgets/pagination_bar.dart diff --git a/lib/new_views/common_widgets/test screen.dart b/lib/new_views/common_widgets/test screen.dart new file mode 100644 index 00000000..ac899292 --- /dev/null +++ b/lib/new_views/common_widgets/test screen.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/new_views/common_widgets/app_bar/custom_app_bar.dart'; + +import 'add_floating_button.dart'; +import 'app_bar/home_app_bar.dart'; +import 'bottom_nav_bar/home_bottom_nav_bar.dart'; + +class TestScreen extends StatefulWidget { + static const String id = '/test'; + const TestScreen({Key key}) : super(key: key); + + @override + State createState() => _TestScreenState(); +} + +class _TestScreenState extends State { + int screenIndex =0; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: HomeAppBar(), + body: Center(child: _widgetOptions[screenIndex]), + floatingActionButton: AddFloatingButton(onPressed: () {},), + bottomNavigationBar: HomeBottomNavigationBar(onPressed: (index){ + setState(() { + screenIndex = index; + }); + },), + ); + } + + static const List _widgetOptions = [ + Text( + 'Index 0', + ), + Text( + 'Index 1', + ), + Text( + 'Index 2', + ), + Text( + 'Index 3', + ), + ]; +}