refactor: fix ai slop

This commit is contained in:
2026-07-31 22:22:33 +07:00 Unverified
parent 8de32bcb3f
commit 255b895112
8 changed files with 214 additions and 74 deletions
+50 -25
View File
@@ -71,6 +71,11 @@ import {
FieldLegend,
FieldSet,
} from "@/components/ui/field";
import {
getQuestionResponseSettings,
getQuestionResponseType,
type QuestionResponseType,
} from "@/lib/question-response-type";
interface Question {
id: string;
@@ -241,6 +246,16 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
questionsAutoSave.schedule();
};
const handleResponseTypeChange = (
question: Question,
responseType: QuestionResponseType,
) => {
handleUpdateQuestion(
question.id,
getQuestionResponseSettings(responseType, question.required),
);
};
const handleDeleteQuestion = async (id: string) => {
try {
await deleteQuestion(id, form.id);
@@ -504,7 +519,7 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
</CardTitle>
<CardDescription>
Question {index + 1} · {questionTypeLabel(q.type)}
{q.required ? " · Required" : ""}
{q.required || q.imageAnswerMode === "required" ? " · Required" : ""}
</CardDescription>
</div>
</AccordionTrigger>
@@ -639,29 +654,12 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
/>
</div>
)}
<div className="flex items-center gap-2">
<Switch
id={`required-${q.id}`}
checked={q.required}
onCheckedChange={(checked) =>
handleUpdateQuestion(q.id, { required: checked })
}
/>
<Label
htmlFor={`required-${q.id}`}
className="text-sm font-normal text-muted-foreground"
>
Required
</Label>
</div>
<Field className="w-full max-w-xs">
<FieldLabel>Answer image</FieldLabel>
<Field className="w-full max-w-sm">
<FieldLabel>Response type</FieldLabel>
<Select
value={q.imageAnswerMode}
value={getQuestionResponseType(q)}
onValueChange={(val) =>
handleUpdateQuestion(q.id, {
imageAnswerMode: val as Question["imageAnswerMode"],
})
handleResponseTypeChange(q, val as QuestionResponseType)
}
>
<SelectTrigger>
@@ -669,13 +667,40 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="none">Off</SelectItem>
<SelectItem value="optional">Optional</SelectItem>
<SelectItem value="required">Required</SelectItem>
<SelectItem value="answer-only">Answer only</SelectItem>
<SelectItem value="answer-optional-image">
Answer + optional image
</SelectItem>
<SelectItem value="image-only">Image only</SelectItem>
<SelectItem value="answer-required-image">
Answer + required image
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<FieldDescription>
“Image only” hides the normal answer field. “Answer + required image” requires both.
</FieldDescription>
</Field>
{(q.imageAnswerMode === "none" || q.imageAnswerMode === "optional") && (
<Field orientation="horizontal">
<Switch
id={`required-${q.id}`}
checked={q.required}
onCheckedChange={(checked) =>
handleUpdateQuestion(q.id, { required: checked })
}
/>
<div>
<FieldLabel htmlFor={`required-${q.id}`}>
Require answer
</FieldLabel>
<FieldDescription>
Users must complete the normal answer field.
</FieldDescription>
</div>
</Field>
)}
</div>
{(q.type === "radio" || q.type === "checkbox") && (
@@ -157,15 +157,11 @@ export default function SubmissionDetailClient({
<Card>
<CardHeader>
<CardTitle>Admin note</CardTitle>
<CardDescription>
Private context for administrators. Respondents cannot see this note.
</CardDescription>
<CardTitle>Note</CardTitle>
</CardHeader>
<CardContent>
<FieldGroup>
<Field data-invalid={noteAutoSave.status === "error"}>
<FieldLabel htmlFor="admin-note">Note</FieldLabel>
<Textarea
id="admin-note"
value={adminNote}
@@ -173,13 +169,11 @@ export default function SubmissionDetailClient({
setAdminNote(event.target.value);
noteAutoSave.schedule();
}}
placeholder="Add a private note about this submission..."
maxLength={10_000}
placeholder="This kinda sigma"
aria-invalid={noteAutoSave.status === "error"}
/>
<FieldDescription>
Autosaves after you stop typing. Only administrators can view
this note.
Autosaves after you stop typing.
</FieldDescription>
<SaveStatusIndicator
status={noteAutoSave.status}
@@ -275,12 +269,7 @@ export default function SubmissionDetailClient({
{answerValue && (
<div className="flex items-start justify-between gap-4 p-3 bg-muted rounded-md group">
<div className="flex flex-col min-w-0">
{wasEdited && (
<span className="text-xs font-semibold text-muted-foreground mb-1">
Current Answer:
</span>
)}
<span className="text-sm whitespace-pre-wrap break-all leading-relaxed">
<span className="text-sm whitespace-pre-wrap break-all">
{answerValue}
</span>
</div>
+2 -2
View File
@@ -142,7 +142,7 @@ export default async function ResultsListPage({
<TableHead>Respondent</TableHead>
<TableHead>Submitted</TableHead>
<TableHead>Status</TableHead>
<TableHead>Admin note</TableHead>
<TableHead>Note</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
@@ -237,7 +237,7 @@ export default async function ResultsListPage({
<CardContent className="flex items-start justify-between gap-4">
<div className="min-w-0">
<p className="text-xs font-medium text-muted-foreground">
Admin note
Note
</p>
{submission.adminNote ? (
<p className="line-clamp-3 whitespace-pre-wrap text-sm">