213 lines
6.0 KiB
JavaScript
213 lines
6.0 KiB
JavaScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import Link from "next/link";
|
|
import { Card, CardHeader, CardContent } from "@/components/ui/Card";
|
|
import Button from "@/components/ui/Button";
|
|
import Badge from "@/components/ui/Badge";
|
|
import PageContainer from "@/components/ui/PageContainer";
|
|
import PageHeader from "@/components/ui/PageHeader";
|
|
import { useTranslation } from "@/lib/i18n";
|
|
|
|
export default function TaskTemplatesPage() {
|
|
const { t } = useTranslation();
|
|
const [templates, setTemplates] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const fetchTemplates = async () => {
|
|
try {
|
|
const response = await fetch('/api/tasks/templates');
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setTemplates(data);
|
|
} else {
|
|
console.error('Failed to fetch templates');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching templates:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchTemplates();
|
|
}, []);
|
|
|
|
const getTaskCategoryBadge = (taskCategory) => {
|
|
const colors = {
|
|
design: "bg-blue-100 text-blue-800",
|
|
construction: "bg-green-100 text-green-800"
|
|
};
|
|
|
|
return (
|
|
<span className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${colors[taskCategory] || "bg-gray-100 text-gray-800"}`}>
|
|
{taskCategory === "design" ? "Projektowe" : taskCategory === "construction" ? "Budowlane" : taskCategory}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<PageContainer>
|
|
<PageHeader
|
|
title={t('taskTemplates.title')}
|
|
description={t('taskTemplates.subtitle')}
|
|
actions={[
|
|
<Link href="/tasks/templates/new" key="new-template">
|
|
<Button variant="primary" size="lg">
|
|
<svg
|
|
className="w-5 h-5 mr-2"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M12 4v16m8-8H4"
|
|
/>
|
|
</svg>
|
|
{t('taskTemplates.newTemplate')}
|
|
</Button>
|
|
</Link>,
|
|
<Link href="/task-sets" key="task-sets">
|
|
<Button variant="secondary" size="lg">
|
|
<svg
|
|
className="w-5 h-5 mr-2"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
|
|
/>
|
|
</svg>
|
|
Zestawy zadań
|
|
</Button>
|
|
</Link>
|
|
]}
|
|
/>
|
|
<div className="text-center py-12">
|
|
<div className="text-gray-500">{t('common.loading')}</div>
|
|
</div>
|
|
</PageContainer>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<PageContainer>
|
|
<PageHeader
|
|
title={t('taskTemplates.title')}
|
|
description={t('taskTemplates.subtitle')}
|
|
actions={[
|
|
<Link href="/tasks/templates/new" key="new-template">
|
|
<Button variant="primary" size="lg">
|
|
<svg
|
|
className="w-5 h-5 mr-2"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M12 4v16m8-8H4"
|
|
/>
|
|
</svg>
|
|
{t('taskTemplates.newTemplate')}
|
|
</Button>
|
|
</Link>,
|
|
<Link href="/task-sets" key="task-sets">
|
|
<Button variant="secondary" size="lg">
|
|
<svg
|
|
className="w-5 h-5 mr-2"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
|
|
/>
|
|
</svg>
|
|
Zestawy zadań
|
|
</Button>
|
|
</Link>
|
|
]}
|
|
/>
|
|
|
|
{templates.length === 0 ? (
|
|
<Card>
|
|
<CardContent className="text-center py-12">
|
|
<div className="text-gray-400 mb-4">
|
|
<svg
|
|
className="w-16 h-16 mx-auto"
|
|
fill="currentColor"
|
|
viewBox="0 0 20 20"
|
|
>
|
|
<path
|
|
fillRule="evenodd"
|
|
d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zm0 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V8zm0 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1v-2z"
|
|
clipRule="evenodd"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
|
{t('taskTemplates.noTemplates')}
|
|
</h3>
|
|
<p className="text-gray-500 mb-6">
|
|
{t('taskTemplates.noTemplatesMessage')}
|
|
</p>
|
|
<Link href="/tasks/templates/new">
|
|
<Button variant="primary">{t('taskTemplates.newTemplate')}</Button>
|
|
</Link>
|
|
</CardContent>
|
|
</Card>
|
|
) : (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
{templates.map((template) => (
|
|
<Card
|
|
key={template.task_id}
|
|
className="hover:shadow-md transition-shadow"
|
|
>
|
|
<CardContent className="p-6">
|
|
<div className="flex items-start justify-between mb-4">
|
|
<h3 className="text-lg font-semibold text-gray-900 truncate pr-2">
|
|
{template.name}
|
|
</h3>
|
|
<div className="flex flex-col gap-1">
|
|
<Badge variant="primary" size="sm">
|
|
{template.max_wait_days} {t('common.days')}
|
|
</Badge>
|
|
{getTaskCategoryBadge(template.task_category)}
|
|
</div>
|
|
</div>
|
|
{template.description && (
|
|
<p className="text-gray-600 text-sm mb-4 line-clamp-2">
|
|
{template.description}
|
|
</p>
|
|
)}{" "}
|
|
<div className="flex items-center justify-end">
|
|
<Link href={`/tasks/templates/${template.task_id}/edit`}>
|
|
<Button variant="outline" size="sm">
|
|
{t('taskTemplates.editTemplate')}
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))}{" "}
|
|
</div>
|
|
)}
|
|
</PageContainer>
|
|
);
|
|
}
|