26 lines
4.1 KiB
TypeScript
26 lines
4.1 KiB
TypeScript
import { useId, useMemo, useState } from "react"
|
|
import { Card, CardHeader, CardTitle, CardContent, Button, Label, FilterBar, FilterBarSearch, FilterBarActions, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DataTable, useDataTable, type DataTableColumnDef, Badge, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose } from "@hm-design/ui"
|
|
import { Heading } from "./Heading"
|
|
|
|
type Row = { id: string; name: string; group: string; status: string }
|
|
const records: Row[] = [{ id: "1", name: "김한맥", group: "설계", status: "진행" }, { id: "2", name: "이한맥", group: "시공", status: "대기" }, { id: "3", name: "박한맥", group: "설계", status: "완료" }]
|
|
const columns: DataTableColumnDef<Row>[] = [{ accessorKey: "name", header: "이름" }, { accessorKey: "group", header: "부서" }, { accessorKey: "status", header: "상태" }]
|
|
export function SearchList({ title, cards = false, detail = "none" }: { title: string; cards?: boolean; detail?: "none" | "dialog" | "sheet" }) {
|
|
const [draft, setDraft] = useState("")
|
|
const [group, setGroup] = useState("all")
|
|
const [applied, setApplied] = useState({ query: "", group: "all" })
|
|
const [confirmed, setConfirmed] = useState(false)
|
|
const rows = useMemo(() => records.filter(r => r.name.includes(applied.query) && (applied.group === "all" || r.group === applied.group)), [applied])
|
|
const table = useDataTable({ columns, data: rows, getRowId: row => row.id })
|
|
const id = useId()
|
|
return <><Heading title={title} description="부서와 이름 조건은 조회할 때 적용됩니다."/><Card><CardContent><div className="grid min-w-0 gap-4"><form onSubmit={e => { e.preventDefault(); setApplied({ query: draft, group }); table.setPageIndex(0) }}><FilterBar layout="list-basic">
|
|
<Select value={group} onValueChange={setGroup}><SelectTrigger size="medium" aria-label="부서"><SelectValue/></SelectTrigger><SelectContent><SelectItem value="all">전체 부서</SelectItem><SelectItem value="설계">설계</SelectItem><SelectItem value="시공">시공</SelectItem></SelectContent></Select>
|
|
<Label htmlFor={id} className="sr-only">이름 검색</Label><FilterBarSearch id={id} value={draft} onValueChange={setDraft} placeholder="이름 검색"/>
|
|
<FilterBarActions><Button type="submit" variant="primary" appearance="solid">조회</Button><Button type="button" variant="cancel" appearance="outline" onClick={() => { setDraft(""); setGroup("all"); setApplied({ query: "", group: "all" }); table.setPageIndex(0) }}>초기화</Button></FilterBarActions>
|
|
</FilterBar></form><p role="status">조회 결과 {rows.length}건{confirmed ? " · 처리 완료" : ""}</p>
|
|
{cards ? <div className="grid gap-3">{rows.map(row => <Card key={row.id}><CardHeader><CardTitle>{row.name}</CardTitle></CardHeader><CardContent>{row.group} · <Badge variant="outline">{row.status}</Badge></CardContent></Card>)}{!rows.length && <p>조건에 맞는 업무가 없습니다.</p>}</div> : <DataTable table={table} emptyMessage="조건에 맞는 항목이 없습니다."/>}
|
|
{detail === "dialog" && <Dialog><DialogTrigger asChild><Button>결재 확인</Button></DialogTrigger><DialogContent><DialogHeader><DialogTitle>결재 확인</DialogTitle><DialogDescription>현재 조회한 결재를 승인합니다.</DialogDescription></DialogHeader><DialogFooter><DialogClose asChild><Button variant="cancel" appearance="solid">취소</Button></DialogClose><DialogClose asChild><Button onClick={() => setConfirmed(true)}>승인</Button></DialogClose></DialogFooter></DialogContent></Dialog>}
|
|
{detail === "sheet" && <Sheet><SheetTrigger asChild><Button>채용 상세</Button></SheetTrigger><SheetContent><SheetHeader><SheetTitle>채용 상세</SheetTitle><SheetDescription>공고의 상세 내용과 확인 상태입니다.</SheetDescription></SheetHeader><SheetBody>설계 부문 채용 · 서류 검토</SheetBody><SheetFooter><SheetClose asChild><Button onClick={() => setConfirmed(true)}>확인</Button></SheetClose></SheetFooter></SheetContent></Sheet>}
|
|
</div></CardContent></Card></>
|
|
}
|