// =============================
// Vite + React + Tailwind App
// Dashboard functional + pages wired to n8n
// Files are concatenated here. When implementing, split into the paths shown.
// =============================

// ------------------------------------------
// File: src/main.jsx
// ------------------------------------------
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
import './index.css'
import { AuthProvider } from './lib/auth'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <AuthProvider>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </AuthProvider>
  </React.StrictMode>
)

// ------------------------------------------
// File: src/App.jsx
// ------------------------------------------
import React from 'react'
import { Routes, Route, Navigate } from 'react-router-dom'
import Layout from './components/Layout'
import DashboardPage from './pages/DashboardPage'
import CreateStoryPage from './pages/CreateStoryPage'
import UploadPage from './pages/UploadPage'
import DownloadsPage from './pages/DownloadsPage'
import PrintCheckoutPage from './pages/PrintCheckoutPage'
import OrdersPage from './pages/OrdersPage'
import StoriesPage from './pages/StoriesPage'
import DonationsPage from './pages/DonationsPage'
import TopUpPage from './pages/TopUpPage'
import LoginPage from './pages/LoginPage'
import { useAuth } from './lib/auth'

function ProtectedRoute({ children }) {
  const { user } = useAuth()
  if (!user) return <Navigate to="/login" replace />
  return children
}

export default function App(){
  return (
    <Routes>
      <Route path="/login" element={<LoginPage/>} />
      <Route
        path="/"
        element={
          <ProtectedRoute>
            <Layout />
          </ProtectedRoute>
        }
      >
        <Route index element={<DashboardPage/>} />
        <Route path="create" element={<CreateStoryPage/>} />
        <Route path="upload" element={<UploadPage/>} />
        <Route path="downloads" element={<DownloadsPage/>} />
        <Route path="print" element={<PrintCheckoutPage/>} />
        <Route path="orders" element={<OrdersPage/>} />
        <Route path="stories" element={<StoriesPage/>} />
        <Route path="donations" element={<DonationsPage/>} />
        <Route path="topup" element={<TopUpPage/>} />
      </Route>
      <Route path="*" element={<Navigate to="/" replace />} />
    </Routes>
  )
}

// ------------------------------------------
// File: src/lib/auth.jsx (very simple client auth state)
// ------------------------------------------
import React, { createContext, useContext, useEffect, useState } from 'react'

const AuthCtx = createContext(null)

export function AuthProvider({ children }){
  const [user, setUser] = useState(null)
  useEffect(()=>{
    const saved = localStorage.getItem('bookoomoo:user')
    if(saved) setUser(JSON.parse(saved))
  },[])
  const login = (payload)=>{ setUser(payload); localStorage.setItem('bookoomoo:user', JSON.stringify(payload)) }
  const logout = ()=>{ setUser(null); localStorage.removeItem('bookoomoo:user') }
  return <AuthCtx.Provider value={{user, login, logout}}>{children}</AuthCtx.Provider>
}
export function useAuth(){ return useContext(AuthCtx) }

// ------------------------------------------
// File: src/lib/api.js (n8n endpoints wrapper)
// ------------------------------------------
export const API = {
  // Set your n8n base here (domain/webhook path). For local dev, use proxy.
  BASE_URL: import.meta.env.VITE_N8N_BASE_URL || 'http://localhost:5678',

  async get(path){
    const res = await fetch(`${this.BASE_URL}${path}`)
    if(!res.ok) throw new Error('Request failed')
    return res.json()
  },
  async post(path, body){
    const res = await fetch(`${this.BASE_URL}${path}`,{ method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(body) })
    if(!res.ok) throw new Error('Request failed')
    return res.json()
  },

  // ---- Bookoomoo specific (align with PRD) ----
  me(){ return this.get('/webhook/user/me') },
  dashboard(){ return this.get('/webhook/dashboard/summary') },
  listStories(){ return this.get('/webhook/stories/list') },
  listOrders(){ return this.get('/webhook/orders/list') },
  listDonations(){ return this.get('/webhook/donations/list') },
  topupToken(data){ return this.post('/webhook/token/topup', data) },

  // Story flow
  genStory(payload){ return this.post('/webhook/story/generate', payload) },
  genPDF(payload){ return this.post('/webhook/pdf/generate', payload) },
  createPrintOrder(payload){ return this.post('/webhook/print/order', payload) },
}

