diff --git a/src/app/faq/page.tsx b/src/app/faq/page.tsx index ede4ec7..584497a 100644 --- a/src/app/faq/page.tsx +++ b/src/app/faq/page.tsx @@ -5,37 +5,35 @@ import { useState } from 'react'; const faqData = [ { id: 1, - question: "1. Phần mềm này tương thích với những hệ điều hành nào?", - answer: "Hệ thống tương thích hoàn toàn với Windows 10/11, macOS 12 trở lên. Đối với môi trường máy chủ, chúng tôi hỗ trợ các bản phân phối Linux phổ biến như Ubuntu và Debian." + question: "1. Tôi có thể đổi mật khẩu ở đâu?", + answer: "Bạn có thể đổi mật khẩu ở mục Thông tin tài khoản ở góc dưới bên trái màn hình. Kéo xuống mục thay đổi mật khẩu và cập nhật thông tin." }, { id: 2, - question: "2. Sự khác biệt giữa phiên bản Miễn phí và Trả phí là gì?", - answer: "Phiên bản trả phí cung cấp băng thông không giới hạn, hỗ trợ kỹ thuật ưu tiên 24/7, và quyền truy cập sớm vào các tính năng nâng cao. Bản miễn phí sẽ giới hạn một số tính năng xuất dữ liệu." + question: "2. Làm sao để liên hệ với ban quản trị khi cần hỗ trợ gấp?", + answer: "Bạn có thể liên hệ với ban quản trị qua email hoặc số điện thoại được cung cấp trong mục Liên hệ hỗ trợ" }, { id: 3, - question: "3. Hệ thống hỗ trợ những phương thức kết nối nào?", - answer: "Chúng tôi hỗ trợ kết nối qua REST API, WebSocket cho dữ liệu thời gian thực và cung cấp sẵn SDK cho các ngôn ngữ phổ biến như TypeScript, Go." + question: "3. Để có thể làm kiểm duyệt viên tôi cần làm gì?", + answer: "Bạn có thể gửi yêu cầu làm Nhà sử học bằng cách truy cập vào mục Nhà Sử Học ở góc dưới bên trái màn hình. Điền đầy đủ thông tin yêu cầu và gửi cho chúng tôi. Chúng tôi sẽ xem xét và liên hệ qua email." }, { id: 4, - question: "4. Làm thế nào để tôi có thể tích hợp vào dự án Next.js hiện tại?", - answer: "Bạn chỉ cần cài đặt package qua npm/yarn, thêm API Key vào file .env và gọi component Provider ở file layout.tsx gốc. Tài liệu chi tiết có sẵn trong mục Developer Docs." + question: "4. Thời gian phản hồi khi gửi yêu cầu là bao lâu?", + answer: "Thông thường chúng tôi sẽ phản hồi yêu cầu của bạn trong vòng 24-48 giờ làm việc." }, { id: 5, - question: "5. Dữ liệu của tôi được bảo mật như thế nào?", - answer: "Toàn bộ dữ liệu được mã hóa đầu cuối (End-to-End Encryption). Chúng tôi tuân thủ nghiêm ngặt các tiêu chuẩn bảo mật quốc tế và thường xuyên rà soát hệ thống để phòng chống các lỗ hổng bảo mật." - } + question: "5. Làm gì nếu tài khoản của tôi bị khóa?", + answer: "Bạn có thể liên hệ với ban quản trị qua email hoặc số điện thoại được cung cấp trong mục Liên hệ hỗ trợ" + }, ]; export default function Page() { - // Lưu index của câu hỏi đang được mở. Mặc định mở câu đầu tiên (index 0). const [openIndex, setOpenIndex] = useState(0); const toggleFAQ = (index: number) => { - // Nếu click lại vào câu đang mở thì đóng nó, ngược lại thì mở câu mới setOpenIndex(openIndex === index ? null : index); }; @@ -62,7 +60,6 @@ export default function Page() { - {/* Phần nội dung có hiệu ứng trượt */}
(null); - const [loading, setLoading] = useState(true); + const currentUser = useSelector((state: RootState) => state.user.data); const dispatch = useDispatch(); - + + const [application, setApplication] = useState(null); + const [appLoading, setAppLoading] = useState(false); + + const isHistorian = !!currentUser?.roles?.some( + (role: any) => role.name === "HISTORIAN" + ); + + // Background refresh of user data to ensure eventual consistency useEffect(() => { const fetchUser = async () => { try { const userData = await apiGetCurrentUser(); dispatch(setUserData(userData.data)); - setUser(userData); } catch (err) { console.error("Lỗi:", err); - } finally { - setLoading(false); } }; fetchUser(); - }, []); - + }, [dispatch]); + + // Fetch applications in parallel immediately if user is a historian + useEffect(() => { + if (isHistorian) { + const fetchApp = async () => { + try { + setAppLoading(true); + const res = await apiGetCurrentUserApplications(); + if (res?.data) { + const approvedApp = + res.data.find((app: any) => app.status === "APPROVED") || + res.data[0]; + setApplication(approvedApp); + } + } catch (err) { + console.error("Lỗi khi tải hồ sơ nhà sử học:", err); + } finally { + setAppLoading(false); + } + }; + fetchApp(); + } + }, [isHistorian]); + + if (!currentUser) { + return ; + } + + const userMetaProps: UserMetaCardProps = { + data: currentUser + ? { + id: currentUser.id, + email: currentUser.email, + profile: currentUser.profile, + roles: currentUser.roles?.map((role) => ({ + id: Number(role.id) || undefined, + name: role.name, + })), + } + : undefined, + status: true, + }; + + // Nếu người dùng có role là HISTORIAN + if (isHistorian) { + return ( +
+ +
+
+ + + +
+ +
+ {appLoading ? ( +
+
+
+ ) : application ? ( +
+ +
+ ) : ( +
+ Không tìm thấy thông tin hồ sơ nhà sử học. +
+ )} +
+
+
+ ); + } + return (
- -
-
- - - +
+

+ Thông tin tài khoản +

+
+ + +
diff --git a/src/app/user/projects/[id]/page.tsx b/src/app/user/projects/[id]/page.tsx index 880d2ce..44a36f3 100644 --- a/src/app/user/projects/[id]/page.tsx +++ b/src/app/user/projects/[id]/page.tsx @@ -143,7 +143,6 @@ export default function ProjectDetailsPage() { }; const handleRemoveMember = async (userId: string) => { - // 1. Hiển thị hộp thoại xác nhận bằng SweetAlert2 const result = await Swal.fire({ title: "Xác nhận xóa?", text: "Bạn có chắc chắn muốn xóa thành viên này khỏi dự án?", @@ -263,18 +262,18 @@ export default function ProjectDetailsPage() { {[ { id: "overview", - label: "Overview", + label: "Tổng quan", icon: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", }, { id: "members", - label: `Members`, + label: `Thành viên`, count: project.members?.length || 0, icon: "M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z", }, { id: "settings", - label: "Settings", + label: "Cài đặt", icon: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z", }, ].map((tab) => ( @@ -324,7 +323,7 @@ export default function ProjectDetailsPage() {
- About + Thông tin
{project.description || ( @@ -339,7 +338,7 @@ export default function ProjectDetailsPage() {

- Owner + Chủ dự án

@@ -379,7 +378,7 @@ export default function ProjectDetailsPage() { {activeTab === "members" && (

- Manage access + Quản lý quyền truy cập

- - + +
@@ -449,8 +448,8 @@ export default function ProjectDetailsPage() { } className="text-sm px-3 py-1.5 rounded-md border border-gray-300 dark:border-[#30363d] bg-white dark:bg-[#21262d] outline-none hover:bg-gray-50 dark:hover:bg-[#30363d] cursor-pointer transition-colors" > - - + +