'use client' import { useEffect, useState } from 'react' import { useSession } from 'next-auth/react' interface EmailAccount { id: number email_address: string quota_mb: number used_mb?: number forward_to?: string auto_reply?: string is_active: boolean created_at: string updated_at: string } interface EmailAccountsTabProps { employeeId: number // Phase 2.4: 員工主要身份資訊 primaryIdentity?: { email_domain: string business_unit_name: string email_quota_mb: number } } export default function EmailAccountsTab({ employeeId, primaryIdentity }: EmailAccountsTabProps) { const { data: session } = useSession() const [emailAccounts, setEmailAccounts] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [showAddForm, setShowAddForm] = useState(false) // Phase 2.4: 根據主要身份設定預設網域和配額 const defaultDomain = primaryIdentity?.email_domain || 'porscheworld.tw' const defaultQuota = primaryIdentity?.email_quota_mb || 2048 const [newEmail, setNewEmail] = useState({ emailPrefix: '', domain: defaultDomain, quota_mb: defaultQuota, }) useEffect(() => { fetchEmailAccounts() }, [employeeId]) const fetchEmailAccounts = async () => { try { setLoading(true) setError(null) const response = await fetch( `${process.env.NEXT_PUBLIC_API_BASE_URL}/email-accounts/?employee_id=${employeeId}` ) if (!response.ok) { throw new Error('無法載入郵件帳號') } const data = await response.json() setEmailAccounts(data.items || []) } catch (err) { setError(err instanceof Error ? err.message : '載入失敗') } finally { setLoading(false) } } const handleCreateEmailAccount = async (e: React.FormEvent) => { e.preventDefault() if (!newEmail.emailPrefix.trim()) { alert('請輸入郵件帳號') return } try { const emailAddress = `${newEmail.emailPrefix}@${newEmail.domain}` const response = await fetch( `${process.env.NEXT_PUBLIC_API_BASE_URL}/email-accounts/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ employee_id: employeeId, email_address: emailAddress, quota_mb: newEmail.quota_mb, }), } ) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.detail || '創建郵件帳號失敗') } alert('郵件帳號創建成功!') setShowAddForm(false) setNewEmail({ emailPrefix: '', domain: 'porscheworld.tw', quota_mb: 2048 }) fetchEmailAccounts() } catch (err) { alert(err instanceof Error ? err.message : '操作失敗') } } const handleToggleActive = async (accountId: number, currentStatus: boolean) => { if (!confirm(`確定要${currentStatus ? '停用' : '啟用'}此郵件帳號嗎?`)) { return } try { const response = await fetch( `${process.env.NEXT_PUBLIC_API_BASE_URL}/email-accounts/${accountId}`, { method: currentStatus ? 'DELETE' : 'PUT', headers: { 'Content-Type': 'application/json', }, body: !currentStatus ? JSON.stringify({ is_active: true }) : undefined, } ) if (!response.ok) { throw new Error('操作失敗') } alert(`郵件帳號已${currentStatus ? '停用' : '啟用'}`) fetchEmailAccounts() } catch (err) { alert(err instanceof Error ? err.message : '操作失敗') } } const formatQuotaUsage = (used: number, total: number) => { const percentage = (used / total) * 100 return { percentage: Math.round(percentage), usedGB: (used / 1024).toFixed(2), totalGB: (total / 1024).toFixed(2), } } if (loading) { return (
載入中...
) } if (error) { return (
{error}
) } return (
{/* 標題與新增按鈕 */}

郵件帳號列表

{/* 新增表單 */} {showAddForm && (

新增郵件帳號

setNewEmail({ ...newEmail, emailPrefix: e.target.value }) } placeholder="例如: john.doe" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" required /> @
{primaryIdentity && newEmail.domain !== primaryIdentity.email_domain && (

⚠️ 注意:您選擇的網域與員工所屬事業部不同

)}
)} {/* 郵件帳號列表 */} {emailAccounts.length === 0 ? (

此員工尚未建立任何郵件帳號

點擊上方「新增郵件帳號」按鈕來創建

) : (
{emailAccounts.map((account) => { const quotaInfo = account.used_mb ? formatQuotaUsage(account.used_mb, account.quota_mb) : null return (
{/* 郵件地址 */}

{account.email_address}

{account.is_active ? '啟用' : '停用'}
{/* 配額資訊 */}
儲存空間 {quotaInfo ? `${quotaInfo.usedGB} / ${quotaInfo.totalGB} GB (${quotaInfo.percentage}%)` : `${(account.quota_mb / 1024).toFixed(2)} GB`}
{quotaInfo && (
= 90 ? 'bg-red-600' : quotaInfo.percentage >= 80 ? 'bg-yellow-600' : 'bg-green-600' }`} style={{ width: `${quotaInfo.percentage}%` }} />
)}
{/* 轉寄與自動回覆 */} {account.forward_to && (
轉寄: {account.forward_to}
)} {account.auto_reply && (
自動回覆: 已啟用
)} {/* 時間戳 */}
建立時間:{' '} {new Date(account.created_at).toLocaleString('zh-TW')}
{/* 操作按鈕 */}
) })}
)} {/* WebMail 連結提示 */}

📧 WebMail 登入說明

員工可使用 Keycloak SSO 登入{' '} WebMail ,系統會自動載入所有啟用的郵件帳號並支援多帳號切換。

⚠️ 注意:員工無法自行新增郵件帳號,所有帳號必須由 HR 透過此系統授予。

) }