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 | 372x 372x 325x 41x | import { Field, ErrorText, Label } from "../../ui/field";
import { Input } from "../../ui/input";
import { Textarea } from "../../ui/textarea";
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">
<Field controlId="project-title" required>
{/* The Job Book marks what is OPTIONAL, never what is required —
so the asterisk is gone and the description below says
"optional" instead. */}
<Label>Project title</Label>
<Input
id="project-title"
value={title}
onChange={(e) => onTitleChange(e.target.value)}
placeholder="e.g. 3BHK in Kondapur"
required
aria-invalid={titleError ? true : undefined}
aria-describedby={titleError ? titleErrorId : undefined}
/>
{titleError ? (
<ErrorText id={titleErrorId} role="alert">
{titleError}
</ErrorText>
) : null}
</Field>
<Field controlId="project-description">
<Label optional>Description</Label>
<Textarea
id="project-description"
value={description}
onChange={(e) => onDescriptionChange(e.target.value)}
placeholder="Materials, what the family asked for, what you solved. Two or three lines is plenty."
rows={3}
/>
</Field>
</div>
);
}
|