feat: enhance layout and styling in CharactersPanel and ChaptersPanel for improved UI

This commit is contained in:
2026-03-13 17:33:50 +08:00
parent 6c91c24e49
commit 96ec3629a2

View File

@@ -1189,7 +1189,7 @@ function CharactersPanel({
if (collapsed && hasChaptersOutline) { if (collapsed && hasChaptersOutline) {
return ( return (
<div className="w-44 shrink-0 flex flex-col border-r border-emerald-500/20 bg-emerald-500/5 overflow-hidden"> <div className="w-44 shrink-0 flex flex-col rounded-xl border border-emerald-500/20 bg-emerald-500/5 overflow-hidden">
<div className="flex items-center justify-between px-2 py-2 shrink-0 border-b border-emerald-500/20"> <div className="flex items-center justify-between px-2 py-2 shrink-0 border-b border-emerald-500/20">
<span className="text-xs font-medium text-emerald-400/80 truncate"> <span className="text-xs font-medium text-emerald-400/80 truncate">
{t('projectCard.chapters.title', { count: detail!.chapters.length })} {t('projectCard.chapters.title', { count: detail!.chapters.length })}
@@ -1198,14 +1198,14 @@ function CharactersPanel({
<PanelLeftOpen className="h-3.5 w-3.5" /> <PanelLeftOpen className="h-3.5 w-3.5" />
</Button> </Button>
</div> </div>
<div className="flex-1 overflow-y-auto"> <div className="flex-1 overflow-y-auto px-2 py-2 space-y-1.5">
{detail!.chapters.map(ch => { {detail!.chapters.map(ch => {
const chTitle = ch.title || t('projectCard.chapters.defaultTitle', { index: ch.chapter_index + 1 }) const chTitle = ch.title || t('projectCard.chapters.defaultTitle', { index: ch.chapter_index + 1 })
const dotClass = ch.status === 'done' ? 'bg-green-400' : ch.status === 'error' ? 'bg-destructive' : ch.status === 'parsing' || ch.status === 'generating' ? 'bg-amber-400' : ch.status === 'ready' ? 'bg-blue-400' : 'bg-muted-foreground/50' const dotClass = ch.status === 'done' ? 'bg-green-400' : ch.status === 'error' ? 'bg-destructive' : ch.status === 'parsing' || ch.status === 'generating' ? 'bg-amber-400' : ch.status === 'ready' ? 'bg-blue-400' : 'bg-muted-foreground/50'
return ( return (
<button <button
key={ch.id} key={ch.id}
className="w-full flex items-center gap-1.5 px-2 py-1.5 text-left hover:bg-muted/60 border-b border-border/30 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1" className="w-full flex items-center gap-1.5 px-3 py-2 text-left rounded-lg border bg-muted/30 shadow-sm hover:bg-muted/60 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
onClick={() => onScrollToChapter(ch.id)} onClick={() => onScrollToChapter(ch.id)}
> >
<span className={`w-1.5 h-1.5 rounded-full shrink-0 ${dotClass}`} /> <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${dotClass}`} />
@@ -1219,7 +1219,7 @@ function CharactersPanel({
} }
return ( return (
<div className="w-72 shrink-0 flex flex-col border-r border-blue-500/20 bg-blue-500/5 overflow-hidden"> <div className="w-72 shrink-0 flex flex-col rounded-xl border border-blue-500/20 bg-blue-500/5 overflow-hidden">
<div className="flex items-center justify-between px-3 py-2 shrink-0"> <div className="flex items-center justify-between px-3 py-2 shrink-0">
<span className="text-xs font-medium text-blue-400/80"> <span className="text-xs font-medium text-blue-400/80">
{t('projectCard.characters.title', { count: charCount })} {t('projectCard.characters.title', { count: charCount })}
@@ -1245,7 +1245,7 @@ function CharactersPanel({
) : ( ) : (
<div className="flex-1 overflow-y-auto px-2 py-2 space-y-1.5"> <div className="flex-1 overflow-y-auto px-2 py-2 space-y-1.5">
{detail.characters.map(char => ( {detail.characters.map(char => (
<div key={char.id} className="border rounded px-3 py-2"> <div key={char.id} className="border rounded-lg px-3 py-2 bg-muted/30 shadow-sm">
{editingCharId === char.id ? ( {editingCharId === char.id ? (
<div className="space-y-2"> <div className="space-y-2">
<Input <Input
@@ -1570,7 +1570,7 @@ function ChaptersPanel({
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
<div className="flex-1 flex flex-col bg-emerald-500/5 overflow-hidden"> <div className="flex-1 flex flex-col rounded-xl border border-emerald-500/20 bg-emerald-500/5 overflow-hidden">
<div className="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between px-3 py-2 shrink-0"> <div className="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between px-3 py-2 shrink-0">
<span className="text-xs font-medium text-emerald-400/80"> <span className="text-xs font-medium text-emerald-400/80">
{t('projectCard.chapters.title', { count: detail?.chapters.length ?? 0 })} {t('projectCard.chapters.title', { count: detail?.chapters.length ?? 0 })}
@@ -2418,7 +2418,7 @@ export default function Audiobook() {
</div> </div>
)} )}
<div className="flex-1 flex overflow-hidden mt-2"> <div className="flex-1 flex overflow-hidden mt-2 px-2 pb-2 gap-2">
<CharactersPanel <CharactersPanel
project={selectedProject} project={selectedProject}
detail={detail} detail={detail}