diff --git a/car_booking/assets/icons/settings.png b/car_booking/assets/icons/settings.png new file mode 100644 index 0000000..c818eb3 Binary files /dev/null and b/car_booking/assets/icons/settings.png differ diff --git a/car_booking/lib/main.dart b/car_booking/lib/main.dart index ec7c532..273b7d0 100644 --- a/car_booking/lib/main.dart +++ b/car_booking/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'screens/Account/profile_screen.dart'; import 'screens/available/available_car_screen.dart'; import 'screens/detail/car_detail_screen.dart'; import 'screens/login/login_screen.dart'; @@ -31,6 +32,7 @@ class MyApp extends StatelessWidget { '/': (context) => LoginScreen(), 'CreateNewAccount': (context) => CreateNewAccount(), 'AvailableCarScreen': (context) => AvailableCarScreen(), + 'ProfileScreen': (context) => ProfileScreen(), }, ); } diff --git a/car_booking/lib/screens/Account/profile_screen.dart b/car_booking/lib/screens/Account/profile_screen.dart new file mode 100644 index 0000000..fa1d932 --- /dev/null +++ b/car_booking/lib/screens/Account/profile_screen.dart @@ -0,0 +1,131 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../../constants.dart'; +import 'widget/appbar.dart'; +import 'widget/body.dart'; +import 'widget/button.dart'; +import 'widget/number.dart'; +import 'widget/profile.dart'; +import 'widget/user.dart'; +import 'widget/user_prefrance.dart'; + + +class ProfileScreen extends StatefulWidget { + @override + _ProfileScreenState createState() => _ProfileScreenState(); +} + +class _ProfileScreenState extends State { + @override + Widget build(BuildContext context) { + final user = UserPreferences.myUser; + + return Scaffold( + appBar: buildAppBar(context), + body: Padding( + padding: const EdgeInsets.all(8.0), + child: ListView( + physics: BouncingScrollPhysics(), + children: [ + ProfileWidget( + imagePath: user.imagePath, + onClicked: () async {}, + ), + const SizedBox(height: 24), + buildName(user), + const SizedBox(height: 24), + NumbersWidget(), + const SizedBox(height: 24), + Body(), + ], + ), + ), + bottomNavigationBar: BuildBottomNavigationBar(), + ); + } + + Widget buildName(User user) => Column( + children: [ + Text( + user.name, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), + ), + const SizedBox(height: 4), + Text( + user.email, + style: TextStyle(color: Colors.grey), + ) + ], + ); + + Widget buildUpgradeButton() => ButtonWidget( + text: 'Pro Membership', + onClicked: () {}, + ); + + Widget buildAbout(User user) => Container( + padding: EdgeInsets.symmetric(horizontal: 48), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'About', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + ], + ), + + ); + +} + + + + +class BuildBottomNavigationBar extends StatefulWidget { + @override + _BuildBottomNavigationBarState createState() => _BuildBottomNavigationBarState(); +} + +class _BuildBottomNavigationBarState extends State { + List bottomNavIcons = [ + 'assets/icons/app.png', + 'assets/icons/calendar.png', + 'assets/icons/pin.png', + 'assets/icons/user.png', + ]; + int selected = 0 ; + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 25, vertical: 15), + color:Color(0xFF203e5a), + height: 65, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: bottomNavIcons.length, + itemBuilder: (context, index) => GestureDetector( + onTap: (){ + setState(() { + selected = index; + + + }); + }, + child: Padding( + padding: EdgeInsets.only(right: mpadding * 2, left: mpadding), + child: Image.asset( + bottomNavIcons[index], + height: 40, + color: selected == index ? mbottonColor :Colors.grey, + ), + ), + ) + ), + ); + } +} + + + diff --git a/car_booking/lib/screens/Account/widget/appbar.dart b/car_booking/lib/screens/Account/widget/appbar.dart new file mode 100644 index 0000000..8808054 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/appbar.dart @@ -0,0 +1,27 @@ +import 'package:car_booking/constants.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +AppBar buildAppBar(BuildContext context) { + final icon = CupertinoIcons.moon_stars; + + return AppBar( + backgroundColor: mCardColor, + elevation: 0, + leading:IconButton( + icon: Icon( + Icons.menu, + color: Colors.white, + ), + onPressed: () {}, + ), + centerTitle: true, + title:Text('Profile'), + actions: [ + IconButton( + icon: Icon(icon), + onPressed: () {}, + ), + ], + ); +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/body.dart b/car_booking/lib/screens/Account/widget/body.dart new file mode 100644 index 0000000..66fab4f --- /dev/null +++ b/car_booking/lib/screens/Account/widget/body.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +import 'menu.dart'; +import 'profile_pic.dart'; + +class Body extends StatelessWidget { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + padding: EdgeInsets.symmetric(vertical: 20), + child: Column( + children: [ + ProfileMenu( + text: "My Account", + icon: "assets/icons/user.png", + press: () => {}, + ), + ProfileMenu( + text: "Notifications", + icon: "assets/icons/bell.png", + press: () {}, + ), + ProfileMenu( + text: "Settings", + icon: "assets/icons/settings.png", + press: () {}, + ), + ProfileMenu( + text: "Help", + icon: "assets/icons/information.png", + press: () {}, + ), + ProfileMenu( + text: "Total Bills", + icon: "assets/icons/windshield.png", + press: () {}, + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/button.dart b/car_booking/lib/screens/Account/widget/button.dart new file mode 100644 index 0000000..c1f61f8 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/button.dart @@ -0,0 +1,26 @@ +import 'package:car_booking/constants.dart'; +import 'package:flutter/material.dart'; + +class ButtonWidget extends StatelessWidget { + final String text; + final VoidCallback onClicked; + + const ButtonWidget({ + Key? key, + required this.text, + required this.onClicked, + }) : super(key: key); + + @override + Widget build(BuildContext context) => ElevatedButton( + + style: ElevatedButton.styleFrom( + shape: StadiumBorder(), + onSurface: mCardColor, + onPrimary: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12), + ), + child: Text(text), + onPressed: onClicked + ); + } \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/menu.dart b/car_booking/lib/screens/Account/widget/menu.dart new file mode 100644 index 0000000..b3c8e45 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/menu.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; + + +class ProfileMenu extends StatelessWidget { + const ProfileMenu({ + Key? key, + required this.text, + required this.icon, + this.press, + }) : super(key: key); + + final String text, icon; + final VoidCallback? press; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: TextButton( + style: TextButton.styleFrom( + primary: Color(0xFF203e5a), + padding: EdgeInsets.all(20), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + backgroundColor: Color(0xFFF5F6F9), + ), + onPressed: press, + child: Row( + children: [ + Image.asset( + icon, + color: Color(0xFF203e5a), + width: 22, + ), + SizedBox(width: 20), + Expanded(child: Text(text)), + Icon(Icons.arrow_forward_ios), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/number.dart b/car_booking/lib/screens/Account/widget/number.dart new file mode 100644 index 0000000..521d773 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/number.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +class NumbersWidget extends StatelessWidget { + @override + Widget build(BuildContext context) => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + buildButton(context, '4.8', 'Ratings'), + buildDivider(), + buildButton(context, '35', 'Booked Rides'), + buildDivider(), + buildButton(context, '5', 'Cncelled Rides'), + ], + ); + Widget buildDivider() => Container( + height: 24, + child: VerticalDivider(), + ); + + Widget buildButton(BuildContext context, String value, String text) => + MaterialButton( + padding: EdgeInsets.symmetric(vertical: 4), + onPressed: () {}, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + value, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), + ), + SizedBox(height: 2), + Text( + text, + style: TextStyle(fontWeight: FontWeight.bold), + ), + ], + ), + ); +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/profile.dart b/car_booking/lib/screens/Account/widget/profile.dart new file mode 100644 index 0000000..8dc61bb --- /dev/null +++ b/car_booking/lib/screens/Account/widget/profile.dart @@ -0,0 +1,77 @@ +import 'dart:io'; + +import 'package:car_booking/constants.dart'; +import 'package:flutter/material.dart'; + +class ProfileWidget extends StatelessWidget { + final String imagePath; + final VoidCallback onClicked; + + const ProfileWidget({ + Key? key, + required this.imagePath, + required this.onClicked, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final color = mCardColor; + + return Center( + child: Stack( + children: [ + buildImage(), + Positioned( + bottom: 0, + right: 4, + child: buildEditIcon(color), + ), + ], + ), + ); + } + + Widget buildImage() { + final image = NetworkImage(imagePath); + + return ClipOval( + child: Material( + color: Colors.transparent, + child: Ink.image( + image: image, + fit: BoxFit.cover, + width: 128, + height: 128, + child: InkWell(onTap: onClicked), + ), + ), + ); + } + + Widget buildEditIcon(Color color) => buildCircle( + color: Colors.white, + all: 3, + child: buildCircle( + color: color, + all: 8, + child: Icon( + Icons.edit, + color: Colors.white, + size: 20, + ), + ), + ); + + Widget buildCircle({ + required Widget child, + required double all, + required Color color, + }) => + ClipOval( + child: Container( + padding: EdgeInsets.all(all), + color: color, + child: child, + ), + ); +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/profile_pic.dart b/car_booking/lib/screens/Account/widget/profile_pic.dart new file mode 100644 index 0000000..b79f6d0 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/profile_pic.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; + + +class ProfilePic extends StatelessWidget { + const ProfilePic({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 115, + width: 115, + child: Stack( + fit: StackFit.expand, + clipBehavior: Clip.none, + children: [ + CircleAvatar( + backgroundImage: AssetImage("assets/icons/user.png"), + ), + Positioned( + right: -16, + bottom: 0, + child: SizedBox( + height: 46, + width: 46, + child: TextButton( + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), + side: BorderSide(color: Colors.white), + ), + primary: Colors.white, + backgroundColor: Color(0xFFF5F6F9), + ), + onPressed: () {}, + child: Image.asset("assets/icons/user.png"), + ), + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/user.dart b/car_booking/lib/screens/Account/widget/user.dart new file mode 100644 index 0000000..3389b8d --- /dev/null +++ b/car_booking/lib/screens/Account/widget/user.dart @@ -0,0 +1,15 @@ +class User { + final String imagePath; + final String name; + final String email; + final String about; + final bool isDarkMode; + + const User({ + required this.imagePath, + required this.name, + required this.email, + required this.about, + required this.isDarkMode, + }); +} \ No newline at end of file diff --git a/car_booking/lib/screens/Account/widget/user_prefrance.dart b/car_booking/lib/screens/Account/widget/user_prefrance.dart new file mode 100644 index 0000000..1e2b1d4 --- /dev/null +++ b/car_booking/lib/screens/Account/widget/user_prefrance.dart @@ -0,0 +1,14 @@ + +import 'user.dart'; + +class UserPreferences { + static const myUser = User( + imagePath: + 'https://images.unsplash.com/photo-1554151228-14d9def656e4?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=333&q=80', + name: 'Olivia', + email: 'olivia@dezenix.com', + about: + '', + isDarkMode: false, + ); +} \ No newline at end of file diff --git a/car_booking/lib/screens/available/available_car_screen.dart b/car_booking/lib/screens/available/available_car_screen.dart index 00465c8..4b05d50 100644 --- a/car_booking/lib/screens/available/available_car_screen.dart +++ b/car_booking/lib/screens/available/available_car_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import '../../constants.dart'; +import '../Account/profile_screen.dart'; import 'widget/build_container.dart'; import 'widget/car_list_item.dart'; @@ -223,6 +224,15 @@ class _BuildBottomNavigationBarState extends State { onTap: (){ setState(() { selected = index; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return ProfileScreen(); + }, + ), + ); + }); }, child: Padding(