尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Katalog undangan digital Heaven Inv (Next.js 16) dengan panel admin
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Katalog undangan digital premium dengan pemesanan lewat WhatsApp dan CMS admin. Pengunjung menjelajah katalog, membuka demo, lalu menekan Pesan Sekarang yang membuka WhatsApp admin dengan pesan berisi template, kategori, harga, dan link demo.
Stack: Next.js 16 (App Router, Cache Components) · TypeScript strict · Tailwind CSS 4 ·
PostgreSQL · Prisma 7 (driver adapter pg) · Zod · JWT (jose) + bcrypt · sharp · Vercel Blob (opsional)
Semua query publik/admin dan server action memakai readDb / mutateDb dari src/lib/store.
Driver dipilih lewat env (src/lib/store/driver.ts):
| Kondisi | Driver |
|---|---|
DATA_STORE=postgres | Postgres lewat DATABASE_URL |
DATA_STORE=dummy | Database dummy JSON |
DATA_STORE kosong, di Vercel dan DATABASE_URL ada | Postgres (otomatis) |
DATA_STORE kosong, di laptop | Database dummy JSON (walau .env berisi DATABASE_URL) |
Database dummy (.data/db.json, di-ignore git): dibuat otomatis dari seed
(src/lib/store/seed.ts), perubahan admin tersimpan ke file itu. Hapus file untuk kembali ke data
contoh; lokasi bisa diganti dengan DUMMY_DB_PATH. Login: SEED_ADMIN_EMAIL (default
[email protected]) dan SEED_ADMIN_PASSWORD (min. 10 karakter; bila kosong dipakai password
contoh heaveninv123, hanya untuk lokal). Cocok untuk laptop, tidak untuk Vercel (data hanya
di memori dan hilang saat server berganti).
Postgres / Neon (src/lib/store/postgres.ts): bentuk data sama dengan dummy. Setiap mutasi
berjalan di satu transaksi dengan advisory lock dan hanya menulis baris yang berubah, jadi aman
untuk beberapa instance serverless.
Cukup npm install, isi AUTH_SECRET di .env, lalu npm run dev (mode dummy).
Desain: lihat MASTER.md (token warna, tipografi, motion GSAP). Tag katalog (Best Seller, New,
Promo, Premium) didefinisikan di src/lib/tags.ts.
Butuh Node.js 20.19+.
npm install
cp .env.example .env # isi AUTH_SECRET & SEED_ADMIN_PASSWORD
npm run db:local # terminal terpisah: Postgres lokal (tanpa Docker) di port 5433
npm run db:setup # migrasi + seed (admin, 5 kategori, 9 undangan, konten)
npm run db:import -- --yes # opsional: pindahkan isi .data/db.json ke Postgres
DATA_STORE=postgres npm run dev # http://localhost:3060
Admin: http://localhost:3060/admin/login. Tidak ada registrasi publik; tambah atau reset admin
lewat CLI:
npm run admin:create -- --email [email protected] --password "minimal-10-karakter" --name "Nama"
| Perintah | Fungsi |
|---|---|
npm run dev / build / start | Development, build produksi, server produksi (port 3060) |
npm run lint · npm run typecheck · npm test | ESLint, TypeScript, unit test (node:test) |
npm run db:local | Postgres lokal via embedded-postgres (data di .local-pg/) |
npm run db:migrate · db:seed · db:setup | Terapkan migrasi, isi data awal (hanya bila kosong), atau keduanya |
npm run db:import | Pindahkan isi .data/db.json ke Postgres (tanpa -- --yes hanya menampilkan ringkasan; admin tidak disentuh) |
npm run admin:create | Buat admin / reset password |
npm run assets:generate | Buat ulang gambar placeholder di public/seed & public/brand |
next buildmemprerender halaman publik dari database, jadi database harus bisa diakses saat build. Saat build produksi Vercel dengan Postgres,scripts/prepare-db.tsotomatis menjalankanprisma migrate deploylalu seed (hanya bila database kosong). Build preview dan mode dummy dilewati.
src/
app/(site)/ halaman publik: /, /catalog, /catalog/[slug]
app/demo/[slug] demo undangan bawaan (dibuka di tab baru)
app/admin/login login admin
app/admin/(panel)/ dashboard, templates, categories, content, settings
app/api/admin/upload upload gambar (admin saja)
app/media/[...key] menyajikan file dari storage lokal
actions/ server actions (selalu memanggil requireAdmin)
components/{site,admin,ui}
lib/
auth/ sesi JWT, hash password, requireAdmin
data/ query publik (use cache + tag) & query admin
content/ settings/ skema + default konten CMS dan pengaturan
storage/ abstraksi storage (local / vercel-blob), validasi gambar
validation/ skema zod
whatsapp.ts pembentuk URL & pesan wa.me
proxy.ts gerbang awal /admin & /api/admin
prisma/ schema, migrasi, seed
site_content, pengaturan di site_settings.
Nilai yang hilang/rusak otomatis jatuh ke default di src/lib/content/schema.ts.use cache + cacheTag). Setiap simpan di admin memanggil
revalidateTag(tag, "max") (stale-while-revalidate): kunjungan pertama setelah simpan bisa masih
versi lama, kunjungan berikutnya sudah baru, tanpa deploy ulang. updateTag sengaja tidak
dipakai: di Next.js 16.4 navigasi klik pertama ke halaman detail gagal setelah cache dihapus seketika.Nomor & template pesan diatur di Admin → Settings → WhatsApp. Placeholder:
{{template_name}}, {{category}}, {{price}}, {{demo_url}}. URL dibentuk di server:
https://wa.me/<nomor>?text=<pesan ter-encode>. Link demo relatif (mis. /demo/elegant-rose)
diubah menjadi absolut memakai SITE_URL.
Seed memakai nomor contoh
6281234567890; dashboard menampilkan peringatan sampai nomor diganti.
STORAGE_DRIVER=local → file di STORAGE_LOCAL_DIR (default ./storage/uploads), disajikan /media/*.
Cocok untuk VPS dengan disk permanen.STORAGE_DRIVER=vercel-blob (atau kosong + BLOB_READ_WRITE_TOKEN terisi) → Vercel Blob.
Wajib di Vercel/serverless, karena filesystem di sana tidak permanen.MAX_UPLOAD_MB (default 4), lalu di-encode ulang ke WebP (EXIF dibuang, maks 2400 px).DATABASE_URL (pooled, dipakai aplikasi) dan DATABASE_URL_UNPOOLED (langsung, dipakai migrasi).sin1), dekat database.BLOB_READ_WRITE_TOKEN terisi (wajib untuk upload).AUTH_SECRET (min. 32 karakter acak), SEED_ADMIN_EMAIL, SEED_ADMIN_PASSWORD
(min. 10 karakter, bukan password contoh), opsional SITE_URL dan UPSTASH_REDIS_REST_URL/TOKEN.SEED_ADMIN_*.DATABASE_URL & DATABASE_URL_UNPOOLED Neon ke .env
laptop, lalu npm run db:import (cek ringkasan) dan npm run db:import -- --yes.proxy.ts menyaring /admin/* & /api/admin/*; setiap halaman, server action, dan route
handler tetap memverifikasi sesi ke database (requireAdmin / getCurrentAdmin).noindex untuk area admin.