137 lines
3.6 KiB
TypeScript
137 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useParams, useRouter } from "next/navigation";
|
|
import { ArrowLeft } from "lucide-react";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { TaskInfoCard } from "@/components/tasks/task-info-card";
|
|
import { CommentSection } from "@/components/tasks/comment-section";
|
|
import { FileSection } from "@/components/tasks/file-section";
|
|
import { FileUploadDialog } from "@/components/tasks/file-upload-dialog";
|
|
import { TaskActions } from "@/components/tasks/task-actions";
|
|
import { useTask } from "@/hooks";
|
|
import { Badge } from "@/components/ui/badge";
|
|
|
|
/**
|
|
* Task Detail Page
|
|
* Zeigt alle Details einer einzelnen Task an
|
|
* - Task-Info-Card mit allen Basis-Informationen
|
|
* - Comment-Section für Kommentare
|
|
* - File-Section für Datei-Anhänge
|
|
* - Nur shadcn/ui Komponenten
|
|
*/
|
|
export default function TaskDetailPage() {
|
|
const params = useParams();
|
|
const router = useRouter();
|
|
const taskId = params.id as string;
|
|
|
|
/**
|
|
* State für File-Upload-Dialog
|
|
*/
|
|
const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
|
|
|
|
/**
|
|
* Hook zum Abrufen der Task-Daten
|
|
*/
|
|
const { data: task, isLoading, error } = useTask(taskId);
|
|
|
|
/**
|
|
* Handler für Zurück-Navigation
|
|
*/
|
|
const handleBack = () => {
|
|
router.push("/dashboard/tasks");
|
|
};
|
|
|
|
/**
|
|
* Loading State
|
|
*/
|
|
if (isLoading) {
|
|
return (
|
|
<div className="space-y-6">
|
|
<Skeleton className="h-10 w-32" />
|
|
<Skeleton className="h-40 w-full" />
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
<Skeleton className="h-96" />
|
|
<div className="space-y-6">
|
|
<Skeleton className="h-96" />
|
|
<Skeleton className="h-40" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Error State
|
|
*/
|
|
if (error || !task) {
|
|
return (
|
|
<div className="space-y-4">
|
|
<Button variant="ghost" onClick={handleBack}>
|
|
<ArrowLeft className="h-4 w-4 mr-2" />
|
|
Zurück
|
|
</Button>
|
|
<Card>
|
|
<CardContent className="pt-6">
|
|
<p className="text-destructive">
|
|
Fehler beim Laden der Task. Bitte versuchen Sie es erneut.
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Main Content
|
|
*/
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Zurück-Button und Actions */}
|
|
<div className="flex items-center justify-between">
|
|
<Button variant="ghost" onClick={handleBack}>
|
|
<ArrowLeft className="h-4 w-4 mr-2" />
|
|
Zurück
|
|
</Button>
|
|
<TaskActions task={task} />
|
|
</div>
|
|
|
|
{/* Task Titel und Beschreibung */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>
|
|
{task.was}
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-sm whitespace-pre-wrap">{task.wo}</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Grid Layout: Info links, Comments und Files rechts */}
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
{/* Linke Spalte: Task Info */}
|
|
<TaskInfoCard task={task} />
|
|
|
|
{/* Rechte Spalte: Comments und Files */}
|
|
<div className="space-y-6">
|
|
<CommentSection task={task} />
|
|
<FileSection
|
|
task={task}
|
|
onUploadClick={() => setUploadDialogOpen(true)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* File Upload Dialog */}
|
|
<FileUploadDialog
|
|
taskId={taskId}
|
|
open={uploadDialogOpen}
|
|
onOpenChange={setUploadDialogOpen}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|