// ------------------------------------------
// File: src/components/Layout.jsx
// ------------------------------------------
import React from 'react'
import { Outlet, Link, useNavigate } from 'react-router-dom'
import { BookOpen, Gift, Home, LogOut, Printer, Search, Upload, Wallet, Download, PlusCircle } from 'lucide-react'
import { useAuth } from '../lib/auth'

function Shell(){
  const { logout } = useAuth()
  const nav = useNavigate()
  return (
    <div className="min-h-screen bg-neutral-50 text-neutral-900">
      <header className="sticky top-0 z-30 border-b bg-white/70 backdrop-blur">
        <div className="mx-auto flex max-w-7xl items-center gap-3 px-4 py-3">
          <Link to="/" className="flex items-center gap-2">
            <div className="grid h-9 w-9 place-items-center rounded-xl bg-gradient-to-br from-amber-500 to-orange-600 text-white shadow">📚</div>
            <div className="text-lg font-semibold tracking-tight">Bookoomoo</div>
          </Link>
          <div className="ml-auto hidden w-full max-w-md items-center gap-2 rounded-xl border bg-white px-3 py-2 shadow-sm md:flex">
            <Search className="h-4 w-4 text-neutral-400" />
            <input className="w-full bg-transparent text-sm outline-none placeholder:text-neutral-400" placeholder="Cari cerita, order, atau donasi…" />
          </div>
          <button onClick={()=>{ logout(); nav('/login') }} className="ml-2 inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-sm hover:bg-neutral-50">
            <LogOut className="h-4 w-4" /> Keluar
          </button>
        </div>
      </header>

      <nav className="mx-auto max-w-7xl px-4 pt-4">
        <div className="flex flex-wrap gap-2">
          <Link to="/" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Home className="h-4 w-4"/> Dashboard</Link>
          <Link to="/create" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><PlusCircle className="h-4 w-4"/> Buat Cerita</Link>
          <Link to="/upload" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Upload className="h-4 w-4"/> Upload Foto</Link>
          <Link to="/downloads" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Download className="h-4 w-4"/> Unduh PDF</Link>
          <Link to="/print" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Printer className="h-4 w-4"/> Cetak Fisik</Link>
          <Link to="/stories" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><BookOpen className="h-4 w-4"/> Cerita</Link>
          <Link to="/orders" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Printer className="h-4 w-4"/> Order</Link>
          <Link to="/donations" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Gift className="h-4 w-4"/> Donasi</Link>
          <Link to="/topup" className="rounded-xl border bg-white px-3 py-1.5 text-sm hover:bg-neutral-50 inline-flex items-center gap-2"><Wallet className="h-4 w-4"/> Top Up</Link>
        </div>
      </nav>

      <main className="mx-auto max-w-7xl px-4 py-6">
        <Outlet />
      </main>

      <footer className="mx-auto max-w-7xl px-4 py-10 text-center text-xs text-neutral-500">© {new Date().getFullYear()} Bookoomoo — Be Different, Be You.</footer>
    </div>
  )
}

export default function Layout(){
  return <Shell />
}

// ------------------------------------------
// File: src/components/StatusBadge.jsx
// ------------------------------------------
import React from 'react'
export default function StatusBadge({ status }){
  const map = {
    Draft: 'bg-neutral-100 text-neutral-700',
    'PDF Ready': 'bg-blue-100 text-blue-700',
    Printed: 'bg-emerald-100 text-emerald-700',
    Completed: 'bg-emerald-100 text-emerald-700',
    'In Production': 'bg-amber-100 text-amber-700',
    Delivered: 'bg-purple-100 text-purple-700',
  }
  const cls = map[status] || 'bg-neutral-100 text-neutral-700'
  return <span className={`inline-flex items-center rounded-xl px-2.5 py-1 text-xs font-medium ${cls}`}>{status}</span>
}

// ------------------------------------------
// File: src/pages/DashboardPage.jsx
// (Fetches real data from n8n)
// ------------------------------------------
import React, { useEffect, useState } from 'react'
import StatusBadge from '../components/StatusBadge'
import { API } from '../lib/api'
import { ArrowRight, BookOpen, Gift, Printer, RefreshCw, Wallet, Download, PlusCircle, Upload } from 'lucide-react'

