diff --git a/package-lock.json b/package-lock.json index 00504b2161ae1aea71a4cc51a8f3d0bc133946e3..b5bd8a0e3f4452fb2f0c59a689dbe31f26752cef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10911,9 +10911,9 @@ "dev": true }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + "version": "2.25.3", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.25.3.tgz", + "integrity": "sha512-PuYv0PHxZvzc15Sp8ybUCoQ+xpyPWvjOuK72a5ovzp2LI32rJXOiIfyoFoYvG3s6EwwrdkMyWuRiEHSZRLJNdg==" }, "moment-timezone": { "version": "0.5.28", @@ -12716,9 +12716,9 @@ } }, "react-hook-form": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-5.6.1.tgz", - "integrity": "sha512-pqlAiWyZqngdEVUinxPSmhs9k2L/ETsTf8LU7wfwrE1bXJnslRsb4aKlYiL2z0bgGrCuksN8el5bxFbnR1/qEA==" + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-5.7.2.tgz", + "integrity": "sha512-bJvY348vayIvEUmSK7Fvea/NgqbT2racA2IbnJz/aPlQ3GBtaTeDITH6rtCa6y++obZzG6E3Q8VuoXPir7QYUg==" }, "react-is": { "version": "16.13.1", diff --git a/package.json b/package.json index 7fde397842fcc5d19bafbf3ce74a3a84346166ae..afc57f5f9412bc272dae836795888c77bfb7b6b4 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,12 @@ "@reach/router": "^1.3.3", "bootstrap": "^4.4.1", "jquery": "^3.5.0", - "moment": "2.24.0", + "moment": "2.25.3", "moment-timezone": "^0.5.28", "popper.js": "^1.16.1", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-hook-form": "^5.6.1", + "react-hook-form": "^5.7.2", "react-moment": "^0.9.7", "react-number-format": "^4.4.1", "react-promise-tracker": "^2.1.0" diff --git a/src/__test__/Pengaturan.test.js b/src/__test__/Pengaturan.test.js new file mode 100644 index 0000000000000000000000000000000000000000..f0064bf7c2954181f20f3d58c71393552310643d --- /dev/null +++ b/src/__test__/Pengaturan.test.js @@ -0,0 +1,310 @@ +import { act, cleanup, fireEvent, render } from "@testing-library/react"; +import AuthContext from "../utils/contex"; +import React from "react"; +import Pengaturan from "../page/pengaturan/Pengaturan"; +import { waitFor } from "@testing-library/dom"; + +beforeEach(() => { + fetch.resetMocks(); +}); +afterEach(cleanup); + +test("Config update bank-account", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const bankName = getByTestId("bank-name"); + expect(bankName.value).toEqual("BNI"); + const accountName = getByTestId("account-name"); + expect(accountName.value).toEqual("Kak Mpit"); + const accountNumber = getByTestId("account-number"); + expect(accountNumber.value).toEqual("987654321"); + expect(fetch.mock.calls.length).toEqual(3); + await act(async () => { + await fireEvent.input(bankName, { target: { value: "test" } }); + await fireEvent.input(accountName, { target: { value: "testAcount" } }); + await fireEvent.input(accountNumber, { target: { value: "123" } }); + await fireEvent.submit(getByTestId("submit-bank")); + }); + expect(fetch.mock.calls.length).toEqual(4); +}); + +test("Config update bank-account empty", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const bankName = getByTestId("bank-name"); + expect(bankName.value).toEqual("BNI"); + const accountName = getByTestId("account-name"); + expect(accountName.value).toEqual("Kak Mpit"); + const accountNumber = getByTestId("account-number"); + expect(accountNumber.value).toEqual("987654321"); + expect(fetch.mock.calls.length).toEqual(3); + await act(async () => { + await fireEvent.input(bankName, { target: { value: "" } }); + await fireEvent.input(accountName, { target: { value: "" } }); + await fireEvent.input(accountNumber, { target: { value: "" } }); + await fireEvent.submit(getByTestId("submit-bank")); + }); + expect(fetch.mock.calls.length).toEqual(3); +}); + +test("Config update email", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const email = getByTestId("email-admin"); + expect(email.value).toEqual("pilar@gmail.com"); + await act(async () => { + await fireEvent.input(email, { target: { value: "test@gmail.com" } }); + await fireEvent.submit(getByTestId("submit-email")); + }); + expect(fetch.mock.calls.length).toEqual(4); +}); + +test("Config update email empty", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const email = getByTestId("email-admin"); + expect(email.value).toEqual("pilar@gmail.com"); + await act(async () => { + await fireEvent.input(email, { target: { value: "" } }); + await fireEvent.submit(getByTestId("submit-email")); + }); + expect(fetch.mock.calls.length).toEqual(3); +}); + +test("Config update shipping", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const rw = getByTestId("rw"); + expect(rw.value).toEqual("016"); + const kelurahan = getByTestId("kelurahan"); + expect(kelurahan.value).toEqual("Penggilingan"); + const kecamatan = getByTestId("kecamatan"); + expect(kecamatan.value).toEqual("Cakung"); + + const rwCost = getByTestId("rw-cost"); + expect(rwCost.value).toEqual("6000.00"); + const kelurahanCost = getByTestId("kelurahan-cost"); + expect(kelurahanCost.value).toEqual("12000.00"); + const kecamatanCost = getByTestId("kecamatan-cost"); + expect(kecamatanCost.value).toEqual("15000.00"); + expect(fetch.mock.calls.length).toEqual(3); + await act(async () => { + await fireEvent.input(rw, { target: { value: "001" } }); + await fireEvent.input(kelurahan, { target: { value: "ada" } }); + await fireEvent.input(kecamatan, { target: { value: "deh" } }); + await fireEvent.input(rwCost, { target: { value: "5000" } }); + await fireEvent.input(kelurahanCost, { target: { value: "10000" } }); + await fireEvent.input(kecamatanCost, { target: { value: "12000" } }); + await fireEvent.submit(getByTestId("submit-shipping")); + }); + expect(fetch.mock.calls.length).toEqual(4); +}); + +test("Config update shipping empty", async () => { + fetch + .once( + JSON.stringify({ + bank_name: "BNI", + account_number: "987654321", + account_owner: "Kak Mpit", + }) + ) + .once( + JSON.stringify({ + email: "pilar@gmail.com", + }) + ) + .once( + JSON.stringify({ + hamlet: "016", + urban_village: "Penggilingan", + sub_district: "Cakung", + same_hamlet_costs: "6000.00", + same_urban_village_different_hamlet_costs: "12000.00", + same_sub_district_different_urban_village_costs: "15000.00", + }) + ) + .once(JSON.stringify({}), { statusCode: 200 }); + const { getByTestId } = render( + <AuthContext.Provider value={{ profile: { token: "BEBAS" } }}> + <Pengaturan /> + </AuthContext.Provider> + ); + const waitConfig = getByTestId("waiting-config"); + expect(waitConfig.textContent).toContain("Fetching data.."); + await waitFor(() => getByTestId("form-config")); + const rw = getByTestId("rw"); + expect(rw.value).toEqual("016"); + const kelurahan = getByTestId("kelurahan"); + expect(kelurahan.value).toEqual("Penggilingan"); + const kecamatan = getByTestId("kecamatan"); + expect(kecamatan.value).toEqual("Cakung"); + + const rwCost = getByTestId("rw-cost"); + expect(rwCost.value).toEqual("6000.00"); + const kelurahanCost = getByTestId("kelurahan-cost"); + expect(kelurahanCost.value).toEqual("12000.00"); + const kecamatanCost = getByTestId("kecamatan-cost"); + expect(kecamatanCost.value).toEqual("15000.00"); + expect(fetch.mock.calls.length).toEqual(3); + await act(async () => { + await fireEvent.input(rw, { target: { value: "" } }); + await fireEvent.input(kelurahan, { target: { value: "" } }); + await fireEvent.input(kecamatan, { target: { value: "" } }); + await fireEvent.input(rwCost, { target: { value: "" } }); + await fireEvent.input(kelurahanCost, { target: { value: "" } }); + await fireEvent.input(kecamatanCost, { target: { value: "" } }); + await fireEvent.submit(getByTestId("submit-shipping")); + }); + expect(fetch.mock.calls.length).toEqual(3); +}); diff --git a/src/__test__/program/EditProgram.test.js b/src/__test__/program/EditProgram.test.js index dadeb2f05db897bd5de7301e6893c6a6e7ae63fb..65212720b99c59ba3f5325c2ccde40e22c1181d5 100644 --- a/src/__test__/program/EditProgram.test.js +++ b/src/__test__/program/EditProgram.test.js @@ -86,4 +86,4 @@ test("Test edit program renders error", async () => { const produk = getByTestId("edit-program"); expect(produk.textContent).toContain("Error !, Data tidak dapat disimpan"); expect(fetch.mock.calls.length).toEqual(2); -}); \ No newline at end of file +}); diff --git a/src/component/Sidebar.jsx b/src/component/Sidebar.jsx index fd15a24d095b4ff74dd9b0f9e12a81c4acf252b4..d17a9712c3b4d8b51da992eff43bf5a3527f529b 100644 --- a/src/component/Sidebar.jsx +++ b/src/component/Sidebar.jsx @@ -54,6 +54,7 @@ const Sidebar = () => { <LinkSidebar to="/program">PROGRAM</LinkSidebar> <LinkSidebar to="/donasi">DONASI</LinkSidebar> <LinkSidebar to="/pengguna">PENGGUNA</LinkSidebar> + <LinkSidebar to="/pengaturan">PENGATURAN</LinkSidebar> <Center css={css` width: 100%; diff --git a/src/page/pengaturan/Pengaturan.jsx b/src/page/pengaturan/Pengaturan.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d0d6f81da7f5f51a049159fadce79117de34f5e0 --- /dev/null +++ b/src/page/pengaturan/Pengaturan.jsx @@ -0,0 +1,38 @@ +import React from "react"; +import useFetchSingleData from "../../utils/useFetchSingleData"; +import PengaturanForm from "./PengaturanForm"; +import { css } from "@emotion/core"; +const Pengaturan = () => { + const url = `${process.env.REACT_APP_BASE_URL}`; + const [bank, errorBank] = useFetchSingleData(`${url}/configs/bank-account/`); + const [email, errorContact] = useFetchSingleData( + `${url}/configs/help-contact/` + ); + const [shipping, errorShipping] = useFetchSingleData( + `${url}/configs/shipment/` + ); + if ( + Object.keys(bank).length === 0 || + Object.keys(email).length === 0 || + Object.keys(shipping).length === 0 || + errorBank || + errorContact || + errorShipping + ) + return ( + <div + data-testid="waiting-config" + css={css` + display: flex; + margin: 2rem 3rem 3rem 3rem; + flex-direction: column; + font-size: 20px; + `} + > + Fetching data.. + </div> + ); + return <PengaturanForm {...{ bank, email, shipping }} />; +}; + +export default Pengaturan; diff --git a/src/page/pengaturan/PengaturanForm.jsx b/src/page/pengaturan/PengaturanForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..3403dd62ac3043d1579d0015937bec085e51608c --- /dev/null +++ b/src/page/pengaturan/PengaturanForm.jsx @@ -0,0 +1,286 @@ +import React from "react"; +import { useForm } from "react-hook-form"; +import { css } from "@emotion/core"; +import { + ErrorDiv, + InputForm, + LabelInput, + RowInput, +} from "../../component/html/html"; +import Button from "@material-ui/core/Button"; +import SaveIcon from "@material-ui/icons/Save"; +import useSendData from "../../utils/useSendData"; + +const PengaturanForm = ({ bank, email, shipping }) => { + const { + register: registerBank, + errors: errorFormBank, + handleSubmit: handleBank, + } = useForm({ + defaultValues: { ...bank }, + }); + const { + register: registerEmail, + errors: errorFormEmail, + handleSubmit: handleEmail, + } = useForm({ + defaultValues: { ...email }, + }); + const { + register: registerShipping, + errors: errorFormShipping, + handleSubmit: handleShipping, + } = useForm({ + defaultValues: { ...shipping }, + }); + const url = `${process.env.REACT_APP_BASE_URL}`; + const conf = { + method: "PUT", + header: { + Accept: "application/json", + "Content-Type": "application/json", + }, + }; + const [sendBank, errorBank] = useSendData({ + url: `${url}/configs/bank-account/`, + ...conf, + }); + const [sendEmail, errorEmail] = useSendData({ + url: `${url}/configs/help-contact/`, + ...conf, + }); + const [sendShipping, errorShipping] = useSendData({ + url: `${url}/configs/shipment/`, + ...conf, + }); + + const submitShipping = (data) => { + sendShipping(JSON.stringify(data)); + }; + + const submitBank = (data) => { + sendBank(JSON.stringify({ ...data })); + }; + const submitEmail = (data) => { + sendEmail(JSON.stringify({ ...data })); + }; + return ( + <div + data-testid="form-config" + css={css` + display: flex; + flex-direction: column; + margin: 2rem 3rem 3rem 3rem; + `} + > + <form + css={css` + display: flex; + flex-direction: column; + `} + onSubmit={handleBank(submitBank)} + > + <h4>Akun bank</h4> + {errorBank && <ErrorDiv>Error simpan konfigurasi bank</ErrorDiv>} + <RowInput> + <LabelInput htmlFor="name">Nama bank: </LabelInput> + <InputForm + data-testid="bank-name" + name="bank_name" + ref={registerBank({ required: true })} + /> + {errorFormBank.bank_name && ( + <ErrorDiv>Nama bank tidak boleh kosong</ErrorDiv> + )} + </RowInput> + + <RowInput> + <LabelInput htmlFor="name">Nama pemilik rekening: </LabelInput> + <InputForm + data-testid="account-name" + name="account_owner" + ref={registerBank({ required: true })} + /> + {errorFormBank.account_owner && ( + <ErrorDiv>Nama pemilik rekening tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <RowInput> + <LabelInput htmlFor="name">Nomor rekening: </LabelInput> + <InputForm + data-testid="account-number" + name="account_number" + type="number" + ref={registerBank({ required: true })} + /> + {errorFormBank.account_number && ( + <ErrorDiv>Nomor rekening tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <div + css={css` + align-self: flex-end; + display: flex; + `} + > + <Button + data-testid="submit-bank" + variant="contained" + color="primary" + size="large" + startIcon={<SaveIcon />} + type="submit" + > + Save + </Button> + </div> + </form> + + <form + css={css` + display: flex; + flex-direction: column; + `} + onSubmit={handleEmail(submitEmail)} + > + <h4>Kontak admin</h4> + {errorEmail && <ErrorDiv>Error simpan konfigurasi kontak</ErrorDiv>} + <RowInput> + <LabelInput htmlFor="name">Email admin: </LabelInput> + <InputForm + data-testid="email-admin" + name="email" + type="email" + ref={registerEmail({ required: true, pattern: /^\S+@\S+$/i })} + /> + {errorFormEmail.email && ( + <ErrorDiv>Mohon periksa apakah email sudah benar</ErrorDiv> + )} + </RowInput> + <div + css={css` + align-self: flex-end; + display: flex; + `} + > + <Button + data-testid="submit-email" + variant="contained" + color="primary" + size="large" + startIcon={<SaveIcon />} + type="submit" + > + Save + </Button> + </div> + </form> + <form + css={css` + display: flex; + flex-direction: column; + `} + onSubmit={handleShipping(submitShipping)} + > + <h4>Pengiriman</h4> + {errorShipping && ( + <ErrorDiv>Error simpan konfigurasi pengiriman</ErrorDiv> + )} + <RowInput> + <LabelInput htmlFor="name">RW: </LabelInput> + <InputForm + data-testid="rw" + name="hamlet" + type="number" + ref={registerShipping({ + required: true, + maxLength: 3, + minLength: 3, + })} + /> + {errorFormShipping.hamlet && ( + <ErrorDiv>Mohon cek apakah rw sudah benar, butuh 3 angka</ErrorDiv> + )} + </RowInput> + + <RowInput> + <LabelInput htmlFor="name">Kelurahan: </LabelInput> + <InputForm + data-testid="kelurahan" + name="urban_village" + ref={registerShipping({ required: true })} + /> + {errorFormShipping.urban_village && ( + <ErrorDiv>Kelurahan tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <RowInput> + <LabelInput htmlFor="name">Kecamatan: </LabelInput> + <InputForm + data-testid="kecamatan" + name="sub_district" + ref={registerShipping({ required: true })} + /> + {errorFormShipping.sub_district && ( + <ErrorDiv>Kecamatan tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <RowInput> + <LabelInput htmlFor="name">Biaya satu RW: </LabelInput> + <InputForm + data-testid="rw-cost" + name="same_hamlet_costs" + type="number" + ref={registerShipping({ required: true })} + /> + {errorFormShipping.same_hamlet_costs && ( + <ErrorDiv>Biaya satu RW tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <RowInput> + <LabelInput htmlFor="name">Biaya satu kelurahan: </LabelInput> + <InputForm + data-testid="kelurahan-cost" + name="same_urban_village_different_hamlet_costs" + type="number" + ref={registerShipping({ required: true })} + /> + {errorFormShipping.same_urban_village_different_hamlet_costs && ( + <ErrorDiv>Biaya satu kelurahan tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <RowInput> + <LabelInput htmlFor="name">Biaya satu kecamatan: </LabelInput> + <InputForm + data-testid="kecamatan-cost" + name="same_sub_district_different_urban_village_costs" + type="number" + ref={registerShipping({ required: true })} + /> + {errorFormShipping.same_sub_district_different_urban_village_costs && ( + <ErrorDiv>Biaya satu kecamatan tidak boleh kosong</ErrorDiv> + )} + </RowInput> + <div + css={css` + align-self: flex-end; + display: flex; + `} + > + <Button + data-testid="submit-shipping" + variant="contained" + color="primary" + size="large" + startIcon={<SaveIcon />} + type="submit" + > + Save + </Button> + </div> + </form> + </div> + ); +}; + +export default PengaturanForm; diff --git a/src/page/program/FormProgram.jsx b/src/page/program/FormProgram.jsx index 15ab7d0305db767f6849c4fceb6490e89b8305ba..e9b61c7b2d92dd028747b2aea9a95536d5415084 100644 --- a/src/page/program/FormProgram.jsx +++ b/src/page/program/FormProgram.jsx @@ -104,7 +104,12 @@ const FormProgram = ({ onSubmit, initialData = null }) => { ) : null} <RowInput> <LabelInput htmlFor="poster_image">Gambar Poster </LabelInput> - <InputForm type="file" name="poster_image" data-testid="photo-program" ref={register} /> + <InputForm + type="file" + name="poster_image" + data-testid="photo-program" + ref={register} + /> </RowInput> <RowInput> <InputSubmitForm type="submit" data-testid="submit-program" /> diff --git a/src/page/transaksi/ListTransaksi.jsx b/src/page/transaksi/ListTransaksi.jsx index 6edce71af0899a2d515fad1adf4478338d07fd74..2770515562108233fa4fee2e49219d4a05ab05f5 100644 --- a/src/page/transaksi/ListTransaksi.jsx +++ b/src/page/transaksi/ListTransaksi.jsx @@ -55,15 +55,6 @@ const ListTransaksi = () => { > KELOLA TRANSAKSI </div> - <div - css={css` - width: 100%; - justify-content: space-between; - display: flex; - flex-direction: row; - margin-top: 1rem; - `} - ></div> <TableComponent {...data} /> </div> ); diff --git a/src/routes.jsx b/src/routes.jsx index b1c0e78b33beba1b3d17ba4545ed4990ddfaa12f..cafb2e55a60078f5419ba8520db9d4134b96265c 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -28,6 +28,7 @@ import DetailTransaksi from "./page/transaksi/DetailTransaksi"; import ListDonasi from "./page/donasi/ListDonasi"; import DetailDonasi from "./page/donasi/DetailDonasi"; +import Pengaturan from "./page/pengaturan/Pengaturan"; const Placeholder = ({ children }) => children; @@ -80,6 +81,10 @@ const Routes = () => { <ProtectedRoute path=":idDonasi" component={DetailDonasi} /> </Placeholder> + <Placeholder path="pengaturan"> + <ProtectedRoute path="/" component={Pengaturan} /> + </Placeholder> + <UnauthenticatedRoute path="/" component={Login} /> </Router> );