From 8bc1d2c4d7d76f787ef132d192b5c3d9c330dc79 Mon Sep 17 00:00:00 2001 From: meylis98 Date: Tue, 28 Feb 2023 20:01:39 +0500 Subject: [PATCH] category fetch static --- lib/components/custom_button.dart | 37 ----- lib/components/snack_message.dart | 41 ------ lib/components/text_field.dart | 43 ------ lib/main.dart | 8 +- lib/models/category_model.dart | 23 --- lib/models/product_model.dart | 8 +- lib/onboard.dart | 36 ----- .../auth_provider/auth_provider.dart | 107 -------------- lib/screens/auth/login.dart | 131 ------------------ lib/screens/auth/register.dart | 121 ---------------- lib/screens/category/category_screen.dart | 23 ++- lib/screens/drawer/sapaly_drawer.dart | 6 +- lib/screens/home/home_screen.dart | 70 +++------- lib/screens/home/product.dart | 99 +++++-------- lib/services/requests.dart | 49 ++++++- pubspec.lock | 72 ++++++++++ pubspec.yaml | 2 + 17 files changed, 191 insertions(+), 685 deletions(-) delete mode 100644 lib/components/custom_button.dart delete mode 100644 lib/components/snack_message.dart delete mode 100644 lib/components/text_field.dart delete mode 100644 lib/onboard.dart delete mode 100644 lib/providers/auth_provider/auth_provider.dart delete mode 100644 lib/screens/auth/login.dart delete mode 100644 lib/screens/auth/register.dart diff --git a/lib/components/custom_button.dart b/lib/components/custom_button.dart deleted file mode 100644 index 7335b47..0000000 --- a/lib/components/custom_button.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:adaptix/adaptix.dart'; -import 'package:flutter/material.dart'; -import 'package:sapaly_shop/services/app_constants.dart'; -import 'package:sapaly_shop/themes/app_theme.dart'; - -Widget customButton({ - void Function()? tap, - bool? status = false, - String? text = 'Save', - String? statusText, - bool? isValid = false, - BuildContext? context, -}) { - return Container( - height: 48.adaptedPx(), - width: AppConstants.deviceWidth(context!), - margin: EdgeInsets.symmetric( - vertical: 15.adaptedPx(), horizontal: 10.adaptedPx()), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8.adaptedPx()), - color: status == false - ? AppTheme.lightPrimaryColor - : AppTheme.blackColor.withOpacity(0.3), - ), - child: TextButton( - onPressed: status == true ? null : tap, - child: Text( - status == false ? text! : statusText!, - style: Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - fontSize: 18.adaptedPx(), - color: AppTheme.whiteColor, - ), - ), - ), - ); -} diff --git a/lib/components/snack_message.dart b/lib/components/snack_message.dart deleted file mode 100644 index 66b85fd..0000000 --- a/lib/components/snack_message.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:adaptix/adaptix.dart'; -import 'package:flutter/material.dart'; -import 'package:sapaly_shop/themes/app_theme.dart'; - -// void successMessage({String? message, BuildContext? context}) { -// ScaffoldMessenger.of(context!).showSnackBar( -// SnackBar( -// content: Text( -// message!, -// style: Theme.of(context).primaryTextTheme.bodyMedium, -// ), -// backgroundColor: AppTheme.blackColor, -// ), -// ); -// } - -// void errorMessage({String? message, BuildContext? context}) { -// ScaffoldMessenger.of(context!).showSnackBar( -// SnackBar( -// content: Text( -// message!, -// style: Theme.of(context).primaryTextTheme.bodyMedium, -// ), -// backgroundColor: AppTheme.redColor, -// ), -// ); -// } - -void showMessage({String? message, BuildContext? context}) { - ScaffoldMessenger.of(context!).showSnackBar( - SnackBar( - content: Text( - message!, - style: Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - fontSize: 16.adaptedPx(), - color: AppTheme.blackColor, - ), - ), - ), - ); -} diff --git a/lib/components/text_field.dart b/lib/components/text_field.dart deleted file mode 100644 index 3a16810..0000000 --- a/lib/components/text_field.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:adaptix/adaptix.dart'; -import 'package:flutter/material.dart'; -import 'package:sapaly_shop/themes/app_theme.dart'; - -Widget customTextField({ - String? title, - String? hint, - TextEditingController? controller, - int? maxLines = 1, - BuildContext? context, -}) { - return Column( - children: [ - Container( - alignment: Alignment.centerLeft, - child: Text( - title!, - style: Theme.of(context!).primaryTextTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w600, - color: AppTheme.blackColor, - ), - ), - ), - TextFormField( - controller: controller, - maxLines: maxLines, - cursorColor: AppTheme.lightPrimaryColor, - decoration: InputDecoration( - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(15.adaptedPx()), - borderSide: const BorderSide( - color: AppTheme.lightPrimaryColor, - ), - ), - focusColor: AppTheme.lightPrimaryColor, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - ), - ], - ); -} diff --git a/lib/main.dart b/lib/main.dart index 800fba1..dc84d61 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,6 @@ import 'package:adaptix/adaptix.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:sapaly_shop/onboard.dart'; -import 'package:sapaly_shop/providers/auth_provider/auth_provider.dart'; -import 'package:sapaly_shop/screens/auth/login.dart'; import 'package:sapaly_shop/screens/category/category_screen.dart'; import 'package:sapaly_shop/screens/dashboard/dashboard.dart'; import 'package:sapaly_shop/screens/drawer/sapaly_drawer.dart'; @@ -23,7 +20,6 @@ Future main() async { MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => SettingsModel(prefs)), - ChangeNotifierProvider(create: (_) => AuthenticatonProvider()), ], child: const MyApp(), ), @@ -41,13 +37,11 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, theme: AppTheme.appLightTheme, title: 'Sapaly Mahabat', - initialRoute: '/login', + initialRoute: '/home', routes: { '/': (context) => const Dashboard(), '/drawer': (context) => SapalyDrawer(), - '/onboard': (context) => const Onboard(), '/home': (context) => const HomeScreen(), - '/login': (context) => const LoginScreen(), '/category': (context) => const CategoryScreen(), }, localizationsDelegates: AppConstants.localizationsDelegate, diff --git a/lib/models/category_model.dart b/lib/models/category_model.dart index 3fc86b8..12da7d4 100644 --- a/lib/models/category_model.dart +++ b/lib/models/category_model.dart @@ -5,13 +5,11 @@ class CategoryModel { required this.id, required this.name, required this.translations, - required this.icon, }); final int id; final String name; final List translations; - final Iconca icon; factory CategoryModel.fromJson( Map json, String currentLang) { @@ -30,31 +28,10 @@ class CategoryModel { translations: (json['translations'] as List) .map((e) => Translation.fromJson(e)) .toList(), - icon: Iconca.fromJson(json["icon"] ?? ''), ); } } -class Iconca { - Iconca({ - required this.id, - required this.path, - }); - - final int id; - final String path; - - factory Iconca.fromJson(Map json) => Iconca( - id: json["id"] ?? 0, - path: json["path"], - ); - - Map toJson() => { - "id": id, - "path": path, - }; -} - class Translation { Translation({ required this.locale, diff --git a/lib/models/product_model.dart b/lib/models/product_model.dart index 3e2eb41..afdc3a4 100644 --- a/lib/models/product_model.dart +++ b/lib/models/product_model.dart @@ -19,7 +19,7 @@ class ProductModel { final String name; final String slug; final int categoryId; - final PreviewImage previewImage; + final PreviewImage? previewImage; final List translations; final List offer; @@ -38,7 +38,9 @@ class ProductModel { name: language, slug: json["slug"] ?? '', categoryId: json["category_id"] ?? '', - previewImage: PreviewImage.fromJson(json["preview_image"] ?? ''), + previewImage: (json["preview_image"] != null) + ? PreviewImage.fromJson(json["preview_image"]) + : null, translations: List.from( json["translations"].map((x) => Translation.fromJson(x))), offer: List.from(json["offer"].map((x) => Offer.fromJson(x))), @@ -50,7 +52,7 @@ class ProductModel { "name": name, "slug": slug, "category_id": categoryId, - "preview_image": previewImage.toJson(), + "preview_image": previewImage!.toJson(), "translations": List.from(translations.map((x) => x.toJson())), }; } diff --git a/lib/onboard.dart b/lib/onboard.dart deleted file mode 100644 index f84a478..0000000 --- a/lib/onboard.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:sapaly_shop/screens/auth/login.dart'; - -class Onboard extends StatefulWidget { - const Onboard({super.key}); - - @override - State createState() => _OnboardState(); -} - -class _OnboardState extends State { - void navigate(BuildContext context) { - Future.delayed(const Duration(seconds: 3), () { - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => const LoginScreen(), - ), - (route) => false); - }); - } - - @override - void initState() { - navigate(context); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return const Scaffold( - body: Center( - child: Text('On Board'), - ), - ); - } -} diff --git a/lib/providers/auth_provider/auth_provider.dart b/lib/providers/auth_provider/auth_provider.dart deleted file mode 100644 index d108c28..0000000 --- a/lib/providers/auth_provider/auth_provider.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:http/http.dart' as http; -import 'package:flutter/widgets.dart'; -import 'package:sapaly_shop/services/app_constants.dart'; - -class AuthenticatonProvider extends ChangeNotifier { - // Base URL - final requestBaseUrl = kBaseUrl; - bool _isLoading = false; - String _resMessage = ''; - - // Getter - bool get isLoading => _isLoading; - String get resMeessage => _resMessage; - - // for sign_up - void register({ - required String email, - required String phoneNumber, - required String password, - required String repeatPassword, - BuildContext? context, - }) async { - _isLoading = true; - notifyListeners(); - - String url = '$requestBaseUrl/api/jwt/register'; - - final body = { - 'email': email, - 'phone': phoneNumber, - 'password': password, - 'password_confirmation': repeatPassword, - }; - - debugPrint('This is SIGNUP BODY ${body.toString()}'); - - try { - final req = await http.post(Uri.parse(url), body: json.encode(body)); - - if (req.statusCode == 200 || req.statusCode == 201) { - debugPrint('SIGNUP success ${req.body}'); - } else { - final res = json.decode(req.body); - debugPrint('SIGNUP error ${res.body}'); - - _isLoading = false; - notifyListeners(); - } - } on SocketException catch (error) { - _isLoading = false; - _resMessage = 'Internet connection is not available'; - notifyListeners(); - } catch (err) { - _isLoading = false; - _resMessage = 'Please try again'; - notifyListeners(); - - debugPrint('::::: ${err.toString()}'); - } - } - - // for sign_in - void login({ - required String email, - required String password, - BuildContext? context, - }) async { - _isLoading = true; - notifyListeners(); - - String url = '$requestBaseUrl/api/jwt/login'; - - final body = { - 'email': email, - 'password': password, - }; - - debugPrint('This is SIGNUP BODY ${body.toString()}'); - - try { - final req = await http.post(Uri.parse(url), body: json.encode(body)); - - if (req.statusCode == 200 || req.statusCode == 201) { - debugPrint('LOGIN success ${req.body}'); - } else { - final res = json.decode(req.body); - debugPrint('LOGIN error ${res.body}'); - - _isLoading = false; - notifyListeners(); - } - } on SocketException catch (error) { - _isLoading = false; - _resMessage = 'Internet connection is not available'; - notifyListeners(); - } catch (err) { - _isLoading = false; - _resMessage = 'Please try again'; - notifyListeners(); - - debugPrint('::::: ${err.toString()}'); - } - } -} diff --git a/lib/screens/auth/login.dart b/lib/screens/auth/login.dart deleted file mode 100644 index 9060198..0000000 --- a/lib/screens/auth/login.dart +++ /dev/null @@ -1,131 +0,0 @@ -import 'package:adaptix/adaptix.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:sapaly_shop/components/custom_button.dart'; -import 'package:sapaly_shop/components/snack_message.dart'; -import 'package:sapaly_shop/components/text_field.dart'; -import 'package:sapaly_shop/providers/auth_provider/auth_provider.dart'; -import 'package:sapaly_shop/screens/auth/register.dart'; -import 'package:sapaly_shop/services/app_constants.dart'; -import 'package:sapaly_shop/themes/app_theme.dart'; - -import '../../services/page_navigator.dart'; - -class LoginScreen extends StatefulWidget { - const LoginScreen({super.key}); - - @override - State createState() => _LoginScreenState(); -} - -class _LoginScreenState extends State { - final TextEditingController _email = TextEditingController(); - final TextEditingController _password = TextEditingController(); - - @override - void dispose() { - _email.clear(); - _password.clear(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Container( - margin: EdgeInsets.symmetric( - horizontal: AppConstants.horizontalPadding(context), - ), - padding: EdgeInsets.symmetric( - horizontal: AppConstants.horizontalPadding(context), - ), - height: AppConstants.deviceHeight(context) / (1.4), - width: double.infinity, - decoration: BoxDecoration( - border: Border.all( - width: 2.adaptedPx(), - color: AppTheme.blackColor.withOpacity(0.1), - ), - borderRadius: BorderRadius.circular(15.adaptedPx()), - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset('assets/images/sapalyLogo.png'), - SizedBox(width: 20.adaptedPx()), - Text( - AppConstants.kAppName, - style: - Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - color: AppTheme.blackColor, - fontWeight: FontWeight.w600, - fontSize: 20.adaptedPx(), - ), - ), - ], - ), - SizedBox(height: 20.adaptedPx()), - customTextField( - title: 'Email', - context: context, - hint: 'Enter your valid email address', - controller: _email, - ), - SizedBox(height: 20.adaptedPx()), - customTextField( - title: 'Password', - context: context, - hint: 'Enter your secured password', - controller: _password, - ), - SizedBox(height: 45.adaptedPx()), - Consumer(builder: (context, auth, child) { - return customButton( - text: 'Login', - tap: () { - if (_email.text.isEmpty || _password.text.isEmpty) { - showMessage( - context: context, - message: 'All fields are required', - ); - } else { - auth.login( - email: _email.text.trim(), - password: _password.text.trim()); - } - }, - context: context, - statusText: 'Loggin in...', - status: auth.isLoading, - ); - }), - Text( - 'Or', - textAlign: TextAlign.center, - style: Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - color: AppTheme.blackColor, - fontSize: 18.adaptedPx(), - ), - ), - customButton( - text: 'Register', - tap: () { - PageNavigator(ctx: context).nextPage( - page: const RegisterScreen(), - ); - }, - context: context, - isValid: false, - status: false, - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/screens/auth/register.dart b/lib/screens/auth/register.dart deleted file mode 100644 index 7daf23b..0000000 --- a/lib/screens/auth/register.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'package:adaptix/adaptix.dart'; -import 'package:flutter/material.dart'; -import 'package:sapaly_shop/components/custom_button.dart'; -import 'package:sapaly_shop/components/text_field.dart'; -import 'package:sapaly_shop/screens/auth/login.dart'; -import 'package:sapaly_shop/services/app_constants.dart'; -import 'package:sapaly_shop/themes/app_theme.dart'; - -import '../../services/page_navigator.dart'; - -class RegisterScreen extends StatefulWidget { - const RegisterScreen({super.key}); - - @override - State createState() => _RegisterScreenState(); -} - -class _RegisterScreenState extends State { - final TextEditingController _email = TextEditingController(); - final TextEditingController _password = TextEditingController(); - final TextEditingController _passwordConfirm = TextEditingController(); - final TextEditingController _phone = TextEditingController(); - - @override - void dispose() { - _email.clear(); - _password.clear(); - _passwordConfirm.clear(); - _phone.clear(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Container( - margin: EdgeInsets.symmetric( - horizontal: AppConstants.horizontalPadding(context), - ), - padding: EdgeInsets.symmetric( - horizontal: AppConstants.horizontalPadding(context), - ), - height: AppConstants.deviceHeight(context) / (1.13), - width: double.infinity, - decoration: BoxDecoration( - border: Border.all( - width: 2.adaptedPx(), - color: AppTheme.blackColor.withOpacity(0.1), - ), - borderRadius: BorderRadius.circular(15.adaptedPx()), - ), - child: ListView( - physics: const NeverScrollableScrollPhysics(), - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset('assets/images/sapalyLogo.png'), - SizedBox(width: 20.adaptedPx()), - Text( - AppConstants.kAppName, - style: - Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - color: AppTheme.blackColor, - fontWeight: FontWeight.w600, - fontSize: 20.adaptedPx(), - ), - ), - ], - ), - SizedBox(height: 20.adaptedPx()), - customTextField( - title: 'Your email', - context: context, - controller: _email, - hint: '', - ), - SizedBox(height: 15.adaptedPx()), - customTextField(title: 'Phone number', context: context), - SizedBox(height: 15.adaptedPx()), - customTextField(title: 'Password', context: context), - SizedBox(height: 15.adaptedPx()), - customTextField(title: 'Password confirmation', context: context), - SizedBox(height: 15.adaptedPx()), - customButton( - text: 'Register', - context: context, - status: false, - statusText: 'Registering...', - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.adaptedPx()), - child: Text( - 'Or', - textAlign: TextAlign.center, - style: - Theme.of(context).primaryTextTheme.bodyMedium?.copyWith( - color: AppTheme.blackColor, - fontSize: 18.adaptedPx(), - ), - ), - ), - customButton( - text: 'Login', - context: context, - tap: () { - PageNavigator(ctx: context).nextPageOnly( - page: const LoginScreen(), - ); - }, - statusText: 'Loggin in...', - status: true, - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/screens/category/category_screen.dart b/lib/screens/category/category_screen.dart index 201f1a3..ac7101d 100644 --- a/lib/screens/category/category_screen.dart +++ b/lib/screens/category/category_screen.dart @@ -2,7 +2,6 @@ import 'package:adaptix/adaptix.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:provider/provider.dart'; import 'package:sapaly_shop/components/sapaly_app_bar.dart'; import 'package:sapaly_shop/models/category_model.dart'; import 'package:sapaly_shop/models/settings_model.dart'; @@ -91,17 +90,17 @@ class _CategoryScreenState extends State { ), child: Column( children: [ - Expanded( - flex: 3, - child: CachedNetworkImage( - imageUrl: categories[index].icon.path, - width: MediaQuery.of(context).size.width / 7, - fit: BoxFit.contain, - progressIndicatorBuilder: - (context, url, progress) => const Center( - child: CircularProgressIndicator()), - ), - ), + // Expanded( + // flex: 3, + // child: CachedNetworkImage( + // imageUrl: categories[index].icon.path, + // width: MediaQuery.of(context).size.width / 7, + // fit: BoxFit.contain, + // progressIndicatorBuilder: + // (context, url, progress) => const Center( + // child: CircularProgressIndicator()), + // ), + // ), Expanded( flex: 1, child: Text( diff --git a/lib/screens/drawer/sapaly_drawer.dart b/lib/screens/drawer/sapaly_drawer.dart index 457301e..2f82ff4 100644 --- a/lib/screens/drawer/sapaly_drawer.dart +++ b/lib/screens/drawer/sapaly_drawer.dart @@ -2,8 +2,6 @@ import 'package:adaptix/adaptix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:sapaly_shop/screens/auth/login.dart'; -import 'package:sapaly_shop/screens/auth/register.dart'; import 'package:sapaly_shop/screens/category/category_screen.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -33,8 +31,8 @@ class SapalyDrawer extends StatelessWidget { List routes = [ const CategoryScreen(), - const LoginScreen(), - const RegisterScreen(), + Container(), + Container(), Container(), Container(), Container(), diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 82954c7..ed364da 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -5,16 +5,14 @@ import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:sapaly_shop/models/product_model.dart'; import 'package:sapaly_shop/models/settings_model.dart'; import 'package:sapaly_shop/models/sliders_model.dart'; import 'package:sapaly_shop/screens/drawer/sapaly_drawer.dart'; -import 'package:sapaly_shop/screens/details/details.dart'; +import 'package:sapaly_shop/screens/home/product.dart'; import 'package:sapaly_shop/screens/home/search.dart'; import 'package:sapaly_shop/services/app_constants.dart'; import 'package:sapaly_shop/services/requests.dart'; -import '../../components/product_card.dart'; import '../../components/sapaly_app_bar.dart'; import '../../models/category_model.dart'; import '../../themes/app_theme.dart'; @@ -31,8 +29,7 @@ class _HomeScreenState extends State with TickerProviderStateMixin { int currentPage = 0; int categoryId = 0; bool hasError = false; - late TabController tabController; - List products = []; + TabController? tabController; List categories = []; List sliders = []; @@ -59,7 +56,6 @@ class _HomeScreenState extends State with TickerProviderStateMixin { hasError = false; }); } - tabController = TabController(length: categories.length, vsync: this); } catch (e) { setState(() { @@ -69,24 +65,11 @@ class _HomeScreenState extends State with TickerProviderStateMixin { } } - Future getProductsByCategory(int id) async { - try { - var list = await API().getProductsByCategory(id); - if (mounted) { - setState(() { - products = list; - }); - } - } catch (e) { - debugPrint(e.toString()); - } - } - @override void initState() { getSliders(); getCategories(); - getProductsByCategory(categoryId); + super.initState(); } @@ -248,39 +231,24 @@ class _HomeScreenState extends State with TickerProviderStateMixin { ), ), SizedBox(height: 15.adaptedPx()), - products.isEmpty && categories.isEmpty - ? SizedBox( - height: AppConstants.deviceHeight(context) / 1.190, - child: const Center(child: CircularProgressIndicator()), - ) - : SizedBox( - height: AppConstants.deviceHeight(context), - width: double.infinity, - child: TabBarView( + SizedBox( + height: AppConstants.deviceHeight(context), + width: double.infinity, + child: tabController != null + ? TabBarView( controller: tabController, - children: [ - for (ProductModel product in products) - ProductCard( - imageUrl: product.previewImage.path, - price: '${product.offer.first.price}.M', - discountPrice: '${product.offer.first.oldPrice}.M', - description: product.offer.first.name, - discountPriceValue: - product.offer.first.discountPriceValue, - onPressed: () => Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => Details( - id: product.id, - image: product.previewImage.path, - price: '${product.offer.first.price}.M', - description: product.offer.first.name, + children: categories.isNotEmpty + ? categories + .map( + (category) => Products( + id: category.id, ), - ), - ), - ) - ], - ), - ), + ) + .toList() + : [], + ) + : Container(), + ), ], ), ), diff --git a/lib/screens/home/product.dart b/lib/screens/home/product.dart index 6b325c5..4be91c1 100644 --- a/lib/screens/home/product.dart +++ b/lib/screens/home/product.dart @@ -1,48 +1,28 @@ import 'package:flutter/material.dart'; -import 'package:sapaly_shop/models/category_model.dart'; import 'package:sapaly_shop/models/product_model.dart'; import '../../components/product_card.dart'; -import '../../services/app_constants.dart'; import '../../services/requests.dart'; import '../details/details.dart'; class Products extends StatefulWidget { - const Products({ - super.key, - required this.id, - required this.length, - required this.controller, - }); - final int id, length; - final TabController controller; - + const Products({super.key, required this.id}); + final int id; @override State createState() => _ProductsState(); } class _ProductsState extends State { List products = []; - List categories = []; - - Future getCategories() async { - try { - var data = await API().getCategories(); - setState(() { - categories = data; - }); - } catch (e) { - debugPrint('Category error ${e.toString()}'); - } - } Future getProductsByCategory(int id) async { try { var list = await API().getProductsByCategory(id); - setState(() { - products = list; - }); - debugPrint("THIS IS PRODUCTS $products"); + if (mounted) { + setState(() { + products = list; + }); + } } catch (e) { debugPrint(e.toString()); } @@ -50,8 +30,8 @@ class _ProductsState extends State { @override void initState() { - getCategories(); getProductsByCategory(widget.id); + print('category id :${widget.id}'); super.initState(); } @@ -59,44 +39,33 @@ class _ProductsState extends State { Widget build(BuildContext context) { return products == null ? const Center(child: CircularProgressIndicator()) - : SizedBox( - height: AppConstants.deviceHeight(context), - width: double.infinity, - child: TabBarView( - controller: widget.controller, - children: [ - for (CategoryModel category in categories) - GridView.builder( - shrinkWrap: true, - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - ), - itemCount: products.length, - itemBuilder: (context, index) { - return ProductCard( - imageUrl: products[index].previewImage.path, - price: '${products[index].offer.first.price}.M', - discountPrice: - '${products[index].offer.first.oldPrice}.M', - description: products[index].offer.first.name, - discountPriceValue: - products[index].offer.first.discountPriceValue, - onPressed: () => Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => Details( - id: products[index].id, - image: products[index].previewImage.path, - price: '${products[index].offer.first.price}.M', - description: products[index].offer.first.name, - ), - ), - ), - ); - }, - ), - ], + : GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, ), + itemCount: products.length, + itemBuilder: (context, index) { + return ProductCard( + imageUrl: products[index].previewImage?.path ?? '', + price: '${products[index].offer.first.price}.M', + discountPrice: '${products[index].offer.first.oldPrice}.M', + description: products[index].offer.first.name, + discountPriceValue: + products[index].offer.first.discountPriceValue, + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => Details( + id: products[index].id, + image: products[index].previewImage?.path ?? '', + price: '${products[index].offer.first.price}.M', + description: products[index].offer.first.name, + ), + ), + ), + ); + }, ); } } diff --git a/lib/services/requests.dart b/lib/services/requests.dart index b7d2333..dd8e602 100644 --- a/lib/services/requests.dart +++ b/lib/services/requests.dart @@ -36,9 +36,12 @@ class API { String currentLang = prefs.getString('language') ?? 'ru'; try { final products = await _getData('v1/products/category/$id'); - return (products['data']['data'] as List) - .map((e) => ProductModel.fromJson(e, currentLang)) - .toList(); + + return products.containsKey('data') + ? (products['data']['data'] as List) + .map((e) => ProductModel.fromJson(e, currentLang)) + .toList() + : [].cast(); } catch (e) { debugPrint('product by categ ' + e.toString()); rethrow; @@ -55,11 +58,26 @@ class API { } } + Future> getSubCategories(int id) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String currentLanguage = prefs.getString('language') ?? 'ru'; + try { + final categories = await _getData("v1/category/sub/$id"); + return (categories["data"] as List) + .map((item) => CategoryModel.fromJson(item, currentLanguage)) + .toList(); + } catch (e) { + debugPrint('Category ' + e.toString()); + rethrow; + } + } + Future> getCategories() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String currentLanguage = prefs.getString('language') ?? 'ru'; try { - final categories = await _getData("v1/categories"); + final categories = await _getData("v1/category/sub/19"); + return (categories["data"] as List) .map((item) => CategoryModel.fromJson(item, currentLanguage)) .toList(); @@ -80,4 +98,27 @@ class API { rethrow; } } + + static Future register(String email, String phone, String password, + String password_confirmation) async { + Map requestHeaders = {'Content-Type': 'application/json'}; + var url = Uri.http(kBaseUrl, 'jwt/register'); + + var response = await http.post( + url, + headers: requestHeaders, + body: jsonEncode({ + 'email': email, + 'password': password, + 'password_confirmation': password_confirmation, + 'phone': phone, + }), + ); + + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } } diff --git a/pubspec.lock b/pubspec.lock index 5c98c16..647ca33 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -146,6 +146,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + url: "https://pub.dev" + source: hosted + version: "0.3.3+4" crypto: dependency: transitive description: @@ -260,6 +268,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.16" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "4bef634684b2c7f3468c77c766c831229af829a0cd2d4ee6c1b99558bd14e5d2" + url: "https://pub.dev" + source: hosted + version: "2.0.8" flutter_svg: dependency: "direct main" description: @@ -318,6 +334,46 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" + image_picker: + dependency: transitive + description: + name: image_picker + sha256: "22207768556b82d55ec70166824350fee32298732d5efa4d6e756f848f51f66a" + url: "https://pub.dev" + source: hosted + version: "0.8.6+3" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "68d067baf7f6e401b1124ee83dd6967e67847314250fd68012aab34a69beb344" + url: "https://pub.dev" + source: hosted + version: "0.8.5+7" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "66fc6e3877bbde82c33d122f3588777c3784ac5bd7d1cdd79213ef7aecb85b34" + url: "https://pub.dev" + source: hosted + version: "2.1.11" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "39aa70b5f1e5e7c94585b9738632d5fdb764a5655e40cd9e7b95fbd2fc50c519" + url: "https://pub.dev" + source: hosted + version: "0.8.6+9" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8" + url: "https://pub.dev" + source: hosted + version: "2.6.3" intl: dependency: "direct main" description: @@ -526,6 +582,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" + progress_hud: + dependency: "direct main" + description: + name: progress_hud + sha256: c7a79d70d278328cf3b0732c119a89ba96329825deb03b5dd64415c77dfb8ac4 + url: "https://pub.dev" + source: hosted + version: "1.1.0" provider: dependency: "direct main" description: @@ -611,6 +675,14 @@ packages: description: flutter source: sdk version: "0.0.99" + snippet_coder_utils: + dependency: "direct main" + description: + name: snippet_coder_utils + sha256: fb60b8a6b4cab3dddc17ce903cc073d2f5d42ebed676146dde0faba040dc4158 + url: "https://pub.dev" + source: hosted + version: "1.0.13" source_span: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 547ebe6..6d60ca1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,6 +52,8 @@ dependencies: url_launcher: ^6.1.9 shared_preferences: ^2.0.17 provider: ^6.0.5 + snippet_coder_utils: ^1.0.13 + progress_hud: ^1.1.0 dev_dependencies: flutter_test: