Skip to content

Commit

Permalink
Merge pull request #50 from 2024-Saphy/feat/SAPHY-32-search-page
Browse files Browse the repository at this point in the history
SAPHY-178 [FEAT] : add search page by integrating apis
  • Loading branch information
cho4u4o authored Oct 8, 2024
2 parents 5dc1309 + 48f43d6 commit a868ecf
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 151 deletions.
92 changes: 24 additions & 68 deletions lib/screens/products/item_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:saphy/utils/colors.dart';
import 'package:saphy/utils/textstyles.dart';
import 'package:saphy/widgets/app_bar.dart';
import 'package:saphy/widgets/product_card.dart';
import 'package:dio/dio.dart';
import 'package:saphy/models/product.dart';
Expand Down Expand Up @@ -59,10 +60,9 @@ class _ItemListPageState extends State<ItemListPage> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xfff4f4f4),
appBar: _appBar(),
appBar: TopAppBar(label: widget.name),
body: CustomScrollView(
slivers: [
_buildHeader(),
const SliverToBoxAdapter(
child: SizedBox(height: 10),
),
Expand All @@ -73,51 +73,6 @@ class _ItemListPageState extends State<ItemListPage> {
);
}

AppBar _appBar() {
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);
},
),
IconButton(
icon: const Icon(
Icons.search,
size: 25,
),
onPressed: () {},
),
],
),
),
);
}

SliverToBoxAdapter _buildHeader() {
return SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0,
),
child: Text(
widget.name,
style: titleText(),
),
),
);
}

SliverPadding _buildSorter() {
return SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 30),
Expand Down Expand Up @@ -151,27 +106,28 @@ class _ItemListPageState extends State<ItemListPage> {
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(),
);
}
})
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(),
);
}
},
)
],
),
),
Expand Down
21 changes: 2 additions & 19 deletions lib/screens/products/liked_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:saphy/models/product.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';

class LikedListPage extends StatefulWidget {
const LikedListPage({super.key});
Expand All @@ -19,27 +20,9 @@ class _LikedListPageState extends State<LikedListPage> {

@override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: const Color(0xfff4f4f4),
appBar: AppBar(
backgroundColor: altWhite,
title: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: const Icon(Icons.arrow_back_ios, size: 25),
onPressed: () {},
),
SizedBox(height: 50, width: screenWidth - 150),
IconButton(
icon: const Icon(Icons.search, size: 25), onPressed: () {}),
],
),
),
),
appBar: const TopAppBar(label: "찜 목록"),
body: CustomScrollView(
slivers: [
SliverPadding(
Expand Down
138 changes: 138 additions & 0 deletions lib/screens/search/search_result_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:saphy/utils/colors.dart';
import 'package:saphy/utils/textstyles.dart';
import 'package:saphy/widgets/product_card.dart';
import 'package:saphy/models/product.dart';
import 'package:saphy/widgets/textfield.dart';

class SearchResultScreen extends StatefulWidget {
final String query;

const SearchResultScreen({super.key, required this.query});

@override
State<SearchResultScreen> createState() => _SearchResultScreenState();
}

class _SearchResultScreenState extends State<SearchResultScreen> {
late TextEditingController _controller;
Future<List<Product>>? _products;

@override
void initState() {
super.initState();
_controller = TextEditingController();
_products = searchText(widget.query);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: const Color(0xfff4f4f4),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: altWhite,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
size: 25,
),
onPressed: () {
Navigator.of(context).pop();
},
),
textField(
_controller,
context,
(String value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchResultScreen(query: value),
),
);
},
),
IconButton(
icon: const Icon(
Icons.search,
size: 25,
),
onPressed: () {
setState(() {
_products = searchText(_controller.text);
});
},
),
],
),
),
body: CustomScrollView(slivers: [
SliverPadding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 30),
sliver: SliverToBoxAdapter(
child: FutureBuilder<List<Product>>(
future: _products,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(
child: 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(),
);
}
},
),
),
),
]),
);
}

Future<List<Product>> searchText(String value) async {
final dio = Dio();
try {
final response = await dio.get(
'https://saphy.site/api/items?deviceType=PHONE&size=20&query=$value');

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('검색 결과가 없습니다.');
}
} else {
throw Exception('상품 로드에 실패했습니다.');
}
} catch (e) {
throw Exception('에러가 발생했습니다.');
}
}
}
Loading

0 comments on commit a868ecf

Please sign in to comment.