First Commit

This commit is contained in:
2026-04-29 09:52:29 +03:00
parent 9d41fe63af
commit a9249842a5
55 changed files with 359 additions and 97 deletions
+38 -26
View File
@@ -1,29 +1,31 @@
import postgres from 'postgres';
import { sql } from '@vercel/postgres';
import {
CustomerField,
CustomersTableType,
CustomersTable,
InvoiceForm,
InvoicesTable,
LatestInvoiceRaw,
User,
Revenue,
} from './definitions';
import { formatCurrency } from './utils';
const sql = postgres(process.env.POSTGRES_URL!, { ssl: 'require' });
export async function fetchRevenue() {
// Add noStore() here prevent the response from being cached.
// This is equivalent to in fetch(..., {cache: 'no-store'}).
try {
// Artificially delay a response for demo purposes.
// Don't do this in production :)
// Artificially delay a reponse for demo purposes.
// Don't do this in real life :)
// console.log('Fetching revenue data...');
// await new Promise((resolve) => setTimeout(resolve, 3000));
const data = await sql<Revenue[]>`SELECT * FROM revenue`;
const data = await sql<Revenue>`SELECT * FROM revenue`;
// console.log('Data fetch completed after 3 seconds.');
// console.log('Data fetch complete after 3 seconds.');
return data;
return data.rows;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch revenue data.');
@@ -32,14 +34,14 @@ export async function fetchRevenue() {
export async function fetchLatestInvoices() {
try {
const data = await sql<LatestInvoiceRaw[]>`
const data = await sql<LatestInvoiceRaw>`
SELECT invoices.amount, customers.name, customers.image_url, customers.email, invoices.id
FROM invoices
JOIN customers ON invoices.customer_id = customers.id
ORDER BY invoices.date DESC
LIMIT 5`;
const latestInvoices = data.map((invoice) => ({
const latestInvoices = data.rows.map((invoice) => ({
...invoice,
amount: formatCurrency(invoice.amount),
}));
@@ -68,10 +70,10 @@ export async function fetchCardData() {
invoiceStatusPromise,
]);
const numberOfInvoices = Number(data[0][0].count ?? '0');
const numberOfCustomers = Number(data[1][0].count ?? '0');
const totalPaidInvoices = formatCurrency(data[2][0].paid ?? '0');
const totalPendingInvoices = formatCurrency(data[2][0].pending ?? '0');
const numberOfInvoices = Number(data[0].rows[0].count ?? '0');
const numberOfCustomers = Number(data[1].rows[0].count ?? '0');
const totalPaidInvoices = formatCurrency(data[2].rows[0].paid ?? '0');
const totalPendingInvoices = formatCurrency(data[2].rows[0].pending ?? '0');
return {
numberOfCustomers,
@@ -81,7 +83,7 @@ export async function fetchCardData() {
};
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch card data.');
throw new Error('Failed to card data.');
}
}
@@ -93,7 +95,7 @@ export async function fetchFilteredInvoices(
const offset = (currentPage - 1) * ITEMS_PER_PAGE;
try {
const invoices = await sql<InvoicesTable[]>`
const invoices = await sql<InvoicesTable>`
SELECT
invoices.id,
invoices.amount,
@@ -114,7 +116,7 @@ export async function fetchFilteredInvoices(
LIMIT ${ITEMS_PER_PAGE} OFFSET ${offset}
`;
return invoices;
return invoices.rows;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch invoices.');
@@ -123,7 +125,7 @@ export async function fetchFilteredInvoices(
export async function fetchInvoicesPages(query: string) {
try {
const data = await sql`SELECT COUNT(*)
const count = await sql`SELECT COUNT(*)
FROM invoices
JOIN customers ON invoices.customer_id = customers.id
WHERE
@@ -134,7 +136,7 @@ export async function fetchInvoicesPages(query: string) {
invoices.status ILIKE ${`%${query}%`}
`;
const totalPages = Math.ceil(Number(data[0].count) / ITEMS_PER_PAGE);
const totalPages = Math.ceil(Number(count.rows[0].count) / ITEMS_PER_PAGE);
return totalPages;
} catch (error) {
console.error('Database Error:', error);
@@ -144,7 +146,7 @@ export async function fetchInvoicesPages(query: string) {
export async function fetchInvoiceById(id: string) {
try {
const data = await sql<InvoiceForm[]>`
const data = await sql<InvoiceForm>`
SELECT
invoices.id,
invoices.customer_id,
@@ -154,7 +156,7 @@ export async function fetchInvoiceById(id: string) {
WHERE invoices.id = ${id};
`;
const invoice = data.map((invoice) => ({
const invoice = data.rows.map((invoice) => ({
...invoice,
// Convert amount from cents to dollars
amount: invoice.amount / 100,
@@ -163,13 +165,12 @@ export async function fetchInvoiceById(id: string) {
return invoice[0];
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch invoice.');
}
}
export async function fetchCustomers() {
try {
const customers = await sql<CustomerField[]>`
const data = await sql<CustomerField>`
SELECT
id,
name
@@ -177,6 +178,7 @@ export async function fetchCustomers() {
ORDER BY name ASC
`;
const customers = data.rows;
return customers;
} catch (err) {
console.error('Database Error:', err);
@@ -186,7 +188,7 @@ export async function fetchCustomers() {
export async function fetchFilteredCustomers(query: string) {
try {
const data = await sql<CustomersTableType[]>`
const data = await sql<CustomersTable>`
SELECT
customers.id,
customers.name,
@@ -204,7 +206,7 @@ export async function fetchFilteredCustomers(query: string) {
ORDER BY customers.name ASC
`;
const customers = data.map((customer) => ({
const customers = data.rows.map((customer) => ({
...customer,
total_pending: formatCurrency(customer.total_pending),
total_paid: formatCurrency(customer.total_paid),
@@ -216,3 +218,13 @@ export async function fetchFilteredCustomers(query: string) {
throw new Error('Failed to fetch customer table.');
}
}
export async function getUser(email: string) {
try {
const user = await sql`SELECT * from USERS where email=${email}`;
return user.rows[0] as User;
} catch (error) {
console.error('Failed to fetch user:', error);
throw new Error('Failed to fetch user.');
}
}