Feedback categories page; treat 204 responses as success

Feedback → Categories: add, rename, reorder, archive/restore, and delete
unused categories. Feedback rows show the category's current label.

The API helper now accepts 204 No Content, which previously surfaced as a
"No Content" error after archive/delete and quiz attempt resets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gosangam
2026-10-18 13:47:09 +05:30
co-authored by Claude Opus 5.5
parent b194d4aa03
commit a63c329850
3 changed files with 435 additions and 17 deletions
+27 -17
View File
@@ -1,6 +1,8 @@
"use client";
import { useCallback, useState } from "react";
import Link from "next/link";
import { Tags } from "lucide-react";
import { Can } from "@/components/staff-context";
import { toast } from "sonner";
import { api, AdminError, type AdminFeedback } from "@/lib/api";
@@ -70,21 +72,29 @@ export default function FeedbackPage() {
total={list.total}
list={list}
toolbar={
<div className="flex gap-1 rounded-lg border border-border bg-card p-1">
{STATUSES.map((s) => (
<button
key={s}
onClick={() => setStatus(s)}
className={cn(
"rounded-md px-3 py-1.5 text-sm capitalize transition-colors",
status === s
? "bg-accent text-accent-foreground font-medium"
: "text-muted-foreground hover:text-foreground",
)}
>
{s}
</button>
))}
<div className="flex flex-wrap items-center gap-2">
<Link href="/feedback/categories">
<Button variant="outline" size="sm">
<Tags className="size-4" />
Categories
</Button>
</Link>
<div className="flex gap-1 rounded-lg border border-border bg-card p-1">
{STATUSES.map((s) => (
<button
key={s}
onClick={() => setStatus(s)}
className={cn(
"rounded-md px-3 py-1.5 text-sm capitalize transition-colors",
status === s
? "bg-accent text-accent-foreground font-medium"
: "text-muted-foreground hover:text-foreground",
)}
>
{s}
</button>
))}
</div>
</div>
}
>
@@ -122,7 +132,7 @@ export default function FeedbackPage() {
</TD>
<TD className="max-w-md">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
{f.category}
{f.category_label || f.category}
</div>
<div className="mt-0.5 whitespace-pre-line">{f.message}</div>
{f.reply_message ? (
@@ -246,7 +256,7 @@ function ReplyModal({
{feedback ? (
<div className="rounded-md bg-muted px-3 py-2 text-sm">
<div className="text-xs uppercase tracking-wide text-muted-foreground">
{feedback.category}
{feedback.category_label || feedback.category}
</div>
<div className="mt-0.5 whitespace-pre-line">{feedback.message}</div>
</div>