"use client"; import React, { useEffect, useState } from "react"; import Image from "next/image"; import { useRouter } from "next/navigation"; import PageBreadcrumb from "@/components/common/PageBreadCrumb"; import ComponentCard from "@/components/common/ComponentCard"; import { toast } from "sonner"; import { useModal } from "@/hooks/useModal"; import { Modal } from "@/components/ui/modal"; import Button from "@/components/ui/button/Button"; import Label from "@/components/form/Label"; import Badge from "@/components/ui/badge/Badge"; import { CreateProjectPayload, Project } from "@/interface/project"; import { apiCreateProject, getCurrentProject } from "@/service/projectService"; export type ProjectSortColumn = "created_at" | "updated_at" | "title"; export default function ProjectsPage() { const router = useRouter(); const [projects, setProjects] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isSubmitting, setIsSubmitting] = useState(false); const [sortBy, setSortBy] = useState("updated_at"); const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc"); const { isOpen, openModal, closeModal } = useModal(); const [formData, setFormData] = useState({ title: "", description: "", project_status: "PRIVATE" }); const fetchProjects = async () => { try { setIsLoading(true); const res = await getCurrentProject(); setProjects(res?.data?.items || res?.data || []); } catch (error) { console.error("Lỗi khi tải danh sách dự án:", error); toast.error("Không thể tải danh sách dự án. Vui lòng thử lại!"); } finally { setIsLoading(false); } }; useEffect(() => { fetchProjects(); }, []); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value })); }; const handleCreateProject = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.title.trim()) { toast.warning("Vui lòng nhập tên dự án!"); return; } try { setIsSubmitting(true); await apiCreateProject(formData); toast.success("Tạo dự án mới thành công!"); closeModal(); setFormData({ title: "", description: "", project_status: "PRIVATE" }); fetchProjects(); } catch (error) { console.error("Lỗi tạo dự án:", error); toast.error("Có lỗi xảy ra khi tạo dự án."); } finally { setIsSubmitting(false); } }; const handleSort = (column: ProjectSortColumn) => { if (sortBy === column) { setSortOrder(sortOrder === "asc" ? "desc" : "asc"); } else { setSortBy(column); setSortOrder("desc"); } }; const sortedProjects = [...projects].sort((a: any, b: any) => { let valA = a[sortBy]; let valB = b[sortBy]; if (!valA) valA = ""; if (!valB) valB = ""; if (valA < valB) return sortOrder === "asc" ? -1 : 1; if (valA > valB) return sortOrder === "asc" ? 1 : -1; return 0; }); // Helper format ngày const formatDate = (dateString: string | null | undefined) => { if (!dateString) return "-"; const date = new Date(dateString); return `Updated on ${date.toLocaleDateString("vi-VN", { day: "2-digit", month: "short", year: "numeric", })}`; }; const getStatusBadge = (status: string) => { switch (status) { case "PUBLIC": return PUBLIC; case "PRIVATE": return PRIVATE; case "ARCHIVE": return ARCHIVE; default: return {status}; } }; const SortButton = ({ column, label }: { column: ProjectSortColumn; label: string }) => { const isActive = sortBy === column; return ( ); }; console.log(projects); return (
+ Tạo dự án mới } >
{isLoading && (
)} {!isLoading && sortedProjects.length > 0 ? (
Sắp xếp:
{sortedProjects.map((project: any) => (
router.push(`/user/projects/${project.id}`)} className="flex items-center gap-2 mb-2 cursor-pointer hover:underline" >
{project.user?.avatar_url ? (
avatar
) : (
{project.user?.display_name?.charAt(0)?.toUpperCase() || "U"}
)}
{project.user?.display_name || "Unknown"}
/

{project.title}

{getStatusBadge(project.project_status)}
{formatDate(project.updated_at)}
{project.members && project.members.length > 0 ? ( <> {project.members.slice(0, 4).map((m: any, index: number) => m.avatar_url ? ( {m.display_name} ) : (
{m.display_name?.charAt(0)?.toUpperCase() || "U"}
) )} {project.members.length > 4 && (
+{project.members.length - 4}
)} ) : ( )}
))}
) : !isLoading && (

Bạn chưa có dự án nào.

)}
{/* Modal Tạo Dự án */}

Tạo dự án mới

); }