clean ui
This commit is contained in:
103
management/src/components/OrganizationSection.tsx
Normal file
103
management/src/components/OrganizationSection.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { apiAdmin, type EmailDomainItem } from '../api';
|
||||
|
||||
export function OrganizationSection() {
|
||||
const [domains, setDomains] = useState<EmailDomainItem[]>([]);
|
||||
const [newDomain, setNewDomain] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await apiAdmin.listEmailDomains();
|
||||
setDomains(res.data);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
load().catch(console.error);
|
||||
}, []);
|
||||
|
||||
const addDomain = async () => {
|
||||
if (!newDomain.trim()) return;
|
||||
setBusy(true);
|
||||
try {
|
||||
await apiAdmin.addEmailDomain(newDomain.trim());
|
||||
setNewDomain('');
|
||||
await load();
|
||||
} catch (e: any) {
|
||||
alert(e?.message || 'Không thêm được');
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
const removeDomain = async (id: number) => {
|
||||
if (!confirm('Xóa đuôi email này?')) return;
|
||||
try {
|
||||
await apiAdmin.deleteEmailDomain(id);
|
||||
await load();
|
||||
} catch (e: any) {
|
||||
alert(e?.message || 'Không xóa được');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="system-section">
|
||||
<div className="system-block">
|
||||
<div className="system-block-head">
|
||||
<div>
|
||||
<h2 className="system-block-title">Đuôi email được phép</h2>
|
||||
<p className="system-block-desc">
|
||||
Giới hạn tài khoản giáo viên / nhân sự theo tổ chức. Chưa cấu hình = chấp nhận mọi đuôi email.
|
||||
</p>
|
||||
</div>
|
||||
<span className="system-stat-pill">{domains.length} đuôi</span>
|
||||
</div>
|
||||
|
||||
<div className="system-inline-form">
|
||||
<input
|
||||
placeholder="vd: rikkeiacademy.com"
|
||||
value={newDomain}
|
||||
onChange={(e) => setNewDomain(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && addDomain()}
|
||||
/>
|
||||
<button type="button" className="btn btn-primary" onClick={addDomain} disabled={busy}>
|
||||
Thêm đuôi
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="system-empty">Đang tải...</div>
|
||||
) : domains.length === 0 ? (
|
||||
<div className="system-empty system-empty--muted">
|
||||
Chưa giới hạn đuôi email — mọi địa chỉ đều có thể đăng ký.
|
||||
</div>
|
||||
) : (
|
||||
<ul className="system-domain-list">
|
||||
{domains.map((d) => (
|
||||
<li key={d.id} className="system-domain-item">
|
||||
<span className="system-domain-label">@{d.domain}</span>
|
||||
<button type="button" className="btn btn-ghost btn-sm" onClick={() => removeDomain(d.id)}>
|
||||
Xóa
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="system-block system-block--info">
|
||||
<h3 className="system-info-title">Gợi ý</h3>
|
||||
<ul className="network-info-list">
|
||||
<li>Thêm từng đuôi email thuộc tổ chức (vd: <code>rikkei.edu.vn</code>)</li>
|
||||
<li>Sinh viên đăng nhập client không bị ảnh hưởng bởi cấu hình này</li>
|
||||
<li>Chỉ áp dụng cho tài khoản quản lý trên portal này</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user