Fakultas Ilmu Komputer UI

Commit 90e29e27 authored by Fadhil Pradipta Widyanto's avatar Fadhil Pradipta Widyanto
Browse files

Merge branch 'PBI-14' into 'dev'

PBI-14

See merge request !32
parents 1c5eeae2 f67ef469
Pipeline #81551 passed with stages
in 3 minutes and 54 seconds
This diff is collapsed.
......@@ -94,4 +94,31 @@ test("Test tanggal form required", async () => {
expect(formBatch.textContent).toContain(
"Tanggal berakhir tidak boleh kosong"
);
});
\ No newline at end of file
});
test("Test tanggal mulai lebih dari tanggal akhir", async () => {
const wrapper = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<TambahBatch />
</AuthContext.Provider>
);
const startDateMoment = moment("Fri Apr 17 2021 00:00:00 GMT+0700")
const endDateMoment = moment("Sat Apr 16 2021 00:00:00 GMT+0700")
const name_batch = wrapper.getByTestId("name-batch-input");
const start_date = wrapper.getByTitle("start-date-title");
const end_date = wrapper.getByTitle("end-date-title");
await act(async () => {
await fireEvent.input(name_batch, { target: { value: "test" } });
});
await act(async () => {
await fireEvent.input(start_date, { target: { value: startDateMoment } });
});
await act(async () => {
await fireEvent.input(end_date, { target: { value: endDateMoment } });
});
await act(async () => {
await fireEvent.submit(wrapper.getByTestId("submit-batch"));
});
const batch = wrapper.getByTestId("tambah-batch");
expect(batch.textContent).toContain("Tanggal mulai tidak boleh melebihi tanggal akhir!");
})
\ No newline at end of file
......@@ -144,7 +144,7 @@ test("Test edit produk renders", async () => {
await act(async () => {
await fireEvent.submit(getByTestId("submit-produk"));
});
expect(fetch.mock.calls.length).toEqual(5);
expect(fetch.mock.calls.length).toEqual(4);
});
test("Test edit produk renders error", async () => {
......@@ -160,6 +160,7 @@ test("Test edit produk renders error", async () => {
subcategory_name: "Baju Tidur hehe",
description: "celana",
price: "50000.00",
preorder: "false",
stock: 9,
image: null,
profit: "100000.00",
......@@ -248,6 +249,7 @@ test("Test edit produk renders error", async () => {
subcategory_name: "Baju Tidur hehe",
description: "celana",
price: "50000.00",
preorder: "false",
stock: 9,
image: null,
profit: "100000.00",
......@@ -277,7 +279,5 @@ test("Test edit produk renders error", async () => {
await act(async () => {
await fireEvent.submit(getByTestId("submit-produk"));
});
expect(fetch.mock.calls.length).toEqual(5);
const bank = getByTestId("edit-produk");
expect(bank.textContent).toContain("Error !, Data tidak dapat disimpan");
expect(fetch.mock.calls.length).toEqual(4);
});
import { cleanup, render } from "@testing-library/react";
import AuthContext from "../../utils/contex";
import React from "react";
import { waitFor } from "@testing-library/dom";
import ListProduk from "../../page/produk/ListProduk";
beforeEach(() => {
fetch.resetMocks();
});
afterEach(cleanup);
test("Test List produk", async () => {
fetch.mockResponseOnce(
JSON.stringify({
count: 23,
next: null,
previous: null,
results: [
{
id: "3d403cd3-e356-4c15-9a86-8843333e2778",
code: "5VK6TY",
name: "a",
category: "f0c08b4f-7421-4298-89e4-3d4a40ef15b4",
category_name: "Baju",
subcategory: "626aa022-50a7-4d3a-b658-79cb0f059b03",
subcategory_name: "Baju Tidur hehe",
description: "celana",
price: "50000.00",
stock: 9,
unit: "pcs",
image: null,
profit: "100000.00"
},
{
id: "9a0bccaa-70f6-48a8-89fc-5c5994684729",
code: "4QKSBC",
name: "Piyama",
category: "f0c08b4f-7421-4298-89e4-3d4a40ef15b4",
category_name: "Baju",
subcategory: "626aa022-50a7-4d3a-b658-79cb0f059b03",
subcategory_name: "Baju Tidur hehe",
description: "piyama",
price: "50000.00",
stock: 14,
unit: "pcs",
image: null,
profit: "100000.00"
},
],
})
);
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "tester" } }}>
<ListProduk />
</AuthContext.Provider>
);
await waitFor(() => getByTestId("tableList"));
const data = getByTestId("tableList");
expect(data.textContent).toContain("Piyama");
expect(data.textContent).toContain("Rp 100.000");
expect(data.textContent).toContain("pcs");
expect(fetch.mock.calls.length).toEqual(1);
});
import { act, cleanup, fireEvent, render } from "@testing-library/react";
import { act, cleanup, fireEvent, render, waitFor } from "@testing-library/react";
import AuthContext from "../../utils/contex";
import React from "react";
import TambahProduk from "../../page/produk/TambahProduk";
......@@ -84,10 +84,16 @@ test("Test tambah produk renders", async () => {
await act(async () => {
await fireEvent.input(modal_produk, {target: { value: "1" } });
});
const stock_produk = getByTestId("stock-produk-input");
const tipe_produk = getByTestId("is-preorder-input-2")
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
await fireEvent.click(tipe_produk, {target: {value: "false"}})
})
await waitFor(() => getByTestId("stock-produk-input")).then(async () => {
const stock_produk = getByTestId("stock-produk-input");
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
})
const unit_produk = getByTestId("unit-produk-input");
await act(async () => {
await fireEvent.input(unit_produk, { target: { value: "pcs" } });
......@@ -244,10 +250,16 @@ test("Test tambah produk error", async () => {
await act(async () => {
await fireEvent.input(modal_produk, {target: { value: "1" } });
});
const stock_produk = getByTestId("stock-produk-input");
const tipe_produk = getByTestId("is-preorder-input-2")
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
await fireEvent.click(tipe_produk, {target: {value: "false"}})
})
await waitFor(() => getByTestId("stock-produk-input")).then(async () => {
const stock_produk = getByTestId("stock-produk-input");
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
})
const unit_produk = getByTestId("unit-produk-input");
await act(async () => {
await fireEvent.input(unit_produk, { target: { value: "pcs" } });
......@@ -339,10 +351,16 @@ test("Test modal produk required", async () => {
await act(async () => {
await fireEvent.input(modal_produk, {target: { value: "1" } });
});
const stock_produk = getByTestId("stock-produk-input");
const tipe_produk = getByTestId("is-preorder-input-2")
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
await fireEvent.click(tipe_produk, {target: {value: "false"}})
})
await waitFor(() => getByTestId("stock-produk-input")).then(async () => {
const stock_produk = getByTestId("stock-produk-input");
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
})
await act(async () => {
await fireEvent.submit(getByTestId("submit-produk"));
});
......@@ -424,10 +442,16 @@ test("Test modal produk required", async () => {
await act(async () => {
await fireEvent.input(price_produk, { target: { value: "1" } });
});
const stock_produk = getByTestId("stock-produk-input");
const tipe_produk = getByTestId("is-preorder-input-2")
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
await fireEvent.click(tipe_produk, {target: {value: "false"}})
})
await waitFor(() => getByTestId("stock-produk-input")).then(async () => {
const stock_produk = getByTestId("stock-produk-input");
await act(async () => {
await fireEvent.input(stock_produk, { target: { value: "1" } });
});
})
const unit_produk = getByTestId("unit-produk-input");
await act(async () => {
await fireEvent.input(unit_produk, { target: { value: "pcs" } });
......
import React from "react";
import React, { useContext } from "react";
import { css } from "@emotion/core";
import { Center } from "./html/html";
import Logo from "./Logo";
import LinkSidebar from "./LinkSidebar";
import { useAuthContext } from "../utils/contex";
import styled from "@emotion/styled";
import { isMobileContext } from "../utils/MobileProvider";
const logout = (token) => {
fetch(`${process.env.REACT_APP_BASE_URL}/auth/logout/`, {
......@@ -15,12 +16,14 @@ const logout = (token) => {
});
};
const Sidebar = () => {
const Sidebar = ({ isToggled }) => {
const { handleLogout, profile } = useAuthContext();
const isMobile = useContext(isMobileContext);
return (
<Center
css={css`
height: 100%;
display: ${isMobile ? (isToggled ? "flex" : "none") : "flex"};
height: 100vh;
border: 1px solid #e0e0e0;
box-sizing: border-box;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
......@@ -48,7 +51,9 @@ const Sidebar = () => {
margin-bottom: 4rem;
`}
>
ADMIN<br />DASHBOARD
ADMIN
<br />
DASHBOARD
</div>
<LinkSidebar to="/batch">BATCH</LinkSidebar>
<LinkSidebar to="/produk">PRODUK</LinkSidebar>
......@@ -65,8 +70,8 @@ const Sidebar = () => {
width: 100%;
text-align: center;
height: 2.5rem;
color: #3C8DBC;
margin-bottom: 2rem
color: #3c8dbc;
margin-bottom: 2rem;
`}
>
<StyledA
......
......@@ -53,7 +53,7 @@ const TableComponent = ({
setStateSearch,
setPageSize,
setFilter,
] = useFetchList([url, pageDefault, searchDefault, 5, argument, null]);
] = useFetchList([url, pageDefault, searchDefault, 10, argument, null]);
const { register, handleSubmit } = useForm();
const {
register: registerFilter,
......@@ -293,7 +293,7 @@ const TableComponent = ({
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 7, 10]}
rowsPerPageOptions={[10, 15, 20]}
count={count || 0}
rowsPerPage={stateSize}
page={statePage - 1}
......
......@@ -2,12 +2,15 @@ import React from "react";
import { useAuthContext } from "../../utils/contex";
import { Redirect } from "@reach/router";
import Layout from "../../layout/Layout";
import MobileProvider from "../../utils/MobileProvider";
const ProtectedRoute = (props) => {
const { is_authenticated } = useAuthContext();
return is_authenticated ? (
<Layout component={props} />
<MobileProvider>
<Layout component={props} />
</MobileProvider>
) : (
<Redirect from="" to="/" noThrow />
);
......
import React from "react";
import React, { useContext, useState } from "react";
import { css } from "@emotion/core";
import Sidebar from "../component/Sidebar";
import { Center } from "../component/html/html";
import { Center, ButtonSubmit } from "../component/html/html";
import { isMobileContext } from "../utils/MobileProvider";
const Layout = (props) => {
const { component: Component, ...rest } = props["component"];
const isMobile = useContext(isMobileContext);
const [isToggled, setIsToggled] = useState(false);
return (
<div
css={css`
......@@ -12,15 +15,31 @@ const Layout = (props) => {
height: 100vh;
`}
>
{isMobile && (
<div
style={{
position: "absolute",
left: "5px",
top: "5px",
zIndex: 1000,
}}
>
<ButtonSubmit onClick={() => setIsToggled(!isToggled)}>
Sidebar
</ButtonSubmit>
</div>
)}
<div
css={css`
width: 60vh;
width: ${isMobile ? "100vw" : "60vh"};
position: ${isMobile && "absolute"};
`}
>
<Sidebar />
<Sidebar {...{ isToggled }} />
</div>
<Center
css={css`
display: ${isToggled ? "none" : "flex"};
width: 100%;
height: 100%;
`}
......
......@@ -78,7 +78,6 @@ const EditBank = ({ idBank }) => {
</DialogActions>
</DialogContent>
</Dialog>
{error && <ErrorDiv>Error !, Data tidak dapat disimpan</ErrorDiv>}
{errorDelete && <ErrorDiv>Tidak dapat menghapus bank.</ErrorDiv>}
<div
css={css`
......@@ -124,7 +123,7 @@ const EditBank = ({ idBank }) => {
Informasi Bank
</div>
</div>
<FormBank {...{ onSubmit, initialData }} />
<FormBank {...{ onSubmit, initialData, error }} />
<div
css={css`
margin-right: 1.5%;
......
......@@ -9,7 +9,7 @@ import {
} from "../../component/html/html";
import { css } from "@emotion/core";
const FormBank = ({ onSubmit, initialData = null }) => {
const FormBank = ({ onSubmit, initialData = null, error }) => {
const { register, handleSubmit, errors } = useForm({
defaultValues:
initialData !== null
......@@ -31,15 +31,24 @@ const FormBank = ({ onSubmit, initialData = null }) => {
`}
>
<div
css={css`
font-size: 15px;
color:red;
`}>
css={css`
font-size: 15px;
color: red;
`}
>
* Perlu diisi
</div>
<RowInput>
<LabelInput htmlFor="bank_name">Nama bank
<span css={css`color:red`}>*</span></LabelInput>
<LabelInput htmlFor="bank_name">
Nama bank
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="name-bank-input"
name="bank_name"
......@@ -48,8 +57,16 @@ const FormBank = ({ onSubmit, initialData = null }) => {
{errors.bank_name && <ErrorDiv>Nama bank tidak boleh kosong</ErrorDiv>}
</RowInput>
<RowInput>
<LabelInput htmlFor="code_number">Nomor kode bank
<span css={css`color:red`}>*</span></LabelInput>
<LabelInput htmlFor="code_number">
Nomor kode bank
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="code-number-input"
name="bank_code_number"
......@@ -60,8 +77,16 @@ const FormBank = ({ onSubmit, initialData = null }) => {
)}
</RowInput>
<RowInput>
<LabelInput htmlFor="account_number">Nomor rekening
<span css={css`color:red`}>*</span></LabelInput>
<LabelInput htmlFor="account_number">
Nomor rekening
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="account-number-input"
name="bank_account_number"
......@@ -72,8 +97,16 @@ const FormBank = ({ onSubmit, initialData = null }) => {
)}
</RowInput>
<RowInput>
<LabelInput htmlFor="account_name">Nama pemilik rekening
<span css={css`color:red`}>*</span></LabelInput>
<LabelInput htmlFor="account_name">
Nama pemilik rekening
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="account-name-input"
name="bank_account_name"
......@@ -83,6 +116,15 @@ const FormBank = ({ onSubmit, initialData = null }) => {
<ErrorDiv>Nama pemilik rekening tidak boleh kosong</ErrorDiv>
)}
</RowInput>
<RowInput>
{error && (
<ErrorDiv>
<button className="btn btn-danger">
Error !, Data tidak dapat disimpan
</button>
</ErrorDiv>
)}
</RowInput>
<RowInput>
<InputSubmitForm
type="submit"
......
......@@ -34,7 +34,7 @@ const ListBank = () => {
</div>
<div
css={css`
width: 35%;
width: 15%;
display: flex;
flex-direction: row;
margin-bottom: 2rem;
......@@ -42,7 +42,6 @@ const ListBank = () => {
`}
>
<LinkYellow to="/bank/tambah">TAMBAH</LinkYellow>
<LinkYellow to="/bank">LIHAT</LinkYellow>
</div>
<TableComponent {...data} />
</div>
......
import React from "react";
import { css } from "@emotion/core";
import { ErrorDiv } from "../../component/html/html";
import FormBank from "./FormBank";
import LinkYellow from "../../component/LinkYellow";
import useSendData from "../../utils/useSendData";
import { Link } from "@reach/router";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
const TambahBank = () => {
const url = `${process.env.REACT_APP_BASE_URL}/bank-account-transfer-destinations/`;
......@@ -29,30 +29,27 @@ const TambahBank = () => {
flex-direction: column;
`}
>
<div>
{error && <ErrorDiv>Error !, Data tidak dapat disimpan</ErrorDiv>}
</div>
<div
css={css`
font-size: 35px;
`}
>
TAMBAH BANK
</div>
<div
css={css`
width: 35%;
display: flex;
flex-direction: row;
margin-bottom: 2rem;
margin-top: 1rem;
font-style: normal;
font-weight: 300;
font-size: 2.5rem;
line-height: 3.4rem;
`}
>
<LinkYellow to="/bank/tambah">TAMBAH</LinkYellow>
<LinkYellow to="/bank">LIHAT</LinkYellow>
<Link to="/bank" style={{ color: "#000000" }}>
<ArrowBackIcon fontSize="large" />
</Link>
<div
css={css`
display: inline;
margin-left: 2rem;
`}
>
TAMBAH BANK
</div>
</div>
<FormBank {...{ onSubmit }} />
<FormBank {...{ onSubmit, error }} />
</div>
);
};
......
import React from "react";
import React, { useState } from "react";
import { css } from "@emotion/core";
import FormBatch from "./FormBatch";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
......@@ -7,19 +7,25 @@ import useFetchSingleData from "../../utils/useFetchSingleData";
import useSendData from "../../utils/useSendData";
import { navigate } from "@reach/router";
import {ErrorDiv } from "../../component/html/html";
import moment from "moment";
const EditBatch = ({ batchId }) => {
const url = `${process.env.REACT_APP_BASE_URL}/batch/${batchId}/`;
// const url = `http://localhost:8000/batch/${batchId}/`; // for local testing purposes
const [initialData, errorState] = useFetchSingleData(url);
const [send, error] = useSendData({ url, method: "PATCH", redirect: -1 });
const [errorMessage, setErrorMessage] = useState("")
const onSubmit = (data) => {
if (moment(data.start_date) > moment(data.end_date)) {
setErrorMessage("Tanggal mulai tidak boleh melebihi tanggal akhir!")
} else {
const formData = new FormData();
formData.append("batch_name", data["batch_name"]);
formData.append("start_date", data["start_date"]);
formData.append("end_date", data["end_date"]);
formData.append("shipping_cost", data["shipping_cost"])
formData.append("shipping_cost", data["shipping_cost"]);
send(formData);
}
};
if (errorState || Object.keys(initialData).length === 0)
return (
......@@ -90,7 +96,7 @@ const EditBatch = ({ batchId }) => {