style(tags): align tags page with list layout

This commit is contained in:
2026-04-29 02:05:46 +03:30
parent 5082dab99e
commit cb4a7ae118

View File

@@ -8,6 +8,7 @@ import { useWorkspace } from "../context/WorkspaceContext";
import { useTranslation } from "../hooks/useTranslation";
import { TAGS_CREATE, TAGS_EDIT, canDeleteWorkspaceResource, canWorkspace } from "../lib/permissions";
import FilterBar from "../components/FilterBar";
import { ListPageSkeleton } from "../components/ListPageSkeleton";
import { Modal } from "../components/Modal";
import { Pagination } from "../components/Pagination";
import { Button } from "../components/ui/button";
@@ -140,39 +141,50 @@ export default function Tags() {
};
if (!activeWorkspace) {
return <div className="p-6 text-center text-slate-500">{t.tags?.selectWorkspace || t.clients.selectWorkspace}</div>;
return (
<div className="mx-auto max-w-7xl p-4 md:p-6">
<div className="rounded-3xl border border-slate-200 bg-white p-6 text-slate-600 shadow-sm dark:border-slate-800 dark:bg-slate-900 dark:text-slate-300">
{t.tags?.selectWorkspace || t.clients.selectWorkspace}
</div>
</div>
);
}
return (
<div className="flex flex-col p-6 min-h-[calc(100vh-73px)] bg-slate-50 dark:bg-slate-900">
<div className="flex justify-between items-center mb-8 gap-4">
<div>
<h1 className="text-2xl font-bold text-slate-900 dark:text-white">{t.tags?.title || "Tags"}</h1>
<p className="text-slate-500 dark:text-slate-400 mt-1">
{t.tags?.description?.(activeWorkspace.name) || `Manage tags for ${activeWorkspace.name}`}
</p>
<div className="mx-auto flex min-h-full max-w-7xl flex-col p-4 md:p-6">
<div className="flex flex-1 flex-col gap-5">
<div className="rounded-3xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-6">
<div className="flex items-start justify-between gap-4">
<div>
<h1 className="text-2xl font-bold text-slate-900 dark:text-white">{t.tags?.title || "Tags"}</h1>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
{t.tags?.description?.(activeWorkspace.name) || `Manage tags for ${activeWorkspace.name}`}
</p>
</div>
{canCreateTag && (
<Button onClick={openCreateModal} size="icon" className="shrink-0 shadow-sm" title={t.tags?.create || "Create Tag"}>
<Plus className="h-5 w-5" />
</Button>
)}
</div>
</div>
{canCreateTag && (
<Button onClick={openCreateModal} size="icon" className="shadow-sm shrink-0" title={t.tags?.create || "Create Tag"}>
<Plus className="h-5 w-5" />
</Button>
)}
</div>
<FilterBar
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
ordering={ordering}
setOrdering={setOrdering}
orderingOptions={orderingOptions}
searchPlaceholder={t.tags?.searchPlaceholder || "Search tags..."}
/>
<div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
<FilterBar
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
ordering={ordering}
setOrdering={setOrdering}
orderingOptions={orderingOptions}
searchPlaceholder={t.tags?.searchPlaceholder || "Search tags..."}
/>
</div>
{isLoading ? (
<div className="p-12 flex justify-center text-slate-500">{t.loading || "Loading..."}</div>
) : (
<div className="flex flex-col flex-1">
<div className="mb-6 grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
{isLoading ? (
<ListPageSkeleton variant="dense-grid" />
) : (
<div className="flex flex-1 flex-col gap-6">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
{tags.map((tag) => {
const canDeleteTag = canDeleteWorkspaceResource({
workspaceRole,
@@ -196,7 +208,13 @@ export default function Tags() {
{(canEditTag || canDeleteTag) && (
<div className="flex shrink-0 items-center gap-1">
{canEditTag && (
<Button variant="ghost" size="icon" onClick={() => openEditModal(tag)} title={t.actions?.edit || "Edit"}>
<Button
variant="ghost"
size="icon"
onClick={() => openEditModal(tag)}
className="h-8 w-8 text-slate-400 hover:bg-blue-50 hover:text-blue-600 dark:hover:bg-blue-900/20 dark:hover:text-blue-400"
title={t.actions?.edit || "Edit"}
>
<Edit2 className="w-4 h-4" />
</Button>
)}
@@ -205,9 +223,10 @@ export default function Tags() {
variant="ghost"
size="icon"
onClick={() => setDeleteModal({ isOpen: true, tag })}
className="h-8 w-8 text-slate-400 hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20 dark:hover:text-red-400"
title={t.actions?.delete || "Delete"}
>
<Trash2 className="w-4 h-4 text-red-500" />
<Trash2 className="w-4 h-4" />
</Button>
)}
</div>
@@ -219,9 +238,9 @@ export default function Tags() {
})}
{tags.length === 0 && (
<div className="py-16 flex flex-col items-center justify-center border-2 border-dashed border-slate-200 dark:border-slate-800 rounded-2xl text-slate-500 dark:text-slate-400">
<div className="col-span-full flex flex-1 flex-col items-center justify-center rounded-3xl border-2 border-dashed border-slate-200 bg-white py-16 text-slate-500 shadow-sm dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400">
<TagIcon className="w-10 h-10 mb-3" />
<p>{t.tags?.emptyState || "No tags found"}</p>
<p className="font-medium">{t.tags?.emptyState || "No tags found"}</p>
</div>
)}
</div>
@@ -235,6 +254,7 @@ export default function Tags() {
/>
</div>
)}
</div>
<Modal
isOpen={isModalOpen}