From 308caf53c1b24e957d4ddae90eb7cfe5c2155035 Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:38:00 +0900 Subject: [PATCH 1/7] feat : add question image asset to show empty result --- assets/images/Question-3d.png | Bin 0 -> 16350 bytes lib/screens/products/item_list_page.dart | 67 ++++++++++++---------- lib/screens/products/liked_list_page.dart | 18 +++++- 3 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 assets/images/Question-3d.png diff --git a/assets/images/Question-3d.png b/assets/images/Question-3d.png new file mode 100644 index 0000000000000000000000000000000000000000..68ba5a36811b1ba6e06b5c4ecbb5d042a60235a9 GIT binary patch literal 16350 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 { return SliverPadding( padding: const EdgeInsets.only(bottom: 50, right: 20, left: 20, top: 10), sliver: SliverToBoxAdapter( - child: Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.spaceBetween, - spacing: 15, - runSpacing: 15, - children: [ - FutureBuilder( - future: _products, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Text('Error: ${snapshot.error.toString()}'); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('상품이 없습니다')); - } else { - final products = snapshot.data!; - return Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.spaceBetween, - spacing: 15, - runSpacing: 15, - children: products - .map((product) => ProductCard(product: product)) - .toList(), - ); - } - }, - ) - ], + child: FutureBuilder( + future: _products, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Text('Error: ${snapshot.error.toString()}'); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Image.asset( + 'assets/images/Question-3d.png', + width: 180.0, + ), + ), + Text( + '상품이 없습니다', + style: textStyle(20, true, null), + ), + ], + )); + } else { + final products = snapshot.data!; + return Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.spaceBetween, + spacing: 15, + runSpacing: 15, + children: products + .map((product) => ProductCard(product: product)) + .toList(), + ); + } + }, ), ), ); diff --git a/lib/screens/products/liked_list_page.dart b/lib/screens/products/liked_list_page.dart index c65a5c3..df58794 100644 --- a/lib/screens/products/liked_list_page.dart +++ b/lib/screens/products/liked_list_page.dart @@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; import 'package:saphy/models/product.dart'; import 'package:saphy/service/api_service.dart'; import 'package:saphy/service/authentication/secure_storage.dart'; +import 'package:saphy/utils/textstyles.dart'; import 'package:saphy/widgets/product_card.dart'; import 'package:saphy/utils/colors.dart'; import 'package:saphy/widgets/app_bar.dart'; @@ -117,7 +118,22 @@ class _LikedListPageState extends State { } else if (snapshot.hasError) { return Text('Error: ${snapshot.error.toString()}'); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('상품이 없습니다')); + return Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Image.asset( + 'assets/images/Question-3d.png', + width: 180.0, + ), + ), + Text( + '상품이 없습니다', + style: textStyle(20, true, null), + ), + ], + )); } else { final products = snapshot.data!; return Wrap( From 91a6dac499758c6f3c6d048135779ab65fa7e317 Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:38:21 +0900 Subject: [PATCH 2/7] design : change textfield design --- lib/widgets/textfield.dart | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/widgets/textfield.dart b/lib/widgets/textfield.dart index 7f0c6df..8dc2fbc 100644 --- a/lib/widgets/textfield.dart +++ b/lib/widgets/textfield.dart @@ -13,21 +13,18 @@ SizedBox textField( controller: controller, onSubmitted: onSubmitted, decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: const BorderSide(color: gray800, width: 1), - borderRadius: BorderRadius.circular(15), - ), + filled: true, + fillColor: white.withOpacity(0.8), + hintText: '검색어를 입력하세요', + hintStyle: const TextStyle(color: Colors.grey), border: OutlineInputBorder( - borderSide: const BorderSide(color: gray800, width: 1), - borderRadius: BorderRadius.circular(15), + borderRadius: BorderRadius.circular(12.0), // 둥근 모서리 설정 + borderSide: BorderSide.none, // 테두리 제거 ), focusedBorder: OutlineInputBorder( - borderSide: const BorderSide(color: mainPrimary, width: 1), - borderRadius: BorderRadius.circular(15), - ), - hintText: '검색어를 입력하세요', - hintStyle: const TextStyle( - color: gray700, + borderRadius: BorderRadius.circular(12.0), // 포커스 시에도 둥근 모서리 유지 + borderSide: BorderSide( + color: mainPrimary.withOpacity(0.5), width: 1.5), // 포커스 시 테두리 스타일 ), ), ), From dcec2fa498d01e3e6d76a97d8d17c2e67e72eece Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:38:38 +0900 Subject: [PATCH 3/7] feat : complete UI of search screen --- lib/screens/search/search_result_screen.dart | 67 ++++++++-- lib/screens/search/search_screen.dart | 129 +++++++++++++++++-- 2 files changed, 179 insertions(+), 17 deletions(-) diff --git a/lib/screens/search/search_result_screen.dart b/lib/screens/search/search_result_screen.dart index 223d8d7..839535b 100644 --- a/lib/screens/search/search_result_screen.dart +++ b/lib/screens/search/search_result_screen.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:saphy/utils/colors.dart'; import 'package:saphy/utils/textstyles.dart'; @@ -18,12 +19,21 @@ class SearchResultScreen extends StatefulWidget { class _SearchResultScreenState extends State { late TextEditingController _controller; Future>? _products; + int cnt = 0; + + Future countProducts() async { + List products = await searchText(widget.query); + setState(() { + cnt = products.length; + }); + } @override void initState() { super.initState(); _controller = TextEditingController(); _products = searchText(widget.query); + countProducts(); } @override @@ -34,10 +44,10 @@ class _SearchResultScreenState extends State { @override Widget build(BuildContext context) { - var screenWidth = MediaQuery.of(context).size.width; return Scaffold( backgroundColor: const Color(0xfff4f4f4), appBar: AppBar( + toolbarHeight: 70, automaticallyImplyLeading: false, backgroundColor: altWhite, title: Row( @@ -58,8 +68,11 @@ class _SearchResultScreenState extends State { (String value) { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchResultScreen(query: value), + PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + SearchResultScreen(query: value), + transitionDuration: Duration.zero, + reverseTransitionDuration: Duration.zero, ), ); }, @@ -79,8 +92,9 @@ class _SearchResultScreenState extends State { ), ), body: CustomScrollView(slivers: [ + _buildSorter(), SliverPadding( - padding: const EdgeInsets.only(left: 20, right: 20, top: 30), + padding: const EdgeInsets.only(left: 20, right: 20, top: 10), sliver: SliverToBoxAdapter( child: FutureBuilder>( future: _products, @@ -91,7 +105,22 @@ class _SearchResultScreenState extends State { return Center( child: Text('Error: ${snapshot.error.toString()}')); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('상품이 없습니다')); + return Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Image.asset( + 'assets/images/Question-3d.png', + width: 180.0, + ), + ), + Text( + '상품이 없습니다', + style: textStyle(20, true, null), + ), + ], + )); } else { final products = snapshot.data!; return Wrap( @@ -126,13 +155,35 @@ class _SearchResultScreenState extends State { .toList(); return products; } else { - throw Exception('검색 결과가 없습니다.'); + return []; } } else { - throw Exception('상품 로드에 실패했습니다.'); + return []; } } catch (e) { - throw Exception('에러가 발생했습니다.'); + return []; } } + + SliverPadding _buildSorter() { + return SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 30), + sliver: SliverToBoxAdapter( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '상품 $cnt', + style: subTitleText(), + ), + IconButton( + icon: const Icon(Icons.sort_outlined), + onPressed: () {}, + ), + ], + ), + ), + ); + } } diff --git a/lib/screens/search/search_screen.dart b/lib/screens/search/search_screen.dart index 9be0310..66032de 100644 --- a/lib/screens/search/search_screen.dart +++ b/lib/screens/search/search_screen.dart @@ -1,5 +1,11 @@ +import 'dart:ui'; + +import 'package:cached_network_image/cached_network_image.dart'; import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:saphy/screens/screen_controller.dart'; import 'package:saphy/utils/colors.dart'; import 'package:saphy/utils/textstyles.dart'; import 'package:saphy/screens/search/search_result_screen.dart'; @@ -43,7 +49,11 @@ class _SearchScreenState extends State { size: 25, ), onPressed: () { - Navigator.of(context).pop(); + Navigator.of(context).pushReplacement( + CupertinoPageRoute( + builder: (context) => const ScreenController(), + ), + ); }, ), textField( @@ -52,8 +62,11 @@ class _SearchScreenState extends State { (String value) { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchResultScreen(query: value), + PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + SearchResultScreen(query: value), + transitionDuration: Duration.zero, + reverseTransitionDuration: Duration.zero, ), ); }, @@ -66,9 +79,11 @@ class _SearchScreenState extends State { onPressed: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => + PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => SearchResultScreen(query: _controller.text), + transitionDuration: Duration.zero, + reverseTransitionDuration: Duration.zero, ), ); }, @@ -79,16 +94,52 @@ class _SearchScreenState extends State { body: Column( children: [ Padding( - padding: const EdgeInsets.all(30.0), + padding: const EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text("최근 검색어", style: titleText()), - const SizedBox(height: 20), Text("인기 검색어", style: titleText()), - const SizedBox(height: 20), + const SizedBox(height: 10), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + buildKeywordButton("iPhone 14", context), + const SizedBox(width: 10), + buildKeywordButton("iPhone SE", context), + const SizedBox(width: 10), + buildKeywordButton("iPhone 13", context), + const SizedBox(width: 10), + buildKeywordButton("Galaxy", context), + const SizedBox(width: 10), + buildKeywordButton("iPhone", context), + const SizedBox(width: 10), + ], + ), + ), + const SizedBox(height: 30), Text("인기 브랜드", style: titleText()), + const SizedBox(height: 10), + Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.spaceBetween, + spacing: 15, + runSpacing: 15, + children: [ + buildBrandButton( + "https://i.pinimg.com/564x/98/86/c2/9886c2f88c318293b04c223f18e57148.jpg", + "Apple"), + buildBrandButton( + "https://i.pinimg.com/564x/68/23/99/68239927494dbd614773edaa5e05606f.jpg", + "Samsung"), + buildBrandButton( + "https://i.pinimg.com/564x/21/9a/ba/219aba5a7e74091741fef401deb08f43.jpg", + "Xiaomi"), + buildBrandButton( + "https://i.pinimg.com/564x/bb/01/82/bb0182822f2cf41937feee1f4a91fb2b.jpg", + "Nokia"), + ]), ], ), ), @@ -96,4 +147,64 @@ class _SearchScreenState extends State { ), ); } + + InkWell buildKeywordButton(String label, BuildContext context) { + return InkWell( + onTap: () { + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + SearchResultScreen(query: label), + transitionDuration: Duration.zero, + reverseTransitionDuration: Duration.zero, + ), + ); + }, + child: Container( + height: 45, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all(color: gray300, width: 1), + color: white, + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 13.0, vertical: 8), + child: Center( + child: Text(label, style: textStyle(15, false, null)), + ), + ), + ), + ); + } + + InkWell buildBrandButton(String link, String label) { + double screenWidth = MediaQuery.of(context).size.width; + return InkWell( + onTap: () {}, + child: Container( + width: (screenWidth - 55) / 2, + height: 200, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: white, + image: DecorationImage( + image: CachedNetworkImageProvider(link), + fit: BoxFit.cover, + ), + ), + // child: SizedBox.expand( + // child: ClipRect( + // child: BackdropFilter( + // filter: ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0), // 블러 강도 + // child: Container( + // color: Colors.transparent, + // child: Center( + // child: Text(label, style: textStyle(25, true, white)))), + // ), + // ), + // ), + ), + ); + } } From 602819c612e5c0f8bc8ce935ba1d4d6860ded389 Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:40:51 +0900 Subject: [PATCH 4/7] fix : App bar layout --- lib/screens/products/item_list_page.dart | 5 ++++- lib/screens/products/liked_list_page.dart | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/screens/products/item_list_page.dart b/lib/screens/products/item_list_page.dart index b9b9fb7..994ccc7 100644 --- a/lib/screens/products/item_list_page.dart +++ b/lib/screens/products/item_list_page.dart @@ -60,7 +60,10 @@ class _ItemListPageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xfff4f4f4), - appBar: TopAppBar(label: widget.name), + appBar: TopAppBar( + label: widget.name, + searchable: true, + ), body: CustomScrollView( slivers: [ const SliverToBoxAdapter( diff --git a/lib/screens/products/liked_list_page.dart b/lib/screens/products/liked_list_page.dart index df58794..9050ef3 100644 --- a/lib/screens/products/liked_list_page.dart +++ b/lib/screens/products/liked_list_page.dart @@ -70,7 +70,10 @@ class _LikedListPageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xfff4f4f4), - appBar: const TopAppBar(label: "찜 목록"), + appBar: const TopAppBar( + label: "찜 목록", + searchable: true, + ), body: CustomScrollView( slivers: [ SliverPadding( From b5655963f8d406c985ea955b62476e9f6c3e7347 Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:55:45 +0900 Subject: [PATCH 5/7] refactor : fix animations --- lib/screens/main/main_screen.dart | 3 ++- lib/screens/products/product_detail_page.dart | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/screens/main/main_screen.dart b/lib/screens/main/main_screen.dart index b0b7a63..79d5630 100644 --- a/lib/screens/main/main_screen.dart +++ b/lib/screens/main/main_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; import 'package:saphy/models/product.dart'; @@ -173,7 +174,7 @@ class _MainScreenState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( + CupertinoPageRoute( builder: (context) => ItemListPage( name: category, url: url, diff --git a/lib/screens/products/product_detail_page.dart b/lib/screens/products/product_detail_page.dart index cb9df63..a1da334 100644 --- a/lib/screens/products/product_detail_page.dart +++ b/lib/screens/products/product_detail_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/widgets.dart'; @@ -318,9 +319,9 @@ class _ProductDetailState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( + CupertinoPageRoute( builder: (context) => PurchasePage( - product: widget.product, + product: productDetail!, )), ); }, From 0bced4644ca73b7426668cf21790956f23c2d6ac Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 14:55:58 +0900 Subject: [PATCH 6/7] design : fix designs and add images --- lib/screens/purchase/purchase_page.dart | 11 ++++++----- lib/screens/purchase/purchase_process_page.dart | 15 +++++++-------- lib/widgets/product_card.dart | 7 +++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/screens/purchase/purchase_page.dart b/lib/screens/purchase/purchase_page.dart index 4b4582b..072e06f 100644 --- a/lib/screens/purchase/purchase_page.dart +++ b/lib/screens/purchase/purchase_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:saphy/screens/purchase/purchase_process_page.dart'; import 'package:saphy/utils/colors.dart'; @@ -103,7 +104,7 @@ class _PurchaseFooterState extends State { ), ), const Divider( - color: black, + color: gray800, thickness: 1, indent: 5, endIndent: 5, @@ -111,13 +112,13 @@ class _PurchaseFooterState extends State { const SizedBox(height: 10), NormalButton( title: "구매하기", - bgColor: white, - txtColor: black, + bgColor: black, + txtColor: white, onTap: _isAgreed ? () { Navigator.push( context, - MaterialPageRoute( + CupertinoPageRoute( builder: (context) => PurchaseProcessPage( product: widget.product, // widget.product 사용 ), @@ -169,7 +170,7 @@ class PurchaseHeader extends StatelessWidget { ), const SizedBox(height: 10), const Divider( - color: black, + color: gray800, thickness: 1, indent: 40, endIndent: 40, diff --git a/lib/screens/purchase/purchase_process_page.dart b/lib/screens/purchase/purchase_process_page.dart index 20000b7..0241cf2 100644 --- a/lib/screens/purchase/purchase_process_page.dart +++ b/lib/screens/purchase/purchase_process_page.dart @@ -40,7 +40,7 @@ class _PurchaseProcessPageState extends State { onPressed: () { Navigator.of(context).pop(); }, - child: Text("취소", style: bodyText()), + child: Text("취소", style: textStyle(15, false, black)), ), ), ], @@ -99,13 +99,12 @@ class _PurchaseProcessPageState extends State { child: Padding( padding: const EdgeInsets.all(10.0), child: Container( - decoration: const BoxDecoration( - color: Colors.white, - // 이미지 추가 시: - // image: DecorationImage( - // image: NetworkImage('image_url'), - // fit: BoxFit.cover, - // ), + decoration: BoxDecoration( + color: Colors.transparent, + image: DecorationImage( + image: NetworkImage(widget.product.images[0].url), + fit: BoxFit.cover, + ), ), height: double.infinity, ), diff --git a/lib/widgets/product_card.dart b/lib/widgets/product_card.dart index 47d1aff..c5b0661 100644 --- a/lib/widgets/product_card.dart +++ b/lib/widgets/product_card.dart @@ -1,6 +1,6 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:intl/intl.dart'; import 'package:saphy/screens/products/product_detail_page.dart'; import 'package:saphy/utils/number_format.dart'; import 'package:saphy/utils/textstyles.dart'; @@ -18,7 +18,7 @@ class ProductCard extends StatelessWidget { onTap: () { Navigator.push( context, - MaterialPageRoute( + CupertinoPageRoute( builder: (context) => ProductDetail( product: product, ), @@ -40,8 +40,7 @@ class ProductCard extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), image: DecorationImage( - image: - CachedNetworkImageProvider(product.images[0].url ?? ""), + image: CachedNetworkImageProvider(product.images[0].url), fit: BoxFit.cover, ), ), From 57a33e19e879cc7d25bae0b5a13869c4e69e6383 Mon Sep 17 00:00:00 2001 From: cho4u4o Date: Sun, 20 Oct 2024 15:09:30 +0900 Subject: [PATCH 7/7] feat : enable filter button in favlist page --- lib/screens/main/main_screen.dart | 6 +- lib/screens/products/liked_list_page.dart | 109 +++++++++++++++------- 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/lib/screens/main/main_screen.dart b/lib/screens/main/main_screen.dart index 79d5630..dfedc1b 100644 --- a/lib/screens/main/main_screen.dart +++ b/lib/screens/main/main_screen.dart @@ -37,13 +37,13 @@ class _MainScreenState extends State { .toList(); return products; } else { - throw Exception('No results found in the response'); + return []; } } else { - throw Exception('Failed to load products'); + // 로드 실패 + return []; } } catch (e) { - print('Error: ${e.toString()}'); return []; } } diff --git a/lib/screens/products/liked_list_page.dart b/lib/screens/products/liked_list_page.dart index 9050ef3..7b1013b 100644 --- a/lib/screens/products/liked_list_page.dart +++ b/lib/screens/products/liked_list_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; // import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:intl/intl.dart'; +import 'package:path/path.dart'; import 'package:saphy/models/product.dart'; import 'package:saphy/service/api_service.dart'; import 'package:saphy/service/authentication/secure_storage.dart'; @@ -22,13 +23,13 @@ class _LikedListPageState extends State { late Future> _products; int cnt = 0; - Future> getProducts() async { + Future> getProducts(String url) async { String token = await readJwt(); token = token.toString().split(" ")[2]; try { final response = await APIService.instance.request( - 'https://saphy.site/item-wishes?type=ALL', + 'https://saphy.site/item-wishes?type=$url', DioMethod.get, contentType: 'application/json', token: "Bearer $token", @@ -55,12 +56,12 @@ class _LikedListPageState extends State { @override void initState() { super.initState(); - _products = getProducts(); - countProducts(); + _products = getProducts("ALL"); + countProducts("ALL"); } - Future countProducts() async { - List products = await getProducts(); + Future countProducts(String url) async { + List products = await getProducts(url); setState(() { cnt = products.length; }); @@ -86,26 +87,39 @@ class _LikedListPageState extends State { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - buildFilterButton("전체"), - const SizedBox(width: 10), - buildFilterButton("스마트폰"), - const SizedBox(width: 10), - buildFilterButton("스마트폰"), - const SizedBox(width: 10), - buildFilterButton("스마트폰"), - const SizedBox(width: 10), - buildFilterButton("스마트폰"), - const SizedBox(width: 10), - buildFilterButton("스마트폰"), - const SizedBox(width: 10), + buildFilterButton("전체", "ALL"), + const SizedBox( + width: 10, + ), + buildFilterButton("스마트폰", "PHONE"), + const SizedBox( + width: 10, + ), + buildFilterButton("태블릿", "TABLET"), + const SizedBox( + width: 10, + ), + buildFilterButton("노트북", "LAPTOP"), + const SizedBox( + width: 10, + ), + buildFilterButton("음향기기", "headphone-3d"), + const SizedBox( + width: 10, + ), + buildFilterButton("웨어러블", "wearable-3d"), ], ), ), ), ), ), + const SliverToBoxAdapter( + child: SizedBox(height: 10), + ), + _buildSorter(), SliverPadding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), sliver: SliverToBoxAdapter( child: Wrap( direction: Axis.horizontal, @@ -160,23 +174,48 @@ class _LikedListPageState extends State { ); } - Container buildFilterButton(String label) { - return Container( - height: 45, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - border: Border.all(color: gray300, width: 1), - color: white, + SliverPadding _buildSorter() { + return SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 30), + sliver: SliverToBoxAdapter( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '상품 $cnt', + style: subTitleText(), + ), + IconButton( + icon: const Icon(Icons.sort_outlined), + onPressed: () {}, + ), + ], + ), ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 13.0, vertical: 8), - child: Center( - child: Text( - label, - style: const TextStyle( - fontFamily: "Pretendard", - fontSize: 15, - fontWeight: FontWeight.bold), + ); + } + + InkWell buildFilterButton(String label, String url) { + return InkWell( + onTap: () { + setState(() { + // URL에 따라 제품을 다시 가져오고, 상태를 업데이트합니다. + _products = getProducts(url); + countProducts(url); // 필터에 맞는 제품 개수를 카운트합니다. + }); + }, + child: Container( + height: 45, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all(color: gray300, width: 1), + color: white, + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 13.0, vertical: 8), + child: Center( + child: Text(label, style: textStyle(15, false, null)), ), ), ),