function Card({ children }){ return <div className="rounded-2xl border bg-white p-4 shadow-sm">{children}</div> }
function Panel({ title, actionLabel, actionHref, right, children }){
  return (
    <div className="rounded-2xl border bg-white p-4 shadow-sm">
      <div className="mb-3 flex items-center gap-3">
        <h3 className="text-base font-semibold">{title}</h3>
        <div className="ml-auto flex items-center gap-3">
          {right || null}
          {actionLabel && actionHref && (
            <a href={actionHref} className="inline-flex items-center gap-1 rounded-xl border px-3 py-1.5 text-sm hover:bg-neutral-50">{actionLabel} <ArrowRight className="h-4 w-4"/></a>
          )}
        </div>
      </div>
      {children}
    </div>
  )
}
function QuickAction({ icon, title, desc, href='#' }){
  return (
    <a href={href} className="group rounded-2xl border bg-white p-4 shadow-sm transition hover:-translate-y-0.5 hover:shadow-md">
      <div className="flex items-start gap-3">
        <div className="grid h-10 w-10 place-items-center rounded-xl bg-neutral-900 text-white group-hover:shadow">{icon}</div>
        <div>
          <div className="font-medium">{title}</div>
          <div className="mt-1 text-sm text-neutral-600">{desc}</div>
        </div>
      </div>
    </a>
  )
}

