import { useState } from "react"; import { Link } from "react-router-dom"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Folder, Plus, RefreshCw, ChevronLeft } from "lucide-react"; import { createProject, getProjects } from "../lib/api"; import type { CreateProjectPayload, Project } from "../lib/api"; import { Card, CardSkeleton, Chip, EmptyState, ErrorState, Modal, PageHeader, PanelsMenu, btnPrimary, btnSecondary, inputCls, } from "../components/ui"; import { useAuthStore } from "../store/auth"; import { Perm, hasPermission } from "../lib/roles"; function ProjectCard({ project }: { project: Project }) { const targetId = project.id || project.op_project_id; const statusLabels: Record = { PLANNING: { label: "برنامه‌ریزی", tone: "amber" }, PLANNED: { label: "برنامه‌ریزی", tone: "amber" }, ACTIVE: { label: "در حال اجرا", tone: "green" }, ON_HOLD: { label: "متوقف", tone: "amber" }, COMPLETED: { label: "تکمیل‌شده", tone: "sky" }, CANCELLED: { label: "لغو شده", tone: "slate" }, ARCHIVED: { label: "بایگانی", tone: "slate" }, }; const currentStatus = project.status ? statusLabels[project.status.toUpperCase()] : null; const progressVal = project.progress !== undefined ? Math.round(project.progress) : project.stats.total > 0 ? Math.round( Math.max( 0, ((project.stats.total - project.stats.overdue - project.stats.failed_qc) / project.stats.total) * 100 ) ) : 0; return (
{/* بلوک محتوایی ۲ سطره در سمت راست */}
{/* سطر ۱: نام پروژه و بج پیل وضعیت */}

{project.name}

{project.stats.failed_qc > 0 ? ( {project.stats.failed_qc} مردود ) : currentStatus ? ( {currentStatus.label} ) : ( در حال اجرا )}
{/* سطر ۲: پیل تعداد فعالیت در راست — نوار پیشرفت باریک با درصد در چپ */}
{project.stats.total} فعالیت {project.stats.awaiting_qc > 0 && ( {project.stats.awaiting_qc} منتظر QC )} {project.location && ( • {project.location} )}
= 100 ? "bg-emerald-500" : "bg-sky-500" }`} style={{ width: `${progressVal}%` }} />
{progressVal}٪
{/* فلش تعاملی در منتهی‌الیه چپ با تراز عمودی کامل روی کل ارتفاع کارت */}
); } function CreateProjectModal({ open, onClose }: { open: boolean; onClose: () => void }) { const queryClient = useQueryClient(); const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [location, setLocation] = useState(""); const [projectManager, setProjectManager] = useState(""); const [errorMsg, setErrorMsg] = useState(""); const createMutation = useMutation({ mutationFn: (payload: CreateProjectPayload) => createProject(payload), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: ["projects"] }); onClose(); setName(""); setDescription(""); setLocation(""); setProjectManager(""); setErrorMsg(""); }, onError: (err: any) => { setErrorMsg(err?.message || "خطا در ثبت پروژه"); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!name.trim()) { setErrorMsg("نام پروژه الزامی است"); return; } setErrorMsg(""); createMutation.mutate({ name: name.trim(), description: description.trim(), location: location.trim(), project_manager: projectManager.trim(), }); }; return (
{errorMsg && (
{errorMsg}
)}
setName(e.target.value)} placeholder="مثال: برج مسکونی آسمان" required className={inputCls} />
setLocation(e.target.value)} placeholder="موقعیت جغرافیایی / شهر" className={inputCls} />
setProjectManager(e.target.value)} placeholder="نام سرپرست" className={inputCls} />