Saleor Store
우리 컬렉션을 쇼핑하세요
결혼식·청혼·생일·기업 행사용 디지털 초대장 카탈로그, 데모 보고 템플릿 선택 후 WhatsApp으로 주문
Katalog undangan digital untuk pernikahan, lamaran, ulang tahun, dan acara perusahaan. Lihat demo, pilih template, pesan via WhatsApp.
커머스TypeScript · JavaScriptGitHub @ricoreynaldo온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.