export default function DashboardPage(){
  const [loading, setLoading] = useState(true)
  const [summary, setSummary] = useState({ user:{name:'—', tokenBalance:0}, stories:[], orders:[], donations:[] })

  async function load(){
    setLoading(true)
    try{
      const data = await API.dashboard()
      setSummary(data)
    } finally { setLoading(false) }
  }

  useEffect(()=>{ load() },[])
  const { user, stories, orders, donations } = summary

  return (
    <div>
      <section className="mb-6 flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <h1 className="text-2xl font-bold leading-tight md:text-3xl">{user?.name || 'Halo, Pengguna'}</h1>
          <p className="mt-1 text-sm text-neutral-600">Buat buku cerita personal, unduh PDF, atau cetak fisik dengan program <span className="font-medium">Buy 1 Donate 1</span>.</p>
        </div>
        <div className="flex flex-wrap gap-2">
          <a href="/create" className="inline-flex items-center gap-2 rounded-2xl bg-neutral-900 px-4 py-2 text-white shadow hover:bg-neutral-800"><PlusCircle className="h-4 w-4"/>Buat Cerita Baru</a>
          <a href="/topup" className="inline-flex items-center gap-2 rounded-2xl border px-4 py-2 hover:bg-neutral-50"><Wallet className="h-4 w-4"/>Top Up Token</a>
        </div>
      </section>

      <section className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <Card>
          <div className="flex items-center justify-between"><span className="text-sm text-neutral-500">Saldo Token</span><Wallet className="h-4 w-4 text-neutral-400"/></div>
          <div className="mt-3 text-3xl font-bold">{user?.tokenBalance ?? 0}</div>
          <div className="mt-2 text-xs text-neutral-500">1 Token = 1x Generate PDF</div>
        </Card>
        <Card>
          <div className="flex items-center justify-between"><span className="text-sm text-neutral-500">Cerita Selesai</span><BookOpen className="h-4 w-4 text-neutral-400"/></div>
          <div className="mt-3 text-3xl font-bold">{stories?.length ?? 0}</div>
          <div className="mt-2 text-xs text-neutral-500">Total semua waktu</div>
        </Card>
        <Card>
          <div className="flex items-center justify-between"><span className="text-sm text-neutral-500">Order Cetak Aktif</span><Printer className="h-4 w-4 text-neutral-400"/></div>
          <div className="mt-3 text-3xl font-bold">{orders?.filter(o=>o.status!=='Completed').length ?? 0}</div>
          <div className="mt-2 text-xs text-neutral-500">Sedang diproses</div>
        </Card>
        <Card>
          <div className="flex items-center justify-between"><span className="text-sm text-neutral-500">Donasi Tersalurkan</span><Gift className="h-4 w-4 text-neutral-400"/></div>
          <div className="mt-3 text-3xl font-bold">{donations?.length ?? 0}</div>
          <div className="mt-2 text-xs text-neutral-500">Buy 1 Donate 1</div>
        </Card>
      </section>

      <section className="mt-6 grid gap-4 md:grid-cols-2 lg:grid-cols-4">
        <QuickAction icon={<PlusCircle className="h-5 w-5"/>} title="Buat Cerita" desc="Masukkan nama anak & pilih tema" href="/create"/>
        <QuickAction icon={<Upload className="h-5 w-5"/>} title="Upload Foto" desc="Opsional untuk personalisasi" href="/upload"/>
        <QuickAction icon={<Download className="h-5 w-5"/>} title="Unduh PDF" desc="Gunakan token kamu" href="/downloads"/>
        <QuickAction icon={<Printer className="h-5 w-5"/>} title="Cetak Fisik" desc="Buy 1 Donate 1" href="/print"/>
      </section>

      <section className="mt-6 grid gap-6 lg:grid-cols-12">
        <div className="lg:col-span-7">
          <Panel title="Cerita Terbaru" actionLabel="Lihat Semua" actionHref="/stories">
            <ul className="divide-y">{(stories||[]).slice(0,5).map((s)=>(
              <li key={s.id} className="flex items-center gap-3 py-3">
                <div className="grid h-10 w-10 place-items-center rounded-xl bg-gradient-to-br from-sky-500 to-blue-600 text-white"><BookOpen className="h-5 w-5"/></div>
                <div className="min-w-0 flex-1">
                  <div className="truncate font-medium">{s.title}</div>
                  <div className="mt-0.5 text-xs text-neutral-500">{s.lang} • {s.theme} • {s.createdAt}</div>
                </div>
                <StatusBadge status={s.status}/>
                <a href={`/stories`} className="ml-2 inline-flex items-center gap-1 text-sm text-neutral-600 hover:text-neutral-900">Buka <ArrowRight className="h-4 w-4"/></a>
              </li>))}
            </ul>
          </Panel>
        </div>
        <div className="lg:col-span-5 space-y-6">
          <Panel title="Order Terakhir" actionLabel="Riwayat Order" actionHref="/orders">
            <ul className="divide-y">{(orders||[]).slice(0,5).map((o)=>(
              <li key={o.id} className="flex items-center gap-3 py-3">
                <div className="grid h-10 w-10 place-items-center rounded-xl bg-gradient-to-br from-emerald-500 to-green-600 text-white"><Printer className="h-5 w-5"/></div>
                <div className="min-w-0 flex-1">
                  <div className="truncate font-medium">{o.type}</div>
                  <div className="mt-0.5 text-xs text-neutral-500">{o.serial} • {o.createdAt}</div>
                </div>
                <StatusBadge status={o.status}/>
              </li>))}
            </ul>
          </Panel>
          <Panel title="Tracking Donasi" actionLabel="Lihat Semua" actionHref="/donations">
            <ul className="divide-y">{(donations||[]).slice(0,5).map((d)=>(
              <li key={d.id} className="flex items-center gap-3 py-3">
                <div className="grid h-10 w-10 place-items-center rounded-xl bg-gradient-to-br from-fuchsia-500 to-pink-600 text-white"><Gift className="h-5 w-5"/></div>
                <div className="min-w-0 flex-1">
                  <div className="truncate font-medium">{d.recipient}</div>
                  <div className="mt-0.5 text-xs text-neutral-500">{d.serial} • Update {d.updatedAt}</div>
                </div>
                <StatusBadge status={d.status}/>
              </li>))}
            </ul>
          </Panel>
        </div>
      </section>

      <section className="mt-6 grid gap-6 lg:grid-cols-12">
        <div className="lg:col-span-7">
          <Panel title="Catatan & Tips">
            <ul className="list-disc space-y-2 pl-5 text-sm text-neutral-700">
              <li>Gunakan token untuk mengunduh PDF. Top up kapan saja lewat menu <span className="font-medium">Top Up Token</span>.</li>
              <li>Untuk cetak fisik, pastikan alamat lengkap dan nomor telepon aktif.</li>
              <li>Tracking donasi tersedia melalui QR di halaman buku donasi.</li>
            </ul>
          </Panel>
        </div>
        <div className="lg:col-span-5">
          <Panel title="Sinkronisasi" right={<button onClick={load} className="inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-sm hover:bg-neutral-50"><RefreshCw className="h-4 w-4"/> Muat Ulang Data</button>}>
            <div className="text-sm text-neutral-700">Status layanan n8n & storage tampak normal. Jika ada kendala, klik tombol untuk menyegarkan data.</div>
          </Panel>
        </div>
      </section>
    </div>
  )
}

