mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
feat(feedback): add user feedback/review system with admin management and hardened image upload validation
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Loader2, Trash2 } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from '@/components/ui/alert-dialog';
|
||||
|
||||
interface DeleteFeedbackButtonProps {
|
||||
feedbackId: string;
|
||||
feedbackTitle: string;
|
||||
redirectTo?: string;
|
||||
size?: 'default' | 'sm';
|
||||
variant?: 'outline' | 'destructive';
|
||||
}
|
||||
|
||||
export function DeleteFeedbackButton({
|
||||
feedbackId,
|
||||
feedbackTitle,
|
||||
redirectTo,
|
||||
size = 'sm',
|
||||
variant = 'outline',
|
||||
}: DeleteFeedbackButtonProps) {
|
||||
const router = useRouter();
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const handleDelete = async () => {
|
||||
setIsDeleting(true);
|
||||
setError(null);
|
||||
try {
|
||||
const response = await fetch(`/api/admin/feedback/${feedbackId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
const data = await response.json().catch(() => ({}));
|
||||
if (!response.ok) {
|
||||
setError((data as { error?: string }).error || 'Failed to delete feedback');
|
||||
return;
|
||||
}
|
||||
|
||||
if (redirectTo) {
|
||||
router.push(redirectTo);
|
||||
} else {
|
||||
router.refresh();
|
||||
}
|
||||
} catch {
|
||||
setError('Failed to delete feedback');
|
||||
} finally {
|
||||
setIsDeleting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant={variant} size={size} disabled={isDeleting}>
|
||||
{isDeleting ? <Loader2 className="mr-1.5 h-4 w-4 animate-spin" /> : <Trash2 className="mr-1.5 h-4 w-4" />}
|
||||
Delete
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete this feedback?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will permanently delete "{feedbackTitle}". This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
{error && <p className="mt-2 text-xs text-destructive">{error}</p>}
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={isDeleting}>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction variant="destructive" onClick={handleDelete} disabled={isDeleting}>
|
||||
{isDeleting ? 'Deleting...' : 'Delete'}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user