Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 860x 860x 729x 51x | import { Input } from "../../ui/input";
interface BasicInfoSectionProps {
title: string;
description: string;
onTitleChange: (value: string) => void;
onDescriptionChange: (value: string) => void;
titleError?: string | null;
}
export function BasicInfoSection({
title,
description,
onTitleChange,
onDescriptionChange,
titleError,
}: BasicInfoSectionProps) {
const titleErrorId = "project-title-error";
return (
<div className="space-y-4">
<h3 className="text-md font-semibold text-foreground-default border-b pb-2">
Basic Information
</h3>
<div>
<label
htmlFor="project-title"
className="block text-sm font-medium text-foreground-default mb-1"
>
Project Title *
</label>
<Input
id="project-title"
value={title}
onChange={(e) => onTitleChange(e.target.value)}
placeholder="e.g., Modern Kitchen Renovation"
required
aria-invalid={titleError ? true : undefined}
aria-describedby={titleError ? titleErrorId : undefined}
/>
{titleError && (
<p
id={titleErrorId}
className="text-xs text-error mt-1"
role="alert"
>
{titleError}
</p>
)}
</div>
<div>
<label
htmlFor="project-description"
className="block text-sm font-medium text-foreground-default mb-1"
>
Description
</label>
<textarea
id="project-description"
value={description}
onChange={(e) => onDescriptionChange(e.target.value)}
placeholder="Describe this project..."
rows={3}
className="flex min-h-[80px] w-full rounded-md border border-default bg-background-elevated px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"
/>
</div>
</div>
);
}
|