Skip to content

Commit eb33def

Browse files
Update installing-a-dependency.md
1 parent 6254386 commit eb33def

File tree

1 file changed

+88
-13
lines changed

1 file changed

+88
-13
lines changed
Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,93 @@
1-
---
2-
id: installing-a-dependency
3-
title: Installing a Dependency
4-
---
1+
import React, { useState, useEffect, useMemo } from "react";
2+
// Single-file React component for an expense manager app
3+
// TailwindCSS is used for styling (assumes Tailwind is configured in the project).
4+
// Recharts is used for a small category pie chart. Install: `npm install recharts`
55

6-
The generated project includes React and ReactDOM as dependencies. It also includes a set of scripts used by Create React App as a development dependency. You may install other dependencies (for example, React Router) with `npm`:
76

8-
```sh
9-
npm install --save react-router-dom
10-
```
7+
import {
8+
PieChart,
9+
Pie,
10+
Cell,
11+
ResponsiveContainer,
12+
Tooltip as ReTooltip,
13+
} from "recharts";
1114

12-
Alternatively you may use `yarn`:
1315

14-
```sh
15-
yarn add react-router-dom
16-
```
16+
const DEFAULT_CATEGORIES = [
17+
"Ăn uống",
18+
"Di chuyển",
19+
"Nhà ở",
20+
"Giải trí",
21+
"Sức khỏe",
22+
"Thu nhập",
23+
"Khác",
24+
];
1725

18-
This works for any library, not only `react-router-dom`.
26+
27+
const COLORS = [
28+
"#4f46e5",
29+
"#06b6d4",
30+
"#f59e0b",
31+
"#ef4444",
32+
"#10b981",
33+
"#8b5cf6",
34+
"#374151",
35+
];
36+
37+
38+
const STORAGE_KEY = "expense_manager_data_v1";
39+
40+
41+
export default function ExpenseManager() {
42+
const [transactions, setTransactions] = useState([]);
43+
const [categories, setCategories] = useState(DEFAULT_CATEGORIES);
44+
45+
46+
const [form, setForm] = useState({
47+
type: "expense", // expense or income
48+
amount: "",
49+
category: DEFAULT_CATEGORIES[0],
50+
note: "",
51+
date: new Date().toISOString().slice(0, 10),
52+
});
53+
54+
55+
const [filterMonth, setFilterMonth] = useState(
56+
new Date().toISOString().slice(0, 7)
57+
);
58+
const [searchText, setSearchText] = useState("");
59+
60+
61+
// load from localStorage
62+
useEffect(() => {
63+
try {
64+
const raw = localStorage.getItem(STORAGE_KEY);
65+
if (raw) {
66+
const parsed = JSON.parse(raw);
67+
if (Array.isArray(parsed.transactions)) {
68+
setTransactions(parsed.transactions);
69+
}
70+
if (Array.isArray(parsed.categories)) {
71+
setCategories(parsed.categories);
72+
}
73+
}
74+
} catch (e) {
75+
console.error("Failed to load data", e);
76+
}
77+
}, []);
78+
79+
80+
// save to localStorage when transactions or categories change
81+
useEffect(() => {
82+
localStorage.setItem(
83+
STORAGE_KEY,
84+
JSON.stringify({ transactions, categories })
85+
);
86+
}, [transactions, categories]);
87+
88+
89+
function handleFormChange(e) {
90+
const { name, value } = e.target;
91+
setForm((f) => ({ ...f, [name]: value }));
92+
}
93+
}

0 commit comments

Comments
 (0)