diff --git a/lib/main.dart b/lib/main.dart index f3f4b62..2d14a36 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,6 +12,7 @@ import 'package:rental_app/screen/add_address_page.dart'; import 'package:rental_app/screen/add_item_page.dart'; import 'package:rental_app/screen/edit_address_page.dart'; import 'package:rental_app/screen/edit_item_page.dart'; +import 'package:rental_app/screen/favorite_detail.dart'; import 'package:rental_app/screen/login_page.dart'; import 'package:rental_app/screen/myaddress.dart'; import 'package:rental_app/screen/pages/myfavorite.dart'; @@ -20,6 +21,7 @@ import 'package:rental_app/screen/myitems_details.dart'; import '../widgets/splash_screen.dart'; import 'package:rental_app/providers/category_provider.dart'; import 'package:rental_app/providers/item_provider.dart'; +import 'model/favorite_model.dart'; import 'screen/home_screen.dart'; import 'screen/register_page.dart'; @@ -78,6 +80,12 @@ final router = GoRouter( item: state.extra as Item, ), ), + GoRoute( + path: '/favorite_details', + builder: (context, state) => FavoriteDetail( + favorite: state.extra as Favorite, + ), + ), GoRoute( path: '/additem', builder: (context, state) => AddItemPage(), diff --git a/lib/providers/favorite_provider.dart b/lib/providers/favorite_provider.dart index db3581d..82f9e85 100644 --- a/lib/providers/favorite_provider.dart +++ b/lib/providers/favorite_provider.dart @@ -6,6 +6,7 @@ import '../client.dart'; class FavoriteProvider extends ChangeNotifier { List favorite = []; bool isLoading = false; + bool isFavorite = false; FavoriteProvider() { loadFavorites(); @@ -44,6 +45,7 @@ class FavoriteProvider extends ChangeNotifier { })); loadFavorites(); + notifyListeners(); } void deleteFavorite(int id) async { @@ -51,4 +53,17 @@ class FavoriteProvider extends ChangeNotifier { loadFavorites(); } + + Future isFavorited(int id) async { + try { + var response = await Client.dio.get('/api/myfavorite/check/$id/'); + + var body = response.data; + isFavorite = body['is_exists']; + print('isFavorite: $isFavorite'); + notifyListeners(); + } catch (e) { + print(e); + } + } } diff --git a/lib/screen/favorite_detail.dart b/lib/screen/favorite_detail.dart new file mode 100644 index 0000000..a204eab --- /dev/null +++ b/lib/screen/favorite_detail.dart @@ -0,0 +1,346 @@ +import 'package:favorite_button/favorite_button.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:provider/provider.dart'; +import '../model/favorite_model.dart'; +import '../model/item_model.dart'; +import '../providers/favorite_provider.dart'; +import '../providers/item_provider.dart'; + +class FavoriteDetail extends StatefulWidget { + final Favorite favorite; + FavoriteDetail({required this.favorite, super.key}); + + @override + State createState() => _FavoriteDetailState(); +} + +class _FavoriteDetailState extends State { + Item? item; + + @override + void initState() { + super.initState(); + + item = context + .read() + .items + .firstWhere((element) => element.id == widget.favorite.item); + } + + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[300], + appBar: AppBar( + toolbarHeight: 40, + elevation: 0, + leadingWidth: 69, + backgroundColor: Colors.grey[300], + foregroundColor: Colors.black, + leading: Padding( + padding: EdgeInsets.only(left: 25), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.yellow[700]), + child: CupertinoButton( + padding: EdgeInsets.only(right: 0), + child: Icon( + Icons.chevron_left, + color: Colors.black, + size: 28, + ), + onPressed: () { + context.pop(); + }, + ), + ), + ), + ), + body: Padding( + padding: EdgeInsets.only(top: 12), + child: ListView( + children: [ + Column( + children: [ + Padding( + padding: EdgeInsets.only(bottom: 0.0), + child: Image.network( + item!.image, + height: 300, + fit: BoxFit.cover, + width: double.infinity, + ), + ), + Container( + padding: EdgeInsets.only(top: 8, bottom: 22), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.vertical(bottom: Radius.circular(30)), + ), + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 17.0, left: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Text( + item!.title, + style: TextStyle( + fontSize: 20, fontWeight: FontWeight.bold), + ), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.all(8.0), + child: Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + 'Category: ', + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 15, fontWeight: FontWeight.bold), + overflow: TextOverflow.ellipsis, + ), + // Text( + // '${category!.title.toString()}', + // textAlign: TextAlign.left, + // style: TextStyle( + // fontSize: 14, + // fontWeight: FontWeight.normal), + // overflow: TextOverflow.ellipsis, + // ), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.only(left: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Description: ', + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 15, fontWeight: FontWeight.bold), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + Padding( + padding: EdgeInsets.only( + left: 8, right: 8, bottom: 8, top: 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Text( + item!.description, + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal), + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + // Padding( + // padding: EdgeInsets.all(8.0), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // Text( + // 'Daily Price: ', + // textAlign: TextAlign.left, + // style: + // TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + // overflow: TextOverflow.ellipsis, + // ), + // Text( + // '${widget.item.price.toString()}00 KD', + // textAlign: TextAlign.left, + // style: TextStyle( + // fontSize: 14, fontWeight: FontWeight.normal), + // overflow: TextOverflow.ellipsis, + // ), + // ], + // ), + // ), + SizedBox( + height: 5, + ), + Padding( + padding: EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Rental Plans:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () {}, + child: Container( + width: 105, + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text( + '1 Day', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox(height: 10), + Padding( + padding: EdgeInsets.only( + left: 10, right: 10, bottom: 20), + child: Text( + 'KD ${item!.price.toString()}00', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + GestureDetector( + onTap: () {}, + child: Container( + width: 105, + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text( + '1 Week', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox(height: 10), + Padding( + padding: EdgeInsets.only( + left: 10, right: 10, bottom: 20), + child: Text( + 'KD ' + + (item!.price * 4).toString() + + '00', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + GestureDetector( + onTap: () {}, + child: Container( + width: 105, + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text( + '1 Month', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox(height: 10), + Padding( + padding: EdgeInsets.only( + left: 10, right: 10, bottom: 20), + child: Text( + 'KD ' + + (item!.price * 16).toString() + + '00', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), + ], + ), + SizedBox(height: 40), + Padding( + padding: EdgeInsets.symmetric(horizontal: 50), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.yellow[700], + foregroundColor: Colors.black, + padding: EdgeInsets.symmetric(horizontal: 20), + ), + onPressed: () {}, + child: Text( + "Rent Item", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + )), + ) + ], + ), + ), + ); + } +} diff --git a/lib/screen/myitems_details.dart b/lib/screen/myitems_details.dart index 04cee1f..4c09a4d 100644 --- a/lib/screen/myitems_details.dart +++ b/lib/screen/myitems_details.dart @@ -6,6 +6,9 @@ import 'package:provider/provider.dart'; import 'package:rental_app/model/category_model.dart'; import 'package:rental_app/model/item_model.dart'; import 'package:rental_app/providers/category_provider.dart'; +import 'package:rental_app/providers/favorite_provider.dart'; + +import '../model/favorite_model.dart'; class ItemDetails extends StatefulWidget { ItemDetails({super.key, required this.item}); @@ -28,6 +31,8 @@ class _ItemDetailsState extends State { .read() .categories .firstWhere((element) => element.id == widget.item.category); + + context.read().isFavorited(widget.item.id); } Widget build(BuildContext context) { @@ -67,10 +72,31 @@ class _ItemDetailsState extends State { color: Colors.yellow[700]), child: Padding( padding: EdgeInsets.symmetric(horizontal: 8.0), - child: FavoriteButton( - isFavorite: false, // here we get it from api (As boolean) - valueChanged: () {}, - iconSize: 30, + child: InkWell( + onTap: () {}, + child: FavoriteButton( + isFavorite: context + .watch() + .isFavorite, // here we get it from api (As boolean) + valueChanged: () { + if (context.watch().isFavorite == + false) { + context + .read() + .addFavorite(item: widget.item.id); + print('added to favorites'); + // print('Is Favourite $_isFavourite'); + } + //wrap in futureBuilder + else if (context.watch().isFavorite == + true) { + context + .read() + .deleteFavorite(widget.item.id); + } + }, + iconSize: 30, + ), ), ), ), diff --git a/lib/screen/pages/home.dart b/lib/screen/pages/home.dart index 2827747..4fdd42a 100644 --- a/lib/screen/pages/home.dart +++ b/lib/screen/pages/home.dart @@ -22,6 +22,14 @@ class _UserHomeState extends State { } @override + void initState() { + super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + context.read().loadItems(); + }); + } + Widget build(BuildContext context) { return Scaffold( backgroundColor: myDefaultBackground, diff --git a/lib/screen/pages/myfavorite.dart b/lib/screen/pages/myfavorite.dart index f90b62a..3f7d19b 100644 --- a/lib/screen/pages/myfavorite.dart +++ b/lib/screen/pages/myfavorite.dart @@ -5,11 +5,10 @@ import 'package:liquid_pull_to_refresh/liquid_pull_to_refresh.dart'; import 'package:provider/provider.dart'; import 'package:rental_app/providers/favorite_provider.dart'; import 'package:rental_app/util/my_favorite.dart'; - import '../../constraints.dart'; class MyFavoriteView extends StatefulWidget { - const MyFavoriteView({super.key}); + MyFavoriteView({super.key}); @override State createState() => _MyFavoriteViewState(); @@ -21,6 +20,11 @@ class _MyFavoriteViewState extends State { } @override + void initState() { + super.initState(); + context.read().loadFavorites(); + } + Widget build(BuildContext context) { return Scaffold( appBar: AppBar( @@ -79,10 +83,10 @@ class _MyFavoriteViewState extends State { itemCount: context.watch().favorite.length, itemBuilder: (context, index) => InkWell( onTap: () { - context.push( - '/itemdetails', - extra: context.read().favorite[index], - ); + // context.push( + // '/favorite_details', + // extra: widget.favorite, + // ); }, child: MyFavorite( favorite: context.watch().favorite[index], diff --git a/lib/screen/pages/myitems.dart b/lib/screen/pages/myitems.dart index 2d953f9..fda35f3 100644 --- a/lib/screen/pages/myitems.dart +++ b/lib/screen/pages/myitems.dart @@ -20,6 +20,11 @@ class _MyItemsViewState extends State { } @override + void initState() { + super.initState(); + context.read().loadMyItems(); + } + Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( diff --git a/lib/util/my_favorite.dart b/lib/util/my_favorite.dart index 67f77ab..3f643d0 100644 --- a/lib/util/my_favorite.dart +++ b/lib/util/my_favorite.dart @@ -7,8 +7,6 @@ import 'package:rental_app/model/favorite_model.dart'; import 'package:rental_app/model/item_model.dart'; import 'package:rental_app/providers/favorite_provider.dart'; import 'package:rental_app/providers/item_provider.dart'; -import 'package:rental_app/providers/myitems_provider.dart'; - import '../model/category_model.dart'; import '../providers/category_provider.dart'; @@ -50,6 +48,10 @@ class _MyFavoriteState extends State { ), child: CupertinoButton( onPressed: () { + context.push( + '/favorite_details', + extra: widget.favorite, + ); // context.push('/itemdetails', extra: widget.favorite); }, child: Row( diff --git a/lib/widgets/my_drawer.dart b/lib/widgets/my_drawer.dart index e76ad43..3731a0c 100644 --- a/lib/widgets/my_drawer.dart +++ b/lib/widgets/my_drawer.dart @@ -66,6 +66,7 @@ class _MyDrawerState extends State { ), onTap: () { context.push('/myfavorite'); + Navigator.pop(context); }, ), if (context.watch().username != null) @@ -100,6 +101,7 @@ class _MyDrawerState extends State { ), onTap: () { context.push('/login'); + Navigator.pop(context); }, ), if (context.watch().username == null) @@ -118,6 +120,7 @@ class _MyDrawerState extends State { ), onTap: () { context.push('/register'); + Navigator.pop(context); }, ), GestureDetector( @@ -155,6 +158,7 @@ class _MyDrawerState extends State { ), onTap: () { context.read().logout(); + Navigator.pop(context); }, ), ]),