- Deleted redundant components (`AddActionButton`, `AlertBox`, `AlertStack`, `BackButton`, `CancelButton`, and `CollapsableArea`) and related files. - Removed unused models (`Book`, `BookSerie`, `BookTables`, `Character`, and `Chapter`) to reduce codebase clutter. - Updated project structure and references to reflect these removals.
92 lines
3.7 KiB
TypeScript
92 lines
3.7 KiB
TypeScript
import {Bot} from 'lucide-react';
|
|
import React, {useContext, useEffect, useState} from 'react';
|
|
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
|
|
import {ConversationProps} from "@/lib/types/quillsense";
|
|
import {apiGet} from '@/lib/api/client';
|
|
import {BookContext, BookContextProps} from "@/context/BookContext";
|
|
import {LangContext, LangContextProps} from "@/context/LangContext";
|
|
import {AlertContext, AlertContextProps} from "@/context/AlertContext";
|
|
import {useTranslations} from '@/lib/i18n';
|
|
import Badge from "@/components/ui/Badge";
|
|
|
|
interface QuillListProps {
|
|
handleSelectConversation: (itemId: string) => void;
|
|
}
|
|
|
|
export default function QuillList({handleSelectConversation}: QuillListProps): React.JSX.Element {
|
|
const t = useTranslations();
|
|
const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
|
|
const {book}: BookContextProps = useContext<BookContextProps>(BookContext);
|
|
const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
|
|
const {errorMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
|
|
|
|
const [conversations, setConversations] = useState<ConversationProps[]>([]);
|
|
|
|
useEffect((): void => {
|
|
getConversations().then();
|
|
}, []);
|
|
|
|
async function getConversations(): Promise<void> {
|
|
try {
|
|
const response: ConversationProps[] = await apiGet<ConversationProps[]>(
|
|
`quillsense/conversations`,
|
|
session.accessToken,
|
|
lang,
|
|
{
|
|
id: book?.bookId,
|
|
}
|
|
);
|
|
if (response.length > 0) {
|
|
setConversations(response);
|
|
}
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
errorMessage(e.message);
|
|
} else {
|
|
errorMessage(t('quillList.error.unknown'));
|
|
}
|
|
}
|
|
}
|
|
|
|
function getStatusColorClass(status: number): string {
|
|
switch (status) {
|
|
case 1:
|
|
return 'bg-muted';
|
|
case 2:
|
|
return 'bg-accent-blue';
|
|
case 3:
|
|
return 'bg-primary';
|
|
case 4:
|
|
return 'bg-error';
|
|
default:
|
|
return 'bg-muted';
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="flex-1 overflow-y-auto p-2">
|
|
{conversations.map((conversation: ConversationProps): React.JSX.Element => (
|
|
<div key={conversation.id}
|
|
className="flex items-center justify-between p-3 mb-2 rounded-xl bg-tertiary hover:bg-secondary cursor-pointer transition-colors duration-150"
|
|
onClick={(): void => handleSelectConversation(conversation.id)}
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className={`w-2.5 h-2.5 rounded-full ${getStatusColorClass(conversation.status)}`}></div>
|
|
<Bot className="text-primary w-5 h-5" strokeWidth={1.75}/>
|
|
<div>
|
|
<span
|
|
className="text-text-primary font-medium">{conversation.title || t('quillList.untitled')}</span>
|
|
{conversation.startDate && (
|
|
<p className="text-xs text-muted mt-0.5">{conversation.startDate}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{conversation.mode && (
|
|
<Badge size="sm">{conversation.mode}</Badge>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
} |