Skip to content

Commit c9561cb

Browse files
committed
formatted all
1 parent 83b3a74 commit c9561cb

File tree

6 files changed

+283
-248
lines changed

6 files changed

+283
-248
lines changed

src/app/page.tsx

Lines changed: 129 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,125 +8,138 @@ import { toast } from "sonner";
88
import { type Budgetable, areRowsEqual } from "@/lib/utils";
99

1010
const DEFAULT_NEW_ROW: Budgetable = {
11-
id: "",
12-
title: "",
13-
price: 0,
14-
link: "",
15-
note: "",
16-
status: "Unpaid",
11+
id: "",
12+
title: "",
13+
price: 0,
14+
link: "",
15+
note: "",
16+
status: "Unpaid",
1717
};
1818

1919
const ENDPOINT = "/pocketbase";
2020

2121
export default function App() {
22-
const [data, setData] = useState<Budgetable[]>([]);
23-
const [isEditing, setIsEditing] = useState(false);
24-
const [newRow, setNewRow] = useState<Budgetable>(DEFAULT_NEW_ROW);
25-
const [recentlyUpdatedRowId, setRecentlyUpdatedRowId] = useState<string | null>(null);
26-
27-
const fetchData = useCallback(async () => {
28-
try {
29-
const res = await fetch(ENDPOINT);
30-
if (!res.ok) throw new Error("Failed to fetch data");
31-
const records: Budgetable[] = await res.json();
32-
setData(records);
33-
} catch (err) {
34-
toast.error("Error fetching data. Please try again later.");
35-
console.error(err);
36-
}
37-
}, []);
38-
39-
useEffect(() => {
40-
fetchData();
41-
}, [fetchData]);
42-
43-
const handleSave = useCallback(async (updatedRow: Budgetable, originalRow: Budgetable) => {
44-
if (areRowsEqual(updatedRow, originalRow)) return;
45-
46-
try {
47-
const res = await fetch(`${ENDPOINT}/${updatedRow.id}`, {
48-
method: "PUT",
49-
headers: { "Content-Type": "application/json" },
50-
body: JSON.stringify(updatedRow),
51-
});
52-
if (!res.ok) throw new Error("Failed to update row");
53-
54-
const updatedData = await res.json();
55-
setData((prev) => prev.map((row) => (row.id === updatedRow.id ? updatedData : row)));
56-
57-
setRecentlyUpdatedRowId(updatedRow.id);
58-
setTimeout(() => setRecentlyUpdatedRowId(null), 500);
59-
toast.success("Row updated successfully!");
60-
} catch (err) {
61-
toast.error("Error updating row. Please try again.");
62-
console.error(err);
63-
}
64-
}, []);
65-
66-
const handleAddRow = useCallback(async () => {
67-
if (!newRow.title || newRow.price <= 0) {
68-
toast.error("Title and price are required.");
69-
return;
70-
}
71-
72-
try {
73-
const res = await fetch(ENDPOINT, {
74-
method: "POST",
75-
headers: { "Content-Type": "application/json" },
76-
body: JSON.stringify(newRow),
77-
});
78-
if (!res.ok) throw new Error("Failed to add row");
79-
80-
const record: Budgetable = await res.json();
81-
setData((prev) => [...prev, record]);
82-
setNewRow(DEFAULT_NEW_ROW);
83-
toast.success("Row added successfully!");
84-
} catch (err) {
85-
toast.error("Error adding row. Please try again.");
86-
console.error(err);
87-
}
88-
}, [newRow]);
89-
90-
const handleDeleteRow = useCallback(async (id: string) => {
91-
try {
92-
const res = await fetch(`${ENDPOINT}/${id}`, { method: "DELETE" });
93-
if (!res.ok) throw new Error("Failed to delete row");
94-
95-
setData((prev) => prev.filter((row) => row.id !== id));
96-
toast.success("Row deleted successfully!");
97-
} catch (err) {
98-
toast.error("Error deleting row. Please try again.");
99-
console.error(err);
100-
}
101-
}, []);
102-
103-
const toggleStatus = useCallback(async (row: Budgetable) => {
104-
const updatedStatus = row.status === "Paid" ? "Unpaid" : "Paid";
105-
const updatedRow: Budgetable = { ...row, status: updatedStatus as "Paid" | "Unpaid" };
106-
await handleSave(updatedRow, row);
107-
}, [handleSave]);
108-
109-
const total = data.reduce(
110-
(sum, item) => sum + (item.status === "Unpaid" ? item.price : 0),
111-
0,
112-
);
113-
114-
return (
115-
<main className="container mx-auto p-4 max-w-7xl">
116-
<Header isEditing={isEditing} setIsEditing={setIsEditing} />
117-
<TotalDisplay total={total} />
118-
<TableWrapper
119-
data={data}
120-
isEditing={isEditing}
121-
setData={setData}
122-
newRow={newRow}
123-
setNewRow={setNewRow}
124-
recentlyUpdatedRowId={recentlyUpdatedRowId}
125-
handleSave={handleSave}
126-
handleAddRow={handleAddRow}
127-
handleDeleteRow={handleDeleteRow}
128-
toggleStatus={toggleStatus}
129-
/>
130-
</main>
131-
);
22+
const [data, setData] = useState<Budgetable[]>([]);
23+
const [isEditing, setIsEditing] = useState(false);
24+
const [newRow, setNewRow] = useState<Budgetable>(DEFAULT_NEW_ROW);
25+
const [recentlyUpdatedRowId, setRecentlyUpdatedRowId] = useState<
26+
string | null
27+
>(null);
28+
29+
const fetchData = useCallback(async () => {
30+
try {
31+
const res = await fetch(ENDPOINT);
32+
if (!res.ok) throw new Error("Failed to fetch data");
33+
const records: Budgetable[] = await res.json();
34+
setData(records);
35+
} catch (err) {
36+
toast.error("Error fetching data. Please try again later.");
37+
console.error(err);
38+
}
39+
}, []);
40+
41+
useEffect(() => {
42+
fetchData();
43+
}, [fetchData]);
44+
45+
const handleSave = useCallback(
46+
async (updatedRow: Budgetable, originalRow: Budgetable) => {
47+
if (areRowsEqual(updatedRow, originalRow)) return;
48+
49+
try {
50+
const res = await fetch(`${ENDPOINT}/${updatedRow.id}`, {
51+
method: "PUT",
52+
headers: { "Content-Type": "application/json" },
53+
body: JSON.stringify(updatedRow),
54+
});
55+
if (!res.ok) throw new Error("Failed to update row");
56+
57+
const updatedData = await res.json();
58+
setData((prev) =>
59+
prev.map((row) => (row.id === updatedRow.id ? updatedData : row)),
60+
);
61+
62+
setRecentlyUpdatedRowId(updatedRow.id);
63+
setTimeout(() => setRecentlyUpdatedRowId(null), 500);
64+
toast.success("Row updated successfully!");
65+
} catch (err) {
66+
toast.error("Error updating row. Please try again.");
67+
console.error(err);
68+
}
69+
},
70+
[],
71+
);
72+
73+
const handleAddRow = useCallback(async () => {
74+
if (!newRow.title || newRow.price <= 0) {
75+
toast.error("Title and price are required.");
76+
return;
77+
}
78+
79+
try {
80+
const res = await fetch(ENDPOINT, {
81+
method: "POST",
82+
headers: { "Content-Type": "application/json" },
83+
body: JSON.stringify(newRow),
84+
});
85+
if (!res.ok) throw new Error("Failed to add row");
86+
87+
const record: Budgetable = await res.json();
88+
setData((prev) => [...prev, record]);
89+
setNewRow(DEFAULT_NEW_ROW);
90+
toast.success("Row added successfully!");
91+
} catch (err) {
92+
toast.error("Error adding row. Please try again.");
93+
console.error(err);
94+
}
95+
}, [newRow]);
96+
97+
const handleDeleteRow = useCallback(async (id: string) => {
98+
try {
99+
const res = await fetch(`${ENDPOINT}/${id}`, { method: "DELETE" });
100+
if (!res.ok) throw new Error("Failed to delete row");
101+
102+
setData((prev) => prev.filter((row) => row.id !== id));
103+
toast.success("Row deleted successfully!");
104+
} catch (err) {
105+
toast.error("Error deleting row. Please try again.");
106+
console.error(err);
107+
}
108+
}, []);
109+
110+
const toggleStatus = useCallback(
111+
async (row: Budgetable) => {
112+
const updatedStatus = row.status === "Paid" ? "Unpaid" : "Paid";
113+
const updatedRow: Budgetable = {
114+
...row,
115+
status: updatedStatus as "Paid" | "Unpaid",
116+
};
117+
await handleSave(updatedRow, row);
118+
},
119+
[handleSave],
120+
);
121+
122+
const total = data.reduce(
123+
(sum, item) => sum + (item.status === "Unpaid" ? item.price : 0),
124+
0,
125+
);
126+
127+
return (
128+
<main className="container mx-auto p-4 max-w-7xl">
129+
<Header isEditing={isEditing} setIsEditing={setIsEditing} />
130+
<TotalDisplay total={total} />
131+
<TableWrapper
132+
data={data}
133+
isEditing={isEditing}
134+
setData={setData}
135+
newRow={newRow}
136+
setNewRow={setNewRow}
137+
recentlyUpdatedRowId={recentlyUpdatedRowId}
138+
handleSave={handleSave}
139+
handleAddRow={handleAddRow}
140+
handleDeleteRow={handleDeleteRow}
141+
toggleStatus={toggleStatus}
142+
/>
143+
</main>
144+
);
132145
}

0 commit comments

Comments
 (0)