random story selector

This commit is contained in:
Stefan Hardegger
2025-08-13 14:48:40 +02:00
parent 142d8328c2
commit 4ab03953ae
5 changed files with 280 additions and 1 deletions

View File

@@ -1,7 +1,8 @@
'use client';
import { useState, useEffect } from 'react';
import { searchApi } from '../../lib/api';
import { useRouter } from 'next/navigation';
import { searchApi, storyApi } from '../../lib/api';
import { Story, Tag, FacetCount } from '../../types/api';
import AppLayout from '../../components/layout/AppLayout';
import { Input } from '../../components/ui/Input';
@@ -14,10 +15,12 @@ type ViewMode = 'grid' | 'list';
type SortOption = 'createdAt' | 'title' | 'authorName' | 'rating' | 'wordCount' | 'lastRead';
export default function LibraryPage() {
const router = useRouter();
const [stories, setStories] = useState<Story[]>([]);
const [tags, setTags] = useState<Tag[]>([]);
const [loading, setLoading] = useState(false);
const [searchLoading, setSearchLoading] = useState(false);
const [randomLoading, setRandomLoading] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const [viewMode, setViewMode] = useState<ViewMode>('list');
@@ -139,6 +142,44 @@ export default function LibraryPage() {
setRefreshTrigger(prev => prev + 1);
};
const handleRandomStory = async () => {
try {
setRandomLoading(true);
// Build filter parameters based on current UI state
const filters: Record<string, any> = {};
// Include search query if present
if (searchQuery && searchQuery.trim() !== '' && searchQuery !== '*') {
filters.searchQuery = searchQuery.trim();
}
// Include all selected tags
if (selectedTags.length > 0) {
filters.tags = selectedTags;
}
console.log('Getting random story with filters:', filters);
const randomStory = await storyApi.getRandomStory(filters);
if (!randomStory) {
// No stories match the current filters
alert('No stories match your current filters. Try clearing some filters or adding more stories to your library.');
return;
}
// Navigate to the random story's reading page
router.push(`/stories/${randomStory.id}/read`);
} catch (error) {
console.error('Failed to get random story:', error);
alert('Failed to get a random story. Please try again.');
} finally {
setRandomLoading(false);
}
};
if (loading) {
return (
<AppLayout>
@@ -163,6 +204,13 @@ export default function LibraryPage() {
</div>
<div className="flex gap-2">
<Button
onClick={handleRandomStory}
disabled={randomLoading || totalElements === 0}
variant="secondary"
>
{randomLoading ? '🎲 ...' : '🎲 Random Story'}
</Button>
<Button href="/import">
Add New Story
</Button>