Gate the Add chapter button behind CreateContent, matching characters/beats
Editors and Reviewers could see and click Add chapter even though the API rejects the create with 403 for anyone without CreateContent — the gate existed everywhere else (characters, beats) but was missed here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JC8Q7Gkv8K7LnJrwkx1xrh
This commit is contained in:
@@ -1,15 +1,19 @@
|
|||||||
import { Link, useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
import { useChapters, useCreateChapter } from '../api/hooks'
|
import { useChapters, useCreateChapter, useProject } from '../api/hooks'
|
||||||
import { EmptyState, ErrorNote, Spinner, StatusBadge } from '../components/ui'
|
import { EmptyState, ErrorNote, Spinner, StatusBadge } from '../components/ui'
|
||||||
import { TagChip } from '../components/TagEditor'
|
import { TagChip } from '../components/TagEditor'
|
||||||
|
import { useAuth } from '../auth/AuthContext'
|
||||||
import { useHotkey } from '../keyboard/HotkeysContext'
|
import { useHotkey } from '../keyboard/HotkeysContext'
|
||||||
|
|
||||||
export default function ChaptersPage() {
|
export default function ChaptersPage() {
|
||||||
const { projectId = '' } = useParams()
|
const { projectId = '' } = useParams()
|
||||||
const { data: chapters, isPending, error } = useChapters(projectId)
|
const { data: chapters, isPending, error } = useChapters(projectId)
|
||||||
|
const { data: project } = useProject(projectId)
|
||||||
|
const { can } = useAuth()
|
||||||
|
const canCreate = can('CreateContent', project)
|
||||||
const create = useCreateChapter(projectId)
|
const create = useCreateChapter(projectId)
|
||||||
|
|
||||||
useHotkey('n', 'Add chapter', () => create.mutate({ title: 'Untitled chapter' }), { group: 'Chapters' })
|
useHotkey('n', 'Add chapter', () => canCreate && create.mutate({ title: 'Untitled chapter' }), { group: 'Chapters' })
|
||||||
|
|
||||||
if (isPending) return <Spinner label="Loading chapters" />
|
if (isPending) return <Spinner label="Loading chapters" />
|
||||||
if (error) return <ErrorNote error={error} />
|
if (error) return <ErrorNote error={error} />
|
||||||
@@ -18,6 +22,7 @@ export default function ChaptersPage() {
|
|||||||
<div>
|
<div>
|
||||||
<div className="mb-5 flex items-center justify-between gap-4">
|
<div className="mb-5 flex items-center justify-between gap-4">
|
||||||
<h2 className="text-xl font-semibold">Chapters</h2>
|
<h2 className="text-xl font-semibold">Chapters</h2>
|
||||||
|
{canCreate && (
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary"
|
className="btn btn-primary"
|
||||||
onClick={() => create.mutate({ title: 'Untitled chapter' })}
|
onClick={() => create.mutate({ title: 'Untitled chapter' })}
|
||||||
@@ -25,6 +30,7 @@ export default function ChaptersPage() {
|
|||||||
>
|
>
|
||||||
Add chapter
|
Add chapter
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{create.error && <ErrorNote error={create.error} />}
|
{create.error && <ErrorNote error={create.error} />}
|
||||||
|
|||||||
Reference in New Issue
Block a user