o2o-negosium-original/negodata/front/src/features/quotations/components/QuotationDetailSheet/InfoField.tsx
Mina Choi 6fa024137f [feat] negodata: 견적·카드 검색/필터 서버사이드 전환 + 견적 상세 Sheet 리팩터
- 백엔드: quotation 목록 search 파라미터(name/number ILIKE) 추가; card 목록 is_wildcard 탭 필터 + total_nego/total_wild 탭 카운트 추가; status/type 코드 int 비교 보정
- 프론트: cards/quotation 검색·상태·유형 필터·페이지네이션을 useServerList 기반 서버사이드로 전환; 엔터 즉시검색 + 디바운스 500ms·최소 2글자; 죽은 client 필터 훅(useCardFilters/useQuotationFilters) 제거
- generated 파라미터/응답 타입 손보강(listCardsParams.is_wildcard, listQuotationsParams.search, resCardList.total_nego/total_wild) — orval 재생성 시 동일
- 견적 상세 Drawer→Sheet 분리, useOverlayParams→useOverlayRouter, CreateQuotationWizard→QuotationCreateModal

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 17:03:53 +09:00

36 lines
905 B
TypeScript

import type { ReactNode } from 'react';
import { cn } from '@/lib/utils';
type InfoFieldProps = {
label: string;
/** 단순 텍스트 값. 커스텀 마크업이 필요하면 value 대신 children 을 쓴다. */
value?: ReactNode;
children?: ReactNode;
className?: string;
labelClassName?: string;
valueClassName?: string;
title?: string;
};
/** 헤더 카드의 `라벨 / 값` 한 칸. (드로어 곳곳에서 ~20회 반복되던 패턴) */
export function InfoField({
label,
value,
children,
className,
labelClassName,
valueClassName,
title,
}: InfoFieldProps) {
return (
<div className={className}>
<span className={cn('text-[10px] block opacity-70', labelClassName)}>{label}</span>
{children ?? (
<span className={cn('text-foreground font-semibold', valueClassName)} title={title}>
{value}
</span>
)}
</div>
);
}