added frontend for social + feed partiali working

This commit is contained in:
2026-05-18 02:25:47 +02:00
parent e1df55df0e
commit 202ce22102
88 changed files with 4236 additions and 737 deletions

View File

@@ -0,0 +1,86 @@
import { useState, useMemo } from "react";
import { NavLink } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { FiSearch, FiPlus } from "react-icons/fi";
import { useApiSocialChatsList } from "@/api/generated/private/chat/chat";
import Avatar from "@/components/ui/Avatar";
import Spinner from "@/components/ui/Spinner";
import EmptyState from "@/components/ui/EmptyState";
import IconButton from "@/components/ui/IconButton";
export default function ChatSidebar() {
const { t } = useTranslation("social");
const [query, setQuery] = useState("");
const { data, isLoading } = useApiSocialChatsList(
query ? { search: query } : undefined,
);
const chats = useMemo(() => data?.results ?? [], [data]);
return (
<aside className="flex h-full flex-col border-r border-brand-lines/15">
<header className="flex items-center justify-between gap-2 border-b border-brand-lines/10 px-3 py-3">
<h2 className="text-sm font-semibold text-brand-text">
{t("chat.sidebar.title")}
</h2>
<IconButton icon={<FiPlus size={16} />} label={t("chat.sidebar.new")} />
</header>
<div className="relative px-3 py-2">
<FiSearch
className="absolute left-5 top-1/2 -translate-y-1/2 text-brand-text/50"
size={14}
/>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder={t("chat.sidebar.search")}
className="w-full rounded-xl bg-brand-bgLight/40 border border-brand-lines/20 py-2 pl-8 pr-2 text-sm text-brand-text placeholder:text-brand-text/40 focus:outline-none focus:border-brand-accent"
/>
</div>
<div className="flex-1 overflow-y-auto">
{isLoading && (
<div className="flex justify-center py-6">
<Spinner size={20} />
</div>
)}
{!isLoading && chats.length === 0 && (
<EmptyState message={t("chat.sidebar.empty")} />
)}
<ul>
{chats.map((chat) => (
<li key={chat.id}>
<NavLink
to={`/social/chats/${chat.id}`}
className={({ isActive }) =>
[
"flex items-center gap-3 px-3 py-2.5 hover:bg-brand-lines/10 transition-colors",
isActive ? "bg-brand-lines/10" : "",
].join(" ")
}
>
<Avatar
name={chat.name ?? `chat ${chat.id}`}
src={chat.icon ?? undefined}
size={36}
/>
<div className="min-w-0 flex-1">
<div className="truncate text-sm font-semibold text-brand-text">
{chat.name || `Chat #${chat.id}`}
</div>
<div className="truncate text-xs text-brand-text/60">
{chat.chat_type}
</div>
</div>
</NavLink>
</li>
))}
</ul>
</div>
</aside>
);
}