diff --git a/src/__test__/program/DetailProgram.test.js b/src/__test__/program/DetailProgram.test.js
index 8c91a1a82c03aca93e02b08cf0843d893266ec1e..83be0662809ff5a5f2f05b1d7242cde5451730ae 100644
--- a/src/__test__/program/DetailProgram.test.js
+++ b/src/__test__/program/DetailProgram.test.js
@@ -33,7 +33,7 @@ test("Test detail program renders", async () => {
   await waitFor(() => getByTestId("program"));
   const program = getByTestId("program");
   expect(program.textContent).toContain("Eddrick");
-  expect(fetch.mock.calls.length).toEqual(1);
+  expect(fetch.mock.calls.length).toEqual(2);
 });
 
 test("Test mock detail program return error", async () => {
@@ -72,7 +72,7 @@ test("Test detail program delete", async () => {
   await waitFor(() => getByTestId("page"));
   const produk = getByTestId("page");
   expect(produk.textContent).toContain("dummy 2");
-  expect(fetch.mock.calls.length).toEqual(1);
+  expect(fetch.mock.calls.length).toEqual(2);
   const btnDeleteModal = getByTestId("button-delete-program-modal");
   await act(async () => {
     await fireEvent.click(btnDeleteModal);
@@ -81,7 +81,7 @@ test("Test detail program delete", async () => {
   await act(async () => {
     await fireEvent.click(btnDelete);
   });
-  expect(fetch.mock.calls.length).toEqual(2);
+  expect(fetch.mock.calls.length).toEqual(3);
 });
 
 test("Test detail produk delete error", async () => {
@@ -110,7 +110,7 @@ test("Test detail produk delete error", async () => {
   await waitFor(() => getByTestId("page"));
   const produk = getByTestId("page");
   expect(produk.textContent).toContain("Eddrick");
-  expect(fetch.mock.calls.length).toEqual(1);
+  expect(fetch.mock.calls.length).toEqual(2);
   const btnDeleteModal = getByTestId("button-delete-program-modal");
   await act(async () => {
     await fireEvent.click(btnDeleteModal);
@@ -119,8 +119,68 @@ test("Test detail produk delete error", async () => {
   await act(async () => {
     await fireEvent.click(btnDelete);
   });
-  expect(fetch.mock.calls.length).toEqual(2);
+  expect(fetch.mock.calls.length).toEqual(3);
   expect(produk.textContent).toContain(
     "Tidak dapat menghapus program, mohon periksa apakah ada program ini."
   );
 });
+test("Test progress program renders", async () => {
+  fetch
+  .once(
+    JSON.stringify({
+      id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
+      code: "3MXZ9T", 
+      name: "dummy 2",
+      description: "yeyyy",
+      start_date_time: null,
+      end_date_time: null,
+      location: "Depok",
+      speaker: "Eddrick",
+      poster_image:
+        "https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
+    })
+    )
+    .once(
+      JSON.stringify([{
+        description: "ada progress guys",
+        date: "2020-04-28",
+        image:
+        "https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
+      }])
+  )
+  .once(JSON.stringify({}), { statusCode: 200 });
+  ;
+
+  const { getByTestId } = render(
+    <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
+      <DetailProgram />
+    </AuthContext.Provider>
+  );
+  await waitFor(() => getByTestId("program"));
+  const program = getByTestId("program");
+  expect(program.textContent).toContain("Eddrick");
+
+  await waitFor(() => getByTestId("progress-date"));
+  const progressDate = getByTestId("progress-date");
+  expect(progressDate.textContent).toContain("2020-04-28");
+  await act(async () => {
+    await fireEvent.click(getByTestId("button-see-proof"));
+  });
+  const close = getByTestId("button-close-proof");
+  expect(close.textContent).toContain("Close");
+  await act(async () => {
+    await fireEvent.click(close);
+  });  
+  expect(fetch.mock.calls.length).toEqual(2);
+});
+test("Test mock progress program fail", async () => {
+  fetch.mockReject(new Error("error message"));
+  const { getByTestId } = render(
+    <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
+      <DetailProgram />
+    </AuthContext.Provider>
+  );
+  await waitFor(() => getByTestId("progress"));
+  const progress = getByTestId("progress");
+  expect(progress.textContent).toContain("Error, progress not found");
+});
diff --git a/src/__test__/program/EditProgram.test.js b/src/__test__/program/EditProgram.test.js
index dbd396b5732d99102c142fc3aef76a47f961168b..a4a68e36eb422cd311a7b1d9fc0274408eaaae1d 100644
--- a/src/__test__/program/EditProgram.test.js
+++ b/src/__test__/program/EditProgram.test.js
@@ -2,7 +2,8 @@ import { act, cleanup, fireEvent, render } from "@testing-library/react";
 import AuthContext from "../../utils/contex";
 import { waitFor } from "@testing-library/dom";
 import React from "react";
-import EditProduk from "../../page/program/EditProgram";
+import EditProgram from "../../page/program/EditProgram";
+import FormProgress from "../../page/program/FormProgress";
 
 beforeEach(() => {
   fetch.resetMocks();
@@ -30,7 +31,7 @@ test("Test edit program renders", async () => {
 
   const { getByTestId } = render(
     <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
-      <EditProduk />
+      <EditProgram />
     </AuthContext.Provider>
   );
   const waitProgram = getByTestId("waiting-edit-program");
@@ -44,8 +45,7 @@ test("Test edit program renders", async () => {
   await act(async () => {
     await fireEvent.submit(getByTestId("submit-program"));
   });
-
-  expect(fetch.mock.calls.length).toEqual(2);
+  expect(fetch.mock.calls.length).toEqual(3);
 });
 
 test("Test edit program renders error", async () => {
@@ -72,7 +72,7 @@ test("Test edit program renders error", async () => {
 
   const { getByTestId } = render(
     <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
-      <EditProduk />
+      <EditProgram />
     </AuthContext.Provider>
   );
   const waitProgram = getByTestId("waiting-edit-program");
@@ -90,8 +90,99 @@ test("Test edit program renders error", async () => {
   await act(async () => {
     await fireEvent.submit(getByTestId("submit-program"));
   });
+  expect(fetch.mock.calls.length).toEqual(3);
+});
 
-  const produk = getByTestId("edit-program");
-  expect(produk.textContent).toContain("Error !, Data tidak dapat disimpan");
+test("Test progress program modal", async () => {
+  fetch.once(
+    JSON.stringify({
+      id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
+      code: "3MXZ9T",
+      name: "dummy 2",
+      description: "yeyyy",
+      start_date_time: null,
+      end_date_time: null,
+      location: "Depok",
+      speaker: "Eddrick",
+      open_donation: true,
+      program_minutes: null,
+      poster_image:
+        "https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
+      link: null,
+      total_donation_amount: "2263691.00",
+    })
+  );
+
+  const { getByTestId } = render(
+    <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
+      <EditProgram />
+    </AuthContext.Provider>
+  );
+  const waitProgram = getByTestId("waiting-edit-program");
+  expect(waitProgram.textContent).toContain("Fetching data..");
+  await waitFor(() => getByTestId("edit-program"));
+  const name_program = getByTestId("name-program-input");
+  expect(name_program.value).toEqual("dummy 2");
+  
+  const modalButton = getByTestId("button-progress")
+  await act(async () => {
+    await fireEvent.click(modalButton);
+  });
+  const modal = getByTestId("modal-progress");
+  expect(modal.textContent).toContain("Tambah Progress");
+  expect(modal.textContent).toContain("Tanggal");
+  expect(modal.textContent).toContain("Berita");
+  expect(modal.textContent).toContain("Gambar");
+
+  const close = getByTestId("close-button");
+  await act(async () => {
+    await fireEvent.click(close);
+  });
   expect(fetch.mock.calls.length).toEqual(2);
 });
+
+test("Test progress program modal submit", async () => {
+  fetch.once(
+    JSON.stringify({
+      id: "6d7462da-6a85-4e2b-9930-69567090a5d5",
+      code: "3MXZ9T",
+      name: "dummy 2",
+      description: "yeyyy",
+      start_date_time: null,
+      end_date_time: null,
+      location: "Depok",
+      speaker: "Eddrick",
+      open_donation: true,
+      program_minutes: null,
+      poster_image:
+        "https://industripilar-api-staging.s3.amazonaws.com/media/uploads/programs/1_txtcYocQEGtOFN33ZCTDbw.png",
+      link: null,
+      total_donation_amount: "2263691.00",
+    })
+  );
+
+  const { getByTestId } = render(
+    <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
+      <FormProgress />
+    </AuthContext.Provider>
+  );
+  const tanggal_progress = getByTestId("tanggal-progress");
+  await act(async () => {
+    await fireEvent.input(tanggal_progress, { target: { value: "2020-05-12T19:30" } });
+  });
+  const berita_progress = getByTestId("berita-progress");
+  await act(async () => {
+    await fireEvent.input(berita_progress, { target: { value: "ini berita" } });
+  });
+  const gambar_progress = getByTestId("gambar-progress");
+  await act(async () => {
+    await fireEvent.input(gambar_progress, {
+      target: { value: "" },
+    });
+  });
+  await act(async () => {
+    await fireEvent.submit(getByTestId("save-button"));
+  });
+  expect(fetch.mock.calls.length).toEqual(0);
+});
+
diff --git a/src/page/donasi-barang/DetailDonasiBarang.jsx b/src/page/donasi-barang/DetailDonasiBarang.jsx
index d2c5ed3702a8e1e443252266f749aab7b0231558..bf485aba720e8381239f2c8945c1a32ee6302afb 100644
--- a/src/page/donasi-barang/DetailDonasiBarang.jsx
+++ b/src/page/donasi-barang/DetailDonasiBarang.jsx
@@ -150,7 +150,7 @@ const DetailDonasiBarang = ({ idDonasi }) => {
         >
           <div>
             {donation.delivery_address === null ? (
-              <div>Diantar ke masjid Al-Jabar</div>
+              <div>Diantar ke Masjid Al-Jabar</div>
             ) : (
             <div>Dijemput di {donation.delivery_address}</div>
             )}
diff --git a/src/page/program/DetailProgram.jsx b/src/page/program/DetailProgram.jsx
index 890d0c899f6134beded0b61b73c29e75ec1536a7..b6a291601db22af3facaf4a63b9ba5e155583e14 100644
--- a/src/page/program/DetailProgram.jsx
+++ b/src/page/program/DetailProgram.jsx
@@ -23,12 +23,27 @@ import {
 
 const DetailProgram = ({ idProgram }) => {
   const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`;
+  const progressUrl = url+"progress";
   const [program, error] = useFetchSingleData(url);
+  const [progress, progressError] = useFetchSingleData(progressUrl);
   const [deleteProgram, errorDelete] = useDelete(url);
   const [openModal, setOpenModal] = useState(false);
   const handleClose = () => setOpenModal(false);
+  const [dialogOpen, setDialogOpen] = useState(false);
+  let image;
+
+  const handleClickOpen = (img) => {
+    image = img;
+    setDialogOpen(true);
+  };
+
+  const handleClickClose = () => {
+    setDialogOpen(false);
+  };
   const start_date_time = new Date(program.start_date_time).toLocaleString();
   const end_date_time = new Date(program.end_date_time).toLocaleString();
+ 
+  
   return (
     <div
       data-testid="page"
@@ -352,11 +367,90 @@ const DetailProgram = ({ idProgram }) => {
                   </div>
                 </div>
               </div>
+              <div
+                css={css`
+                  margin-top: 1rem;
+                  margin-bottom: 1rem;
+                `}
+              >
+                <div>
+                  <div
+                    css={css`
+                      margin-top: 1rem;
+                    `}
+                  >
+                  <div
+                    css={css`
+                      margin-top: 2rem;
+                      margin-bottom: 1rem;
+                      font-style: normal;
+                      font-weight: normal;
+                      font-size: 24px;
+                      line-height: 22px;
+                    `}
+                    data-testid="progress"
+                  >
+                    Progress Program
+                    {progressError && <ErrorDiv>Error, progress not found.</ErrorDiv>}
+                    {progress.length > 0 ?
+                    <div>
+                      {progress.map ( p => 
+                        <div key={p.id} css={css `margin-top: 1rem; font-size: 18px`}>
+                          <p data-testid="progress-date">{p.date}</p>
+                          <p>{p.description}</p>
+                          {p.image !== null && 
+                            <Button
+                              onClick={() => handleClickOpen(p.image)}
+                              variant="contained"
+                              color="primary"
+                              size="medium"
+                              data-testid="button-see-proof"
+                            >
+                              Gambar
+                            </Button>
+                          }
+                        </div>
+                      )}
+                    </div>
+                    :<div css={css `margin-top: 1rem ; font-size: 18px`}>Belum ada progress</div>
+                    }
+                  </div>
+              </div>
             </div>
           </div>
         </div>
       </div>
     </div>
+    </div>
+    <Dialog
+        maxWidth="xl"
+        open={dialogOpen}
+        onClose={handleClickClose}
+        aria-labelledby="max-width-dialog-title"
+      >
+        <DialogTitle id="max-width-dialog-title">Bukti Transfer</DialogTitle>
+        <DialogContent>
+          <img
+            css={css`
+              height: 80vh;
+              width: 80vw;
+              object-fit: contain;
+            `}
+            src={image}
+            alt="Foto Progress"
+          />
+        </DialogContent>
+        <DialogActions>
+          <Button
+            data-testid="button-close-proof"
+            onClick={handleClickClose}
+            color="primary"
+          >
+            Close
+          </Button>
+        </DialogActions>
+      </Dialog>
+    </div>
   );
 };
 
diff --git a/src/page/program/EditProgram.jsx b/src/page/program/EditProgram.jsx
index 6a36903e524b13243632701cf0924ba32eab10bc..39315dd291510e9da33c6445fe3463c81f47b31e 100644
--- a/src/page/program/EditProgram.jsx
+++ b/src/page/program/EditProgram.jsx
@@ -1,20 +1,44 @@
-import React from "react";
+import React, {useState} from "react";
 import useFetchSingleData from "../../utils/useFetchSingleData";
 import { css } from "@emotion/core";
-import { ErrorDiv } from "../../component/html/html";
+import { ErrorDiv, RowInput } from "../../component/html/html";
 import FormProgram from "./FormProgram";
 import ArrowBackIcon from "@material-ui/icons/ArrowBack";
 import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline";
 import { navigate } from "@reach/router";
 import useSendData from "../../utils/useSendData";
+import Button from "@material-ui/core/Button";
+import Dialog from "@material-ui/core/Dialog";
+import DialogActions from "@material-ui/core/DialogActions";
+import DialogContent from "@material-ui/core/DialogContent";
+import DialogTitle from "@material-ui/core/DialogTitle";
+import FormProgress from "./FormProgress";
 
 const EditProgram = ({ idProgram }) => {
   const url = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/`;
   const [initialData, errorState] = useFetchSingleData(url);
   const [send, error] = useSendData({ url, method: "PATCH", redirect: -1 });
+  const [dialogOpen, setDialogOpen] = useState(false);
   const onSubmit = (data) => {
     send(data);
   };
+
+  const urlProgress = `${process.env.REACT_APP_BASE_URL}/programs/${idProgram}/progress`;
+  const [initialProgressData] = useFetchSingleData(urlProgress);
+  const [sendProgress] = useSendData({
+    url: urlProgress,
+    method: "POST",
+    redirect: "/program",
+  });
+  const onSubmitProgress = (data) => {
+      const formData = new FormData();
+      formData.append( "date", data["tanggal_progress"]);
+      formData.append("description", data["berita_progress"]);
+      if (data["gambar_progress"].length !== 0)
+        formData.append("image", data["gambar_progress"][0]);
+      sendProgress(formData);
+  };
+
   if (errorState || Object.keys(initialData).length === 0)
     return (
       <div
@@ -29,6 +53,13 @@ const EditProgram = ({ idProgram }) => {
         Fetching data..
       </div>
     );
+    const handleClickOpen = () => {
+      setDialogOpen(true);
+    };
+  
+    const handleClose = () => {
+      setDialogOpen(false);
+    };
   return (
     <div
       data-testid="edit-program"
@@ -84,6 +115,51 @@ const EditProgram = ({ idProgram }) => {
         </div>
       </div>
       <FormProgram {...{ onSubmit, initialData }} />
+      <RowInput>
+        <Button
+          onClick={handleClickOpen}
+          variant="contained"
+          size="medium"
+          data-testid="button-progress"
+          css={css`
+            text-transform: none;
+            width: 100%;
+            background: #FFFFFF;
+            border: 1px solid #3c8dbc;
+            box-sizing: border-box;
+            border-radius: 50px;
+            font-size: 14px;
+            line-height: 17px;
+            text-align: center;
+            letter-spacing: 0.2em;
+            color: #3c8dbc;
+            height: 2.3rem;
+          `}
+          >
+          Tambah Progress
+        </Button>
+      </RowInput>
+      <Dialog
+        maxWidth="xl"
+        open={dialogOpen}
+        onClose={handleClose}
+        aria-labelledby="max-width-dialog-title"
+        data-testid="modal-progress"
+      >
+        <DialogTitle id="max-width-dialog-title">Tambah Progress</DialogTitle>
+        <DialogContent>
+          <FormProgress {...{ onSubmitProgress, initialProgressData }} />
+        </DialogContent>
+        <DialogActions>
+          <Button
+            data-testid="close-button"
+            onClick={handleClose}
+            color="primary"
+          >
+            Close
+          </Button>
+        </DialogActions>
+      </Dialog>
     </div>
   );
 };
diff --git a/src/page/program/FormProgram.jsx b/src/page/program/FormProgram.jsx
index d37d13af9064f016ebf91dcca99ecf37091a5d45..a36f1cb1f6232af983d862c0eda36fa60eaf5149 100644
--- a/src/page/program/FormProgram.jsx
+++ b/src/page/program/FormProgram.jsx
@@ -226,4 +226,4 @@ const FormProgram = ({ onSubmit, initialData = null }) => {
   );
 };
 
-export default FormProgram;
+export default FormProgram;
\ No newline at end of file
diff --git a/src/page/program/FormProgress.jsx b/src/page/program/FormProgress.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..75bfc588f7fa2fbbad8f628f63a267d8c1a67f69
--- /dev/null
+++ b/src/page/program/FormProgress.jsx
@@ -0,0 +1,70 @@
+import React from "react";
+import {
+    ErrorDiv,
+    RowInput,
+    InputForm,
+    LabelInput,
+    InputSubmitForm,
+  } from "../../component/html/html";
+import { useForm } from "react-hook-form";
+import { css } from "@emotion/core";
+
+function FormProgress ({ onSubmitProgress, initialProgressData = null }) {
+
+    const {register, handleSubmit, errors} = useForm({
+        defaultValues: initialProgressData !== null
+        ? {
+            tanggal_progress: initialProgressData["tanggal_progress"],
+            berita_progress: initialProgressData["berita_progress"],
+            gambar_progress: initialProgressData["gambar_progress"]
+        } : {}
+      });
+
+    return (
+        <form onSubmit={handleSubmit(onSubmitProgress)} css={css`
+        display: flex;
+        flex-direction: column;
+        `}>
+            <RowInput>
+                <LabelInput htmlFor="tanggal_progress">
+                    Tanggal
+                </LabelInput>
+                <InputForm
+                    data-testid="tanggal-progress"
+                    type="date"
+                    name="tanggal_progress"
+                    ref={register({ required: true })}
+                />
+                {errors.tanggal_progress && <ErrorDiv>Mohon isi tanggal progress</ErrorDiv>}
+            </RowInput>
+            
+            <RowInput>
+                <LabelInput htmlFor="berita_progress">
+                    Berita 
+                </LabelInput>
+                    <InputForm
+                            data-testid="berita-progress"
+                            name="berita_progress"
+                            ref={register({ required: true })}
+                        />
+                        {errors.berita_progress && <ErrorDiv>Mohon isi berita progress</ErrorDiv>}
+            </RowInput>
+
+            <RowInput>
+                <LabelInput htmlFor="gambar_progress">
+                    Gambar 
+                </LabelInput>
+                    <InputForm
+                            data-testid="gambar-progress"
+                            type="file"
+                            name="gambar_progress"
+                            ref={register({ required: false})}
+                        />
+                    </RowInput>
+            <RowInput data-testid="save-button">
+                <InputSubmitForm  type="submit" value="SIMPAN"/>
+            </RowInput>
+        </form>
+    )
+}
+export default FormProgress;
\ No newline at end of file