Files
bewcloud/routes/expenses.tsx
Bruno Bernardino e337859a22 Implement a more robust Config (#60)
* Implement a more robust Config

This moves the configuration variables from the `.env` file to a new `bewcloud.config.ts` file. Note that DB connection and secrets are still in the `.env` file.

This will allow for more reliable and easier personalized configurations, and was a requirement to start working on adding SSO (#13).

For now, `.env`-based config will still be allowed and respected (overriden by `bewcloud.config.ts`), but in the future I'll probably remove it (some major upgrade).

* Update deploy script to also copy the new config file
2025-05-25 15:48:53 +01:00

74 lines
2.6 KiB
TypeScript

import { Handlers, PageProps } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState, SupportedCurrencySymbol } from '/lib/types.ts';
import { AppConfig } from '/lib/config.ts';
import { BudgetModel, ExpenseModel, generateMonthlyBudgetsAndExpenses } from '/lib/models/expenses.ts';
import ExpensesWrapper from '/islands/expenses/ExpensesWrapper.tsx';
interface Data {
userBudgets: Budget[];
userExpenses: Expense[];
initialMonth: string;
currency: SupportedCurrencySymbol;
}
export const handler: Handlers<Data, FreshContextState> = {
async GET(request, context) {
if (!context.state.user) {
return new Response('Redirect', { status: 303, headers: { 'Location': `/login` } });
}
if (!(await AppConfig.isAppEnabled('expenses'))) {
return new Response('Redirect', { status: 303, headers: { 'Location': `/files` } });
}
const searchParams = new URL(request.url).searchParams;
let initialMonth = searchParams.get('month') || new Date().toISOString().substring(0, 7);
const currentMonth = new Date().toISOString().substring(0, 7);
const nextMonth = new Date(new Date(currentMonth).setUTCMonth(new Date(currentMonth).getUTCMonth() + 1))
.toISOString()
.substring(0, 7);
// Send invalid months (format) back to current month
if (!initialMonth.match(/^\d{4}-\d{2}$/)) {
initialMonth = currentMonth;
}
// Reset to next month if the selected month is too far in the future
if (initialMonth > nextMonth) {
initialMonth = nextMonth;
}
let userBudgets = await BudgetModel.list(context.state.user.id, initialMonth);
let userExpenses = await ExpenseModel.list(context.state.user.id, initialMonth);
// If there are no budgets or expenses, and the selected month is in the future, generate the month's budgets and expenses
if (userBudgets.length === 0 && userExpenses.length === 0 && initialMonth >= currentMonth) {
await generateMonthlyBudgetsAndExpenses(context.state.user.id, initialMonth);
userBudgets = await BudgetModel.list(context.state.user.id, initialMonth);
userExpenses = await ExpenseModel.list(context.state.user.id, initialMonth);
}
const currency = context.state.user.extra.expenses_currency || '$';
return await context.render({ userBudgets, userExpenses, initialMonth, currency });
},
};
export default function ExpensesPage({ data }: PageProps<Data, FreshContextState>) {
return (
<main>
<ExpensesWrapper
initialBudgets={data.userBudgets}
initialExpenses={data.userExpenses}
initialMonth={data.initialMonth}
currency={data.currency}
/>
</main>
);
}