Refactor: Use consolidated escalateSubmission action

This commit is contained in:
gpt-engineer-app[bot]
2025-11-05 18:49:21 +00:00
parent 0d6d3fb2cc
commit 882959bce6
3 changed files with 67 additions and 43 deletions

View File

@@ -1,5 +1,5 @@
import { useState } from 'react';
import { AlertTriangle } from 'lucide-react';
import { AlertTriangle, AlertCircle } from 'lucide-react';
import {
Dialog,
DialogContent,
@@ -18,12 +18,14 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
interface EscalationDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onEscalate: (reason: string) => Promise<void>;
submissionType: string;
error?: { message: string; errorId?: string } | null;
}
const escalationReasons = [
@@ -40,6 +42,7 @@ export function EscalationDialog({
onOpenChange,
onEscalate,
submissionType,
error,
}: EscalationDialogProps) {
const [selectedReason, setSelectedReason] = useState('');
const [additionalNotes, setAdditionalNotes] = useState('');
@@ -76,6 +79,23 @@ export function EscalationDialog({
</DialogDescription>
</DialogHeader>
{error && (
<Alert variant="destructive" className="mt-4">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Escalation Failed</AlertTitle>
<AlertDescription>
<div className="space-y-2">
<p className="text-sm">{error.message}</p>
{error.errorId && (
<p className="text-xs font-mono bg-destructive/10 px-2 py-1 rounded">
Reference: {error.errorId.slice(0, 8)}
</p>
)}
</div>
</AlertDescription>
</Alert>
)}
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label>Escalation Reason</Label>

View File

@@ -12,12 +12,12 @@ import {
detectDependencyConflicts,
approveSubmissionItems,
rejectSubmissionItems,
escalateSubmission,
checkSubmissionConflict,
type SubmissionItemWithDeps,
type DependencyConflict,
type ConflictCheckResult
} from '@/lib/submissionItemsService';
import { useModerationActions } from '@/hooks/moderation/useModerationActions';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '@/components/ui/sheet';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
@@ -77,6 +77,10 @@ export function SubmissionReviewManager({
const [conflictData, setConflictData] = useState<ConflictCheckResult | null>(null);
const [showConflictResolutionModal, setShowConflictResolutionModal] = useState(false);
const [lastModifiedTimestamp, setLastModifiedTimestamp] = useState<string | null>(null);
const [escalationError, setEscalationError] = useState<{
message: string;
errorId?: string;
} | null>(null);
const { toast } = useToast();
const { isAdmin, isSuperuser } = useUserRole();
@@ -87,6 +91,17 @@ export function SubmissionReviewManager({
// Lock monitoring integration
const { extendLock } = useLockMonitor(state, dispatch, submissionId);
// Moderation actions
const { escalateSubmission } = useModerationActions({
user,
onActionStart: (itemId: string) => {
logger.log(`Starting escalation for ${itemId}`);
},
onActionComplete: () => {
logger.log('Escalation complete');
}
});
// Auto-claim on mount
useEffect(() => {
if (open && submissionId && state.status === 'idle') {
@@ -425,50 +440,35 @@ export function SubmissionReviewManager({
}
try {
const { supabase } = await import('@/integrations/supabase/client');
// Call the escalation notification edge function
const { data, error, requestId } = await invokeWithTracking(
'send-escalation-notification',
{
submissionId,
escalationReason: reason,
escalatedBy: user.id
},
user.id
);
if (error) {
handleError(error, {
action: 'Send escalation notification',
userId: user.id,
metadata: { submissionId }
});
// Fallback to direct database update if email fails
await escalateSubmission(submissionId, reason, user.id);
toast({
title: 'Escalated (Email Failed)',
description: 'Submission escalated but notification email failed to send',
variant: 'default',
});
} else {
toast({
title: 'Escalated Successfully',
description: 'Submission escalated and admin notified via email',
});
}
setEscalationError(null);
// Use consolidated action from useModerationActions
// This handles: edge function call, fallback, error logging, cache invalidation
await escalateSubmission(
{
id: submissionId,
submission_type: submissionType,
type: 'submission'
} as any,
reason
);
// Success - close dialog
onComplete();
onOpenChange(false);
} catch (error: unknown) {
handleError(error, {
action: 'Escalate Submission',
userId: user?.id,
metadata: {
submissionId,
reason: reason.substring(0, 100)
}
} catch (error: any) {
// Track error for retry UI
setEscalationError({
message: getErrorMessage(error),
errorId: error.errorId
});
logger.error('Escalation failed in SubmissionReviewManager', {
submissionId,
error: getErrorMessage(error)
});
// Don't close dialog on error - let user retry
}
};
@@ -587,6 +587,7 @@ export function SubmissionReviewManager({
onOpenChange={setShowEscalationDialog}
onEscalate={handleEscalate}
submissionType={submissionType}
error={escalationError}
/>
<RejectionDialog

View File

@@ -372,7 +372,10 @@ export const useModerationQueue = (config?: UseModerationQueueConfig) => {
return Math.max(0, currentLock.expiresAt.getTime() - Date.now());
}, [currentLock]);
// Escalate submission
/**
* @deprecated Use escalateSubmission from useModerationActions instead
* This method only updates the database and doesn't send email notifications
*/
const escalateSubmission = useCallback(async (submissionId: string, reason: string): Promise<boolean> => {
if (!user?.id) return false;