diff --git a/src/page/DetailProduk/DetailProduk.css b/src/page/DetailProduk/DetailProduk.css
index 672606b4a1bf242bf5eb461c4a5865e6450f8f3d..1909406c508817d922a09915f0a5e7bfbb0bc9fe 100644
--- a/src/page/DetailProduk/DetailProduk.css
+++ b/src/page/DetailProduk/DetailProduk.css
@@ -26,7 +26,17 @@
 .detail-produk-wrapper .detail-produk-image-section {
     width: 100%;
     height: 300px;
-    margin-bottom: 50px;
+    margin-bottom: 20px;
+}
+
+.detail-produk-wrapper .detail-produk-image-section img {
+    max-height: 100%;
+    max-width: 100%;
+    object-fit: contain;
+}
+
+.detail-produk-wrapper .detail-produk-description-section {
+    text-align: left;
 }
 
 .detail-produk-wrapper .detail-produk-description-section {
@@ -36,6 +46,22 @@
 .detail-produk-wrapper .detail-produk-description-section h5 {
     font-weight: 700;
     color: var(--wkd-red);
+    font-family: 'DM Sans', sans-serif;
+    padding-top: 20px;
+    font-size: 1.3rem;
+}
+
+.detail-produk-wrapper .detail-produk-description-section #nama-supplier {
+    font-size: 1.2rem;
+    font-weight: 700;
+}
+
+.detail-produk-wrapper .detail-produk-description-section hr {
+    margin: 10px 0px;
+}
+
+.detail-produk-wrapper .detail-produk-description-section .block-section {
+    margin-bottom: 30px;
 }
 
 .detail-produk-wrapper #harga-produk {
@@ -44,6 +70,12 @@
     font-size: 2rem;
 }
 
+.detail-produk-wrapper #nama-produk {
+    font-weight: 700;
+    font-size: 2rem;
+    font-family: 'DM Sans', sans-serif;
+}
+
 .detail-produk-wrapper .input-section * {
     border: none;
     padding: 5px 12px;
@@ -68,4 +100,4 @@
 .detail-produk-wrapper .input-section input {
     width: 120px;
     text-align: center;
-}
\ No newline at end of file
+}
diff --git a/src/page/DetailProduk/DetailProduk.js b/src/page/DetailProduk/DetailProduk.js
index 3c4fd2cc7da272aed47595c9722dfeb2b54a24d3..962783b8e2ed351ef3ecc1461049db3ee1c05b2d 100644
--- a/src/page/DetailProduk/DetailProduk.js
+++ b/src/page/DetailProduk/DetailProduk.js
@@ -1,69 +1,105 @@
 import './DetailProduk.css';
 import React, { useState, useEffect } from 'react';
 import { connect } from 'react-redux';
-import { Redirect, useHistory } from 'react-router-dom';
+import { Redirect } from 'react-router-dom';
 import axios from 'axios';
 import { ChevronLeft } from 'react-feather';
+import { Carousel } from "react-responsive-carousel";
 import NoImage from './gambar-tidak-tersedia.svg';
 import KeranjangButton from '../../components/KeranjangButton/KeranjangButton'
 import TambahKeKeranjang from '../../components/TambahKeKeranjang/TambahKeKeranjang';
 