// ------------------------------------------
// File: src/pages/CreateStoryPage.jsx
// ------------------------------------------
import React, { useState } from 'react'
import { API } from '../lib/api'

export default function CreateStoryPage(){
  const [form, setForm] = useState({ childName:'', theme:'Adventure', lang:'ID/EN', illustration:'Auto' })
  const [result, setResult] = useState(null)
  const [loading, setLoading] = useState(false)

  async function submit(e){
    e.preventDefault(); setLoading(true); setResult(null)
    try{
      const story = await API.genStory(form)
      setResult(story)
    } finally { setLoading(false) }
  }
  async function toPDF(){
    setLoading(true)
    try{
      const pdf = await API.genPDF({ storyId: result.storyId })
      setResult(prev=>({...prev, pdf}))
    } finally { setLoading(false) }
  }

  return (
    <div className="max-w-2xl">
      <h2 className="text-xl font-semibold mb-3">Buat Cerita</h2>
      <form onSubmit={submit} className="space-y-3">
        <div>
          <label className="text-sm">Nama Anak</label>
          <input value={form.childName} onChange={e=>setForm({...form, childName:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2" required/>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="text-sm">Tema</label>
            <select value={form.theme} onChange={e=>setForm({...form, theme:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2">
              <option>Adventure</option>
              <option>Fantasy</option>
              <option>Ocean</option>
              <option>Space</option>
            </select>
          </div>
          <div>
            <label className="text-sm">Bahasa</label>
            <select value={form.lang} onChange={e=>setForm({...form, lang:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2">
              <option>ID/EN</option>
              <option>ID</option>
              <option>EN</option>
            </select>
          </div>
        </div>
        <div>
          <label className="text-sm">Ilustrasi</label>
          <select value={form.illustration} onChange={e=>setForm({...form, illustration:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2">
            <option>Auto</option>
            <option>Watercolor</option>
            <option>Pencil</option>
            <option>3D</option>
          </select>
        </div>
        <button disabled={loading} className="rounded-xl bg-neutral-900 px-4 py-2 text-white">{loading? 'Memproses…':'Generate Cerita'}</button>
      </form>

      {result && (
        <div className="mt-6 rounded-2xl border bg-white p-4">
          <div className="font-medium">{result.title}</div>
          <pre className="mt-2 whitespace-pre-wrap text-sm text-neutral-700">{JSON.stringify(result.content_json, null, 2)}</pre>
          <div className="mt-3 flex gap-2">
            <button onClick={toPDF} disabled={loading} className="rounded-xl border px-3 py-2">Generate PDF</button>
            {result.pdf?.pdfUrl && <a className="rounded-xl bg-neutral-900 px-3 py-2 text-white" href={result.pdf.pdfUrl} target="_blank">Buka PDF</a>}
          </div>
        </div>
      )}
    </div>
  )
}

// ------------------------------------------
// File: src/pages/UploadPage.jsx
// ------------------------------------------
import React, { useState } from 'react'

export default function UploadPage(){
  const [file, setFile] = useState(null)
  function submit(e){ e.preventDefault(); alert('Upload via Signed URL n8n (implement nanti)') }
  return (
    <div className="max-w-xl">
      <h2 className="text-xl font-semibold mb-3">Upload Foto (Opsional)</h2>
      <form onSubmit={submit} className="space-y-3">
        <input type="file" accept="image/*" onChange={e=>setFile(e.target.files?.[0])} className="w-full rounded-xl border bg-white px-3 py-2"/>
        <button className="rounded-xl bg-neutral-900 px-4 py-2 text-white">Upload</button>
      </form>
      {file && <p className="mt-2 text-sm">File dipilih: {file.name}</p>}
    </div>
  )
}

// ------------------------------------------
// File: src/pages/DownloadsPage.jsx
// ------------------------------------------
import React, { useEffect, useState } from 'react'
import { API } from '../lib/api'

export default function DownloadsPage(){
  const [stories, setStories] = useState([])
  useEffect(()=>{ API.listStories().then(r=>setStories(r)) },[])
  return (
    <div>
      <h2 className="text-xl font-semibold mb-3">Unduh PDF</h2>
      <table className="w-full text-sm">
        <thead><tr className="text-left text-neutral-500"><th className="py-2">Judul</th><th>Serial</th><th>Status</th><th>Aksi</th></tr></thead>
        <tbody>
          {stories.map(s=> (
            <tr key={s.id} className="border-t">
              <td className="py-2">{s.title}</td>
              <td>{s.serial || '—'}</td>
              <td>{s.status}</td>
              <td>
                {s.pdfUrl ? (
                  <a className="rounded-xl bg-neutral-900 px-3 py-1.5 text-white" href={s.pdfUrl} target="_blank">Download</a>
                ) : (
                  <button onClick={async()=>{ await API.genPDF({ storyId:s.id }); location.reload() }} className="rounded-xl border px-3 py-1.5">Generate PDF (1 Token)</button>
                )}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ------------------------------------------
// File: src/pages/PrintCheckoutPage.jsx
// ------------------------------------------
import React, { useState } from 'react'
import { API } from '../lib/api'

export default function PrintCheckoutPage(){
  const [form, setForm] = useState({ storyId:'', name:'', phone:'', address:'', donateRecipient:'' })
  const [result, setResult] = useState(null)

  async function submit(e){
    e.preventDefault();
    const r = await API.createPrintOrder(form)
    setResult(r)
  }

  return (
    <div className="max-w-2xl">
      <h2 className="text-xl font-semibold mb-3">Cetak Fisik — Buy 1 Donate 1</h2>
      <form onSubmit={submit} className="space-y-3">
        <div>
          <label className="text-sm">Story ID</label>
          <input value={form.storyId} onChange={e=>setForm({...form, storyId:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2" required/>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="text-sm">Nama</label>
            <input value={form.name} onChange={e=>setForm({...form, name:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2" required/>
          </div>
          <div>
            <label className="text-sm">No. HP</label>
            <input value={form.phone} onChange={e=>setForm({...form, phone:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2" required/>
          </div>
        </div>
        <div>
          <label className="text-sm">Alamat</label>
          <textarea value={form.address} onChange={e=>setForm({...form, address:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2" rows={3} required></textarea>
        </div>
        <div>
          <label className="text-sm">Penerima Donasi (opsional)</label>
          <input value={form.donateRecipient} onChange={e=>setForm({...form, donateRecipient:e.target.value})} className="mt-1 w-full rounded-xl border bg-white px-3 py-2"/>
        </div>
        <button className="rounded-xl bg-neutral-900 px-4 py-2 text-white">Buat Order Cetak</button>
      </form>
      {result && (
        <div className="mt-4 rounded-2xl border bg-white p-4 text-sm">
          <div>Order ID: <b>{result.orderId}</b></div>
          <div>Serial Pembeli: <b>{result.serial_1}</b></div>
          <div>Serial Donasi: <b>{result.serial_2}</b></div>
          <div>Status: <b>{result.status}</b></div>
        </div>
      )}
    </div>
  )
}

// ------------------------------------------
// File: src/pages/OrdersPage.jsx
// ------------------------------------------
import React, { useEffect, useState } from 'react'
import { API } from '../lib/api'
import StatusBadge from '../components/StatusBadge'

export default function OrdersPage(){
  const [orders, setOrders] = useState([])
  useEffect(()=>{ API.listOrders().then(setOrders) },[])
  return (
    <div>
      <h2 className="text-xl font-semibold mb-3">Riwayat Order</h2>
      <table className="w-full text-sm">
        <thead><tr className="text-left text-neutral-500"><th className="py-2">Serial</th><th>Jenis</th><th>Status</th><th>Tanggal</th></tr></thead>
        <tbody>
          {orders.map(o=> (
            <tr key={o.id} className="border-t">
              <td className="py-2">{o.serial}</td>
              <td>{o.type}</td>
              <td><StatusBadge status={o.status}/></td>
              <td>{o.createdAt}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ------------------------------------------
// File: src/pages/StoriesPage.jsx
// ------------------------------------------
import React, { useEffect, useState } from 'react'
import { API } from '../lib/api'
import StatusBadge from '../components/StatusBadge'

export default function StoriesPage(){
  const [stories, setStories] = useState([])
  useEffect(()=>{ API.listStories().then(setStories) },[])
  return (
    <div>
      <h2 className="text-xl font-semibold mb-3">Cerita Saya</h2>
      <table className="w-full text-sm">
        <thead><tr className="text-left text-neutral-500"><th className="py-2">Judul</th><th>Tema</th><th>Bahasa</th><th>Status</th><th>Created</th></tr></thead>
        <tbody>
          {stories.map(s=> (
            <tr key={s.id} className="border-t">
              <td className="py-2">{s.title}</td>
              <td>{s.theme}</td>
              <td>{s.lang}</td>
              <td><StatusBadge status={s.status}/></td>
              <td>{s.createdAt}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ------------------------------------------
// File: src/pages/DonationsPage.jsx
// ------------------------------------------
import React, { useEffect, useState } from 'react'
import { API } from '../lib/api'
import StatusBadge from '../components/StatusBadge'

export default function DonationsPage(){
  const [donations, setDonations] = useState([])
  useEffect(()=>{ API.listDonations().then(setDonations) },[])
  return (
    <div>
      <h2 className="text-xl font-semibold mb-3">Tracking Donasi</h2>
      <table className="w-full text-sm">
        <thead><tr className="text-left text-neutral-500"><th className="py-2">Serial</th><th>Penerima</th><th>Status</th><th>Update</th><th>QR</th></tr></thead>
        <tbody>
          {donations.map(d=> (
            <tr key={d.id} className="border-t">
              <td className="py-2">{d.serial}</td>
              <td>{d.recipient}</td>
              <td><StatusBadge status={d.status}/></td>
              <td>{d.updatedAt}</td>
              <td>{d.qrUrl ? <a className="underline" href={d.qrUrl} target="_blank">Buka</a> : '—'}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ------------------------------------------
// File: src/pages/TopUpPage.jsx
// ------------------------------------------
import React, { useState } from 'react'
import { API } from '../lib/api'

export default function TopUpPage(){
  const [amount, setAmount] = useState(1)
  const [result, setResult] = useState(null)
  async function submit(e){ e.preventDefault(); const r = await API.topupToken({ tokens: amount }); setResult(r) }
  return (
    <div className="max-w-md">
      <h2 className="text-xl font-semibold mb-3">Top Up Token</h2>
      <form onSubmit={submit} className="space-y-3">
        <div>
          <label className="text-sm">Jumlah Token</label>
          <input type="number" min={1} value={amount} onChange={e=>setAmount(parseInt(e.target.value||'1'))} className="mt-1 w-full rounded-xl border bg-white px-3 py-2"/>
        </div>
        <button className="rounded-xl bg-neutral-900 px-4 py-2 text-white">Buat Invoice</button>
      </form>
      {result && (
        <div className="mt-4 rounded-2xl border bg-white p-4 text-sm">
          <div>Invoice: <b>{result.invoiceId}</b></div>
          <div>Metode: <b>{result.method}</b></div>
          <div>Total: <b>{result.total}</b></div>
          {result.qrisUrl && <a className="mt-2 inline-block rounded-xl bg-neutral-900 px-3 py-2 text-white" href={result.qrisUrl} target="_blank">Bayar via QRIS</a>}
        </div>
      )}
    </div>
  )
}

// ------------------------------------------
// File: src/pages/LoginPage.jsx
// ------------------------------------------
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useAuth } from '../lib/auth'

export default function LoginPage(){
  const nav = useNavigate();
  const { login } = useAuth()
  const [email, setEmail] = useState('demo@bookoomoo.app')
  const [pass, setPass] = useState('demo')
  function submit(e){ e.preventDefault(); login({ id:1, name:'Demo User', email, tokenBalance: 3 }); nav('/') }
  return (
    <div className="min-h-screen grid place-items-center bg-neutral-50">
      <form onSubmit={submit} className="w-full max-w-sm rounded-2xl border bg-white p-6 shadow-sm">
        <div className="text-lg font-semibold">Masuk ke Bookoomoo</div>
        <div className="mt-4">
          <label className="text-sm">Email</label>
          <input className="mt-1 w-full rounded-xl border bg-white px-3 py-2" value={email} onChange={e=>setEmail(e.target.value)} />
        </div>
        <div className="mt-3">
          <label className="text-sm">Password</label>
          <input type="password" className="mt-1 w-full rounded-xl border bg-white px-3 py-2" value={pass} onChange={e=>setPass(e.target.value)} />
        </div>
        <button className="mt-4 w-full rounded-xl bg-neutral-900 px-4 py-2 text-white">Masuk</button>
      </form>
    </div>
  )
}

// ------------------------------------------
// File: src/index.css (Tailwind base)
// ------------------------------------------
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Optional: smooth fonts */
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
