사이트를 임시 오픈하고 신청서를 받기 시작했다. 문제는 관리자 페이지였다.
처음엔 아래처럼 생각했는데 내 사이트가 소규모도 아니고 초소규모일 것 같은데 그냥 한 페이지에 퉁쳐버릴까? 라고 생각했는데 역시 안되겠다.
여하튼 지금 결제 요청서랑 결제 건은 쌓여만 가고 있다. 관리자가 시급하다~! 라이브러리의 힘으로 빨리 구현해보자.
관리자 페이지에 제격인 라이브러리라고 생각한다. Next.js 13 이상(App Router)으로 진행해 본다.
npm install ag-grid-react
블로그에서 본 걸로는 ag-grid-react랑 ag-grid-community를 같이 깔고 이 두 lib의 버전이 동일해야만 한다고 한다.
마지막에 시도했을 때는 layout.tsx에 css 파일 2개 import만하는 거였는데 그 사이 변화가 생긴 듯 하다. (https://velog.io/@jinvicky/cms-update-240912)
AG Grid: error #239 Theming API and CSS File Themes are both used in the same page. In v33 we released the Theming API as the new default method of styling the grid. See the migration docs https://www.ag-grid.com/react-data-grid/theming-migration/. Because no value was provided to the
theme
grid option it defaulted to themeQuartz. But the file (ag-grid.css) is also included and will cause styling issues. Either pass the string "legacy" to the theme grid option to use v32 style themes, or remove ag-grid.css from the page to use Theming API.
아래 css import를 주석처리하고 ModuleRegistry
로 등록을 추가하면서 에러를 해결했다.
ModuleRegistry
를 전역으로 1번만 등록하고 싶었는데 layout.tsx
에 등록하는 것으로 해결하지 못했다.
사용 페이지별로 아래 코드를 추가한다.
// 이거 이제 안 쓰는 듯.
// import "ag-grid-community/styles/ag-grid.css";
// import "ag-grid-community/styles/ag-theme-alpine.css";
import { AllCommunityModule, ModuleRegistry } from 'ag-grid-community';
ModuleRegistry.registerModules([AllCommunityModule]);
참고 👉 https://www.ag-grid.com/react-data-grid/modules/
mui를 사용할 수도 있지만 코드 라인 수와 간편함이 차원이 다르다:)
상위 서버 컴포넌트에서 데이터를 fetch하고 하위 클라이언트 컴포넌트에 rowData를 뿌려준다. 서버 컴포넌트라서 컴포넌트 자체에 async
를 추가할 수 있다.
CommissionApplyListPage.tsx
import CommissionApplyList from "./CommissionApplyList";
const CommissionApplyListPage = async () => {
const resp = await fetch(process.env.NEXT_DOMAIN_URL + "/api/commission/apply");
const data = await resp.json() as ApiResult<CommissionApply[]>;
return <>
<CommissionApplyList rowData={data.data} />
</>
};
export default CommissionApplyListPage;
CommissionApplyList.tsx
"use client";
import React, { useState } from "react";
import Link from "next/link";
import { AllCommunityModule, ModuleRegistry } from 'ag-grid-community';
import { AgGridReact } from "ag-grid-react";
import { ColDef } from "ag-grid-community";
ModuleRegistry.registerModules([AllCommunityModule]);
interface CommissionApplyListProps {
rowData: CommissionApply[];
}
const CommissionApplyList = ({ rowData }: CommissionApplyListProps) => {
const agGridReactRef = React.useRef<AgGridReact>(null);
const [columnDefs] = useState<ColDef[]>([
{
field: "id",
checkboxSelection: true,
cellRenderer: (params: any) => (
<Link href={`/commission/apply/${params.data.id}`}>{params.value}</Link>
),
},
{ field: "userName" },
{ field: "userEmail" },
{
field: "title",
cellRenderer: (params: any) => (
<Link href={`/commission/apply/${params.data.id}`}>{params.value}</Link>
),
},
{ field: "status" },
{ field: "rgtrDt" }
]);
const gridOptions = {
columnDefs: columnDefs,
pagination: true,
paginationPageSize: 10,
};
const handleSelected = () => {
if (agGridReactRef.current) {
const selectedNodes = agGridReactRef.current.api.getSelectedNodes();
const selectedData = selectedNodes.map((node) => node.data);
console.log(selectedData);
}
}
return (
<div>
<div className="ag-theme-alpine" style={{ height: '600px', width: '100%' }}>
<AgGridReact
ref={agGridReactRef}
rowData={rowData}
columnDefs={columnDefs}
pagination={gridOptions.pagination}
paginationPageSize={gridOptions.paginationPageSize}
rowSelection={'multiple'}
/>
</div>
<div className="p-4">
<button
onClick={handleSelected}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
삭제하기
</button>
</div>
</div>
);
};
export default CommissionApplyList;
field
는 데이터의 key값과 일치해야 한다. renderer
에 정의한다. rowSelection
은 다중 row 선택을 가능케 하며, checkboxSelection
을 true
로 하면 체크박스가 생성된다. handleSelected
함수를 참고하면 체크된 rowData들을 useRef
로 얻어올 수 있다. 나는 다중 삭제에 적용해볼 예정이다. ag-grid 기본 정리 굿굿 https://jforj.tistory.com/255