summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.jsx82
-rw-r--r--src/Entry.jsx29
-rw-r--r--src/SalaryInput.jsx23
-rw-r--r--src/main.jsx13
4 files changed, 147 insertions, 0 deletions
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..da2bbc7
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,82 @@
+import {useEffect, useState} from "react";
+import Entry from "./Entry.jsx";
+
+import {Button, Container, Typography} from "@mui/material";
+import dayjs from "dayjs";
+import SalaryInput from "./SalaryInput.jsx";
+
+
+function App() {
+ const [listEntry, setListEntry] = useState(
+ [
+ {id: 0, date: dayjs(), start: dayjs(), finish: dayjs()},
+ ]
+ );
+ const [removeDisabled, setRemoveDisabled] = useState(false);
+ // const [lastId, setLastId] = useState(0);
+
+ useEffect(() => {
+ setRemoveDisabled(listEntry.length === 1);
+ }, [listEntry]);
+
+ const getLastId = () => {
+ const lastEntry = listEntry[listEntry.length - 1];
+ return lastEntry.id;
+ }
+
+ const addToList = () => {
+ const newEntry = {
+ id: getLastId() + 1,
+ date: dayjs(),
+ start: dayjs(),
+ finish: dayjs()
+ }
+ setListEntry((currentList) => [...currentList, newEntry]);
+ }
+
+ const removeFromList = (id) => {
+ setListEntry((currentList) => {
+ return currentList.filter((en) => en.id !== id);
+ });
+ }
+
+ return (
+ <Container>
+ <Typography variant='h3' align='center'>Overtime Calculator</Typography>
+ <Typography variant='overline' display='block' align='center'>🤑🤑 Sudahkah anda lembur hari ini? 🤑🤑</Typography>
+ <ul>
+ <li style={{listStyle: 'none', margin: '20px 0'}}>
+ <SalaryInput/>
+ </li>
+ {listEntry.map((entry) => {
+ return (
+ <div key={entry.id} style={{display: 'flex', gap: '10px', marginBottom: '10px'}}>
+ <li style={{listStyle: 'none'}} key={entry.id}>
+ <Entry
+ propDate={entry.date}
+ propStart={entry.start}
+ propFinish={entry.finish}
+ />
+ </li>
+ <Button
+ disabled={removeDisabled}
+ variant="outlined"
+ onClick={() => removeFromList(entry.id)}
+ >Hapus</Button>
+ {
+ entry.id === getLastId() ?
+ <Button
+ variant="outlined"
+ onClick={addToList}
+ >Tambah</Button>
+ : null
+ }
+ </div>
+ )
+ })}
+ </ul>
+ </Container>
+ )
+}
+
+export default App
diff --git a/src/Entry.jsx b/src/Entry.jsx
new file mode 100644
index 0000000..e554050
--- /dev/null
+++ b/src/Entry.jsx
@@ -0,0 +1,29 @@
+import {useState} from "react";
+import {DatePicker, LocalizationProvider, TimePicker} from '@mui/x-date-pickers';
+import {AdapterDayjs} from '@mui/x-date-pickers/AdapterDayjs';
+import 'dayjs/locale/id';
+
+
+function Entry({propDate, propStart, propFinish}) {
+ const [date, setDate] = useState(propDate);
+ const [start, setStart] = useState(propStart);
+ const [finish, setFinish] = useState(propFinish);
+
+ return (
+ <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale='id'>
+ <div style={{display: 'flex', gap: '5px'}}>
+ <DatePicker label="Tanggal Lembur" value={date}
+ onAccept={(newDate) => setDate(newDate)}/>
+ <TimePicker label="Mulai" ampm={false} value={start} maxTime={finish} onAccept={(newStart) => {
+ setStart(newStart)
+ }}/>
+ <TimePicker label="Selesai" ampm={false} value={finish} minTime={start} onAccept={(newFinish) => {
+ setFinish(newFinish);
+ console.log(newFinish)
+ }}/>
+ </div>
+ </LocalizationProvider>
+ )
+}
+
+export default Entry; \ No newline at end of file
diff --git a/src/SalaryInput.jsx b/src/SalaryInput.jsx
new file mode 100644
index 0000000..f04c68f
--- /dev/null
+++ b/src/SalaryInput.jsx
@@ -0,0 +1,23 @@
+import { useState } from "react";
+import TextField from "@mui/material/TextField";
+import { NumericFormat } from "react-number-format";
+
+function SalaryInput() {
+ const [displayValue, setDisplayValue] = useState('');
+ return (
+ <NumericFormat
+ customInput={ TextField }
+ label='Gaji Bulanan'
+ variant="outlined"
+ valueIsNumericString={true}
+ thousandSeparator={true}
+ value={displayValue}
+ onValueChange={(value, sourceInfo) => {setDisplayValue(value.value)}}
+ InputProps={{
+ startAdornment: <span>Rp</span>
+ }}
+ />
+ );
+}
+
+export default SalaryInput;
diff --git a/src/main.jsx b/src/main.jsx
new file mode 100644
index 0000000..6552764
--- /dev/null
+++ b/src/main.jsx
@@ -0,0 +1,13 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App.jsx'
+import '@fontsource/roboto/300.css';
+import '@fontsource/roboto/400.css';
+import '@fontsource/roboto/500.css';
+import '@fontsource/roboto/700.css';
+
+ReactDOM.createRoot(document.getElementById('root')).render(
+ <React.StrictMode>
+ <App />
+ </React.StrictMode>,
+)