/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * BCFTopicList - Topic list with filtering and sorting for the BCF panel. */ import React, { useCallback, useState, useMemo } from 'react'; import { Plus, MessageSquare, Camera, Filter, Edit2, User, Calendar, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { ScrollArea } from '@/components/ui/scroll-area'; import type { BCFTopic } from '@ifc-lite/bcf'; import { StatusBadge, PriorityBadge, formatDate, TOPIC_STATUSES } from './bcfHelpers'; // ============================================================================ // Types // ============================================================================ export interface BCFTopicListProps { topics: BCFTopic[]; onSelectTopic: (topicId: string) => void; onCreateTopic: () => void; statusFilter: string; onStatusFilterChange: (status: string) => void; author: string; onSetAuthor: (author: string) => void; } // ============================================================================ // Component // ============================================================================ export function BCFTopicList({ topics, onSelectTopic, onCreateTopic, statusFilter, onStatusFilterChange, author, onSetAuthor, }: BCFTopicListProps) { const [editingEmail, setEditingEmail] = useState(false); const [emailInput, setEmailInput] = useState(author); const isDefaultEmail = author === 'user@example.com'; const handleSaveEmail = useCallback(() => { if (emailInput.trim() && emailInput.includes('@')) { onSetAuthor(emailInput.trim()); setEditingEmail(false); } }, [emailInput, onSetAuthor]); const filteredTopics = useMemo(() => { if (!statusFilter || statusFilter === 'all') return topics; return topics.filter( (t) => t.topicStatus?.toLowerCase() === statusFilter.toLowerCase() ); }, [topics, statusFilter]); // Sort by creation date (newest first) const sortedTopics = useMemo(() => { return [...filteredTopics].sort( (a, b) => new Date(b.creationDate).getTime() - new Date(a.creationDate).getTime() ); }, [filteredTopics]); return (
{/* Filter */}
{/* Topic List */} {sortedTopics.length === 0 ? (

No topics

{/* Email setup nudge */}
{editingEmail ? (
setEmailInput(e.target.value)} placeholder="your@email.com" className="h-8 text-sm" onKeyDown={(e) => { if (e.key === 'Enter') handleSaveEmail(); if (e.key === 'Escape') setEditingEmail(false); }} autoFocus />
) : (

Author

{author}

)}
{isDefaultEmail && !editingEmail && (

Set your email to identify your issues and comments

)}
) : (
{sortedTopics.map((topic) => ( ))}
)}
); }