diff --git a/DEPLOY_VERCEL.md b/DEPLOY_VERCEL.md deleted file mode 100644 index d462651..0000000 --- a/DEPLOY_VERCEL.md +++ /dev/null @@ -1,301 +0,0 @@ -# ๐Ÿš€ Deploy Web Javaherbal ke Vercel - -## โœ… Persiapan Selesai! - -File-file yang sudah disiapkan: -- โœ… `.gitignore` - Exclude node_modules, dist, .env -- โœ… `vercel.json` - Konfigurasi Vercel -- โœ… `package.json` - Script build sudah ada - ---- - -## ๐Ÿ“‹ LANGKAH-LANGKAH DEPLOY - -### 1๏ธโƒฃ Push ke GitHub - -#### A. Buat Repository Baru di GitHub -1. Buka https://github.com -2. Klik tombol **"New"** (repository baru) -3. Isi: - - Repository name: `frondend-web` - - Description: `Web dashboard untuk sistem pengeringan cabai jawa` - - Visibility: **Public** atau **Private** -4. **JANGAN** centang "Add a README file" -5. Klik **"Create repository"** - -#### B. Push Code ke GitHub -```bash -cd javaherbal-v2/javaherbal2 - -# Initialize git -git init - -# Add all files -git add . - -# Commit -git commit -m "Initial commit - Web Javaherbal" - -# Add remote -git remote add origin https://github.com/flemss/frondend-web.git - -# Push -git branch -M main -git push -u origin main -``` - ---- - -### 2๏ธโƒฃ Deploy ke Vercel - -#### A. Buka Vercel -1. Buka https://vercel.com -2. Klik **"Sign Up"** atau **"Login"** -3. Login dengan **GitHub** - -#### B. Import Project -1. Klik **"Add New..."** โ†’ **"Project"** -2. Pilih **"Import Git Repository"** -3. Cari repository **"frondend-web"** -4. Klik **"Import"** - -#### C. Configure Project -1. **Project Name:** `frondend-web` (atau nama lain) -2. **Framework Preset:** Vercel akan auto-detect **Vite** -3. **Root Directory:** `./` (default) -4. **Build Command:** `npm run build` (auto-filled) -5. **Output Directory:** `dist` (auto-filled) -6. **Install Command:** `npm install` (auto-filled) - -#### D. Environment Variables (Opsional) -Jika ada environment variables, tambahkan di sini. -Untuk saat ini, tidak perlu karena API_URL sudah hardcoded. - -#### E. Deploy! -1. Klik **"Deploy"** -2. Tunggu 1-2 menit -3. **Selesai!** ๐ŸŽ‰ - ---- - -## ๐ŸŒ URL VERCEL - -Setelah deploy selesai, Vercel akan memberikan URL seperti: -``` -https://frondend-web.vercel.app -``` - -atau - -``` -https://frondend-web-flemss.vercel.app -``` - ---- - -## ๐Ÿงช TESTING - -### 1. Buka URL Vercel -``` -https://frondend-web.vercel.app -``` - -### 2. Test Register -1. Klik "Daftar di sini" -2. Isi form registrasi -3. Klik "Daftar" -4. **Expected:** Alert "Registrasi berhasil!" โ†’ Redirect ke login - -### 3. Test Login -1. Isi form login -2. Klik "Masuk" -3. **Expected:** Redirect ke beranda -4. **Expected:** Floating stat suhu muncul - -### 4. Test Control Panel -1. Klik menu "Control" -2. **Expected:** Panel kontrol muncul -3. **Expected:** Data suhu real-time -4. **Expected:** Toggle heater berfungsi - ---- - -## ๐Ÿ”„ UPDATE WEB - -Setiap kali ada perubahan code: - -```bash -cd javaherbal-v2/javaherbal2 - -# Add changes -git add . - -# Commit -git commit -m "Update: deskripsi perubahan" - -# Push -git push origin main -``` - -**Vercel akan otomatis:** -- Detect perubahan di GitHub -- Build ulang -- Deploy versi baru -- Zero downtime! - ---- - -## โš™๏ธ CUSTOM DOMAIN (Opsional) - -Jika ingin pakai domain sendiri (contoh: `javaherbal.com`): - -### 1. Beli Domain -- Namecheap, GoDaddy, Niagahoster, dll - -### 2. Tambah Domain di Vercel -1. Buka project di Vercel dashboard -2. Klik tab **"Settings"** -3. Klik **"Domains"** -4. Klik **"Add"** -5. Masukkan domain Anda -6. Follow instruksi untuk update DNS - -### 3. Update DNS -Di provider domain Anda, tambahkan record: -``` -Type: CNAME -Name: www -Value: cname.vercel-dns.com -``` - -Tunggu 5-60 menit untuk propagasi DNS. - ---- - -## ๐Ÿ” ENVIRONMENT VARIABLES (Jika Diperlukan) - -Jika ingin API_URL bisa diubah tanpa rebuild: - -### 1. Buat file `.env.production` -```bash -VITE_API_URL=https://web-production-32384.up.railway.app/api -``` - -### 2. Update code untuk pakai env variable -```typescript -// Sebelum -const API_URL = 'https://web-production-32384.up.railway.app/api' - -// Sesudah -const API_URL = import.meta.env.VITE_API_URL || 'https://web-production-32384.up.railway.app/api' -``` - -### 3. Set di Vercel Dashboard -1. Buka project di Vercel -2. Klik tab **"Settings"** -3. Klik **"Environment Variables"** -4. Tambah: - - Key: `VITE_API_URL` - - Value: `https://web-production-32384.up.railway.app/api` -5. Save - -### 4. Redeploy -Vercel akan auto redeploy dengan env variable baru. - ---- - -## ๐Ÿ“Š MONITORING - -### Vercel Dashboard -https://vercel.com/dashboard - -**Fitur:** -- โœ… Deployment history -- โœ… Build logs -- โœ… Analytics (traffic, performance) -- โœ… Error tracking -- โœ… Custom domains -- โœ… Environment variables - ---- - -## ๐Ÿ” TROUBLESHOOTING - -### Problem: Build Failed - -**Solusi:** -1. Cek build logs di Vercel dashboard -2. Test build lokal: - ```bash - npm run build - ``` -3. Fix error yang muncul -4. Push lagi ke GitHub - -### Problem: 404 Not Found - -**Solusi:** -1. Pastikan `vercel.json` ada dan benar -2. Pastikan rewrites sudah diset untuk SPA routing -3. Redeploy - -### Problem: API Not Working - -**Solusi:** -1. Cek backend Railway masih online -2. Cek CORS di backend -3. Cek API_URL di code -4. Cek browser console untuk error - ---- - -## โœ… CHECKLIST - -### Sebelum Deploy: -- [x] `.gitignore` sudah dibuat -- [x] `vercel.json` sudah dibuat -- [x] `package.json` script build ada -- [x] API_URL sudah diset ke Railway -- [ ] Test build lokal (`npm run build`) -- [ ] Push ke GitHub - -### Setelah Deploy: -- [ ] URL Vercel bisa diakses -- [ ] Register berfungsi -- [ ] Login berfungsi -- [ ] Control panel berfungsi -- [ ] Data real-time muncul - ---- - -## ๐ŸŽ‰ SELESAI! - -Web Javaherbal sekarang online di Vercel! - -**Keuntungan:** -- โœ… Gratis unlimited -- โœ… Auto deploy dari GitHub -- โœ… HTTPS otomatis -- โœ… CDN global (cepat) -- โœ… Zero downtime deployment -- โœ… Custom domain support - -**Selamat! Web Anda sekarang production-ready!** ๐Ÿš€ - ---- - -## ๐Ÿ“ž SUPPORT - -### Vercel Documentation -https://vercel.com/docs - -### Vite Documentation -https://vitejs.dev/guide/ - -### React Router Documentation -https://reactrouter.com/ - ---- - -**Created:** May 21, 2026 -**Status:** โœ… Ready to Deploy diff --git a/PENJELASAN_SISTEM_LOGIN.md b/PENJELASAN_SISTEM_LOGIN.md deleted file mode 100644 index a62f9a8..0000000 --- a/PENJELASAN_SISTEM_LOGIN.md +++ /dev/null @@ -1,397 +0,0 @@ -# ๐Ÿ“š Penjelasan Sistem Login Web Javaherbal - -## ๐Ÿ” Sistem Penyimpanan Akun - -Web Javaherbal menggunakan **localStorage** browser untuk menyimpan data akun dan status login. - ---- - -## ๐Ÿ“ฆ Apa itu localStorage? - -**localStorage** adalah fitur browser yang memungkinkan website menyimpan data di komputer user secara permanen (tidak hilang saat browser ditutup). - -### Karakteristik localStorage: -- โœ… Data disimpan di **browser user** (bukan di server) -- โœ… Data **tidak hilang** saat browser ditutup -- โœ… Data **tetap ada** sampai dihapus manual -- โœ… Kapasitas: ~5-10 MB per domain -- โœ… Format: Key-Value (string) -- โŒ **TIDAK AMAN** untuk data sensitif (password terlihat plain text) - ---- - -## ๐Ÿ”„ Alur Sistem Login - -### 1๏ธโƒฃ REGISTRASI (Register) - -**File:** `src/pages/Register.tsx` - -#### Langkah-langkah: -1. User mengisi form: - - Nama lengkap - - Email - - Password (minimal 6 karakter) - - Konfirmasi password - -2. Validasi: - ```typescript - // Cek password cocok - if (password !== confirmPassword) { - setError('Password tidak cocok') - return - } - - // Cek panjang password - if (password.length < 6) { - setError('Password minimal 6 karakter') - return - } - - // Cek email sudah terdaftar - const users = JSON.parse(localStorage.getItem('users') || '[]') - if (users.find((u: any) => u.email === email)) { - setError('Email sudah terdaftar') - return - } - ``` - -3. Simpan ke localStorage: - ```typescript - // Buat user baru - const newUser = { name, email, password } - - // Ambil array users yang sudah ada - const users = JSON.parse(localStorage.getItem('users') || '[]') - - // Tambahkan user baru - users.push(newUser) - - // Simpan kembali ke localStorage - localStorage.setItem('users', JSON.stringify(users)) - ``` - -4. Redirect ke halaman login - -#### Contoh Data di localStorage: -```json -{ - "users": [ - { - "name": "John Doe", - "email": "john@example.com", - "password": "123456" - }, - { - "name": "Jane Smith", - "email": "jane@example.com", - "password": "password123" - } - ] -} -``` - ---- - -### 2๏ธโƒฃ LOGIN - -**File:** `src/pages/Login.tsx` - -#### Langkah-langkah: -1. User mengisi form: - - Email - - Password - -2. Validasi: - ```typescript - // Ambil semua users dari localStorage - const users = JSON.parse(localStorage.getItem('users') || '[]') - - // Cari user dengan email dan password yang cocok - const user = users.find((u: any) => - u.email === email && u.password === password - ) - - if (user) { - // Login berhasil - localStorage.setItem('isAuthenticated', 'true') - localStorage.setItem('currentUser', JSON.stringify(user)) - navigate('/') - } else { - // Login gagal - setError('Email atau password salah') - } - ``` - -3. Jika berhasil: - - Set `isAuthenticated` = `'true'` - - Simpan data user ke `currentUser` - - Redirect ke halaman beranda - -#### Data di localStorage Setelah Login: -```json -{ - "users": [...], - "isAuthenticated": "true", - "currentUser": { - "name": "John Doe", - "email": "john@example.com", - "password": "123456" - } -} -``` - ---- - -### 3๏ธโƒฃ CEK STATUS LOGIN - -**File:** `src/components/ProtectedRoute.tsx` - -#### Cara Kerja: -```typescript -const isAuthenticated = localStorage.getItem('isAuthenticated') === 'true' - -if (!isAuthenticated) { - // Redirect ke login - return -} - -// Tampilkan halaman yang dilindungi -return <>{children} -``` - -#### Penggunaan: -```tsx -// Halaman yang perlu login - - - - } -/> -``` - ---- - -### 4๏ธโƒฃ LOGOUT - -**File:** `src/components/Navbar.tsx` (kemungkinan) - -#### Cara Kerja: -```typescript -function handleLogout() { - // Hapus status login - localStorage.removeItem('isAuthenticated') - localStorage.removeItem('currentUser') - - // Redirect ke login - navigate('/login') -} -``` - ---- - -## ๐Ÿ“Š Struktur Data di localStorage - -### Key-Value Pairs: - -| Key | Value | Deskripsi | -|-----|-------|-----------| -| `users` | `[{name, email, password}, ...]` | Array semua user yang terdaftar | -| `isAuthenticated` | `'true'` atau `'false'` | Status login user saat ini | -| `currentUser` | `{name, email, password}` | Data user yang sedang login | - -### Contoh Lengkap: -```json -{ - "users": [ - { - "name": "Admin", - "email": "admin@javaherbal.com", - "password": "admin123" - }, - { - "name": "User Test", - "email": "test@example.com", - "password": "test123" - } - ], - "isAuthenticated": "true", - "currentUser": { - "name": "Admin", - "email": "admin@javaherbal.com", - "password": "admin123" - } -} -``` - ---- - -## ๐Ÿ” Cara Lihat Data di Browser - -### Chrome / Edge: -1. Buka web di browser -2. Tekan **F12** (Developer Tools) -3. Klik tab **Application** -4. Di sidebar kiri, klik **Local Storage** -5. Pilih domain web (contoh: `http://localhost:5173`) -6. Lihat semua key-value yang tersimpan - -### Firefox: -1. Buka web di browser -2. Tekan **F12** (Developer Tools) -3. Klik tab **Storage** -4. Di sidebar kiri, klik **Local Storage** -5. Pilih domain web -6. Lihat semua key-value yang tersimpan - ---- - -## โš ๏ธ KELEMAHAN SISTEM INI - -### 1. **Password Tidak Terenkripsi** -```json -{ - "password": "123456" // โŒ Plain text, bisa dilihat siapa saja! -} -``` - -**Solusi:** -- Gunakan hashing (bcrypt, SHA-256) -- Simpan password di backend, bukan localStorage - -### 2. **Data Bisa Dihapus User** -User bisa hapus localStorage via Developer Tools โ†’ semua akun hilang! - -**Solusi:** -- Simpan data di backend (database) -- localStorage hanya untuk token/session - -### 3. **Tidak Aman untuk Production** -localStorage bisa diakses oleh JavaScript โ†’ rentan XSS attack - -**Solusi:** -- Gunakan backend API untuk autentikasi -- Simpan token di httpOnly cookie -- Implementasi JWT (JSON Web Token) - -### 4. **Data Lokal per Browser** -Akun di Chrome tidak bisa diakses di Firefox (data terpisah) - -**Solusi:** -- Gunakan backend database (MongoDB, PostgreSQL) -- Sinkronisasi data via API - ---- - -## ๐Ÿš€ REKOMENDASI UNTUK PRODUCTION - -### Sistem Login yang Aman: - -#### 1. **Backend API** -``` -Frontend (React) โ†’ Backend API (Express) โ†’ Database (MongoDB) -``` - -#### 2. **Registrasi:** -```typescript -// Frontend -const response = await fetch('/api/auth/register', { - method: 'POST', - body: JSON.stringify({ name, email, password }) -}) - -// Backend -const hashedPassword = await bcrypt.hash(password, 10) -await User.create({ name, email, password: hashedPassword }) -``` - -#### 3. **Login:** -```typescript -// Frontend -const response = await fetch('/api/auth/login', { - method: 'POST', - body: JSON.stringify({ email, password }) -}) -const { token } = await response.json() -localStorage.setItem('token', token) - -// Backend -const user = await User.findOne({ email }) -const isValid = await bcrypt.compare(password, user.password) -if (isValid) { - const token = jwt.sign({ userId: user._id }, SECRET_KEY) - return { token } -} -``` - -#### 4. **Protected Routes:** -```typescript -// Frontend -const token = localStorage.getItem('token') -const response = await fetch('/api/protected', { - headers: { 'Authorization': `Bearer ${token}` } -}) - -// Backend -const token = req.headers.authorization?.split(' ')[1] -const decoded = jwt.verify(token, SECRET_KEY) -const user = await User.findById(decoded.userId) -``` - ---- - -## ๐Ÿ“ KESIMPULAN - -### Sistem Saat Ini (localStorage): -- โœ… **Kelebihan:** - - Mudah implementasi - - Tidak perlu backend - - Cocok untuk prototype/demo - - Cepat - -- โŒ **Kekurangan:** - - Tidak aman (password plain text) - - Data lokal (tidak sinkron antar device) - - Bisa dihapus user - - Tidak cocok untuk production - -### Untuk Production: -- โœ… Gunakan backend API (Express + MongoDB) -- โœ… Hash password (bcrypt) -- โœ… Gunakan JWT untuk token -- โœ… Simpan token di httpOnly cookie -- โœ… Implementasi refresh token -- โœ… Rate limiting untuk prevent brute force -- โœ… HTTPS untuk enkripsi data - ---- - -## ๐ŸŽฏ NEXT STEPS - -Jika ingin upgrade ke sistem yang lebih aman: - -1. **Buat Backend API untuk Auth** - - Endpoint: `/api/auth/register` - - Endpoint: `/api/auth/login` - - Endpoint: `/api/auth/logout` - - Endpoint: `/api/auth/me` (get current user) - -2. **Gunakan MongoDB untuk Simpan User** - - Collection: `users` - - Schema: `{ name, email, password (hashed), createdAt }` - -3. **Implementasi JWT** - - Generate token saat login - - Verify token di protected routes - - Refresh token untuk extend session - -4. **Update Frontend** - - Ganti localStorage dengan API calls - - Simpan hanya token (bukan password) - - Handle token expiration - ---- - -**Untuk saat ini, sistem localStorage sudah cukup untuk development/testing, tapi TIDAK AMAN untuk production!** ๐Ÿ”’ diff --git a/PUSH_TO_GITHUB.md b/PUSH_TO_GITHUB.md deleted file mode 100644 index ab2e11b..0000000 --- a/PUSH_TO_GITHUB.md +++ /dev/null @@ -1,69 +0,0 @@ -# ๐Ÿš€ Push Web Javaherbal ke GitHub - -## ๐Ÿ“‹ COMMAND SIAP PAKAI - -Copy-paste command ini satu per satu: - -### 1. Masuk ke Folder Web -```bash -cd javaherbal-v2/javaherbal2 -``` - -### 2. Initialize Git -```bash -git init -``` - -### 3. Add All Files -```bash -git add . -``` - -### 4. Commit -```bash -git commit -m "Initial commit - Web Javaherbal dengan auth backend" -``` - -### 5. Add Remote (Repository: frondend-web) -```bash -git remote add origin https://github.com/flemss/frondend-web.git -``` - -### 6. Set Branch ke Main -```bash -git branch -M main -``` - -### 7. Push ke GitHub -```bash -git push -u origin main -``` - ---- - -## โœ… SELESAI! - -Repository: https://github.com/flemss/frondend-web - -**Next:** Deploy ke Vercel! - ---- - -## ๐Ÿ”„ UPDATE SETELAH PUSH PERTAMA - -Jika ada perubahan code: - -```bash -cd javaherbal-v2/javaherbal2 - -# Add changes -git add . - -# Commit -git commit -m "Update: deskripsi perubahan" - -# Push -git push origin main -``` - -Vercel akan auto deploy! ๐Ÿš€ diff --git a/README.md b/README.md deleted file mode 100644 index 76ba741..0000000 --- a/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# JavaHerbal ๐ŸŒฟ - -Website herbal modern dengan React + TypeScript + Vite. - -## Cara Menjalankan - -```bash -# 1. Install dependencies -npm install - -# 2. Jalankan dev server -npm run dev -# โ†’ buka http://localhost:5173 - -# 3. Build production -npm run build -``` - -## Fitur -- Hero section dengan animasi -- Panel Kontrol: gauge SVG, toggle power, slider suhu, chart 24 jam (Recharts) -- Grid 6 produk dengan hover effects & keranjang belanja -- Footer lengkap dengan navigasi -- TypeScript strict-free (tidak ada error) - -## Stack -- React 18 + TypeScript -- Vite 5 -- Recharts -- Lucide React -- Google Fonts (Playfair Display + Plus Jakarta Sans) diff --git a/README_UPDATE.md b/README_UPDATE.md deleted file mode 100644 index 600fc67..0000000 --- a/README_UPDATE.md +++ /dev/null @@ -1,245 +0,0 @@ -# โœ… Update Web Javaherbal - Connected to Railway Backend - -## ๐ŸŽ‰ Yang Sudah Diupdate: - -### 1. API Connection -- **Backend URL:** `https://web-production-32384.up.railway.app/api` -- **File:** `src/components/ControlPanel.tsx` - -### 2. Fitur Baru: - -#### โœ… Real-time Data -- Suhu update otomatis setiap 5 detik -- Data dari ESP32 via backend Railway -- Grafik menampilkan history 24 jam terakhir - -#### โœ… Kontrol Manual Heater -- Toggle HEATER: ON/OFF -- Kirim kontrol ke backend โ†’ MQTT โ†’ ESP32 -- Status heater real-time - -#### โœ… Target Suhu (Setpoint) -- Slider untuk set target suhu (30-80ยฐC) -- Kirim setpoint ke backend -- Update otomatis - -### 3. Tampilan -- **TIDAK DIUBAH** - Tampilan tetap sama seperti sebelumnya -- Hanya fungsi backend yang ditambahkan - ---- - -## ๐Ÿš€ Cara Menjalankan - -### 1. Install Dependencies (jika belum) -```bash -cd javaherbal-v2/javaherbal2 -npm install -``` - -### 2. Jalankan Development Server -```bash -npm run dev -``` - -### 3. Buka Browser -``` -http://localhost:5173 -``` - -### 4. Login & Akses Control Panel -- Login dengan akun yang sudah terdaftar -- Klik menu "Control" atau akses `/control` - ---- - -## ๐ŸŽฏ Fitur Control Panel - -### Gauge Suhu -- Menampilkan suhu real-time dari ESP32 -- Update setiap 5 detik -- Range: 0-100ยฐC - -### Toggle HEATER -- **ON:** Heater aktif (hijau) -- **OFF:** Heater nonaktif (abu-abu) -- Klik untuk toggle ON/OFF -- Kirim kontrol ke ESP32 via backend - -### Slider Target Suhu -- Set target suhu: 30-80ยฐC -- Drag slider untuk ubah setpoint -- Otomatis kirim ke backend - -### Grafik Riwayat -- Menampilkan data 24 jam terakhir -- Update setiap 5 detik -- Hover untuk lihat detail - ---- - -## ๐Ÿ”„ Data Flow - -``` -ESP32 (Publish MQTT) - โ†“ -MQTT Broker (broker.hivemq.com) - โ†“ -Backend Railway (Subscribe & Save) - โ†“ -MongoDB Atlas (Store data) - โ†“ -API Endpoint (/api/sensor/latest) - โ†“ -Web Javaherbal (Fetch & Display) -``` - -### Kontrol Flow - -``` -Web Javaherbal (Toggle Heater) - โ†“ -POST /api/sensor/control - โ†“ -Backend Railway (Publish MQTT) - โ†“ -MQTT Broker - โ†“ -ESP32 (Receive & Execute) -``` - ---- - -## ๐Ÿงช Testing - -### Test 1: Data Real-time -1. Buka web di browser -2. Login dan akses Control Panel -3. Lihat gauge suhu -4. **Expected:** Suhu muncul dan update setiap 5 detik - -### Test 2: Kontrol Heater -1. Klik toggle HEATER -2. Lihat perubahan warna (hijau = ON, abu = OFF) -3. Cek di aplikasi mobile atau ESP32 -4. **Expected:** Heater ON/OFF sesuai toggle - -### Test 3: Set Target Suhu -1. Drag slider target suhu -2. Lihat angka berubah -3. **Expected:** Setpoint terkirim ke backend - -### Test 4: Grafik History -1. Lihat grafik di panel kanan -2. Hover untuk lihat detail -3. **Expected:** Grafik menampilkan data 24 jam - ---- - -## ๐Ÿ” Troubleshooting - -### Problem: "Memuat data..." terus menerus - -**Solusi:** -1. Cek backend Railway masih online: - ```bash - curl https://web-production-32384.up.railway.app/api/sensor/latest - ``` -2. Cek browser console (F12) untuk error -3. Pastikan CORS enabled di backend - -### Problem: Toggle heater tidak berfungsi - -**Solusi:** -1. Cek network tab di browser (F12) -2. Lihat response dari POST /api/sensor/control -3. Cek backend logs di Railway - -### Problem: Grafik kosong - -**Solusi:** -1. Tunggu beberapa menit untuk data terkumpul -2. Cek ESP32 masih publish data -3. Cek MongoDB ada data - ---- - -## ๐Ÿ“Š API Endpoints yang Digunakan - -### GET /api/sensor/latest -Fetch data sensor terbaru -```typescript -Response: { - success: true, - data: { - device: "esp32_cabai_01", - suhu: 27.8, - heater: true, - setpoint: 60 - } -} -``` - -### GET /api/sensor/esp32_cabai_01?limit=24 -Fetch history 24 data terakhir -```typescript -Response: { - success: true, - data: [ - { - suhu: 27.8, - createdAt: "2026-05-19T14:45:58.139Z" - } - ] -} -``` - -### POST /api/sensor/control -Kirim kontrol heater -```typescript -Body: { - mode: "MANUAL", - heater: true -} - -Response: { - success: true, - message: "Kontrol relay berhasil dikirim" -} -``` - -### POST /api/sensor/setpoint -Set target suhu -```typescript -Body: { - setpoint: 60 -} - -Response: { - success: true, - message: "Setpoint berhasil diatur" -} -``` - ---- - -## โœ… Checklist - -- [x] Connect ke backend Railway -- [x] Fetch data real-time -- [x] Display suhu di gauge -- [x] Toggle heater ON/OFF -- [x] Set target suhu -- [x] Display grafik history -- [x] Auto refresh setiap 5 detik -- [x] Error handling -- [x] Loading state -- [x] Tampilan tidak berubah - ---- - -## ๐ŸŽ‰ Selesai! - -Web Javaherbal sekarang sudah terhubung dengan backend Railway dan bisa kontrol heater secara manual! - -**Selamat menggunakan!** ๐ŸŒถ๏ธ diff --git a/UPDATE_HERO.md b/UPDATE_HERO.md deleted file mode 100644 index 2ff9265..0000000 --- a/UPDATE_HERO.md +++ /dev/null @@ -1,88 +0,0 @@ -# โœ… Update Hero - Sembunyikan Status Suhu Jika Belum Login - -## ๐ŸŽฏ Perubahan - -### File yang Diubah: -- **`src/components/Hero.tsx`** - -### Apa yang Diubah: -Floating stat "SUHU OPTIMAL 50ยฐC โ€“ 70ยฐC" di hero section sekarang **hanya tampil jika user sudah login**. - ---- - -## ๐Ÿ”’ Logika - -### Sebelum: -```tsx -{/* Floating stat */} -
- ๐ŸŒก๏ธ SUHU OPTIMAL 50ยฐC โ€“ 70ยฐC -
-``` - -**Masalah:** Floating stat selalu tampil, bahkan jika user belum login. - -### Sesudah: -```tsx -{/* Floating stat - Hanya tampil jika sudah login */} -{isAuthenticated && ( -
- ๐ŸŒก๏ธ SUHU OPTIMAL 50ยฐC โ€“ 70ยฐC -
-)} -``` - -**Solusi:** Floating stat hanya tampil jika `isAuthenticated === true`. - ---- - -## ๐Ÿงช Testing - -### Test 1: User Belum Login -1. Buka web di browser -2. Akses halaman beranda (/) -3. **Expected:** Floating stat suhu **TIDAK TAMPIL** -4. Hero section tetap tampil normal tanpa floating stat - -### Test 2: User Sudah Login -1. Login dengan akun yang valid -2. Kembali ke halaman beranda (/) -3. **Expected:** Floating stat suhu **TAMPIL** -4. Menampilkan "SUHU OPTIMAL 50ยฐC โ€“ 70ยฐC" - -### Test 3: Logout -1. Sudah login dan floating stat tampil -2. Logout dari aplikasi -3. Kembali ke halaman beranda -4. **Expected:** Floating stat suhu **TIDAK TAMPIL** - ---- - -## ๐Ÿ”„ Cara Kerja - -### Autentikasi -Web menggunakan `localStorage` untuk menyimpan status login: -```typescript -const isAuthenticated = localStorage.getItem('isAuthenticated') === 'true' -``` - -### Conditional Rendering -React akan render floating stat hanya jika `isAuthenticated === true`: -```tsx -{isAuthenticated && } -``` - ---- - -## ๐Ÿ“Š Status - -- โœ… Floating stat disembunyikan jika belum login -- โœ… Floating stat tampil jika sudah login -- โœ… Tampilan hero section tidak berubah -- โœ… Tidak ada perubahan pada halaman lain - ---- - -## ๐ŸŽ‰ Selesai! - -Floating stat suhu sekarang hanya tampil untuk user yang sudah login! diff --git a/UPDATE_RESPONSIVE.md b/UPDATE_RESPONSIVE.md deleted file mode 100644 index 15c90f1..0000000 --- a/UPDATE_RESPONSIVE.md +++ /dev/null @@ -1,186 +0,0 @@ -# โœ… Update Responsive - Web Javaherbal - -## ๐ŸŽฏ Perubahan - -Web javaherbal sekarang sudah **responsive** dan tidak terpotong di HP! - ---- - -## ๐Ÿ“ฑ Yang Sudah Diupdate - -### 1. **index.css** -- โœ… Prevent horizontal scroll -- โœ… Prevent text size adjustment di mobile -- โœ… Max-width 100% untuk semua elemen -- โœ… Responsive images -- โœ… Font size adjustment untuk mobile -- โœ… Prevent zoom on input focus (font-size 16px) - -### 2. **Navbar.tsx** -- โœ… Responsive height: 64px โ†’ 56px (mobile) -- โœ… Responsive padding: 2rem โ†’ 1rem (mobile) -- โœ… **Hamburger menu di mobile** (icon Menu/X dari lucide-react) -- โœ… Mobile menu dropdown dengan semua navigation links -- โœ… Show user info di mobile menu -- โœ… Full-width login/logout button di mobile menu -- โœ… Auto-close menu saat route berubah -- โœ… Auto-close menu saat resize ke desktop -- โœ… Smooth transitions dan hover effects -- โœ… Active link highlighting di mobile menu - -### 3. **Footer.tsx** -- โœ… Grid responsive: 4 kolom โ†’ 1 kolom (mobile) -- โœ… Padding responsive: 4rem 2rem โ†’ 3rem 1rem (mobile) -- โœ… Bottom bar: row โ†’ column (mobile) -- โœ… Smaller gaps di mobile - -### 4. **Hero.tsx** -- โœ… Grid responsive: 2 kolom โ†’ 1 kolom (mobile) -- โœ… Padding responsive: 2rem โ†’ 1rem - -### 5. **Dashboard.tsx** -- โœ… Section padding responsive: 5rem 2rem โ†’ 3rem 1rem (mobile) -- โœ… Grid auto-fit untuk cards - -### 6. **ControlPanel.tsx** -- โœ… Grid responsive: 2 kolom โ†’ 1 kolom (mobile) -- โœ… Section padding responsive: 5rem 2rem โ†’ 3rem 1rem (mobile) - -### 7. **Login.tsx & Register.tsx** -- โœ… Container padding responsive: 3rem โ†’ 2rem 1.5rem (mobile) -- โœ… Border radius responsive: 24px โ†’ 16px (mobile) -- โœ… Wrapper padding responsive: 2rem โ†’ 1rem (mobile) - -### 8. **Products.tsx** -- โœ… Hero padding responsive: 4rem 2rem โ†’ 3rem 1rem (mobile) -- โœ… Section padding responsive: 4rem 2rem โ†’ 3rem 1rem (mobile) -- โœ… Filter layout: row โ†’ column (mobile) -- โœ… Grid responsive: auto-fill โ†’ 1 kolom (mobile) -- โœ… PaddingTop adjust dengan navbar mobile (56px) - -### 9. **About.tsx** -- โœ… All section padding responsive: 5rem 2rem โ†’ 3rem 1rem (mobile) -- โœ… Timeline layout: 3 kolom โ†’ horizontal (mobile) -- โœ… Hide timeline line di mobile -- โœ… PaddingTop adjust dengan navbar mobile (56px) - ---- - -## ๐Ÿ“Š Breakpoints - -### Desktop (> 768px) -- Navbar: 64px height -- Grid: 2-4 kolom -- Padding: 4-5rem 2rem -- Font size: Normal -- Show all navigation links - -### Mobile (โ‰ค 768px) -- Navbar: 56px height -- **Hamburger menu icon** (Menu/X toggle) -- **Mobile dropdown menu** dengan semua navigation links -- Grid: 1 kolom -- Padding: 3rem 1rem -- Font size: Smaller -- Input font: 16px (prevent zoom) -- Compact buttons - ---- - -## ๐Ÿ”ง Implementasi - -Semua komponen menggunakan: -```typescript -const [isMobile, setIsMobile] = useState(window.innerWidth <= 768) - -React.useEffect(() => { - const handleResize = () => setIsMobile(window.innerWidth <= 768) - window.addEventListener('resize', handleResize) - return () => window.removeEventListener('resize', handleResize) -}, []) -``` - -Kemudian conditional rendering: -```typescript -style={{ - padding: isMobile ? '1rem' : '2rem', - gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr' -}} -``` - ---- - -## ๐Ÿงช Testing - -### Desktop -1. Buka web di browser -2. Resize window -3. **Expected:** Layout adjust smoothly - -### Tablet -1. Buka web di tablet atau resize browser ke 768px -2. **Expected:** Grid jadi 1 kolom -3. **Expected:** Padding lebih kecil - -### Mobile -1. Buka web di HP -2. **Expected:** Hamburger menu icon (โ˜ฐ) muncul di kanan atas -3. **Expected:** Klik hamburger, dropdown menu muncul dengan semua links -4. **Expected:** Klik link, menu auto-close dan navigate -5. **Expected:** Tidak ada horizontal scroll -6. **Expected:** UI tidak terpotong -7. **Expected:** Text readable -8. **Expected:** Input tidak zoom saat focus - ---- - -## โœ… Checklist - -- [x] Prevent horizontal scroll -- [x] Responsive navbar (hide links, compact buttons) -- [x] **Hamburger menu untuk mobile navigation** -- [x] Mobile menu dropdown dengan semua links -- [x] Auto-close menu on route change -- [x] Responsive footer (4 col โ†’ 1 col) -- [x] Responsive grid (2-4 col โ†’ 1 col) -- [x] Responsive padding (all pages) -- [x] Responsive font size -- [x] Prevent zoom on input -- [x] Max-width 100% semua elemen -- [x] Responsive images -- [x] Responsive timeline (About page) -- [x] Responsive filter (Products page) -- [x] Responsive login/register forms - ---- - -## ๐ŸŽ‰ Selesai! - -Web sekarang **fully responsive** dan mobile-friendly! ๐Ÿ“ฑ - -Semua halaman sudah disesuaikan: -- โœ… Home (Hero, Dashboard) -- โœ… Products -- โœ… About -- โœ… Control Panel (gauge tidak terpotong) -- โœ… Login -- โœ… Register -- โœ… **Navbar dengan Hamburger Menu** ๐Ÿ” -- โœ… Footer - -## ๐Ÿ” Fitur Hamburger Menu - -Di mobile (โ‰ค 768px): -1. **Icon hamburger** (โ˜ฐ) muncul di kanan atas navbar -2. **Klik icon** โ†’ Dropdown menu muncul dari atas -3. **Menu berisi:** - - User info (jika login) - - Semua navigation links (Beranda, Produk, Tentang Kami) - - Control Panel link (jika login) - - Button Login/Logout -4. **Auto-close** saat: - - Klik link (navigate ke halaman lain) - - Resize window ke desktop - - Klik icon X -5. **Smooth animations** dan hover effects -6. **Active link highlighting** (warna hijau untuk halaman aktif) diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 8f0d072..e5f484f 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Leaf, Mail, Phone, MapPin, Instagram, Facebook, Youtube, LucideProps } from 'lucide-react' +import { Leaf, Mail, Phone, MapPin, LucideProps } from 'lucide-react' // โ”€โ”€ types โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ type IconComponent = React.FC @@ -8,10 +8,8 @@ interface LinkColData { title: string; links: string[] } interface ContactData { Icon: IconComponent; text: string } // โ”€โ”€ data โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -const SOCIAL_ICONS: IconComponent[] = [Instagram, Facebook, Youtube] - const LINK_COLS: LinkColData[] = [ - { title: 'Produk', links: ['Rempah Kering','Jamu Tradisional', 'Paket Bundle'] }, + { title: 'Produk', links: ['Rempah Kering','Jamu Tradisional'] }, ] const CONTACT_ITEMS: ContactData[] = [ @@ -46,27 +44,6 @@ function HoverLink({ children, dimColor = 'rgba(255,255,255,0.6)', size = '0.85r ) } -function SocialBtn({ Icon }: { Icon: IconComponent }) { - const [hovered, setHovered] = useState(false) - return ( - - ) -} - function LinkCol({ title, links }: LinkColData) { return (
@@ -152,11 +129,6 @@ export default function Footer() { > Teknologi pengeringan untuk menjaga khasiat alami rempah Nusantara.

-
- {SOCIAL_ICONS.map((Icon, i) => ( - - ))} -
{/* Link columns */}