코딩/Next.js
Next.js를 알아보자 - Customers 페이지
김기지
2024. 5. 14. 19:33
공식문서 따라하기 그 이후..
customer 페이지를 완성해보자!
1. Customer 데이터 받아오기
data.ts 파일에는 2개의 고객 정보 요청 함수가 작성되어 있다.
export async function fetchCustomers() {
noStore();
try {
const data = await sql<CustomerField>`
SELECT
id,
name
FROM customers
ORDER BY name ASC
`;
const customers = data.rows;
return customers;
} catch (err) {
console.error('Database Error:', err);
throw new Error('Failed to fetch all customers.');
}
}
export async function fetchFilteredCustomers(query: string) {
noStore();
try {
const data = await sql<CustomersTableType>`
SELECT
customers.id,
customers.name,
customers.email,
customers.image_url,
COUNT(invoices.id) AS total_invoices,
SUM(CASE WHEN invoices.status = 'pending' THEN invoices.amount ELSE 0 END) AS total_pending,
SUM(CASE WHEN invoices.status = 'paid' THEN invoices.amount ELSE 0 END) AS total_paid
FROM customers
LEFT JOIN invoices ON customers.id = invoices.customer_id
WHERE
customers.name ILIKE ${`%${query}%`} OR
customers.email ILIKE ${`%${query}%`}
GROUP BY customers.id, customers.name, customers.email, customers.image_url
ORDER BY customers.name ASC
`;
const customers = data.rows.map((customer) => ({
...customer,
total_pending: formatCurrency(customer.total_pending),
total_paid: formatCurrency(customer.total_paid),
}));
return customers;
} catch (err) {
console.error('Database Error:', err);
throw new Error('Failed to fetch customer table.');
}
}
여기서 CustomersTable 컴포넌트에 필요한 데이터를 보면
export type FormattedCustomersTable = {
id: string;
name: string;
email: string;
image_url: string;
total_invoices: number;
total_pending: string;
total_paid: string;
};
fetchFilteredCustomers함수를 사용해야 필요한 데이터를 모두 받아올 수 있다.
fetchFilteredCustomers 함수는 query를 인자로 받는다.
여기서는 전체 데이터를 요청해야 하기 때문에 빈 문자열을 전달해 모든 데이터를 받아온다.
export default async function Page() {
const allCustomers = await fetchFilteredCustomers('');
// 빈문자열을 전달해 모든 데이터를 가져오기
return (
<div>
<CustomersTable customers={allCustomers} />
</div>
);
}
2. Customer 검색 기능 추가하기
기존에 구현한 Search를 사용했기 때문에 검색어와 URL 쿼리가 연동되는 작업은 되어있다.
따라서 URL 쿼리를 받아와 fetchFilteredCustomers의 인자로 보내 필터링된 데이터를 받아온다.
export default async function Page({
searchParams,
}: {
searchParams?: {
query?: string;
};
}) {
const query = searchParams?.query || '';
const allCustomers = await fetchFilteredCustomers(query);
return (
<div>
<CustomersTable customers={allCustomers} />
</div>
);
}
searchParams가 존재하지 않을 때는 빈 문자열을 전달해 모든 데이터를 요청하고
searchParams가 존재할 때는 해당 쿼리를 전달해 쿼리와 일치하는 데이터를 요청한다.
728x90