Skip to content

Commit

Permalink
Add update transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
FPT-NMTung committed May 13, 2024
1 parent 33b5edd commit ea403d6
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 22 deletions.
14 changes: 12 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "budgoose",
"private": true,
"version": "0.1.2",
"version": "0.1.3",
"type": "module",
"scripts": {
"dev": "vite",
Expand All @@ -21,6 +21,7 @@
"moment": "^2.30.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-confirm": "^0.3.0-7",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.3",
"react-hot-toast": "^2.4.1",
Expand Down
4 changes: 4 additions & 0 deletions src/common/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ export const formatZoneTimeToString = (date) => {

export const convertStringToDate = (str) => {
return moment(str).format('DD/MM/YYYY HH:mm:ss')
}

export const removeMilliseconds = (stringDate) => {
return stringDate.split('.')[0]+"Z"
}
51 changes: 51 additions & 0 deletions src/components/alert/CustomAlertConfirm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PropTypes from 'prop-types';
import { confirmable } from 'react-confirm';
import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@nextui-org/react";

const CustomAlertConfirm = ({show, proceed, confirmation, options}) => (
<Modal
size={'sm'}
backdrop={'blur'}
isOpen={show}
onOpenChange={(status) => {
proceed(status)
}}
>
<ModalContent>
<ModalHeader className="flex flex-col gap-1">Alert confirm!</ModalHeader>
<ModalBody>
<p className={'text-default-800 text-sm'}>
{confirmation}
</p>
</ModalBody>
<ModalFooter>
<Button
size={'sm'}
variant={'flat'}
color={options?.cancel?.color ? options?.cancel?.color : 'default'}
onClick={() => proceed(false)}
>
{options?.cancel?.text ? options?.cancel?.text : 'Cancel'}
</Button>
<Button
size={'sm'}
variant={'flat'}
color={options?.confirm?.color ? options?.confirm?.color : 'primary'}
onClick={() => proceed(true)}
>
{options?.confirm?.text ? options?.confirm?.text : 'Confirm'}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)

CustomAlertConfirm.propTypes = {
show: PropTypes.bool, // from confirmable. indicates if the dialog is shown or not.
proceed: PropTypes.func, // from confirmable. call to close the dialog with promise resolved.
confirmation: PropTypes.string, // arguments of your confirm function
options: PropTypes.object // arguments of your confirm function
}

// confirmable HOC pass props `show`, `dismiss`, `cancel` and `proceed` to your component.
export default confirmable(CustomAlertConfirm);
10 changes: 10 additions & 0 deletions src/components/alert/createConfirmation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createConfirmation } from 'react-confirm';
import CustomAlertConfirm from './CustomAlertConfirm';

// create confirm function
export const confirm = createConfirmation(CustomAlertConfirm);

// This is optional. But wrapping function makes it easy to use.
export function confirmWrapper(confirmation, options = {}) {
return confirm({ confirmation, options });
}
3 changes: 2 additions & 1 deletion src/components/customInput/core/InputAutocomplete.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import PropTypes from "prop-types";
import {IconAsterisk} from "@tabler/icons-react";
import {useController} from "react-hook-form";
import {useEffect} from "react";

const InputAutocomplete = (props) => {
const {
Expand All @@ -19,7 +20,7 @@ const InputAutocomplete = (props) => {
// react form hook
onSelectionChange={field.onChange}
onBlur={field.onBlur}
value={field.value}
selectedKey={field.value}
ref={field.ref}

// nextUI
Expand Down
4 changes: 3 additions & 1 deletion src/layout/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const Footer = () => {
<Card className={'h-12 min-w-12'} isPressable={true}>
<CardBody>
<div className={'h-full w-full flex justify-center items-center overflow-hidden'}>
<IconPower size={18} className={'text-red-600'}/>
<IconPower size={18} className={'text-red-600'} onClick={() => {
document.location.href = import.meta.env.VITE_SSO_URL + '/settings'
}}/>
</div>
</CardBody>
</Card>
Expand Down
48 changes: 36 additions & 12 deletions src/pages/transactionPage/Transaction.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import TableLoading from "../../layout/TableLoading.jsx";
import TableEmpty from "../../layout/TableEmpty.jsx";
import UpdateTransaction from "./UpdateTransaction.jsx";
import {IconArrowBigUpFilled, IconEdit, IconTrashX} from "@tabler/icons-react";
import { confirmWrapper, confirm } from '../../components/alert/createConfirmation.js'
import toast from "react-hot-toast";

const Transaction = () => {
Expand Down Expand Up @@ -51,16 +52,38 @@ const Transaction = () => {
getAllManagement()
}

const handlerDelete = (id) => {
setIsLoading(true)
callApi('pkg_bud_management.delete_item', {
pk_bud_management: id
}, () => {
toast.success('Delete successfully.')
getAllManagement()
}, (err) => {
console.log(err)
})
const handleOnClick = async (id) => {
if (await confirm({
confirmation: 'Are you sure you want to delete this transaction?',
options: {
confirm: {
text: 'Delete',
color: 'danger'
}
}
})) {
setIsLoading(true)
callApi('pkg_bud_management.delete_item', {
pk_bud_management: id
}, () => {
toast.success('Delete successfully.')
getAllManagement()
}, (err) => {
console.log(err)
})
}
}

const handleOpenCreate = (id) => {
setIdSelected(undefined)
setMode('create')
onOpen(true)
}

const handleOpenDetail = (id) => {
setIdSelected(id)
setMode('edit')
onOpen(true)
}

return (
Expand All @@ -78,7 +101,7 @@ const Transaction = () => {
size="sm"
variant="flat"
color="primary"
onClick={onOpen}
onClick={handleOpenCreate}
>
Add transaction
</Button>
Expand Down Expand Up @@ -134,11 +157,12 @@ const Transaction = () => {
<IconEdit
className={'text-blue-500 cursor-pointer'}
size={16}
onClick={() => {handleOpenDetail(item?.PK_BUD_MANAGEMENT)}}
/>
<IconTrashX
className={'text-rose-500 cursor-pointer'}
size={16}
onClick={() => {handlerDelete(item?.PK_BUD_MANAGEMENT)}}
onClick={() => {handleOnClick(item?.PK_BUD_MANAGEMENT)}}
/>
</div>
</TableCell>
Expand Down
31 changes: 26 additions & 5 deletions src/pages/transactionPage/UpdateTransaction.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,54 @@ import InputSelectHolder from "../../components/customInput/InputSelectHolder.js
import InputArrowTransaction from "../../components/customInput/InputArrowTransaction.jsx";
import InputText from "../../components/customInput/InputText.jsx";
import InputDatetime from "../../components/customInput/InputDatetime.jsx";
import {getLocalTimeZone, now} from "@internationalized/date";
import {getLocalTimeZone, now, parseAbsolute, parseDateTime} from "@internationalized/date";
import callApi from "../../apis/GatewayApi.js";
import {formatZoneTimeToString, revertFormatNumber} from "../../common/common.js";
import {formatZoneTimeToString, removeMilliseconds, revertFormatNumber} from "../../common/common.js";
import toast from "react-hot-toast";
import {useForm} from "react-hook-form";

const UpdateTransaction = (props) => {
const [stateUpdate, setStateUpdate] = useState('init')

const { control, handleSubmit, reset } = useForm({
const { control, handleSubmit, reset, setValue } = useForm({
defaultValues: {
holder: '',
amount: '',
note: '',
date: now(getLocalTimeZone()),
date: undefined,
stateArrow: 'UP'
}
})

useEffect(() => {
reset();
if (props.isOpen) {
if (props.mode === 'edit') {
getDetailTransaction()
} else {
setValue('date', now(getLocalTimeZone()))
}
} else {
reset();
}
}, [props.isOpen]);

const getDetailTransaction = () => {
callApi('pkg_bud_management.get_item', {
pk_bud_management: props.id
}, (data) => {
setValue('holder', data[0].FK_BUD_HOLDER)
setValue('amount', data[0].C_CASH_IN ? data[0].C_CASH_IN : data[0].C_CASH_OUT)
setValue('note', data[0].C_NOTE)
setValue('date', parseAbsolute(data[0].C_DATE))
setValue('stateArrow', data[0].C_CASH_IN ? 'UP' : 'DOWN')
})
}

const onSubmit = (data, onClose) => {
setStateUpdate('pending')

callApi('pkg_bud_management.update_item', {
pk_bud_management: props.id,
fk_bud_holder: data.holder,
cash_in: data.stateArrow === 'UP' ? revertFormatNumber(data.amount) : 0,
cash_out: data.stateArrow === 'DOWN' ? revertFormatNumber(data.amount) : 0,
Expand Down

0 comments on commit ea403d6

Please sign in to comment.