mirror of
https://github.com/skidoodle/budgetable.git
synced 2025-02-15 03:39:14 +01:00
formatted all
This commit is contained in:
parent
83b3a747a1
commit
c9561cb795
6 changed files with 263 additions and 228 deletions
|
@ -22,7 +22,9 @@ export default function App() {
|
||||||
const [data, setData] = useState<Budgetable[]>([]);
|
const [data, setData] = useState<Budgetable[]>([]);
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [newRow, setNewRow] = useState<Budgetable>(DEFAULT_NEW_ROW);
|
const [newRow, setNewRow] = useState<Budgetable>(DEFAULT_NEW_ROW);
|
||||||
const [recentlyUpdatedRowId, setRecentlyUpdatedRowId] = useState<string | null>(null);
|
const [recentlyUpdatedRowId, setRecentlyUpdatedRowId] = useState<
|
||||||
|
string | null
|
||||||
|
>(null);
|
||||||
|
|
||||||
const fetchData = useCallback(async () => {
|
const fetchData = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -40,7 +42,8 @@ export default function App() {
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [fetchData]);
|
}, [fetchData]);
|
||||||
|
|
||||||
const handleSave = useCallback(async (updatedRow: Budgetable, originalRow: Budgetable) => {
|
const handleSave = useCallback(
|
||||||
|
async (updatedRow: Budgetable, originalRow: Budgetable) => {
|
||||||
if (areRowsEqual(updatedRow, originalRow)) return;
|
if (areRowsEqual(updatedRow, originalRow)) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -52,7 +55,9 @@ export default function App() {
|
||||||
if (!res.ok) throw new Error("Failed to update row");
|
if (!res.ok) throw new Error("Failed to update row");
|
||||||
|
|
||||||
const updatedData = await res.json();
|
const updatedData = await res.json();
|
||||||
setData((prev) => prev.map((row) => (row.id === updatedRow.id ? updatedData : row)));
|
setData((prev) =>
|
||||||
|
prev.map((row) => (row.id === updatedRow.id ? updatedData : row)),
|
||||||
|
);
|
||||||
|
|
||||||
setRecentlyUpdatedRowId(updatedRow.id);
|
setRecentlyUpdatedRowId(updatedRow.id);
|
||||||
setTimeout(() => setRecentlyUpdatedRowId(null), 500);
|
setTimeout(() => setRecentlyUpdatedRowId(null), 500);
|
||||||
|
@ -61,7 +66,9 @@ export default function App() {
|
||||||
toast.error("Error updating row. Please try again.");
|
toast.error("Error updating row. Please try again.");
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}, []);
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const handleAddRow = useCallback(async () => {
|
const handleAddRow = useCallback(async () => {
|
||||||
if (!newRow.title || newRow.price <= 0) {
|
if (!newRow.title || newRow.price <= 0) {
|
||||||
|
@ -100,11 +107,17 @@ export default function App() {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const toggleStatus = useCallback(async (row: Budgetable) => {
|
const toggleStatus = useCallback(
|
||||||
|
async (row: Budgetable) => {
|
||||||
const updatedStatus = row.status === "Paid" ? "Unpaid" : "Paid";
|
const updatedStatus = row.status === "Paid" ? "Unpaid" : "Paid";
|
||||||
const updatedRow: Budgetable = { ...row, status: updatedStatus as "Paid" | "Unpaid" };
|
const updatedRow: Budgetable = {
|
||||||
|
...row,
|
||||||
|
status: updatedStatus as "Paid" | "Unpaid",
|
||||||
|
};
|
||||||
await handleSave(updatedRow, row);
|
await handleSave(updatedRow, row);
|
||||||
}, [handleSave]);
|
},
|
||||||
|
[handleSave],
|
||||||
|
);
|
||||||
|
|
||||||
const total = data.reduce(
|
const total = data.reduce(
|
||||||
(sum, item) => sum + (item.status === "Unpaid" ? item.price : 0),
|
(sum, item) => sum + (item.status === "Unpaid" ? item.price : 0),
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
import pb from "@/lib/pocketbase";
|
import pb from "@/lib/pocketbase";
|
||||||
import { ResponseHelper } from "@/lib/helper";
|
import { ResponseHelper } from "@/lib/helper";
|
||||||
import { RESPONSE } from "@/lib/const";
|
import { RESPONSE } from "@/lib/const";
|
||||||
import { Budgetable } from "@/lib/utils";
|
import type { Budgetable } from "@/lib/utils";
|
||||||
|
|
||||||
const { INTERNAL_SERVER_ERROR, MISSING_ID, FAILED_TO_DELETE_DATA, FAILED_TO_UPDATE_DATA, INVALID_DATA, SUCCESS, CREATED } = RESPONSE;
|
const {
|
||||||
|
INTERNAL_SERVER_ERROR,
|
||||||
|
MISSING_ID,
|
||||||
|
FAILED_TO_DELETE_DATA,
|
||||||
|
FAILED_TO_UPDATE_DATA,
|
||||||
|
INVALID_DATA,
|
||||||
|
SUCCESS,
|
||||||
|
CREATED,
|
||||||
|
} = RESPONSE;
|
||||||
const { EMAIL, PASSWORD, COLLECTION = "budgetable" } = process.env;
|
const { EMAIL, PASSWORD, COLLECTION = "budgetable" } = process.env;
|
||||||
|
|
||||||
async function authenticateSuperuser(): Promise<void> {
|
async function authenticateSuperuser(): Promise<void> {
|
||||||
|
@ -17,7 +25,7 @@ async function authenticateSuperuser(): Promise<void> {
|
||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
_req: Request,
|
_req: Request,
|
||||||
context: { params: Promise<{ id: string }> }
|
context: { params: Promise<{ id: string }> },
|
||||||
): Promise<Response> {
|
): Promise<Response> {
|
||||||
try {
|
try {
|
||||||
await authenticateSuperuser();
|
await authenticateSuperuser();
|
||||||
|
@ -27,7 +35,9 @@ export async function GET(
|
||||||
return ResponseHelper.error(MISSING_ID);
|
return ResponseHelper.error(MISSING_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
const record: Budgetable = await pb.collection<Budgetable>(COLLECTION).getOne(id);
|
const record: Budgetable = await pb
|
||||||
|
.collection<Budgetable>(COLLECTION)
|
||||||
|
.getOne(id);
|
||||||
return ResponseHelper.success<Budgetable>(record, CREATED.STATUS);
|
return ResponseHelper.success<Budgetable>(record, CREATED.STATUS);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching data:", error);
|
console.error("Error fetching data:", error);
|
||||||
|
@ -37,7 +47,7 @@ export async function GET(
|
||||||
|
|
||||||
export async function DELETE(
|
export async function DELETE(
|
||||||
_req: Request,
|
_req: Request,
|
||||||
context: { params: Promise<{ id: string }> }
|
context: { params: Promise<{ id: string }> },
|
||||||
): Promise<Response> {
|
): Promise<Response> {
|
||||||
try {
|
try {
|
||||||
await authenticateSuperuser();
|
await authenticateSuperuser();
|
||||||
|
@ -57,7 +67,7 @@ export async function DELETE(
|
||||||
|
|
||||||
export async function PUT(
|
export async function PUT(
|
||||||
req: Request,
|
req: Request,
|
||||||
context: { params: Promise<{ id: string }> }
|
context: { params: Promise<{ id: string }> },
|
||||||
): Promise<Response> {
|
): Promise<Response> {
|
||||||
try {
|
try {
|
||||||
await authenticateSuperuser();
|
await authenticateSuperuser();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import pb from "@/lib/pocketbase";
|
import pb from "@/lib/pocketbase";
|
||||||
import { ResponseHelper } from "@/lib/helper";
|
import { ResponseHelper } from "@/lib/helper";
|
||||||
import { RESPONSE } from "@/lib/const";
|
import { RESPONSE } from "@/lib/const";
|
||||||
import { Budgetable } from "@/lib/utils";
|
import type { Budgetable } from "@/lib/utils";
|
||||||
|
|
||||||
const { INTERNAL_SERVER_ERROR } = RESPONSE;
|
const { INTERNAL_SERVER_ERROR } = RESPONSE;
|
||||||
const { EMAIL, PASSWORD, COLLECTION = "budgetable" } = process.env;
|
const { EMAIL, PASSWORD, COLLECTION = "budgetable" } = process.env;
|
||||||
|
|
|
@ -18,7 +18,7 @@ const Header = ({ isEditing, setIsEditing }: AppHeaderProps) => (
|
||||||
</Link>
|
</Link>
|
||||||
</h1>
|
</h1>
|
||||||
<Button variant="ghost" onClick={() => setIsEditing(!isEditing)} size="lg">
|
<Button variant="ghost" onClick={() => setIsEditing(!isEditing)} size="lg">
|
||||||
<span className='text-lg'>{isEditing ? "Lock" : "Unlock"} Editing</span>
|
<span className="text-lg">{isEditing ? "Lock" : "Unlock"} Editing</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,11 +19,23 @@ type ResponseConstant = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RESPONSE: ResponseMap = {
|
export const RESPONSE: ResponseMap = {
|
||||||
INTERNAL_SERVER_ERROR: createResponse(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error."),
|
INTERNAL_SERVER_ERROR: createResponse(
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
"Internal server error.",
|
||||||
|
),
|
||||||
MISSING_ID: createResponse(HttpStatus.BAD_REQUEST, "Missing ID in request."),
|
MISSING_ID: createResponse(HttpStatus.BAD_REQUEST, "Missing ID in request."),
|
||||||
FAILED_TO_DELETE_DATA: createResponse(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to delete data."),
|
FAILED_TO_DELETE_DATA: createResponse(
|
||||||
FAILED_TO_UPDATE_DATA: createResponse(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to update data."),
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
INVALID_DATA: createResponse(HttpStatus.BAD_REQUEST, "Invalid data provided."),
|
"Failed to delete data.",
|
||||||
|
),
|
||||||
|
FAILED_TO_UPDATE_DATA: createResponse(
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
"Failed to update data.",
|
||||||
|
),
|
||||||
|
INVALID_DATA: createResponse(
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
"Invalid data provided.",
|
||||||
|
),
|
||||||
SUCCESS: createResponse(HttpStatus.OK, "Operation completed successfully."),
|
SUCCESS: createResponse(HttpStatus.OK, "Operation completed successfully."),
|
||||||
CREATED: createResponse(HttpStatus.CREATED, "Resource created successfully."),
|
CREATED: createResponse(HttpStatus.CREATED, "Resource created successfully."),
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,11 +30,11 @@ export class ResponseHelper<T = unknown> {
|
||||||
|
|
||||||
static error(
|
static error(
|
||||||
constant: (typeof RESPONSE)[keyof typeof RESPONSE],
|
constant: (typeof RESPONSE)[keyof typeof RESPONSE],
|
||||||
details?: unknown
|
details?: unknown,
|
||||||
): Response {
|
): Response {
|
||||||
return new ResponseHelper<ErrorResponse>(
|
return new ResponseHelper<ErrorResponse>(
|
||||||
{ error: { message: constant.MESSAGE, details } },
|
{ error: { message: constant.MESSAGE, details } },
|
||||||
{ status: constant.STATUS }
|
{ status: constant.STATUS },
|
||||||
).toResponse();
|
).toResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue