diff --git a/assets/sort.svg b/assets/sort.svg
new file mode 100644
index 0000000..553c62b
--- /dev/null
+++ b/assets/sort.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/assets/user.png b/assets/user.png
new file mode 100644
index 0000000..071dc5a
Binary files /dev/null and b/assets/user.png differ
diff --git a/assets/waves.png b/assets/waves.png
new file mode 100644
index 0000000..51b50c1
Binary files /dev/null and b/assets/waves.png differ
diff --git a/fonts/ProductSans-Bold.ttf b/fonts/ProductSans-Bold.ttf
new file mode 100644
index 0000000..96619df
Binary files /dev/null and b/fonts/ProductSans-Bold.ttf differ
diff --git a/fonts/ProductSans-Regular.ttf b/fonts/ProductSans-Regular.ttf
new file mode 100644
index 0000000..e2c69c3
Binary files /dev/null and b/fonts/ProductSans-Regular.ttf differ
diff --git a/images/bmw_i8.png b/images/bmw_i8.png
new file mode 100644
index 0000000..3fff19d
Binary files /dev/null and b/images/bmw_i8.png differ
diff --git a/images/lamborghini.png b/images/lamborghini.png
new file mode 100644
index 0000000..2d049dc
Binary files /dev/null and b/images/lamborghini.png differ
diff --git a/images/lamborghini2.png b/images/lamborghini2.png
new file mode 100644
index 0000000..d9ccd67
Binary files /dev/null and b/images/lamborghini2.png differ
diff --git a/lib/main.dart b/lib/main.dart
index 2c084ed..3e0f71d 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,255 +1,28 @@
+import 'package:car_renting/view/feed.dart';
import 'package:flutter/material.dart';
-import 'dart:math' as math;
+import 'package:flutter/services.dart';
+
void main() {
+ SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
+ statusBarColor: Colors.transparent,
+ statusBarIconBrightness: Brightness.light,
+ ));
runApp(const MyApp());
}
-class Contact {
- String image;
- String name;
- String mobileNumber;
- DateTime date;
- bool isIncoming;
-
- Contact(this.image, this.name, this.mobileNumber, this.date, this.isIncoming);
-}
-
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
- title: 'Flutter Demo 2',
+ title: 'Flutter Demo',
+ debugShowCheckedModeBanner: false,
theme: ThemeData(
+ fontFamily: 'ProductSans',
primarySwatch: Colors.blue,
),
- debugShowCheckedModeBanner: false,
- home: const MyHomePage(title: 'Contacts App'),
- );
- }
-}
-
-class MyHomePage extends StatefulWidget {
- const MyHomePage({Key? key, required this.title}) : super(key: key);
-
- final String title;
-
- @override
- State createState() => _MyHomePageState();
-}
-
-class _MyHomePageState extends State {
- int _selectedIndex = 2;
- static const TextStyle optionStyle =
- TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
- static late List _pages;
-
- _MyHomePageState() {
- _pages = [
- buildContactsList(),
- buildFavoritesGridView(),
- // Text('hello'),
- Text(
- 'Index 2: School',
- style: optionStyle,
- ),
- ];
- }
-
- void _onItemTapped(int index) {
- setState(() {
- _selectedIndex = index;
- });
- }
-
- var contacts = [
- Contact(
- 'https://i.pravatar.cc/300',
- 'Ahmed',
- '71766137347',
- DateTime.now().add(
- const Duration(seconds: 3),
- ),
- true,
- ),
- Contact(
- 'https://i.pravatar.cc/301',
- 'Ali',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 1),
- ),
- false,
- ),
- Contact(
- 'https://i.pravatar.cc/302',
- 'Kamal',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 3),
- ),
- true,
- ),
- Contact(
- 'https://i.pravatar.cc/303',
- 'Mohammad',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 5),
- ),
- true,
- ),
- Contact(
- 'https://i.pravatar.cc/304',
- 'Mohammad',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 5),
- ),
- false,
- ),
- Contact(
- 'https://i.pravatar.cc/305',
- 'Hussein',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 6),
- ),
- false,
- ),
- Contact(
- 'https://i.pravatar.cc/306',
- 'Aboud',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 7),
- ),
- false,
- ),
- Contact(
- 'https://i.pravatar.cc/307',
- 'Osama',
- '71766137347',
- DateTime.now().add(
- const Duration(days: 6),
- ),
- false,
- ),
- ];
-
- Widget buildFavoritesGridView() {
- return Column(
- children: [
- Text('Favorites'),
- Divider(thickness: 4,),
- Expanded(
- child: GridView.count(
- crossAxisCount: 3,
- children: List.generate(5, (index) {
- var personColor = Color((math.Random().nextDouble() * 0xFFFFFF).toInt())
- .withOpacity(1.0);
- return Center(
- child: Container(
- width: 120,
- height: 120,
- child: Text(
- contacts[index].name[0],
- style: TextStyle(fontSize: 40),
- ),
- alignment: Alignment.center,
- decoration:
- BoxDecoration(shape: BoxShape.circle, color: personColor),
- ),
- );
- }),
- ),
- ),
- ],
- );
- }
-
- Widget buildContactItem(Contact _contact) {
- return Card(
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Row(
- children: [
- CircleAvatar(
- backgroundImage: NetworkImage(_contact.image),
- ),
- Padding(
- padding: const EdgeInsets.all(16),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- _contact.name,
- style: const TextStyle(fontWeight: FontWeight.bold),
- ),
- Text(_contact.mobileNumber),
- ],
- ),
- ),
- Text(_contact.date.toIso8601String().split('T').first),
- Expanded(
- child: Container(),
- ),
- if (_contact.isIncoming)
- Icon(
- Icons.arrow_downward,
- color: Colors.red,
- )
- else
- Icon(
- Icons.arrow_upward,
- color: Colors.green,
- )
- ],
- ),
- ),
- );
- }
-
- Widget buildContactsList() {
- return ListView.builder(
- itemBuilder: (_context, index) {
- return buildContactItem(contacts[index]);
- },
- itemCount: contacts.length,
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- ),
- body: Center(
- child: _pages[_selectedIndex],
- ),
- bottomNavigationBar: BottomNavigationBar(
- items: const [
- BottomNavigationBarItem(
- icon: Icon(Icons.home),
- label: 'Recent',
- ),
- BottomNavigationBarItem(
- icon: Icon(Icons.favorite),
- label: 'Favorites',
- ),
- BottomNavigationBarItem(
- icon: Icon(Icons.access_time_outlined),
- label: 'School',
- activeIcon: Icon(Icons.access_time_filled)
- ),
- ],
- currentIndex: _selectedIndex,
- selectedItemColor: Colors.amber[800],
- onTap: _onItemTapped,
- ),
+ home: const CarFeedPage(),
);
}
}
diff --git a/lib/model/car.dart b/lib/model/car.dart
new file mode 100644
index 0000000..72b30f7
--- /dev/null
+++ b/lib/model/car.dart
@@ -0,0 +1,35 @@
+class Car {
+ String name;
+ String image;
+ int price;
+ double rating;
+ int deals;
+
+ Car(
+ {required this.image,
+ required this.name,
+ required this.price,
+ required this.rating,
+ required this.deals});
+}
+
+List cars = [
+ Car(
+ image: 'images/bmw_i8.png',
+ name: 'BMW i8',
+ price: 299,
+ rating: 4.3,
+ deals: 15),
+ Car(
+ image: 'images/lamborghini.png',
+ name: 'Lamborghini Huracan',
+ price: 599,
+ rating: 4.8,
+ deals: 27),
+ Car(
+ image: 'images/lamborghini2.png',
+ name: 'Lamborghini Gallardo',
+ price: 399,
+ rating: 4.5,
+ deals: 18),
+];
diff --git a/lib/view/car_details.dart b/lib/view/car_details.dart
new file mode 100644
index 0000000..06407df
--- /dev/null
+++ b/lib/view/car_details.dart
@@ -0,0 +1,383 @@
+import 'package:car_renting/model/car.dart';
+import 'package:flutter/material.dart';
+
+class CarDetailsView extends StatefulWidget {
+ const CarDetailsView({Key? key, required this.car}) : super(key: key);
+ final Car car;
+ @override
+ _CarDetailsViewState createState() => _CarDetailsViewState();
+}
+
+class _CarDetailsViewState extends State {
+ @override
+ Widget build(BuildContext context) {
+ Size size = MediaQuery.of(context).size;
+ return Scaffold(
+ backgroundColor: Colors.blueGrey.shade50,
+ body: Stack(
+ children: [
+ Positioned(
+ width: size.width,
+ height: size.height * 0.3,
+ top: 0,
+ right: 0,
+ child: ClipRRect(
+ borderRadius: const BorderRadius.only(
+ bottomLeft: Radius.circular(30),
+ bottomRight: Radius.circular(30)),
+ child: Image.asset(
+ 'assets/waves.png',
+ width: size.width,
+ fit: BoxFit.fill,
+ ),
+ ),
+ ),
+ Positioned(
+ width: size.width * 0.9,
+ height: size.height * 0.4,
+ top: size.height * 0.2,
+ right: size.width * .05,
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(60),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.2),
+ blurRadius: 20,
+ spreadRadius: 0,
+ offset: const Offset(5, 5))
+ ],
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ SizedBox(
+ height: size.height * .13,
+ ),
+ Text(
+ widget.car.name,
+ style: const TextStyle(
+ color: Colors.black87,
+ fontSize: 25,
+ fontWeight: FontWeight.w800),
+ ),
+ SizedBox(
+ height: size.height * .02,
+ ),
+ const Text(
+ '4 doors | Sport Package',
+ style: TextStyle(color: Colors.grey, fontSize: 18),
+ ),
+ SizedBox(
+ height: size.height * .02,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: const [
+ Icon(
+ Icons.star,
+ color: Colors.amberAccent,
+ size: 20,
+ ),
+ Icon(
+ Icons.star,
+ color: Colors.amberAccent,
+ size: 20,
+ ),
+ Icon(
+ Icons.star,
+ color: Colors.amberAccent,
+ size: 20,
+ ),
+ Icon(
+ Icons.star,
+ color: Colors.amberAccent,
+ size: 20,
+ ),
+ Icon(
+ Icons.star_outline,
+ color: Colors.amberAccent,
+ size: 20,
+ ),
+ Text(
+ '(23.5k)',
+ style: TextStyle(color: Colors.grey, fontSize: 18),
+ ),
+ ],
+ ),
+ SizedBox(
+ height: size.height * .02,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ Column(
+ children: const [
+ Icon(
+ Icons.settings,
+ color: Colors.black87,
+ ),
+ Text('Automatic'),
+ ],
+ ),
+ Column(
+ children: const [
+ Icon(
+ Icons.ac_unit,
+ color: Colors.black87,
+ ),
+ Text('Air Con.'),
+ ],
+ ),
+ Column(
+ children: const [
+ Icon(
+ Icons.person,
+ color: Colors.black87,
+ ),
+ Text('5 Seater'),
+ ],
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ Positioned(
+ width: size.width * 0.7,
+ height: size.height * 0.3,
+ top: size.height * 0.06,
+ right: size.width * .15,
+ child: Image.asset(widget.car.image)),
+ Positioned(
+ top: size.height * 0.04,
+ left: size.height * 0.02,
+ width: 30,
+ height: 30,
+ child: IconButton(
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ icon: const Icon(
+ Icons.arrow_back_ios,
+ color: Colors.white,
+ ))),
+ Positioned(
+ top: size.height * 0.63,
+ left: size.height * 0.03,
+ width: size.width * 0.88,
+ height: size.height * 0.37,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text(
+ 'Trip Dates',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 21,
+ fontWeight: FontWeight.w800),
+ ),
+ const SizedBox(height: 10),
+ Row(
+ children: [
+ ClipPath(
+ clipper: MyCustomClipper(),
+ child: Container(
+ width: size.width * 0.75,
+ padding: const EdgeInsets.symmetric(
+ horizontal: 15, vertical: 10),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(20),
+ bottomLeft: Radius.circular(20)),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.3),
+ blurRadius: 20,
+ spreadRadius: 0,
+ offset: const Offset(5, 5))
+ ],
+ ),
+ child: Row(children: [
+ Container(
+ width: 40,
+ height: 40,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(15),
+ color: const Color(0xfff26cab)),
+ child: const Icon(
+ Icons.date_range_outlined,
+ color: Colors.white,
+ )),
+ const Text(
+ ' Miami, 786 FL',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 16,
+ fontWeight: FontWeight.w600),
+ ),
+ ]),
+ ),
+ ),
+ Container(
+ width: 50,
+ height: 50,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ color: const Color(0xff2156c0)),
+ child: const Icon(
+ Icons.double_arrow_rounded,
+ color: Colors.white,
+ ),
+ )
+ ],
+ ),
+ const SizedBox(height: 10),
+ const Text(
+ 'Pickup & Return',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 21,
+ fontWeight: FontWeight.w800),
+ ),
+ const SizedBox(height: 10),
+ Row(
+ children: [
+ ClipPath(
+ clipper: MyCustomClipper(),
+ child: Container(
+ width: size.width * 0.75,
+ padding: const EdgeInsets.symmetric(
+ horizontal: 15, vertical: 10),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(20),
+ bottomLeft: Radius.circular(20)),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.2),
+ blurRadius: 20,
+ spreadRadius: 0,
+ offset: const Offset(5, 5))
+ ],
+ ),
+ child: Row(children: [
+ Container(
+ width: 40,
+ height: 40,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(15),
+ color: const Color(0xfff26cab)),
+ child: const Icon(
+ Icons.location_on,
+ color: Colors.white,
+ )),
+ const Text(
+ ' Miami, 786 FL',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 16,
+ fontWeight: FontWeight.w600),
+ ),
+ ]),
+ ),
+ ),
+ Container(
+ width: 50,
+ height: 50,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(20),
+ color: const Color(0xff2156c0)),
+ child: const Icon(
+ Icons.double_arrow_rounded,
+ color: Colors.white,
+ ),
+ )
+ ],
+ ),
+ ],
+ )),
+ Positioned(
+ top: size.height * 0.91,
+ left: 0,
+ width: size.width,
+ height: size.height * 0.09,
+ child: Container(
+ width: size.width,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(40),
+ topRight: Radius.circular(40)),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.2),
+ blurRadius: 20,
+ spreadRadius: 0,
+ offset: const Offset(5, 5))
+ ],
+ ),
+ child: Padding(
+ padding: const EdgeInsets.only(
+ top: 10, left: 20, right: 20, bottom: 5),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text(
+ 'Total',
+ style: TextStyle(color: Colors.grey, fontSize: 16),
+ ),
+ Text(
+ '${widget.car.price} / trip',
+ style: const TextStyle(
+ color: Colors.black87,
+ fontSize: 18,
+ fontWeight: FontWeight.w800),
+ ),
+ ],
+ ),
+ ElevatedButton(
+ style: ElevatedButton.styleFrom(
+ elevation: 0,
+ primary: Colors.redAccent,
+ shape: const StadiumBorder()),
+ onPressed: () {},
+ child: const Text('Go to Checkout'),
+ ),
+ ],
+ ),
+ ),
+ )),
+ ],
+ ),
+ );
+ }
+}
+
+class MyCustomClipper extends CustomClipper {
+ @override
+ Path getClip(Size size) {
+ var path = Path();
+ path.moveTo(0, 0);
+ path.lineTo(0, size.height);
+ path.lineTo(size.width + 80, size.height);
+ path.quadraticBezierTo(size.width / 1.15, size.height * 1.45,
+ size.width / 1.013, size.height * 0.035);
+ path.lineTo(size.width, 0);
+ return path;
+ }
+
+ @override
+ bool shouldReclip(covariant CustomClipper oldClipper) {
+ return true;
+ }
+}
diff --git a/lib/view/feed.dart b/lib/view/feed.dart
new file mode 100644
index 0000000..6b33df7
--- /dev/null
+++ b/lib/view/feed.dart
@@ -0,0 +1,54 @@
+import 'package:car_renting/model/car.dart';
+import 'package:flutter/material.dart';
+import 'widget/app_bar.dart';
+import 'widget/cars_cards.dart';
+
+class CarFeedPage extends StatelessWidget {
+ const CarFeedPage({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+
+ return Scaffold(
+ backgroundColor: const Color(0xfffcfcfc),
+ appBar: const PreferredSize(
+ preferredSize: Size.fromHeight(180), child: MyAppBar()),
+ body: Column(
+ children: [
+ Container(
+ padding: const EdgeInsets.only(top: 17, left: 17, right: 17),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: const [
+ Text(
+ '23 Results',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 21,
+ fontWeight: FontWeight.w700),
+ ),
+ Icon(
+ Icons.more_horiz,
+ color: Colors.black87,
+ size: 33,
+ )
+ ],
+ ),
+ ),
+ Expanded(
+ child: ListView.builder(
+ scrollDirection: Axis.vertical,
+ shrinkWrap: true,
+ itemBuilder: (_context, index) {
+ return BuildCardView(
+ car: cars[index],
+ );
+ },
+ itemCount: cars.length,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/view/widget/app_bar.dart b/lib/view/widget/app_bar.dart
new file mode 100644
index 0000000..ccbdfe4
--- /dev/null
+++ b/lib/view/widget/app_bar.dart
@@ -0,0 +1,110 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class MyAppBar extends StatelessWidget {
+ const MyAppBar({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ Size size = MediaQuery.of(context).size;
+ return Stack(
+ children: [
+ ClipRRect(
+ borderRadius: const BorderRadius.only(
+ bottomLeft: Radius.circular(30),
+ bottomRight: Radius.circular(30)),
+ child: Image.asset(
+ 'assets/waves.png',
+ width: size.width,
+ fit: BoxFit.fill,
+ ),
+ ),
+ Positioned(
+ height: 50,
+ width: size.width * 0.9,
+ left: size.width * 0.05,
+ top: 27,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ SvgPicture.asset(
+ 'assets/sort.svg',
+ width: 30,
+ ),
+ Image.asset(
+ 'assets/user.png',
+ width: 40,
+ )
+ ],
+ )),
+ Positioned(
+ height: 30,
+ left: size.width * 0.05,
+ top: size.height * 0.12,
+ child: const Text(
+ 'Choose a Car',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 24,
+ fontWeight: FontWeight.w600),
+ )),
+ Positioned(
+ height: 50,
+ left: size.width * 0.05,
+ top: size.height * 0.17,
+ child: Row(
+ children: [
+ Container(
+ width: size.width * 0.8,
+ padding: const EdgeInsets.only(
+ top: 5, bottom: 5, left: 15, right: 5),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(15), // radius of 10
+ color: Colors.white,
+ ),
+ child: Row(
+ children: [
+ const Icon(
+ Icons.location_on_outlined,
+ color: Colors.grey,
+ size: 24,
+ ),
+ const Text(
+ ' Florida, USA',
+ style: TextStyle(
+ color: Colors.black87,
+ fontSize: 17,
+ fontWeight: FontWeight.bold),
+ ),
+ Expanded(
+ child: Container(),
+ ),
+ Container(
+ width: 40,
+ height: 40,
+ decoration: BoxDecoration(
+ borderRadius:
+ BorderRadius.circular(13), // radius of 10
+ color: const Color(0xfff26cab)),
+ child: const Icon(
+ Icons.date_range_outlined,
+ color: Colors.white,
+ ))
+ ],
+ ),
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ const Icon(
+ Icons.tune_outlined,
+ color: Colors.white,
+ size: 30,
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/view/widget/cars_cards.dart b/lib/view/widget/cars_cards.dart
new file mode 100644
index 0000000..af4cf0b
--- /dev/null
+++ b/lib/view/widget/cars_cards.dart
@@ -0,0 +1,166 @@
+import 'package:car_renting/model/car.dart';
+import 'package:flutter/material.dart';
+
+import '../car_details.dart';
+
+class BuildCardView extends StatefulWidget {
+ const BuildCardView({Key? key, required this.car}) : super(key: key);
+ final Car car;
+ @override
+ _BuildCardViewState createState() => _BuildCardViewState();
+}
+
+class _BuildCardViewState extends State {
+ @override
+ Widget build(BuildContext context) {
+ // Size size = MediaQuery.of(context).size;
+ return Padding(
+ padding: const EdgeInsets.all(20),
+ child: Container(
+ decoration: BoxDecoration(
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.3),
+ blurRadius: 20,
+ spreadRadius: 0,
+ offset: const Offset(5, 5))
+ ],
+ ),
+ child: Stack(
+ children: [
+ ClipPath(
+ clipper: MyCustomClipper(),
+ child: Card(
+ elevation: 0,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(35),
+ ),
+ color: Colors.white,
+ child: Padding(
+ padding: const EdgeInsets.all(30),
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ padding: const EdgeInsets.symmetric(
+ vertical: 4, horizontal: 7),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(13),
+ color: const Color(0xfffec05f)),
+ child: Row(
+ children: [
+ const Icon(
+ Icons.star_rounded,
+ color: Colors.white,
+ size: 17,
+ ),
+ Text(
+ ' ${widget.car.rating}',
+ style: const TextStyle(
+ color: Colors.white,
+ fontSize: 17,
+ fontWeight: FontWeight.w800),
+ )
+ ],
+ ),
+ ),
+ Text(
+ ' ${widget.car.deals} Deals',
+ style: const TextStyle(
+ color: Color(0xff78c4ad),
+ fontSize: 17,
+ fontWeight: FontWeight.w800),
+ )
+ ],
+ ),
+ Center(
+ child: Image.asset(widget.car.image),
+ ),
+ const SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ widget.car.name,
+ style: const TextStyle(
+ color: Colors.black87,
+ fontSize: 20,
+ fontWeight: FontWeight.bold),
+ ),
+ Text(
+ 'From${widget.car.price} /day',
+ style: const TextStyle(
+ color: Colors.grey,
+ fontSize: 17,
+ fontWeight: FontWeight.w800),
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ Positioned(
+ height: 80,
+ width: 80,
+ bottom: 0,
+ right: 0,
+ child: IconButton(
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => CarDetailsView(
+ car: widget.car,
+ )),
+ );
+ },
+ icon: Container(
+ width: 80,
+ height: 80,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(25),
+ color: const Color(0xff2156c0)),
+ child: const Icon(
+ Icons.double_arrow_rounded,
+ color: Colors.white,
+ ),
+ )),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class MyCustomClipper extends CustomClipper {
+ @override
+ Path getClip(Size size) {
+
+ var path = Path();
+ path.moveTo(0, 0);
+ path.lineTo(0, size.height);
+ path.lineTo(size.width * 0.76, size.height);
+
+ path.quadraticBezierTo(
+ size.width / 1.45, size.height * 0.67, size.width, size.height / 1.35);
+ path.lineTo(size.width, 0);
+ return path;
+ }
+
+ @override
+ bool shouldReclip(covariant CustomClipper oldClipper) {
+ return true;
+ }
+}
diff --git a/lib/view/widget/details_card.dart b/lib/view/widget/details_card.dart
new file mode 100644
index 0000000..001e9f0
--- /dev/null
+++ b/lib/view/widget/details_card.dart
@@ -0,0 +1,19 @@
+import 'package:car_renting/model/car.dart';
+import 'package:flutter/material.dart';
+
+class BuildDetailsView extends StatefulWidget {
+ const BuildDetailsView({ Key? key,required this.car }) : super(key: key);
+ final Car car;
+
+ @override
+ _BuildDetailsViewState createState() => _BuildDetailsViewState();
+}
+
+class _BuildDetailsViewState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 750761f..92c58ab 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -69,6 +69,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.23.0+1"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -102,6 +109,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
+ path_drawing:
+ dependency: transitive
+ description:
+ name: path_drawing
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.5.1+1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "4.3.0"
sky_engine:
dependency: transitive
description: flutter
@@ -163,5 +191,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "5.3.0"
sdks:
- dart: ">=2.12.0 <3.0.0"
+ dart: ">=2.14.0 <3.0.0"
+ flutter: ">=1.24.0-7.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 1c93cc7..7fb34fd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,4 +1,4 @@
-name: contacts_01
+name: car_renting
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
@@ -34,6 +34,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
+ flutter_svg: ^0.23.0+1
dev_dependencies:
flutter_test:
@@ -58,9 +59,9 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
+ assets:
+ - assets/
+ - images/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
@@ -73,12 +74,11 @@ flutter:
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
- # fonts:
- # - family: Schyler
- # fonts:
- # - asset: fonts/Schyler-Regular.ttf
- # - asset: fonts/Schyler-Italic.ttf
- # style: italic
+ fonts:
+ - family: ProductSans
+ fonts:
+ - asset: fonts/ProductSans-Regular.ttf
+ - asset: fonts/ProductSans-Bold.ttf
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
diff --git a/test/widget_test.dart b/test/widget_test.dart
deleted file mode 100644
index 5f578bd..0000000
--- a/test/widget_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:contacts_01/main.dart';
-
-void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(const MyApp());
-
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
-
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
-
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
- });
-}