;
- };
+ weight: number
+ worth: number
+ qty: number
+ category: {
+ code: CategoryCodeEnum
+ description: string
+ rules: Rule[]
+ }
- constructor(category: Category, weight: number, worth: number, qty: number) {
- this.weight = weight;
- this.worth = worth;
- this.qty = qty;
- this.category = category;
- }
+ constructor(
+ category: Category,
+ weight: number,
+ worth: number,
+ qty: number,
+ ) {
+ this.weight = weight
+ this.worth = worth
+ this.qty = qty
+ this.category = category
+ }
}
enum CategoryCodeEnum {
- nRaw = "nRaw",
- nUnripe = "nUnripe",
- nEmptyLadder = "nEmptyLadder",
- nRipe = "nRipe",
- nLongRod = "nLongRod",
- nSmallLadder = "nSmallLadder",
- nRestan = "nRestan",
- nRipenedUnripe = "nRipenedUnripe",
- nPiece = "nPiece",
- nDirtyPiece = "nDirtyPiece",
+ nRaw = 'nRaw',
+ nUnripe = 'nUnripe',
+ nEmptyLadder = 'nEmptyLadder',
+ nRipe = 'nRipe',
+ nLongRod = 'nLongRod',
+ nSmallLadder = 'nSmallLadder',
+ nRestan = 'nRestan',
+ nRipenedUnripe = 'nRipenedUnripe',
+ nPiece = 'nPiece',
+ nDirtyPiece = 'nDirtyPiece',
}
diff --git a/src/classes/rule.ts b/src/classes/rule.ts
index 7e38488..9f4d6c3 100644
--- a/src/classes/rule.ts
+++ b/src/classes/rule.ts
@@ -1,21 +1,26 @@
enum OperationEnum {
- addition = 'addition',
- subtraction = 'subtraction'
+ addition = 'addition',
+ subtraction = 'subtraction',
}
export default class Rule {
- operation: OperationEnum;
- limit: {
- type: string;
- value: number;
- };
- operand: number;
- description: string;
+ operation: OperationEnum
+ limit: {
+ type: string
+ value: number
+ }
+ operand: number
+ description: string
- constructor(operation: OperationEnum, limit: any, operand: number, description: string) {
- this.operation = operation;
- this.limit = limit;
- this.operand = operand;
- this.description = description;
- }
-}
\ No newline at end of file
+ constructor(
+ operation: OperationEnum,
+ limit: any,
+ operand: number,
+ description: string,
+ ) {
+ this.operation = operation
+ this.limit = limit
+ this.operand = operand
+ this.description = description
+ }
+}
diff --git a/src/components/disclaimer-dialog.tsx b/src/components/disclaimer-dialog.tsx
index 7e1664d..dffe1bd 100644
--- a/src/components/disclaimer-dialog.tsx
+++ b/src/components/disclaimer-dialog.tsx
@@ -1,57 +1,69 @@
-import * as React from 'react';
-import Button from '@mui/material/Button';
-import Dialog from '@mui/material/Dialog';
-import DialogActions from '@mui/material/DialogActions';
-import DialogContent from '@mui/material/DialogContent';
-import DialogContentText from '@mui/material/DialogContentText';
-import DialogTitle from '@mui/material/DialogTitle';
-import grey from '@mui/material/colors/grey';
+import * as React from 'react'
+import Button from '@mui/material/Button'
+import Dialog from '@mui/material/Dialog'
+import DialogActions from '@mui/material/DialogActions'
+import DialogContent from '@mui/material/DialogContent'
+import DialogContentText from '@mui/material/DialogContentText'
+import DialogTitle from '@mui/material/DialogTitle'
+import grey from '@mui/material/colors/grey'
import InfoIcon from '@mui/icons-material/Info'
export default function DisclaimerDialog() {
- const [open, setOpen] = React.useState(false);
+ const [open, setOpen] = React.useState(false)
- const handleClickOpen = () => {
- setOpen(true);
- };
+ const handleClickOpen = () => {
+ setOpen(true)
+ }
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = () => {
+ setOpen(false)
+ }
- return (
-
-
} sx={{
- color: grey[500],
- }}>
- Penafian
-
-
-
- );
+ return (
+
+
}
+ sx={{
+ color: grey[500],
+ }}>
+ Penafian
+
+
+
+ )
}
diff --git a/src/components/donation-dialog/components/qris-dialog.tsx b/src/components/donation-dialog/components/qris-dialog.tsx
index adaf6fe..f703345 100644
--- a/src/components/donation-dialog/components/qris-dialog.tsx
+++ b/src/components/donation-dialog/components/qris-dialog.tsx
@@ -1,48 +1,49 @@
-import * as React from "react";
-import Button from "@mui/material/Button";
-import Dialog from "@mui/material/Dialog";
-import DialogActions from "@mui/material/DialogActions";
-import DialogContent from "@mui/material/DialogContent";
-import DialogTitle from "@mui/material/DialogTitle";
+import * as React from 'react'
+import Button from '@mui/material/Button'
+import Dialog from '@mui/material/Dialog'
+import DialogActions from '@mui/material/DialogActions'
+import DialogContent from '@mui/material/DialogContent'
+import DialogTitle from '@mui/material/DialogTitle'
export default function QrisDialog() {
- const [open, setOpen] = React.useState(false);
+ const [open, setOpen] = React.useState(false)
- const handleClickOpen = () => {
- setOpen(true);
- };
+ const handleClickOpen = () => {
+ setOpen(true)
+ }
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = () => {
+ setOpen(false)
+ }
- return (
-
-
-
-
- );
+ return (
+
+
+
+
+ )
}
diff --git a/src/components/donation-dialog/components/saweria-dialog.tsx b/src/components/donation-dialog/components/saweria-dialog.tsx
index e809e55..d8dccc9 100644
--- a/src/components/donation-dialog/components/saweria-dialog.tsx
+++ b/src/components/donation-dialog/components/saweria-dialog.tsx
@@ -1,68 +1,67 @@
-import * as React from "react";
-import Button from "@mui/material/Button";
-import Dialog from "@mui/material/Dialog";
-import DialogActions from "@mui/material/DialogActions";
-import DialogContent from "@mui/material/DialogContent";
-import DialogTitle from "@mui/material/DialogTitle";
-import Link from "@mui/material/Link";
-import Box from "@mui/system/Box";
+import * as React from 'react'
+import Button from '@mui/material/Button'
+import Dialog from '@mui/material/Dialog'
+import DialogActions from '@mui/material/DialogActions'
+import DialogContent from '@mui/material/DialogContent'
+import DialogTitle from '@mui/material/DialogTitle'
+import Link from '@mui/material/Link'
+import Box from '@mui/system/Box'
export default function SaweriaDialog() {
- const [open, setOpen] = React.useState(false);
+ const [open, setOpen] = React.useState(false)
- const handleClickOpen = () => {
- setOpen(true);
- };
+ const handleClickOpen = () => {
+ setOpen(true)
+ }
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = () => {
+ setOpen(false)
+ }
- return (
-
-
-
-
- );
+ return (
+
+
+
+
+ )
}
diff --git a/src/components/donation-dialog/donation-dialog.tsx b/src/components/donation-dialog/donation-dialog.tsx
index 375855a..96647f2 100644
--- a/src/components/donation-dialog/donation-dialog.tsx
+++ b/src/components/donation-dialog/donation-dialog.tsx
@@ -1,61 +1,61 @@
-import * as React from "react";
-import Button from "@mui/material/Button";
-import Dialog from "@mui/material/Dialog";
-import DialogActions from "@mui/material/DialogActions";
-import DialogContent from "@mui/material/DialogContent";
-import DialogContentText from "@mui/material/DialogContentText";
-import DialogTitle from "@mui/material/DialogTitle";
-import Typography from "@mui/material/Typography";
+import * as React from 'react'
+import Button from '@mui/material/Button'
+import Dialog from '@mui/material/Dialog'
+import DialogActions from '@mui/material/DialogActions'
+import DialogContent from '@mui/material/DialogContent'
+import DialogContentText from '@mui/material/DialogContentText'
+import DialogTitle from '@mui/material/DialogTitle'
+import Typography from '@mui/material/Typography'
-import PaidIcon from "@mui/icons-material/Paid";
-import QrisDialog from "./components/qris-dialog";
-import SaweriaDialog from "./components/saweria-dialog";
+import PaidIcon from '@mui/icons-material/Paid'
+import QrisDialog from './components/qris-dialog'
+import SaweriaDialog from './components/saweria-dialog'
export default function DonationDialog() {
- const [open, setOpen] = React.useState(false);
+ const [open, setOpen] = React.useState(false)
- const handleClickOpen = () => {
- setOpen(true);
- };
+ const handleClickOpen = () => {
+ setOpen(true)
+ }
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = () => {
+ setOpen(false)
+ }
- return (
-
- }
- size="large"
- >
- Donasi
-
-
-
- );
+ return (
+
+ }
+ size="large">
+ Donasi
+
+
+
+ )
}
diff --git a/src/components/donation-dialog/index.ts b/src/components/donation-dialog/index.ts
index 7351e48..b03228a 100644
--- a/src/components/donation-dialog/index.ts
+++ b/src/components/donation-dialog/index.ts
@@ -1 +1 @@
-export { default } from "./donation-dialog";
+export { default } from './donation-dialog'
diff --git a/src/components/footer.tsx b/src/components/footer.tsx
index 8085e74..2fa22f0 100644
--- a/src/components/footer.tsx
+++ b/src/components/footer.tsx
@@ -1,41 +1,40 @@
-import Typography from "@mui/material/Typography";
-import Box from "@mui/material/Box";
-import Link from "@mui/material/Link";
-import dayjs from "dayjs";
-import packageJson from "../../package.json";
+import Typography from '@mui/material/Typography'
+import Box from '@mui/material/Box'
+import Link from '@mui/material/Link'
+import dayjs from 'dayjs'
+import packageJson from '../../package.json'
// import { GALog } from "../helpers/firebaseClient";
-const SX = { mt: 4, mb: 4, textAlign: "center" };
-const COMPANY_URL = "https://github.com/sensasi-apps";
+const SX = { mt: 4, mb: 4, textAlign: 'center' }
+const COMPANY_URL = 'https://github.com/sensasi-apps'
// const ON_CLICK_LINK = (e) => GALog('click_company_page')
-const versionDateDayjs = dayjs(packageJson.versionDate);
+const versionDateDayjs = dayjs(packageJson.versionDate)
function Footer() {
- return (
-
-
- {"Copyright © "}
-
- Sensasi Apps
-
- {" " + versionDateDayjs.format("YYYY")}
-
-
- v{packageJson.version}
-
-
-
- {versionDateDayjs.format("DD-MM-YYYY")}
-
-
-
- );
+ return (
+
+
+ {'Copyright © '}
+
+ Sensasi Apps
+
+ {' ' + versionDateDayjs.format('YYYY')}
+
+
+ v{packageJson.version}
+
+
+
+ {versionDateDayjs.format('DD-MM-YYYY')}
+
+
+
+ )
}
-export default Footer;
+export default Footer
diff --git a/src/components/form.tsx b/src/components/form.tsx
index 05feefe..a2f5c27 100644
--- a/src/components/form.tsx
+++ b/src/components/form.tsx
@@ -1,37 +1,44 @@
-import Button from "@mui/material/Button";
-import Box from '@mui/material/Box';
+import Button from '@mui/material/Button'
+import Box from '@mui/material/Box'
-import TextField from "./text-field";
+import TextField from './text-field'
const SX_SUBMIT_BUTTON = { display: 'none' }
-const Form = ({ inputCodes, values, isErrors, handleNext }: {
- inputCodes: string[],
- values: { [key: string]: number },
- isErrors: { [key: string]: boolean },
+const Form = ({
+ inputCodes,
+ values,
+ isErrors,
+ handleNext,
+}: {
+ inputCodes: string[]
+ values: Record
+ isErrors: Record
handleNext: () => void
}) => {
- const TextFields = inputCodes.map(code =>
- (
+ values[code] = value}
- />
- )
+ toParent={value => (values[code] = value)}
+ />
+ ))
- return (
- {
- e.preventDefault()
- return handleNext()
- }}>
- {TextFields}
-
-
- )
+ return (
+ {
+ e.preventDefault()
+ return handleNext()
+ }}>
+ {TextFields}
+
+
+ )
}
-export default Form
\ No newline at end of file
+export default Form
diff --git a/src/components/header.tsx b/src/components/header.tsx
index 0b0ee6e..016bf78 100644
--- a/src/components/header.tsx
+++ b/src/components/header.tsx
@@ -1,34 +1,30 @@
-import Box from '@mui/system/Box';
+import Box from '@mui/system/Box'
-import Typography from '@mui/material/Typography';
-import Avatar from '@mui/material/Avatar';
-
-import PercentOutlinedIcon from '@mui/icons-material/PercentOutlined';
+import Typography from '@mui/material/Typography'
+import Avatar from '@mui/material/Avatar'
+import PercentOutlinedIcon from '@mui/icons-material/PercentOutlined'
const SX_HEADER = {
- marginTop: 8,
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
+ marginTop: 8,
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
}
-const SX_AVATAR = { m: 1,
- bgcolor: 'primary.main',
- width: 56, height: 56
-}
+const SX_AVATAR = { m: 1, bgcolor: 'primary.main', width: 56, height: 56 }
function Header() {
- return (
-
-
-
-
-
- Simulasi Grading Sawit
-
-
- );
+ return (
+
+
+
+
+
+ Simulasi Grading Sawit
+
+
+ )
}
-export default Header;
\ No newline at end of file
+export default Header
diff --git a/src/components/result-box/components/detail-dialog.tsx b/src/components/result-box/components/detail-dialog.tsx
index 03b07a9..a61323a 100644
--- a/src/components/result-box/components/detail-dialog.tsx
+++ b/src/components/result-box/components/detail-dialog.tsx
@@ -1,54 +1,55 @@
-import AppBar from "@mui/material/AppBar";
-import Container from "@mui/system/Container";
-import Dialog from "@mui/material/Dialog";
-import Toolbar from "@mui/material/Toolbar";
-import IconButton from "@mui/material/IconButton";
-import Typography from "@mui/material/Typography";
-import Slide from "@mui/material/Slide";
-import CloseIcon from "@mui/icons-material/Close";
-import DetailTable from "./detail-dialog/components/detail-table";
+import AppBar from '@mui/material/AppBar'
+import Container from '@mui/system/Container'
+import Dialog from '@mui/material/Dialog'
+import Toolbar from '@mui/material/Toolbar'
+import IconButton from '@mui/material/IconButton'
+import Typography from '@mui/material/Typography'
+import Slide from '@mui/material/Slide'
+import CloseIcon from '@mui/icons-material/Close'
+import DetailTable from './detail-dialog/components/detail-table'
-const SX_MY = { my: 4 };
-const SX_ML_FLEX = { ml: 2, flex: 1 };
+const SX_MY = { my: 4 }
+const SX_ML_FLEX = { ml: 2, flex: 1 }
const DetailDialog = ({
- dataset,
- isOpen,
- setIsOpen,
+ dataset,
+ isOpen,
+ setIsOpen,
}: {
- dataset: any;
- isOpen: boolean;
- setIsOpen: any;
+ dataset: any
+ isOpen: boolean
+ setIsOpen: any
}) => {
- return (
-
- );
-};
+ return (
+
+ )
+}
-export default DetailDialog;
+export default DetailDialog
diff --git a/src/components/result-box/components/detail-dialog/components/detail-table.tsx b/src/components/result-box/components/detail-dialog/components/detail-table.tsx
index e4ee87d..8b8c2ab 100644
--- a/src/components/result-box/components/detail-dialog/components/detail-table.tsx
+++ b/src/components/result-box/components/detail-dialog/components/detail-table.tsx
@@ -1,129 +1,132 @@
-import Table from "@mui/material/Table";
-import TableBody from "@mui/material/TableBody";
-import TableCell from "@mui/material/TableCell";
-import TableContainer from "@mui/material/TableContainer";
-import TableHead from "@mui/material/TableHead";
-import TableRow from "@mui/material/TableRow";
-import TableFooter from "@mui/material/TableFooter";
-import ValueTableCell from "../../value-table-cell.tsx";
+import Table from '@mui/material/Table'
+import TableBody from '@mui/material/TableBody'
+import TableCell from '@mui/material/TableCell'
+import TableContainer from '@mui/material/TableContainer'
+import TableHead from '@mui/material/TableHead'
+import TableRow from '@mui/material/TableRow'
+import TableFooter from '@mui/material/TableFooter'
+import ValueTableCell from '../../value-table-cell'
-const SX_BORDER_RIGHT = { borderRight: 1 };
-const SX_TH_BOLD = { th: { fontWeight: "bold" } };
-const SX_STICKY_COLUMN = { position: "sticky", left: 0, background: "white" };
-const SX_TH_CENTER = { th: { textAlign: "center" } };
+const SX_BORDER_RIGHT = { borderRight: 1 }
+const SX_TH_BOLD = { th: { fontWeight: 'bold' } }
+const SX_STICKY_COLUMN = { position: 'sticky', left: 0, background: 'white' }
+const SX_TH_CENTER = { th: { textAlign: 'center' } }
const Row = ({
- data,
+ data,
}: {
- data: {
- category: {
- name: string;
- unit: string;
- };
- qty: number;
- percentage: number;
- percentageNote: string;
- cutWorth: number;
- cutNote: string;
- addWorth: number;
- addNote: string;
- };
+ data: {
+ category: {
+ name: string
+ unit: string
+ }
+ qty: number
+ percentage: number
+ percentageNote: string
+ cutWorth: number
+ cutNote: string
+ addWorth: number
+ addNote: string
+ }
}) => {
- return (
-
-
- {data.category.name}
-
-
-
-
-
-
- );
-};
+ return (
+
+
+ {data.category.name}
+
+
+
+
+
+
+ )
+}
export default function DetailTable({
- dataset,
+ dataset,
}: {
- dataset: {
- category: {
- name: string;
- unit: string;
- };
- qty: number;
- percentage: number;
- percentageNote: string;
- cutWorth: number;
- cutNote: string;
- addWorth: number;
- addNote: string;
- }[];
+ dataset: {
+ category: {
+ name: string
+ unit: string
+ }
+ qty: number
+ percentage: number
+ percentageNote: string
+ cutWorth: number
+ cutNote: string
+ addWorth: number
+ addNote: string
+ }[]
}) {
- const TableRows = dataset.map((data, i) =>
);
+ const TableRows = dataset.map((data, i) =>
)
- const cutWorthTotal = dataset.reduce(
- (acc: number, curr: any) => acc + curr.cutWorth,
- 0
- );
- const addWorthTotal = dataset.reduce(
- (acc: number, curr: any) => acc + curr.addWorth,
- 0
- );
+ const cutWorthTotal = dataset.reduce(
+ (acc: number, curr: any) => acc + curr.cutWorth,
+ 0,
+ )
+ const addWorthTotal = dataset.reduce(
+ (acc: number, curr: any) => acc + curr.addWorth,
+ 0,
+ )
- return (
-
-
-
-
-
-
- TANDAN BUAH SEGAR
-
- POTONGAN
- INSENTIF
-
-
- KATEGORI
- JUMLAH
- (%)
- Rp
- Rp
-
-
- {TableRows}
-
-
-
- TOTAL
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+ TANDAN BUAH SEGAR
+
+ POTONGAN
+ INSENTIF
+
+
+ KATEGORI
+ JUMLAH
+ (%)
+ Rp
+ Rp
+
+
+ {TableRows}
+
+
+
+ TOTAL
+
+
+
+
+
+
+
+ )
}
diff --git a/src/components/result-box/components/summary-table.tsx b/src/components/result-box/components/summary-table.tsx
index 9041d3f..99ad2c7 100644
--- a/src/components/result-box/components/summary-table.tsx
+++ b/src/components/result-box/components/summary-table.tsx
@@ -1,64 +1,68 @@
-import Table from "@mui/material/Table";
-import TableBody from "@mui/material/TableBody";
-import TableCell from "@mui/material/TableCell";
-import TableContainer from "@mui/material/TableContainer";
-import TableHead from "@mui/material/TableHead";
-import TableRow from "@mui/material/TableRow";
-import TableFooter from "@mui/material/TableFooter";
-import ValueTableCell from "./value-table-cell";
+import Table from '@mui/material/Table'
+import TableBody from '@mui/material/TableBody'
+import TableCell from '@mui/material/TableCell'
+import TableContainer from '@mui/material/TableContainer'
+import TableHead from '@mui/material/TableHead'
+import TableRow from '@mui/material/TableRow'
+import TableFooter from '@mui/material/TableFooter'
+import ValueTableCell from './value-table-cell'
-const SX_TABLE_CONTAINER = { mt: 2 };
+const SX_TABLE_CONTAINER = { mt: 2 }
const SX_TABLE = {
- th: {
- fontWeight: "bold",
- },
- "td, th": {
- whiteSpace: "nowrap",
- },
-};
+ th: {
+ fontWeight: 'bold',
+ },
+ 'td, th': {
+ whiteSpace: 'nowrap',
+ },
+}
interface Data {
- name: string;
- weight: number;
- worth: number;
+ name: string
+ weight: number
+ worth: number
}
const Row = ({ data }: { data: Data }) => (
-
- {data.name}
-
-
-
-);
+
+ {data.name}
+
+
+
+)
export default function SummaryTable({ dataset }: { dataset: Data[] }) {
- const rows = dataset.map((data) =>
);
+ const rows = dataset.map(data =>
)
- const finalWeight =
- dataset[0]?.weight - dataset[1]?.weight + dataset[2]?.weight;
- const finalWorth = dataset[0]?.worth - dataset[1]?.worth + dataset[2]?.worth;
+ const finalWeight =
+ dataset[0]?.weight - dataset[1]?.weight + dataset[2]?.weight
+ const finalWorth = dataset[0]?.worth - dataset[1]?.worth + dataset[2]?.worth
- return (
-
-
-
-
- NAMA
- BOBOT
- NILAI
-
-
- {rows}
-
-
-
- HASIL AKHIR
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+ NAMA
+ BOBOT
+ NILAI
+
+
+ {rows}
+
+
+
+ HASIL AKHIR
+
+
+
+
+
+
+
+ )
}
diff --git a/src/components/result-box/components/value-table-cell.tsx b/src/components/result-box/components/value-table-cell.tsx
index 992c34a..5553dd7 100644
--- a/src/components/result-box/components/value-table-cell.tsx
+++ b/src/components/result-box/components/value-table-cell.tsx
@@ -1,54 +1,62 @@
-import Box from "@mui/system/Box"
-import TableCell from "@mui/material/TableCell"
-import Tooltip from "@mui/material/Tooltip";
+import Box from '@mui/system/Box'
+import TableCell from '@mui/material/TableCell'
+import Tooltip from '@mui/material/Tooltip'
-import { numberFormat } from "../../../helpers";
+import { numberFormat } from '../../../helpers'
-type Props = {
- value: number,
- unit?: string,
- th?: boolean,
- tooltip?: string,
- sx?: object,
- format?: string
-};
+interface Props {
+ value: number
+ unit?: string
+ th?: boolean
+ tooltip?: string
+ sx?: object
+ format?: string
+}
-export default function ValueTableCell({ value, unit, th, tooltip, sx, format }: Props) {
- return (
-
- {
- !isNaN(value) && value !== 0 &&
- {
- format === 'currency' && Rp
- }
+export default function ValueTableCell({
+ value,
+ unit,
+ th,
+ tooltip,
+ sx,
+ format,
+}: Props) {
+ return (
+
+ {!isNaN(value) && value !== 0 && (
+
+ {format === 'currency' && Rp}
-
- {
- tooltip &&
-
- {numberFormat(value, format === 'currency' ? 0 : 2)}
-
- }
+
+ {tooltip && (
+
+
+ {numberFormat(
+ value,
+ format === 'currency' ? 0 : 2,
+ )}
+
+
+ )}
- {
- !tooltip && numberFormat(value, format === 'currency' ? 0 : 2)
- }
-
+ {!tooltip &&
+ numberFormat(value, format === 'currency' ? 0 : 2)}
+
- {
- unit && {unit}
- }
-
-
- }
-
- )
-}
\ No newline at end of file
+ {unit && {unit}}
+
+ )}
+
+ )
+}
diff --git a/src/components/result-box/index.ts b/src/components/result-box/index.ts
index 2b646b5..f543be6 100644
--- a/src/components/result-box/index.ts
+++ b/src/components/result-box/index.ts
@@ -1 +1 @@
-export { default } from "./result-box";
+export { default } from './result-box'
diff --git a/src/components/result-box/result-box.tsx b/src/components/result-box/result-box.tsx
index 14ed28a..c9aed9a 100644
--- a/src/components/result-box/result-box.tsx
+++ b/src/components/result-box/result-box.tsx
@@ -1,219 +1,220 @@
-import { useRef, useState, useEffect, useMemo } from "react";
+import { useRef, useState, useEffect, useMemo } from 'react'
-import Box from "@mui/system/Box";
-import Button from "@mui/material/Button";
-import IconButton from "@mui/material/IconButton";
-import Tooltip from "@mui/material/Tooltip";
+import Box from '@mui/system/Box'
+import Button from '@mui/material/Button'
+import IconButton from '@mui/material/IconButton'
+import Tooltip from '@mui/material/Tooltip'
-import calculatePalmGrade from "../../helpers/calculate-palm-grade";
-import DetailDialog from "./components/detail-dialog";
-import SummaryTable from "./components/summary-table";
-import TextField from "../text-field";
+import calculatePalmGrade from '../../helpers/calculate-palm-grade'
+import DetailDialog from './components/detail-dialog'
+import SummaryTable from './components/summary-table'
+import TextField from '../text-field'
// import { GALog } from "../helpers/firebaseClient";
import {
- currencyFormat,
- getSavedDatasets,
- numberFormat,
-} from "../../helpers/index";
-import vars from "../../helpers/vars";
-import moment from "moment";
+ currencyFormat,
+ getSavedDatasets,
+ numberFormat,
+} from '../../helpers/index'
+import vars from '../../helpers/vars'
+import moment from 'moment'
-import SaveIcon from "@mui/icons-material/Save";
+import SaveIcon from '@mui/icons-material/Save'
const getSummaryData = (detailsCalculation: AnuType[]) => {
- const dataset = vars.formValues[0];
-
- const summaryDataset: TypeB[] = [
- {
- name: "Tandan Buah Segar",
- weight: dataset.totalWeight,
- worth: dataset.totalWeight * dataset.pricePerKg,
- tooltip: `${numberFormat(dataset.totalWeight)} × ${currencyFormat(
- dataset.pricePerKg
- )}`,
- },
- ];
-
- const { totalCutWorth, totalAddWorth } = detailsCalculation.reduce(
- (acc, detail) => ({
- totalCutWorth: acc.totalCutWorth + detail.cutWorth,
- totalAddWorth: acc.totalAddWorth + detail.addWorth,
- }),
- {
- totalCutWorth: 0,
- totalAddWorth: 0,
- }
- );
-
- summaryDataset.push({
- name: "Potongan",
- weight: totalCutWorth / dataset.pricePerKg,
- worth: totalCutWorth,
- });
-
- summaryDataset.push({
- name: "Insentif",
- weight: totalAddWorth / dataset.pricePerKg,
- worth: totalAddWorth,
- });
-
- return summaryDataset;
-};
-
-let calculationResults: AnuType[] = [];
+ const dataset = vars.formValues[0]
+
+ const summaryDataset: TypeB[] = [
+ {
+ name: 'Tandan Buah Segar',
+ weight: dataset.totalWeight,
+ worth: dataset.totalWeight * dataset.pricePerKg,
+ tooltip: `${numberFormat(dataset.totalWeight)} × ${currencyFormat(
+ dataset.pricePerKg,
+ )}`,
+ },
+ ]
+
+ const { totalCutWorth, totalAddWorth } = detailsCalculation.reduce(
+ (acc, detail) => ({
+ totalCutWorth: acc.totalCutWorth + detail.cutWorth,
+ totalAddWorth: acc.totalAddWorth + detail.addWorth,
+ }),
+ {
+ totalCutWorth: 0,
+ totalAddWorth: 0,
+ },
+ )
+
+ summaryDataset.push({
+ name: 'Potongan',
+ weight: totalCutWorth / dataset.pricePerKg,
+ worth: totalCutWorth,
+ })
+
+ summaryDataset.push({
+ name: 'Insentif',
+ weight: totalAddWorth / dataset.pricePerKg,
+ worth: totalAddWorth,
+ })
+
+ return summaryDataset
+}
+
+let calculationResults: AnuType[] = []
const ResultBox = () => {
- const temp = vars.formValues[0];
- const dataset = useMemo(() => {
- return { ...temp };
- }, [temp]);
-
- const [isDetailOpen, setIsDetailOpen] = useState(false);
- const [summaryData, setSummaryData] = useState([]);
- const [pricePerKg, setPricePerKg] = useState(dataset.pricePerKg || "");
-
- const detailBtnRef = useRef(null);
-
- useEffect(() => {
- vars.formValues[0].pricePerKg = pricePerKg;
- vars.formValues[1]({ ...vars.formValues[0] });
-
- calculationResults = calculatePalmGrade(vars.formValues[0]);
-
- setSummaryData(getSummaryData(calculationResults));
- }, [pricePerKg]);
-
- useEffect(() => {
- setPricePerKg(dataset.pricePerKg || "");
- }, [dataset.savedAt, dataset.pricePerKg]);
-
- return (
- <>
- {
- e.preventDefault();
- return detailBtnRef.current?.focus();
- }}
- >
- setPricePerKg(value)}
- value={pricePerKg}
- // onBlur={(e) => GALog("enter_price")}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- data.savedAt === dataset.savedAt
- )
- )
- }
- onClick={() => {
- const savedDatasets = getSavedDatasets();
-
- if (dataset.savedAt) {
- const delIndex = savedDatasets.findIndex(
- (data) => data.savedAt === dataset.savedAt
- );
- savedDatasets.splice(delIndex, 1);
- }
-
- dataset.savedAt = moment().format();
- dataset.finalWeight =
- summaryData[0]?.weight -
- summaryData[1]?.weight +
- summaryData[2]?.weight;
- dataset.finalWorth =
- summaryData[0]?.worth -
- summaryData[1]?.worth +
- summaryData[2]?.worth;
-
- vars.formValues[1]({ ...dataset });
- savedDatasets.push({ ...dataset });
-
- window.localStorage.setItem(
- "savedDatasets",
- JSON.stringify(savedDatasets)
- );
- }}
- >
-
-
-
-
-
-
-
-
-
-
- >
- );
-};
-
-export default ResultBox;
+ const temp = vars.formValues[0]
+ const dataset = useMemo(() => {
+ return { ...temp }
+ }, [temp])
+
+ const [isDetailOpen, setIsDetailOpen] = useState(false)
+ const [summaryData, setSummaryData] = useState([])
+ const [pricePerKg, setPricePerKg] = useState(dataset.pricePerKg || '')
+
+ const detailBtnRef = useRef(null)
+
+ useEffect(() => {
+ vars.formValues[0].pricePerKg = pricePerKg
+ vars.formValues[1]({ ...vars.formValues[0] })
+
+ calculationResults = calculatePalmGrade(vars.formValues[0])
+
+ setSummaryData(getSummaryData(calculationResults))
+ }, [pricePerKg])
+
+ useEffect(() => {
+ setPricePerKg(dataset.pricePerKg || '')
+ }, [dataset.savedAt, dataset.pricePerKg])
+
+ return (
+ <>
+ {
+ e.preventDefault()
+ return detailBtnRef.current?.focus()
+ }}>
+ setPricePerKg(value)}
+ value={pricePerKg}
+ // onBlur={(e) => GALog("enter_price")}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ data.savedAt ===
+ dataset.savedAt,
+ ),
+ )
+ }
+ onClick={() => {
+ const savedDatasets = getSavedDatasets()
+
+ if (dataset.savedAt) {
+ const delIndex =
+ savedDatasets.findIndex(
+ data =>
+ data.savedAt ===
+ dataset.savedAt,
+ )
+ savedDatasets.splice(delIndex, 1)
+ }
+
+ dataset.savedAt = moment().format()
+ dataset.finalWeight =
+ summaryData[0]?.weight -
+ summaryData[1]?.weight +
+ summaryData[2]?.weight
+ dataset.finalWorth =
+ summaryData[0]?.worth -
+ summaryData[1]?.worth +
+ summaryData[2]?.worth
+
+ vars.formValues[1]({ ...dataset })
+ savedDatasets.push({ ...dataset })
+
+ window.localStorage.setItem(
+ 'savedDatasets',
+ JSON.stringify(savedDatasets),
+ )
+ }}>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+
+export default ResultBox
interface AnuType {
- qty: number;
- category: any;
- percentage: number;
- percentageNote: string;
- weight: number;
- weightNote: string;
- worth: number;
- worthNote: string;
- cutWorth: number;
- cutNote: string;
- addWorth: number;
- addNote: string;
+ qty: number
+ category: any
+ percentage: number
+ percentageNote: string
+ weight: number
+ weightNote: string
+ worth: number
+ worthNote: string
+ cutWorth: number
+ cutNote: string
+ addWorth: number
+ addNote: string
}
interface TypeB {
- name: string;
- weight: number;
- worth: number;
- tooltip?: string;
+ name: string
+ weight: number
+ worth: number
+ tooltip?: string
}
diff --git a/src/components/saved-calculation.tsx b/src/components/saved-calculation.tsx
index 7acc362..437dc65 100644
--- a/src/components/saved-calculation.tsx
+++ b/src/components/saved-calculation.tsx
@@ -1,145 +1,186 @@
-import * as React from 'react';
-import Container from '@mui/material/Container';
-import Dialog from '@mui/material/Dialog';
-import ListItemText from '@mui/material/ListItemText';
-import ListItem from '@mui/material/ListItem';
-import List from '@mui/material/List';
-import Divider from '@mui/material/Divider';
-import AppBar from '@mui/material/AppBar';
-import Menu from '@mui/material/Menu';
-import MenuItem from '@mui/material/MenuItem';
-import IconButton from '@mui/material/IconButton';
-import Typography from '@mui/material/Typography';
-import CloseIcon from '@mui/icons-material/Close';
-import Slide from '@mui/material/Slide';
-import { TransitionProps } from '@mui/material/transitions';
-import VisibilityIcon from '@mui/icons-material/Visibility';
-import MoreVert from '@mui/icons-material/MoreVert';
-import moment from 'moment';
-import { currencyFormat, getSavedDatasets, numberFormat } from '../helpers/index.ts';
-import vars from '../helpers/vars.ts';
-import Tooltip from '@mui/material/Tooltip';
-import ListIcon from '@mui/icons-material/List';
-
-
+import * as React from 'react'
+import Container from '@mui/material/Container'
+import Dialog from '@mui/material/Dialog'
+import ListItemText from '@mui/material/ListItemText'
+import ListItem from '@mui/material/ListItem'
+import List from '@mui/material/List'
+import Divider from '@mui/material/Divider'
+import AppBar from '@mui/material/AppBar'
+import Menu from '@mui/material/Menu'
+import MenuItem from '@mui/material/MenuItem'
+import IconButton from '@mui/material/IconButton'
+import Typography from '@mui/material/Typography'
+import CloseIcon from '@mui/icons-material/Close'
+import Slide from '@mui/material/Slide'
+import { TransitionProps } from '@mui/material/transitions'
+import VisibilityIcon from '@mui/icons-material/Visibility'
+import MoreVert from '@mui/icons-material/MoreVert'
+import moment from 'moment'
+import {
+ currencyFormat,
+ getSavedDatasets,
+ numberFormat,
+} from '../helpers'
+import vars from '../helpers/vars'
+import Tooltip from '@mui/material/Tooltip'
+import ListIcon from '@mui/icons-material/List'
const Transition = React.forwardRef(function Transition(
- props: TransitionProps & {
- children: React.ReactElement;
- },
- ref: React.Ref,
+ props: TransitionProps & {
+ children: React.ReactElement
+ },
+ ref: React.Ref,
) {
- return ;
-});
+ return
+})
export default function SavedCalculationDialog() {
- const [open, setOpen] = React.useState(false);
+ const [open, setOpen] = React.useState(false)
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = () => {
+ setOpen(false)
+ }
- const [anchorEl, setAnchorEl] = React.useState(null);
- const isMoreVertOpen = Boolean(anchorEl);
- const handleMoreVertClick = (event: React.MouseEvent) => {
- setAnchorEl(event.currentTarget);
- };
+ const [anchorEl, setAnchorEl] = React.useState(null)
+ const isMoreVertOpen = Boolean(anchorEl)
+ const handleMoreVertClick = (
+ event: React.MouseEvent,
+ ) => {
+ setAnchorEl(event.currentTarget)
+ }
- const handleMoreVertClose = () => {
- setAnchorEl(null);
- };
+ const handleMoreVertClose = () => {
+ setAnchorEl(null)
+ }
- return (
- <>
-
- setOpen(true)}>
-
-
-
+ return (
+ <>
+
+ setOpen(true)}>
+
+
+
-
- >
- );
-}
\ No newline at end of file
+ {getSavedDatasets().length === 0 && (
+
+ Belum ada data tersimpan
+
+ )}
+
+
+
+ >
+ )
+}
diff --git a/src/components/stepper.tsx b/src/components/stepper.tsx
index f5c98ac..e1e9b1d 100644
--- a/src/components/stepper.tsx
+++ b/src/components/stepper.tsx
@@ -1,45 +1,49 @@
-import MobileStepper from "@mui/material/MobileStepper";
-import Grid from "@mui/material/Grid";
-import Button from "@mui/material/Button";
+import MobileStepper from '@mui/material/MobileStepper'
+import Grid from '@mui/material/Grid'
+import Button from '@mui/material/Button'
-import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
-import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
+import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'
+import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'
-type Props = {
- activeStep: number,
- handlePrev: () => void,
- handleNext: () => void
+interface Props {
+ activeStep: number
+ handlePrev: () => void
+ handleNext: () => void
}
export default function Stepper({ activeStep, handlePrev, handleNext }: Props) {
-
- return
-
-
- Selanjutnya
-
-
- }
- backButton={
-
- }
- />
-
-}
\ No newline at end of file
+ return (
+
+
+ Selanjutnya
+
+
+ }
+ backButton={
+
+ }
+ />
+
+ )
+}
diff --git a/src/components/text-field.tsx b/src/components/text-field.tsx
index c51cfa6..8ed4317 100644
--- a/src/components/text-field.tsx
+++ b/src/components/text-field.tsx
@@ -1,107 +1,109 @@
-import { useEffect, useState } from "react";
+import { useEffect, useState } from 'react'
-import InputAdornment from "@mui/material/InputAdornment";
-import TextField from "@mui/material/TextField";
-import categoriesDataset from "../data/categories";
+import InputAdornment from '@mui/material/InputAdornment'
+import TextField from '@mui/material/TextField'
+import categoriesDataset from '../data/categories'
const getCategory = (code: string): (typeof categoriesDataset)[0] | undefined =>
- categoriesDataset.find((category) => category.code === code);
+ categoriesDataset.find(category => category.code === code)
const MyTextField = ({
- code,
- toParent,
- onBlur,
- ...props
+ code,
+ toParent,
+ onBlur,
+ ...props
}: {
- code: string;
- toParent: (value: number) => void;
- onBlur?: () => void;
- value?: string | number;
- isError?: boolean;
+ code: string
+ toParent: (value: number) => void
+ onBlur?: () => void
+ value?: string | number
+ isError?: boolean
}) => {
- const [value, setValue] = useState(props.value?.toString() ?? '');
- const [isError, setIsError] = useState(props.isError ? true : false);
+ const [value, setValue] = useState(props.value?.toString() ?? '')
+ const [isError, setIsError] = useState(props.isError ? true : false)
- let temp:
- | (typeof categoriesDataset)[0]
- | {
- name: string;
- unit: string;
- }
- | undefined;
+ let temp:
+ | (typeof categoriesDataset)[0]
+ | {
+ name: string
+ unit: string
+ }
+ | undefined
- if (code === "price" || code === "totalWeight") {
- if (code === "price") {
- temp = {
- name: "Harga Jual",
- unit: "/kg",
- };
- }
+ if (code === 'price' || code === 'totalWeight') {
+ if (code === 'price') {
+ temp = {
+ name: 'Harga Jual',
+ unit: '/kg',
+ }
+ }
- if (code === "totalWeight") {
- temp = {
- name: "Total Bobot (Berat / Tonase)",
- unit: "kg",
- };
- }
- } else {
- temp = getCategory(code);
- }
+ if (code === 'totalWeight') {
+ temp = {
+ name: 'Total Bobot (Berat / Tonase)',
+ unit: 'kg',
+ }
+ }
+ } else {
+ temp = getCategory(code)
+ }
- const category = temp;
+ const category = temp
- const getHelperText = () => {
- const subtractionRule =
- category && "rules" in category
- ? category.rules.find((rule) => rule.operation === "subtraction")
- : undefined;
+ const getHelperText = () => {
+ const subtractionRule =
+ category && 'rules' in category
+ ? category.rules.find(rule => rule.operation === 'subtraction')
+ : undefined
- if (subtractionRule && subtractionRule.operand === 1)
- return "potongan 100% / reject";
- if (isError) return "Mohon melengkapi isian";
+ if (subtractionRule && subtractionRule.operand === 1)
+ return 'potongan 100% / reject'
+ if (isError) return 'Mohon melengkapi isian'
- return "";
- };
+ return ''
+ }
- useEffect(() => setIsError(props?.isError ?? false), [props.isError]);
+ useEffect(() => setIsError(props?.isError ?? false), [props.isError])
- useEffect(() => setValue(props.value?.toString() ?? ""), [props.value]);
+ useEffect(() => setValue(props.value?.toString() ?? ''), [props.value])
- return (
- {
- if (isError) setIsError(false);
- toParent(parseFloat(e.target.value));
- return setValue(e.target.value);
- }}
- label={category?.name}
- onBlur={onBlur}
- error={isError}
- helperText={getHelperText()}
- InputProps={{
- startAdornment:
- code === "price" ? (
- Rp
- ) : (
- ""
- ),
- endAdornment: (
- {category?.unit}
- ),
- inputMode: "numeric",
- // pattern: "[0-9]*",
- inputProps: { min: 0 },
- }}
- // style & type
- size="small"
- fullWidth
- margin="dense"
- type="number"
- required
- autoComplete="off"
- />
- );
-};
+ return (
+ {
+ if (isError) setIsError(false)
+ toParent(parseFloat(e.target.value))
+ return setValue(e.target.value)
+ }}
+ label={category?.name}
+ onBlur={onBlur}
+ error={isError}
+ helperText={getHelperText()}
+ InputProps={{
+ startAdornment:
+ code === 'price' ? (
+ Rp
+ ) : (
+ ''
+ ),
+ endAdornment: (
+
+ {category?.unit}
+
+ ),
+ inputMode: 'numeric',
+ // pattern: "[0-9]*",
+ inputProps: { min: 0 },
+ }}
+ // style & type
+ size="small"
+ fullWidth
+ margin="dense"
+ type="number"
+ required
+ autoComplete="off"
+ />
+ )
+}
-export default MyTextField;
+export default MyTextField
diff --git a/src/data/categories.ts b/src/data/categories.ts
index 3cff961..00bb598 100644
--- a/src/data/categories.ts
+++ b/src/data/categories.ts
@@ -1,175 +1,181 @@
const categories = [
- {
- id: 1,
- code: "BM",
- name: "Buah Mentah",
- unit: "Janjang",
- rules: [
- {
- operation: "subtraction",
- limit: {
- type: "max",
- value: 0,
- },
- operand: 0.5,
- description: "kelebihan dari limit.value akan dikenakan potongan 50%",
- },
- ],
- },
- {
- id: 2,
- code: "BLM",
- name: "Buah Lewat Matang",
- unit: "Janjang",
- rules: [
- {
- operation: "subtraction",
- limit: {
- type: "max",
- value: 0.05,
- },
- operand: 0.25,
- description: "kelebihan dari limit.value akan dikenakan potongan 25%",
- },
- ],
- },
- // {
- // "id: 3,
- // "code: "TBK",
- // "name: "Tandan Buah Kosong",
- // "unit: "Janjang",
- // "rules: [
- // {
- // "operation: "subtraction",
- // "limit: {
- // "type: "max",
- // "value: 0
- // },
- // "operand: 1,
- // "description: "dipotong semua (100%)"
- // }
- // ]
- // },
- {
- id: 4,
- code: "BMTG",
- name: "Buah Matang",
- unit: "Janjang",
- rules: [],
- },
- {
- id: 5,
- code: "BGP",
- name: "Buah Ganggang Panjang",
- unit: "Janjang",
- rules: [
- {
- operation: "subtraction",
- limit: {
- type: "max",
- value: 0,
- },
- operand: 0.01,
- description: "kelebihan dari limit.value akan dikenakan potongan 1%",
- },
- ],
- },
- // {
- // "id: 6,
- // "code: "JK",
- // "name: "Janjang Kecil (< 3kg)",
- // "unit: "Janjang",
- // "rules: [
- // {
- // "operation: "subtraction",
- // "limit: {
- // "type: "max",
- // "value: 0
- // },
- // "operand: 1,
- // "description: "dipotong semua (100%)"
- // }
- // ]
- // },
- {
- id: 7,
- code: "BR",
- name: "Buah Matang Menginap > 48 jam",
- description:
- "jika mencapai > 5% misal 8% maka yang kena potongan hanya yang 3%",
- unit: "Janjang",
- rules: [
- {
- operation: "subtraction",
- limit: {
- type: "max",
- value: 0.05,
- },
- operand: 0.5,
- description: "kelebihan dari limit.value akan dikenakan potongan 50%",
- },
- ],
- },
- // {
- // "id: 8,
- // "code: "BP",
- // "name: "Buah Mentah Diperam",
- // "unit: "Janjang",
- // "rules: [
- // {
- // "operation: "subtraction",
- // "limit: {
- // "type: "max",
- // "value: 0
- // },
- // "operand: 1,
- // "description: "dipotong semua (100%)"
- // }
- // ]
- // },
- {
- id: 9,
- code: "PBB",
- name: "Berondolan Bersih",
- unit: "kg",
- rules: [
- {
- operation: "addition",
- limit: {
- type: "max",
- value: 0.1,
- },
- operand: 0.08,
- description: "kelebihan dari limit.value akan diberikan insentif 8%",
- },
- {
- operation: "subtraction",
- limit: {
- type: "min",
- value: 0.1,
- },
- operand: 0.3,
- description: "kekurangan dari limit.value akan dikenakan potongan 30%",
- },
- ],
- },
- {
- id: 10,
- code: "BK",
- name: "Berondolan Kotor",
- unit: "kg",
- rules: [
- {
- operation: "subtraction",
- limit: {
- type: "max",
- value: 0,
- },
- operand: 1,
- description: "dipotong semua (100%)",
- },
- ],
- },
-];
+ {
+ id: 1,
+ code: 'BM',
+ name: 'Buah Mentah',
+ unit: 'Janjang',
+ rules: [
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'max',
+ value: 0,
+ },
+ operand: 0.5,
+ description:
+ 'kelebihan dari limit.value akan dikenakan potongan 50%',
+ },
+ ],
+ },
+ {
+ id: 2,
+ code: 'BLM',
+ name: 'Buah Lewat Matang',
+ unit: 'Janjang',
+ rules: [
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'max',
+ value: 0.05,
+ },
+ operand: 0.25,
+ description:
+ 'kelebihan dari limit.value akan dikenakan potongan 25%',
+ },
+ ],
+ },
+ // {
+ // "id: 3,
+ // "code: "TBK",
+ // "name: "Tandan Buah Kosong",
+ // "unit: "Janjang",
+ // "rules: [
+ // {
+ // "operation: "subtraction",
+ // "limit: {
+ // "type: "max",
+ // "value: 0
+ // },
+ // "operand: 1,
+ // "description: "dipotong semua (100%)"
+ // }
+ // ]
+ // },
+ {
+ id: 4,
+ code: 'BMTG',
+ name: 'Buah Matang',
+ unit: 'Janjang',
+ rules: [],
+ },
+ {
+ id: 5,
+ code: 'BGP',
+ name: 'Buah Ganggang Panjang',
+ unit: 'Janjang',
+ rules: [
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'max',
+ value: 0,
+ },
+ operand: 0.01,
+ description:
+ 'kelebihan dari limit.value akan dikenakan potongan 1%',
+ },
+ ],
+ },
+ // {
+ // "id: 6,
+ // "code: "JK",
+ // "name: "Janjang Kecil (< 3kg)",
+ // "unit: "Janjang",
+ // "rules: [
+ // {
+ // "operation: "subtraction",
+ // "limit: {
+ // "type: "max",
+ // "value: 0
+ // },
+ // "operand: 1,
+ // "description: "dipotong semua (100%)"
+ // }
+ // ]
+ // },
+ {
+ id: 7,
+ code: 'BR',
+ name: 'Buah Matang Menginap > 48 jam',
+ description:
+ 'jika mencapai > 5% misal 8% maka yang kena potongan hanya yang 3%',
+ unit: 'Janjang',
+ rules: [
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'max',
+ value: 0.05,
+ },
+ operand: 0.5,
+ description:
+ 'kelebihan dari limit.value akan dikenakan potongan 50%',
+ },
+ ],
+ },
+ // {
+ // "id: 8,
+ // "code: "BP",
+ // "name: "Buah Mentah Diperam",
+ // "unit: "Janjang",
+ // "rules: [
+ // {
+ // "operation: "subtraction",
+ // "limit: {
+ // "type: "max",
+ // "value: 0
+ // },
+ // "operand: 1,
+ // "description: "dipotong semua (100%)"
+ // }
+ // ]
+ // },
+ {
+ id: 9,
+ code: 'PBB',
+ name: 'Berondolan Bersih',
+ unit: 'kg',
+ rules: [
+ {
+ operation: 'addition',
+ limit: {
+ type: 'max',
+ value: 0.1,
+ },
+ operand: 0.08,
+ description:
+ 'kelebihan dari limit.value akan diberikan insentif 8%',
+ },
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'min',
+ value: 0.1,
+ },
+ operand: 0.3,
+ description:
+ 'kekurangan dari limit.value akan dikenakan potongan 30%',
+ },
+ ],
+ },
+ {
+ id: 10,
+ code: 'BK',
+ name: 'Berondolan Kotor',
+ unit: 'kg',
+ rules: [
+ {
+ operation: 'subtraction',
+ limit: {
+ type: 'max',
+ value: 0,
+ },
+ operand: 1,
+ description: 'dipotong semua (100%)',
+ },
+ ],
+ },
+]
-export default categories;
+export default categories
diff --git a/src/helpers/calculate-palm-grade.ts b/src/helpers/calculate-palm-grade.ts
index fa16bcc..654407b 100644
--- a/src/helpers/calculate-palm-grade.ts
+++ b/src/helpers/calculate-palm-grade.ts
@@ -1,130 +1,130 @@
-import { currencyFormat, numberFormat } from "./index.ts";
-import categoryDataset from "../data/categories.ts";
+import { currencyFormat, numberFormat } from './index'
+import categoryDataset from '../data/categories'
-let totalWeight = 0;
-let pricePerKg = 0;
+let totalWeight = 0
+let pricePerKg = 0
-const setTotalWeight = (weight: number) => (totalWeight = weight);
-const setPricePerKg = (price: number) => (pricePerKg = price);
+const setTotalWeight = (weight: number) => (totalWeight = weight)
+const setPricePerKg = (price: number) => (pricePerKg = price)
const rulesCalculation = (
- rules: {
- limit: {
- type: string;
- value: number;
- };
- operation: string;
- operand: number;
- }[],
- percentage: number
+ rules: {
+ limit: {
+ type: string
+ value: number
+ }
+ operation: string
+ operand: number
+ }[],
+ percentage: number,
) =>
- rules
- .map((rule) => {
- let diff = 0;
- let cutWorth = 0;
- let cutNote = "";
- let addWorth = 0;
- let addNote = "";
-
- if (rule.limit.type === "max") {
- diff = percentage - rule.limit.value;
- }
-
- if (rule.limit.type === "min") {
- diff = rule.limit.value - percentage;
- }
-
- if (diff > 0) {
- if (rule.operation === "subtraction") {
- cutWorth = rule.operand * (diff * totalWeight) * pricePerKg;
- cutNote = `${rule.operand * 100}% × ${numberFormat(
- diff * 100
- )}% × ${totalWeight}kg × Rp. ${pricePerKg}`;
- }
-
- if (rule.operation === "addition") {
- addWorth = rule.operand * (diff * totalWeight) * pricePerKg;
- addNote = `${rule.operand * 100}% × ${numberFormat(
- diff * 100
- )}% × ${totalWeight}kg × Rp. ${pricePerKg}`;
- }
- }
-
- return {
- cutWorth: cutWorth,
- cutNote: cutNote,
- addWorth: addWorth,
- addNote: addNote,
- };
- })
- .reduce(
- (acc, cur) => {
- return {
- cutWorth: acc.cutWorth + cur.cutWorth,
- addWorth: acc.addWorth + cur.addWorth,
- cutNote: acc.cutNote + cur.cutNote,
- addNote: acc.addNote + cur.addNote,
- };
- },
- {
- cutWorth: 0,
- addWorth: 0,
- cutNote: "",
- addNote: "",
- }
- );
-
-const getResult = (dataset: { [x: string]: any }) => {
- setTotalWeight(dataset.totalWeight);
- setPricePerKg(dataset.pricePerKg);
-
- const totalLadder = ["BM", "BLM", "BMTG"]
- .map((code) => dataset[code])
- .reduce((acc, cur) => acc + cur, 0);
-
- const weightPerLadder = totalWeight / totalLadder;
-
- return categoryDataset.map((category) => {
- const userInput = dataset[category.code];
- const weight =
- category.unit === "kg" ? userInput : userInput * weightPerLadder;
-
- let percentage = weight / dataset.totalWeight;
- let percentageNote = `${numberFormat(weight)} / ${dataset.totalWeight} Kg`;
-
- if (category.unit !== "kg") {
- percentage = userInput / totalLadder;
- percentageNote = `${numberFormat(userInput)} / ${totalLadder} Janjang`;
- }
-
- const worth = weight * pricePerKg;
- const { cutWorth, addWorth, cutNote, addNote } = rulesCalculation(
- category.rules,
- percentage
- );
- const finalWorth = worth - cutWorth + addWorth;
-
- return {
- qty: userInput,
- category: category,
- percentage: percentage,
- percentageNote: percentageNote,
- weight: weight,
- weightNote:
- category.unit !== "kg"
- ? `${numberFormat(percentage * 100)}% × ${totalWeight}kg`
- : "",
- worth: worth,
- worthNote: `${numberFormat(weight)}kg × Rp. ${currencyFormat(
- pricePerKg
- )}`,
- cutWorth: cutWorth,
- cutNote: cutNote,
- addWorth: addWorth,
- addNote: addNote,
- finalWorth: finalWorth,
- };
- });
-};
-
-export default getResult;
+ rules
+ .map(rule => {
+ let diff = 0
+ let cutWorth = 0
+ let cutNote = ''
+ let addWorth = 0
+ let addNote = ''
+
+ if (rule.limit.type === 'max') {
+ diff = percentage - rule.limit.value
+ }
+
+ if (rule.limit.type === 'min') {
+ diff = rule.limit.value - percentage
+ }
+
+ if (diff > 0) {
+ if (rule.operation === 'subtraction') {
+ cutWorth = rule.operand * (diff * totalWeight) * pricePerKg
+ cutNote = `${rule.operand * 100}% × ${numberFormat(
+ diff * 100,
+ )}% × ${totalWeight}kg × Rp. ${pricePerKg}`
+ }
+
+ if (rule.operation === 'addition') {
+ addWorth = rule.operand * (diff * totalWeight) * pricePerKg
+ addNote = `${rule.operand * 100}% × ${numberFormat(
+ diff * 100,
+ )}% × ${totalWeight}kg × Rp. ${pricePerKg}`
+ }
+ }
+
+ return {
+ cutWorth: cutWorth,
+ cutNote: cutNote,
+ addWorth: addWorth,
+ addNote: addNote,
+ }
+ })
+ .reduce(
+ (acc, cur) => {
+ return {
+ cutWorth: acc.cutWorth + cur.cutWorth,
+ addWorth: acc.addWorth + cur.addWorth,
+ cutNote: acc.cutNote + cur.cutNote,
+ addNote: acc.addNote + cur.addNote,
+ }
+ },
+ {
+ cutWorth: 0,
+ addWorth: 0,
+ cutNote: '',
+ addNote: '',
+ },
+ )
+
+const getResult = (dataset: Record) => {
+ setTotalWeight(dataset.totalWeight)
+ setPricePerKg(dataset.pricePerKg)
+
+ const totalLadder = ['BM', 'BLM', 'BMTG']
+ .map(code => dataset[code])
+ .reduce((acc, cur) => acc + cur, 0)
+
+ const weightPerLadder = totalWeight / totalLadder
+
+ return categoryDataset.map(category => {
+ const userInput = dataset[category.code]
+ const weight =
+ category.unit === 'kg' ? userInput : userInput * weightPerLadder
+
+ let percentage = weight / dataset.totalWeight
+ let percentageNote = `${numberFormat(weight)} / ${dataset.totalWeight} Kg`
+
+ if (category.unit !== 'kg') {
+ percentage = userInput / totalLadder
+ percentageNote = `${numberFormat(userInput)} / ${totalLadder} Janjang`
+ }
+
+ const worth = weight * pricePerKg
+ const { cutWorth, addWorth, cutNote, addNote } = rulesCalculation(
+ category.rules,
+ percentage,
+ )
+ const finalWorth = worth - cutWorth + addWorth
+
+ return {
+ qty: userInput,
+ category: category,
+ percentage: percentage,
+ percentageNote: percentageNote,
+ weight: weight,
+ weightNote:
+ category.unit !== 'kg'
+ ? `${numberFormat(percentage * 100)}% × ${totalWeight}kg`
+ : '',
+ worth: worth,
+ worthNote: `${numberFormat(weight)}kg × Rp. ${currencyFormat(
+ pricePerKg,
+ )}`,
+ cutWorth: cutWorth,
+ cutNote: cutNote,
+ addWorth: addWorth,
+ addNote: addNote,
+ finalWorth: finalWorth,
+ }
+ })
+}
+
+export default getResult
diff --git a/src/helpers/index.ts b/src/helpers/index.ts
index 7dc5aa5..308fb44 100644
--- a/src/helpers/index.ts
+++ b/src/helpers/index.ts
@@ -1,38 +1,44 @@
-export const currencyFormat = (number: number) => number?.toLocaleString('id-ID', {
- style: 'currency',
- currency: 'IDR',
- maximumFractionDigits: 0
-});
+export const currencyFormat = (number: number) =>
+ number?.toLocaleString('id-ID', {
+ style: 'currency',
+ currency: 'IDR',
+ maximumFractionDigits: 0,
+ })
-export const numberFormat = (number: number, maximumFractionDigits = 2) => number?.toLocaleString('id-ID', {
- maximumFractionDigits: maximumFractionDigits
-});
+export const numberFormat = (number: number, maximumFractionDigits = 2) =>
+ number?.toLocaleString('id-ID', {
+ maximumFractionDigits: maximumFractionDigits,
+ })
export const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.0/8 are considered localhost for IPv4.
- window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
-);
+ window.location.hostname === 'localhost' ||
+ // [::1] is the IPv6 localhost address.
+ window.location.hostname === '[::1]' ||
+ // 127.0.0.0/8 are considered localhost for IPv4.
+ /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/.exec(
+ window.location.hostname,
+ ),
+)
export const isProduction = Boolean(
- process.env.NODE_ENV === 'production' && process.env.REACT_APP_ENV === 'production'
+ process.env.NODE_ENV === 'production' &&
+ process.env.REACT_APP_ENV === 'production',
)
export const getSavedDatasets = () => {
- let savedDatasets: {
- finalWorth: number,
- totalWeight: number,
+ let savedDatasets: {
+ finalWorth: number
+ totalWeight: number
savedAt: string
- }[] = [];
+ }[] = []
- const savedDatasetsString = localStorage.getItem('savedDatasets');
+ const savedDatasetsString = localStorage.getItem('savedDatasets')
- try {
- savedDatasets = savedDatasetsString ? JSON.parse(savedDatasetsString) : [];
- } catch (error) {
- }
+ try {
+ savedDatasets = savedDatasetsString
+ ? JSON.parse(savedDatasetsString)
+ : []
+ } catch (error) {}
- return savedDatasets;
-}
\ No newline at end of file
+ return savedDatasets
+}
diff --git a/src/helpers/vars.ts b/src/helpers/vars.ts
index 7e91cda..9d658ac 100644
--- a/src/helpers/vars.ts
+++ b/src/helpers/vars.ts
@@ -1,11 +1,11 @@
const vars: {
- summaryData: any[];
- formValues: any[];
- activeStep: any[];
+ summaryData: any[]
+ formValues: any[]
+ activeStep: any[]
} = {
- summaryData: [],
- formValues: [],
- activeStep: []
-};
+ summaryData: [],
+ formValues: [],
+ activeStep: [],
+}
-export default vars;
\ No newline at end of file
+export default vars
diff --git a/src/main.tsx b/src/main.tsx
index a299121..27aa2fb 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,28 +1,30 @@
-import "@fontsource/roboto/300.css";
-import "@fontsource/roboto/400.css";
-import "@fontsource/roboto/500.css";
-import "@fontsource/roboto/700.css";
+/* eslint-disable react-refresh/only-export-components */
-import createTheme from "@mui/material/styles/createTheme";
-import ThemeProvider from "@mui/material/styles/ThemeProvider";
-import red from "@mui/material/colors/red";
+import '@fontsource/roboto/300.css'
+import '@fontsource/roboto/400.css'
+import '@fontsource/roboto/500.css'
+import '@fontsource/roboto/700.css'
-import { StrictMode } from "react";
-import { createRoot } from "react-dom/client";
-import App from "./app";
+import createTheme from '@mui/material/styles/createTheme'
+import ThemeProvider from '@mui/material/styles/ThemeProvider'
+import red from '@mui/material/colors/red'
+
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import App from './app'
const THEME = createTheme({
- palette: {
- primary: {
- main: red["A700"],
- },
- },
-});
+ palette: {
+ primary: {
+ main: red.A700,
+ },
+ },
+})
-createRoot(document.getElementById("root")!).render(
-
-
-
-
-
-);
+createRoot(document.getElementById('root')!).render(
+
+
+
+
+ ,
+)
diff --git a/tsconfig.node.json b/tsconfig.node.json
index 0d3d714..ff22671 100644
--- a/tsconfig.node.json
+++ b/tsconfig.node.json
@@ -1,22 +1,24 @@
{
- "compilerOptions": {
- "target": "ES2022",
- "lib": ["ES2023"],
- "module": "ESNext",
- "skipLibCheck": true,
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["ES2023", "DOM"],
+ "module": "ESNext",
+ "skipLibCheck": true,
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "isolatedModules": true,
- "moduleDetection": "force",
- "noEmit": true,
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["vite.config.ts"]
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+
+ "jsx": "react-jsx"
+ },
+ "include": ["vite.config.ts", "src"]
}
diff --git a/vite.config.ts b/vite.config.ts
index 4467326..52482e5 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,15 +1,18 @@
-import { sentryVitePlugin } from "@sentry/vite-plugin";
+import { sentryVitePlugin } from '@sentry/vite-plugin'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [react(), sentryVitePlugin({
- org: "sensasi-apps",
- project: "simulasi-grading-sawit"
- })],
+ plugins: [
+ react(),
+ sentryVitePlugin({
+ org: 'sensasi-apps',
+ project: 'simulasi-grading-sawit',
+ }),
+ ],
- build: {
- sourcemap: true
- }
-})
\ No newline at end of file
+ build: {
+ sourcemap: true,
+ },
+})