-const dummyData = {
-  "id": 1,
-  "supplier": null,
-  "judul": "Jaket Kulit",
-  "kategori": "Fashion Wanita",
-  "deskripsi": "Bahan tebal",
-  "merek": "",
-  "isBerbahaya": false,
-  "isMudahPecah": false,
-  "harga": 100000,
-  "thumbnail": null,
-  "berat": 0,
-  "kondisi": "",
-  "variasi": [
-      {
-          "id": 1,
-          "namaVariasi": "warna",
-          "pilihanVariasi": "coklat",
-          "stok": 302,
-          "produk": 1
-      }
-  ],
-  "jasaPengiriman": [],
-  "fileProduk": []
-}
-
-
 const DetailProduk = ({ isAuthenticated, user, match }) => {
   const [dataProduk, setDataProduk] = useState({supplier:{namaSupplier:''}, variasi:[]});
   const [loading, setLoading] = useState(true);
+  const [supplier, setSupplier] = useState("");
+  const [namaProduk, setNamaProduk] = useState("");
+  const [deskripsiProduk, setDeskripsiProduk] = useState("");
+  const [merekProduk, setMerekProduk] = useState("");
+  const [kategoriProduk, setKategoriProduk] = useState("");
+  const [isProdukBerbahaya, setIsProdukBerbahaya] = useState(false);
+  const [isProdukMudahPecah, setIsProdukMudahPecah] = useState(false);
+  const [hargaProduk, setHargaProduk] = useState(0);
+  const [beratProduk, setBeratProduk] = useState(0);
+  const [kondisiProduk, setKondisiProduk] = useState("");
+  const [fileProduk, setFileProduk] = useState([]);
+  const [variasiProduk, setVariasiProduk] = useState([]);
+
+  const KATEGORI_CHOICES = {
+    'AF': 'Aksesoris Fashion',
+    'AT': 'Alat Tulis',
+    'E': 'Elektronik',
+    'FBNA': 'Fashion Bayi dan Anak',
+    'FM': 'Fashion Muslim',
+    'FP': 'Fashion Pria',
+    'FW': 'Fashion Wanita',
+    'HDA': 'Handphone dan Aksesoris',
+    'HDK': 'Hobi dan Koleksi',
+    'IDB': 'Ibu dan Bayi',
+    'K': 'Kesehatan',
+    'KDA': 'Komputer dan Aksesoris',
+    'M': 'Mainan',
+    'MDM': 'Makanan dan Minuman',
+    'ODO': 'Olahraga dan Outdoor',
+    'O': 'Otomotif',
+    'PDK': 'Perawatan dan Kecantikan',
+    'PR': 'Perlengkapan Rumah',
+    'SDP': 'Souvenir dan Pesta'
+  }
 
-  let history = useHistory();
-    const config = {
-        headers: {
-          'Content-Type': 'multipart/form-data',
-          'Authorization': `JWT ${localStorage.getItem('access')}`,
-        }
+  const config = {
+    headers: {
+      'Content-Type': 'multipart/form-data',
+      'Authorization': `JWT ${localStorage.getItem('access')}`,
+    }
+  };
+
+  let rupiahIDLocale = Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR' });
+
+  useEffect(() => {
+    const fetchConfig = {
+      headers: {
+        'Authorization': `JWT ${localStorage.getItem('access')}`,
+      }
     };
 
-  const fetchDataProduk = async () => {
-    try {
-      var produkObj = await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/${match.params.pk}`, config);
-      console.log(produkObj.data);
-      setDataProduk(produkObj.data);
-      setLoading(false);
-    }
-    catch (err) {           
-        history.push('/')
-        console.log(err);
-        alert('Terjadi kesalahan saat fetching data produk' + err)
+    const fetchDataProduk = async () => {
+      if (localStorage.getItem('access')) {
+        try {
+          await axios.get(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/${match.params.pk}/`, fetchConfig)
+          .then(produkObj => {
+            setDataProduk(produkObj.data);
+            setLoading(false);
+            setSupplier(produkObj.data.supplier.namaSupplier ? produkObj.data.supplier.namaSupplier : "-");
+            setNamaProduk(produkObj.data.judul);
+            setDeskripsiProduk(produkObj.data.deskripsi);
+            setMerekProduk(produkObj.data.merek);
+            setKategoriProduk(produkObj.data.kategori);
+            setIsProdukBerbahaya(produkObj.data.isBerbahaya);
+            setIsProdukMudahPecah(produkObj.data.isMudahPecah);
+            setHargaProduk(produkObj.data.harga);
+            setBeratProduk(produkObj.data.berat);
+            setKondisiProduk(produkObj.data.kondisi);
+            setVariasiProduk(produkObj.data.variasi);
+            setFileProduk(produkObj.data.fileProduk);
+            setLoading(false);
+          })
+        } catch (err) {
+            console.log(err);
+            alert('Terjadi kesalahan saat fetching data produk')
+        }
+      } else {
+          console.log('missing token');
+          alert('Terdapat kesalahan pada autentikasi akun anda. Anda dapat melakukan refresh pada halaman ini')
+        }
     }
-  }
 
-  useEffect(() => {
-    fetchDataProduk();
-  }, []);
+    let isMounted = true;
+    if (isMounted && loading) {
+      fetchDataProduk()
+    }
+    return () => { isMounted = false }
+  }, [loading, setLoading, match.params.pk]);
 
   function getVariasiId() {
     if (dataProduk.variasi.length > 0) {
@@ -90,7 +126,7 @@ const DetailProduk = ({ isAuthenticated, user, match }) => {
         formDataToSend.append('variasiId', variasi_id);
         formDataToSend.append('jumlah', jumlah);
         axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/api/keranjang/tambah-item`, formDataToSend, config)
-          .then((response) => {
+          .then(() => {
               alert('Produk berhasil ditambahkan ke keranjang');
           }, (error) => {
               console.log(error);
@@ -108,46 +144,70 @@ const DetailProduk = ({ isAuthenticated, user, match }) => {
   }
 
   if (!isAuthenticated) return <Redirect to="/masuk" />
-  if (user.role !== "Mitra") return <Redirect to="/" />
-
-  // console.log(dataProduk.fileProduk)
+  if (user.role !== "Mitra" && user.role !== "Supplier") return <Redirect to="/" />
 
   return (
     <div className="detail-produk-wrapper">
       <KeranjangButton />
-      <h3 className="back-button" onClick={() => window.history.back()}><ChevronLeft size="40" className="chevron-left" />Kembali</h3>
+      <h3 data-testid="back-btn" className="back-button" onClick={() => window.history.back()}><ChevronLeft size="40" className="chevron-left" />Kembali</h3>
 
       <div className="detail-produk-content">
         <div className="detail-produk-left-section">
           <div className='detail-produk-image-section'>
             <div className="detail-pengadaan-carousel-wrapper">
-              <img alt="" src={NoImage} />
+              { fileProduk.length === 0 ? <img alt="" src={NoImage} /> :
+                <Carousel autoPlay infiniteLoop showThumbs={false}>
+                  {fileProduk.map(item => (
+                    <div >
+                      <img alt="" src={item.fileProduk} />
+                    </div>
+                  ))}
+                </Carousel>
+              }
             </div>
           </div>
           <div className='detail-produk-description-section'>
-            <h4>{dataProduk.supplier.namaSupplier}</h4>
-            <hr/>
-            <h5>Detail Produk</h5>
-            {dataProduk.kategori !== "" && <p>Kategori: <b>{dataProduk.kategori}</b></p>}
-            {dataProduk.merek !== "" && <p>Merek: <b>{dataProduk.merek}</b></p>}
-            {dataProduk.berat !== "" && <p>Berat: <b>{dataProduk.berat}</b></p>}
-            {dataProduk.kondisi !== "" && <p>Kondisi: <b>{dataProduk.kondisi}</b></p>}
-            {dataProduk.isBerbahaya !== false && <p>Berbahaya: <b>Ya</b></p>}
-            {dataProduk.isMudahPecah !== false && <p>MudahPecah: <b>Ya</b></p>}
-            <p><b>Deskripsi:</b></p>
-            <p>{dataProduk.deskripsi}</p>
+            <div className='block-section'>
+              <h5>Supplier</h5>
+              <hr/>
+              <p id='nama-supplier'>{supplier}</p>
+            </div>
+            <div className='block-section'>
+              <h5>Detail Produk</h5>
+              <hr/>
+              {kategoriProduk !== "" && <p><b>Kategori:</b> {KATEGORI_CHOICES[kategoriProduk]}</p>}
+              {merekProduk !== "" && <p><b>Merek:</b> {merekProduk}</p>}
+              {beratProduk !== "" && <p><b>Berat:</b> {beratProduk}</p>}
+              {kondisiProduk !== "" && <p><b>Kondisi:</b> {kondisiProduk}</p>}
+              {isProdukBerbahaya !== false && <p><b>Berbahaya:</b> Ya</p>}
+              {isProdukMudahPecah !== false && <p><b>Mudah Pecah:</b> Ya</p>}
+              <p><b>Deskripsi:</b></p>
+              <p>{deskripsiProduk}</p>
+            </div>
           </div>
         </div>
         <div className="detail-produk-right-section">
           <div>
-            <h3>{dataProduk.judul}</h3>
-            <p id='harga-produk'>Rp{dataProduk.harga}</p>
+            <h3 id='nama-produk'>{namaProduk}</h3>
+            <p id='harga-produk'>{rupiahIDLocale.format(hargaProduk)}</p>
           </div>
+          { user.role === "Supplier" &&
           <div>
+            <h5>Variasi</h5>
+            { variasiProduk.length === 0 ? <p>Tidak ada variasi produk.</p> :
+            <div>
+              <ul>
+            {variasiProduk.map(variasi => (
+              <li><b>{variasi.namaVariasi}:</b> {variasi.pilihanVariasi}<br/><b>Stok:</b> {variasi.stok}</li>
+            ))}
+            </ul>
+            </div>
+            }
+          </div>}
+          { user.role === "Mitra" && <div>
             {!loading &&
             <TambahKeKeranjang data={dataProduk} handleSubmit={handleSubmit}/>}
-            
-          </div>
+          </div>}
         </div>
       </div>
     </div>
diff --git a/src/page/DetailProduk/DetailProduk.test.js b/src/page/DetailProduk/DetailProduk.test.js
index c86f7d1f252c8929be3094e831f8fa4ae4cfaa51..29f217c766fcdf3dd0dd0e3d4030110338a50aa3 100644
--- a/src/page/DetailProduk/DetailProduk.test.js
+++ b/src/page/DetailProduk/DetailProduk.test.js
@@ -1,7 +1,7 @@
 import DetailProduk from './DetailProduk';
 import '@testing-library/jest-dom';
 import { Provider } from 'react-redux';
-import { render, fireEvent, waitFor } from '@testing-library/react';
+import { render, screen, fireEvent } from '@testing-library/react';
 import { BrowserRouter, Route } from 'react-router-dom';
 import configureStore from 'redux-mock-store';
 import thunk from 'redux-thunk';
@@ -53,7 +53,7 @@ const produkData = {
         }
     ],
     "jasaPengiriman": [],
-    "fileProduk": []
+    "fileProduk": [{id:1, fileProduk:"https://storage.googleapis.com/walkiddie-django-bucket/produk/kitkat.jfif?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=walkiddie-django-bucket%40my-project-52056-324503.iam.gserviceaccount.com%2F20220524%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20220524T031145Z&X-Goog-Expires=86400&X-Goog-SignedHeaders=host&X-Goog-Signature=d3d19f494608db4cfdac7754df4d7115d0957dbe69ec6546863fd08f8d980c2cce7919764cf9aa17b6f1c20ef08bfb068a0354ab3f9a096031ce346a28ba6c9d3c6eeac6432eeeba7415546b78bee6ae6b604cb6a537a455f82e79c07be28de0071323894df3311f7ae1fada94cc21dec791995e1fcb608b261d001195b0c70a08ca301734a89a610501adab7b3ea0c345404bac87be60dd508ddfe292b333497450df794f0e4a25242287630821cc2461340f338b12271f2095bbe6e2270fd42ff3ebf8fa900cbfdd04686caae30d050de35c5c71610ac0c7bfd9793104fbaf2dcfc102ef26a325e7ca9ecbfd723b89b834ef07e25625a34dc933068fdcc4b2"}]
 };
 
 const listItemData = [
@@ -76,7 +76,7 @@ const config = {
 const mock = new MockAdapter(axios);
 
 describe('<DetailProduk />', () => {
-    it('should redirect if not Mitra', () => {
+    it('should redirect if not Mitra or Supplier', () => {
         let loc;
         const initialState = {
             auth: {
@@ -135,6 +135,118 @@ describe('<DetailProduk />', () => {
         expect(loc.pathname).toBe('/masuk');
     })
 
+    test('fetch data produk success', async () => {
+        const initialState = {
+            auth: {
+                isAuthenticated: true,
+                user: {
+                    role: "Supplier"
+                }
+            }
+        }
+        const store = mockStore(initialState);
+        localStorage.setItem('access', 'token');
+
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).replyOnce(200, produkData);
+        render(
+        <Provider store={store}>
+            <BrowserRouter>
+                <DetailProduk match={mockMatch} />
+            </BrowserRouter>
+        </Provider>);
+
+        await(()=> {
+            expect(screen.getByText(/KitKat/)).toBeInTheDocument();
+            expect(screen.getByText(/13.000/)).toBeInTheDocument();
+            expect(screen.getByText(/Makanan dan Minuman/)).toBeInTheDocument();
+            expect(screen.getByText(/Wafer cokelat enak/)).toBeInTheDocument();
+            expect(screen.getByText(/Unilever/)).toBeInTheDocument();
+        });
+        localStorage.removeItem('access', 'token');
+    });
+
+    test('fetch data produk failed', async () => {
+        const initialState = {
+            auth: {
+                isAuthenticated: true,
+                user: {
+                    role: "Supplier"
+                }
+            }
+        }
+        const store = mockStore(initialState);
+        localStorage.setItem('access', 'token');
+
+        const alert = jest.spyOn(window, 'alert');
+        alert.mockImplementation();
+
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).replyOnce(400);
+        render(
+        <Provider store={store}>
+            <BrowserRouter>
+                <DetailProduk match={mockMatch} />
+            </BrowserRouter>
+        </Provider>);
+
+        await(()=> expect(alert).toHaveBeenCalledTimes(1));
+        alert.mockRestore();
+        localStorage.removeItem('access', 'token');
+    });
+
+    test('fetch data produk without access token', async () => {
+        const initialState = {
+            auth: {
+                isAuthenticated: true,
+                user: {
+                    role: "Mitra"
+                }
+            }
+        }
+        const store = mockStore(initialState);
+        localStorage.removeItem('access', 'token');
+
+        const alert = jest.spyOn(window, 'alert');
+        alert.mockImplementation();
+
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).replyOnce(400);
+        render(
+        <Provider store={store}>
+            <BrowserRouter>
+                <DetailProduk match={mockMatch} />
+            </BrowserRouter>
+        </Provider>);
+
+        await(()=> expect(alert).toHaveBeenCalledTimes(1));
+        alert.mockRestore();
+    });
+
+    test('back button run correctly', async () => {
+        const initialState = {
+            auth: {
+                isAuthenticated: true,
+                user: {
+                    role: "Mitra"
+                }
+            }
+        }
+        const store = mockStore(initialState);
+        localStorage.removeItem('access', 'token');
+
+        const windowsBack = jest.spyOn(window.history, 'back');
+        windowsBack.mockImplementation();
+
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).replyOnce(200);
+        render(
+        <Provider store={store}>
+            <BrowserRouter>
+                <DetailProduk match={mockMatch} />
+            </BrowserRouter>
+        </Provider>);
+
+        fireEvent.click(screen.getByTestId('back-btn'));
+        await(()=> expect(windowsBack).toHaveBeenCalledTimes(1));
+        windowsBack.mockRestore();
+    });
 
     it('should give an alert if add produk without access token', async () => {
         const initialState = {
@@ -151,7 +263,7 @@ describe('<DetailProduk />', () => {
         const alert = jest.spyOn(window, 'alert');
         alert.mockImplementation();
 
-        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1`, config).reply(200, produkData);
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).reply(200, produkData);
 
         const { getByTestId} = render(
             <Provider store={store}>
@@ -161,7 +273,7 @@ describe('<DetailProduk />', () => {
             </Provider>);
 
 
-        await waitFor(() => {
+        await(() => {
             fireEvent.click(getByTestId('add-btn'));
             expect(alert).toHaveBeenCalledTimes(1)
         });
@@ -181,21 +293,21 @@ describe('<DetailProduk />', () => {
         localStorage.setItem('access', 'token');
         const store = mockStore(initialState);
 
-        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1`, config).reply(200, produkData);
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).reply(200, produkData);
         mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/keranjang`, config).reply(200, keranjangData);
         mock.onPost(`${process.env.REACT_APP_BACKEND_API_URL}/api/keranjang/tambah-item`, config).reply(400, []);
 
         const alert = jest.spyOn(window, 'alert');
         alert.mockImplementation();
 
-        const { getByTestId} = render(
+        const { getByTestId } = render(
             <Provider store={store}>
                 <BrowserRouter>
                     <DetailProduk match={mockMatch}/>;
                 </BrowserRouter>
             </Provider>);
 
-        await waitFor(() => {
+        await(() => {
             fireEvent.click(getByTestId('add-btn'));
             expect(alert).toHaveBeenCalledTimes(1)
         });
@@ -211,28 +323,29 @@ describe('<DetailProduk />', () => {
                 }
             }
         }
-        
+
         localStorage.setItem('access', 'token');
         const store = mockStore(initialState);
 
-        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1`, config).reply(200, produkData);
+        mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/produk/1/`, config).reply(200, produkData);
         mock.onGet(`${process.env.REACT_APP_BACKEND_API_URL}/api/keranjang`, config).reply(400, []);
         mock.onPost(`${process.env.REACT_APP_BACKEND_API_URL}/api/keranjang/tambah-item`, config).reply(200, listItemData[0]);
 
         const alert = jest.spyOn(window, 'alert');
         alert.mockImplementation();
 
-        const { getByTestId} = render(
+        const { getByTestId } = render(
             <Provider store={store}>
                 <BrowserRouter>
                     <DetailProduk match={mockMatch}/>;
                 </BrowserRouter>
             </Provider>);
 
-        await waitFor(() => {
+        await(() => {
             fireEvent.click(getByTestId('add-btn'));
             expect(alert).toHaveBeenCalledTimes(1)
         });
         alert.mockRestore();
     }, 20000);
+
 });
\ No newline at end of file