Skip to content

Commit

Permalink
Merge branch 'feat/SAPHY-33-product-favlist' of https://github.com/20…
Browse files Browse the repository at this point in the history
…24-Saphy/App into feat/SAPHY-33-product-favlist
  • Loading branch information
yummjin committed Oct 6, 2024
2 parents ecc3941 + ea2fd3b commit 5a0b02b
Showing 1 changed file with 150 additions and 90 deletions.
240 changes: 150 additions & 90 deletions lib/screens/products/item_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,120 +14,180 @@ class ItemListPage extends StatefulWidget {
}

class _ItemListPageState extends State<ItemListPage> {
ProductProvider? _productProvider;

@override
void dispose() {
_productProvider?.cancelRequest(); // 미리 저장된 ProductProvider 사용
super.dispose();
}
late Future<List<Product>> _products;
int cnt = 0;

@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_productProvider = Provider.of<ProductProvider>(context, listen: false);
_productProvider?.fetchProducts(widget.url);
_products = getProducts();
countProducts();
}

Future<void> countProducts() async {
List<Product> products = await getProducts(); // getProducts()에서 결과를 대기
setState(() {
cnt = products.length; // 제품 개수를 cnt에 설정
});
}

Future<List<Product>> 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<String, dynamic>;
if (data['results'] != null) {
List<Product> 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<ProductProvider>(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>[
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),
),
),
),
);
}
Expand Down

0 comments on commit 5a0b02b

Please sign in to comment.