mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:31:12 -05:00
Fix auto-refresh and queue claiming
This commit is contained in:
@@ -7,11 +7,12 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { useUserRole } from '@/hooks/useUserRole';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { format } from 'date-fns';
|
||||
import { format, formatDistance } from 'date-fns';
|
||||
import { PhotoModal } from './PhotoModal';
|
||||
import { SubmissionReviewManager } from './SubmissionReviewManager';
|
||||
import { useIsMobile } from '@/hooks/use-mobile';
|
||||
@@ -366,6 +367,17 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
|
||||
// If there are changes and we should preserve interaction
|
||||
if (mergeResult.hasChanges) {
|
||||
// Debug logging for smart merge
|
||||
console.log('🔄 Smart merge detected changes:', {
|
||||
added: mergeResult.changes.added.length,
|
||||
updated: mergeResult.changes.updated.length,
|
||||
removed: mergeResult.changes.removed.length,
|
||||
newItemsCount: mergeResult.changes.added.length,
|
||||
protectedIds: Array.from(preserveInteraction ? interactingWith : new Set<string>()),
|
||||
strategy: refreshStrategy,
|
||||
preserveInteraction
|
||||
});
|
||||
|
||||
// Filter out items user is interacting with
|
||||
const protectedIds = preserveInteraction ? interactingWith : new Set<string>();
|
||||
const mergedWithProtection = mergeResult.items.map(item => {
|
||||
@@ -2027,21 +2039,40 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* New Items Notification */}
|
||||
{/* Auto-refresh Status Indicator */}
|
||||
{refreshMode === 'auto' && (
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground px-1">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
|
||||
<span>Auto-refresh active</span>
|
||||
</div>
|
||||
<span>•</span>
|
||||
<span>Checking every {Math.round(pollInterval / 1000)}s</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* New Items Notification - Enhanced */}
|
||||
{newItemsCount > 0 && (
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="sticky top-0 z-10 animate-in fade-in-50">
|
||||
<Alert className="border-primary/50 bg-primary/5">
|
||||
<AlertCircle className="h-4 w-4 animate-pulse" />
|
||||
<AlertTitle>New Items Available</AlertTitle>
|
||||
<AlertDescription className="flex items-center justify-between">
|
||||
<span>{newItemsCount} new {newItemsCount === 1 ? 'submission' : 'submissions'} pending review</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setNewItemsCount(0);
|
||||
fetchItems(activeEntityFilter, activeStatusFilter, false);
|
||||
}}
|
||||
className="flex items-center gap-2 border-primary/50 bg-primary/5 hover:bg-primary/10"
|
||||
className="ml-4"
|
||||
>
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
Show {newItemsCount} new {newItemsCount === 1 ? 'item' : 'items'}
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
Show New Items
|
||||
</Button>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
-- Fix ambiguous column reference in claim_next_submission
|
||||
CREATE OR REPLACE FUNCTION public.claim_next_submission(
|
||||
moderator_id UUID,
|
||||
lock_duration INTERVAL DEFAULT '15 minutes'
|
||||
)
|
||||
RETURNS TABLE (
|
||||
submission_id UUID,
|
||||
submission_type TEXT,
|
||||
priority INTEGER,
|
||||
waiting_time INTERVAL
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
BEGIN
|
||||
-- Update priority for all pending submissions first
|
||||
UPDATE content_submissions
|
||||
SET priority = calculate_submission_priority(id)
|
||||
WHERE status IN ('pending', 'partially_approved')
|
||||
AND (assigned_to IS NULL OR locked_until < NOW());
|
||||
|
||||
-- Claim next item with row-level lock
|
||||
RETURN QUERY
|
||||
UPDATE content_submissions
|
||||
SET
|
||||
assigned_to = moderator_id,
|
||||
assigned_at = NOW(),
|
||||
locked_until = NOW() + lock_duration,
|
||||
first_reviewed_at = COALESCE(first_reviewed_at, NOW())
|
||||
WHERE id = (
|
||||
SELECT cs.id FROM content_submissions cs
|
||||
WHERE cs.status IN ('pending', 'partially_approved')
|
||||
AND (cs.assigned_to IS NULL OR cs.locked_until < NOW())
|
||||
ORDER BY
|
||||
cs.priority DESC,
|
||||
cs.submitted_at ASC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED
|
||||
)
|
||||
RETURNING
|
||||
content_submissions.id,
|
||||
content_submissions.submission_type,
|
||||
content_submissions.priority,
|
||||
NOW() - content_submissions.submitted_at;
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user