Skip to content

Commit

Permalink
Fixed cents problem
Browse files Browse the repository at this point in the history
  • Loading branch information
thedanielforum committed May 2, 2022
1 parent d4b9208 commit 9ff2169
Show file tree
Hide file tree
Showing 13 changed files with 2,213 additions and 152 deletions.
13 changes: 12 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
{
"extends": "next/core-web-vitals"
"extends": "next/core-web-vitals",
"plugins": ["testing-library"],
"overrides": [
// Only uses Testing Library lint rules in test files
{
"files": [
"**/__tests__/**/*.[jt]s?(x)",
"**/?(*.)+(spec|test).[jt]s?(x)"
],
"extends": ["plugin:testing-library/react"]
}
]
}
5 changes: 4 additions & 1 deletion components/MobileNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
AccountCircle,
Add,
} from "@mui/icons-material";
import { parseCurrency } from "utils/currency";
import {
GET_TRANSACTIONS,
TRANSACTION_AMOUNT_AGGREGATE,
Expand All @@ -40,11 +41,13 @@ const MobileNavbar: React.FC = () => {

const onNewTransaction = async (values: TransactionFormValues) => {
try {
let amount = values.type === "income" ? values.amount : -values.amount;

await addTransaction({
variables: {
input: [
{
amount: values.amount,
amount: parseCurrency(amount),
date: values.date,
category: { id: values.category },
user: {
Expand Down
3 changes: 2 additions & 1 deletion components/SmallNumberCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { useIntl } from "react-intl";
import classNames from "classnames";
import Dinero from "dinero.js";
import { ArrowDownward, ArrowUpward } from "@mui/icons-material";

export interface SmallNumberCardProps {
Expand Down Expand Up @@ -53,7 +54,7 @@ const SmallNumberCard: React.FC<SmallNumberCardProps> = (props) => {
"text-red-700": props.amount < 0,
})}
>
$ {intl.formatNumber(props.amount)}
{Dinero({ amount: props.amount, precision: 2 }).toFormat("$0,0.00")}
</h5>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion components/Transaction.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { useIntl } from "react-intl";
import { DateTime } from "luxon";
import Dinero from "dinero.js";

export interface TransactionProps {
amount: number;
Expand Down Expand Up @@ -28,7 +29,7 @@ const Transaction: React.FC<TransactionProps> = (props) => {
</div>
</div>
<h1 className="text-lg font-semibold text-green-700">
$ {intl.formatNumber(props.amount)}
{Dinero({ amount: props.amount, precision: 2 }).toFormat("$0,0.00")}
</h1>
</div>
);
Expand Down
127 changes: 69 additions & 58 deletions forms/TransactionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ export interface TransactionFormProps {
}

export type TransactionFormValues = {
amount?: number;
date?: Date;
category?: string;
amount: number;
date: Date;
category: string;
type: "expense" | "income";
};

const TransactionForm: React.FC<TransactionFormProps> = (props) => {
Expand All @@ -43,62 +44,72 @@ const TransactionForm: React.FC<TransactionFormProps> = (props) => {
onSubmit={props.onSubmit}
validationSchema={validationSchema}
>
<Form className="w-full flex flex-col items-start">
<Field
as={Input}
name="amount"
type="number"
placeholder="1,000"
label="Amount"
className="mb-4"
/>
<Field
as={Input}
name="date"
type="date"
label="Date"
className="mb-4"
/>
{!data.queryCategory.length ? (
<Link href="/account/categories">
<a className="self-center px-6 py-6 mt-12 mb-12 rounded-full drop-shadow-lg bg-gradient-to-br from-ikura-light to-ikura-dark text-white">
Add category
</a>
</Link>
) : (
<div className="mb-4 w-full flex flex-col items-start">
<h3 className="font-semibold">Select category</h3>
{data.queryCategory.map((category: any) => (
<label
key={category.id}
className="flex flex-row justify-center items-center"
>
<Field
type="radio"
name="category"
value={category.id}
className="mr-2"
/>
{category.name}
</label>
))}
{(form) => (
<Form className="w-full flex flex-col items-start">
<Field
as={Input}
name="amount"
type="number"
placeholder="1,000"
label="Amount"
className="mb-4"
/>
<Field
as={Input}
name="date"
type="date"
label="Date"
className="mb-4"
/>
{!data.queryCategory.length ? (
<Link href="/account/categories">
<a className="self-center px-6 py-6 mt-12 mb-12 rounded-full drop-shadow-lg bg-gradient-to-br from-ikura-light to-ikura-dark text-white">
Add category
</a>
</Link>
) : (
<div className="mb-4 w-full flex flex-col items-start">
<h3 className="font-semibold">Select category</h3>
{data.queryCategory.map((category: any) => (
<label
key={category.id}
className="flex flex-row justify-center items-center"
>
<Field
type="radio"
name="category"
value={category.id}
className="mr-2"
/>
{category.name}
</label>
))}
</div>
)}
<div className="flex flex-row justify-between w-full">
<Button
type="button"
className="bg-gradient-to-br from-ikura-light to-ikura-dark text-white mt-2"
onClick={() => {
form.setValues({ ...form.values, type: "income" });
form.handleSubmit();
}}
>
{intl.formatMessage({ defaultMessage: "Income" })}
</Button>
<Button
type="button"
className="bg-gradient-to-br from-ikura-light to-ikura-dark text-white mt-2"
onClick={() => {
form.setValues({ ...form.values, type: "expense" });
form.handleSubmit();
}}
>
{intl.formatMessage({ defaultMessage: "Expense" })}
</Button>
</div>
)}
<div className="flex flex-row justify-between w-full">
<Button
type="button"
className="bg-gradient-to-br from-ikura-light to-ikura-dark text-white mt-2"
>
{intl.formatMessage({ defaultMessage: "Income" })}
</Button>
<Button
type="button"
className="bg-gradient-to-br from-ikura-light to-ikura-dark text-white mt-2"
>
{intl.formatMessage({ defaultMessage: "Expence" })}
</Button>
</div>
</Form>
</Form>
)}
</Formik>
);
};
Expand Down
25 changes: 25 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// TODO: Setup integration with next so we can do snapshot testing

/*
const nextJest = require("next/jest");
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
});
// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
"^@/components/(.*)$": "<rootDir>/components/$1",
"^@/pages/(.*)$": "<rootDir>/pages/$1",
},
testEnvironment: "jest-environment-jsdom",
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
*/
6 changes: 6 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`

// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom/extend-expect";
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest --watch",
"test:ci": "jest --ci",
"i18n:extract": "formatjs extract 'pages/**/*.ts*' 'components/**/*.ts*' --out-file lang/en.json",
"i18n:compile": "formatjs compile-folder lang compiled-lang",
"cdk": "cdk"
Expand All @@ -28,6 +30,7 @@
"chart.js": "^3.5.1",
"classnames": "^2.3.1",
"deepmerge": "^4.2.2",
"dinero.js": "^1.9.1",
"emoji-picker-react": "^3.5.1",
"formik": "^2.2.9",
"graphql": "^16.3.0",
Expand All @@ -51,18 +54,25 @@
"devDependencies": {
"@formatjs/cli": "^4.3.2",
"@tailwindcss/forms": "^0.5.0",
"@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "12.1.2",
"@testing-library/user-event": "13.5.0",
"@types/dinero.js": "^1.9.0",
"@types/jsonwebtoken": "^8.5.8",
"@types/luxon": "^2.0.5",
"@types/node": "^16.11.1",
"@types/react": "17.0.27",
"autoprefixer": "^10.4.4",
"aws-cdk": "^2.20.0",
"aws-cdk-lib": "^2.20.0",
"babel-jest": "27.4.5",
"babel-plugin-formatjs": "^10.3.10",
"constructs": "^10.0.118",
"eslint": "7.32.0",
"eslint-config-next": "11.1.2",
"eslint-plugin-formatjs": "^2.17.9",
"eslint-plugin-testing-library": "5.0.1",
"jest": "27.4.5",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23",
"typescript": "4.4.3"
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
},
"include": [
"next-env.d.ts",
"index.d.ts",
"**/*.ts",
"**/*.tsx"
"**/*.tsx",
"types.d.ts"
],
"exclude": [
"node_modules"
Expand Down
File renamed without changes.
18 changes: 18 additions & 0 deletions utils/currency.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { parseCurrency } from "./currency";

test("parseCurrency", () => {
expect(parseCurrency(0)).toBe(0);
expect(parseCurrency(1)).toBe(100);
expect(parseCurrency(1.25)).toBe(125);
expect(parseCurrency(1.5)).toBe(150);
expect(parseCurrency(1.75)).toBe(175);
expect(parseCurrency(1.12345)).toBe(112);
expect(parseCurrency(10000)).toBe(1000000);

expect(parseCurrency(-1)).toBe(-100);
expect(parseCurrency(-1.25)).toBe(-125);
expect(parseCurrency(-1.5)).toBe(-150);
expect(parseCurrency(-1.75)).toBe(-175);
expect(parseCurrency(-1.12345)).toBe(-112);
expect(parseCurrency(-10000)).toBe(-1000000);
});
13 changes: 13 additions & 0 deletions utils/currency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const parseCurrency = (value: number): number => {
if (isNaN(value)) {
return 0;
}

// Check if the value is a int
if (Number.isInteger(value)) {
return value * 100;
}

const fixed = parseFloat(value.toFixed(2));
return Math.round(fixed * 100);
};
Loading

0 comments on commit 9ff2169

Please sign in to comment.