fix series number and improve author view

This commit is contained in:
Stefan Hardegger
2026-07-20 12:51:20 +02:00
parent ddfc5aef99
commit d910ad8fa8
4 changed files with 79 additions and 27 deletions

View File

@@ -489,7 +489,8 @@ export default function AddStoryContent() {
<Input
label="Volume/Part (optional)"
type="number"
min="1"
min="0.1"
step="any"
value={formData.volume}
onChange={handleInputChange('volume')}
placeholder="Enter volume/part number"

View File

@@ -11,6 +11,39 @@ import Button from '../../../components/ui/Button';
import StoryCard from '../../../components/stories/StoryCard';
import LoadingSpinner from '../../../components/ui/LoadingSpinner';
type DisplayItem =
| { type: 'standalone'; story: Story }
| { type: 'series'; seriesId: string; seriesName: string; stories: Story[] };
function buildDisplayItems(stories: Story[], authorId: string): DisplayItem[] {
const authorStories = stories.filter(s => s.authorId === authorId);
const sorted = [...authorStories].sort(
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
);
const items: DisplayItem[] = [];
const addedSeries = new Set<string>();
for (const story of sorted) {
if (story.seriesId) {
if (!addedSeries.has(story.seriesId)) {
const seriesStories = sorted.filter(s => s.seriesId === story.seriesId);
items.push({
type: 'series',
seriesId: story.seriesId,
seriesName: story.seriesName!,
stories: seriesStories,
});
addedSeries.add(story.seriesId);
}
} else {
items.push({ type: 'standalone', story });
}
}
return items;
}
export default function AuthorDetailPage() {
const params = useParams();
const router = useRouter();
@@ -220,17 +253,37 @@ export default function AuthorDetailPage() {
</div>
) : (
<div className="space-y-4">
{stories.map((story) => (
<StoryCard
key={story.id}
story={story}
viewMode="list"
onUpdate={() => {
// Reload stories after update
window.location.reload();
}}
/>
))}
{buildDisplayItems(stories, authorId).map((item) => {
if (item.type === 'standalone') {
return (
<StoryCard
key={item.story.id}
story={item.story}
viewMode="list"
onUpdate={() => window.location.reload()}
/>
);
}
return (
<div key={item.seriesId}>
<div className="flex items-center gap-2 mb-2 px-1">
<span className="text-xs font-semibold theme-text uppercase tracking-wide opacity-60">Series</span>
<span className="font-semibold theme-header">{item.seriesName}</span>
<span className="text-xs theme-text opacity-60">({item.stories.length} {item.stories.length === 1 ? 'part' : 'parts'})</span>
</div>
<div className="space-y-4 pl-4 border-l-2 border-gray-300 dark:border-gray-600">
{item.stories.map((story) => (
<StoryCard
key={story.id}
story={story}
viewMode="list"
onUpdate={() => window.location.reload()}
/>
))}
</div>
</div>
);
})}
</div>
)}
</div>

View File

@@ -439,7 +439,8 @@ export default function EditStoryPage() {
<Input
label="Volume/Part (optional)"
type="number"
min="1"
min="0.1"
step="any"
value={formData.volume}
onChange={handleInputChange('volume')}
placeholder="Enter volume/part number"