Skip to content

Commit 1a9a86d

Browse files
Add product search functionality
1 parent bc09570 commit 1a9a86d

File tree

4 files changed

+116
-3
lines changed

4 files changed

+116
-3
lines changed

lib/controllers/home_controller.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class HomeController extends GetxController {
66

77
var userName = '';
88

9+
TextEditingController searchController = TextEditingController();
10+
911
@override
1012
void onInit() {
1113
getUserName();

lib/services/firestore_service.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,8 @@ class FirestoreService {
8383
.collection(productsCollection)
8484
.where('p_is_featured', isEqualTo: true)
8585
.get();
86+
87+
// get search products
88+
static getSearchProducts(title) =>
89+
firestore.collection(productsCollection).get();
8690
}

lib/views/home_screen_view/home_screen.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ import 'package:emart/common_widgets/home_buttons.dart';
55
import 'package:emart/common_widgets/loading_indicator.dart';
66
import 'package:emart/consts/consts.dart';
77
import 'package:emart/consts/list.dart';
8+
import 'package:emart/controllers/home_controller.dart';
89
import 'package:emart/services/firestore_service.dart';
910
import 'package:emart/views/category_screen_view/item_details.dart';
1011
import 'package:emart/views/home_screen_view/components/featured_button.dart';
12+
import 'package:emart/views/home_screen_view/search_screen.dart';
1113
import 'package:get/get.dart';
1214

1315
class HomeScreen extends StatelessWidget {
1416
const HomeScreen({super.key});
1517

1618
@override
1719
Widget build(BuildContext context) {
20+
// TODO: work on message screen (seller buyer messages)
21+
var controller = Get.find<HomeController>();
1822
return Container(
1923
color: lightGolden,
2024
padding: const EdgeInsets.all(12),
@@ -28,13 +32,22 @@ class HomeScreen extends StatelessWidget {
2832
alignment: Alignment.center,
2933
color: lightGrey,
3034
child: TextFormField(
31-
decoration: const InputDecoration(
35+
controller: controller.searchController,
36+
decoration: InputDecoration(
3237
border: InputBorder.none,
33-
suffix: Icon(Icons.search),
38+
suffix: const Icon(Icons.search).onTap(() {
39+
if (controller.searchController.text.isNotEmptyAndNotNull) {
40+
Get.to(() => SearchScreen(
41+
title: controller.searchController.text,
42+
));
43+
controller.searchController.clear();
44+
FocusScope.of(context).unfocus();
45+
}
46+
}),
3447
fillColor: whiteColor,
3548
filled: true,
3649
hintText: searchanyThing,
37-
hintStyle: TextStyle(color: textfieldGrey),
50+
hintStyle: const TextStyle(color: textfieldGrey),
3851
),
3952
),
4053
),
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// ignore_for_file: curly_braces_in_flow_control_structures
2+
3+
import 'package:cloud_firestore/cloud_firestore.dart';
4+
import 'package:emart/common_widgets/loading_indicator.dart';
5+
import 'package:emart/consts/consts.dart';
6+
import 'package:emart/services/firestore_service.dart';
7+
import 'package:emart/views/category_screen_view/item_details.dart';
8+
import 'package:get/get.dart';
9+
10+
class SearchScreen extends StatelessWidget {
11+
final String? title;
12+
const SearchScreen({
13+
super.key,
14+
required this.title,
15+
});
16+
17+
@override
18+
Widget build(BuildContext context) {
19+
return Scaffold(
20+
backgroundColor: whiteColor,
21+
appBar: AppBar(title: title!.text.color(darkFontGrey).make()),
22+
body: FutureBuilder(
23+
future: FirestoreService.getSearchProducts(title),
24+
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
25+
if (!snapshot.hasData)
26+
return loadingIndicator();
27+
else if (snapshot.data!.docs.isEmpty)
28+
return "No such product".text.color(darkFontGrey).makeCentered();
29+
var data = snapshot.data!.docs;
30+
var filteredData = data
31+
.where((element) => element['p_name']
32+
.toString()
33+
.toLowerCase()
34+
.contains(title!.toLowerCase()))
35+
.toList();
36+
return Padding(
37+
padding: const EdgeInsets.all(8.0),
38+
child: GridView(
39+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
40+
crossAxisCount: 2,
41+
mainAxisSpacing: 8,
42+
crossAxisSpacing: 8,
43+
mainAxisExtent: 300,
44+
),
45+
children: filteredData
46+
.mapIndexed(
47+
(currentValue, index) => Column(
48+
crossAxisAlignment: CrossAxisAlignment.start,
49+
children: [
50+
Image.network(
51+
filteredData[index]['p_images'][0],
52+
width: 200,
53+
height: 200,
54+
fit: BoxFit.cover,
55+
),
56+
const Spacer(),
57+
"${filteredData[index]['p_name']}"
58+
.text
59+
.fontFamily(semibold)
60+
.color(darkFontGrey)
61+
.make(),
62+
10.heightBox,
63+
"${filteredData[index]['p_price']}"
64+
.numCurrency
65+
.text
66+
.color(redColor)
67+
.fontFamily(bold)
68+
.size(16)
69+
.make(),
70+
],
71+
)
72+
.box
73+
.white
74+
.roundedSM
75+
.shadowSm
76+
.margin(const EdgeInsets.all(4))
77+
.padding(const EdgeInsets.all(12))
78+
.make()
79+
.onTap(() {
80+
Get.to(
81+
() => ItemDetails(
82+
title: filteredData[index]['p_name'],
83+
data: filteredData[index]),
84+
);
85+
}),
86+
)
87+
.toList(),
88+
),
89+
);
90+
},
91+
),
92+
);
93+
}
94+
}

0 commit comments

Comments
 (0)