diff --git a/lib/screens/products/item_list_page.dart b/lib/screens/products/item_list_page.dart index 0ee9143..fa6642c 100644 --- a/lib/screens/products/item_list_page.dart +++ b/lib/screens/products/item_list_page.dart @@ -14,120 +14,180 @@ class ItemListPage extends StatefulWidget { } class _ItemListPageState extends State { - ProductProvider? _productProvider; - - @override - void dispose() { - _productProvider?.cancelRequest(); // 미리 저장된 ProductProvider 사용 - super.dispose(); - } + late Future> _products; + int cnt = 0; @override void initState() { super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { - _productProvider = Provider.of(context, listen: false); - _productProvider?.fetchProducts(widget.url); + _products = getProducts(); + countProducts(); + } + + Future countProducts() async { + List products = await getProducts(); // getProducts()에서 결과를 대기 + setState(() { + cnt = products.length; // 제품 개수를 cnt에 설정 }); } + Future> getProducts() async { + final dio = Dio(); + try { + final response = await dio + .get('https://saphy.site/api/items?deviceType=${widget.url}&size=20'); + if (response.statusCode == 200) { + final data = response.data as Map; + if (data['results'] != null) { + List products = (data['results'] as List) + .map((item) => Product.fromJson(item)) + .toList(); + return products; + } else { + throw Exception('No results found in the response'); + } + } else { + throw Exception('Failed to load products'); + } + } catch (e) { + print('Error: ${e.toString()}'); // 오류 메시지 확인 + return []; + } + } + @override Widget build(BuildContext context) { final productProvider = Provider.of(context); return Scaffold( backgroundColor: const Color(0xfff4f4f4), - appBar: _buildAppBar(context), + appBar: AppBar( + automaticallyImplyLeading: false, + backgroundColor: altWhite, + title: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton( + icon: const Icon( + Icons.arrow_back_ios, + size: 25, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + IconButton( + icon: const Icon( + Icons.search, + size: 25, + ), + onPressed: () {}, + ), + ], + ), + ), + ), body: CustomScrollView( slivers: [ - _buildHeader(widget.name), - _buildProductCount(productProvider.count), - _buildProductGrid(productProvider) - ], - ), - ); - } - - AppBar _buildAppBar(BuildContext context) { - return AppBar( - automaticallyImplyLeading: false, - backgroundColor: altWhite, - title: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: const Icon(Icons.arrow_back_ios, size: 25), - onPressed: () { - Navigator.pop(context); - }, + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 30.0, + ), + child: Text( + widget.name, + style: titleText(), + ), ), - IconButton( - icon: const Icon(Icons.search, size: 25), - onPressed: () {}, + ), + const SliverToBoxAdapter( + child: SizedBox( + height: 10, ), - ], - ), - ), - ); - } - - SliverToBoxAdapter _buildHeader(String name) { - return SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Text(name, style: titleText()), - ), - ); - } - - SliverPadding _buildProductCount(int count) { - return SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 30), - sliver: SliverToBoxAdapter( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text.rich( - TextSpan( - text: "상품 ", - style: subTitleText(bold: false), - children: [ - TextSpan(text: "$count", style: subTitleText()) + ), + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 20), + sliver: SliverToBoxAdapter( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '상품 $cnt', + style: subTitleText(), + ), + IconButton( + icon: const Icon(Icons.sort_outlined), + onPressed: () {}, + ), ], ), ), - IconButton( - icon: const Icon( - Icons.sort, - size: 20, - ), - onPressed: () {}), - ], - ), + ), + SliverPadding( + padding: const EdgeInsets.all(20), + 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('No products found')); + } 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(), + ); + } + }) + ], + ), + ), + ), + ], ), ); } - SliverPadding _buildProductGrid(ProductProvider provider) { - return SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 20), - sliver: SliverToBoxAdapter( - child: provider.isLoading - ? const Center(child: CircularProgressIndicator()) - : provider.products.isEmpty - ? const Center(child: Text('상품이 없습니다')) - : Wrap( - direction: Axis.horizontal, - alignment: WrapAlignment.spaceBetween, - spacing: 15, - runSpacing: 15, - children: provider.products - .map((product) => ProductCard(product: product)) - .toList(), - ), + Container buildFilterButton(String label) { + return 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: const TextStyle( + fontFamily: "Pretendard", + fontSize: 15, + fontWeight: FontWeight.bold), + ), + ), ), ); }