Files
sam-react-prod/src/components/hr/OrgChart/UnassignedPanel.tsx
유병철 00ac954fa7 feat: [HR] 조직도 페이지 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:30:21 +09:00

84 lines
2.8 KiB
TypeScript

'use client';
import { useState } from 'react';
import { useDroppable } from '@dnd-kit/core';
import { Search, UserX } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { EmployeeCard } from './EmployeeCard';
import type { OrgEmployee } from './types';
interface UnassignedPanelProps {
employees: OrgEmployee[];
onAssignClick: (employee: OrgEmployee) => void;
}
export function UnassignedPanel({ employees, onAssignClick }: UnassignedPanelProps) {
const [searchQuery, setSearchQuery] = useState('');
const { setNodeRef, isOver } = useDroppable({
id: 'unassigned-zone',
data: { type: 'unassigned-zone' },
});
const filtered = searchQuery.trim()
? employees.filter((e) => {
const q = searchQuery.toLowerCase();
return (
e.displayName.toLowerCase().includes(q) ||
(e.positionLabel && e.positionLabel.toLowerCase().includes(q))
);
})
: employees;
return (
<div
ref={setNodeRef}
className={cn(
'w-full md:w-72 shrink-0 flex flex-col border rounded-lg bg-white transition-colors h-full',
isOver && 'bg-orange-50 ring-2 ring-orange-300',
)}
>
<div className="p-2 md:p-3 border-b">
<div className="flex items-center gap-2 mb-1.5 md:mb-2">
<UserX className="h-4 w-4 text-orange-500 shrink-0" />
<span className="font-semibold text-xs md:text-sm"> </span>
<span className="text-[10px] md:text-xs text-muted-foreground ml-auto">{employees.length}</span>
</div>
<div className="relative">
<Search className="absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
<Input
placeholder="이름, 직급 검색..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="h-7 md:h-8 pl-7 md:pl-8 text-xs md:text-sm"
/>
</div>
</div>
<div className="flex-1 min-h-0">
<ScrollArea className="h-full">
<div className="p-1.5 md:p-2 space-y-1">
{filtered.length > 0 ? (
filtered.map((emp) => (
<EmployeeCard
key={emp.id}
employee={emp}
sourceDeptId={null}
showAssignButton
onAssignClick={onAssignClick}
/>
))
) : (
<div className="text-center text-xs md:text-sm text-muted-foreground py-6 md:py-8">
{searchQuery ? '검색 결과가 없습니다' : '미배치 직원이 없습니다'}
</div>
)}
</div>
</ScrollArea>
</div>
</div>
);
}