# Explore Lumajang Admin Panel ## Struktur Utama - `app/Models/Kategori.php` dan `app/Models/Wisata.php`: model relasi kategori dan destinasi. - `app/Http/Controllers/Admin`: controller dashboard, login, CRUD wisata, CRUD kategori, dan user aplikasi. - `app/Http/Controllers/API`: API auth, destinations, dan kategori untuk Flutter. - `app/Http/Resources`: format JSON `success`, `message`, dan `data`. - `resources/views/admin`: Blade admin panel Bootstrap 5. - `storage/app/public/images`: penyimpanan gambar wisata. - `storage/app/public/videos`: penyimpanan video wisata. - `storage/app/public/models`: penyimpanan model GLB/GLTF wisata AR. - `routes/web.php`: route admin berbasis session dan middleware `auth` + `admin`. - `routes/api.php`: endpoint JSON untuk aplikasi Flutter. ## Instalasi ```bash cd website/wisata_web composer install cp .env.example .env php artisan key:generate ``` Atur database MySQL di `.env`: ```env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=explore_lumajang_ar DB_USERNAME=root DB_PASSWORD= ``` Jalankan migrasi, seeder admin awal, dan storage link: ```bash php artisan migrate --seed php artisan storage:link php artisan serve ``` Admin panel tersedia di: ```text http://127.0.0.1:8000/admin/login ``` Akun admin awal: ```text Email: admin@explorelumajang.test Password: password ``` Ganti password ini sebelum digunakan untuk produksi. Seeder juga membuat contoh data demo: - `Ranu Pani`: wisata normal. - `Puncak B29`: wisata AR, tombol AR aktif jika `model_path` tersedia. - `Air Terjun Tumpak Sewu`: wisata video, video player aktif jika `is_video = true`. ## Endpoint API Flutter Base URL lokal Android emulator: ```text http://10.0.2.2:8000/api ``` Base URL perangkat fisik: ```text http://IP_LAPTOP_KAMU:8000/api ``` Endpoint publik: ```text GET /health POST /register POST /login POST /forgot-password GET /kategori GET /destinations GET /destinations/{id} ``` Endpoint dengan token Bearer: ```text GET /profile POST /logout POST /wisata/{id}/gambar ``` Contoh response login: ```json { "success": true, "message": "Success", "data": { "token_type": "Bearer", "token": "plain-token", "user": { "id": 1, "name": "User", "email": "user@example.com", "role": "user", "created_at": "2026-05-20T10:00:00.000000Z" } } } ``` Contoh response wisata: ```json { "success": true, "message": "Success", "data": { "id": 1, "title": "Ranu Pani", "category": { "id": 1, "name": "Wisata Alam", "slug": "wisata-alam" }, "location": "Senduro, Lumajang", "image": "http://IP_LAPTOP:8000/storage/images/file.jpg", "rating": 4.8, "distance": "48 km dari pusat kota", "elevation": "2.100 mdpl", "model_path": "http://IP_LAPTOP:8000/storage/models/file.glb", "video_path": "http://IP_LAPTOP:8000/storage/videos/file.mp4", "is_video": false, "type": "normal", "show_ar_button": false, "show_video_player": false, "latitude": -8.0092, "longitude": 112.9446, "google_maps_url": "https://www.google.com/maps?q=-8.0092000,112.9446000" } } ``` ## Integrasi Flutter Simpan base URL di `auth_service.dart` atau konfigurasi environment Flutter. Untuk perangkat fisik gunakan IP laptop, bukan localhost: ```dart const String baseUrl = 'http://IP_LAPTOP:8000/api'; ``` Untuk Android emulator boleh memakai: ```dart const String baseUrl = 'http://10.0.2.2:8000/api'; ``` Untuk request login/register gunakan `POST`. Setelah login, simpan token dari `data.token`, lalu kirim pada endpoint protected: ```dart headers: { 'Accept': 'application/json', 'Authorization': 'Bearer $token', } ``` Untuk memuat destinasi: ```text GET $baseUrl/wisata GET $baseUrl/destinations GET $baseUrl/destinations/{id} GET $baseUrl/kategori ``` Field URL `image`, `model_path`, dan `video_path` sudah dikirim sebagai URL publik dari Laravel storage sehingga bisa langsung digunakan di Flutter. Logic Flutter: ```dart if (destination['show_ar_button'] == true) { // tampilkan tombol AR dan buka model_path } if (destination['show_video_player'] == true) { // tampilkan video player dari video_path } ```