feat: завершить проект — добавить недостающие файлы, тесты и CI/CD
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"use client";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import Link from "next/link";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
async function fetchProject(id: string) {
|
||||
const res = await fetch(`/api/projects/${id}`);
|
||||
if (!res.ok) throw new Error("Проект не найден");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export default function ProjectPage() {
|
||||
const params = useParams<{ id: string }>();
|
||||
const router = useRouter();
|
||||
|
||||
const { data: project, isLoading } = useQuery({
|
||||
queryKey: ["project", params.id],
|
||||
queryFn: () => fetchProject(params.id),
|
||||
});
|
||||
|
||||
if (isLoading) return <div className="min-h-screen flex items-center justify-center">Загрузка...</div>;
|
||||
if (!project) return <div>Проект не найден</div>;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<header className="bg-white border-b px-6 py-4 flex items-center justify-between">
|
||||
<Link href="/dashboard" className="text-blue-600 hover:text-blue-800">← Назад</Link>
|
||||
<h1 className="text-xl font-bold">Freelancer Match</h1>
|
||||
</header>
|
||||
|
||||
<main className="container mx-auto px-4 py-8 max-w-3xl">
|
||||
<div className="bg-white rounded-xl shadow-sm p-6 mb-6">
|
||||
<h2 className="text-2xl font-bold mb-4">{project.title}</h2>
|
||||
<p className="text-gray-700 whitespace-pre-wrap mb-4">{project.description}</p>
|
||||
|
||||
{project.category && (
|
||||
<span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">
|
||||
{project.category}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="mt-4 flex gap-2 flex-wrap">
|
||||
{project.required_skills.map((skill: string) => (
|
||||
<span key={skill} className="px-2 py-1 bg-gray-100 rounded text-sm">{skill}</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{(project.budget_min || project.budget_max) && (
|
||||
<div className="mt-4 p-3 bg-green-50 rounded">
|
||||
{project.budget_min ? `${project.budget_min.toLocaleString()}₽` : "—"} —{" "}
|
||||
{project.budget_max ? `${project.budget_max.toLocaleString()}₽` : "до бесконечности"}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{project.deadline && (
|
||||
<p className="mt-2 text-sm text-gray-500">Дедлайн: {new Date(project.deadline).toLocaleDateString("ru-RU")}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button onClick={() => router.push("/auth/login")}>Оставить заявку</Button>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user