source: chapterx-frontend/src/pages/writer/EditChapterPage.tsx@ a6e33d1

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

Added frontend and imporoved AI Suggestions service

  • Property mode set to 100644
File size: 4.7 KB
Line 
1import React, { useState, useEffect } from 'react'
2import { useParams, useNavigate } from 'react-router-dom'
3import { ArrowLeft, Save, Globe, BookOpen } from 'lucide-react'
4import { useStoryStore } from '../../store/storyStore'
5import { useUIStore } from '../../store/uiStore'
6import { Button } from '../../components/ui/Button'
7import { AISuggestionPanel } from '../../components/writer/AISuggestionPanel'
8
9export const EditChapterPage: React.FC = () => {
10 const { chapterId } = useParams<{ chapterId: string }>()
11 const navigate = useNavigate()
12 const { stories, chapters, updateChapter } = useStoryStore()
13 const { addToast } = useUIStore()
14 const [saving, setSaving] = useState(false)
15
16 const chapter = chapters.find(c => c.chapter_id === Number(chapterId))
17 const story = chapter ? stories.find(s => s.story_id === chapter.story_id) : null
18
19 const [form, setForm] = useState({ title: '', content: '' })
20
21 useEffect(() => {
22 if (chapter) {
23 setForm({ title: chapter.title, content: chapter.content })
24 }
25 }, [chapter?.chapter_id])
26
27 if (!chapter || !story) {
28 return (
29 <div className="max-w-4xl mx-auto px-4 py-20 text-center">
30 <h2 className="text-2xl text-white mb-4">Chapter not found</h2>
31 <Button onClick={() => navigate('/writer')}>Back</Button>
32 </div>
33 )
34 }
35
36 const wordCount = form.content.trim().split(/\s+/).filter(Boolean).length
37
38 const handleSave = async (publish?: boolean) => {
39 setSaving(true)
40 await new Promise(r => setTimeout(r, 400))
41 updateChapter(chapter.chapter_id, {
42 ...form,
43 word_count: wordCount,
44 is_published: publish !== undefined ? publish : chapter.is_published,
45 })
46 addToast('Chapter saved!')
47 setSaving(false)
48 }
49
50 return (
51 <div className="max-w-5xl mx-auto px-4 py-8">
52 {/* Header */}
53 <div className="flex items-center justify-between mb-8">
54 <div className="flex items-center gap-3">
55 <button
56 onClick={() => navigate(`/writer/edit-story/${story.story_id}`)}
57 className="text-slate-400 hover:text-white transition-colors"
58 >
59 <ArrowLeft size={20} />
60 </button>
61 <div>
62 <p className="text-slate-400 text-sm">{story.title} · Chapter {chapter.chapter_number}</p>
63 <h1 className="font-serif text-2xl font-bold text-white">Edit Chapter</h1>
64 </div>
65 </div>
66 <div className="flex gap-2">
67 {!chapter.is_published && (
68 <Button size="sm" variant="secondary" onClick={() => handleSave(true)} loading={saving}>
69 <Globe size={14} />
70 Publish
71 </Button>
72 )}
73 <Button size="sm" onClick={() => handleSave()} loading={saving}>
74 <Save size={14} />
75 Save
76 </Button>
77 </div>
78 </div>
79
80 <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
81 {/* Editor */}
82 <div className="lg:col-span-2 space-y-5">
83 <div>
84 <label className="block text-sm font-medium text-slate-300 mb-1.5">Chapter Title</label>
85 <input
86 value={form.title}
87 onChange={e => setForm(f => ({ ...f, title: e.target.value }))}
88 className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-xl text-white focus:outline-none focus:border-indigo-500 font-serif text-lg"
89 />
90 </div>
91 <div>
92 <div className="flex items-center justify-between mb-1.5">
93 <label className="text-sm font-medium text-slate-300">Content</label>
94 <span className="flex items-center gap-1 text-xs text-slate-500">
95 <BookOpen size={12} />
96 {wordCount.toLocaleString()} words
97 </span>
98 </div>
99 <textarea
100 value={form.content}
101 onChange={e => setForm(f => ({ ...f, content: e.target.value }))}
102 rows={24}
103 className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-xl text-white focus:outline-none focus:border-indigo-500 resize-y font-serif text-base leading-relaxed"
104 />
105 </div>
106
107 <div className={`text-xs px-3 py-2 rounded-lg flex items-center gap-2 ${
108 chapter.is_published
109 ? 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'
110 : 'bg-amber-500/10 text-amber-400 border border-amber-500/20'
111 }`}>
112 {chapter.is_published ? 'Published — visible to readers' : 'Draft — not visible to readers'}
113 </div>
114 </div>
115
116 {/* AI Suggestions panel */}
117 <div>
118 <AISuggestionPanel chapterId={chapter.chapter_id} storyId={chapter.story_id} />
119 </div>
120 </div>
121 </div>
122 )
123}
Note: See TracBrowser for help on using the repository browser.