mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:31:11 -05:00
Changes
This commit is contained in:
54
src/components/moderation/DetailedViewCollapsible.tsx
Normal file
54
src/components/moderation/DetailedViewCollapsible.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
|
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
interface DetailedViewCollapsibleProps {
|
||||||
|
isCollapsed: boolean;
|
||||||
|
onToggle: () => void;
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collapsible wrapper for detailed field-by-field view sections
|
||||||
|
* Provides expand/collapse functionality with visual indicators
|
||||||
|
*/
|
||||||
|
export function DetailedViewCollapsible({
|
||||||
|
isCollapsed,
|
||||||
|
onToggle,
|
||||||
|
children,
|
||||||
|
className
|
||||||
|
}: DetailedViewCollapsibleProps) {
|
||||||
|
return (
|
||||||
|
<Collapsible open={!isCollapsed} onOpenChange={() => onToggle()}>
|
||||||
|
<div className={cn("mt-6 pt-6 border-t", className)}>
|
||||||
|
<CollapsibleTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="w-full flex items-center justify-between hover:bg-muted/50 p-2 h-auto"
|
||||||
|
>
|
||||||
|
<div className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">
|
||||||
|
All Fields (Detailed View)
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-xs text-muted-foreground normal-case font-normal">
|
||||||
|
{isCollapsed ? 'Show' : 'Hide'}
|
||||||
|
</span>
|
||||||
|
{isCollapsed ? (
|
||||||
|
<ChevronDown className="h-4 w-4 text-muted-foreground" />
|
||||||
|
) : (
|
||||||
|
<ChevronUp className="h-4 w-4 text-muted-foreground" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
|
||||||
|
<CollapsibleContent className="mt-3">
|
||||||
|
{children}
|
||||||
|
</CollapsibleContent>
|
||||||
|
</div>
|
||||||
|
</Collapsible>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
src/hooks/useDetailedViewState.ts
Normal file
48
src/hooks/useDetailedViewState.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'detailed-view-collapsed';
|
||||||
|
|
||||||
|
interface UseDetailedViewStateReturn {
|
||||||
|
isCollapsed: boolean;
|
||||||
|
toggle: () => void;
|
||||||
|
setCollapsed: (value: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to manage detailed view collapsed/expanded state
|
||||||
|
* Syncs with localStorage for persistence across sessions
|
||||||
|
* Defaults to collapsed to reduce visual clutter
|
||||||
|
*/
|
||||||
|
export function useDetailedViewState(): UseDetailedViewStateReturn {
|
||||||
|
const [isCollapsed, setIsCollapsed] = useState<boolean>(() => {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sync to localStorage when state changes
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(isCollapsed));
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn('Error saving detailed view state to localStorage', { error });
|
||||||
|
}
|
||||||
|
}, [isCollapsed]);
|
||||||
|
|
||||||
|
const toggle = () => setIsCollapsed(prev => !prev);
|
||||||
|
|
||||||
|
const setCollapsed = (value: boolean) => setIsCollapsed(value);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isCollapsed,
|
||||||
|
toggle,
|
||||||
|
setCollapsed,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user