Extract APIs to their own files #108
							
								
								
									
										38
									
								
								app/api/expenses.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/api/expenses.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | import { Expense } from '@/app/lib/definitions'; | ||||||
|  | import { getCsrfToken } from '@/app/lib/utils'; | ||||||
|  | 
 | ||||||
|  | export function loadExpenses(onLoad?: (expenses: Expense[]) => void) { | ||||||
|  |   fetch("/api/expenses") | ||||||
|  |     .then((response) => response.json()) | ||||||
|  |     .then((data) => { | ||||||
|  |       onLoad && onLoad(data.map((record: any) => { | ||||||
|  |         return ({ | ||||||
|  |           id: record.id, | ||||||
|  |           name: record.name, | ||||||
|  |           amount: record.amount, | ||||||
|  |           pricingType: record.pricing_type | ||||||
|  |         }); | ||||||
|  |       })); | ||||||
|  |     }, (error) => { | ||||||
|  |       return []; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function updateExpense(expense: Expense) { | ||||||
|  |   fetch(`/api/expenses/${expense.id}`, | ||||||
|  |     { | ||||||
|  |       method: 'PUT', | ||||||
|  |       body: JSON.stringify({ | ||||||
|  |         expense: { | ||||||
|  |           name: expense.name, | ||||||
|  |           amount: expense.amount, | ||||||
|  |           pricing_type: expense.pricingType, | ||||||
|  |         } | ||||||
|  |       }), | ||||||
|  |       headers: { | ||||||
|  |         'Content-Type': 'application/json', | ||||||
|  |         'X-CSRF-TOKEN': getCsrfToken(), | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     .catch((error) => console.error(error)); | ||||||
|  | } | ||||||
| @ -2,52 +2,24 @@ | |||||||
| 
 | 
 | ||||||
| 'use client' | 'use client' | ||||||
| 
 | 
 | ||||||
| import React, { useState } from "react" | import { loadExpenses, updateExpense } from '@/app/api/expenses'; | ||||||
| import { Expense } from '@/app/lib/definitions'; | import { Expense } from '@/app/lib/definitions'; | ||||||
| import TableOfContents from "../components/table-of-contents"; | import { useState } from "react"; | ||||||
| import InlineTextField from "../components/form/inlineTextField"; | import InlineTextField from "../components/form/inlineTextField"; | ||||||
| import { getCsrfToken } from '@/app/lib/utils'; | import TableOfContents from "../components/table-of-contents"; | ||||||
| 
 | 
 | ||||||
| export default function ExpensesTable() { | export default function ExpensesTable() { | ||||||
|   const [expenses, setExpenses] = useState<Array<Expense>>([]); |   const [expenses, setExpenses] = useState<Array<Expense>>([]); | ||||||
|  |   const [expensesLoaded, setExpensesLoaded] = useState(false); | ||||||
| 
 | 
 | ||||||
|     const handleExpenseUpdate = (expense: Expense) => { |   function refreshExpenses() { | ||||||
|         fetch(`/api/expenses/${expense.id}`, |     loadExpenses((expenses) => { | ||||||
|             { |       setExpenses(expenses); | ||||||
|                 method: 'PUT', |       setExpensesLoaded(true); | ||||||
|                 body: JSON.stringify({ |  | ||||||
|                     expense: { |  | ||||||
|                         name: expense.name, |  | ||||||
|                         amount: expense.amount, |  | ||||||
|                         pricing_type: expense.pricingType, |  | ||||||
|                     } |  | ||||||
|                 }), |  | ||||||
|                 headers: { |  | ||||||
|                     'Content-Type': 'application/json', |  | ||||||
|                     'X-CSRF-TOKEN': getCsrfToken(), |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|             .catch((error) => console.error(error)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function loadExpenses() { |  | ||||||
|         fetch("/api/expenses") |  | ||||||
|             .then((response) => response.json()) |  | ||||||
|             .then((data) => { |  | ||||||
|                 setExpenses(data.map((record: any) => { |  | ||||||
|                     return ({ |  | ||||||
|                         id: record.id, |  | ||||||
|                         name: record.name, |  | ||||||
|                         amount: record.amount, |  | ||||||
|                         pricingType: record.pricing_type |  | ||||||
|                     }); |  | ||||||
|                 })); |  | ||||||
|             }, (error) => { |  | ||||||
|                 return []; |  | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|     expenses.length === 0 && loadExpenses(); |   !expensesLoaded && refreshExpenses(); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <TableOfContents |     <TableOfContents | ||||||
| @ -57,10 +29,10 @@ export default function ExpensesTable() { | |||||||
|       rowRender={(expense) => ( |       rowRender={(expense) => ( | ||||||
|         <tr key={expense.id} className="bg-white border-b odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800"> |         <tr key={expense.id} className="bg-white border-b odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800"> | ||||||
|           <th scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"> |           <th scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"> | ||||||
|                         <InlineTextField initialValue={expense.name} onChange={(value) => { expense.name = value; handleExpenseUpdate(expense) }} /> |             <InlineTextField initialValue={expense.name} onChange={(value) => { expense.name = value; updateExpense(expense) }} /> | ||||||
|           </th> |           </th> | ||||||
|           <td className="px-6 py-4"> |           <td className="px-6 py-4"> | ||||||
|                         <InlineTextField initialValue={expense.amount.toString()} onChange={(value) => { expense.amount = parseFloat(value); handleExpenseUpdate(expense) }} /> |             <InlineTextField initialValue={expense.amount.toString()} onChange={(value) => { expense.amount = parseFloat(value); updateExpense(expense) }} /> | ||||||
|           </td> |           </td> | ||||||
|           <td> |           <td> | ||||||
|             {expense.pricingType} |             {expense.pricingType} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user