'use client' import { useState, useEffect } from 'react' import apiClient from '@/lib/api-client' import AlertDialog from '@/components/ui/AlertDialog' interface SystemFunction { id?: number code: string name: string function_type: number upper_function_id: number order: number function_icon: string module_code: string | null module_functions: string[] description: string is_mana: boolean is_active: boolean edit_by: number } interface Props { function: SystemFunction | null onClose: () => void onSave: (isEdit: boolean) => void } const AVAILABLE_OPERATIONS = [ { value: 'View', label: 'View' }, { value: 'Create', label: 'Create' }, { value: 'Read', label: 'Read' }, { value: 'Update', label: 'Update' }, { value: 'Delete', label: 'Delete' }, { value: 'Print', label: 'Print' }, { value: 'File', label: 'File' }, ] export default function FunctionFormModal({ function: editingFunction, onClose, onSave }: Props) { const [formData, setFormData] = useState({ code: '', name: '', function_type: 2, upper_function_id: 0, order: 10, function_icon: '', module_code: null, module_functions: [], description: '', is_mana: false, is_active: true, edit_by: 1, }) const [parentFunctions, setParentFunctions] = useState([]) const [loading, setLoading] = useState(false) // 對話框狀態 const [alertDialog, setAlertDialog] = useState<{ isOpen: boolean title: string message: string type: 'info' | 'warning' | 'error' | 'success' }>({ isOpen: false, title: '', message: '', type: 'info', }) // 載入上層功能選項 (只顯示 function_type=1 的 NODE) useEffect(() => { const loadParentFunctions = async () => { try { const response: any = await apiClient.get('/system-functions?function_type=1&page_size=100') setParentFunctions(response.items || []) } catch (error) { console.error('Failed to load parent functions:', error) } } loadParentFunctions() }, []) // 如果是編輯模式,填入現有資料 useEffect(() => { if (editingFunction) { setFormData(editingFunction) } }, [editingFunction]) const handleChange = (field: keyof SystemFunction, value: any) => { setFormData(prev => ({ ...prev, [field]: value })) } const handleOperationToggle = (operation: string) => { const currentOperations = formData.module_functions || [] const newOperations = currentOperations.includes(operation) ? currentOperations.filter(op => op !== operation) : [...currentOperations, operation] setFormData(prev => ({ ...prev, module_functions: newOperations })) } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setLoading(true) try { // 驗證 if (!formData.code || !formData.name) { setAlertDialog({ isOpen: true, title: '欄位驗證', message: '請填寫功能代碼和名稱', type: 'warning', }) setLoading(false) return } if (formData.function_type === 2 && !formData.module_code) { setAlertDialog({ isOpen: true, title: '欄位驗證', message: 'FUNCTION 類型需要填寫模組代碼', type: 'warning', }) setLoading(false) return } // 準備資料 const submitData = { ...formData, module_code: formData.function_type === 1 ? null : formData.module_code, module_functions: formData.function_type === 1 ? [] : formData.module_functions, } const isEdit = !!editingFunction if (isEdit) { // 更新 await apiClient.put(`/system-functions/${editingFunction.id}`, submitData) } else { // 新增 await apiClient.post('/system-functions', submitData) } onSave(isEdit) onClose() } catch (error: any) { console.error('Failed to save function:', error) setAlertDialog({ isOpen: true, title: '儲存失敗', message: error.response?.data?.detail || '儲存失敗,請稍後再試', type: 'error', }) } finally { setLoading(false) } } return (
e.stopPropagation()} > {/* Card Header */}

{formData.name || '系統功能'} - {editingFunction ? '編輯作業' : '新增作業'}

{/* Card Body - Scrollable */}
{/* Row 1: 功能代碼 + 功能名稱 */}
handleChange('code', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm text-gray-900 placeholder:text-gray-500" placeholder="例如: dashboard" required />
handleChange('name', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm text-gray-900 placeholder:text-gray-500" placeholder="例如: 系統首頁" required />
{/* Row 2: 功能類型 + 上層功能 */}
{/* Row 3: 順序 + Emoji 圖示 */}
handleChange('order', parseInt(e.target.value))} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm text-gray-900 placeholder:text-gray-500" min={1} required />
handleChange('function_icon', e.target.value)} className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm text-gray-900 placeholder:text-gray-500" placeholder="📊" /> {formData.function_icon && ( {formData.function_icon} )}
{/* Row 4: 模組代碼 (只在 FUNCTION 時顯示) */} {formData.function_type === 2 && (
handleChange('module_code', e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm text-gray-900 placeholder:text-gray-500" placeholder="例如: dashboard" required />
)} {/* 模組操作權限 (橫置) */} {formData.function_type === 2 && (
{AVAILABLE_OPERATIONS.map(op => ( ))}
)} {/* 說明 */}