source: chapterx-frontend/src/pages/browse/GenrePage.tsx@ b62cefc

main
Last change on this file since b62cefc was b62cefc, checked in by kikisrbinoska <srbinoskakristina07@…>, 4 months ago

Added frontend and imporoved AI Suggestions service

  • Property mode set to 100644
File size: 3.1 KB
Line 
1import React from 'react'
2import { useParams, useNavigate } from 'react-router-dom'
3import { ArrowLeft } from 'lucide-react'
4import { useStoryStore } from '../../store/storyStore'
5import { StoryGrid } from '../../components/story/StoryGrid'
6import { getGenreGradient } from '../../components/story/GenreBadge'
7
8function toTitleCase(s: string) {
9 return s.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())
10}
11
12export const GenrePage: React.FC = () => {
13 const { genre } = useParams<{ genre: string }>()
14 const navigate = useNavigate()
15 const { stories } = useStoryStore()
16
17 const genreName = toTitleCase(genre || '')
18 const gradient = getGenreGradient(genreName)
19 const filtered = stories.filter(
20 s => s.status === 'published' && s.genres.some(g => g.toLowerCase() === genreName.toLowerCase())
21 )
22
23 return (
24 <div className="max-w-7xl mx-auto px-4 py-8">
25 {/* Hero */}
26 <div className={`relative rounded-2xl overflow-hidden mb-8 h-40 bg-gradient-to-br ${gradient}`}>
27 <div className="absolute inset-0 flex flex-col justify-end p-8">
28 <button
29 onClick={() => navigate('/genres')}
30 className="flex items-center gap-2 text-white/70 hover:text-white text-sm mb-3 transition-colors w-fit"
31 >
32 <ArrowLeft size={16} />
33 All Genres
34 </button>
35 <h1 className="font-serif text-3xl font-bold text-white">{genreName}</h1>
36 <p className="text-white/70 text-sm mt-1">{filtered.length} stories</p>
37 </div>
38 <div className="absolute top-4 right-8 w-32 h-32 rounded-full bg-white/5 blur-xl" />
39 </div>
40
41 <StoryGrid
42 stories={filtered}
43 emptyMessage={`No ${genreName} stories published yet.`}
44 />
45 </div>
46 )
47}
48
49export const GenresListPage: React.FC = () => {
50 const navigate = useNavigate()
51 const { genres } = useStoryStore()
52
53 return (
54 <div className="max-w-7xl mx-auto px-4 py-8">
55 <div className="mb-8">
56 <h1 className="font-serif text-3xl font-bold text-white mb-2">Explore Genres</h1>
57 <p className="text-slate-400">Find stories by your favorite genre</p>
58 </div>
59 <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
60 {genres.map(genre => {
61 const gradient = getGenreGradient(genre.name)
62 return (
63 <button
64 key={genre.genre_id}
65 onClick={() => navigate(`/genres/${genre.name.toLowerCase().replace(' ', '-')}`)}
66 className={`relative rounded-2xl overflow-hidden h-32 bg-gradient-to-br ${gradient} hover:scale-105 transition-transform group`}
67 >
68 <div className="absolute inset-0 flex flex-col items-center justify-center p-4">
69 <p className="font-serif font-semibold text-white text-center">{genre.name}</p>
70 <p className="text-white/60 text-xs mt-1">{genre.story_count} stories</p>
71 </div>
72 <div className="absolute inset-0 bg-black/20 group-hover:bg-black/10 transition-colors" />
73 </button>
74 )
75 })}
76 </div>
77 </div>
78 )
79}
Note: See TracBrowser for help on using the repository browser.