From 437e2b353cb9541a04cb9c25c46403dac67754bd Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Wed, 12 Nov 2025 14:45:06 +0000
Subject: [PATCH] testing changes with virtual file cleanup
---
src/components/moderation/QueueFilters.tsx | 54 +++++----
src/hooks/useDetailedViewState.ts | 121 +++++++++++++++++----
2 files changed, 135 insertions(+), 40 deletions(-)
diff --git a/src/components/moderation/QueueFilters.tsx b/src/components/moderation/QueueFilters.tsx
index d5ac7a08..6796a76c 100644
--- a/src/components/moderation/QueueFilters.tsx
+++ b/src/components/moderation/QueueFilters.tsx
@@ -4,6 +4,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { RefreshButton } from '@/components/ui/refresh-button';
import { QueueSortControls } from './QueueSortControls';
import { useFilterPanelState } from '@/hooks/useFilterPanelState';
@@ -80,25 +81,40 @@ export const QueueFilters = ({
{/* Global toggle for detailed views */}
-
- {detailsCollapsed ? (
- <>
-
- {!isMobile && Expand All }
- >
- ) : (
- <>
-
- {!isMobile && Collapse All }
- >
- )}
-
+
+
+
+
+ {detailsCollapsed ? (
+ <>
+
+ {!isMobile && Expand All }
+ >
+ ) : (
+ <>
+
+ {!isMobile && Collapse All }
+ >
+ )}
+
+
+
+
+ {detailsCollapsed
+ ? "Show detailed field-by-field view for all items in the queue"
+ : "Hide detailed field-by-field view for all items in the queue"}
+
+
+ This preference is saved to your account
+
+
+
+
{isMobile && (
diff --git a/src/hooks/useDetailedViewState.ts b/src/hooks/useDetailedViewState.ts
index 922d3f93..836ce6c5 100644
--- a/src/hooks/useDetailedViewState.ts
+++ b/src/hooks/useDetailedViewState.ts
@@ -1,48 +1,127 @@
import { useState, useEffect } from 'react';
import { logger } from '@/lib/logger';
+import { useAuth } from '@/hooks/useAuth';
+import { supabase } from '@/lib/supabaseClient';
+import { handleNonCriticalError } from '@/lib/errorHandler';
+import type { Json } from '@/integrations/supabase/types';
const STORAGE_KEY = 'detailed-view-collapsed';
+interface ModerationPreferences {
+ detailed_view_collapsed: boolean;
+}
+
interface UseDetailedViewStateReturn {
isCollapsed: boolean;
toggle: () => void;
setCollapsed: (value: boolean) => void;
+ loading: boolean;
}
/**
* Hook to manage detailed view collapsed/expanded state
- * Syncs with localStorage for persistence across sessions
+ * Persists to database for authenticated users, localStorage for guests
* Defaults to collapsed to reduce visual clutter
*/
export function useDetailedViewState(): UseDetailedViewStateReturn {
- const [isCollapsed, setIsCollapsed] = useState(() => {
- // Initialize from localStorage on mount
- try {
- const stored = localStorage.getItem(STORAGE_KEY);
- // Default to collapsed (true) to reduce visual clutter
- return stored ? JSON.parse(stored) : true;
- } catch (error) {
- logger.warn('Error reading detailed view state from localStorage', { error });
- return true;
- }
- });
+ const { user } = useAuth();
+ const [isCollapsed, setIsCollapsed] = useState(true);
+ const [loading, setLoading] = useState(true);
- // Sync to localStorage when state changes
+ // Load preferences on mount
useEffect(() => {
- try {
- localStorage.setItem(STORAGE_KEY, JSON.stringify(isCollapsed));
- } catch (error) {
- logger.warn('Error saving detailed view state to localStorage', { error });
- }
- }, [isCollapsed]);
+ loadPreferences();
+ }, [user]);
- const toggle = () => setIsCollapsed(prev => !prev);
+ const loadPreferences = async () => {
+ try {
+ if (user) {
+ // Load from database for authenticated users
+ const { data, error } = await supabase
+ .from('user_preferences')
+ .select('moderation_preferences')
+ .eq('user_id', user.id)
+ .maybeSingle();
+
+ if (error && error.code !== 'PGRST116') {
+ handleNonCriticalError(error, {
+ action: 'Load moderation preferences',
+ userId: user.id,
+ });
+ }
+
+ if (data?.moderation_preferences) {
+ const prefs = data.moderation_preferences as ModerationPreferences;
+ setIsCollapsed(prefs.detailed_view_collapsed ?? true);
+ }
+ } else {
+ // Load from localStorage for guests
+ try {
+ const stored = localStorage.getItem(STORAGE_KEY);
+ setIsCollapsed(stored ? JSON.parse(stored) : true);
+ } catch (error) {
+ logger.warn('Error reading detailed view state from localStorage', { error });
+ }
+ }
+ } catch (error) {
+ logger.warn('Error loading detailed view preferences', { error });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const savePreferences = async (collapsed: boolean) => {
+ try {
+ if (user) {
+ // Save to database for authenticated users
+ const moderationPrefs: ModerationPreferences = {
+ detailed_view_collapsed: collapsed,
+ };
+
+ const { error } = await supabase
+ .from('user_preferences')
+ .upsert({
+ user_id: user.id,
+ moderation_preferences: moderationPrefs as unknown as Json,
+ updated_at: new Date().toISOString(),
+ }, {
+ onConflict: 'user_id',
+ });
+
+ if (error) {
+ handleNonCriticalError(error, {
+ action: 'Save moderation preferences',
+ userId: user.id,
+ });
+ }
+ } else {
+ // Save to localStorage for guests
+ try {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(collapsed));
+ } catch (error) {
+ logger.warn('Error saving detailed view state to localStorage', { error });
+ }
+ }
+ } catch (error) {
+ logger.warn('Error saving detailed view preferences', { error });
+ }
+ };
+
+ const toggle = () => {
+ const newValue = !isCollapsed;
+ setIsCollapsed(newValue);
+ savePreferences(newValue);
+ };
- const setCollapsed = (value: boolean) => setIsCollapsed(value);
+ const setCollapsed = (value: boolean) => {
+ setIsCollapsed(value);
+ savePreferences(value);
+ };
return {
isCollapsed,
toggle,
setCollapsed,
+ loading,
};
}