update: oke

main
marszayn 2025-09-17 13:26:06 +07:00
parent 04044070ba
commit aa0767242a
61 changed files with 4310 additions and 784 deletions

View File

@ -0,0 +1,232 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\InformasiKegiatan;
use App\Models\SaranTanggapan;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class LayananController extends Controller
{
/**
* Get all activities data for layanan page
*/
public function getLayananData(): JsonResponse
{
try {
$activities = InformasiKegiatan::active()
->currentPeriod()
->orderBy('TanggalMulaiPeriode', 'desc')
->get();
$groupedData = [];
foreach ($activities as $activity) {
$docType = strtolower(str_replace(['-', ' '], ['', ''], $activity->JenisDokumen));
if (!isset($groupedData[$docType])) {
$groupedData[$docType] = [];
}
$groupedData[$docType][] = [
'id' => $activity->KegiatanID,
'title' => $activity->NamaKegiatan,
'description' => $activity->DampakPotensial,
'link' => '#',
'periode' => $activity->periode,
'no_registrasi' => $activity->NoRegistrasi,
'jenis_dokumen' => $activity->JenisDokumen,
'bidang_usaha' => $activity->BidangUsaha,
'skala_besaran' => $activity->SkalaBesaran,
'lokasi_kegiatan' => $activity->LokasiKegiatan,
'kewenangan' => $activity->Kewenangan,
'pemrakarsa' => $activity->Pemrakarsa,
'provinsi_kota' => $activity->ProvinsiKota,
'deskripsi_kegiatan' => $activity->DeskripsiKegiatan,
'dampak_potensial' => $activity->DampakPotensial,
'deskripsi_lokasi' => $activity->DeskripsiLokasi,
'latitude' => $activity->Latitude,
'longitude' => $activity->Longitude
];
}
// Add audit data (static for now)
$groupedData['audit'] = [
[
'no' => 1,
'company' => 'PT PETROKIMIA GRESIK',
'title' => 'PENGUMUMAN AUDIT LINGKUNGAN HIDUP WAJIB BERKALA INDUSTRI PETROKIMIA',
'description' => 'PT Petrokimia Gresik merupakan Kegiatan pada sektor Industri Petrokimia : Industri Pupuk dan Bahan Kimia (Amonia, Pupuk, Asam Sulfat, Asam Fosfat, dan Asam Klorida)...',
'link' => '#'
]
];
$response = [
'header' => [
'title' => 'Daftar Pengumuman & Informasi',
'subtitle' => 'Daftar Pengumuman dan Informasi terkait kegiatan yang mengajukan izin lingkungan'
],
'tabs' => [
['id' => 'amdal', 'label' => 'AMDAL'],
['id' => 'addendum', 'label' => 'Addendum'],
['id' => 'uklupl', 'label' => 'UKL - UPL'],
['id' => 'audit', 'label' => 'AUDIT']
],
'contents' => $groupedData
];
return response()->json($response);
} catch (\Exception $e) {
return response()->json([
'error' => 'Failed to fetch layanan data',
'message' => $e->getMessage()
], 500);
}
}
/**
* Get specific activity information
*/
public function getActivityInfo($id): JsonResponse
{
try {
$activity = InformasiKegiatan::findOrFail($id);
$data = [
'no_registrasi' => $activity->NoRegistrasi,
'jenis_dokumen' => $activity->JenisDokumen,
'nama_kegiatan' => $activity->NamaKegiatan,
'bidang_usaha' => $activity->BidangUsaha,
'skala_besaran' => $activity->SkalaBesaran,
'lokasi_kegiatan' => $activity->LokasiKegiatan,
'kewenangan' => $activity->Kewenangan,
'pemrakarsa' => $activity->Pemrakarsa,
'provinsi_kota' => $activity->ProvinsiKota,
'deskripsi_kegiatan' => $activity->DeskripsiKegiatan,
'dampak_potensial' => $activity->DampakPotensial,
'deskripsi_lokasi' => $activity->DeskripsiLokasi,
'latitude' => $activity->Latitude,
'longitude' => $activity->Longitude,
'periode' => $activity->periode,
'is_active' => $activity->isActiveFeedbackPeriod()
];
return response()->json($data);
} catch (\Exception $e) {
return response()->json([
'error' => 'Activity not found',
'message' => $e->getMessage()
], 404);
}
}
/**
* Submit feedback for an activity
*/
public function submitFeedback(Request $request): JsonResponse
{
try {
$validator = Validator::make($request->all(), [
'kegiatan_id' => 'required|exists:InformasiKegiatan,KegiatanID',
'nama' => 'required|string|max:100',
'peran' => 'required|in:masyarakat,lsm,akademisi,pemerintah',
'nik' => 'required|string|size:16',
'no_telepon' => 'required|string|max:20',
'email' => 'required|email|max:100',
'gender' => 'required|in:laki-laki,perempuan',
'kondisi_lingkungan' => 'required|string',
'nilai_lokal' => 'required|string',
'kekhawatiran' => 'required|string',
'harapan' => 'required|string',
'tingkat_kekhawatiran' => 'required|integer|min:1|max:5',
'foto_selfie' => 'nullable|image|mimes:jpg,jpeg,png|max:1024'
]);
if ($validator->fails()) {
return response()->json([
'error' => 'Validation failed',
'errors' => $validator->errors()
], 422);
}
// Check if activity is still accepting feedback
$activity = InformasiKegiatan::findOrFail($request->kegiatan_id);
if (!$activity->isActiveFeedbackPeriod()) {
return response()->json([
'error' => 'Periode pengajuan tanggapan untuk kegiatan ini sudah berakhir'
], 400);
}
// Handle photo upload
$photoPath = null;
if ($request->hasFile('foto_selfie')) {
$photo = $request->file('foto_selfie');
$fileName = time() . '_' . uniqid() . '.' . $photo->getClientOriginalExtension();
$photoPath = $photo->storeAs('feedback-photos', $fileName, 'public');
}
// Create feedback record
$feedback = SaranTanggapan::create([
'KegiatanID' => $request->kegiatan_id,
'Nama' => $request->nama,
'Peran' => $request->peran,
'NIK' => $request->nik,
'NoTelepon' => $request->no_telepon,
'Email' => $request->email,
'Gender' => $request->gender,
'KondisiLingkungan' => $request->kondisi_lingkungan,
'NilaiLokal' => $request->nilai_lokal,
'Kekhawatiran' => $request->kekhawatiran,
'Harapan' => $request->harapan,
'TingkatKekhawatiran' => $request->tingkat_kekhawatiran,
'FotoSelfie' => $photoPath,
'TanggalDiajukan' => now()
]);
return response()->json([
'message' => 'Tanggapan berhasil dikirim dan akan diproses oleh admin',
'tanggapan_id' => $feedback->TanggapanID
], 201);
} catch (\Exception $e) {
return response()->json([
'error' => 'Failed to submit feedback',
'message' => $e->getMessage()
], 500);
}
}
/**
* Get feedback statistics for an activity
*/
public function getFeedbackStats($id): JsonResponse
{
try {
$activity = InformasiKegiatan::findOrFail($id);
$stats = [
'total_feedback' => $activity->saranTanggapan()->count(),
'approved_feedback' => $activity->saranTanggapanApproved()->count(),
'pending_feedback' => $activity->saranTanggapan()->pending()->count(),
'by_role' => [
'masyarakat' => $activity->saranTanggapanApproved()->byRole('masyarakat')->count(),
'lsm' => $activity->saranTanggapanApproved()->byRole('lsm')->count(),
'akademisi' => $activity->saranTanggapanApproved()->byRole('akademisi')->count(),
'pemerintah' => $activity->saranTanggapanApproved()->byRole('pemerintah')->count(),
],
'average_rating' => $activity->saranTanggapanApproved()->avg('TingkatKekhawatiran')
];
return response()->json($stats);
} catch (\Exception $e) {
return response()->json([
'error' => 'Activity not found',
'message' => $e->getMessage()
], 404);
}
}
}

View File

@ -4,59 +4,85 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use App\Models\JadwalSidang as JadwalSidangModel;
use App\Models\Perusahaan;
use App\Models\DokumenType;
use Carbon\Carbon;
class JadwalSidangController extends Controller
{
public function index(Request $request)
{
$jadwal = json_decode(File::get(public_path('assets/json/backend/jadwal.json')), true);
// Ambil jadwal dari DB dengan relasi
$query = JadwalSidangModel::with(['perusahaan', 'dokumenType'])->orderBy('TanggalMulai', 'desc');
// Filter by document type if provided in request
$documentType = $request->input('document_type');
if ($documentType) {
$jadwal = array_values(array_filter($jadwal, function($item) use ($documentType) {
return isset($item['documentType']) && $item['documentType'] === $documentType;
}));
if ($request->filled('document_type')) {
$kode = $request->input('document_type');
$query->whereHas('dokumenType', function ($q) use ($kode) {
$q->where('Kode', $kode);
});
}
return view('penjadwalan.jadwal_sidang', compact('jadwal'));
$jadwalDb = $query->get();
// Map ke struktur frontend lama agar script disable time bekerja
$jadwal = $jadwalDb->map(function ($j) {
return [
'id' => $j->JadwalSidangID,
'title' => $j->NamaKegiatan,
'start' => optional($j->TanggalMulai)->toIso8601String(),
'end' => optional($j->TanggalSelesai)->toIso8601String(),
'documentType' => optional($j->dokumenType)->Kode,
'perusahaan' => optional($j->perusahaan)->NamaPerusahaan,
'description' => $j->Deskripsi,
];
})->values()->all();
// Data master untuk modal
$perusahaan = Perusahaan::orderBy('NamaPerusahaan')->get();
$dokumenTypes = DokumenType::orderBy('Nama')->get();
return view('penjadwalan.jadwal_sidang', compact('jadwal', 'perusahaan', 'dokumenTypes'));
}
public function create(Request $request)
{
// Handle form submission for creating new schedule
if ($request->isMethod('post')) {
$jadwal = json_decode(File::get(public_path('assets/json/backend/jadwal.json')), true);
// Validasi minimal
$request->validate([
'title' => 'required|string|max:255',
'perusahaan_id' => 'required|exists:Perusahaan,PerusahaanID',
'start_date' => 'required|string',
'end_date' => 'required|string',
'document_type' => 'required|string',
]);
// Get the highest ID and increment by 1
$maxId = 0;
foreach ($jadwal as $item) {
if (isset($item['id']) && $item['id'] > $maxId) {
$maxId = $item['id'];
}
}
// Cari / buat dokumen type jika belum ada
$kode = $request->input('document_type');
$dokumenType = DokumenType::firstOrCreate(
['Kode' => $kode],
['Nama' => strtoupper(str_replace('_', ' ', $kode))]
);
// Create new jadwal item
$newJadwal = [
'id' => $maxId + 1,
'title' => $request->input('title'),
'start' => $request->input('start_date'),
'end' => $request->input('end_date'),
'allDay' => $request->input('all_day', false),
'documentType' => $request->input('document_type'),
'description' => $request->input('description', '')
];
// Parse tanggal dari format d/m/Y H:i
$start = Carbon::createFromFormat('d/m/Y H:i', $request->input('start_date'));
$end = Carbon::createFromFormat('d/m/Y H:i', $request->input('end_date'));
// Add to existing jadwal
$jadwal[] = $newJadwal;
// Save back to JSON file
File::put(public_path('assets/json/backend/jadwal.json'), json_encode($jadwal, JSON_PRETTY_PRINT));
// Simpan ke DB
JadwalSidangModel::create([
'NamaKegiatan' => $request->input('title'),
'PerusahaanID' => $request->input('perusahaan_id'),
'DokumenTypeID' => $dokumenType->DokumenTypeID,
'Deskripsi' => $request->input('description', ''),
'TanggalMulai' => $start,
'TanggalSelesai' => $end,
]);
return redirect()->route('jadwal.index')->with('success', 'Jadwal berhasil ditambahkan');
}
return view('penjadwalan.create_jadwal');
// GET fallback (tidak digunakan karena pakai modal)
return redirect()->route('jadwal.index');
}
}

View File

@ -0,0 +1,227 @@
<?php
namespace App\Http\Controllers;
use App\Models\InformasiKegiatan;
use App\Models\Kabupaten;
use App\Models\Kecamatan;
use App\Models\Kelurahan;
use Illuminate\Http\Request;
use Carbon\Carbon;
class LayananController extends Controller
{
/**
* Get layanan data for homepage
*/
public function getLayananData()
{
// Header data
$header = [
'title' => 'Layanan Perizinan Lingkungan',
'subtitle' => 'Informasi terkini mengenai berbagai layanan perizinan dan penilaian dampak lingkungan'
];
// Tabs data
$tabs = [
['id' => 'amdal', 'label' => 'AMDAL'],
['id' => 'uklupl', 'label' => 'UKL-UPL'],
['id' => 'addendum', 'label' => 'Addendum'],
['id' => 'audit', 'label' => 'AUDIT']
];
// Contents data from database
$contents = [
'amdal' => $this->getKegiatanByJenis('AMDAL'),
'uklupl' => $this->getKegiatanByJenis('UKL-UPL'),
'addendum' => $this->getKegiatanByJenis('Addendum'),
'audit' => $this->getKegiatanByJenis('AUDIT', true) // Special format for audit
];
return response()->json([
'header' => $header,
'tabs' => $tabs,
'contents' => $contents
]);
}
/**
* Get kegiatan data by document type
*/
private function getKegiatanByJenis($jenis, $isAudit = false)
{
$kegiatan = InformasiKegiatan::where('JenisDokumen', $jenis)
->where('Status', 'aktif')
->whereDate('TanggalSelesaiPeriode', '>=', Carbon::now())
->orderBy('TanggalMulaiPeriode', 'desc')
->take(10)
->get();
if ($isAudit) {
// Format untuk audit table
return $kegiatan->map(function ($item, $index) {
return [
'no' => $index + 1,
'company' => $item->Pemrakarsa,
'title' => $item->NamaKegiatan,
'description' => $item->DeskripsiKegiatan,
'link' => route('layanan.detail', $item->KegiatanID)
];
})->toArray();
} else {
// Format untuk standard items
return $kegiatan->map(function ($item) {
return [
'id' => $item->KegiatanID,
'title' => $item->NamaKegiatan,
'description' => $item->DeskripsiKegiatan,
'periode' => $this->formatPeriode($item->TanggalMulaiPeriode, $item->TanggalSelesaiPeriode),
'link' => route('layanan.detail', $item->KegiatanID),
'status' => $item->Status,
'pemrakarsa' => $item->Pemrakarsa,
'jenis_dokumen' => $item->JenisDokumen,
'no_registrasi' => $item->NoRegistrasi
];
})->toArray();
}
}
/**
* Format periode display
*/
private function formatPeriode($tanggalMulai, $tanggalSelesai)
{
$mulai = Carbon::parse($tanggalMulai);
$selesai = Carbon::parse($tanggalSelesai);
return $mulai->format('d M') . ' - ' . $selesai->format('d M Y');
}
/**
* Get detail kegiatan for feedback form
*/
public function getDetailKegiatan($id)
{
$kegiatan = InformasiKegiatan::findOrFail($id);
return response()->json([
'id' => $kegiatan->KegiatanID,
'no_registrasi' => $kegiatan->NoRegistrasi,
'jenis_dokumen' => $kegiatan->JenisDokumen,
'nama_kegiatan' => $kegiatan->NamaKegiatan,
'bidang_usaha' => $kegiatan->BidangUsaha,
'skala_besaran' => $kegiatan->SkalaBesaran,
'lokasi_kegiatan' => $kegiatan->LokasiKegiatan,
'kewenangan' => $kegiatan->Kewenangan,
'pemrakarsa' => $kegiatan->Pemrakarsa,
'provinsi_kota' => $kegiatan->ProvinsiKota,
'deskripsi_kegiatan' => $kegiatan->DeskripsiKegiatan,
'dampak_potensial' => $kegiatan->DampakPotensial,
'deskripsi_lokasi' => $kegiatan->DeskripsiLokasi,
'latitude' => $kegiatan->Latitude,
'longitude' => $kegiatan->Longitude,
'periode' => $this->formatPeriode($kegiatan->TanggalMulaiPeriode, $kegiatan->TanggalSelesaiPeriode)
]);
}
/**
* Get wilayah data (Kabupaten, Kecamatan, Kelurahan)
*/
public function getWilayahData()
{
$kabupaten = Kabupaten::orderBy('NamaKabupaten')->get();
$kecamatan = Kecamatan::orderBy('NamaKecamatan')->get();
$kelurahan = Kelurahan::orderBy('NamaKelurahan')->get();
return response()->json([
'kabkota' => $kabupaten->map(function($item) {
return [
'value' => $item->KabupatenId,
'label' => $item->NamaKabupaten
];
}),
'kecamatan' => $kecamatan->map(function($item) {
return [
'value' => $item->KecamatanId,
'label' => $item->NamaKecamatan,
'kabupaten_id' => $item->KabupatenId
];
}),
'kelurahan' => $kelurahan->map(function($item) {
return [
'value' => $item->KelurahanId,
'label' => $item->NamaKelurahan,
'kecamatan_id' => $item->KecamatanId
];
})
]);
}
/**
* Get filtered kegiatan data
*/
public function getFilteredKegiatan(Request $request)
{
$query = InformasiKegiatan::where('Status', 'aktif')
->whereDate('TanggalSelesaiPeriode', '>=', Carbon::now());
// Filter by search term
if ($request->search) {
$query->where(function($q) use ($request) {
$q->where('NamaKegiatan', 'ILIKE', '%' . $request->search . '%')
->orWhere('DeskripsiKegiatan', 'ILIKE', '%' . $request->search . '%')
->orWhere('Pemrakarsa', 'ILIKE', '%' . $request->search . '%');
});
}
// Filter by document type
if ($request->jenis_dokumen) {
$allowedTypes = ['AMDAL', 'UKL-UPL', 'Addendum', 'AUDIT'];
if (in_array($request->jenis_dokumen, $allowedTypes)) {
$query->where('JenisDokumen', $request->jenis_dokumen);
}
}
// Filter by location (you can extend this based on your needs)
if ($request->kabkota) {
$query->where('ProvinsiKota', 'ILIKE', '%' . $request->kabkota . '%');
}
$kegiatan = $query->orderBy('TanggalMulaiPeriode', 'desc')->get();
// Group by document type
$groupedKegiatan = $kegiatan->groupBy('JenisDokumen');
$contents = [];
foreach ($groupedKegiatan as $jenis => $items) {
$key = strtolower($jenis);
if ($jenis === 'AUDIT') {
$contents[$key] = $items->map(function ($item, $index) {
return [
'no' => $index + 1,
'company' => $item->Pemrakarsa,
'title' => $item->NamaKegiatan,
'description' => $item->DeskripsiKegiatan,
'link' => route('layanan.detail', $item->KegiatanID)
];
})->toArray();
} else {
$contents[$key] = $items->map(function ($item) {
return [
'id' => $item->KegiatanID,
'title' => $item->NamaKegiatan,
'description' => $item->DeskripsiKegiatan,
'periode' => $this->formatPeriode($item->TanggalMulaiPeriode, $item->TanggalSelesaiPeriode),
'link' => route('layanan.detail', $item->KegiatanID),
'status' => $item->Status,
'pemrakarsa' => $item->Pemrakarsa,
'jenis_dokumen' => $item->JenisDokumen,
'no_registrasi' => $item->NoRegistrasi
];
})->toArray();
}
}
return response()->json($contents);
}
}

View File

@ -10,4 +10,10 @@ class LoginController extends Controller
{
return view('auth/signin');
}
public function register()
{
return view('auth/signup');
}
}

View File

