diff --git a/lib/api/products.dart b/lib/api/api.dart
similarity index 56%
rename from lib/api/products.dart
rename to lib/api/api.dart
index c9989d1..df3e0c0 100644
--- a/lib/api/products.dart
+++ b/lib/api/api.dart
@@ -5,4 +5,10 @@ Future<dynamic> getProducts() async {
   var req = await Dio().get(host + '/getproducts');
   var res = req.data;
   return res;
+}
+
+Future<dynamic> getProduct(id) async {
+  var req = await Dio().get(host + '/getproduct', queryParameters: {'id': id});
+  var res = req.data;
+  return res;
 }
\ No newline at end of file
diff --git a/lib/components/product_box.dart b/lib/components/product_box.dart
index b5d10a6..c92f97a 100644
--- a/lib/components/product_box.dart
+++ b/lib/components/product_box.dart
@@ -2,11 +2,12 @@ import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/material.dart';
 
 class ProductBox extends StatefulWidget {
-  const ProductBox({Key? key, required this.imageUrl, required this.title})
+  const ProductBox({Key? key, required this.imageUrl, required this.title, required this.callback})
       : super(key: key);
 
   final String imageUrl;
   final String title;
+  final Function() callback;
 
   @override
   State<ProductBox> createState() => _ProductBoxState();
@@ -23,7 +24,7 @@ class _ProductBoxState extends State<ProductBox> {
           borderRadius: BorderRadius.circular(10),
         ),
         child: InkWell(
-          onTap: () {},
+          onTap: () => widget.callback(),
           borderRadius: BorderRadius.circular(10),
           splashColor: const Color(0xff8B0000),
           highlightColor: const Color(0xff8B0000),
diff --git a/lib/components/product_detail.dart b/lib/components/product_detail.dart
new file mode 100644
index 0000000..4b90e8c
--- /dev/null
+++ b/lib/components/product_detail.dart
@@ -0,0 +1,88 @@
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+
+import 'package:nekoya_flutter/api/api.dart';
+
+Widget makeDismissible({required context, required Widget child}) => GestureDetector(
+  behavior: HitTestBehavior.opaque,
+  onTap: () => Navigator.of(context).pop(),
+  child: GestureDetector(
+    onTap: () {},
+    child: child,
+  )
+);
+
+Widget productDetail(context, id) {
+  return makeDismissible(
+    context: context,
+    child: DraggableScrollableSheet(
+      initialChildSize: 0.7,
+      minChildSize: 0.5,
+      maxChildSize: 1,
+      builder: (_, controller) => FutureBuilder<dynamic> (
+        future: getProduct(id),
+        builder: (context, snapshot) {
+          if (snapshot.hasData) {
+            var data = snapshot.data;
+            return Container(
+              decoration: const BoxDecoration(
+                color: Color(0xff1b1c1e),
+                borderRadius: BorderRadius.vertical(top: Radius.circular(20))
+              ),
+              padding: const EdgeInsets.all(16),
+              child: ListView(
+                controller: controller,
+                children: [
+                  CachedNetworkImage(
+                    imageUrl: 'https://nekoya.moe.team/img/' + data[0]['IMAGE'],
+                    placeholder: (context, url) =>
+                      const CircularProgressIndicator(
+                        color: Color(0xff8B0000),
+                    ),
+                    errorWidget: (context, url, error) => Image.asset('assets/image-error.webp'),
+                    fadeOutDuration: const Duration(milliseconds: 5),
+                    imageBuilder: (context, imageProvider) => Container(
+                      margin: const EdgeInsets.all(5.0),
+                      width: 300,
+                      height: 300,
+                      decoration: BoxDecoration(
+                          image: DecorationImage(
+                              image: imageProvider, fit: BoxFit.cover)),
+                    ),
+                  ),
+                  Text(data[0]['TITLE'], style: const TextStyle(color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.w700),),
+                  const SizedBox(height: 15.0),
+                  Text(data[0]['DESCRIPTION'], style: const TextStyle(color: Colors.white, fontSize: 18.0),),
+                  const SizedBox(height: 15.0),
+                  Text('Price : ' + data[0]['PRICE'].toString(), style: const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.w500),),
+                  Text('Stock : ' + data[0]['STOCK'].toString(), style: const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.w500),),
+                  Text('Size : ' + data[0]['SIZE'], style: const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.w500),),
+                  const SizedBox(height: 30.0),
+                  ElevatedButton.icon(
+                    onPressed: (){},
+                    icon: const Icon(Icons.add_shopping_cart),
+                    label: const Text('Add to Cart', style: TextStyle(color: Colors.white, fontSize: 18.0),),
+                    style: ButtonStyle(
+                      backgroundColor: MaterialStateProperty.all<Color>(const Color(0xff8B0000)),
+                      shape: MaterialStateProperty.all<RoundedRectangleBorder>(
+                        RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(18.0)
+                        )
+                      )
+                    )
+                  )
+                ],
+              )
+            );
+          }
+
+          return const Center(
+            child: CircularProgressIndicator(
+              color: Color(0xff8B0000),
+            ),
+          );
+        }
+      )
+    )
+  );
+}
\ No newline at end of file
diff --git a/lib/screens/products.dart b/lib/screens/products.dart
index 50659f4..94f2ca7 100644
--- a/lib/screens/products.dart
+++ b/lib/screens/products.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
-import 'package:nekoya_flutter/api/products.dart';
+import 'package:nekoya_flutter/api/api.dart';
 import 'package:nekoya_flutter/components/product_box.dart';
+import 'package:nekoya_flutter/components/product_detail.dart';
 
 class Products extends StatefulWidget {
   const Products({Key? key}) : super(key: key);
@@ -30,7 +31,15 @@ class _ProductsState extends State<Products> {
                 return ProductBox(
                     imageUrl:
                         'https://nekoya.moe.team/img/' + data[index]['IMAGE'],
-                    title: data[index]['TITLE']
+                    title: data[index]['TITLE'],
+                    callback: () {
+                      showModalBottomSheet(
+                        isScrollControlled: true,
+                        backgroundColor: Colors.transparent,
+                        context: context,
+                        builder: (context) => productDetail(context, data[index]['ID']),
+                      );
+                    },
                 );
               }),
             );