Series auto complete

This commit is contained in:
Stefan Hardegger
2025-08-18 14:19:14 +02:00
parent 6b97c0a70f
commit 241a15a174
3 changed files with 333 additions and 8 deletions

View File

@@ -10,6 +10,7 @@ import TagInput from '../../components/stories/TagInput';
import RichTextEditor from '../../components/stories/RichTextEditor';
import ImageUpload from '../../components/ui/ImageUpload';
import AuthorSelector from '../../components/stories/AuthorSelector';
import SeriesSelector from '../../components/stories/SeriesSelector';
import { storyApi, authorApi } from '../../lib/api';
export default function AddStoryPage() {
@@ -22,6 +23,7 @@ export default function AddStoryPage() {
sourceUrl: '',
tags: [] as string[],
seriesName: '',
seriesId: undefined as string | undefined,
volume: '',
});
@@ -208,6 +210,19 @@ export default function AddStoryPage() {
}
};
const handleSeriesChange = (seriesName: string, seriesId?: string) => {
setFormData(prev => ({
...prev,
seriesName,
seriesId: seriesId // This will be undefined if creating new series, which clears the existing ID
}));
// Clear error when user changes series
if (errors.seriesName) {
setErrors(prev => ({ ...prev, seriesName: '' }));
}
};
const validateForm = () => {
const newErrors: Record<string, string> = {};
@@ -252,7 +267,8 @@ export default function AddStoryPage() {
contentHtml: formData.contentHtml,
sourceUrl: formData.sourceUrl || undefined,
volume: formData.seriesName ? parseInt(formData.volume) : undefined,
seriesName: formData.seriesName || undefined,
// Send seriesId if we have it (existing series), otherwise send seriesName (new series)
...(formData.seriesId ? { seriesId: formData.seriesId } : { seriesName: formData.seriesName || undefined }),
// Send authorId if we have it (existing author), otherwise send authorName (new author)
...(formData.authorId ? { authorId: formData.authorId } : { authorName: formData.authorName }),
tagNames: formData.tags.length > 0 ? formData.tags : undefined,
@@ -405,12 +421,13 @@ export default function AddStoryPage() {
{/* Series and Volume */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Input
<SeriesSelector
label="Series (optional)"
value={formData.seriesName}
onChange={handleInputChange('seriesName')}
placeholder="Enter series name if part of a series"
onChange={handleSeriesChange}
placeholder="Select or enter series name if part of a series"
error={errors.seriesName}
authorId={formData.authorId}
/>
<Input

View File

@@ -10,6 +10,7 @@ import TagSuggestions from '../../../../components/tags/TagSuggestions';
import RichTextEditor from '../../../../components/stories/RichTextEditor';
import ImageUpload from '../../../../components/ui/ImageUpload';
import AuthorSelector from '../../../../components/stories/AuthorSelector';
import SeriesSelector from '../../../../components/stories/SeriesSelector';
import LoadingSpinner from '../../../../components/ui/LoadingSpinner';
import { storyApi } from '../../../../lib/api';
import { Story } from '../../../../types/api';
@@ -33,6 +34,7 @@ export default function EditStoryPage() {
sourceUrl: '',
tags: [] as string[],
seriesName: '',
seriesId: undefined as string | undefined,
volume: '',
});
@@ -55,6 +57,7 @@ export default function EditStoryPage() {
sourceUrl: storyData.sourceUrl || '',
tags: storyData.tags?.map(tag => tag.name) || [],
seriesName: storyData.seriesName || '',
seriesId: storyData.seriesId,
volume: storyData.volume?.toString() || '',
});
} catch (error) {
@@ -117,6 +120,19 @@ export default function EditStoryPage() {
}
};
const handleSeriesChange = (seriesName: string, seriesId?: string) => {
setFormData(prev => ({
...prev,
seriesName,
seriesId: seriesId // This will be undefined if creating new series, which clears the existing ID
}));
// Clear error when user changes series
if (errors.seriesName) {
setErrors(prev => ({ ...prev, seriesName: '' }));
}
};
const validateForm = () => {
const newErrors: Record<string, string> = {};
@@ -161,7 +177,8 @@ export default function EditStoryPage() {
contentHtml: formData.contentHtml,
sourceUrl: formData.sourceUrl || undefined,
volume: formData.seriesName && formData.volume ? parseInt(formData.volume) : undefined,
seriesName: formData.seriesName, // Send empty string to explicitly clear series
// Send seriesId if we have it (existing series), otherwise send seriesName (new/changed series)
...(formData.seriesId ? { seriesId: formData.seriesId } : { seriesName: formData.seriesName }),
// Send authorId if we have it (existing author), otherwise send authorName (new/changed author)
...(formData.authorId ? { authorId: formData.authorId } : { authorName: formData.authorName }),
tagNames: formData.tags,
@@ -326,12 +343,13 @@ export default function EditStoryPage() {
{/* Series and Volume */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<Input
<SeriesSelector
label="Series (optional)"
value={formData.seriesName}
onChange={handleInputChange('seriesName')}
placeholder="Enter series name if part of a series"
onChange={handleSeriesChange}
placeholder="Select or enter series name if part of a series"
error={errors.seriesName}
authorId={formData.authorId}
/>
</div>