Personal portfolio website with a full-featured admin dashboard built with Next.js 15, React 19, tRPC, Drizzle ORM, and NextAuth v5.
- Homepage — Hero section, daftar project, tech stack, dan career timeline
- Projects — Showcase project dengan thumbnail, kategori, link repo & web demo
- Blog — Artikel menggunakan MDX dengan syntax highlighting
- Contact — Form kontak terintegrasi email (Resend)
- Testimonials — Review / testimoni dari pengunjung
- SEO — Sitemap, robots.txt, dan Open Graph image
- Project Management — CRUD project dengan upload gambar (UploadThing)
- Career Management — Kelola riwayat pendidikan & pengalaman kerja
- Review Management — Moderasi review dari pengunjung
- User Management — Kelola user & role (admin/user)
- Blog Management — Tulis dan publish artikel blog
- Credentials — Register & login dengan email/password
- Email Verification — Verifikasi email saat registrasi
- Password Reset — Lupa password via email
- Role-based Access — Admin & User role
| Layer | Teknologi |
|---|---|
| Framework | Next.js 15 (App Router) |
| Language | TypeScript 5 |
| Styling | Tailwind CSS 4 |
| UI Components | shadcn/ui (Radix UI primitives) |
| Animation | Framer Motion |
| API Layer | tRPC 11 + TanStack Query |
| Database | Neon PostgreSQL (serverless) |
| ORM | Drizzle ORM |
| Auth | NextAuth v5 (Auth.js) |
| File Upload | UploadThing |
| Resend | |
| Blog | MDX + remark plugins |
| Validation | Zod + drizzle-zod |
| Package Mgr | Bun |
portfolio-final/
├── app/ # Next.js App Router
│ ├── (auth)/ # Halaman auth (sign-in, sign-up)
│ ├── (root)/ # Halaman publik (home, blog, projects, contact, testimonials)
│ ├── (verification)/ # Halaman verifikasi email
│ ├── api/ # API routes (auth, tRPC, uploadthing)
│ ├── dashboard/ # Admin dashboard (project, career, review, users)
│ └── review/ # Halaman submit review
├── actions/ # Server actions (login, register, email, dll)
├── blog/ # MDX blog content & images
│ ├── content/ # File .mdx artikel
│ └── img/ # Gambar untuk artikel
├── components/ # Shared UI components (shadcn/ui)
├── data/ # Data access layer (user, token queries)
├── db/ # Database schema & connection (Drizzle)
├── hooks/ # Custom React hooks
├── lib/ # Utilities (auth, mail, config, routes, dll)
├── modules/ # Feature modules
│ ├── auth/ # Auth components & logic
│ ├── blog/ # Blog views
│ ├── contact/ # Contact form
│ ├── dashboard/ # Dashboard UI, server actions, components
│ ├── projects/ # Project showcase
│ ├── review/ # Review/testimoni
│ └── root/ # Homepage sections
├── public/ # Static assets (images, SVGs)
└── trpc/ # tRPC client, server, & routers
- Node.js >= 18
- Bun (package manager)
- Neon PostgreSQL database (atau PostgreSQL lainnya)
- Akun UploadThing untuk file upload
- Akun Resend untuk pengiriman email
git clone https://github.com/chndrwali/portfolio.git
cd portfoliobun installBuat file .env.local di root project:
# Database
DATABASE_URL=postgresql://user:password@host/database?sslmode=require
# App
NEXT_PUBLIC_URL=http://localhost:3000
# Auth
AUTH_SECRET=your-auth-secret-key # generate: openssl rand -base64 32
# UploadThing
UPLOADTHING_TOKEN=your-uploadthing-token
# Resend (Email)
RESEND_API_KEY=your-resend-api-keyPush schema ke database:
bunx drizzle-kit push(Opsional) Seed data kategori:
bun run seed:categoriesbun run devBuka http://localhost:3000 di browser.
| Script | Deskripsi |
|---|---|
bun run dev |
Jalankan development server |
bun run build |
Build production |
bun run start |
Jalankan production server |
bun run lint |
Jalankan ESLint |
bun run seed:categories |
Seed data kategori ke database |
bunx drizzle-kit push |
Push schema ke database |
bunx drizzle-kit studio |
Buka Drizzle Studio (DB GUI) |
Blog di project ini menggunakan file MDX yang ditulis secara manual. Untuk menambahkan artikel baru:
blog/
├── content/
│ ├── my-setup.mdx
│ ├── why-nextjs.mdx
│ └── judul-artikel-baru.mdx ← tambahkan di sini
└── img/ ← simpan gambar artikel di sini
Setiap file .mdx wajib memiliki frontmatter berikut:
---
title: Judul Artikel
publishedAt: 2026-03-01
summary: Deskripsi singkat tentang artikel ini.
repository: https://github.com/username/repo
website: https://example.com
---
## Konten artikel dimulai di sini
Tulis konten menggunakan Markdown biasa. Kamu juga bisa menggunakan komponen React di dalam MDX.
### Syntax Highlighting
Code block otomatis mendapatkan syntax highlighting:
\`\`\`typescript
const hello = "world";
\`\`\`| Field | Wajib | Deskripsi |
|---|---|---|
title |
✅ | Judul artikel |
publishedAt |
✅ | Tanggal publish (format YYYY-MM-DD) |
summary |
✅ | Ringkasan singkat artikel |
repository |
❌ | Link repository terkait |
website |
❌ | Link website terkait |
erDiagram
users ||--o{ projects : creates
users ||--o{ blog : writes
users ||--o{ accounts : has
users ||--o{ sessions : has
projects ||--o{ image_projects : has
users {
text id PK
text name
text email UK
text username UK
text password
timestamp emailVerified
text image
enum role
}
projects {
uuid id PK
text title
text description
text web_url
text category
text repository_url
text thumbnail_url
enum visibility
text user_id FK
}
blog {
uuid id PK
varchar title
varchar slug UK
text excerpt
text content
text cover_image
boolean published
text author_id FK
}
review {
uuid id PK
text first_name
text last_name
integer rating
text comment
text image_url
}
careers {
uuid id PK
text title
text company
enum career_type
enum work_type
text period
}
tech_stacks {
uuid id PK
text title
text image_url
}
- Push repository ke GitHub
- Import project di Vercel
- Tambahkan semua environment variables di Vercel dashboard
- Deploy! 🎉
Pastikan semua variabel berikut sudah diatur di Vercel → Settings → Environment Variables:
DATABASE_URLNEXT_PUBLIC_URL(set ke domain production, contoh:https://yourdomain.com)AUTH_SECRETUPLOADTHING_TOKENRESEND_API_KEY
This project is open source and available under the MIT License.
Built with ❤️ by chndrwali