Files
ERitors-Scribe-Desktop/components/rightbar/ComposerRightBar.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

225 lines
9.1 KiB
TypeScript

'use client'
import {ExternalLink, Feather, Globe, Info, MapPin, MessageCircle, Users, Wand2, X} from 'lucide-react';
import React, {lazy, Suspense, useContext, useEffect, useState} from "react";
import {BookContext, BookContextProps} from "@/context/BookContext";
import {PanelComponent} from "@/lib/types/editor";
import SectionHeader from "@/components/ui/SectionHeader";
import AboutEditors from "@/components/rightbar/AboutERitors";
import QuillSense from "@/components/quillsense/QuillSenseComponent";
import {useTranslations} from '@/lib/i18n';
import PulseLoader from '@/components/ui/PulseLoader';
import InsetPanel from "@/components/ui/InsetPanel";
import IconButton from "@/components/ui/IconButton";
// Lazy loaded Editor components
const WorldEditor = lazy(function () {
return import('@/components/book/settings/world/editor/WorldEditor');
});
const LocationEditor = lazy(function () {
return import('@/components/book/settings/locations/editor/LocationEditor');
});
const CharacterEditor = lazy(function () {
return import('@/components/book/settings/characters/editor/CharacterEditor');
});
const SpellEditor = lazy(function () {
return import('@/components/book/settings/spells/editor/SpellEditor');
});
interface PanelContentProps {
currentPanelId: number | undefined;
}
function PanelContent({currentPanelId}: PanelContentProps): React.JSX.Element {
return (
<Suspense fallback={<PulseLoader/>}>
{currentPanelId === 1 && <QuillSense/>}
{currentPanelId === 2 && <WorldEditor/>}
{currentPanelId === 3 && <LocationEditor/>}
{currentPanelId === 4 && <CharacterEditor/>}
{currentPanelId === 5 && <SpellEditor/>}
</Suspense>
);
}
export default function ComposerRightBar(): React.JSX.Element {
const {book}: BookContextProps = useContext<BookContextProps>(BookContext);
const t = useTranslations();
const [panelHidden, setPanelHidden] = useState<boolean>(false);
const [currentPanel, setCurrentPanel] = useState<PanelComponent | undefined>();
const [showAbout, setShowAbout] = useState<boolean>(false);
function togglePanel(component: PanelComponent): void {
if (panelHidden) {
if (currentPanel?.id === component.id) {
setPanelHidden(!panelHidden);
return;
}
} else {
setPanelHidden(true);
}
}
const editorComponents: PanelComponent[] = [
{
id: 1,
title: t("composerRightBar.editorComponents.quillSense.title"),
description: t("composerRightBar.editorComponents.quillSense.description"),
badge: t("composerRightBar.editorComponents.quillSense.badge"),
icon: Feather
},
{
id: 2,
title: t("composerRightBar.editorComponents.worlds.title"),
description: t("composerRightBar.editorComponents.worlds.description"),
badge: t("composerRightBar.editorComponents.worlds.badge"),
icon: Globe
},
{
id: 3,
title: t("composerRightBar.editorComponents.locations.title"),
description: t("composerRightBar.editorComponents.locations.description"),
badge: t("composerRightBar.editorComponents.locations.badge"),
icon: MapPin
},
{
id: 4,
title: t("composerRightBar.editorComponents.characters.title"),
description: t("composerRightBar.editorComponents.characters.description"),
badge: t("composerRightBar.editorComponents.characters.badge"),
icon: Users
},
{
id: 5,
title: t("composerRightBar.editorComponents.spells.title"),
description: t("composerRightBar.editorComponents.spells.description"),
badge: t("composerRightBar.editorComponents.spells.badge"),
icon: Wand2
},
];
const homeComponents: PanelComponent[] = [
{
id: 1,
title: t("composerRightBar.homeComponents.about.title"),
description: t("composerRightBar.homeComponents.about.description"),
badge: t("composerRightBar.homeComponents.about.badge"),
icon: Info,
action: function (): void {
setShowAbout(true);
}
},
{
id: 2,
title: t("composerRightBar.homeComponents.facebook.title"),
description: t("composerRightBar.homeComponents.facebook.description"),
badge: t("composerRightBar.homeComponents.facebook.badge"),
icon: ExternalLink,
action: function (): void {
window.open('https://www.facebook.com/profile.php?id=61562628720878', '_blank');
}
},
{
id: 3,
title: t("composerRightBar.homeComponents.discord.title"),
description: t("composerRightBar.homeComponents.discord.description"),
badge: t("composerRightBar.homeComponents.discord.badge"),
icon: MessageCircle,
action: function (): void {
window.open('https://discord.gg/CHXRPvmaXm', '_blank');
}
}
];
function disabled(componentId: number): boolean {
return book === null;
}
useEffect(function (): void {
if (!book) {
setCurrentPanel(undefined);
setPanelHidden(false);
}
}, [book]);
async function handleClosePanel(): Promise<void> {
setPanelHidden(!panelHidden);
}
return (
<div id="right-panel-container" className="flex transition-all duration-300">
{panelHidden && (
<div id="right-panel"
className="bg-tertiary min-w-[450px] max-w-[450px] h-full transition-all duration-300 flex flex-col">
<InsetPanel>
<div className="p-4">
<SectionHeader title={currentPanel?.title ?? ''}
icon={currentPanel?.icon}
actions={<IconButton icon={X} variant="ghost"
onClick={handleClosePanel}/>}/>
</div>
<div className="flex-1 overflow-auto">
<PanelContent currentPanelId={currentPanel?.id}/>
</div>
</InsetPanel>
</div>
)}
<div className="bg-tertiary p-1 flex flex-col space-y-2">
{book ? editorComponents.filter(function (component: PanelComponent): boolean {
if (component.id === 1 && book.quillsenseEnabled === false) {
return false;
}
if (component.id === 2 && !book?.tools?.worlds) {
return false;
}
if (component.id === 3 && !book?.tools?.locations) {
return false;
}
if (component.id === 4 && !book?.tools?.characters) {
return false;
}
if (component.id === 5 && !book?.tools?.spells) {
return false;
}
return true;
}).map(function (component: PanelComponent) {
return (
<IconButton
key={component.id}
icon={component.icon}
variant="ghost"
shape="square"
tooltip={component.title}
disabled={disabled(component.id)}
selected={panelHidden && currentPanel?.id === component.id}
onClick={function (): void {
togglePanel(component);
setCurrentPanel(component);
}}
/>
);
}) : homeComponents.map(function (component: PanelComponent) {
return (
<IconButton
key={component.id}
icon={component.icon}
variant="ghost"
shape="square"
tooltip={component.title}
selected={panelHidden && currentPanel?.id === component.id}
onClick={component.action ?? function (): void {
}}
/>
);
})}
</div>
{showAbout && <AboutEditors onClose={function (): void {
setShowAbout(false);
}}/>}
</div>
);
}