From 6aa5e5d0da7753fc8867e73d4464de2e8ad2afd5 Mon Sep 17 00:00:00 2001 From: Markov Date: Mon, 23 Feb 2026 12:28:37 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20project=20tabs=20=E2=80=94=20files=20(p?= =?UTF-8?q?laceholder)=20and=20settings=20(edit/delete)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(protected)/projects/[slug]/page.tsx | 14 ++ src/components/ProjectFiles.tsx | 17 +++ src/components/ProjectSettings.tsx | 139 +++++++++++++++++++ src/lib/api.ts | 8 ++ 4 files changed, 178 insertions(+) create mode 100644 src/components/ProjectFiles.tsx create mode 100644 src/components/ProjectSettings.tsx diff --git a/src/app/(protected)/projects/[slug]/page.tsx b/src/app/(protected)/projects/[slug]/page.tsx index deb5137..cb4f881 100644 --- a/src/app/(protected)/projects/[slug]/page.tsx +++ b/src/app/(protected)/projects/[slug]/page.tsx @@ -6,10 +6,14 @@ import { getProjects, Project } from "@/lib/api"; import Sidebar from "@/components/Sidebar"; import KanbanBoard from "@/components/KanbanBoard"; import ChatPanel from "@/components/ChatPanel"; +import ProjectFiles from "@/components/ProjectFiles"; +import ProjectSettings from "@/components/ProjectSettings"; const TABS = [ { key: "board", label: "📋 Доска" }, { key: "chat", label: "💬 Чат" }, + { key: "files", label: "📁 Файлы" }, + { key: "settings", label: "⚙️ Настройки" }, ]; export default function ProjectPage() { @@ -27,6 +31,10 @@ export default function ProjectPage() { const project = projects.find((p) => p.slug === slug); + const handleProjectUpdated = (updated: Project) => { + setProjects((prev) => prev.map((p) => (p.id === updated.id ? updated : p))); + }; + if (loading) { return
Загрузка...
; } @@ -77,6 +85,12 @@ export default function ProjectPage() { Чат недоступен )} + {activeTab === "files" && ( + + )} + {activeTab === "settings" && ( + + )} diff --git a/src/components/ProjectFiles.tsx b/src/components/ProjectFiles.tsx new file mode 100644 index 0000000..20dd6b2 --- /dev/null +++ b/src/components/ProjectFiles.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { Project } from "@/lib/api"; + +interface Props { + project: Project; +} + +export default function ProjectFiles({ project }: Props) { + return ( +
+
📁
+
Файлы проекта
+
Скоро здесь можно будет загружать и просматривать файлы
+
+ ); +} diff --git a/src/components/ProjectSettings.tsx b/src/components/ProjectSettings.tsx new file mode 100644 index 0000000..4291fb5 --- /dev/null +++ b/src/components/ProjectSettings.tsx @@ -0,0 +1,139 @@ +"use client"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { Project, updateProject, deleteProject } from "@/lib/api"; + +interface Props { + project: Project; + onUpdated: (p: Project) => void; +} + +export default function ProjectSettings({ project, onUpdated }: Props) { + const router = useRouter(); + const [name, setName] = useState(project.name); + const [description, setDescription] = useState(project.description || ""); + const [repoUrls, setRepoUrls] = useState(project.repo_urls?.join("\n") || ""); + const [status, setStatus] = useState(project.status); + const [saving, setSaving] = useState(false); + const [saved, setSaved] = useState(false); + const [confirmDelete, setConfirmDelete] = useState(false); + + const handleSave = async () => { + setSaving(true); + try { + const urls = repoUrls.split("\n").map((u) => u.trim()).filter(Boolean); + const updated = await updateProject(project.slug, { + name: name.trim(), + description: description.trim() || null, + repo_urls: urls, + status, + }); + onUpdated(updated); + setSaved(true); + setTimeout(() => setSaved(false), 2000); + } catch (e) { + console.error(e); + } finally { + setSaving(false); + } + }; + + const handleDelete = async () => { + try { + await deleteProject(project.slug); + router.push("/"); + } catch (e) { + console.error(e); + } + }; + + return ( +
+

Настройки проекта

+ +
+ + setName(e.target.value)} + className="w-full px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg outline-none focus:border-[var(--accent)] text-sm" + /> +
+ +
+ +