Index: chapterx-frontend/src/components/writer/AISuggestionPanel.tsx
===================================================================
--- chapterx-frontend/src/components/writer/AISuggestionPanel.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/writer/AISuggestionPanel.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,182 @@
+import React, { useState, useEffect } from 'react'
+import { Sparkles, Check, X, Clock, ChevronDown, ChevronUp } from 'lucide-react'
+import { useStoryStore } from '../../store/storyStore'
+import { useUIStore } from '../../store/uiStore'
+import { AISuggestion, SuggestionType } from '../../types'
+import { Button } from '../ui/Button'
+
+interface AISuggestionPanelProps {
+  chapterId: number
+  storyId?: number
+}
+
+const typeColors: Record<SuggestionType, string> = {
+  grammar: 'bg-blue-500/20 text-blue-300 border-blue-500/30',
+  style: 'bg-violet-500/20 text-violet-300 border-violet-500/30',
+  plot: 'bg-amber-500/20 text-amber-300 border-amber-500/30',
+  character: 'bg-emerald-500/20 text-emerald-300 border-emerald-500/30',
+  pacing: 'bg-pink-500/20 text-pink-300 border-pink-500/30',
+}
+
+const SuggestionCard: React.FC<{
+  suggestion: AISuggestion
+  onAccept: () => void
+  onReject: () => void
+}> = ({ suggestion, onAccept, onReject }) => {
+  const [expanded, setExpanded] = useState(false)
+
+  return (
+    <div className="bg-slate-800 border border-slate-700 rounded-xl p-4">
+      <div className="flex items-start justify-between gap-3 mb-3">
+        <div className="flex items-center gap-2">
+          <span className={`px-2 py-0.5 text-xs font-medium rounded-full border ${typeColors[suggestion.suggestion_type]}`}>
+            {suggestion.suggestion_type}
+          </span>
+          {suggestion.accepted === true && (
+            <span className="flex items-center gap-1 text-xs text-emerald-400">
+              <Check size={12} /> Accepted
+            </span>
+          )}
+          {suggestion.accepted === false && (
+            <span className="flex items-center gap-1 text-xs text-rose-400">
+              <X size={12} /> Rejected
+            </span>
+          )}
+          {suggestion.accepted === null && (
+            <span className="flex items-center gap-1 text-xs text-amber-400">
+              <Clock size={12} /> Pending
+            </span>
+          )}
+        </div>
+        <button
+          onClick={() => setExpanded(!expanded)}
+          className="text-slate-500 hover:text-slate-300 transition-colors"
+        >
+          {expanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
+        </button>
+      </div>
+
+      <div className="space-y-3">
+        <div>
+          <p className="text-xs text-slate-500 mb-1">Original:</p>
+          <p className="text-sm text-slate-400 bg-slate-900 rounded-lg p-3 italic border border-slate-700">
+            "{suggestion.original_text}"
+          </p>
+        </div>
+        <div>
+          <p className="text-xs text-slate-500 mb-1">Suggested:</p>
+          <p className="text-sm text-emerald-300 bg-emerald-500/5 rounded-lg p-3 border border-emerald-500/20">
+            "{suggestion.suggested_text}"
+          </p>
+        </div>
+
+        {expanded && (
+          <div>
+            <p className="text-xs text-slate-500 mb-1">Explanation:</p>
+            <p className="text-sm text-slate-400">{suggestion.explanation}</p>
+            {suggestion.applied_at && (
+              <p className="text-xs text-slate-600 mt-2">
+                Applied: {new Date(suggestion.applied_at).toLocaleString()}
+              </p>
+            )}
+          </div>
+        )}
+
+        {suggestion.accepted === null && (
+          <div className="flex gap-2 pt-1">
+            <Button size="sm" onClick={onAccept} className="flex-1">
+              <Check size={14} />
+              Accept
+            </Button>
+            <Button size="sm" variant="danger" onClick={onReject} className="flex-1">
+              <X size={14} />
+              Reject
+            </Button>
+          </div>
+        )}
+      </div>
+    </div>
+  )
+}
+
+export const AISuggestionPanel: React.FC<AISuggestionPanelProps> = ({ chapterId, storyId }) => {
+  const { aiSuggestions, acceptSuggestion, rejectSuggestion, fetchSuggestions } = useStoryStore()
+  const { addToast } = useUIStore()
+  const [tab, setTab] = useState<'pending' | 'accepted' | 'rejected'>('pending')
+  const [loading, setLoading] = useState(false)
+
+  useEffect(() => {
+    setLoading(true)
+    fetchSuggestions().finally(() => setLoading(false))
+  }, [chapterId])
+
+  // Filter by storyId if available (backend), else fall back to chapterId (mock)
+  const chapterSuggestions = aiSuggestions.filter(s =>
+    storyId ? (s as any).story_id === storyId : s.chapter_id === chapterId
+  )
+  const pending = chapterSuggestions.filter(s => s.accepted === null)
+  const accepted = chapterSuggestions.filter(s => s.accepted === true)
+  const rejected = chapterSuggestions.filter(s => s.accepted === false)
+
+  const currentList = tab === 'pending' ? pending : tab === 'accepted' ? accepted : rejected
+
+  return (
+    <div className="bg-slate-900 border border-slate-700 rounded-2xl p-6">
+      <div className="flex items-center gap-2 mb-4">
+        <Sparkles size={18} className="text-violet-400" />
+        <h3 className="text-white font-semibold">AI Writing Suggestions</h3>
+        <span className="ml-auto text-xs text-slate-500">{chapterSuggestions.length} total</span>
+      </div>
+
+      {/* Tabs */}
+      <div className="flex gap-1 p-1 bg-slate-800 rounded-xl mb-4">
+        {([
+          { key: 'pending', label: 'Pending', count: pending.length },
+          { key: 'accepted', label: 'Accepted', count: accepted.length },
+          { key: 'rejected', label: 'Rejected', count: rejected.length },
+        ] as const).map(t => (
+          <button
+            key={t.key}
+            onClick={() => setTab(t.key)}
+            className={`flex-1 flex items-center justify-center gap-1.5 py-1.5 rounded-lg text-sm font-medium transition-colors ${
+              tab === t.key
+                ? 'bg-indigo-600 text-white'
+                : 'text-slate-400 hover:text-white'
+            }`}
+          >
+            {t.label}
+            <span className={`text-xs px-1.5 py-0.5 rounded-full ${
+              tab === t.key ? 'bg-indigo-500' : 'bg-slate-700'
+            }`}>
+              {t.count}
+            </span>
+          </button>
+        ))}
+      </div>
+
+      {/* Suggestions */}
+      <div className="space-y-3">
+        {loading ? (
+          <div className="text-center py-8 text-slate-500 text-sm">
+            <Sparkles size={32} className="mx-auto mb-2 opacity-30 animate-pulse" />
+            Loading suggestions...
+          </div>
+        ) : currentList.length === 0 ? (
+          <div className="text-center py-8 text-slate-500 text-sm">
+            <Sparkles size={32} className="mx-auto mb-2 opacity-30" />
+            No {tab} suggestions
+          </div>
+        ) : (
+          currentList.map(s => (
+            <SuggestionCard
+              key={s.suggestion_id}
+              suggestion={s}
+              onAccept={async () => { await acceptSuggestion(s.suggestion_id); addToast('Suggestion accepted!') }}
+              onReject={async () => { await rejectSuggestion(s.suggestion_id); addToast('Suggestion rejected', 'info') }}
+            />
+          ))
+        )}
+      </div>
+    </div>
+  )
+}
Index: chapterx-frontend/src/components/writer/CollaboratorManager.tsx
===================================================================
--- chapterx-frontend/src/components/writer/CollaboratorManager.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/writer/CollaboratorManager.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,190 @@
+import React, { useState } from 'react'
+import { Users, Trash2, UserPlus, Shield } from 'lucide-react'
+import { useStoryStore } from '../../store/storyStore'
+import { useAuthStore } from '../../store/authStore'
+import { useNotificationStore } from '../../store/notificationStore'
+import { useUIStore } from '../../store/uiStore'
+import { Collaboration, CollaboratorRole, PermissionLevel } from '../../types'
+import { Button } from '../ui/Button'
+import { Avatar } from '../ui/Avatar'
+import { Modal } from '../ui/Modal'
+
+interface CollaboratorManagerProps {
+  storyId: number
+  storyTitle: string
+  ownerId: number
+}
+
+const roles: CollaboratorRole[] = ['co-author', 'editor', 'proofreader', 'beta-reader']
+
+const permissionLabels: Record<PermissionLevel, string> = {
+  1: 'View Only',
+  2: 'Comment',
+  3: 'Edit Chapters',
+  4: 'Manage Story',
+  5: 'Full Access',
+}
+
+export const CollaboratorManager: React.FC<CollaboratorManagerProps> = ({
+  storyId,
+  storyTitle,
+  ownerId,
+}) => {
+  const { collaborations, addCollaboration, removeCollaboration, updateCollaborationPermission } = useStoryStore()
+  const { allUsers } = useAuthStore()
+  const { addNotification } = useNotificationStore()
+  const { addToast } = useUIStore()
+
+  const [inviteOpen, setInviteOpen] = useState(false)
+  const [selectedUser, setSelectedUser] = useState('')
+  const [selectedRole, setSelectedRole] = useState<CollaboratorRole>('editor')
+  const [selectedLevel, setSelectedLevel] = useState<PermissionLevel>(3)
+
+  const storyCollabs = collaborations.filter(c => c.story_id === storyId)
+  const collabUserIds = new Set(storyCollabs.map(c => c.user_id))
+  const availableUsers = allUsers.filter(u => u.user_id !== ownerId && !collabUserIds.has(u.user_id))
+
+  const handleInvite = () => {
+    const user = availableUsers.find(u => u.username === selectedUser)
+    if (!user) { addToast('User not found', 'error'); return }
+
+    const newCollab: Collaboration = {
+      collab_id: Date.now(),
+      story_id: storyId,
+      story_title: storyTitle,
+      user_id: user.user_id,
+      username: user.username,
+      name: user.name,
+      role: selectedRole,
+      permission_level: selectedLevel,
+      joined_at: new Date().toISOString(),
+    }
+    addCollaboration(newCollab)
+    addNotification({
+      user_id: user.user_id,
+      type: 'collaboration',
+      title: 'Collaboration Invite',
+      message: `You've been invited to collaborate on "${storyTitle}" as ${selectedRole}.`,
+      link: `/story/${storyId}`,
+    })
+    addToast(`${user.username} added as collaborator!`)
+    setInviteOpen(false)
+    setSelectedUser('')
+  }
+
+  const handleRemove = (collab: Collaboration) => {
+    removeCollaboration(collab.user_id, storyId)
+    addToast(`${collab.username} removed from collaborators`, 'info')
+  }
+
+  return (
+    <div className="bg-slate-900 border border-slate-700 rounded-2xl p-6">
+      <div className="flex items-center justify-between mb-4">
+        <div className="flex items-center gap-2">
+          <Users size={18} className="text-violet-400" />
+          <h3 className="text-white font-semibold">Collaborators</h3>
+          <span className="text-xs text-slate-500">({storyCollabs.length})</span>
+        </div>
+        <Button size="sm" onClick={() => setInviteOpen(true)}>
+          <UserPlus size={14} />
+          Invite
+        </Button>
+      </div>
+
+      {storyCollabs.length === 0 ? (
+        <div className="text-center py-8 text-slate-500 text-sm">
+          <Users size={32} className="mx-auto mb-2 opacity-30" />
+          No collaborators yet
+        </div>
+      ) : (
+        <div className="space-y-3">
+          {storyCollabs.map(collab => (
+            <div key={collab.collab_id} className="flex items-center gap-3 p-3 bg-slate-800 rounded-xl border border-slate-700">
+              <Avatar name={collab.name} size="sm" />
+              <div className="flex-1 min-w-0">
+                <p className="text-sm font-medium text-white">@{collab.username}</p>
+                <div className="flex items-center gap-2 mt-0.5">
+                  <span className="text-xs text-violet-400">{collab.role}</span>
+                  <span className="text-slate-600">·</span>
+                  <Shield size={11} className="text-slate-500" />
+                  <span className="text-xs text-slate-500">Level {collab.permission_level}: {permissionLabels[collab.permission_level]}</span>
+                </div>
+              </div>
+              <div className="flex items-center gap-2">
+                <select
+                  value={collab.permission_level}
+                  onChange={e => {
+                    updateCollaborationPermission(collab.user_id, storyId, Number(e.target.value) as PermissionLevel)
+                    addToast('Permission updated')
+                  }}
+                  className="bg-slate-700 border border-slate-600 text-slate-300 text-xs rounded-lg px-2 py-1 focus:outline-none focus:border-indigo-500"
+                >
+                  {([1, 2, 3, 4, 5] as PermissionLevel[]).map(l => (
+                    <option key={l} value={l}>Level {l}</option>
+                  ))}
+                </select>
+                <button
+                  onClick={() => handleRemove(collab)}
+                  className="text-slate-500 hover:text-rose-400 transition-colors p-1"
+                >
+                  <Trash2 size={14} />
+                </button>
+              </div>
+            </div>
+          ))}
+        </div>
+      )}
+
+      {/* Invite Modal */}
+      <Modal isOpen={inviteOpen} onClose={() => setInviteOpen(false)} title="Invite Collaborator">
+        <div className="space-y-4">
+          <div>
+            <label className="block text-sm text-slate-400 mb-1">Select User</label>
+            <select
+              value={selectedUser}
+              onChange={e => setSelectedUser(e.target.value)}
+              className="w-full bg-slate-800 border border-slate-700 text-slate-300 rounded-xl px-4 py-2 focus:outline-none focus:border-indigo-500"
+            >
+              <option value="">-- Choose a user --</option>
+              {availableUsers.map(u => (
+                <option key={u.user_id} value={u.username}>
+                  @{u.username} ({u.role})
+                </option>
+              ))}
+            </select>
+          </div>
+          <div>
+            <label className="block text-sm text-slate-400 mb-1">Role</label>
+            <select
+              value={selectedRole}
+              onChange={e => setSelectedRole(e.target.value as CollaboratorRole)}
+              className="w-full bg-slate-800 border border-slate-700 text-slate-300 rounded-xl px-4 py-2 focus:outline-none focus:border-indigo-500"
+            >
+              {roles.map(r => <option key={r} value={r}>{r}</option>)}
+            </select>
+          </div>
+          <div>
+            <label className="block text-sm text-slate-400 mb-1">Permission Level</label>
+            <select
+              value={selectedLevel}
+              onChange={e => setSelectedLevel(Number(e.target.value) as PermissionLevel)}
+              className="w-full bg-slate-800 border border-slate-700 text-slate-300 rounded-xl px-4 py-2 focus:outline-none focus:border-indigo-500"
+            >
+              {([1, 2, 3, 4, 5] as PermissionLevel[]).map(l => (
+                <option key={l} value={l}>Level {l} – {permissionLabels[l]}</option>
+              ))}
+            </select>
+          </div>
+          <div className="flex gap-3 pt-2">
+            <Button variant="secondary" className="flex-1" onClick={() => setInviteOpen(false)}>
+              Cancel
+            </Button>
+            <Button className="flex-1" onClick={handleInvite} disabled={!selectedUser}>
+              Send Invite
+            </Button>
+          </div>
+        </div>
+      </Modal>
+    </div>
+  )
+}
Index: chapterx-frontend/src/components/writer/StoryAnalytics.tsx
===================================================================
--- chapterx-frontend/src/components/writer/StoryAnalytics.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/writer/StoryAnalytics.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,95 @@
+import React from 'react'
+import {
+  LineChart,
+  Line,
+  BarChart,
+  Bar,
+  XAxis,
+  YAxis,
+  CartesianGrid,
+  Tooltip,
+  ResponsiveContainer,
+} from 'recharts'
+import { Eye, Heart, MessageCircle, TrendingUp, Clock, BarChart2 } from 'lucide-react'
+import { mockAnalytics } from '../../data/mockData'
+
+const StatCard: React.FC<{ icon: React.ReactNode; label: string; value: string | number; color: string }> = ({
+  icon, label, value, color,
+}) => (
+  <div className={`p-4 bg-slate-800 rounded-xl border border-slate-700`}>
+    <div className={`w-10 h-10 rounded-xl ${color} flex items-center justify-center mb-3`}>
+      {icon}
+    </div>
+    <p className="text-2xl font-bold text-white">{value.toLocaleString()}</p>
+    <p className="text-slate-400 text-sm mt-0.5">{label}</p>
+  </div>
+)
+
+const CustomTooltip = ({ active, payload, label }: any) => {
+  if (active && payload && payload.length) {
+    return (
+      <div className="bg-slate-800 border border-slate-700 rounded-xl px-3 py-2 text-sm">
+        <p className="text-slate-400 mb-1">{label}</p>
+        {payload.map((p: any) => (
+          <p key={p.dataKey} className="text-white font-medium">
+            {p.name}: {p.value.toLocaleString()}
+          </p>
+        ))}
+      </div>
+    )
+  }
+  return null
+}
+
+export const StoryAnalytics: React.FC = () => {
+  const analytics = mockAnalytics
+  const viewsData = analytics.views_over_time.filter((_, i) => i % 5 === 0)
+  const likesData = analytics.likes_over_time.filter((_, i) => i % 5 === 0)
+
+  return (
+    <div className="space-y-6">
+      {/* Stat cards */}
+      <div className="grid grid-cols-2 lg:grid-cols-5 gap-4">
+        <StatCard icon={<Eye size={18} className="text-blue-300" />} label="Total Views" value={analytics.total_views} color="bg-blue-500/20" />
+        <StatCard icon={<Heart size={18} className="text-rose-300" />} label="Total Likes" value={analytics.total_likes} color="bg-rose-500/20" />
+        <StatCard icon={<MessageCircle size={18} className="text-violet-300" />} label="Comments" value={analytics.total_comments} color="bg-violet-500/20" />
+        <StatCard icon={<Clock size={18} className="text-amber-300" />} label="Avg Read (min)" value={analytics.avg_read_time} color="bg-amber-500/20" />
+        <StatCard icon={<BarChart2 size={18} className="text-emerald-300" />} label="Completion %" value={`${analytics.completion_rate}%`} color="bg-emerald-500/20" />
+      </div>
+
+      {/* Views chart */}
+      <div className="bg-slate-800 border border-slate-700 rounded-2xl p-6">
+        <div className="flex items-center gap-2 mb-4">
+          <TrendingUp size={16} className="text-blue-400" />
+          <h3 className="text-white font-semibold">Views Over Time</h3>
+        </div>
+        <ResponsiveContainer width="100%" height={200}>
+          <LineChart data={viewsData}>
+            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
+            <XAxis dataKey="date" tick={{ fill: '#64748b', fontSize: 11 }} tickLine={false} axisLine={false} />
+            <YAxis tick={{ fill: '#64748b', fontSize: 11 }} tickLine={false} axisLine={false} />
+            <Tooltip content={<CustomTooltip />} />
+            <Line type="monotone" dataKey="views" stroke="#6366f1" strokeWidth={2} dot={false} name="Views" />
+          </LineChart>
+        </ResponsiveContainer>
+      </div>
+
+      {/* Likes chart */}
+      <div className="bg-slate-800 border border-slate-700 rounded-2xl p-6">
+        <div className="flex items-center gap-2 mb-4">
+          <Heart size={16} className="text-rose-400" />
+          <h3 className="text-white font-semibold">Likes Over Time</h3>
+        </div>
+        <ResponsiveContainer width="100%" height={200}>
+          <BarChart data={likesData}>
+            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
+            <XAxis dataKey="date" tick={{ fill: '#64748b', fontSize: 11 }} tickLine={false} axisLine={false} />
+            <YAxis tick={{ fill: '#64748b', fontSize: 11 }} tickLine={false} axisLine={false} />
+            <Tooltip content={<CustomTooltip />} />
+            <Bar dataKey="likes" fill="#f43f5e" radius={[4, 4, 0, 0]} name="Likes" />
+          </BarChart>
+        </ResponsiveContainer>
+      </div>
+    </div>
+  )
+}
