mirror of
https://github.com/vercel/next-learn.git
synced 2026-06-23 12:45:51 +00:00
* Rename file and add data fetches for overview page * Rename calculations.ts to utils.ts * Update code to match course * Add temporary calculation * Fix error * Move types to data fetching file * Add error handling * Parallelize data fetches * Add skeletons * Add delayed data request * Fix ts errors * Code for chapter 8 * Fix error * Clean up * Move formatDateToLocal to utils file * Extract add invoice button * Extract edit invoice button * Extract InvoiceStatus * Use formatCurrency from utils * Misc * Use outline icon * outline! * Rename table-search to search
103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import { Invoice, Revenue, Customer } from './definitions';
|
|
|
|
export const formatCurrency = (amount: number) => {
|
|
return (amount / 100).toLocaleString('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD',
|
|
});
|
|
};
|
|
|
|
export const formatDateToLocal = (
|
|
dateStr: string,
|
|
locale: string = 'en-US',
|
|
) => {
|
|
const date = new Date(dateStr);
|
|
const options: Intl.DateTimeFormatOptions = {
|
|
day: 'numeric',
|
|
month: 'short',
|
|
year: 'numeric',
|
|
};
|
|
const formatter = new Intl.DateTimeFormat(locale, options);
|
|
return formatter.format(date);
|
|
};
|
|
|
|
export function findLatestInvoices(invoices: Invoice[], customers: Customer[]) {
|
|
// Sort the invoices by date in descending order and take the top 5
|
|
const latestInvoices = [...invoices]
|
|
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
|
|
.slice(0, 5);
|
|
|
|
// Find corresponding customers for the latest 5 invoices
|
|
const latestInvoicesWithCustomerInfo = latestInvoices.map((invoice) => {
|
|
const customer = customers.find(
|
|
(customer) => customer.id === invoice.customer_id,
|
|
);
|
|
|
|
// Format the amount to USD
|
|
const formattedAmount = invoice.amount.toLocaleString('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD',
|
|
});
|
|
|
|
return {
|
|
id: invoice.id,
|
|
name: customer?.name,
|
|
image_url: customer?.image_url,
|
|
email: customer?.email,
|
|
amount: formattedAmount,
|
|
};
|
|
});
|
|
|
|
return latestInvoicesWithCustomerInfo;
|
|
}
|
|
|
|
export const calculateInvoicesByStatus = (
|
|
invoices: Invoice[],
|
|
status: 'pending' | 'paid',
|
|
) => {
|
|
return invoices
|
|
.filter((invoice) => !status || invoice.status === status)
|
|
.reduce((total, invoice) => total + invoice.amount / 100, 0)
|
|
.toLocaleString('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD',
|
|
});
|
|
};
|
|
|
|
export const calculateCustomerInvoices = (
|
|
invoices: Invoice[],
|
|
status: 'pending' | 'paid',
|
|
customerId: number,
|
|
) => {
|
|
return invoices
|
|
.filter((invoice) => invoice.customer_id === customerId)
|
|
.filter((invoice) => !status || invoice.status === status)
|
|
.reduce((total, invoice) => total + invoice.amount / 100, 0)
|
|
.toLocaleString('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD',
|
|
});
|
|
};
|
|
|
|
export const countCustomerInvoices = (
|
|
invoices: Invoice[],
|
|
customerId: number,
|
|
) => {
|
|
return invoices.filter((invoice) => invoice.customer_id === customerId)
|
|
.length;
|
|
};
|
|
|
|
export const generateYAxis = (revenue: Revenue[]) => {
|
|
// Calculate what labels we need to display on the y-axis
|
|
// based on highest record and in 1000s
|
|
const yAxisLabels = [];
|
|
const highestRecord = Math.max(...revenue.map((month) => month.revenue));
|
|
const topLabel = Math.ceil(highestRecord / 1000) * 1000;
|
|
|
|
for (let i = topLabel; i >= 0; i -= 1000) {
|
|
yAxisLabels.push(`$${i / 1000}K`);
|
|
}
|
|
|
|
return { yAxisLabels, topLabel };
|
|
};
|