diff --git a/lib/components/search_form.dart b/lib/components/search_form.dart
index 5b941fa..50b7d0a 100644
--- a/lib/components/search_form.dart
+++ b/lib/components/search_form.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/flutter_svg.dart';
+import 'package:nekoya_flutter/components/search_page.dart';
 
 import 'package:nekoya_flutter/utils/utils.dart';
 
@@ -8,16 +9,21 @@ const OutlineInputBorder outlineInputBorder = OutlineInputBorder(
   borderSide: BorderSide.none,
 );
 
-class SearchForm extends StatelessWidget {
-  const SearchForm({
-    Key? key,
-  }) : super(key: key);
+class SearchForm extends StatefulWidget {
+  const SearchForm({Key? key}) : super(key: key);
+
+  @override
+  State<SearchForm> createState() => _SearchFormState();
+}
+
+class _SearchFormState extends State<SearchForm> {
+  TextEditingController searchController = TextEditingController();
 
   @override
   Widget build(BuildContext context) {
     return Form(
       child: TextFormField(
-        onSaved: (value) {},
+        controller: searchController,
         decoration: InputDecoration(
           filled: true,
           fillColor: const Color(0xff212226),
@@ -45,7 +51,11 @@ class SearchForm extends StatelessWidget {
                     borderRadius: BorderRadius.all(Radius.circular(12)),
                   ),
                 ),
-                onPressed: () {},
+                onPressed: () {
+                  Navigator.push(context, MaterialPageRoute(
+                    builder: (context) => SearchPage(query: searchController.text)
+                  ));
+                },
                 child: const Text('Search'),
               ),
             ),
diff --git a/lib/components/search_item.dart b/lib/components/search_item.dart
new file mode 100644
index 0000000..adb3066
--- /dev/null
+++ b/lib/components/search_item.dart
@@ -0,0 +1,41 @@
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+
+class SearchItem extends StatelessWidget {
+  const SearchItem({Key? key, required this.title, required this.description, required this.imageUrl, required this.callback}) : super(key: key);
+
+  final String title;
+  final String description;
+  final String imageUrl;
+  final Function() callback;
+
+  @override
+  Widget build(BuildContext context) {
+    return Card(
+      child: ListTile(
+        title: Text(title, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
+        subtitle: Text(description, style: const TextStyle(color: Color.fromARGB(255, 201, 191, 191), fontWeight: FontWeight.w400)),
+        tileColor: const Color(0xff212226),
+        leading: CachedNetworkImage(
+          imageUrl: imageUrl,
+          placeholder: (context, url) =>
+              const CircularProgressIndicator(
+            color: Color(0xff8B0000),
+          ),
+          errorWidget: (context, url, error) =>
+            Image.asset('assets/images/image_error.webp'),
+          fadeOutDuration: const Duration(milliseconds: 5),
+          imageBuilder: (context, imageProvider) => Container(
+            width: 100,
+            height: 100,
+            decoration: BoxDecoration(
+                image: DecorationImage(
+                    image: imageProvider, fit: BoxFit.cover)),
+          ),
+        ),
+        trailing: const Icon(Icons.arrow_right, color: Colors.white,),
+        onTap: () => callback(),
+      )
+    );
+  }
+}
\ No newline at end of file
diff --git a/lib/components/search_page.dart b/lib/components/search_page.dart
new file mode 100644
index 0000000..8a453aa
--- /dev/null
+++ b/lib/components/search_page.dart
@@ -0,0 +1,63 @@
+import 'package:intl/intl.dart';
+import 'package:flutter/material.dart';
+
+import 'package:nekoya_flutter/api/api.dart';
+import 'package:nekoya_flutter/components/product_detail.dart';
+import 'package:nekoya_flutter/components/search_item.dart';
+
+class SearchPage extends StatefulWidget {
+  const SearchPage({Key? key, required this.query}) : super(key: key);
+
+  final String query;
+
+  @override
+  State<SearchPage> createState() => _SearchPageState();
+}
+
+class _SearchPageState extends State<SearchPage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      backgroundColor: const Color(0xff1b1c1e),
+      appBar: AppBar(
+        title: Text("Search Result of ${widget.query}"),
+        centerTitle: true,
+        backgroundColor: const Color(0xff212226),
+      ),
+      body: FutureBuilder<dynamic>(
+        future: getProducts(),
+        builder: (context, snapshot) {
+          if (snapshot.hasData) {
+            var data = snapshot.data;
+            var filteredData = data.where((x) => x['TITLE'].toLowerCase().contains(widget.query.toLowerCase()) ? true : false).toList();
+            return ListView.separated(
+              separatorBuilder: (BuildContext context, int index) => const Divider(),
+              itemCount: filteredData.length,
+              itemBuilder: (context, index) {
+                return SearchItem(
+                  title: filteredData[index]['TITLE'],
+                  description: "Price : Rp ${NumberFormat('#,##0.00', 'ID').format(filteredData[index]['PRICE'])}",
+                  imageUrl: "https://nekoya.moe.team/img/${filteredData[index]['IMAGE']}",
+                  callback: () {
+                    showModalBottomSheet(
+                      isScrollControlled: true,
+                      backgroundColor: Colors.transparent,
+                      context: context,
+                      builder: (context) => productDetail(context, filteredData[index]['ID']),
+                    );
+                  },
+                );
+              }
+            );
+          }
+          
+          return const Center(
+            child: CircularProgressIndicator(
+              color: Color(0xff8B0000),
+            ),
+          );
+        }
+      ),
+    );
+  }
+}
\ No newline at end of file