-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
268 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,12 @@ | ||
const path = require("path"); | ||
const fullFile = process.env.LEDGER_FILE; | ||
import path from 'path'; | ||
import { formatTransaction, Transaction } from 'pta-js'; | ||
|
||
import fs from 'fs/promises'; | ||
|
||
export const fullFile = path.resolve(process.env.K_LEDGER_FILE || ""); | ||
|
||
export const filename = path.basename(fullFile); | ||
|
||
export function addTransaction(data: Transaction): Promise<void> { | ||
return fs.appendFile(fullFile, `\n${formatTransaction(data)}`, "utf8"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
export async function callApi(url: string, options: RequestInit = {}) { | ||
const fetchOptions: RequestInit = { | ||
credentials: "same-origin", | ||
headers: { | ||
Accept: "application/json", | ||
"Content-Type": "application/json", | ||
}, | ||
...options, | ||
}; | ||
|
||
const response = await fetch(url, fetchOptions); | ||
// IE11 polyfill for response.ok | ||
if (!("ok" in response)) { | ||
//@ts-ignore | ||
response.ok = response.status >= 200 && response.status < 300; | ||
} | ||
return response; | ||
} | ||
|
||
export function callJsonApi<T>(url, options): Promise<T | undefined> { | ||
return callApi(url, options).then((response) => { | ||
if (response.ok) { | ||
return response.json() as Promise<T>; | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import dayjs from 'dayjs'; | ||
import { Transaction } from 'pta-js'; | ||
|
||
// Removes empty entries | ||
function clearTransaction(trx: Transaction): Transaction { | ||
return { | ||
...trx, | ||
entries: trx.entries.filter((e) => !(e.account == "" && e.amount === "")), | ||
}; | ||
} | ||
|
||
export default clearTransaction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React, { FC } from 'react'; | ||
|
||
import clearTransaction from 'helpers/clear-transaction'; | ||
|
||
import { Button, Code, Group, Modal } from '@mantine/core'; | ||
|
||
import { formatTransaction, Transaction } from 'pta-js'; | ||
|
||
const ConfirmationModal: FC<{ | ||
data: Transaction; | ||
onCancel: () => void; | ||
onConfirm: (data: Transaction) => void; | ||
}> = ({ data, onCancel, onConfirm }) => { | ||
const clean = clearTransaction(data); | ||
const trxstr = formatTransaction(clean); | ||
return ( | ||
<Modal opened={true} onClose={onCancel} title="Confirm transaction"> | ||
<Code block>{trxstr}</Code> | ||
<Group position="right" style={{ marginTop: 25 }}> | ||
<Button variant="white" onClick={onCancel}> | ||
Cancel | ||
</Button> | ||
<Button onClick={() => onConfirm(clean)}>Confirm</Button> | ||
</Group> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default ConfirmationModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import React, { FC, useState } from 'react'; | ||
|
||
import { callApi } from 'helpers/api'; | ||
import clearTransaction from 'helpers/clear-transaction'; | ||
|
||
import { Button, Group, LoadingOverlay, Paper, TextInput, Title } from '@mantine/core'; | ||
import { DatePicker } from '@mantine/dates'; | ||
import { useForm } from '@mantine/hooks'; | ||
|
||
import { Transaction } from 'pta-js'; | ||
|
||
import ConfirmationModal from './confirmation-modal'; | ||
|
||
const EMPTY_ENTRY = { account: "", amount: "" }; | ||
|
||
const Dashboard: FC = () => { | ||
const { onSubmit, values, setFieldValue, setValues, reset } = useForm({ | ||
initialValues: { | ||
date: new Date(), | ||
description: "", | ||
entries: [EMPTY_ENTRY], | ||
}, | ||
}); | ||
|
||
const [modalOpen, setModalOpen] = useState(false); | ||
const [showOverlay, setOverlay] = useState(false); | ||
|
||
const handleSubmit = () => { | ||
setModalOpen(true); | ||
}; | ||
|
||
function addRow() { | ||
setValues((state) => ({ | ||
...state, | ||
entries: state.entries.concat({ ...EMPTY_ENTRY }), | ||
})); | ||
} | ||
|
||
function updateRow(idx: number, field: string, value: string) { | ||
setValues((state) => ({ | ||
...state, | ||
entries: state.entries.map((e, i) => { | ||
if (i !== idx) { | ||
return e; | ||
} | ||
|
||
return { ...e, [field]: value }; | ||
}), | ||
})); | ||
} | ||
|
||
function removeRow(idx: number) { | ||
return () => { | ||
setValues((state) => ({ | ||
...state, | ||
entries: state.entries.filter((e, i) => i !== idx), | ||
})); | ||
}; | ||
} | ||
|
||
async function handleModalConfirm(data: Transaction) { | ||
setModalOpen(false); | ||
setOverlay(true); | ||
const response = await callApi("/api/journal", { | ||
method: "POST", | ||
body: JSON.stringify(data), | ||
}); | ||
setOverlay(false); | ||
if (response.ok) { | ||
reset(); | ||
} | ||
} | ||
|
||
return ( | ||
<div> | ||
<Paper padding="md" shadow="sm" component="section"> | ||
<form | ||
onSubmit={onSubmit(handleSubmit)} | ||
style={{ position: "relative" }} | ||
> | ||
<LoadingOverlay visible={showOverlay} /> | ||
<Title order={2}>Add</Title> | ||
<DatePicker | ||
placeholder="Pick a date" | ||
label="Date" | ||
value={values.date} | ||
onChange={(date) => date && setFieldValue("date", date)} | ||
/> | ||
<TextInput | ||
label="Description" | ||
value={values.description} | ||
onChange={(event) => | ||
setFieldValue("description", event.currentTarget.value) | ||
} | ||
/> | ||
{values.entries.map((entry, i) => ( | ||
<Group style={{ marginTop: 25, alignItems: "center" }} key={i}> | ||
<TextInput | ||
label="Account" | ||
value={entry.account} | ||
onChange={(event) => | ||
updateRow(i, "account", event.currentTarget.value) | ||
} | ||
/> | ||
<TextInput | ||
label="Amount" | ||
value={entry.amount} | ||
onChange={(event) => | ||
updateRow(i, "amount", event.currentTarget.value) | ||
} | ||
/> | ||
<Button compact style={{ marginTop: "30px" }} onClick={addRow}> | ||
+ | ||
</Button> | ||
{i !== 0 && ( | ||
<Button | ||
compact | ||
style={{ marginTop: "30px" }} | ||
onClick={removeRow(i)} | ||
> | ||
- | ||
</Button> | ||
)} | ||
</Group> | ||
))} | ||
<Group position="right" style={{ marginTop: 25 }}> | ||
<Button color="blue" type="submit"> | ||
Add | ||
</Button> | ||
</Group> | ||
</form> | ||
</Paper> | ||
{modalOpen && ( | ||
<ConfirmationModal | ||
data={values} | ||
onCancel={() => setModalOpen(false)} | ||
onConfirm={handleModalConfirm} | ||
/> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default Dashboard; |
Oops, something went wrong.