Files
ERitors-Scribe-Desktop/components/book/settings/story/act/ActIncidents.tsx
natreex 64ed90d993 Remove unused components and models for improved maintainability
- 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.
2026-03-22 22:37:31 -04:00

172 lines
9.3 KiB
TypeScript

import React, {useState} from 'react';
import {ChevronDown, ChevronUp, Plus, Trash2} from 'lucide-react';
import {Incident} from '@/lib/types/book';
import {ActChapter, ChapterListProps} from '@/lib/types/chapter';
import ActChapterItem from './ActChapter';
import IconButton from '@/components/ui/IconButton';
import Collapse from '@/components/ui/Collapse';
import SelectBox, {SelectBoxProps} from '@/components/form/SelectBox';
import InputField from '@/components/form/InputField';
import TextInput from '@/components/form/TextInput';
import {useTranslations} from '@/lib/i18n';
interface ActIncidentsProps {
incidents: Incident[];
actId: number;
mainChapters: ChapterListProps[];
newIncidentTitle: string;
setNewIncidentTitle: (title: string) => void;
onAddIncident: (actId: number) => Promise<void>;
onDeleteIncident: (actId: number, incidentId: string) => Promise<void>;
onLinkChapter: (actId: number, chapterId: string, incidentId: string) => Promise<void>;
onUpdateChapterSummary: (chapterId: string, summary: string, incidentId: string) => void;
onUnlinkChapter: (chapterInfoId: string, chapterId: string, incidentId: string) => Promise<void>;
sectionKey: string;
isExpanded: boolean;
onToggleSection: (sectionKey: string) => void;
}
export default function ActIncidents({
incidents,
actId,
mainChapters,
newIncidentTitle,
setNewIncidentTitle,
onAddIncident,
onDeleteIncident,
onLinkChapter,
onUpdateChapterSummary,
onUnlinkChapter,
sectionKey,
isExpanded,
onToggleSection,
}: ActIncidentsProps) {
const t = useTranslations('actComponent');
const [expandedItems, setExpandedItems] = useState<{ [key: string]: boolean }>({});
const [selectedChapterId, setSelectedChapterId] = useState<string>('');
function toggleItem(itemKey: string): void {
setExpandedItems(prev => ({
...prev,
[itemKey]: !prev[itemKey],
}));
}
function mainChaptersData(): SelectBoxProps[] {
return mainChapters.map(function (chapter: ChapterListProps): SelectBoxProps {
return {
value: chapter.chapterId,
label: `${chapter.chapterOrder}. ${chapter.title}`,
};
});
}
return (
<Collapse title={t('incidentsTitle')} defaultOpen={isExpanded}>
<div className="space-y-3">
{incidents && incidents.length > 0 ? (
incidents.map(function (item: Incident): React.JSX.Element {
const itemKey: string = `incident_${item.incidentId}`;
const isItemExpanded: boolean = expandedItems[itemKey];
return (
<div key={`incident-${item.incidentId}`}
className="bg-secondary rounded-xl overflow-hidden">
<button
className="flex justify-between items-center w-full p-3 text-left"
onClick={function (): void {
toggleItem(itemKey);
}}
>
<span className="font-bold text-text-primary">{item.title}</span>
<div className="flex items-center gap-1">
{isItemExpanded
? <ChevronUp className="text-primary w-3.5 h-3.5" strokeWidth={1.75}/>
: <ChevronDown className="text-primary w-3.5 h-3.5" strokeWidth={1.75}/>
}
<div onClick={function (e: React.MouseEvent): void {
e.stopPropagation();
}}>
<IconButton
icon={Trash2}
variant="danger"
size="sm"
onClick={async function (): Promise<void> {
await onDeleteIncident(actId, item.incidentId);
}}
/>
</div>
</div>
</button>
{isItemExpanded && (
<div className="p-3">
{item.chapters && item.chapters.length > 0 ? (
item.chapters.map(function (chapter: ActChapter): React.JSX.Element {
return (
<ActChapterItem
key={`inc-chapter-${chapter.chapterId}-${chapter.chapterInfoId}`}
chapter={chapter}
onUpdateSummary={function (chapterId: string, summary: string): void {
onUpdateChapterSummary(chapterId, summary, item.incidentId);
}}
onUnlink={function (chapterInfoId: string, chapterId: string): Promise<void> {
return onUnlinkChapter(chapterInfoId, chapterId, item.incidentId);
}}
/>
);
})
) : (
<p className="text-text-secondary text-center text-sm p-2">
{t('noLinkedChapter')}
</p>
)}
<InputField
input={
<SelectBox
defaultValue={null}
onChangeCallBack={function (e: React.ChangeEvent<HTMLSelectElement>): void {
setSelectedChapterId(e.target.value);
}}
data={mainChaptersData()}
placeholder={t('selectChapterPlaceholder')}
/>
}
addButtonCallBack={function (): Promise<void> {
return onLinkChapter(actId, selectedChapterId, item.incidentId);
}}
isAddButtonDisabled={selectedChapterId.length === 0}
/>
</div>
)}
</div>
);
})
) : (
<p className="text-text-secondary text-center text-sm p-2">
{t('noIncidentAdded')}
</p>
)}
<InputField
input={
<TextInput
value={newIncidentTitle}
setValue={function (e: React.ChangeEvent<HTMLInputElement>): void {
setNewIncidentTitle(e.target.value);
}}
placeholder={t('newIncidentPlaceholder')}
/>
}
actionIcon={Plus}
addButtonCallBack={function (): Promise<void> {
return onAddIncident(actId);
}}
isAddButtonDisabled={newIncidentTitle.trim() === ''}
/>
</div>
</Collapse>
);
}