import React, { useState, useEffect, useMemo } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { T, translate } from '@/i18n'; import { Search, FileText, Check, Users, User } from 'lucide-react'; import { useAuth } from '@/hooks/useAuth'; import { cn } from '@/lib/utils'; import { fetchFeed } from '@/modules/feed/client-feed'; /** Simplified page shape returned from the feed API */ interface FeedPage { id: string; title: string; slug: string; // from meta.slug user_id: string; // owner UUID author?: { display_name?: string; username?: string }; } interface PagePickerDialogProps { isOpen: boolean; onClose: () => void; onSelect: (page: FeedPage | null) => void; currentValue?: string | null; forbiddenIds?: string[]; } export const PagePickerDialog: React.FC = ({ isOpen, onClose, onSelect, currentValue, forbiddenIds = [] }) => { const { user } = useAuth(); const [pages, setPages] = useState([]); const [loading, setLoading] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [selectedId, setSelectedId] = useState(currentValue || null); const [showAllUsers, setShowAllUsers] = useState(false); useEffect(() => { if (isOpen) { fetchPages(); setSelectedId(currentValue || null); } }, [isOpen, currentValue, showAllUsers]); const fetchPages = async () => { setLoading(true); try { const feedItems: any[] = await fetchFeed({ contentType: 'pages', limit: 200, sortBy: 'latest', visibilityFilter: 'invisible', ...(!showAllUsers && user?.id ? { source: 'user', sourceId: user.id } : {}), }); // Transform feed items into simple page objects const transformed: FeedPage[] = feedItems .filter((item: any) => item.type === 'page-intern' || item.meta?.slug) .map((item: any) => ({ id: item.id, title: item.title || 'Untitled', slug: item.meta?.slug || item.slug || item.id, user_id: item.user_id || item.owner || '', author: item.author, })); setPages(transformed); } catch (err) { console.error('Error fetching pages:', err); } finally { setLoading(false); } }; const filteredPages = useMemo(() => { return pages .filter(page => !forbiddenIds.includes(page.id)) .filter(page => { const q = searchQuery.toLowerCase(); return page.title.toLowerCase().includes(q) || page.slug.toLowerCase().includes(q) || (page.author?.display_name || '').toLowerCase().includes(q); }); }, [pages, searchQuery, forbiddenIds]); const handleConfirm = () => { if (selectedId) { const selectedPage = pages.find(p => p.id === selectedId) || null; onSelect(selectedPage); } else { onSelect(null); } onClose(); }; const handleClear = () => { setSelectedId(null); }; return ( Select Page Choose a page to link in the menu. {/* Search + scope toggle */}
setSearchQuery(e.target.value)} className="pl-10" />
{/* Pages Grid */}
{loading ? (
) : filteredPages.length === 0 ? (

{searchQuery ? 'No pages found' : 'No pages available'}

) : (
{/* Option for None */}
/

None

Clear selection

{selectedId === null && }
{filteredPages.map((page) => (
setSelectedId(page.id)} onDoubleClick={() => { setSelectedId(page.id); onSelect(page); onClose(); }} className={cn( "cursor-pointer rounded-lg border-2 p-3 flex items-center gap-3 transition-all hover:border-primary/50 bg-background", selectedId === page.id ? "border-primary" : "border-transparent" )} >

{page.title}

/{page.slug} {showAllUsers && page.author?.display_name && ( • {page.author.display_name} )}

{selectedId === page.id && }
))}
)}
{/* Actions */}
); };