Files
sam-react-prod/src/components/hr/EmployeeManagement/UserInviteDialog.tsx
byeongcheolryu 48dbba0e5f feat: 단가관리 페이지 마이그레이션 및 HR 관리 기능 추가
## 단가관리 (Pricing Management)
- 단가 목록 페이지 (IntegratedListTemplateV2 공통 템플릿 적용)
- 단가 등록/수정 폼 (원가/마진 자동 계산)
- 이력 조회, 수정 이력, 최종 확정 다이얼로그
- 판매관리 > 단가관리 네비게이션 메뉴 추가

## HR 관리 (Human Resources)
- 사원관리 (목록, 등록, 수정, 상세, CSV 업로드)
- 부서관리 (트리 구조)
- 근태관리 (기본 구조)

## 품목관리 개선
- Radix UI Select controlled mode 버그 수정 (key prop 적용)
- DynamicItemForm 파일 업로드 지원
- 수정 페이지 데이터 로딩 개선

## 문서화
- 단가관리 마이그레이션 체크리스트
- HR 관리 구현 체크리스트
- Radix UI Select 버그 수정 가이드

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 11:36:38 +09:00

116 lines
3.4 KiB
TypeScript

'use client';
import { useState } from 'react';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import type { UserRole } from './types';
import { USER_ROLE_LABELS } from './types';
interface UserInviteDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onInvite: (data: { email: string; role: UserRole; message?: string }) => void;
}
export function UserInviteDialog({ open, onOpenChange, onInvite }: UserInviteDialogProps) {
const [email, setEmail] = useState('');
const [role, setRole] = useState<UserRole>('user');
const [message, setMessage] = useState('');
const handleSubmit = () => {
if (!email) return;
onInvite({ email, role, message: message || undefined });
// Reset form
setEmail('');
setRole('user');
setMessage('');
};
const handleCancel = () => {
setEmail('');
setRole('user');
setMessage('');
onOpenChange(false);
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle> </DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
{/* 이메일 주소 */}
<div className="space-y-2">
<Label htmlFor="invite-email"> </Label>
<Input
id="invite-email"
type="email"
placeholder="이메일"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
{/* 권한 */}
<div className="space-y-2">
<Label htmlFor="invite-role"></Label>
<Select value={role} onValueChange={(value) => setRole(value as UserRole)}>
<SelectTrigger id="invite-role">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="admin">{USER_ROLE_LABELS.admin}</SelectItem>
<SelectItem value="manager">{USER_ROLE_LABELS.manager}</SelectItem>
<SelectItem value="user">{USER_ROLE_LABELS.user}</SelectItem>
</SelectContent>
</Select>
</div>
{/* 초대 메시지 (선택) */}
<div className="space-y-2">
<Label htmlFor="invite-message"> ()</Label>
<Textarea
id="invite-message"
placeholder="초대 메시지를 입력해주세요."
value={message}
onChange={(e) => setMessage(e.target.value)}
rows={4}
/>
</div>
</div>
{/* 버튼 */}
<div className="flex justify-end gap-2">
<Button variant="outline" onClick={handleCancel}>
</Button>
<Button
onClick={handleSubmit}
disabled={!email}
className="bg-black hover:bg-black/90 text-white"
>
</Button>
</div>
</DialogContent>
</Dialog>
);
}