Merge branch 'iipbs/common/main' into iipbs/sn/dev

This commit is contained in:
swcho
2025-06-23 20:26:35 +09:00
8 changed files with 85 additions and 30 deletions
@@ -1,7 +1,7 @@
"use client"
import { Pie, PieChart } from "recharts";
import type { CSSProperties } from "react";
import { Pie, PieChart } from "recharts";
import {
Card,
CardContent
@@ -99,7 +99,7 @@ const CustomLegend = (props: LegendProps) => {
};
export default function DoughnutChart(props: {
chartConfig: ChartConfig;
chartConfig: any;
chartData: ChartDataItem[] | undefined;
chartTitle: string
}) {
@@ -12,37 +12,39 @@ import { FormControl } from "../form";
import { ko } from "date-fns/locale";
import { useState } from "react";
type DatePickerProps = DayPickerSingleProps & { field: { value: Date; onChange: (date: Date | undefined) => void } ,selectClass:string|undefined };
export function DatePicker({ field, selectClass }: DatePickerProps) {
type DatePickerProps = DayPickerSingleProps & { field: { value: Date; onChange: (date: Date | undefined) => void }, selectClass: string | undefined, readOnly?: boolean };
export function DatePicker({ field, selectClass, readOnly = false, ...props }: DatePickerProps) {
const [open, setOpen] = useState(false);
const handleSelect = (date: Date | undefined) => {
field.onChange(date); // React Hook Form 업데이트
setOpen(false);
};
if (!readOnly) { // readOnly가 아닐 때만 변경 허용
field.onChange(date); // React Hook Form 업데이트
setOpen(false);
}
};
return (
<Popover open={open} onOpenChange={setOpen}>
<Popover open={open && !readOnly} onOpenChange={readOnly ? undefined : setOpen}>
<PopoverTrigger asChild>
<FormControl>
<Button
color="white"
variant={"outline"}
className={!selectClass? cn(
disabled={readOnly} // readOnly일 때 버튼 비활성화
className={!selectClass ? cn(
"w-[240px] pl-3 text-left font-normal",
!field?.value && "text-muted-foreground",
):selectClass}
readOnly && "opacity-60 cursor-not-allowed" // readOnly 스타일 추가
) : cn(selectClass, readOnly && "opacity-60 cursor-not-allowed")}
>
{field?.value ? (
format(
field.value instanceof Date && !isNaN(field.value.getTime())
? field.value
: new Date()
? field.value
: new Date()
, "PPP", { locale: ko })
) : (
<span>Pick a date</span>
@@ -3,7 +3,7 @@ import { CloudUpload, Paperclip } from "lucide-react";
import { FileInput, FileUploader, FileUploaderContent, FileUploaderItem } from "./lib/file_upload";
const dropZoneConfig = {
maxFiles: 5,
maxSize: 1024 * 1024 * 4,
maxSize: 1024 * 1024 * 100,
multiple: true,
};
@@ -12,12 +12,18 @@ const dropZoneConfig = {
files: File[]; // 파일 배열
setFiles: (files: File[] | null) => void; // 파일 배열 세터
fileTypes?: string; // 옵션 (파일 확장자 문자열)
onFileClick?:(index:number)=> void; // 파일 클릭 핸들러
onFileClick?:(index:number)=> void;
maxFiles?: number; // 파일 클릭 핸들러
}
export const FileUpload =
({ files, setFiles, fileTypes ,onFileClick}: FileUploadProps) => {
({ files, setFiles, fileTypes ,onFileClick, maxFiles}: FileUploadProps) => {
if(maxFiles){
dropZoneConfig.maxFiles = maxFiles;
if(maxFiles===1)
dropZoneConfig.multiple = false;
}
return (
<FileUploader
value={files}
@@ -19,4 +19,5 @@ export * from "./tab";
export * from "./table";
export * from "./table_div";
export * from "./title";
export * from "./sdmInsertForm";
export * from "./sdmInsertForm";
export * from "./popover_ui"
@@ -0,0 +1,23 @@
import { Popover, PopoverContent, PopoverTrigger } from "@common/components/ui";
export default function PopoverUi({
childrenTriger,
childrenBody,
bodyClassName
}: {
childrenTriger: React.ReactNode;
childrenBody: React.ReactNode;
bodyClassName:string
}) {
return (
<>
<Popover>
<PopoverTrigger>{childrenTriger}</PopoverTrigger>
<PopoverContent className={bodyClassName}>
{childrenBody}
</PopoverContent>
</Popover>
</>
);
}
@@ -60,7 +60,7 @@ const defaultValues: FormSchema = {
bznmTotNo: '',
daddr: '',
telno: '',
rgtr: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
rgtr: '',
dmdAplyPswd: '',
};
@@ -16,14 +16,15 @@ const SelectBox = React.forwardRef<
className:string,
selectArray:SelectBox1[],
onSelectValue:(val:string|number)=>void,
value?: string|number
value?: string|number,
readOnly?: boolean // readOnly 속성 추가
}
>(({ label, className, selectClass, selectArray, onSelectValue, value }, ref)=>{
>(({ label, className, selectClass, selectArray, onSelectValue, value, readOnly = false }, ref)=>{
const placeHolder = selectArray?.[0]?.text ?? "";
return (
<div className={className+" flex items-center"} ref={ref}>
{label && <Label className="w-20 text-xl text-gray-600">{label}</Label>}
{label && <Label className="whitespace-nowrap w-20 text-xl text-gray-600">{label}</Label>}
<Select onValueChange={onSelectValue} value={value !== undefined ? String(value) : undefined}>
<SelectTrigger className={selectClass?selectClass:"flex-1 p-2 border rounded"}>
<SelectValue placeholder={placeHolder} />
@@ -1,9 +1,11 @@
"use client"
import { Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components";
import { Checkbox, Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components";
import { useEffect, useState } from "react";
import { HeadMakeColSpan } from "./HeadMakeColSpan";
import UiPageNations from "./uiPageNations";
import { AlignVerticalDistributeCenterIcon, Check } from "lucide-react";
import { boolean } from "zod";
type UiTableProps = {
headName: React.ReactNode | undefined;
@@ -29,6 +31,9 @@ type UiHeadProps = {
export function UiTable({ tableData, headlist, pageSize, total, headName, children, cellClick, onPageChange, className = '', resetPageNo = false, boldArray = [] }: UiTableProps) {
const [cur, setCur] = useState<number>(1);
const [idx, setIdx] = useState<number>(-1);
const [isCheck, seIsCheck] = useState<boolean>(false);
useEffect(() => {
if (resetPageNo) {
setCur(1);
@@ -47,6 +52,7 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
setIdx(index);
}
};
return (
<>
@@ -65,7 +71,9 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
.filter((item) => item.visible != false)
.map((head) => (
head.id && head.id.length > 1 && (
boldArray.includes(index) ? <TableCell
boldArray.includes(index)
?
<TableCell
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : typeof el[head.id] === 'number' ? 'text-right' : 'text-center'} ${
cellClick && idx === index ? '!font-[1000] cursor-pointer' :
cellClick ? 'cursor-pointer' : ''
@@ -78,7 +86,8 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
: String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
</TableCell>:
</TableCell>
:
<TableCell
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : typeof el[head.id] === 'number' ? 'text-right' : 'text-center'} ${
cellClick && idx === index ? '!font-[1000] cursor-pointer' :
@@ -87,11 +96,24 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{typeof el[head.id] !== 'number'?String(el[head.id] ?? ''): String(el[head.id]).includes('.')
{typeof el[head.id] === 'boolean'
?<Checkbox
checked={el[head.id] === true}
onCheckedChange={(checked) => {
el[head.id]= checked;
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
:
typeof el[head.id] !== 'number'?
String(el[head.id] ?? ''):
String(el[head.id]).includes('.')
? String(el[head.id]).split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
: String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
).join('.')
:
String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
</TableCell>
)
))}