코딩/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