UI icon-only buttons: 9 components, compact header, inline edit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 01:18:23 +00:00
parent 8cf14dcf59
commit 6d68b68412
4 changed files with 143 additions and 269 deletions

View File

@@ -10,6 +10,8 @@ import {
deleteProject,
Project,
} from "@/lib/api";
import PageActionBar from "@/components/features/PageActionBar";
import DeleteIconButton from "@/components/features/DeleteIconButton";
export default function ProjectsPage() {
const { token, user } = useAuth();
@@ -20,7 +22,6 @@ export default function ProjectsPage() {
const [showForm, setShowForm] = useState(false);
const [error, setError] = useState<string | null>(null);
// Form state
const [formName, setFormName] = useState("");
const [formDesc, setFormDesc] = useState("");
const [formColor, setFormColor] = useState("#3B82F6");
@@ -96,18 +97,14 @@ export default function ProjectsPage() {
return (
<div className="space-y-4 pb-24 sm:pb-8 px-4 sm:px-0">
{/* Header */}
<div className="flex items-center justify-between">
<h1 className="text-xl font-bold dark:text-white">{t("nav.projects")}</h1>
<button
onClick={() => setShowForm(!showForm)}
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm font-medium transition-colors min-h-[44px]"
>
{showForm ? t("tasks.form.cancel") : `+ ${t("projects.add")}`}
</button>
</div>
<PageActionBar
title={t("nav.projects")}
showAdd
onToggleAdd={() => setShowForm(!showForm)}
addOpen={showForm}
t={t}
/>
{/* Error */}
{error && (
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-3 text-red-700 dark:text-red-300 text-sm">
{error}
@@ -115,7 +112,6 @@ export default function ProjectsPage() {
</div>
)}
{/* Create form */}
{showForm && (
<form onSubmit={handleCreate} className="bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 p-4 space-y-3">
<div>
@@ -179,7 +175,6 @@ export default function ProjectsPage() {
</form>
)}
{/* Projects list */}
{loading ? (
<div className="flex justify-center py-12">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" />
@@ -219,15 +214,11 @@ export default function ProjectsPage() {
</div>
<div className="flex items-center gap-1 flex-shrink-0">
<div className="w-3 h-3 rounded-full" style={{ backgroundColor: project.color || "#3B82F6" }} />
<button
<DeleteIconButton
onClick={() => handleDelete(project.id)}
className="p-2 text-gray-400 hover:text-red-500 transition-colors min-h-[44px] min-w-[44px] flex items-center justify-center"
title={t("tasks.delete")}
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</button>
label={t("tasks.delete")}
size="sm"
/>
</div>
</div>
</div>