mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-28 19:06:59 -05:00
Add transaction status indicators to moderation UI
Implement visual indicators in the moderation queue and review manager to display the status of ongoing transactions. This includes states for processing, timeout, and cached results, providing users with clearer feedback on the system's activity.
This commit is contained in:
@@ -39,6 +39,7 @@ import { ValidationBlockerDialog } from './ValidationBlockerDialog';
|
||||
import { WarningConfirmDialog } from './WarningConfirmDialog';
|
||||
import { ConflictResolutionModal } from './ConflictResolutionModal';
|
||||
import { EditHistoryAccordion } from './EditHistoryAccordion';
|
||||
import { TransactionStatusIndicator } from './TransactionStatusIndicator';
|
||||
import { validateMultipleItems, ValidationResult } from '@/lib/entityValidationSchemas';
|
||||
import { logger } from '@/lib/logger';
|
||||
import { ModerationErrorBoundary } from '@/components/error';
|
||||
@@ -83,6 +84,8 @@ export function SubmissionReviewManager({
|
||||
message: string;
|
||||
errorId?: string;
|
||||
} | null>(null);
|
||||
const [transactionStatus, setTransactionStatus] = useState<'idle' | 'processing' | 'timeout' | 'cached' | 'completed' | 'failed'>('idle');
|
||||
const [transactionMessage, setTransactionMessage] = useState<string | undefined>();
|
||||
|
||||
const { toast } = useToast();
|
||||
const { isAdmin, isSuperuser } = useUserRole();
|
||||
@@ -337,6 +340,7 @@ export function SubmissionReviewManager({
|
||||
}
|
||||
|
||||
// Proceed with approval - wrapped with transaction resilience
|
||||
setTransactionStatus('processing');
|
||||
await executeTransaction(
|
||||
'approval',
|
||||
selectedIds,
|
||||
@@ -400,10 +404,34 @@ export function SubmissionReviewManager({
|
||||
onComplete();
|
||||
onOpenChange(false);
|
||||
|
||||
setTransactionStatus('completed');
|
||||
setTimeout(() => setTransactionStatus('idle'), 3000);
|
||||
|
||||
return data;
|
||||
}
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
// Check for timeout
|
||||
if (error && typeof error === 'object' && 'type' in error && error.type === 'timeout') {
|
||||
setTransactionStatus('timeout');
|
||||
setTransactionMessage(getErrorMessage(error));
|
||||
}
|
||||
// Check for cached/409
|
||||
else if (error && typeof error === 'object' && ('status' in error && error.status === 409)) {
|
||||
setTransactionStatus('cached');
|
||||
setTransactionMessage('Using cached result from duplicate request');
|
||||
}
|
||||
// Generic failure
|
||||
else {
|
||||
setTransactionStatus('failed');
|
||||
setTransactionMessage(getErrorMessage(error));
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setTransactionStatus('idle');
|
||||
setTransactionMessage(undefined);
|
||||
}, 5000);
|
||||
|
||||
dispatch({ type: 'ERROR', payload: { error: getErrorMessage(error) } });
|
||||
handleError(error, {
|
||||
action: 'Approve Submission Items',
|
||||
@@ -467,6 +495,7 @@ export function SubmissionReviewManager({
|
||||
|
||||
try {
|
||||
// Wrap rejection with transaction resilience
|
||||
setTransactionStatus('processing');
|
||||
await executeTransaction(
|
||||
'rejection',
|
||||
selectedIds,
|
||||
@@ -484,10 +513,34 @@ export function SubmissionReviewManager({
|
||||
onComplete();
|
||||
onOpenChange(false);
|
||||
|
||||
setTransactionStatus('completed');
|
||||
setTimeout(() => setTransactionStatus('idle'), 3000);
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
// Check for timeout
|
||||
if (error && typeof error === 'object' && 'type' in error && error.type === 'timeout') {
|
||||
setTransactionStatus('timeout');
|
||||
setTransactionMessage(getErrorMessage(error));
|
||||
}
|
||||
// Check for cached/409
|
||||
else if (error && typeof error === 'object' && ('status' in error && error.status === 409)) {
|
||||
setTransactionStatus('cached');
|
||||
setTransactionMessage('Using cached result from duplicate request');
|
||||
}
|
||||
// Generic failure
|
||||
else {
|
||||
setTransactionStatus('failed');
|
||||
setTransactionMessage(getErrorMessage(error));
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setTransactionStatus('idle');
|
||||
setTransactionMessage(undefined);
|
||||
}, 5000);
|
||||
|
||||
dispatch({ type: 'ERROR', payload: { error: getErrorMessage(error) } });
|
||||
handleError(error, {
|
||||
action: 'Reject Submission Items',
|
||||
@@ -625,7 +678,10 @@ export function SubmissionReviewManager({
|
||||
{isMobile ? (
|
||||
<SheetContent side="bottom" className="h-[90vh] overflow-y-auto">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Review Submission</SheetTitle>
|
||||
<div className="flex items-center justify-between">
|
||||
<SheetTitle>Review Submission</SheetTitle>
|
||||
<TransactionStatusIndicator status={transactionStatus} message={transactionMessage} />
|
||||
</div>
|
||||
<SheetDescription>
|
||||
{pendingCount} pending item(s) • {selectedCount} selected
|
||||
</SheetDescription>
|
||||
@@ -635,7 +691,10 @@ export function SubmissionReviewManager({
|
||||
) : (
|
||||
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Review Submission</DialogTitle>
|
||||
<div className="flex items-center justify-between">
|
||||
<DialogTitle>Review Submission</DialogTitle>
|
||||
<TransactionStatusIndicator status={transactionStatus} message={transactionMessage} />
|
||||
</div>
|
||||
<DialogDescription>
|
||||
{pendingCount} pending item(s) • {selectedCount} selected
|
||||
</DialogDescription>
|
||||
|
||||
Reference in New Issue
Block a user