[style] negodata/front: 상품·카드 목록 포털형 카드(툴바+테이블 한 카드로 결합)
This commit is contained in:
parent
bcb87de35e
commit
f8f8f70f54
@ -7,11 +7,14 @@ type CardTableProps = {
|
|||||||
data: NegotiationCard[];
|
data: NegotiationCard[];
|
||||||
onEdit: (card: NegotiationCard) => void;
|
onEdit: (card: NegotiationCard) => void;
|
||||||
footer?: ReactNode;
|
footer?: ReactNode;
|
||||||
|
/** 툴바와 한 카드로 붙일 때 테이블 자체 테두리/라운드를 죽이는 용도 */
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function CardTable({ data, onEdit, footer }: CardTableProps) {
|
export function CardTable({ data, onEdit, footer, className }: CardTableProps) {
|
||||||
return (
|
return (
|
||||||
<DataTable
|
<DataTable
|
||||||
|
className={className}
|
||||||
data={data}
|
data={data}
|
||||||
rowKey={(card) => card.id}
|
rowKey={(card) => card.id}
|
||||||
onRowClick={onEdit}
|
onRowClick={onEdit}
|
||||||
|
|||||||
@ -15,6 +15,8 @@ type ProductTableProps = {
|
|||||||
totalCount: number;
|
totalCount: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
onPageChange: (page: number) => void;
|
onPageChange: (page: number) => void;
|
||||||
|
/** 툴바와 한 카드로 붙일 때 테이블 자체 테두리/라운드를 죽이는 용도 */
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ProductTable({
|
export function ProductTable({
|
||||||
@ -27,10 +29,12 @@ export function ProductTable({
|
|||||||
totalCount,
|
totalCount,
|
||||||
pageSize,
|
pageSize,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
|
className,
|
||||||
}: ProductTableProps) {
|
}: ProductTableProps) {
|
||||||
const label = useLabels(); // 회사 설정 용어(카테고리/상품 단가 등)
|
const label = useLabels(); // 회사 설정 용어(카테고리/상품 단가 등)
|
||||||
return (
|
return (
|
||||||
<DataTable
|
<DataTable
|
||||||
|
className={className}
|
||||||
data={data}
|
data={data}
|
||||||
rowKey={(prod) => prod.item_id}
|
rowKey={(prod) => prod.item_id}
|
||||||
onRowClick={onRowClick}
|
onRowClick={onRowClick}
|
||||||
@ -69,7 +73,7 @@ export function ProductTable({
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: '상품코드',
|
header: label('item.code'),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
cellClassName: 'font-mono font-medium text-muted-foreground',
|
cellClassName: 'font-mono font-medium text-muted-foreground',
|
||||||
cell: (prod) => prod.code,
|
cell: (prod) => prod.code,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { PageToolbar, SearchInput } from '@/components/layout/PageToolbar';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu';
|
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu';
|
||||||
import { TablePagination } from '@/components/ui/table-pagination';
|
import { TablePagination } from '@/components/ui/table-pagination';
|
||||||
import { Typography } from '@/components/ui/typography';
|
import { cn } from '@/lib/utils';
|
||||||
import { useServerList } from '@/lib/useServerList';
|
import { useServerList } from '@/lib/useServerList';
|
||||||
import { useCards } from '@/features/cards/hooks/useCards';
|
import { useCards } from '@/features/cards/hooks/useCards';
|
||||||
import { useGetCard } from '@/api/generated/card/card';
|
import { useGetCard } from '@/api/generated/card/card';
|
||||||
@ -62,8 +62,10 @@ export default function CardsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
{/* 플랫 툴바 — 다른 목록 페이지와 동일 문법(검색 좌측, 주버튼+⋯ 우측) */}
|
{/* 검색/액션 + 탭 + 테이블을 한 카드로 붙인다(포털형, 상품관리와 동일 문법). */}
|
||||||
|
<div className="overflow-hidden rounded-lg border border-border bg-card">
|
||||||
<PageToolbar
|
<PageToolbar
|
||||||
|
className="rounded-none border-0 border-b border-border"
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@ -99,32 +101,30 @@ export default function CardsPage() {
|
|||||||
onClear={list.clearSearch}
|
onClear={list.clearSearch}
|
||||||
placeholder="전체 카드이름, 카드번호, 코드 검색..."
|
placeholder="전체 카드이름, 카드번호, 코드 검색..."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</PageToolbar>
|
</PageToolbar>
|
||||||
|
|
||||||
{/* Primary Navigation Tab */}
|
{/* 구분 탭 — 검색/액션 바 아래, 테이블 바로 위 */}
|
||||||
<div className="flex border-b border-border">
|
<div className="flex border-b border-border px-3">
|
||||||
{tabs.map((tab) => (
|
{tabs.map((tab) => (
|
||||||
<button
|
<button
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
id={`card-tab-${tab.id.toLowerCase()}`}
|
id={`card-tab-${tab.id.toLowerCase()}`}
|
||||||
onClick={() => list.setFilter('tab', tab.id)}
|
onClick={() => list.setFilter('tab', tab.id)}
|
||||||
className={`py-2 px-6 font-bold text-xs tracking-tight border-b-2 transition-all cursor-pointer ${
|
className={cn(
|
||||||
|
'cursor-pointer border-b-2 px-6 py-2 text-xs font-bold tracking-tight transition-all',
|
||||||
activeTab === tab.id
|
activeTab === tab.id
|
||||||
? 'border-primary text-primary'
|
? 'border-primary text-primary'
|
||||||
: 'border-transparent text-muted-foreground hover:text-foreground'
|
: 'border-transparent text-muted-foreground hover:text-foreground'
|
||||||
}`}
|
)}
|
||||||
>
|
>
|
||||||
{tab.label} ({tab.count})
|
{tab.label} ({tab.count})
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 배너에 있던 공용 카드 안내는 캡션 한 줄로 유지 */}
|
|
||||||
<Typography variant="caption" className="-mt-3 block">
|
|
||||||
우리 회사 카드와 기본 제공(공용) 카드를 함께 조회합니다. 공용 카드는 수정·삭제할 수 없습니다.
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<CardTable
|
<CardTable
|
||||||
|
className="rounded-none border-0"
|
||||||
data={cards}
|
data={cards}
|
||||||
onEdit={openEdit}
|
onEdit={openEdit}
|
||||||
footer={
|
footer={
|
||||||
@ -139,6 +139,7 @@ export default function CardsPage() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{isFormOpen && (
|
{isFormOpen && (
|
||||||
<CardFormSheet
|
<CardFormSheet
|
||||||
|
|||||||
@ -91,7 +91,10 @@ export default function ProductsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
|
{/* 검색/액션 바 + 테이블을 한 카드로 붙인다(포털형). 툴바는 카드 상단 헤더, 테이블은 본문. */}
|
||||||
|
<div className="overflow-hidden rounded-lg border border-border bg-card">
|
||||||
<PageToolbar
|
<PageToolbar
|
||||||
|
className="rounded-none border-0 border-b border-border"
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
@ -166,6 +169,7 @@ export default function ProductsPage() {
|
|||||||
</PageToolbar>
|
</PageToolbar>
|
||||||
|
|
||||||
<ProductTable
|
<ProductTable
|
||||||
|
className="rounded-none border-0"
|
||||||
data={products}
|
data={products}
|
||||||
selectedIds={selectedIds}
|
selectedIds={selectedIds}
|
||||||
onSelectionChange={setSelectedIds}
|
onSelectionChange={setSelectedIds}
|
||||||
@ -176,6 +180,7 @@ export default function ProductsPage() {
|
|||||||
pageSize={list.pageSize}
|
pageSize={list.pageSize}
|
||||||
onPageChange={list.setPage}
|
onPageChange={list.setPage}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{isFormOpen && (
|
{isFormOpen && (
|
||||||
<ProductFormSheet
|
<ProductFormSheet
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user