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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user