@ -0,0 +1,301 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\InformasiKegiatan;
use App\Models\Kabupaten;
use App\Models\Kecamatan;
use App\Models\Kelurahan;
use Carbon\Carbon;
class PengumumanController extends Controller
{
public function index()
{
$pengumuman = InformasiKegiatan::with('saranTanggapan')
->active()
->orderBy('TanggalMulaiPeriode', 'desc')
->get()
->map(function ($item, $index) {
return [
'no' => $index + 1,
'no_registrasi' => $item->NoRegistrasi,
'nama_perusahaan' => $item->Pemrakarsa,
'nama_kegiatan' => $item->NamaKegiatan,
'jenis_dokumen' => $item->JenisDokumen,
'periode' => $this->formatBusinessDayPeriod($item->TanggalMulaiPeriode, 10),
'status' => 'Menunggu Tanggapan',
'detail_url' => route('pengumuman.detail', $item->KegiatanID)
];
});
return view('pengumuman.index', compact('pengumuman'));
}
/**
* Generate business day period (10 working days excluding weekends and holidays)
*/
private function formatBusinessDayPeriod($startDate, $workingDays = 10)
{
$start = Carbon::parse($startDate);
$current = $start->copy();
$daysAdded = 0;
// Indonesian public holidays 2025 (tanggal merah)
$holidays = [
'2025-01-01', // Tahun Baru
'2025-01-29', // Tahun Baru Imlek
'2025-03-29', // Hari Raya Nyepi
'2025-03-30', // Wafat Isa Almasih
'2025-04-09', // Isra Miraj
'2025-05-01', // Hari Buruh
'2025-05-12', // Hari Raya Waisak
'2025-05-29', // Kenaikan Isa Almasih
'2025-06-01', // Hari Lahir Pancasila
'2025-06-06', // Idul Fitri 1446 H
'2025-06-07', // Idul Fitri 1446 H
'2025-08-17', // Hari Kemerdekaan RI
'2025-08-31', // Idul Adha 1446 H
'2025-09-21', // Tahun Baru Islam 1447 H
'2025-11-30', // Maulid Nabi Muhammad SAW
'2025-12-25', // Hari Raya Natal
];
while ($daysAdded < $workingDays) {
$current->addDay();
// Skip weekends (Saturday = 6, Sunday = 0)
if ($current->dayOfWeek == Carbon::SATURDAY || $current->dayOfWeek == Carbon::SUNDAY) {
continue;
}
// Skip public holidays
if (in_array($current->format('Y-m-d'), $holidays)) {
continue;
}
$daysAdded++;
}
return $start->format('d M') . ' - ' . $current->format('d M Y');
}
public function detail($id)
{
$kegiatan = InformasiKegiatan::with('saranTanggapanApproved')->findOrFail($id);
return view('pengumuman.detail', compact('kegiatan'));
}
public function create()
{
$kabupaten = Kabupaten::orderBy('NamaKabupaten', 'asc')->get();
return view('pengumuman.create', compact('kabupaten'));
}
/**
* Generate unique 12-digit registration number with enhanced security
* Format: Mixed alphanumeric with timestamp hash to prevent easy guessing
* Example: ENV4B7X9K2M
*/
private function generateRegistrationNumber()
{
do {
// Create a unique seed from current time, microtime, and random data
$seed = now()->timestamp . microtime(true) . random_int(100000, 999999);
// Generate hash and extract alphanumeric characters
$hash = hash('sha256', $seed);
// Create character pool (excluding similar looking characters)
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
// Start with prefix
$prefix = 'REG';
// Generate 9 additional characters from hash
$remaining = '';
$hashPos = 0;
while (strlen($remaining) < 9 && $hashPos < strlen($hash)) {
$hexChar = strtoupper($hash[$hashPos]);
// Convert hex to index in our character pool
$index = hexdec($hexChar) % strlen($chars);
$remaining .= $chars[$index];
$hashPos++;
}
// If we need more characters, use additional random generation
while (strlen($remaining) < 9) {
$remaining .= $chars[random_int(0, strlen($chars) - 1)];
}
$registrationNumber = $prefix . $remaining;
// Check if this number already exists
$exists = InformasiKegiatan::where('NoRegistrasi', $registrationNumber)->exists();
} while ($exists); // Keep generating until we get a unique number
return $registrationNumber;
}
public function store(Request $request)
{
$validated = $request->validate([
'jenis_dokumen' => 'required|string|max:50',
'nama_kegiatan' => 'required|string|max:255',
'pemrakarsa' => 'required|string|max:100',
'bidang_usaha' => 'required|string|max:100',
'deskripsi_kegiatan' => 'required|string',
'dampak_potensial' => 'required|string',
'kabupaten' => 'required|string|max:100',
'kecamatan' => 'required|string|max:100',
'kelurahan' => 'required|string|max:100',
'lokasi_kegiatan' => 'nullable|string|max:100',
'deskripsi_lokasi' => 'required|string',
'latitude' => 'nullable|numeric|between:-90,90',
'longitude' => 'nullable|numeric|between:-180,180',
'tanggal_mulai' => 'required|date|after_or_equal:today',
'skala_besaran' => 'nullable|string|max:50',
'kewenangan' => 'required|string|max:50',
'status' => 'required|in:aktif,nonaktif'
], [
'jenis_dokumen.required' => 'Jenis dokumen wajib dipilih',
'nama_kegiatan.required' => 'Nama kegiatan wajib diisi',
'pemrakarsa.required' => 'Pemrakarsa wajib diisi',
'bidang_usaha.required' => 'Bidang usaha wajib diisi',
'deskripsi_kegiatan.required' => 'Deskripsi kegiatan wajib diisi',
'dampak_potensial.required' => 'Dampak potensial wajib diisi',
'kabupaten.required' => 'Kabupaten wajib dipilih',
'kecamatan.required' => 'Kecamatan wajib dipilih',
'kelurahan.required' => 'Kelurahan wajib dipilih',
'deskripsi_lokasi.required' => 'Deskripsi lokasi wajib diisi',
'tanggal_mulai.required' => 'Tanggal mulai periode wajib diisi',
'tanggal_mulai.after_or_equal' => 'Tanggal mulai tidak boleh kurang dari hari ini',
'kewenangan.required' => 'Kewenangan wajib dipilih',
'status.required' => 'Status wajib dipilih',
'latitude.between' => 'Latitude harus antara -90 sampai 90',
'longitude.between' => 'Longitude harus antara -180 sampai 180'
]);
try {
// Generate unique registration number
$noRegistrasi = $this->generateRegistrationNumber();
// Calculate end date (10 business days from start date)
$startDate = Carbon::parse($validated['tanggal_mulai']);
$endDate = $this->calculateBusinessDayEnd($startDate, 10);
// Get location names from database
$kabupaten = Kabupaten::find($validated['kabupaten']);
$kecamatan = Kecamatan::find($validated['kecamatan']);
$kelurahan = Kelurahan::find($validated['kelurahan']);
$kombinasiLokasi = $kabupaten->NamaKabupaten . ', ' . $kecamatan->NamaKecamatan . ', ' . $kelurahan->NamaKelurahan;
InformasiKegiatan::create([
'NoRegistrasi' => $noRegistrasi,
'JenisDokumen' => $validated['jenis_dokumen'],
'NamaKegiatan' => $validated['nama_kegiatan'],
'Pemrakarsa' => $validated['pemrakarsa'],
'BidangUsaha' => $validated['bidang_usaha'],
'DeskripsiKegiatan' => $validated['deskripsi_kegiatan'],
'DampakPotensial' => $validated['dampak_potensial'],
'ProvinsiKota' => $kombinasiLokasi,
'LokasiKegiatan' => $validated['lokasi_kegiatan'],
'DeskripsiLokasi' => $validated['deskripsi_lokasi'],
'Latitude' => $validated['latitude'],
'Longitude' => $validated['longitude'],
'TanggalMulaiPeriode' => $startDate,
'TanggalSelesaiPeriode' => $endDate,
'SkalaBesaran' => $validated['skala_besaran'],
'Kewenangan' => $validated['kewenangan'],
'Status' => $validated['status']
]);
return redirect()->route('pengumuman.index')
->with('success', 'Pengumuman kegiatan berhasil ditambahkan dengan nomor registrasi: ' . $noRegistrasi);
} catch (\Exception $e) {
return back()
->withInput()
->with('error', 'Terjadi kesalahan saat menyimpan data: ' . $e->getMessage());
}
}
public function calculatePeriod(Request $request)
{
$startDate = Carbon::parse($request->start_date);
$endDate = $this->calculateBusinessDayEnd($startDate, 10);
$periode = $startDate->format('d M') . ' - ' . $endDate->format('d M Y');
return response()->json([
'success' => true,
'periode' => $periode,
'start_date' => $startDate->format('Y-m-d'),
'end_date' => $endDate->format('Y-m-d')
]);
}
/**
* Calculate business day end date (excludes weekends and holidays)
*/
private function calculateBusinessDayEnd($startDate, $workingDays = 10)
{
$current = $startDate->copy();
$daysAdded = 0;
// Indonesian public holidays 2025 (tanggal merah)
$holidays = [
'2025-01-01', '2025-01-29', '2025-03-29', '2025-03-30', '2025-04-09',
'2025-05-01', '2025-05-12', '2025-05-29', '2025-06-01', '2025-06-06',
'2025-06-07', '2025-08-17', '2025-08-31', '2025-09-21', '2025-11-30',
'2025-12-25'
];
while ($daysAdded < $workingDays) {
$current->addDay();
// Skip weekends and holidays
if ($current->dayOfWeek == Carbon::SATURDAY ||
$current->dayOfWeek == Carbon::SUNDAY ||
in_array($current->format('Y-m-d'), $holidays)) {
continue;
}
$daysAdded++;
}
return $current;
}
/**
* Get kecamatan by kabupaten ID
*/
public function getKecamatan(Request $request)
{
$kabupatenId = $request->kabupaten_id;
$kecamatan = Kecamatan::where('KabupatenId', $kabupatenId)
->orderBy('NamaKecamatan', 'asc')
->get(['KecamatanId', 'NamaKecamatan']);
return response()->json($kecamatan);
}
/**
* Get kelurahan by kecamatan ID
*/
public function getKelurahan(Request $request)
{
$kecamatanId = $request->kecamatan_id;
$kelurahan = Kelurahan::where('KecamatanId', $kecamatanId)
->orderBy('NamaKelurahan', 'asc')
->get(['KelurahanId', 'NamaKelurahan']);
return response()->json($kelurahan);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PerusahaanController extends Controller
{
public function kelengkapan(Request $request)
{
// show a placeholder kelengkapan page; view can be implemented later
return view('perusahaan.kelengkapan', [
'userId' => $request->query('user'),
'daftarId' => $request->query('daftar'),
]);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers;
use App\Models\Daftar;
use App\Models\Perusahaan;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
class SignupController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'company_name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', 'unique:users,email'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
// Create user and signup record
DB::beginTransaction();
try {
$user = User::create([
'name' => $data['company_name'],
'email' => $data['email'],
'username' => $data['email'],
'password' => Hash::make($data['password']),
]);
// Ensure 'perusahaan' role exists, then assign it
if (!\Spatie\Permission\Models\Role::where('name', 'perusahaan')->exists()) {
\Spatie\Permission\Models\Role::create(['name' => 'perusahaan']);
}
$user->assignRole('perusahaan');
// Create Daftar record (Status Active by default)
$daftar = Daftar::create([
'NamaPerusahaan' => $data['company_name'],
'Email' => $data['email'],
'Password' => Hash::make($data['password']),
'Status' => 'Active',
]);
// Ensure a Perusahaan exists and attach user via pivot
$perusahaan = Perusahaan::firstOrCreate(
['NamaPerusahaan' => $data['company_name']],
['Alamat' => null]
);
// Attach user to perusahaan via pivot (avoid duplicates)
$user->perusahaans()->syncWithoutDetaching([$perusahaan->PerusahaanID]);
DB::commit();
} catch (\Throwable $e) {
DB::rollBack();
report($e);
return back()->withErrors(['error' => 'Registration failed.']);
}
// Redirect to login page; user already has 'perusahaan' role and is attached to perusahaan
return redirect()->route('login.index')->with('status', 'Akun berhasil dibuat dan aktif. Silakan masuk.');
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Daftar extends Model
{
use HasFactory, HasUuids;
protected $table = 'Daftar';
protected $primaryKey = 'DaftarID';
protected $keyType = 'string';
public $incrementing = false;
protected $fillable = [
'NamaPerusahaan',
'Email',
'Password',
'Status',
];
protected $hidden = [
'Password',
];
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DokumenType extends Model
{
protected $table = 'DokumenType';
protected $primaryKey = 'DokumenTypeID';
protected $fillable = [
'Kode',
'Nama',
];
public function jadwalSidang()
{
return $this->hasMany(JadwalSidang::class, 'DokumenTypeID', 'DokumenTypeID');
}
}

View File

@ -41,7 +41,7 @@ class FastestPermohonan extends Model
return self::where('Kategori_ID', $kategori)
->whereDate('SyncDate', $latestSyncDate)
->orderBy('FastestPermohonanID') // Keep API order by using insertion order
->orderBy('FastestPermohonanID')
->limit(5)
->get();
}

View File

@ -0,0 +1,103 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class InformasiKegiatan extends Model
{
use HasFactory;
protected $table = 'InformasiKegiatan';
protected $primaryKey = 'KegiatanID';
protected $fillable = [
'NoRegistrasi',
'JenisDokumen',
'NamaKegiatan',
'BidangUsaha',
'SkalaBesaran',
'LokasiKegiatan',
'Kewenangan',
'Pemrakarsa',
'ProvinsiKota',
'DeskripsiKegiatan',
'DampakPotensial',
'DeskripsiLokasi',
'Latitude',
'Longitude',
'TanggalMulaiPeriode',
'TanggalSelesaiPeriode',
'Status'
];
protected $casts = [
'TanggalMulaiPeriode' => 'date',
'TanggalSelesaiPeriode' => 'date',
'Latitude' => 'decimal:8',
'Longitude' => 'decimal:8',
];
/**
* Get all feedback for this activity
*/
public function saranTanggapan()
{
return $this->hasMany(SaranTanggapan::class, 'KegiatanID');
}
/**
* Get approved feedback only
*/
public function saranTanggapanApproved()
{
return $this->hasMany(SaranTanggapan::class, 'KegiatanID')->where('Status', 'approved');
}
/**
* Scope for active activities
*/
public function scopeActive($query)
{
return $query->where('Status', 'aktif');
}
/**
* Scope for specific document type
*/
public function scopeByDocumentType($query, $type)
{
return $query->where('JenisDokumen', $type);
}
/**
* Scope for current period
*/
public function scopeCurrentPeriod($query)
{
$today = now()->toDateString();
return $query->where('TanggalMulaiPeriode', '<=', $today)
->where('TanggalSelesaiPeriode', '>=', $today);
}
/**
* Get formatted period string
*/
public function getPeriodeAttribute()
{
return $this->TanggalMulaiPeriode->format('d M') . ' - ' .
$this->TanggalSelesaiPeriode->format('d M Y');
}
/**
* Check if activity is currently active for feedback
*/
public function isActiveFeedbackPeriod()
{
$today = now()->toDateString();
return $this->Status === 'aktif' &&
$this->TanggalMulaiPeriode <= $today &&
$this->TanggalSelesaiPeriode >= $today;
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class JadwalSidang extends Model
{
protected $table = 'JadwalSidang';
protected $primaryKey = 'JadwalSidangID';
protected $fillable = [
'NamaKegiatan',
'PerusahaanID',
'DokumenTypeID',
'Deskripsi',
'TanggalMulai',
'TanggalSelesai',
];
protected $casts = [
'TanggalMulai' => 'datetime',
'TanggalSelesai' => 'datetime',
];
public function dokumenType()
{
return $this->belongsTo(DokumenType::class, 'DokumenTypeID', 'DokumenTypeID');
}
public function perusahaan()
{
return $this->belongsTo(Perusahaan::class, 'PerusahaanID', 'PerusahaanID');
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Kabupaten extends Model
{
protected $table = 'Kabupaten';
protected $primaryKey = 'KabupatenId';
protected $fillable = [
'KabupatenId',
'NamaKabupaten',
];
public function kecamatan()
{
return $this->hasMany(Kecamatan::class, 'KabupatenId', 'KabupatenId');
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Kecamatan extends Model
{
protected $table = 'Kecamatan';
protected $primaryKey = 'KecamatanId';
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = [
'KecamatanId',
'KabupatenId',
'NamaKecamatan'
];
public function kabupaten()
{
return $this->belongsTo(Kabupaten::class, 'KabupatenId', 'KabupatenId');
}
public function kelurahan()
{
return $this->hasMany(Kelurahan::class, 'KecamatanId', 'KecamatanId');
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Kelurahan extends Model
{
protected $table = 'Kelurahan';
protected $primaryKey = 'KelurahanId';
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = ['KelurahanId', 'KecamatanId', 'NamaKelurahan'];
public function kecamatan()
{
return $this->belongsTo(Kecamatan::class, 'KecamatanId', 'KecamatanId');
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Perusahaan extends Model
{
protected $table = 'Perusahaan';
protected $primaryKey = 'PerusahaanID';
protected $fillable = [
'NamaPerusahaan',
'Alamat',
];
public function jadwalSidang()
{
return $this->hasMany(JadwalSidang::class, 'PerusahaanID', 'PerusahaanID');
}
public function users()
{
return $this->belongsToMany(User::class, 'Perusahaan_User', 'PerusahaanID', 'UserID');
}
}

View File

@ -0,0 +1,139 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SaranTanggapan extends Model
{
use HasFactory;
protected $table = 'SaranTanggapan';
protected $primaryKey = 'TanggapanID';
protected $fillable = [
'KegiatanID',
'Nama',
'Peran',
'NIK',
'NoTelepon',
'Email',
'Gender',
'KondisiLingkungan',
'NilaiLokal',
'Kekhawatiran',
'Harapan',
'TingkatKekhawatiran',
'FotoSelfie',
'Status',
'CatatanAdmin',
'TanggalDiajukan',
'TanggalDiproses'
];
protected $casts = [
'TanggalDiajukan' => 'datetime',
'TanggalDiproses' => 'datetime',
'TingkatKekhawatiran' => 'integer'
];
/**
* Get the activity this feedback belongs to
*/
public function informasiKegiatan()
{
return $this->belongsTo(InformasiKegiatan::class, 'KegiatanID');
}
/**
* Scope for pending feedback
*/
public function scopePending($query)
{
return $query->where('Status', 'pending');
}
/**
* Scope for approved feedback
*/
public function scopeApproved($query)
{
return $query->where('Status', 'approved');
}
/**
* Scope for rejected feedback
*/
public function scopeRejected($query)
{
return $query->where('Status', 'rejected');
}
/**
* Scope by role
*/
public function scopeByRole($query, $role)
{
return $query->where('Peran', $role);
}
/**
* Get the rating level description
*/
public function getRatingDescriptionAttribute()
{
$descriptions = [
1 => 'Sangat Khawatir',
2 => 'Khawatir',
3 => 'Netral',
4 => 'Berharap',
5 => 'Sangat Berharap'
];
return $descriptions[$this->TingkatKekhawatiran] ?? 'Tidak Diketahui';
}
/**
* Get formatted submission date
*/
public function getFormattedSubmissionDateAttribute()
{
return $this->TanggalDiajukan->format('d M Y H:i');
}
/**
* Get photo URL
*/
public function getPhotoUrlAttribute()
{
if ($this->FotoSelfie) {
return asset('storage/feedback-photos/' . $this->FotoSelfie);
}
return null;
}
/**
* Approve this feedback
*/
public function approve($adminNote = null)
{
$this->update([
'Status' => 'approved',
'CatatanAdmin' => $adminNote,
'TanggalDiproses' => now()
]);
}
/**
* Reject this feedback
*/
public function reject($adminNote = null)
{
$this->update([
'Status' => 'rejected',
'CatatanAdmin' => $adminNote,
'TanggalDiproses' => now()
]);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Signup extends Model
{
use HasFactory, HasUuids;
protected $table = 'Signups';
protected $keyType = 'string';
public $incrementing = false;
protected $fillable = [
'CompanyName',
'Email',
'Password',
'Status',
];
protected $hidden = [
'Password',
];
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
}

View File

@ -64,4 +64,9 @@ class User extends Authenticatable
'password' => 'hashed',
];
}
public function perusahaans()
{
return $this->belongsToMany(Perusahaan::class, 'Perusahaan_User', 'UserID', 'PerusahaanID');
}
}

View File

@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('InformasiKegiatan', function (Blueprint $table) {
$table->id('KegiatanID');
$table->string('NoRegistrasi', 50)->unique();
$table->string('JenisDokumen', 50);
$table->string('NamaKegiatan');
$table->string('BidangUsaha', 100);
$table->string('SkalaBesaran', 50);
$table->string('LokasiKegiatan', 100)->nullable();
$table->string('Kewenangan', 50);
$table->string('Pemrakarsa', 100);
$table->string('ProvinsiKota', 100);
$table->text('DeskripsiKegiatan');
$table->text('DampakPotensial');
$table->string('DeskripsiLokasi');
$table->decimal('Latitude', 10, 8)->nullable();
$table->decimal('Longitude', 11, 8)->nullable();
$table->date('TanggalMulaiPeriode');
$table->date('TanggalSelesaiPeriode');
$table->enum('Status', ['aktif', 'nonaktif', 'selesai'])->default('aktif');
$table->timestamps();
$table->index(['JenisDokumen', 'Status']);
$table->index(['TanggalMulaiPeriode', 'TanggalSelesaiPeriode']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('InformasiKegiatan');
}
};

View File

@ -0,0 +1,49 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('SaranTanggapan', function (Blueprint $table) {
$table->id('TanggapanID');
$table->unsignedBigInteger('KegiatanID');
$table->string('Nama', 100);
$table->enum('Peran', ['masyarakat', 'lsm', 'akademisi', 'pemerintah']);
$table->string('NIK', 16);
$table->string('NoTelepon', 20);
$table->string('Email', 100);
$table->enum('Gender', ['laki-laki', 'perempuan']);
$table->text('KondisiLingkungan');
$table->text('NilaiLokal');
$table->text('Kekhawatiran');
$table->text('Harapan');
$table->tinyInteger('TingkatKekhawatiran')->comment('1-5 scale: 1=sangat khawatir, 5=sangat berharap');
$table->string('FotoSelfie', 255)->nullable();
$table->enum('Status', ['pending', 'approved', 'rejected'])->default('pending');
$table->text('CatatanAdmin')->nullable();
$table->timestamp('TanggalDiajukan')->useCurrent();
$table->timestamp('TanggalDiproses')->nullable();
$table->timestamps();
$table->foreign('KegiatanID')->references('KegiatanID')->on('InformasiKegiatan')->onDelete('cascade');
$table->index(['KegiatanID', 'Status']);
$table->index(['Peran', 'Status']);
$table->index('TanggalDiajukan');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('SaranTanggapan');
}
};

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('DokumenType', function (Blueprint $table) {
$table->id('DokumenTypeID');
$table->string('Kode', 50)->unique();
$table->string('Nama', 100);
$table->timestamps();
$table->index(['Kode'], 'IX_DokumenType_Kode');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('DokumenType');
}
};

View File

@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('JadwalSidang', function (Blueprint $table) {
$table->id('JadwalSidangID');
$table->string('NamaKegiatan');
// FK ke master DokumenType
$table->unsignedBigInteger('DokumenTypeID');
$table->text('Deskripsi')->nullable();
$table->dateTime('TanggalMulai');
$table->dateTime('TanggalSelesai');
$table->timestamps();
$table->index(['DokumenTypeID'], 'IX_Jadwal_DokumenTypeID');
$table->index(['TanggalMulai'], 'IX_Jadwal_TanggalMulai');
$table->index(['TanggalMulai', 'TanggalSelesai'], 'IX_Jadwal_TanggalRange');
$table->foreign('DokumenTypeID')
->references('DokumenTypeID')
->on('DokumenType')
->cascadeOnUpdate()
->restrictOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('JadwalSidang');
}
};

View File

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Perusahaan', function (Blueprint $table) {
$table->id('PerusahaanID');
$table->string('NamaPerusahaan', 255);
$table->text('Alamat')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('Perusahaan');
}
};

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('JadwalSidang', function (Blueprint $table) {
$table->unsignedBigInteger('PerusahaanID')->after('JadwalSidangID');
$table->index(['PerusahaanID'], 'IX_Jadwal_PerusahaanID');
$table->foreign('PerusahaanID')
->references('PerusahaanID')
->on('Perusahaan')
->cascadeOnUpdate()
->restrictOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('JadwalSidang', function (Blueprint $table) {
$table->dropForeign(['PerusahaanID']);
$table->dropIndex('IX_Jadwal_PerusahaanID');
$table->dropColumn('PerusahaanID');
});
}
};

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Daftar', function (Blueprint $table) {
$table->uuid('DaftarID')->primary();
$table->string('NamaPerusahaan');
$table->string('Email')->unique();
$table->string('Password');
$table->string('Status')->default('Active');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('signups');
}
};

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Perusahaan_User', function (Blueprint $table) {
// Perusahaan.PerusahaanID was created with $table->id(), so it's bigint
$table->unsignedBigInteger('PerusahaanID');
// users.id is UUID in this project
$table->uuid('UserID');
$table->timestamps();
$table->primary(['PerusahaanID', 'UserID']);
// Foreign key constraints
$table->foreign('PerusahaanID')->references('PerusahaanID')->on('Perusahaan')->onDelete('cascade');
$table->foreign('UserID')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('Perusahaan_User');
}
};

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Kabupaten', function (Blueprint $table) {
$table->id('KabupatenId');
$table->string('NamaKabupaten');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('Kabupaten');
}
};

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Kecamatan', function (Blueprint $table) {
$table->id('KecamatanId');
$table->unsignedBigInteger('KabupatenId');
$table->foreign('KabupatenId')->references('KabupatenId')->on('Kabupaten')->onDelete('cascade');
$table->string('NamaKecamatan');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('Kecamatan');
}
};

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('Kelurahan', function (Blueprint $table) {
$table->id('KelurahanId');
$table->unsignedBigInteger('KecamatanId');
$table->foreign('KecamatanId')->references('KecamatanId')->on('Kecamatan')->onDelete('cascade');
$table->string('NamaKelurahan');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('Kelurahan');
}
};

View File

@ -2,10 +2,10 @@
namespace Database\Seeders;
use App\Models\User;
use Database\Seeders\UserSeeder;
use Database\Seeders\RolesAndPermissionsSeeder;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Database\Seeders\PerusahaanSeeder;
use Database\Seeders\InformasiKegiatanSeeder;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
@ -19,6 +19,11 @@ class DatabaseSeeder extends Seeder
$this->call([
RolesAndPermissionsSeeder::class,
UserSeeder::class,
PerusahaanSeeder::class,
InformasiKegiatanSeeder::class,
KabupatenTableSeeder::class,
KecamatanTableSeeder::class,
KelurahanTableSeeder::class,
]);
}
}

View File

@ -0,0 +1,313 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\InformasiKegiatan;
use Carbon\Carbon;
class InformasiKegiatanSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$kegiatan = [
// AMDAL Documents (5 records)
[
'NoRegistrasi' => 'REGC7EGE9465',
'JenisDokumen' => 'AMDAL',
'NamaKegiatan' => 'Kegiatan Penggalian Kuarsa/Pasir Kuarsa, LUKITO HARTONO LAWY',
'BidangUsaha' => 'Pertambangan',
'SkalaBesaran' => '50000.00 ton/tahun',
'LokasiKegiatan' => 'Desa Marga Sungsang',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. KARUNIA SAGEA MINERAL',
'ProvinsiKota' => 'SUMATERA SELATAN',
'DeskripsiKegiatan' => 'Kegiatan penggalian kuarsa dan pasir kuarsa untuk keperluan industri kaca dan konstruksi dengan metode tambang terbuka',
'DampakPotensial' => 'Penurunan Kualitas Udara, Peningkatan Kebisingan, Peningkatan Air Larian, Peningkatan Timbulan Sampah, Terjadinya Gangguan Lalu Lintas',
'DeskripsiLokasi' => 'Desa Marga Sungsang, Kecamatan Banyuasin II, Kabupaten Banyuasin, Sumatra Selatan',
'Latitude' => -2.1234567,
'Longitude' => 104.7654321,
'TanggalMulaiPeriode' => Carbon::now()->subDays(5),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(10),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REG976H3AG89',
'JenisDokumen' => 'AMDAL',
'NamaKegiatan' => 'Pembangunan Waterfront Malalayang, TARCISIUS ASWIN JULIZAR',
'BidangUsaha' => 'Perhubungan Laut',
'SkalaBesaran' => '5000.00 m2',
'LokasiKegiatan' => 'Pantai Malalayang',
'Kewenangan' => 'Daerah',
'Pemrakarsa' => 'PT. BENUA LAUT LEPAS',
'ProvinsiKota' => 'SULAWESI UTARA',
'DeskripsiKegiatan' => 'Pembangunan Terminal Alih Muat Barang (Ship To Ship Transfer) dan Fasilitas Penunjangnya oleh PT. Benua Laut Lepas',
'DampakPotensial' => 'Penurunan kualitas air laut, Peningkatan Sedimentasi, Perubahan Garis Pantai, Peningkatan Kesempatan Kerja dan Berusaha',
'DeskripsiLokasi' => 'Pantai Malalayang, Kecamatan Malalayang, Kota Manado, Sulawesi Utara',
'Latitude' => 1.4897167,
'Longitude' => 124.8421083,
'TanggalMulaiPeriode' => Carbon::now()->subDays(2),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(12),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGAMD001235',
'JenisDokumen' => 'AMDAL',
'NamaKegiatan' => 'Pembangunan PLTU Batubara Cilacap Unit 3 & 4',
'BidangUsaha' => 'Energi dan Sumber Daya Mineral',
'SkalaBesaran' => '2000.00 MW',
'LokasiKegiatan' => 'Pesisir Cilacap',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. PLN (PERSERO)',
'ProvinsiKota' => 'JAWA TENGAH',
'DeskripsiKegiatan' => 'Pembangunan pembangkit listrik tenaga uap dengan bahan bakar batubara kapasitas 2x1000 MW lengkap dengan fasilitas penunjang',
'DampakPotensial' => 'Emisi gas buang, Limbah abu batubara, Peningkatan suhu air laut, Dampak visual, Peningkatan lapangan kerja',
'DeskripsiLokasi' => 'Pesisir Cilacap, Kecamatan Cilacap Selatan, Kabupaten Cilacap, Jawa Tengah',
'Latitude' => -7.7326,
'Longitude' => 109.0158,
'TanggalMulaiPeriode' => Carbon::now()->subDays(10),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(5),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGAMD004578',
'JenisDokumen' => 'AMDAL',
'NamaKegiatan' => 'Pembangunan Jalan Tol Trans Sumatera Segmen Kayu Agung - Palembang',
'BidangUsaha' => 'Perhubungan Darat',
'SkalaBesaran' => '75.50 km',
'LokasiKegiatan' => 'Kabupaten Ogan Komering Ilir - Kota Palembang',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. HUTAMA KARYA (PERSERO)',
'ProvinsiKota' => 'SUMATERA SELATAN',
'DeskripsiKegiatan' => 'Pembangunan jalan tol 4 lajur sebagai bagian dari jaringan jalan tol Trans Sumatera untuk meningkatkan konektivitas antar wilayah',
'DampakPotensial' => 'Pembebasan lahan, Gangguan hidrologi, Kebisingan konstruksi, Peningkatan aksesibilitas, Pembukaan lapangan kerja',
'DeskripsiLokasi' => 'Melintasi Kabupaten Ogan Komering Ilir hingga Kota Palembang, Sumatera Selatan',
'Latitude' => -3.0044,
'Longitude' => 104.6178,
'TanggalMulaiPeriode' => Carbon::now()->subDays(15),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(0),
'Status' => 'berakhir'
],
[
'NoRegistrasi' => 'REGAMD007892',
'JenisDokumen' => 'AMDAL',
'NamaKegiatan' => 'Pengembangan Bandara Internasional Syamsudin Noor Fase II',
'BidangUsaha' => 'Perhubungan Udara',
'SkalaBesaran' => '15000.00 m2',
'LokasiKegiatan' => 'Banjarbaru',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. ANGKASA PURA II (PERSERO)',
'ProvinsiKota' => 'KALIMANTAN SELATAN',
'DeskripsiKegiatan' => 'Perluasan terminal penumpang, penambahan apron pesawat, dan peningkatan fasilitas bandara untuk mendukung peningkatan kapasitas penumpang',
'DampakPotensial' => 'Kebisingan pesawat, Peningkatan lalu lintas, Perubahan tata guna lahan, Peningkatan perekonomian daerah',
'DeskripsiLokasi' => 'Banjarbaru, Kalimantan Selatan',
'Latitude' => -3.4424,
'Longitude' => 114.7625,
'TanggalMulaiPeriode' => Carbon::now()->addDays(3),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(18),
'Status' => 'aktif'
],
// Addendum Documents (5 records)
[
'NoRegistrasi' => 'REG7HA9279E8',
'JenisDokumen' => 'Addendum',
'NamaKegiatan' => 'Addendum AMDAL Pembangunan Waterfront Malalayang',
'BidangUsaha' => 'Perhubungan Laut',
'SkalaBesaran' => '7500.00 m2',
'LokasiKegiatan' => 'Pantai Malalayang',
'Kewenangan' => 'Daerah',
'Pemrakarsa' => 'PT. BENUA LAUT LEPAS',
'ProvinsiKota' => 'SULAWESI UTARA',
'DeskripsiKegiatan' => 'Perubahan dan penambahan fasilitas pendukung pada proyek pembangunan waterfront dengan penambahan area parkir dan fasilitas komersial',
'DampakPotensial' => 'Peningkatan lalu lintas, Perubahan tata guna lahan, Peningkatan aktivitas ekonomi lokal',
'DeskripsiLokasi' => 'Pantai Malalayang, Kecamatan Malalayang, Kota Manado, Sulawesi Utara',
'Latitude' => 1.4897167,
'Longitude' => 124.8421083,
'TanggalMulaiPeriode' => Carbon::now()->subDays(1),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(13),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGADD002456',
'JenisDokumen' => 'Addendum',
'NamaKegiatan' => 'Addendum AMDAL PLTU Batubara Cilacap - Perubahan Teknologi',
'BidangUsaha' => 'Energi dan Sumber Daya Mineral',
'SkalaBesaran' => '2000.00 MW',
'LokasiKegiatan' => 'Pesisir Cilacap',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. PLN (PERSERO)',
'ProvinsiKota' => 'JAWA TENGAH',
'DeskripsiKegiatan' => 'Perubahan teknologi pembakaran batubara dengan teknologi yang lebih ramah lingkungan dan efisien untuk mengurangi emisi',
'DampakPotensial' => 'Pengurangan emisi SO2 dan NOx, Peningkatan efisiensi bahan bakar, Pengurangan abu terbang',
'DeskripsiLokasi' => 'Pesisir Cilacap, Kecamatan Cilacap Selatan, Kabupaten Cilacap, Jawa Tengah',
'Latitude' => -7.7326,
'Longitude' => 109.0158,
'TanggalMulaiPeriode' => Carbon::now()->subDays(8),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(7),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGADD003789',
'JenisDokumen' => 'Addendum',
'NamaKegiatan' => 'Addendum AMDAL Tol Trans Sumatera - Penambahan Rest Area',
'BidangUsaha' => 'Perhubungan Darat',
'SkalaBesaran' => '85.50 km',
'LokasiKegiatan' => 'Kabupaten Ogan Komering Ilir - Kota Palembang',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. HUTAMA KARYA (PERSERO)',
'ProvinsiKota' => 'SUMATERA SELATAN',
'DeskripsiKegiatan' => 'Penambahan 3 rest area di sepanjang ruas tol dengan fasilitas SPBU, food court, dan area istirahat untuk meningkatkan keselamatan perjalanan',
'DampakPotensial' => 'Peningkatan keselamatan jalan, Pembukaan lapangan kerja baru, Peningkatan konsumsi air dan listrik',
'DeskripsiLokasi' => 'Melintasi Kabupaten Ogan Komering Ilir hingga Kota Palembang, Sumatera Selatan',
'Latitude' => -3.0044,
'Longitude' => 104.6178,
'TanggalMulaiPeriode' => Carbon::now()->subDays(3),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(12),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGADD005123',
'JenisDokumen' => 'Addendum',
'NamaKegiatan' => 'Addendum AMDAL Bandara Syamsudin Noor - Perpanjangan Runway',
'BidangUsaha' => 'Perhubungan Udara',
'SkalaBesaran' => '3200.00 m',
'LokasiKegiatan' => 'Banjarbaru',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. ANGKASA PURA II (PERSERO)',
'ProvinsiKota' => 'KALIMANTAN SELATAN',
'DeskripsiKegiatan' => 'Perpanjangan runway dari 2500m menjadi 3200m untuk mengakomodasi pesawat wide body dan meningkatkan kapasitas operasional bandara',
'DampakPotensial' => 'Peningkatan kebisingan pesawat, Pembebasan lahan tambahan, Peningkatan frekuensi penerbangan',
'DeskripsiLokasi' => 'Banjarbaru, Kalimantan Selatan',
'Latitude' => -3.4424,
'Longitude' => 114.7625,
'TanggalMulaiPeriode' => Carbon::now()->addDays(5),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(20),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGADD006789',
'JenisDokumen' => 'Addendum',
'NamaKegiatan' => 'Addendum AMDAL Tambang Kuarsa - Perluasan Area Tambang',
'BidangUsaha' => 'Pertambangan',
'SkalaBesaran' => '75000.00 ton/tahun',
'LokasiKegiatan' => 'Desa Marga Sungsang',
'Kewenangan' => 'Pusat',
'Pemrakarsa' => 'PT. KARUNIA SAGEA MINERAL',
'ProvinsiKota' => 'SUMATERA SELATAN',
'DeskripsiKegiatan' => 'Perluasan area penambangan kuarsa dari 100 ha menjadi 150 ha untuk memenuhi peningkatan demand pasar domestik dan ekspor',
'DampakPotensial' => 'Peningkatan kebisingan, Bertambahnya debu dan partikel, Perluasan dampak visual, Peningkatan produksi',
'DeskripsiLokasi' => 'Desa Marga Sungsang, Kecamatan Banyuasin II, Kabupaten Banyuasin, Sumatra Selatan',
'Latitude' => -2.1234567,
'Longitude' => 104.7654321,
'TanggalMulaiPeriode' => Carbon::now()->addDays(2),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(17),
'Status' => 'aktif'
],
// UKL-UPL Documents (5 records)
[
'NoRegistrasi' => 'REGDF3D52A98',
'JenisDokumen' => 'UKL-UPL',
'NamaKegiatan' => 'Pembangunan Pabrik Pengolahan Kelapa Sawit',
'BidangUsaha' => 'Industri Pangan',
'SkalaBesaran' => '1000.00 ton/hari',
'LokasiKegiatan' => 'Desa Sumber Jaya',
'Kewenangan' => 'Provinsi',
'Pemrakarsa' => 'PT. AGRO MANDIRI SEJAHTERA',
'ProvinsiKota' => 'RIAU',
'DeskripsiKegiatan' => 'Pembangunan dan operasional pabrik pengolahan kelapa sawit menjadi crude palm oil (CPO) dan produk turunannya',
'DampakPotensial' => 'Pencemaran air limbah, Bau dari proses produksi, Peningkatan lalu lintas kendaraan berat',
'DeskripsiLokasi' => 'Desa Sumber Jaya, Kecamatan Kampar, Kabupaten Kampar, Riau',
'Latitude' => 0.2895833,
'Longitude' => 101.3828889,
'TanggalMulaiPeriode' => Carbon::now()->addDays(1),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(15),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGUKL001234',
'JenisDokumen' => 'UKL-UPL',
'NamaKegiatan' => 'Pembangunan Pabrik Tekstil dan Garmen Modern',
'BidangUsaha' => 'Industri Tekstil',
'SkalaBesaran' => '500.00 ton/bulan',
'LokasiKegiatan' => 'Kawasan Industri Karawang',
'Kewenangan' => 'Provinsi',
'Pemrakarsa' => 'PT. TEKSTIL NUSANTARA MAKMUR',
'ProvinsiKota' => 'JAWA BARAT',
'DeskripsiKegiatan' => 'Pembangunan pabrik tekstil terintegrasi dengan fasilitas dyeing, printing, dan finishing untuk produksi kain dan garmen',
'DampakPotensial' => 'Limbah cair pewarna, Konsumsi air tinggi, Kebisingan mesin, Peningkatan lapangan kerja',
'DeskripsiLokasi' => 'Kawasan Industri Karawang, Kabupaten Karawang, Jawa Barat',
'Latitude' => -6.3019,
'Longitude' => 107.3372,
'TanggalMulaiPeriode' => Carbon::now()->subDays(4),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(11),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGUKL002567',
'JenisDokumen' => 'UKL-UPL',
'NamaKegiatan' => 'Pembangunan Cold Storage dan Distribution Center',
'BidangUsaha' => 'Logistik dan Pergudangan',
'SkalaBesaran' => '10000.00 m3',
'LokasiKegiatan' => 'Kawasan Industri Medan',
'Kewenangan' => 'Provinsi',
'Pemrakarsa' => 'PT. LOGISTIK SUMATERA UTARA',
'ProvinsiKota' => 'SUMATERA UTARA',
'DeskripsiKegiatan' => 'Pembangunan fasilitas penyimpanan dingin dan pusat distribusi untuk produk pertanian dan perikanan dengan sistem otomatis',
'DampakPotensial' => 'Konsumsi listrik tinggi, Refrigeran ramah lingkungan, Peningkatan lalu lintas truk, Peningkatan nilai tambah produk',
'DeskripsiLokasi' => 'Kawasan Industri Medan, Kota Medan, Sumatera Utara',
'Latitude' => 3.6951,
'Longitude' => 98.7579,
'TanggalMulaiPeriode' => Carbon::now()->subDays(6),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(9),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGUKL003890',
'JenisDokumen' => 'UKL-UPL',
'NamaKegiatan' => 'Pembangunan Pabrik Pengolahan Limbah Medis',
'BidangUsaha' => 'Jasa Lingkungan',
'SkalaBesaran' => '50.00 ton/hari',
'LokasiKegiatan' => 'Kawasan Industri Makassar',
'Kewenangan' => 'Provinsi',
'Pemrakarsa' => 'PT. ECO MEDICAL WASTE SOLUTION',
'ProvinsiKota' => 'SULAWESI SELATAN',
'DeskripsiKegiatan' => 'Pembangunan fasilitas pengolahan limbah medis B3 dengan teknologi incinerator dan autoclave untuk wilayah Sulawesi Selatan',
'DampakPotensial' => 'Emisi hasil pembakaran, Pengelolaan abu insinerator, Peningkatan keselamatan kesehatan masyarakat',
'DeskripsiLokasi' => 'Kawasan Industri Makassar, Kota Makassar, Sulawesi Selatan',
'Latitude' => -5.1477,
'Longitude' => 119.4327,
'TanggalMulaiPeriode' => Carbon::now()->addDays(4),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(19),
'Status' => 'aktif'
],
[
'NoRegistrasi' => 'REGUKL004567',
'JenisDokumen' => 'UKL-UPL',
'NamaKegiatan' => 'Pembangunan Pabrik Pupuk Organik dari Limbah Ternak',
'BidangUsaha' => 'Industri Pupuk',
'SkalaBesaran' => '200.00 ton/hari',
'LokasiKegiatan' => 'Desa Sidomulyo',
'Kewenangan' => 'Provinsi',
'Pemrakarsa' => 'PT. PUPUK ORGANIK NUSANTARA',
'ProvinsiKota' => 'JAWA TIMUR',
'DeskripsiKegiatan' => 'Pembangunan pabrik pengolahan limbah ternak menjadi pupuk organik granul dengan teknologi composting dan granulasi modern',
'DampakPotensial' => 'Bau selama proses composting, Lalat dan serangga, Peningkatan nilai tambah limbah ternak, Produksi pupuk ramah lingkungan',
'DeskripsiLokasi' => 'Desa Sidomulyo, Kecamatan Tempeh, Kabupaten Lumajang, Jawa Timur',
'Latitude' => -8.1215,
'Longitude' => 113.2234,
'TanggalMulaiPeriode' => Carbon::now()->addDays(6),
'TanggalSelesaiPeriode' => Carbon::now()->addDays(21),
'Status' => 'aktif'
]
];
foreach ($kegiatan as $data) {
InformasiKegiatan::create($data);
}
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
use App\Models\Kabupaten;
use Illuminate\Support\Facades\Log;
class KabupatenTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Ambil data kabupaten dari API
$response = Http::get('https://api-wilayah.dinaslhdki.id/api/kabupaten/dkj/search');
// Loop data kabupaten yang diterima dari API
foreach ($response->json() as $kabupaten) {
// Convert the id format and map the data
$cleanId = str_replace('.', '', $kabupaten['id']);
Kabupaten::create([
'KabupatenId' => $cleanId,
'NamaKabupaten' => $kabupaten['data']
]);
// Log data kabupaten yang sedang di-seed
Log::info('Seeding kabupaten: ', [
'KabupatenId' => $cleanId,
'NamaKabupaten' => $kabupaten['data']
]);
}
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Database\Seeders;
use App\Models\Kecamatan;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Models\Kabupaten;
class KecamatanTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$kabupatens = Kabupaten::all();
foreach ($kabupatens as $kabupaten) {
$kabId = substr($kabupaten->KabupatenId, 0, 2) . '.' .
substr($kabupaten->KabupatenId, 2, 2);
$response = Http::get("https://api-wilayah.dinaslhdki.id/api/kecamatan/search?kab={$kabId}");
foreach ($response->json() as $kecamatan) {
$cleanId = str_replace('.', '', $kecamatan['id']);
Kecamatan::create([
'KecamatanId' => $cleanId,
'KabupatenId' => $kabupaten->KabupatenId,
'NamaKecamatan' => $kecamatan['data']
]);
// Log the seeding process
Log::info('Seeding kecamatan: ', [
'KecamatanId' => $cleanId,
'KabupatenId' => $kabupaten->KabupatenId,
'NamaKecamatan' => $kecamatan['data']
]);
}
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Database\Seeders;
use App\Models\Kecamatan;
use App\Models\Kelurahan;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class KelurahanTableSeeder extends Seeder
{
public function run(): void
{
$kecamatans = Kecamatan::all();
foreach ($kecamatans as $kecamatan) {
$kecId = substr($kecamatan->KecamatanId, 0, 2) . '.' .
substr($kecamatan->KecamatanId, 2, 2) . '.' .
substr($kecamatan->KecamatanId, 4, 2);
$response = Http::get("https://api-wilayah.dinaslhdki.id/api/kelurahan/search?kec={$kecId}");
foreach ($response->json() as $kelurahan) {
$cleanId = str_replace('.', '', $kelurahan['id']);
$cleanName = str_replace("\n", ' ', $kelurahan['data']);
Kelurahan::create([
'KelurahanId' => $cleanId,
'KecamatanId' => $kecamatan->KecamatanId,
'NamaKelurahan' => $cleanName
]);
Log::info('Seeding kelurahan: ', [
'KelurahanId' => $cleanId,
'KecamatanId' => $kecamatan->KecamatanId,
'NamaKelurahan' => $cleanName
]);
}
}
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Perusahaan;
class PerusahaanSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$data = [
[
'NamaPerusahaan' => 'PT. Permata Hijau',
'Alamat' => 'Jl. Merdeka No. 1, Jakarta Pusat',
],
[
'NamaPerusahaan' => 'PT. BERKAH SELAMANYA ENERGI (R4)',
'Alamat' => 'Jl. Sudirman No. 88, Jakarta Selatan',
],
[
'NamaPerusahaan' => 'PT. FORTUNA MUDA LAGA (FORMULA BAN)',
'Alamat' => 'Jl. Gatot Subroto No. 12, Jakarta Barat',
],
[
'NamaPerusahaan' => 'PT. MANDIRI KREASI KOLABORASI',
'Alamat' => 'Jl. Ahmad Yani No. 45, Jakarta Timur',
],
[
'NamaPerusahaan' => 'PT. UNILAB PERDANA',
'Alamat' => 'Kawasan Industri Cikarang, Bekasi',
],
];
foreach ($data as $row) {
Perusahaan::updateOrCreate(
['NamaPerusahaan' => $row['NamaPerusahaan']],
['Alamat' => $row['Alamat']]
);
}
}
}

View File

@ -21,6 +21,7 @@ class RolesAndPermissionsSeeder extends Seeder
'dashboard.view.uji_emisi',
// Menus
'pengumuman.access',
'penjadwalan.access',
'persetujuan_teknis.access',
'rincian_teknis.access',
@ -42,6 +43,24 @@ class RolesAndPermissionsSeeder extends Seeder
$kadis = Role::firstOrCreate(['name' => 'Kadis']);
$ppkl = Role::firstOrCreate(['name' => 'PPKL']);
$dlh = Role::firstOrCreate(['name' => 'DLH']);
$perusahaan = Role::firstOrCreate(['name' => 'Perusahaan']);
// Kadis permissions (semua dashboard tabs + modules, tanpa pengaturan/konten/master data)
$perusahaanPerms = [
'dashboard.view.pertek',
'dashboard.view.rintek',
'dashboard.view.amdal',
'dashboard.view.izin_angkut',
'dashboard.view.uji_emisi',
'pengumuman.access',
'penjadwalan.access',
'persetujuan_teknis.access',
'rincian_teknis.access',
'persetujuan_lingkungan.access',
'izin_angkut_olah.access',
'izin_tempat_uji_emisi.access',
];
$perusahaan->syncPermissions($perusahaanPerms);
// Kadis permissions (semua dashboard tabs + modules, tanpa pengaturan/konten/master data)
$kadisPerms = [

View File

@ -0,0 +1,121 @@
<?php
namespace Database\Seeders;
use App\Models\SaranTanggapan;
use App\Models\InformasiKegiatan;
use Illuminate\Database\Seeder;
class SaranTanggapanSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Get some InformasiKegiatan IDs
$kegiatanIds = InformasiKegiatan::pluck('KegiatanID')->take(3);
$sampleTanggapan = [
[
'KegiatanID' => $kegiatanIds[0],
'Nama' => 'Budi Santoso',
'Peran' => 'masyarakat',
'NIK' => '3171234567890123',
'Email' => 'budi.santoso@email.com',
'NoTelepon' => '081234567890',
'Gender' => 'laki-laki',
'KondisiLingkungan' => 'Lingkungan sekitar masih cukup bersih dengan kualitas udara yang baik. Terdapat sungai kecil di dekat area.',
'NilaiLokal' => 'Area ini adalah tempat bermain anak-anak dan berkumpul warga setiap sore. Memiliki nilai sosial yang tinggi bagi masyarakat.',
'Kekhawatiran' => 'Khawatir akan dampak terhadap lalu lintas di sekitar area dan kemungkinan polusi suara yang mengganggu.',
'Harapan' => 'Berharap kegiatan ini dapat memberikan manfaat ekonomi bagi masyarakat sekitar dan tidak merusak lingkungan.',
'TingkatKekhawatiran' => 3,
'Status' => 'approved',
'TanggalDiajukan' => now()->subDays(2),
'TanggalDiproses' => now()->subDays(1),
'created_at' => now()->subDays(2),
'updated_at' => now()->subDays(1),
],
[
'KegiatanID' => $kegiatanIds[0],
'Nama' => 'Siti Rahayu',
'Peran' => 'masyarakat',
'NIK' => '3171234567890124',
'Email' => 'siti.rahayu@email.com',
'NoTelepon' => '081234567891',
'Gender' => 'perempuan',
'KondisiLingkungan' => 'Kualitas air sungai di sekitar masih bagus dan digunakan warga untuk kebutuhan sehari-hari.',
'NilaiLokal' => 'Sungai ini merupakan sumber air bersih bagi warga sekitar dan tempat mencuci pakaian.',
'Kekhawatiran' => 'Sangat khawatir limbah dari kegiatan ini akan mencemari sungai yang menjadi sumber air bagi warga.',
'Harapan' => 'Berharap ada sistem pengolahan limbah yang baik sehingga tidak mencemari lingkungan.',
'TingkatKekhawatiran' => 2,
'Status' => 'approved',
'TanggalDiajukan' => now()->subDays(1),
'TanggalDiproses' => now()->subHours(12),
'created_at' => now()->subDays(1),
'updated_at' => now()->subHours(12),
],
[
'KegiatanID' => $kegiatanIds[1],
'Nama' => 'Ahmad Wijaya',
'Peran' => 'lsm',
'NIK' => '3171234567890125',
'Email' => 'ahmad.wijaya@email.com',
'NoTelepon' => '081234567892',
'Gender' => 'laki-laki',
'KondisiLingkungan' => 'Area ini masih alami dengan banyak pohon dan burung. Merupakan habitat beberapa spesies lokal.',
'NilaiLokal' => 'Tempat ini memiliki nilai konservasi tinggi sebagai habitat satwa lokal dan paru-paru kota.',
'Kekhawatiran' => 'Khawatir akan hilangnya habitat satwa dan berkurangnya ruang terbuka hijau.',
'Harapan' => 'Berharap ada kompensasi berupa penanaman pohon di lokasi lain dan program konservasi.',
'TingkatKekhawatiran' => 2,
'Status' => 'approved',
'TanggalDiajukan' => now()->subHours(12),
'TanggalDiproses' => now()->subHours(6),
'created_at' => now()->subHours(12),
'updated_at' => now()->subHours(6),
],
[
'KegiatanID' => $kegiatanIds[1],
'Nama' => 'Dr. Maria Kusuma',
'Peran' => 'akademisi',
'NIK' => '3171234567890126',
'Email' => 'maria.kusuma@email.com',
'NoTelepon' => '081234567893',
'Gender' => 'perempuan',
'KondisiLingkungan' => 'Dari segi geologis, area ini stabil. Namun perlu perhatian khusus pada drainase.',
'NilaiLokal' => 'Secara akademis, area ini menarik untuk penelitian tentang urban development.',
'Kekhawatiran' => 'Khawatir tentang dampak jangka panjang terhadap sistem drainase dan kemungkinan banjir.',
'Harapan' => 'Berharap ada studi dampak lingkungan yang komprehensif dan sistem mitigasi yang tepat.',
'TingkatKekhawatiran' => 3,
'Status' => 'approved',
'TanggalDiajukan' => now()->subHours(6),
'TanggalDiproses' => now()->subHours(3),
'created_at' => now()->subHours(6),
'updated_at' => now()->subHours(3),
],
[
'KegiatanID' => $kegiatanIds[2],
'Nama' => 'Rudi Hartono',
'Peran' => 'masyarakat',
'NIK' => '3171234567890127',
'Email' => 'rudi.hartono@email.com',
'NoTelepon' => '081234567894',
'Gender' => 'laki-laki',
'KondisiLingkungan' => 'Lingkungan cukup padat penduduk dengan aktivitas ekonomi yang tinggi.',
'NilaiLokal' => 'Area ini adalah pusat ekonomi lokal dengan banyak warung dan toko kecil.',
'Kekhawatiran' => 'Khawatir akan gangguan terhadap aktivitas ekonomi masyarakat selama pembangunan.',
'Harapan' => 'Berharap ada kompensasi ekonomi dan lapangan kerja bagi masyarakat yang terdampak.',
'TingkatKekhawatiran' => 4,
'Status' => 'approved',
'TanggalDiajukan' => now()->subHours(3),
'TanggalDiproses' => now()->subHours(1),
'created_at' => now()->subHours(3),
'updated_at' => now()->subHours(1),
],
];
foreach ($sampleTanggapan as $tanggapan) {
SaranTanggapan::create($tanggapan);
}
}
}

View File

@ -33,6 +33,17 @@ class UserSeeder extends Seeder
);
$kadis->syncRoles(['Kadis']);
// Perusahaan user
$perusahaan = User::updateOrCreate(
['email' => 'perusahaan@dinaslhdki.id'],
[
'name' => 'Perusahaan',
'username' => 'perusahaan',
'password' => Hash::make('Perling2025$'),
]
);
$perusahaan->syncRoles(['Perusahaan']);
// PPKL user (note: domain as provided)
$ppkl = User::updateOrCreate(
['email' => 'ppkl@dinaslhkdki.id'],

View File

@ -0,0 +1,53 @@
# Registration Number Format
## Secure Registration Number Generation
The system automatically generates a unique 12-character registration number for each announcement with enhanced security to prevent easy guessing.
### Format Structure:
```
ENV + XXXXXXXXX
```
Where:
- **ENV** = Environmental document prefix (3 characters)
- **XXXXXXXXX** = 9 secure random alphanumeric characters (excluding similar-looking characters)
### Character Pool:
- Uses: `23456789ABCDEFGHJKLMNPQRSTUVWXYZ`
- Excludes: `0, 1, I, O` (to prevent confusion)
- No lowercase letters (for consistency)
### Examples:
- **ENV4B7X9K2MQ** - Secure random generation
- **ENVH3K8P5W7R** - Another secure random generation
- **ENV9F2N6Y4MP** - Each number is unpredictable
### Security Features:
1. **Cryptographic Hash** - Uses SHA-256 for randomness
2. **Timestamp Seed** - Includes microtime for uniqueness
3. **Unpredictable** - No date/time patterns visible
4. **No Sequential** - Cannot guess next number
5. **Character Filtering** - Excludes confusing characters
### Technical Implementation:
- Generated using cryptographic hash functions
- Seeds include timestamp + microtime + random integers
- Character pool designed to avoid visual confusion
- Multiple entropy sources for maximum security
- Still maintains 12-character length requirement
### Usage:
1. Number is automatically generated when form is submitted
2. Field is completely hidden from users (no manual interaction)
3. System validates uniqueness before saving to database
4. Success message shows the final registration number
5. Each generation is completely unpredictable and secure
6. No user interface for regeneration (fully automated)

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -1,9 +1,17 @@
function getDatePicker(receiveID) {
flatpickr(receiveID, {
function getDatePicker(selector) {
try {
flatpickr(selector, {
enableTime: true,
dateFormat: "d/m/Y H:i",
time_24hr: true,
minDate: "today",
disable: Array.isArray(window.disabledJadwalRanges) ? window.disabledJadwalRanges : [],
});
} catch (e) {
// no-op
}
}
getDatePicker("#startDate");
getDatePicker("#endDate");

View File

@ -1,8 +1,10 @@
// Fetch Wilayah JSON
fetch("/assets/json/home/wilayah.json")
// Fetch Wilayah dari API Database
fetch("/api/layanan/wilayah")
.then((response) => response.json())
.then((data) => populateFilters(data))
.catch((error) => console.error("Gagal load wilayah.json:", error));
.catch((error) =>
console.error("Gagal load wilayah dari database:", error)
);
function populateFilters(data) {
populateSelect("kabkota", data.kabkota);
@ -14,7 +16,19 @@ function populateSelect(id, options) {
const select = document.getElementById(id);
if (!select) return;
select.innerHTML = options
// Add default option
let defaultOption =
'<option value="">Semua ' +
(id === "kabkota"
? "Kabupaten"
: id === "kecamatan"
? "Kecamatan"
: "Kelurahan") +
"</option>";
select.innerHTML =
defaultOption +
options
.map(
(opt) => `
<option value="${opt.value}">${opt.label}</option>
@ -23,22 +37,24 @@ function populateSelect(id, options) {
.join("");
}
// Fetch Layanan JSON
// Fetch Layanan dari API Database
document.addEventListener("DOMContentLoaded", function () {
fetch("/assets/json/home/layanan.json")
fetch("/api/layanan/data")
.then((response) => response.json())
.then((data) => {
initializeLayanan(data);
setupUIHandlers();
})
.catch((error) => console.error("Gagal load layanan.json:", error));
.catch((error) =>
console.error("Gagal load layanan dari database:", error)
);
});
function initializeLayanan(data) {
renderHeader(data.header);
renderTabs(data.tabs);
renderContents(data.contents);
changeTab("pertek");
changeTab("amdal");
}
// Data Header
@ -62,7 +78,7 @@ function renderTabs(tabs) {
(tab) => `
<button id="tab-${tab.id}"
class="tab-btn bg-white border border-gray-300 px-3 sm:px-6 py-2 rounded text-sm sm:text-base"
onclick="changeTab('${tab.id}')">
onclick="handleTabClick('${tab.id}')">
${tab.label}
</button>
`
@ -86,7 +102,9 @@ function renderContents(contents) {
} else {
return `
<div id="content-${key}" class="tab-content hidden bg-blue-900 rounded overflow-hidden">
${items.map((item) => renderStandardItem(item)).join("")}
${items
.map((item, index) => renderStandardItem(item, index))
.join("")}
</div>
`;
}
@ -94,7 +112,7 @@ function renderContents(contents) {
.join("");
}
function renderStandardItem(item) {
function renderStandardItem(item, index) {
return `
<div class="border-b border-blue-800 p-4 sm:p-6 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
<div class="flex gap-3 sm:gap-4 w-full">
@ -106,14 +124,25 @@ function renderStandardItem(item) {
</div>
</div>
<div>
<h2 class="text-white font-bold text-sm sm:text-base">${item.title}</h2>
<p class="text-blue-200 mt-1 sm:mt-2 text-xs sm:text-sm">${item.description}</p>
<a href="${item.link}" class="text-green-300 mt-1 block text-xs sm:text-sm">Baca selengkapnya ...</a>
<div class="text-blue-200 text-xs mt-1">
<span class="bg-blue-700 px-2 py-1 rounded text-xs">${item.no_registrasi}</span>
<span class="ml-2">${item.pemrakarsa}</span>
</div>
<h2 class="text-white font-bold text-sm sm:text-base mt-1 sm:mt-2 ">${item.title}</h2>
<p class="text-blue-200 text-xs sm:text-sm">${item.description}</p>
</div>
</div>
<div class="flex flex-row sm:flex-col items-center sm:items-end justify-between sm:justify-end gap-2 w-full sm:w-auto mt-2 sm:mt-0">
<div class="text-white text-xs sm:text-sm text-right">${item.periode}</div>
<button class="bg-green-500 text-white px-3 sm:px-6 py-1.5 sm:py-2 rounded text-xs sm:text-sm whitespace-nowrap">Berikan Tanggapan</button>
<button class="berikan-tanggapan-btn bg-green-500 text-white px-3 sm:px-6 py-1.5 sm:py-2 rounded text-xs sm:text-sm whitespace-nowrap"
data-item-id="${item.id}"
data-item-index="${index}"
data-item-title="${item.title}"
data-item-description="${item.description}"
data-item-periode="${item.periode}">
Berikan Tanggapan
</button>
</div>
</div>
`;
@ -178,8 +207,387 @@ function setupUIHandlers() {
'input[placeholder="Search"]'
);
if (searchInput) searchInput.value = "";
// Reload original data
loadOriginalData();
});
}
// Apply filter
const applyFilterButton = document.querySelector(".bg-blue-600");
if (applyFilterButton) {
applyFilterButton.addEventListener("click", function () {
applyFilters();
});
}
// Search input
const searchInput = document.querySelector('input[placeholder="Search"]');
if (searchInput) {
let searchTimeout;
searchInput.addEventListener("input", function () {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
applyFilters();
}, 500); // Debounce 500ms
});
}
// Handle "Berikan Tanggapan" button clicks
document.addEventListener("click", function (e) {
if (e.target && e.target.classList.contains("berikan-tanggapan-btn")) {
const itemId = e.target.getAttribute("data-item-id");
const itemTitle = e.target.getAttribute("data-item-title");
const itemDescription = e.target.getAttribute(
"data-item-description"
);
const itemPeriode = e.target.getAttribute("data-item-periode");
if (itemId) {
// Fetch detail from API
fetch(`/api/layanan/detail/${itemId}`)
.then((response) => response.json())
.then((data) => {
showFeedbackForm(data);
})
.catch((error) => {
console.error("Error fetching detail:", error);
// Fallback to basic data
showFeedbackForm({
nama_kegiatan: itemTitle,
deskripsi_kegiatan: itemDescription,
periode: itemPeriode,
});
});
} else {
// Fallback for old data structure
showFeedbackForm({
nama_kegiatan: itemTitle,
deskripsi_kegiatan: itemDescription,
periode: itemPeriode,
});
}
}
});
}
// Function to show the feedback form
function showFeedbackForm(detailData) {
const contentsContainer = document.querySelector("#layanan-contents");
if (!contentsContainer) return;
// Keep tabs visible, just reset their state
const tabButtons = document.querySelectorAll(".tab-btn");
tabButtons.forEach((button) => {
button.classList.remove("bg-blue-900", "text-white");
button.classList.add("bg-white", "border", "border-gray-300");
});
// Render the feedback form
contentsContainer.innerHTML = `
<div class="bg-white rounded overflow-hidden shadow">
${renderInformasiRencanaKegiatan(detailData)}
${renderSaranPendapatForm()}
</div>
`;
}
// Function to render "Informasi Rencana Kegiatan" section
function renderInformasiRencanaKegiatan(data) {
return `
<div class="border border-green-600 rounded-lg mb-6">
<div class="bg-green-50 p-4 border-b border-green-200">
<h2 class="text-lg font-semibold text-green-800">Informasi Rencana Kegiatan</h2>
</div>
<div class="p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">No. Registrasi</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.no_registrasi || "-"
}</div>
</div>
<div class="md:col-span-2">
<label class="block text-sm font-medium text-gray-700 mb-2">Jenis Dokumen</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.jenis_dokumen || "-"
}</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Nama Kegiatan</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium leading-relaxed">
${data.nama_kegiatan || "-"}
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Bidang Usaha/Kegiatan</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.bidang_usaha || "-"
}</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Skala/Besaran</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.skala_besaran || "-"
}</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Lokasi Kegiatan</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.lokasi_kegiatan || "-"
}</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Kewenangan</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.kewenangan || "-"
}</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Pemrakarsa</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.pemrakarsa || "-"
}</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Provinsi/Kota</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">${
data.provinsi_kota || "-"
}</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Deskripsi Kegiatan</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium leading-relaxed">
${data.deskripsi_kegiatan || "-"}
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Dampak Potensial</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium leading-relaxed">
${data.dampak_potensial || "-"}
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Lokasi</label>
<div class="bg-blue-500 rounded-lg h-64 flex items-center justify-center text-white">
<div class="text-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto mb-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<p class="text-sm">Peta Lokasi Kegiatan</p>
${
data.latitude && data.longitude
? `<p class="text-xs mt-1">${data.latitude}, ${data.longitude}</p>`
: ""
}
</div>
</div>
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Deskripsi Lokasi</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium leading-relaxed">
${data.deskripsi_lokasi || "-"}
</div>
</div>
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Periode</label>
<div class="bg-green-100 text-green-800 px-3 py-2 rounded text-sm font-medium">
${data.periode || "-"}
</div>
</div>
<div class="mt-6">
<button onclick="goBackToList()" class="bg-red-500 hover:bg-red-600 text-white px-6 py-2 rounded-md text-sm font-medium transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
Kembali
</button>
</div>
</div>
</div>
</div>
</div>
`;
}
// Function to render "Saran, Pendapat dan Tanggapan Kegiatan" form
function renderSaranPendapatForm() {
return `
<div class="border border-green-600 rounded-lg">
<div class="bg-green-50 p-4 border-b border-green-200">
<h2 class="text-lg font-semibold text-green-800 text-center">Saran, Pendapat, dan Tanggapan untuk Kegiatan</h2>
</div>
<div class="p-6">
<form class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="nama" class="block text-sm font-medium text-gray-700 mb-1">Nama</label>
<input type="text" id="nama" name="nama" placeholder="Nama"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500">
</div>
<div>
<label for="peran" class="block text-sm font-medium text-gray-700 mb-1">Peran</label>
<select id="peran" name="peran"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500">
<option value="">Pilih Peran</option>
<option value="masyarakat">Masyarakat</option>
<option value="lsm">LSM</option>
<option value="akademisi">Akademisi</option>
<option value="pemerintah">Pemerintah</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="nik" class="block text-sm font-medium text-gray-700 mb-1">NIK</label>
<input type="text" id="nik" name="nik" placeholder="NIK"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500">
</div>
<div>
<label for="telepon" class="block text-sm font-medium text-gray-700 mb-1">No. Telepon/Handphone</label>
<div class="flex">
<select class="px-3 py-2 border border-gray-300 border-r-0 rounded-l-md bg-gray-50">
<option value="+62">+62</option>
</select>
<input type="text" id="telepon" name="telepon" placeholder="No. Telepon/Handphone"
class="flex-1 px-3 py-2 border border-gray-300 rounded-r-md focus:outline-none focus:ring-green-500 focus:border-green-500">
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input type="email" id="email" name="email" placeholder="Email"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500">
</div>
<div>
<label for="gender" class="block text-sm font-medium text-gray-700 mb-1">Gender</label>
<select id="gender" name="gender"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500">
<option value="">Pilih Gender</option>
<option value="laki-laki">Laki-laki</option>
<option value="perempuan">Perempuan</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="md:col-span-2">
<div class="space-y-4">
<div>
<label for="kondisi_lingkungan" class="block text-sm font-medium text-gray-700 mb-1">
Kondisi Lingkungan di Dalam dan Sekitar Lokasi Tapak Proyek
</label>
<span class="text-xs text-red-500">Data wajib diisi</span>
<textarea id="kondisi_lingkungan" name="kondisi_lingkungan" rows="3"
placeholder="Kondisi Lingkungan di Dalam dan Sekitar Lokasi Tapak Proyek"
class="w-full px-3 py-2 border border-red-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500"></textarea>
</div>
<div>
<label for="nilai_lokal" class="block text-sm font-medium text-gray-700 mb-1">
Nilai Lokal yang Berpotensi akan Terkena Dampak
</label>
<span class="text-xs text-red-500">Data wajib diisi</span>
<textarea id="nilai_lokal" name="nilai_lokal" rows="3"
placeholder="Nilai Lokal yang Berpotensi akan Terkena Dampak"
class="w-full px-3 py-2 border border-red-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500"></textarea>
</div>
<div>
<label for="kekhawatiran" class="block text-sm font-medium text-gray-700 mb-1">Kekhawatiran</label>
<span class="text-xs text-red-500">Data wajib diisi</span>
<textarea id="kekhawatiran" name="kekhawatiran" rows="3"
placeholder="Kekhawatiran"
class="w-full px-3 py-2 border border-red-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500"></textarea>
</div>
<div>
<label for="harapan" class="block text-sm font-medium text-gray-700 mb-1">Harapan</label>
<span class="text-xs text-red-500">Data wajib diisi</span>
<textarea id="harapan" name="harapan" rows="3"
placeholder="Harapan"
class="w-full px-3 py-2 border border-red-300 rounded-md focus:outline-none focus:ring-green-500 focus:border-green-500"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">
Tingkat Kekhawatiran atau Harapan terhadap Kegiatan Ini
</label>
<div class="flex items-center justify-between">
<span class="text-sm text-gray-600">Khawatir</span>
<div class="flex space-x-1">
<button type="button" class="rating-star text-gray-300 hover:text-yellow-400 text-2xl" data-rating="1"></button>
<button type="button" class="rating-star text-gray-300 hover:text-yellow-400 text-2xl" data-rating="2"></button>
<button type="button" class="rating-star text-gray-300 hover:text-yellow-400 text-2xl" data-rating="3"></button>
<button type="button" class="rating-star text-gray-300 hover:text-yellow-400 text-2xl" data-rating="4"></button>
<button type="button" class="rating-star text-gray-300 hover:text-yellow-400 text-2xl" data-rating="5"></button>
</div>
<span class="text-sm text-gray-600">Harapan</span>
</div>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Unggah Foto Selfie
</label>
<span class="text-xs text-gray-500">(Ukuran Maks 1 MB)</span>
<div class="mt-2 flex flex-col items-center">
<div class="bg-gray-200 rounded-full w-24 h-24 flex items-center justify-center mb-3">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
</div>
<input type="file" id="foto_selfie" name="foto_selfie" accept="image/*"
class="text-xs text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-xs file:font-semibold file:bg-green-50 file:text-green-700 hover:file:bg-green-100">
</div>
</div>
</div>
<div class="flex justify-end space-x-4 pt-6">
<button type="button" onclick="goBackToList()"
class="bg-red-500 text-white px-6 py-2 rounded hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500">
Batal
</button>
<button type="submit"
class="bg-green-500 text-white px-6 py-2 rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500">
Kirim
</button>
</div>
</form>
</div>
</div>
`;
}
// Function to go back to the main list
function goBackToList() {
// Re-render the original content from database
fetch("/api/layanan/data")
.then((response) => response.json())
.then((data) => {
renderContents(data.contents);
changeTab("amdal"); // Default to AMDAL tab
})
.catch((error) =>
console.error("Gagal load layanan dari database:", error)
);
}
// Tab switching function
@ -206,3 +614,100 @@ function changeTab(tabName) {
selectedContent.classList.remove("hidden");
}
}
// Handle tab click - check if we need to return to table view first
function handleTabClick(tabName) {
// Check if we're currently in feedback form view
const contentsContainer = document.querySelector("#layanan-contents");
const isFeedbackForm =
contentsContainer && !contentsContainer.querySelector(".tab-content");
if (isFeedbackForm) {
// Return to table view first, then switch to the clicked tab
fetch("/api/layanan/data")
.then((response) => response.json())
.then((data) => {
renderContents(data.contents);
changeTab(tabName);
})
.catch((error) =>
console.error("Gagal load layanan dari database:", error)
);
} else {
// Normal tab switching
changeTab(tabName);
}
}
// Star rating functionality
document.addEventListener("click", function (e) {
if (e.target && e.target.classList.contains("rating-star")) {
const rating = parseInt(e.target.getAttribute("data-rating"));
const stars = document.querySelectorAll(".rating-star");
stars.forEach((star, index) => {
if (index < rating) {
star.classList.remove("text-gray-300");
star.classList.add("text-yellow-400");
} else {
star.classList.remove("text-yellow-400");
star.classList.add("text-gray-300");
}
});
}
});
// Map tab ID to document type
function mapTabToDocumentType(tabId) {
const mapping = {
amdal: "AMDAL",
"ukl-upl": "UKL-UPL",
addendum: "Addendum",
audit: "AUDIT",
};
return mapping[tabId] || "AMDAL";
}
// Apply filters function
function applyFilters() {
const searchValue =
document.querySelector('input[placeholder="Search"]')?.value || "";
const kabkotaValue = document.getElementById("kabkota")?.value || "";
const kecamatanValue = document.getElementById("kecamatan")?.value || "";
const kelurahanValue = document.getElementById("kelurahan")?.value || "";
// Get current active tab
const activeTab = document.querySelector(".tab-btn.bg-blue-900");
const activeTabId = activeTab ? activeTab.id.replace("tab-", "") : "amdal";
const params = new URLSearchParams({
search: searchValue,
kabkota: kabkotaValue,
kecamatan: kecamatanValue,
kelurahan: kelurahanValue,
jenis_dokumen: mapTabToDocumentType(activeTabId),
});
fetch(`/api/layanan/filter?${params}`)
.then((response) => response.json())
.then((data) => {
renderContents(data);
changeTab(activeTabId);
})
.catch((error) => {
console.error("Error applying filters:", error);
});
}
// Load original data function
function loadOriginalData() {
fetch("/api/layanan/data")
.then((response) => response.json())
.then((data) => {
renderContents(data.contents);
changeTab("amdal");
})
.catch((error) =>
console.error("Gagal load layanan dari database:", error)
);
}

View File

@ -4,42 +4,12 @@
"subtitle": "Daftar Pengumuman dan Informasi terkait kegiatan yang mengajukan izin lingkungan"
},
"tabs": [
{ "id": "pertek", "label": "PERTEK" },
{ "id": "rintek", "label": "RINTEK" },
{ "id": "amdal", "label": "AMDAL" },
{ "id": "addendum", "label": "Addendum" },
{ "id": "ukl-upl", "label": "UKL - UPL" },
{ "id": "audit", "label": "AUDIT" }
],
"contents": {
"pertek": [
{
"title": "Kegiatan Penggalian Kuarsa/Pasir Kuarsa, LUKITO HARTONO LAWY",
"description": "Dampak Potensials: Penurunan Kualitas Udara, Peningkatan Kebisingan, Peningkatan Air Larian, Peningkatan Timbulan Sampah, Terjadinya Gangguan Lalu Lintas, Terbukanya Kes",
"link": "#",
"periode": "27 Maret - 10 April 2025"
},
{
"title": "Pembangunan Waterfront Malalayang, TARCISIUS ASWIN JULIZAR, W",
"description": "Dampak Potensials: Pra Konstruksi 1. Persepsi Masyarakat Tahap Konstruksi 1. Peningkatan Kesempatan Kerja dan Berusaha 2. Peningkatan Sedimentasi 3. Perubahan Garis",
"link": "#",
"periode": "26 Maret - 9 April 2025"
}
],
"rintek": [
{
"title": "Test Penggalian Kuarsa/Pasir Kuarsa, LUKITO HARTONO LAWY",
"description": "Dampak Potensials: Penurunan Kualitas Udara, Peningkatan Kebisingan, Peningkatan Air Larian, Peningkatan Timbulan Sampah, Terjadinya Gangguan Lalu Lintas, Terbukanya Kes",
"link": "#",
"periode": "27 Maret - 10 April 2025"
},
{
"title": "Pembangunan Waterfront Malalayang, TARCISIUS ASWIN JULIZAR, W",
"description": "Dampak Potensials: Pra Konstruksi 1. Persepsi Masyarakat Tahap Konstruksi 1. Peningkatan Kesempatan Kerja dan Berusaha 2. Peningkatan Sedimentasi 3. Perubahan Garis",
"link": "#",
"periode": "26 Maret - 9 April 2025"
}
],
"amdal": [
{
"title": "Kegiatan Penggalian Kuarsa/Pasir Kuarsa, LUKITO HARTONO LAWY",

View File

@ -1,492 +0,0 @@
@extends('layout.layout')
@php
$title='Users Grid';
$subTitle = 'Users Grid';
$script ='<script>
$(".remove-item-btn").on("click", function() {
$(this).closest("tr").addClass("d-none")
});
</script>';
@endphp
@section('content')
<div class="card h-100 p-0 radius-12">
<div class="card-header border-bottom bg-base py-16 px-24 d-flex align-items-center flex-wrap gap-3 justify-content-between">
<div class="d-flex align-items-center flex-wrap gap-3">
<span class="text-md fw-medium text-secondary-light mb-0">Show</span>
<select class="form-select form-select-sm w-auto ps-12 py-6 radius-12 h-40-px">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<form class="navbar-search">
<input type="text" class="bg-base h-40-px w-auto" name="search" placeholder="Search">
<iconify-icon icon="ion:search-outline" class="icon"></iconify-icon>
</form>
<select class="form-select form-select-sm w-auto ps-12 py-6 radius-12 h-40-px">
<option>Status</option>
<option>Active</option>
<option>Inactive</option>
</select>
</div>
<a href="#" class="btn btn-primary text-sm btn-sm px-12 py-12 radius-8 d-flex align-items-center gap-2">
<iconify-icon icon="ic:baseline-plus" class="icon text-xl line-height-1"></iconify-icon>
Add New User
</a>
</div>
<div class="card-body p-24">
<div class="table-responsive scroll-sm">
<table class="table bordered-table sm-table mb-0">
<thead>
<tr>
<th scope="col">
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border input-form-dark" type="checkbox" name="checkbox" id="selectAll">
</div>
S.L
</div>
</th>
<th scope="col">Join Date</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Department</th>
<th scope="col">Designation</th>
<th scope="col" class="text-center">Status</th>
<th scope="col" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
01
</div>
</td>
<td>25 Jan 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list1.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Kathryn Murphy</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">osgoodwy@gmail.com</span></td>
<td>HR</td>
<td>Manager</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
02
</div>
</td>
<td>25 Jan 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list2.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Annette Black</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">redaniel@gmail.com</span></td>
<td>Design</td>
<td>UI UX Designer</td>
<td class="text-center">
<span class="bg-neutral-200 text-neutral-600 border border-neutral-400 px-24 py-4 radius-4 fw-medium text-sm">Inactive</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
03
</div>
</td>
<td>10 Feb 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list3.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Ronald Richards</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">seannand@mail.ru</span></td>
<td>Design</td>
<td>UI UX Designer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
04
</div>
</td>
<td>10 Feb 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list4.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Eleanor Pena</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">miyokoto@mail.ru</span></td>
<td>Design</td>
<td>UI UX Designer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
05
</div>
</td>
<td>15 March 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list5.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Leslie Alexander</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">icadahli@gmail.com</span></td>
<td>Design</td>
<td>UI UX Designer</td>
<td class="text-center">
<span class="bg-neutral-200 text-neutral-600 border border-neutral-400 px-24 py-4 radius-4 fw-medium text-sm">Inactive</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
06
</div>
</td>
<td>15 March 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list6.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Albert Flores</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">warn@mail.ru</span></td>
<td>Design</td>
<td>UI UX Designer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
07
</div>
</td>
<td>27 April 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list7.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Jacob Jones</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">zitka@mail.ru</span></td>
<td>Development</td>
<td>Frontend developer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
08
</div>
</td>
<td>25 Jan 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list8.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Jerome Bell</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">igerrin@gmail.com</span></td>
<td>Development</td>
<td>Frontend developer</td>
<td class="text-center">
<span class="bg-neutral-200 text-neutral-600 border border-neutral-400 px-24 py-4 radius-4 fw-medium text-sm">Inactive</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
09
</div>
</td>
<td>30 April 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list2.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Marvin McKinney</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">maka@yandex.ru</span></td>
<td>Development</td>
<td>Frontend developer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-10">
<div class="form-check style-check d-flex align-items-center">
<input class="form-check-input radius-4 border border-neutral-400" type="checkbox" name="checkbox">
</div>
10
</div>
</td>
<td>30 April 2024</td>
<td>
<div class="d-flex align-items-center">
<img src="{{ asset('assets/images/user-list/user-list10.png') }}" alt="" class="w-40-px h-40-px rounded-circle flex-shrink-0 me-12 overflow-hidden">
<div class="flex-grow-1">
<span class="text-md mb-0 fw-normal text-secondary-light">Cameron Williamson</span>
</div>
</div>
</td>
<td><span class="text-md mb-0 fw-normal text-secondary-light">danten@mail.ru</span></td>
<td>Development</td>
<td>Frontend developer</td>
<td class="text-center">
<span class="bg-success-focus text-success-600 border border-success-main px-24 py-4 radius-4 fw-medium text-sm">Active</span>
</td>
<td class="text-center">
<div class="d-flex align-items-center gap-10 justify-content-center">
<button type="button" class="bg-info-focus bg-hover-info-200 text-info-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="majesticons:eye-line" class="icon text-xl"></iconify-icon>
</button>
<button type="button" class="bg-success-focus text-success-600 bg-hover-success-200 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="lucide:edit" class="menu-icon"></iconify-icon>
</button>
<button type="button" class="remove-item-btn bg-danger-focus bg-hover-danger-200 text-danger-600 fw-medium w-40-px h-40-px d-flex justify-content-center align-items-center rounded-circle">
<iconify-icon icon="fluent:delete-24-regular" class="menu-icon"></iconify-icon>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mt-24">
<span>Showing 1 to 10 of 12 entries</span>
<ul class="pagination d-flex flex-wrap align-items-center gap-2 justify-content-center">
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md" href="javascript:void(0)">
<iconify-icon icon="ep:d-arrow-left" class=""></iconify-icon>
</a>
</li>
<li class="page-item">
<a class="page-link text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md bg-primary-600 text-white" href="javascript:void(0)">1</a>
</li>
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px" href="javascript:void(0)">2</a>
</li>
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md" href="javascript:void(0)">3</a>
</li>
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md" href="javascript:void(0)">4</a>
</li>
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md" href="javascript:void(0)">5</a>
</li>
<li class="page-item">
<a class="page-link bg-neutral-200 text-secondary-light fw-semibold radius-8 border-0 d-flex align-items-center justify-content-center h-32-px w-32-px text-md" href="javascript:void(0)">
<iconify-icon icon="ep:d-arrow-right" class=""></iconify-icon>
</a>
</li>
</ul>
</div>
</div>
</div>
@endsection

View File

@ -7,32 +7,47 @@
<body>
<section class="auth bg-base d-flex flex-wrap">
<div class="auth-left d-lg-block d-none">
<div class="d-flex align-items-center flex-column h-100 justify-content-center">
<img src="{{ asset('assets/images/auth/auth-img.png') }}" alt="">
<div class="auth-left d-lg-block d-none bg-blue-800">
<div class="d-flex align-items-center flex-column justify-content-center object-cover">
<img src="{{ asset('assets/images/auth/auth_img.png') }}" alt="">
</div>
</div>
<div class="auth-right py-32 px-24 d-flex flex-column justify-content-center">
<div class="max-w-464-px mx-auto w-100">
<div>
<a href="{{ route('index') }}" class="mb-40 max-w-290-px">
<a href="#" class="mb-40 max-w-290-px">
<img src="{{ asset('assets/images/logo.png') }}" alt="">
</a>
<h4 class="mb-12">Sign Up to your Account</h4>
<p class="mb-32 text-secondary-light text-lg">Welcome back! please enter your detail</p>
<h4 class="mb-12">Daftar Akun</h4>
{{-- <p class="mb-32 text-secondary-light text-lg">Silakan masukkan detail Anda</p> --}}
</div>
<form action="#">
<form method="POST" action="{{ route('auth.daftar.store') }}">
@csrf
@if(session('status'))
<div class="alert alert-success">{{ session('status') }}</div>
@endif
@if($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="icon-field mb-16">
<span class="icon top-50 translate-middle-y">
<iconify-icon icon="f7:person"></iconify-icon>
</span>
<input type="text" class="form-control h-56-px bg-neutral-50 radius-12" placeholder="Username">
<input name="company_name" type="text" class="form-control h-56-px bg-neutral-50 radius-12" placeholder="Nama Perusahaan">
</div>
<div class="icon-field mb-16">
<span class="icon top-50 translate-middle-y">
<iconify-icon icon="mage:email"></iconify-icon>
</span>
<input type="email" class="form-control h-56-px bg-neutral-50 radius-12" placeholder="Email">
<input name="email" type="email" class="form-control h-56-px bg-neutral-50 radius-12" placeholder="Email">
</div>
<div class="mb-20">
<div class="position-relative ">
@ -40,53 +55,45 @@
<span class="icon top-50 translate-middle-y">
<iconify-icon icon="solar:lock-password-outline"></iconify-icon>
</span>
<input type="password" class="form-control h-56-px bg-neutral-50 radius-12" id="your-password" placeholder="Password">
<input name="password" type="password" class="form-control h-56-px bg-neutral-50 radius-12" id="password" placeholder="Password">
</div>
<span class="toggle-password ri-eye-line cursor-pointer position-absolute end-0 top-50 translate-middle-y me-16 text-secondary-light" data-toggle="#your-password"></span>
<span class="toggle-password ri-eye-line cursor-pointer position-absolute end-0 top-50 translate-middle-y me-16 text-secondary-light" data-toggle="#password"></span>
</div>
</div>
<div class="mb-20">
<div class="position-relative ">
<div class="icon-field">
<span class="icon top-50 translate-middle-y">
<iconify-icon icon="solar:lock-password-outline"></iconify-icon>
</span>
<input name="password_confirmation" type="password" class="form-control h-56-px bg-neutral-50 radius-12" id="password-confirm" placeholder="Konfirmasi Password">
</div>
<span class="toggle-password ri-eye-line cursor-pointer position-absolute end-0 top-50 translate-middle-y me-16 text-secondary-light" data-toggle="#password-confirm"></span>
</div>
<span class="mt-12 text-sm text-secondary-light">Your password must have at least 8 characters</span>
</div>
<div class="">
<div class="d-flex justify-content-between gap-2">
<div class="form-check style-check d-flex align-items-start">
<input class="form-check-input border border-neutral-300 mt-4" type="checkbox" value="" id="condition">
<label class="form-check-label text-sm" for="condition">
By creating an account means you agree to the
<a href="javascript:void(0)" class="text-primary-600 fw-semibold">Terms & Conditions</a> and our
<a href="javascript:void(0)" class="text-primary-600 fw-semibold">Privacy Policy</a>
Saya setuju dengan
<a href="javascript:void(0)" class="text-primary-600 fw-semibold">Syarat & Ketentuan</a> dan
<a href="javascript:void(0)" class="text-primary-600 fw-semibold">Kebijakan Privasi</a>
</label>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary text-sm btn-sm px-12 py-16 w-100 radius-12 mt-32"> Sign Up</button>
<div class="mt-32 center-border-horizontal text-center">
<span class="bg-base z-1 px-4">Or sign up with</span>
</div>
<div class="mt-32 d-flex align-items-center gap-3">
<button type="button" class="fw-semibold text-primary-light py-16 px-24 w-50 border radius-12 text-md d-flex align-items-center justify-content-center gap-12 line-height-1 bg-hover-primary-50">
<iconify-icon icon="ic:baseline-facebook" class="text-primary-600 text-xl line-height-1"></iconify-icon>
Google
</button>
<button type="button" class="fw-semibold text-primary-light py-16 px-24 w-50 border radius-12 text-md d-flex align-items-center justify-content-center gap-12 line-height-1 bg-hover-primary-50">
<iconify-icon icon="logos:google-icon" class="text-primary-600 text-xl line-height-1"></iconify-icon>
Google
</button>
</div>
<div class="mt-32 text-center text-sm">
<p class="mb-0">Already have an account? <a href="{{ route('signin') }}" class="text-primary-600 fw-semibold">Sign In</a></p>
</div>
<button type="submit" class="btn btn-primary text-sm btn-sm px-12 py-16 w-100 radius-12 mt-32">Daftar</button>
</form>
</div>
</div>
</section>
@php
$script = '<script>
// ================== Password Show Hide Js Start ==========
@push('scripts')
<script>
function initializePasswordToggle(toggleSelector) {
$(toggleSelector).on("click", function() {
$(this).toggleClass("ri-eye-off-line");
@ -98,11 +105,9 @@
}
});
}
// Call the function
initializePasswordToggle(".toggle-password");
// ========================= Password Show Hide Js End ===========================
</script>';
@endphp
</script>
@endpush
<x-script />

View File

@ -9,6 +9,15 @@
<form action="{{ route('jadwal.create') }}" method="POST">
@csrf
<div class="row">
<div class="col-12 mb-20">
<label class="form-label fw-semibold text-primary-light text-sm mb-8">Perusahaan</label>
<select name="perusahaan_id" class="form-select radius-8 select2" style="width: 100%" required>
<option value="" disabled selected>Pilih Perusahaan</option>
@foreach(($perusahaan ?? []) as $p)
<option value="{{ $p->PerusahaanID }}">{{ $p->NamaPerusahaan }}</option>
@endforeach
</select>
</div>
<div class="col-12 mb-20">
<label class="form-label fw-semibold text-primary-light text-sm mb-8">Nama Kegiatan</label>
<input type="text" name="title" class="form-control radius-8" placeholder="Masukkan Nama Kegiatan" required>
@ -32,57 +41,15 @@
</div>
</div>
<div class="col-12 mb-20">
<label class="form-label fw-semibold text-primary-light text-sm mb-8">Jenis Perizinan </label>
<div class="d-flex align-items-center flex-wrap gap-28">
<div class="form-check checked-success d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="amdal" value="amdal" required>
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="amdal">
<span class="w-8-px h-8-px bg-info-600 rounded-circle"></span>
AMDAL
</label>
</div>
<div class="form-check checked-primary d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="pertek" value="pertek">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="pertek">
<span class="w-8-px h-8-px bg-success-600 rounded-circle"></span>
Pertek
</label>
</div>
<div class="form-check checked-warning d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="andal_rkl_rpl" value="andal_rkl_rpl">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="andal_rkl_rpl">
<span class="w-8-px h-8-px bg-warning-600 rounded-circle"></span>
Andal RKL-RPL
</label>
</div>
<div class="form-check checked-secondary d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="addendum" value="addendum">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="addendum">
<span class="w-8-px h-8-px bg-info-600 rounded-circle"></span>
Addendum
</label>
</div>
<div class="form-check checked-secondary d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="dplh" value="dplh">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="dplh">
<span class="w-8-px h-8-px bg-pink rounded-circle"></span>
DPLH
</label>
</div>
<div class="form-check checked-secondary d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="delh" value="delh">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="delh">
<span class="w-8-px h-8-px bg-lilac-600 rounded-circle"></span>
DELH
</label>
</div>
<div class="form-check checked-secondary d-flex align-items-center gap-2">
<input class="form-check-input" type="radio" name="document_type" id="ukl_upl" value="ukl_upl">
<label class="form-check-label line-height-1 fw-medium text-secondary-light text-sm d-flex align-items-center gap-1" for="ukl_upl">
<span class="w-8-px h-8-px bg-lilac-600 rounded-circle"></span>
UKL-UPL
</label>
</div>
<label class="form-label fw-semibold text-primary-light text-sm mb-8">Jenis Perizinan</label>
<div class="position-relative">
<select name="document_type" class="form-select radius-8" required>
<option value="" disabled selected>Pilih Jenis Dokumen</option>
@php $listTypes = ($dokumenTypes ?? null) && count($dokumenTypes) ? $dokumenTypes->pluck('Kode','Kode')->keys()->toArray() : ['amdal','pertek','andal_rkl_rpl','addendum','dplh','delh','ukl_upl']; @endphp
@foreach($listTypes as $kode)
<option value="{{ $kode }}">{{ strtoupper(str_replace('_',' ', $kode)) }}</option>
@endforeach
</select>
</div>
</div>

View File

@ -22,7 +22,7 @@
<!-- Desktop Menu -->
<div class="hidden md:flex items-center space-x-2">
<div class="relative group">
{{-- <div class="relative group">
<a href="{{ route('dashboard.index') }}"
class="text-gray-700 text-sm font-medium px-4 py-2 rounded-full transition-all duration-300
hover:bg-blue-50 hover:text-blue-600 hover:shadow flex items-center group">
@ -143,8 +143,15 @@
hover:bg-blue-50 hover:text-blue-600 hover:shadow flex items-center group">
CATATAN RILIS
</a>
</div>
</div> --}}
<a href="{{ route('daftar') }}"
class="border border-blue-400 ml-2 relative overflow-hidden group text-blue-700 hover:text-white px-6 py-2.5 rounded-full hover:shadow-lg">
<span class="relative z-10">DAFTAR</span>
<span
class="absolute left-0 bottom-0 w-0 h-full bg-blue-600 group-hover:w-full transition-all duration-300"></span>
</a>
<!-- Login/Dashboard Button -->
@auth
<a href="{{ route('dashboard.index') }}"

View File

@ -31,4 +31,6 @@
<!-- main js -->
<script src="{{ asset('assets/js/app.js') }}"></script>
@stack('scripts')
<?php echo (isset($script) ? $script : '')?>

View File

@ -27,6 +27,15 @@
</li>
@endcan
@can('pengumuman.access')
<li>
<a href="{{ route('pengumuman.index') }}">
<iconify-icon icon="bi:megaphone" class="menu-icon"></iconify-icon>
<span>PENGUMUMAN</span>
</a>
</li>
@endcan
{{-- <li class="sidebar-menu-group-title">Persetujuan Teknis</li> --}}
@can('persetujuan_teknis.access')
<li class="dropdown">

View File

@ -13,7 +13,7 @@
@include('components.frontend.home.popup', ['popup' => $popup])
@include('components.frontend.home.hero', ['heros' => $heros])
@include('components.frontend.home.layanan')
@include('components.frontend.home.faq', ['faqs' => $faqs])
{{-- @include('components.frontend.home.faq', ['faqs' => $faqs]) --}}
@include('components.frontend.home.news', ['newsItems' => $newsItems, 'videoItems' => $videoItems])
@include('components.frontend.footer')

View File

@ -0,0 +1,461 @@
@extends('layout.layout')
@php
$title='Tambah Pengumuman Kegiatan';
$subTitle = 'Tambah Data Pengumuman Kegiatan';
$script = '<script>
// Form validation and date picker initialization
document.addEventListener("DOMContentLoaded", function() {
// Initialize date picker if using flatpickr
if (typeof flatpickr !== "undefined") {
flatpickr("#tanggal_mulai", {
dateFormat: "Y-m-d",
minDate: "today"
});
}
// Form validation
const form = document.getElementById("createForm");
if (form) {
form.addEventListener("submit", function(e) {
const requiredFields = form.querySelectorAll("[required]");
let isValid = true;
requiredFields.forEach(field => {
if (!field.value.trim()) {
isValid = false;
field.classList.add("is-invalid");
} else {
field.classList.remove("is-invalid");
}
});
if (!isValid) {
e.preventDefault();
alert("Mohon lengkapi semua field yang wajib diisi");
}
});
}
});
</script>';
@endphp
@section('content')
<div class="card">
<div class="card-body">
<div class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-4">
<div>
<h5 class="mb-0">Tambah Pengumuman Kegiatan</h5>
<p class="text-muted mb-0">Masukkan informasi lengkap mengenai kegiatan yang akan diumumkan</p>
</div>
<div>
<a href="{{ route('pengumuman.index') }}" class="btn btn-outline-primary">
<i class="ri-arrow-left-line"></i> Kembali
</a>
</div>
</div>
<form id="createForm" action="{{ route('pengumuman.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="row">
<!-- Left Column -->
<div class="col-md-8">
<!-- Basic Information -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-primary-subtle">
<h6 class="mb-0 text-primary">Informasi Dasar</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="jenis_dokumen" class="form-label">Jenis Dokumen <span class="text-danger">*</span></label>
<select class="form-select @error('jenis_dokumen') is-invalid @enderror"
id="jenis_dokumen" name="jenis_dokumen" required>
<option value="">Pilih Jenis Dokumen</option>
<option value="AMDAL" {{ old('jenis_dokumen') == 'AMDAL' ? 'selected' : '' }}>AMDAL</option>
<option value="Addendum" {{ old('jenis_dokumen') == 'Addendum' ? 'selected' : '' }}>Addendum</option>
<option value="UKL-UPL" {{ old('jenis_dokumen') == 'UKL-UPL' ? 'selected' : '' }}>UKL-UPL</option>
</select>
@error('jenis_dokumen')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="nama_kegiatan" class="form-label">Nama Kegiatan <span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama_kegiatan') is-invalid @enderror"
id="nama_kegiatan" name="nama_kegiatan" value="{{ old('nama_kegiatan') }}" required>
@error('nama_kegiatan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="pemrakarsa" class="form-label">Pemrakarsa/Perusahaan <span class="text-danger">*</span></label>
<input type="text" class="form-control @error('pemrakarsa') is-invalid @enderror"
id="pemrakarsa" name="pemrakarsa" value="{{ old('pemrakarsa') }}" required>
@error('pemrakarsa')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="col-md-6">
<label for="bidang_usaha" class="form-label">Bidang Usaha <span class="text-danger">*</span></label>
<input type="text" class="form-control @error('bidang_usaha') is-invalid @enderror"
id="bidang_usaha" name="bidang_usaha" value="{{ old('bidang_usaha') }}" required>
@error('bidang_usaha')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-3">
<label for="deskripsi_kegiatan" class="form-label">Deskripsi Kegiatan <span class="text-danger">*</span></label>
<textarea class="form-control @error('deskripsi_kegiatan') is-invalid @enderror"
id="deskripsi_kegiatan" name="deskripsi_kegiatan" rows="4" required>{{ old('deskripsi_kegiatan') }}</textarea>
@error('deskripsi_kegiatan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="dampak_potensial" class="form-label">Dampak Potensial <span class="text-danger">*</span></label>
<textarea class="form-control @error('dampak_potensial') is-invalid @enderror"
id="dampak_potensial" name="dampak_potensial" rows="3" required>{{ old('dampak_potensial') }}</textarea>
@error('dampak_potensial')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div>
</div>
<!-- Location Information -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-primary-subtle">
<h6 class="mb-0 text-primary">Informasi Lokasi</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-4">
<label for="kabupaten" class="form-label">Kabupaten <span class="text-danger">*</span></label>
<select class="form-select @error('kabupaten') is-invalid @enderror"
id="kabupaten" name="kabupaten" required onchange="loadKecamatan()">
<option value="">Pilih Kabupaten</option>
@foreach($kabupaten as $kab)
<option value="{{ $kab->KabupatenId }}" {{ old('kabupaten') == $kab->KabupatenId ? 'selected' : '' }}>
{{ $kab->NamaKabupaten }}
</option>
@endforeach
</select>
@error('kabupaten')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="col-md-4">
<label for="kecamatan" class="form-label">Kecamatan <span class="text-danger">*</span></label>
<select class="form-select @error('kecamatan') is-invalid @enderror"
id="kecamatan" name="kecamatan" required onchange="loadKelurahan()">
<option value="">Pilih Kecamatan</option>
</select>
@error('kecamatan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="col-md-4">
<label for="kelurahan" class="form-label">Kelurahan <span class="text-danger">*</span></label>
<select class="form-select @error('kelurahan') is-invalid @enderror"
id="kelurahan" name="kelurahan" required>
<option value="">Pilih Kelurahan</option>
</select>
@error('kelurahan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="lokasi_kegiatan" class="form-label">Lokasi Kegiatan</label>
<textarea type="text" class="form-control @error('lokasi_kegiatan') is-invalid @enderror"
id="lokasi_kegiatan" name="lokasi_kegiatan" value="{{ old('lokasi_kegiatan') }}"></textarea>
@error('lokasi_kegiatan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-3">
<label for="deskripsi_lokasi" class="form-label">Deskripsi Lokasi <span class="text-danger">*</span></label>
<textarea class="form-control @error('deskripsi_lokasi') is-invalid @enderror"
id="deskripsi_lokasi" name="deskripsi_lokasi" rows="3" required>{{ old('deskripsi_lokasi') }}</textarea>
@error('deskripsi_lokasi')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="latitude" class="form-label">Latitude</label>
<input type="number" step="any" class="form-control @error('latitude') is-invalid @enderror"
id="latitude" name="latitude" value="{{ old('latitude') }}" placeholder="-6.2000000">
@error('latitude')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="col-md-6">
<label for="longitude" class="form-label">Longitude</label>
<input type="number" step="any" class="form-control @error('longitude') is-invalid @enderror"
id="longitude" name="longitude" value="{{ old('longitude') }}" placeholder="106.8000000">
@error('longitude')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-md-4">
<!-- Settings -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-primary-subtle">
<h6 class="mb-0 text-primary">Pengaturan</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="tanggal_mulai" class="form-label">Tanggal Mulai Periode <span class="text-danger">*</span></label>
<input type="date" class="form-control @error('tanggal_mulai') is-invalid @enderror"
id="tanggal_mulai" name="tanggal_mulai" value="{{ old('tanggal_mulai') }}" required>
<small class="text-muted">Periode berakhir otomatis setelah 10 hari kerja</small>
@error('tanggal_mulai')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="skala_besaran" class="form-label">Skala/Besaran</label>
<input type="text" class="form-control @error('skala_besaran') is-invalid @enderror"
id="skala_besaran" name="skala_besaran" value="{{ old('skala_besaran') }}"
placeholder="1000 ton/tahun">
@error('skala_besaran')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="kewenangan" class="form-label">Kewenangan <span class="text-danger">*</span></label>
<select class="form-select @error('kewenangan') is-invalid @enderror"
id="kewenangan" name="kewenangan" required>
<option value="">Pilih Kewenangan</option>
<option value="Pusat" {{ old('kewenangan') == 'Pusat' ? 'selected' : '' }}>Pusat</option>
<option value="Provinsi" {{ old('kewenangan') == 'Provinsi' ? 'selected' : '' }}>Provinsi</option>
<option value="Daerah" {{ old('kewenangan') == 'Daerah' ? 'selected' : '' }}>Daerah</option>
</select>
@error('kewenangan')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Hidden status field with default value -->
<input type="hidden" name="status" value="aktif">
</div>
</div>
<!-- Preview -->
<div class="card border-0 shadow-sm">
<div class="card-header bg-primary-subtle">
<h6 class="mb-0 text-primary">Preview Periode</h6>
</div>
<div class="card-body">
<div class="text-center">
<div class="text-muted small mb-2">Periode Pengumuman</div>
<div id="periode-preview" class="fw-bold text-primary">
Pilih tanggal mulai untuk melihat periode
</div>
<small class="text-muted">
*Menghitung 10 hari kerja (tidak termasuk sabtu, minggu, dan tanggal merah)
</small>
</div>
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="d-flex justify-content-end gap-2 mt-4">
<a href="{{ route('pengumuman.index') }}" class="btn btn-outline-secondary">
<i class="ri-close-line"></i> Batal
</a>
<button type="submit" class="btn btn-primary">
<i class="ri-save-line"></i> Simpan Pengumuman
</button>
</div>
</form>
</div>
</div>
<script>
// Preview periode calculation
document.getElementById('tanggal_mulai').addEventListener('change', function() {
const startDate = this.value;
if (startDate) {
// You can implement AJAX call here to get calculated end date
// For now, just show a simple preview
const preview = document.getElementById('periode-preview');
const start = new Date(startDate);
const options = { day: 'numeric', month: 'short', year: 'numeric' };
const startFormatted = start.toLocaleDateString('id-ID', options);
preview.innerHTML = `${startFormatted} - <span class="text-muted">Menghitung...</span>`;
// AJAX call to calculate end date
fetch('/admin/pengumuman/calculate-period', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ start_date: startDate })
})
.then(response => response.json())
.then(data => {
if (data.success) {
preview.innerHTML = data.periode;
}
})
.catch(() => {
preview.innerHTML = `${startFormatted} - (Error calculating)`;
});
}
});
// Load kecamatan based on selected kabupaten
function loadKecamatan() {
const kabupatenSelect = document.getElementById('kabupaten');
const kecamatanSelect = document.getElementById('kecamatan');
const kelurahanSelect = document.getElementById('kelurahan');
if (!kabupatenSelect || !kecamatanSelect || !kelurahanSelect) {
console.error('Required select elements not found');
return;
}
const selectedKabupaten = kabupatenSelect.value;
// Clear kecamatan and kelurahan
kecamatanSelect.innerHTML = '<option value="">Pilih Kecamatan</option>';
kelurahanSelect.innerHTML = '<option value="">Pilih Kelurahan</option>';
if (selectedKabupaten) {
// Show loading state
kecamatanSelect.innerHTML = '<option value="">Loading...</option>';
// Get CSRF token
const csrfToken = document.querySelector('meta[name="csrf-token"]');
const token = csrfToken ? csrfToken.getAttribute('content') : '';
// Fetch kecamatan from database
const url = `/admin/pengumuman/get-kecamatan?kabupaten_id=${selectedKabupaten}`;
fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': token
}
})
.then(response => {
if (!response.ok) {
return response.text().then(text => {
throw new Error(`HTTP ${response.status}: ${text}`);
});
}
return response.json();
})
.then(data => {
kecamatanSelect.innerHTML = '<option value="">Pilih Kecamatan</option>';
if (Array.isArray(data) && data.length > 0) {
data.forEach(kecamatan => {
const option = document.createElement('option');
option.value = kecamatan.KecamatanId;
option.textContent = kecamatan.NamaKecamatan;
kecamatanSelect.appendChild(option);
});
} else {
kecamatanSelect.innerHTML = '<option value="">No data available</option>';
}
})
.catch(error => {
console.error('Error loading kecamatan:', error);
kecamatanSelect.innerHTML = '<option value="">Error loading data</option>';
});
}
}
// Load kelurahan based on selected kecamatan
function loadKelurahan() {
const kecamatanSelect = document.getElementById('kecamatan');
const kelurahanSelect = document.getElementById('kelurahan');
if (!kecamatanSelect || !kelurahanSelect) {
console.error('Required select elements not found');
return;
}
const selectedKecamatan = kecamatanSelect.value;
// Clear kelurahan
kelurahanSelect.innerHTML = '<option value="">Pilih Kelurahan</option>';
if (selectedKecamatan) {
// Show loading state
kelurahanSelect.innerHTML = '<option value="">Loading...</option>';
// Get CSRF token
const csrfToken = document.querySelector('meta[name="csrf-token"]');
const token = csrfToken ? csrfToken.getAttribute('content') : '';
// Fetch kelurahan from database
const url = `/admin/pengumuman/get-kelurahan?kecamatan_id=${selectedKecamatan}`;
fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': token
}
})
.then(response => {
if (!response.ok) {
return response.text().then(text => {
throw new Error(`HTTP ${response.status}: ${text}`);
});
}
return response.json();
})
.then(data => {
kelurahanSelect.innerHTML = '<option value="">Pilih Kelurahan</option>';
if (Array.isArray(data) && data.length > 0) {
data.forEach(kelurahan => {
const option = document.createElement('option');
option.value = kelurahan.KelurahanId;
option.textContent = kelurahan.NamaKelurahan;
kelurahanSelect.appendChild(option);
});
} else {
kelurahanSelect.innerHTML = '<option value="">No data available</option>';
}
})
.catch(error => {
console.error('Error loading kelurahan:', error);
kelurahanSelect.innerHTML = '<option value="">Error loading data</option>';
});
}
}
</script>
@endsection

View File

@ -0,0 +1,331 @@
@extends('layout.layout')
@section('title', 'Detail Pengumuman')
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Detail Pengumuman</h5>
<a href="{{ route('pengumuman.index') }}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Kembali
</a>
</div>
<div class="card-body">
<div class="row">
<!-- Informasi Utama -->
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Informasi Pengumuman</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-4"><strong>No. Registrasi:</strong></div>
<div class="col-sm-8">
<span class="badge bg-primary">{{ $kegiatan->NoRegistrasi }}</span>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Nama Kegiatan:</strong></div>
<div class="col-sm-8">{{ $kegiatan->NamaKegiatan }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Jenis Dokumen:</strong></div>
<div class="col-sm-8">{{ $kegiatan->JenisDokumen }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Bidang Usaha:</strong></div>
<div class="col-sm-8">{{ $kegiatan->BidangUsaha }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Skala Besaran:</strong></div>
<div class="col-sm-8">{{ $kegiatan->SkalaBesaran }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Kewenangan:</strong></div>
<div class="col-sm-8">{{ $kegiatan->Kewenangan }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Status:</strong></div>
<div class="col-sm-8">
@if($kegiatan->Status == 'aktif')
<span class="badge bg-success">Aktif</span>
@elseif($kegiatan->Status == 'nonaktif')
<span class="badge bg-danger">Non Aktif</span>
@elseif($kegiatan->Status == 'selesai')
<span class="badge bg-info">Selesai</span>
@else
<span class="badge bg-warning">{{ $kegiatan->Status }}</span>
@endif
</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Deskripsi:</strong></div>
<div class="col-sm-8">
<div class="border p-3 bg-light rounded">
{!! nl2br(e($kegiatan->DeskripsiKegiatan)) !!}
</div>
</div>
</div>
</div>
</div>
<!-- Informasi Lokasi -->
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Informasi Lokasi</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-4"><strong>Lokasi Kegiatan:</strong></div>
<div class="col-sm-8">{{ $kegiatan->LokasiKegiatan ?? '-' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Provinsi/Kota:</strong></div>
<div class="col-sm-8">{{ $kegiatan->ProvinsiKota }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4"><strong>Deskripsi Lokasi:</strong></div>
<div class="col-sm-8">{{ $kegiatan->DeskripsiLokasi }}</div>
</div>
@if($kegiatan->Latitude && $kegiatan->Longitude)
<div class="row mb-3">
<div class="col-sm-4"><strong>Koordinat:</strong></div>
<div class="col-sm-8">
<span class="badge bg-info">{{ $kegiatan->Latitude }}, {{ $kegiatan->Longitude }}</span>
</div>
</div>
@endif
</div>
</div>
<!-- Dampak Potensial -->
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Dampak Potensial</h6>
</div>
<div class="card-body">
<div class="border p-3 bg-light rounded">
{!! nl2br(e($kegiatan->DampakPotensial)) !!}
</div>
</div>
</div>
<!-- Informasi Pemrakarsa -->
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Informasi Pemrakarsa</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-4"><strong>Nama Pemrakarsa:</strong></div>
<div class="col-sm-8">{{ $kegiatan->Pemrakarsa }}</div>
</div>
</div>
</div>
</div>
<!-- Sidebar Informasi -->
<div class="col-lg-4">
<!-- Informasi Waktu -->
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Informasi Waktu</h6>
</div>
<div class="card-body">
<div class="mb-3">
<strong>Tanggal Mulai:</strong><br>
<span class="text-primary">
{{ \Carbon\Carbon::parse($kegiatan->TanggalMulaiPeriode)->format('d F Y') }}
</span>
</div>
<div class="mb-3">
<strong>Tanggal Selesai:</strong><br>
<span class="text-danger">
{{ \Carbon\Carbon::parse($kegiatan->TanggalSelesaiPeriode)->format('d F Y') }}
</span>
</div>
<div class="mb-0">
<strong>Dibuat:</strong><br>
<small class="text-muted">
{{ \Carbon\Carbon::parse($kegiatan->created_at)->format('d M Y H:i') }}
</small>
</div>
</div>
</div>
<!-- Status Pengumuman -->
<div class="card mb-4">
<div class="card-header">
<h6 class="card-title mb-0">Status Pengumuman</h6>
</div>
<div class="card-body text-center">
@php
$now = \Carbon\Carbon::now();
$tanggalSelesai = \Carbon\Carbon::parse($kegiatan->TanggalSelesaiPeriode);
$sisaHari = $now->diffInDays($tanggalSelesai, false);
@endphp
@if($sisaHari > 0)
<div class="alert alert-success">
<i class="fas fa-clock"></i>
<strong>Masih Aktif</strong><br>
<small>Sisa {{ $sisaHari }} hari lagi</small>
</div>
@elseif($sisaHari == 0)
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle"></i>
<strong>Berakhir Hari Ini</strong>
</div>
@else
<div class="alert alert-danger">
<i class="fas fa-times-circle"></i>
<strong>Sudah Berakhir</strong><br>
<small>{{ abs($sisaHari) }} hari yang lalu</small>
</div>
@endif
</div>
</div>
<!-- Tombol Aksi -->
<div class="card">
<div class="card-header">
<h6 class="card-title mb-0">Aksi</h6>
</div>
<div class="card-body">
@if($sisaHari >= 0)
<a href="#" class="btn btn-primary btn-block mb-2">
<i class="fas fa-comment"></i> Berikan Tanggapan
</a>
@endif
<a href="#" class="btn btn-info btn-block mb-2">
<i class="fas fa-download"></i> Download PDF
</a>
<a href="#" class="btn btn-secondary btn-block">
<i class="fas fa-print"></i> Print
</a>
</div>
</div>
</div>
</div>
<!-- Tanggapan/Komentar -->
@if($kegiatan->saranTanggapanApproved && $kegiatan->saranTanggapanApproved->count() > 0)
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h6 class="card-title mb-0">
Tanggapan Masyarakat
<span class="badge bg-secondary">{{ $kegiatan->saranTanggapanApproved->count() }}</span>
</h6>
</div>
<div class="card-body">
@foreach($kegiatan->saranTanggapanApproved as $tanggapan)
<div class="border-bottom pb-3 mb-3">
<div class="d-flex justify-content-between align-items-start">
<div>
<strong>{{ $tanggapan->Nama }}</strong>
<small class="text-muted">- {{ $tanggapan->Email }}</small>
<span class="badge bg-info ms-2">{{ ucfirst($tanggapan->Peran) }}</span>
</div>
<small class="text-muted">
{{ \Carbon\Carbon::parse($tanggapan->TanggalDiajukan)->format('d M Y H:i') }}
</small>
</div>
<div class="mt-2">
<div class="row">
<div class="col-md-6">
<small class="text-muted"><strong>Kondisi Lingkungan:</strong></small>
<p class="mb-2">{{ $tanggapan->KondisiLingkungan }}</p>
<small class="text-muted"><strong>Nilai Lokal:</strong></small>
<p class="mb-2">{{ $tanggapan->NilaiLokal }}</p>
</div>
<div class="col-md-6">
<small class="text-muted"><strong>Kekhawatiran:</strong></small>
<p class="mb-2">{{ $tanggapan->Kekhawatiran }}</p>
<small class="text-muted"><strong>Harapan:</strong></small>
<p class="mb-2">{{ $tanggapan->Harapan }}</p>
</div>
</div>
<div class="mt-2">
<small class="text-muted"><strong>Tingkat Kekhawatiran:</strong></small>
<div class="d-flex align-items-center">
@for($i = 1; $i <= 5; $i++)
@if($i <= $tanggapan->TingkatKekhawatiran)
<i class="fas fa-star text-warning"></i>
@else
<i class="far fa-star text-muted"></i>
@endif
@endfor
<span class="ms-2 text-muted">({{ $tanggapan->TingkatKekhawatiran }}/5)</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection
@section('styles')
<style>
.card {
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
border: 1px solid rgba(0, 0, 0, 0.125);
}
.btn-block {
width: 100%;
}
.alert {
border: none;
border-radius: 8px;
}
.badge {
font-size: 0.875em;
}
@media (max-width: 768px) {
.col-sm-4 {
font-weight: bold;
margin-bottom: 0.5rem;
}
.col-sm-8 {
margin-bottom: 1rem;
}
}
</style>
@endsection

View File

@ -0,0 +1,87 @@
@extends('layout.layout')
@php
$title='Daftar Pengumuman Kegiatan';
$subTitle = 'Daftar Pengumuman Kegiatan';
$script = '<script>
let table = new DataTable("#dataTable");
</script>';
@endphp
@section('content')
<div class="card basic-data-table">
<div class="card-body">
<div class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-3 gap-3">
<div>
<h5 class="mb-0">Data Pengumuman Kegiatan</h5>
</div>
<div>
<a href="{{ route('pengumuman.create') }}" class="btn btn-primary-600 radius-8 px-20 py-11">
<i class="ri-add-line"></i>
Tambah Pengumuman
</a>
</div>
</div>
<div class="table-responsive">
<table class="table bordered-table mb-0" id="dataTable" data-page-length='10'>
<thead>
<tr>
<th scope="col">
<div class="form-check style-check d-flex align-items-center">
<label class="form-check-label">
No
</label>
</div>
</th>
<th scope="col">Nomor Registrasi</th>
<th scope="col">Nama Perusahaan</th>
<th scope="col">Nama Kegiatan</th>
<th scope="col">Jenis Dokumen</th>
<th scope="col">Tanggal</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
@forelse($pengumuman as $item)
<tr>
<td>
<div class="form-check style-check d-flex align-items-center">
<label class="form-check-label">
{{ str_pad($item['no'], 2, '0', STR_PAD_LEFT) }}
</label>
</div>
</td>
<td>
<a href="{{ $item['detail_url'] }}" class="text-primary-600">{{ $item['no_registrasi'] }}</a>
</td>
<td>
<div class="d-flex align-items-center">
<h6 class="text-md mb-0 fw-medium flex-grow-1">{{ $item['nama_perusahaan'] }}</h6>
</div>
</td>
<td>{{ Str::limit($item['nama_kegiatan'], 50) }}</td>
<td>{{ $item['jenis_dokumen'] }}</td>
<td>{{ $item['periode'] }}</td>
<td>
<span class="bg-success-focus text-success-main px-24 py-4 rounded-pill fw-medium text-sm">
{{ $item['status'] }}
</span>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="text-center py-4">
<div class="text-muted">
<i class="ri-inbox-line fs-2"></i>
<p class="mt-2">Tidak ada data pengumuman kegiatan</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@ -1,112 +1,176 @@
@extends('layout.layout')
@php
$title='Jadwal Sidang';
$subTitle = 'Jadwal Sidang';
$script = '
<script src="' . asset('assets/js/backend/jadwal/full-calendar.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/flatpickr.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/pagination.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/datepickr.js') . '"></script>';
$title = 'Penjadwalan';
$subTitle = 'Penjadwalan';
$script = '
<script src="' . asset('assets/js/backend/jadwal/flatpickr.js') . '"></script>
<script>
// Build disabled time ranges from existing jadwal
(function(){
const events = ' . json_encode($jadwal ?? []) . ';
function parseToDate(s){
if(!s) return null;
if(/T/.test(s)) { // ISO 8601
return new Date(s);
}
if(/^\d{4}-\d{2}-\d{2}$/.test(s)) { // yyyy-mm-dd (all day)
return new Date(s + "T00:00:00");
}
const m = s.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2})$/);
if(m){
const d = m[1], mo = m[2], y = m[3], H = m[4], i = m[5];
return new Date(`${y}-${mo}-${d}T${H}:${i}:00`);
}
return null;
}
const ranges = [];
(events || []).forEach(ev => {
const from = parseToDate(ev.start);
let to = parseToDate(ev.end);
if(from && to){
// If end is date-only (no time) push to end of day
if(/^\d{4}-\d{2}-\d{2}$/.test(ev.end || "")){
to = new Date(to.getFullYear(), to.getMonth(), to.getDate(), 23, 59, 59);
}
ranges.push({ from, to });
}
});
window.disabledJadwalRanges = ranges;
})();
</script>
<script src="' . asset('assets/js/backend/jadwal/datepickr.js') . '"></script>
<script>
let table = new DataTable("#dataTable");
if (window.jQuery) {
const initSelect2 = function(){
try {
jQuery(".select2").select2({ dropdownParent: jQuery("#exampleModal"), width: "100%" });
} catch(e) {}
};
initSelect2();
document.addEventListener("shown.bs.modal", function(e){
if (e.target && e.target.id === "exampleModal") initSelect2();
});
}
</script>';
@endphp
@section('content')
<div class="row gy-4">
<div class="col-xxl-3 col-lg-4">
<div class="card h-100 p-0">
<div class="card-body p-24">
<div class="d-flex justify-content-center">
<button type="button" class="btn btn-primary text-sm btn-sm px-12 py-12 w-100 radius-8 d-flex align-items-center justify-items-center gap-2 mb-32" data-bs-toggle="modal" data-bs-target="#exampleModal">
<iconify-icon icon="fa6-regular:square-plus" class="icon text-lg line-height-1"></iconify-icon>
Buat Jadwal
<div class="card basic-data-table">
<div class="card-body">
<div class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-3 gap-3">
<div>
<h5 class="mb-0">Data Jadwal Sidang</h5>
</div>
<div class="d-flex flex-column flex-sm-row align-items-stretch align-items-sm-center justify-content-end gap-2 w-md-auto">
<div class="flex-fill flex-sm-fill-0">
<button class="btn btn-primary btn-sm d-flex align-items-center justify-content-center gap-2 w-100" type="button">
<iconify-icon icon="material-symbols:info"></iconify-icon>
<span class="d-none d-sm-inline">Total Jadwal:</span>
<span class="d-inline d-sm-none">Total:</span>
<strong>{{ isset($jadwal) ? count($jadwal) : 0 }}</strong>
</button>
</div>
<div class="mb-24 document-type-filter">
<h6 class="text-primary-light fw-semibold mb-12">Filter Jenis Dokumen</h6>
<div class="position-relative">
<select id="document_type_filter" class="form-select radius-8">
<option value="all" {{ request('document_type') == '' ? 'selected' : '' }}>Semua Jenis Dokumen</option>
<option value="amdal" {{ request('document_type') == 'amdal' ? 'selected' : '' }}>AMDAL</option>
<option value="pertek" {{ request('document_type') == 'pertek' ? 'selected' : '' }}>PERTEK</option>
<option value="andal_rkl_rpl" {{ request('document_type') == 'andal_rkl_rpl' ? 'selected' : '' }}>ANDAL RKL-RPL</option>
<option value="addendum" {{ request('document_type') == 'addendum' ? 'selected' : '' }}>ADDENDUM</option>
<option value="dplh" {{ request('document_type') == 'dplh' ? 'selected' : '' }}>DPLH</option>
<option value="delh" {{ request('document_type') == 'delh' ? 'selected' : '' }}>DELH</option>
<option value="ukl_upl" {{ request('document_type') == 'ukl_upl' ? 'selected' : '' }}>UKL-UPL</option>
</select>
</div>
</div>
<div class="mt-32">
<div class="event-item d-flex align-items-center justify-content-between gap-4 pb-16 mb-16 border border-start-0 border-end-0 border-top-0">
<div class="d-flex flex-column">
<div class="d-flex flex-column gap-10">
<div class="mt-2">
<span class="badge bg-info-100 text-info-600 fw-medium radius-4 text-xs px-8 py-4">AMDAL</span>
</div>
<span class="text-secondary-light text-sm">Today, 10:30 PM - 02:30 AM</span>
</div>
<span class="text-primary-light fw-bold text-md mt-4 text-uppercase">PT. Mitra Usaha Sejahtera</span>
</div>
<div class="dropdown">
<button type="button" data-bs-toggle="dropdown" aria-expanded="false">
<iconify-icon icon="entypo:dots-three-vertical" class="icon text-secondary-light"></iconify-icon>
<div class="flex-fill flex-sm-fill-0">
<button class="btn btn-success btn-sm d-flex align-items-center justify-content-center gap-2 w-100" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal">
<iconify-icon icon="fa6-regular:square-plus"></iconify-icon>
<span class="d-none d-sm-inline">Buat Jadwal</span>
<span class="d-inline d-sm-none">Tambah</span>
</button>
<ul class="dropdown-menu p-12 border bg-base shadow">
<li>
<button type="button" class="dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-neutral-200 text-hover-neutral-900 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalView">
<iconify-icon icon="hugeicons:view" class="icon text-lg line-height-1"></iconify-icon>
View
</div>
</div>
</div>
<div class="table-responsive">
<table class="table bordered-table mb-0" id="dataTable" data-page-length='10'>
<thead>
<tr>
<th scope="col">
<div class="form-check style-check d-flex align-items-center">
<label class="form-check-label">No</label>
</div>
</th>
<th scope="col">Perusahaan</th>
<th scope="col">Nama Kegiatan</th>
<th scope="col">Jenis Dokumen</th>
<th scope="col">Mulai</th>
<th scope="col">Selesai</th>
<th scope="col">Status</th>
<th scope="col">Aksi</th>
</tr>
</thead>
<tbody>
@forelse(($jadwal ?? []) as $item)
@php
$start = \Carbon\Carbon::parse($item['start'] ?? null);
$end = \Carbon\Carbon::parse($item['end'] ?? null);
$now = \Carbon\Carbon::now();
$status = 'Terjadwal';
$statusClass = 'bg-info-100 text-info-600';
if ($start && $end) {
if ($now->between($start, $end)) {
$status = 'Berjalan';
$statusClass = 'bg-warning-100 text-warning-600';
} elseif ($now->gt($end)) {
$status = 'Selesai';
$statusClass = 'bg-success-focus text-success-main';
}
}
@endphp
<tr>
<td>
<div class="form-check style-check d-flex align-items-center">
<label class="form-check-label">{{ $loop->iteration }}</label>
</div>
</td>
<td>
<span class="text-primary-600">{{ $item['perusahaan'] ?? "-" }}</span>
</td>
<td>
<span class="text-primary-600">{{ $item['title'] ?? "-" }}</span>
</td>
<td>
<span class="badge bg-neutral-100 text-neutral-700 fw-medium radius-4 text-xs px-8 py-4 text-uppercase">{{ $item['documentType'] ?? '-' }}</span>
</td>
<td>{{ $start ? $start->format('d M Y H:i') : '-' }}</td>
<td>{{ $end ? $end->format('d M Y H:i') : '-' }}</td>
<td>
<span class="px-24 py-4 rounded-pill fw-medium text-sm {{ $statusClass }}">{{ $status }}</span>
</td>
<td>
<button type="button" class="btn btn-sm btn-light-primary" title="Detail" data-bs-toggle="modal" data-bs-target="#exampleModalView">
<iconify-icon icon="hugeicons:view" class="text-xl"></iconify-icon>
</button>
</li>
<li>
<button type="button" class="dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-neutral-200 text-hover-neutral-900 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalEdit">
<iconify-icon icon="lucide:edit" class="icon text-lg line-height-1"></iconify-icon>
Edit
</button>
</li>
<li>
<button type="button" class="delete-item dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-danger-100 text-hover-danger-600 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalDelete">
<iconify-icon icon="fluent:delete-24-regular" class="icon text-lg line-height-1"></iconify-icon>
Delete
</button>
</li>
</ul>
</td>
</tr>
@empty
<tr>
<td colspan="8" class="text-center text-secondary-light">Belum ada jadwal</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xxl-9 col-lg-8">
<div class="card h-100 p-0">
<div class="card-body p-24">
<div id='wrap'>
<div id='calendar'></div>
<div style='clear:both'></div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Add Jadwal -->
@include('components.backend.jadwal.modal_add')
<!-- Modal View Jadwal -->
@include('components.backend.jadwal.modal_view')
<!-- Modal Edit Jadwal -->
@include('components.backend.jadwal.modal_edit')
<!-- Modal Delete Jadwal -->
@include('components.backend.jadwal.modal_delete')
<!-- JS Filter -->
@include('components.backend.jadwal.filter')
@include('components.backend.jadwal.modal_add')
@include('components.backend.jadwal.modal_view')
@endsection

View File

@ -0,0 +1,112 @@
@extends('layout.layout')
@php
$title='Jadwal Sidang';
$subTitle = 'Jadwal Sidang';
$script = '
<script src="' . asset('assets/js/backend/jadwal/full-calendar.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/flatpickr.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/pagination.js') . '"></script>
<script src="' . asset('assets/js/backend/jadwal/datepickr.js') . '"></script>';
@endphp
@section('content')
<div class="row gy-4">
<div class="col-xxl-3 col-lg-4">
<div class="card h-100 p-0">
<div class="card-body p-24">
<div class="d-flex justify-content-center">
<button type="button" class="btn btn-primary text-sm btn-sm px-12 py-12 w-100 radius-8 d-flex align-items-center justify-items-center gap-2 mb-32" data-bs-toggle="modal" data-bs-target="#exampleModal">
<iconify-icon icon="fa6-regular:square-plus" class="icon text-lg line-height-1"></iconify-icon>
Buat Jadwal
</button>
</div>
<div class="mb-24 document-type-filter">
<h6 class="text-primary-light fw-semibold mb-12">Filter Jenis Dokumen</h6>
<div class="position-relative">
<select id="document_type_filter" class="form-select radius-8">
<option value="all" {{ request('document_type') == '' ? 'selected' : '' }}>Semua Jenis Dokumen</option>
<option value="amdal" {{ request('document_type') == 'amdal' ? 'selected' : '' }}>AMDAL</option>
<option value="pertek" {{ request('document_type') == 'pertek' ? 'selected' : '' }}>PERTEK</option>
<option value="andal_rkl_rpl" {{ request('document_type') == 'andal_rkl_rpl' ? 'selected' : '' }}>ANDAL RKL-RPL</option>
<option value="addendum" {{ request('document_type') == 'addendum' ? 'selected' : '' }}>ADDENDUM</option>
<option value="dplh" {{ request('document_type') == 'dplh' ? 'selected' : '' }}>DPLH</option>
<option value="delh" {{ request('document_type') == 'delh' ? 'selected' : '' }}>DELH</option>
<option value="ukl_upl" {{ request('document_type') == 'ukl_upl' ? 'selected' : '' }}>UKL-UPL</option>
</select>
</div>
</div>
<div class="mt-32">
<div class="event-item d-flex align-items-center justify-content-between gap-4 pb-16 mb-16 border border-start-0 border-end-0 border-top-0">
<div class="d-flex flex-column">
<div class="d-flex flex-column gap-10">
<div class="mt-2">
<span class="badge bg-info-100 text-info-600 fw-medium radius-4 text-xs px-8 py-4">AMDAL</span>
</div>
<span class="text-secondary-light text-sm">Today, 10:30 PM - 02:30 AM</span>
</div>
<span class="text-primary-light fw-bold text-md mt-4 text-uppercase">PT. Mitra Usaha Sejahtera</span>
</div>
<div class="dropdown">
<button type="button" data-bs-toggle="dropdown" aria-expanded="false">
<iconify-icon icon="entypo:dots-three-vertical" class="icon text-secondary-light"></iconify-icon>
</button>
<ul class="dropdown-menu p-12 border bg-base shadow">
<li>
<button type="button" class="dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-neutral-200 text-hover-neutral-900 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalView">
<iconify-icon icon="hugeicons:view" class="icon text-lg line-height-1"></iconify-icon>
View
</button>
</li>
<li>
<button type="button" class="dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-neutral-200 text-hover-neutral-900 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalEdit">
<iconify-icon icon="lucide:edit" class="icon text-lg line-height-1"></iconify-icon>
Edit
</button>
</li>
<li>
<button type="button" class="delete-item dropdown-item px-16 py-8 rounded text-secondary-light bg-hover-danger-100 text-hover-danger-600 d-flex align-items-center gap-10" data-bs-toggle="modal" data-bs-target="#exampleModalDelete">
<iconify-icon icon="fluent:delete-24-regular" class="icon text-lg line-height-1"></iconify-icon>
Delete
</button>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xxl-9 col-lg-8">
<div class="card h-100 p-0">
<div class="card-body p-24">
<div id='wrap'>
<div id='calendar'></div>
<div style='clear:both'></div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Add Jadwal -->
@include('components.backend.jadwal.modal_add')
<!-- Modal View Jadwal -->
@include('components.backend.jadwal.modal_view')
<!-- Modal Edit Jadwal -->
@include('components.backend.jadwal.modal_edit')
<!-- Modal Delete Jadwal -->
@include('components.backend.jadwal.modal_delete')
<!-- JS Filter -->
@include('components.backend.jadwal.filter')
@endsection

View File

@ -0,0 +1,23 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kelengkapan Perusahaan</title>
</head>
<body>
<h1>Lengkapi Data Perusahaan</h1>
<p>User ID: {{ $userId }}</p>
<p>Daftar ID: {{ $daftarId }}</p>
<form method="post" action="#">
@csrf
<label>Nama Perusahaan</label>
<input type="text" name="NamaPerusahaan" value="" />
<br />
<label>Alamat</label>
<textarea name="Alamat"></textarea>
<br />
<button type="submit">Simpan</button>
</form>
</body>
</html>

View File

@ -3,6 +3,7 @@
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\LayananController;
// API Authentication Routes (Token-based)
Route::prefix('auth')->group(function () {
@ -15,6 +16,17 @@ Route::prefix('auth')->group(function () {
});
});
// Public API Routes for Layanan
Route::prefix('layanan')->group(function () {
Route::get('/data', [LayananController::class, 'getLayananData']);
Route::get('/wilayah', [LayananController::class, 'getWilayahData']);
Route::get('/filter', [LayananController::class, 'getFilteredKegiatan']);
Route::get('/detail/{id}', [LayananController::class, 'getDetailKegiatan']);
Route::get('/activity/{id}', [LayananController::class, 'getActivityInfo']);
Route::post('/feedback', [LayananController::class, 'submitFeedback']);
Route::get('/activity/{id}/stats', [LayananController::class, 'getFeedbackStats']);
});
// Protected API Routes
Route::middleware('auth:sanctum')->group(function () {
// Dashboard API endpoints

View File

@ -12,6 +12,7 @@ use App\Http\Controllers\PenugasanController;
use App\Http\Controllers\Admin\RoleController;
use App\Http\Controllers\Admin\PermissionController;
use App\Http\Controllers\PengumumanController;
use App\Http\Controllers\Persetujuan\AddendumController;
use App\Http\Controllers\Persetujuan\AmdalController;
use App\Http\Controllers\Persetujuan\DelhController;
@ -72,12 +73,20 @@ Route::middleware(['web.auth'])->group(function () {
});
// Web Authentication (Session-based with cookies)
Route::get('/auth/login', [LoginController::class, 'index'])->name('login.index');
Route::post('/auth/session-login', [WebAuthController::class, 'sessionLogin'])->name('login.session');
Route::post('/auth/logout', [WebAuthController::class, 'sessionLogout'])->name('logout.session');
// Daftar / Registrasi
Route::get('/auth/daftar', [LoginController::class, 'register'])->name('auth.daftar');
Route::get('/daftar', function () {
return redirect()->route('auth.daftar');
})->name('daftar');
// Signup form submission
Route::post('/auth/daftar', [\App\Http\Controllers\SignupController::class, 'store'])->name('auth.daftar.store');
// User Management & Settings (restricted to settings.manage)
Route::prefix('admin')->middleware(['web.auth', 'permission:settings.manage'])->group(function () {
// User Management
@ -136,6 +145,16 @@ Route::prefix('admin')->middleware(['web.auth'])->group(function () {
Route::get('/izinemisi', [IzinEmisiController::class, 'index_emisi'])->middleware('permission:izin_tempat_uji_emisi.access')->name('izinemisi.index_permohonan');
});
Route::prefix('admin')->middleware(['web.auth'])->group(function () {
Route::get('/pengumuman', [PengumumanController::class, 'index'])->middleware('permission:pengumuman.access')->name('pengumuman.index');
Route::get('/pengumuman/create', [PengumumanController::class, 'create'])->middleware('permission:pengumuman.access')->name('pengumuman.create');
Route::post('/pengumuman', [PengumumanController::class, 'store'])->middleware('permission:pengumuman.access')->name('pengumuman.store');
Route::post('/pengumuman/calculate-period', [PengumumanController::class, 'calculatePeriod'])->middleware('permission:pengumuman.access')->name('pengumuman.calculate-period');
Route::get('/pengumuman/get-kecamatan', [PengumumanController::class, 'getKecamatan'])->middleware('permission:pengumuman.access')->name('pengumuman.get-kecamatan');
Route::get('/pengumuman/get-kelurahan', [PengumumanController::class, 'getKelurahan'])->middleware('permission:pengumuman.access')->name('pengumuman.get-kelurahan');
Route::get('/pengumuman/{id}', [PengumumanController::class, 'detail'])->middleware('permission:pengumuman.access')->name('pengumuman.detail');
});
//rintek
// Route::prefix('admin')->group(function () {
// Route::get('/jadwal', [JadwalSidangController::class, 'index'])->name('jadwal.index');
@ -163,6 +182,7 @@ Route::prefix('admin/profile')->middleware(['web.auth'])->group(function () {
Route::get('/change-email', [ProfileController::class, 'changeEmailForm'])->name('profile.change-email');
Route::put('/change-email', [ProfileController::class, 'updateEmail'])->name('profile.update-email');
Route::post('/update-photo', [ProfileController::class, 'updatePhoto'])->name('profile.update-photo');
});
// News Management
@ -205,3 +225,11 @@ Route::prefix('admin')->middleware(['web.auth'])->group(function () {
Route::get('/dplh', [DplhController::class, 'index'])->middleware('permission:persetujuan_lingkungan.access')->name('persetujuan.dplh.index');
Route::get('/dplh/detail', [DplhController::class, 'detail'])->middleware('permission:persetujuan_lingkungan.access')->name('persetujuan.dplh.detail');
});
// API Routes for Frontend Layanan
Route::prefix('api/layanan')->group(function () {
Route::get('/data', [App\Http\Controllers\LayananController::class, 'getLayananData'])->name('api.layanan.data');
Route::get('/wilayah', [App\Http\Controllers\LayananController::class, 'getWilayahData'])->name('api.layanan.wilayah');
Route::get('/detail/{id}', [App\Http\Controllers\LayananController::class, 'getDetailKegiatan'])->name('layanan.detail');
Route::get('/filter', [App\Http\Controllers\LayananController::class, 'getFilteredKegiatan'])->name('api.layanan.filter');
});