source: chapterx-frontend/src/components/ui/StoryCard.tsx@ 99c1e45

main
Last change on this file since 99c1e45 was 99c1e45, checked in by kikisrbinoska <srbinoskakristina07@…>, 11 days ago

Fixed writer section and admin management

  • Property mode set to 100644
File size: 3.5 KB
Line 
1import React from 'react'
2import { useNavigate } from 'react-router-dom'
3import { Heart, MessageCircle, Lock } from 'lucide-react'
4import { Story } from '../../types'
5import { useAuthStore } from '../../store/authStore'
6import { StatusBadge, GenreBadge } from './Badge'
7import { getGenreGradient } from '../story/GenreBadge'
8
9interface StoryCardProps {
10 story: Story
11 showStatus?: boolean
12}
13
14export const StoryCard: React.FC<StoryCardProps> = ({ story, showStatus = false }) => {
15 const navigate = useNavigate()
16 const { currentUser, showMatureContent } = useAuthStore()
17
18 const isMature = story.mature_content
19 const isGuest = !currentUser
20 const blurContent = isMature && isGuest && !showMatureContent
21
22 const primaryGenre = story.genres[0] || 'Fantasy'
23 const gradient = getGenreGradient(primaryGenre)
24
25 return (
26 <div
27 className="relative group cursor-pointer rounded-xl overflow-hidden bg-slate-800 border border-slate-700 hover:border-indigo-500/50 transition-all duration-300 hover:scale-105 hover:shadow-xl hover:shadow-indigo-500/10"
28 onClick={() => navigate(`/story/${story.story_id}`)}
29 >
30 {/* Cover */}
31 <div className={`relative h-40 bg-gradient-to-br ${gradient} flex items-end p-4`}>
32 {/* Mature ribbon */}
33 {isMature && (
34 <div className="absolute top-2 right-2 bg-rose-500/90 text-white text-xs px-2 py-0.5 rounded-full font-medium flex items-center gap-1">
35 <Lock size={10} />
36 18+
37 </div>
38 )}
39 {/* Status badge */}
40 {showStatus && (
41 <div className="absolute top-2 left-2">
42 <StatusBadge status={story.status} />
43 </div>
44 )}
45 {/* Blur overlay for mature on guest */}
46 {blurContent && (
47 <div className="absolute inset-0 backdrop-blur-md bg-slate-900/60 flex items-center justify-center">
48 <div className="text-center">
49 <Lock size={24} className="text-slate-400 mx-auto mb-1" />
50 <p className="text-xs text-slate-400">Mature Content</p>
51 <p className="text-xs text-slate-500">Login to view</p>
52 </div>
53 </div>
54 )}
55 {/* Genre decorative circles */}
56 <div className="absolute top-4 left-4 w-20 h-20 rounded-full bg-white/5 blur-xl" />
57 <div className="absolute bottom-2 right-8 w-12 h-12 rounded-full bg-white/5 blur-lg" />
58 </div>
59
60 {/* Content */}
61 <div className="p-4">
62 <h3 className="font-serif font-semibold text-white text-sm leading-tight mb-1 line-clamp-2 group-hover:text-indigo-300 transition-colors">
63 {story.title}
64 </h3>
65 <p className="text-slate-500 text-xs mb-2">by {story.author_username}</p>
66 <p className="text-slate-400 text-xs line-clamp-2 mb-3">{story.short_description}</p>
67
68 {/* Genre badges */}
69 <div className="flex flex-wrap gap-1 mb-3">
70 {story.genres.slice(0, 2).map(g => (
71 <GenreBadge key={g} genre={g} />
72 ))}
73 {story.genres.length > 2 && (
74 <span className="text-xs text-slate-500">+{story.genres.length - 2}</span>
75 )}
76 </div>
77
78 {/* Stats */}
79 <div className="flex items-center gap-3 text-slate-500 text-xs">
80 <span className="flex items-center gap-1">
81 <Heart size={12} />
82 {story.total_likes.toLocaleString()}
83 </span>
84 <span className="flex items-center gap-1">
85 <MessageCircle size={12} />
86 {story.total_comments}
87 </span>
88 </div>
89 </div>
90 </div>
91 )
92}
Note: See TracBrowser for help on using the repository browser.