Submatter/apps/web/components/chat/ChatMessageList.tsx
varutasu fcd6a59a2c
Some checks failed
CI / Lint, type-check, test (push) Failing after 4m25s
Deploy homelab (CT 116) / Deploy to CT 116 (push) Successful in 14m28s
Implement chat sidebar with Favorites/Channels/DMs sections, search/filter, and expansion state
2026-11-02 22:28:55 +00:00

162 lines
No EOL
4.9 KiB
TypeScript

"use client";
import { useState } from "react";
import { useSidebarStore } from "@/lib/stores/sidebar-store";
import { ChatSectionHeader } from "./ChatSectionHeader";
import { ChatListRow } from "./ChatListRow";
import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils";
export interface ChatMessageListProps {
channelId?: string;
}
export function ChatMessageList({ channelId }: ChatMessageListProps = {}) {
const pathname = usePathname();
const isChatRoute = pathname.startsWith("/") && pathname.includes("/chat/");
if (!isChatRoute) return null;
const [searchQuery, setSearchQuery] = useState("");
const [filter, setFilter] = useState("");
const [expandedSections, setExpandedSections] = useState({
favorites: true,
channels: true,
dms: true,
});
const { favorites, channels, dms } = useSidebarStore((state) => ({
favorites: state.favorites,
channels: state.channels,
dms: state.dms,
}));
const toggleSection = (section: "favorites" | "channels" | "dms") =>
setExpandedSections((prev) => ({
...prev,
[section]: !prev[section],
}));
// Filter items based on search query
const filterItems = (items: any[], query: string) => {
if (!query) return items;
return items.filter(
(item) =>
item.label.toLowerCase().includes(query.toLowerCase()) ||
item.preview?.toLowerCase().includes(query.toLowerCase())
);
};
const filteredFavorites = filterItems(favorites, searchQuery);
const filteredChannels = filterItems(channels, searchQuery);
const filteredDms = filterItems(dms, searchQuery);
return (
<div className="chat-message-list flex-1">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-semibold text-foreground">
{channelId ? "Channel Messages" : "Recent Chats"}
</h2>
<button
onClick={() => setExpandedSections((prev) => ({
...prev,
favorites: !prev.favorites,
channels: !prev.channels,
dms: !prev.dms,
}))}
className="text-sm text-indigo-600 hover:text-indigo-800 font-medium"
>
Toggle All Sections
</button>
</div>
<div className="p-2 border-b border-sidebar-border">
<input
type="text"
placeholder="Search chats"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full p-2 border border-sidebar-rounded bg-background"
/>
<select
value={filter}
onChange={(e) => setFilter(e.target.value)}
className="w-full p-2 border border-sidebar-rounded bg-background mt-2"
>
<option value="">All</option>
<option value="unread">Unread</option>
<option value="favorites">Favorites</option>
</select>
</div>
{/* Favorites Section */}
<ChatSectionHeader
title="Favorites"
isExpanded={expandedSections.favorites}
onToggle={() => toggleSection("favorites")}
onAdd={() => console.log("Add to favorites")}
onMore={() => console.log("More options for favorites")}
/>
{expandedSections.favorites && (
<div className="px-2 space-y-1">
{filteredFavorites.map((item) => (
<ChatListRow
key={item.id}
label={item.label}
type={item.type}
id={item.id}
count={item.count}
preview={item.preview}
/>
))}
</div>
)}
{/* Channels Section */}
<ChatSectionHeader
title="Channels"
isExpanded={expandedSections.channels}
onToggle={() => toggleSection("channels")}
onAdd={() => console.log("Add channel")}
onMore={() => console.log("More options for channels")}
/>
{expandedSections.channels && (
<div className="px-2 space-y-1">
{filteredChannels.map((item) => (
<ChatListRow
key={item.id}
label={item.label}
type={item.type}
id={item.id}
count={item.count}
preview={item.preview}
/>
))}
</div>
)}
{/* DMs Section */}
<ChatSectionHeader
title="DMs"
isExpanded={expandedSections.dms}
onToggle={() => toggleSection("dms")}
onAdd={() => console.log("Add DM")}
onMore={() => console.log("More options for DMs")}
/>
{expandedSections.dms && (
<div className="px-2 space-y-1">
{filteredDms.map((item) => (
<ChatListRow
key={item.id}
label={item.label}
type={item.type}
id={item.id}
count={item.count}
preview={item.preview}
/>
))}
</div>
)}
</div>
);
}