feat(desktop): empty-state for chat list

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
byGalax
2026-05-16 16:51:37 +02:00
parent 502c6af1b8
commit b7d7a85253
+24 -22
View File
@@ -2,10 +2,11 @@ import { acceptDm, type ConversationSummary, isConversationMuted } from '@chat-a
import { extractErrorCode } from '@chat-app/shared/i18n'; import { extractErrorCode } from '@chat-app/shared/i18n';
import { useEffect, useMemo, useRef, useState } from 'react'; import { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NavLink, Outlet, useParams } from 'react-router-dom'; import { NavLink, Outlet, useNavigate, useParams } from 'react-router-dom';
import { ConversationRowMenu } from '../components/ConversationRowMenu'; import { ConversationRowMenu } from '../components/ConversationRowMenu';
import { CreateGroupDialog } from '../components/CreateGroupDialog'; import { CreateGroupDialog } from '../components/CreateGroupDialog';
import { EmptyState } from '../components/EmptyState';
import { import {
AddUserIcon, AddUserIcon,
ArchiveIcon, ArchiveIcon,
@@ -119,6 +120,7 @@ function ConversationList({
archivedCount, archivedCount,
}: ConversationListProps) { }: ConversationListProps) {
const { t } = useTranslation(['app']); const { t } = useTranslation(['app']);
const navigate = useNavigate();
return ( return (
<aside <aside
@@ -223,27 +225,27 @@ function ConversationList({
) : error ? ( ) : error ? (
<p className="px-4 py-2 text-xs text-rose-500 dark:text-rose-300">{error}</p> <p className="px-4 py-2 text-xs text-rose-500 dark:text-rose-300">{error}</p>
) : items.length === 0 ? ( ) : items.length === 0 ? (
<div className="flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center"> showArchived ? (
<div className="flex h-12 w-12 items-center justify-center rounded-2xl border border-line bg-surface-3 text-accent"> <EmptyState
{showArchived ? ( icon={<ArchiveIcon className="h-8 w-8" />}
<ArchiveIcon className="h-5 w-5" /> title={t('app:chats.archived_empty_title', { defaultValue: 'Nichts archiviert' })}
) : ( description={t('app:chats.archived_empty_subtitle', {
<ChatBubbleIcon className="h-5 w-5" /> defaultValue: 'Archivierte Unterhaltungen erscheinen hier.',
)} })}
</div> />
<p className="text-sm text-fg-muted"> ) : (
{showArchived <EmptyState
? t('app:chats.archived_empty_title', { defaultValue: 'Nichts archiviert' }) icon={<ChatBubbleIcon className="h-8 w-8" />}
: t('app:chats.empty_title')} title={t('app:chats.empty_title', { defaultValue: 'Noch keine Chats' })}
</p> description={t('app:chats.empty_desc', {
<p className="text-xs text-fg-muted/80"> defaultValue: 'Lade einen Freund ein und schreibe die erste Nachricht.',
{showArchived })}
? t('app:chats.archived_empty_subtitle', { action={{
defaultValue: 'Archivierte Unterhaltungen erscheinen hier.', label: t('app:chats.empty_cta', { defaultValue: 'Freunde verwalten' }),
}) onClick: () => navigate('/friends'),
: t('app:chats.empty_subtitle')} }}
</p> />
</div> )
) : ( ) : (
<VirtualConversationList <VirtualConversationList
items={items} items={items}