Compare commits

..

No commits in common. "c71c01297728cf5c55e42559eb0b54c851c05af7" and "1472d41f2a267d961ab204055c6627cb905fdcd1" have entirely different histories.

73 changed files with 1079 additions and 12814 deletions

View File

@ -2,12 +2,10 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Nette\Utils\Strings;
use App\Models\DataKategori; use App\Models\DataKategori;
use Nette\Utils\Strings;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use PhpParser\Node\Stmt\TryCatch; use PhpParser\Node\Stmt\TryCatch;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\Events\Validated; use Illuminate\Auth\Events\Validated;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use PhpParser\Node\Expr\Cast\String_; use PhpParser\Node\Expr\Cast\String_;
@ -18,37 +16,23 @@
class AdminDataKursusController extends Controller class AdminDataKursusController extends Controller
{ {
public function dataKursus(Request $request) // ADMIN FADIAS TUKANG SERVER
public function dataKursus()
{ {
$query = DataKursus::with('kategoris') // Mengambil semua data kursus dari model DataKursus
->where('user_id', auth()->id()); // Filter berdasarkan user login $courses = DataKursus::with('kategoris')->paginate(10);
// Filter berdasarkan pencarian // Mengambil gambar untuk setiap course, jika ada
if ($request->has('search') && !empty($request->search)) {
$query->where('nama_kursus', 'like', '%' . $request->search . '%');
}
// Filter berdasarkan kategori (jika dipilih)
if ($request->has('role') && !empty($request->role)) {
$query->whereHas('kategoris', function ($q) use ($request) {
$q->where('nama_kategori', $request->role);
});
}
$kategoriList = DataKategori::all();
// Ambil data dengan paginasi
$courses = $query->paginate(10);
// Ambil gambar untuk setiap course
foreach ($courses as $course) { foreach ($courses as $course) {
$course->imageNames = $course->img_konten ? json_decode($course->img_konten, true) : []; $course->imageNames = $course->img_konten ? json_decode($course->img_konten, true) : [];
} }
return view('admin.dataKursusAdmin', compact('courses', 'kategoriList')); // Mengirim data courses dengan gambar ke view
return view('admin.dataKursusAdmin', ['courses' => $courses]);
} }
public function create() public function create()
{ {
$kategori = DataKategori::all(); $kategori = DataKategori::all();
@ -69,6 +53,7 @@ public function store(Request $request)
'lokasi' => 'required', 'lokasi' => 'required',
'latitude' => 'required', // Ubah menjadi wajib diisi 'latitude' => 'required', // Ubah menjadi wajib diisi
'longitude' => 'required', // Ubah menjadi wajib diisi 'longitude' => 'required', // Ubah menjadi wajib diisi
'popular' => 'required',
'img_konten.*' => 'nullable|image', // Gambar konten tetap opsional 'img_konten.*' => 'nullable|image', // Gambar konten tetap opsional
], [ ], [
'nama_kursus.required' => 'Nama kursus wajib diisi.', 'nama_kursus.required' => 'Nama kursus wajib diisi.',
@ -84,6 +69,7 @@ public function store(Request $request)
'lokasi.required' => 'Lokasi wajib diisi.', 'lokasi.required' => 'Lokasi wajib diisi.',
'latitude.required' => 'Latitude wajib diisi.', // Pesan error custom 'latitude.required' => 'Latitude wajib diisi.', // Pesan error custom
'longitude.required' => 'Longitude wajib diisi.', // Pesan error custom 'longitude.required' => 'Longitude wajib diisi.', // Pesan error custom
'popular.required' => 'Status popular wajib diisi.',
'img_konten.*.nullable' => 'Gambar konten bersifat opsional.', 'img_konten.*.nullable' => 'Gambar konten bersifat opsional.',
'img_konten.*.file' => 'File yang di-upload harus berupa gambar.', 'img_konten.*.file' => 'File yang di-upload harus berupa gambar.',
]); ]);
@ -105,7 +91,6 @@ public function store(Request $request)
} }
} }
// Simpan data ke dalam database
// Simpan data ke dalam database // Simpan data ke dalam database
$result = DataKursus::create([ $result = DataKursus::create([
'nama_kursus' => $request->nama_kursus, 'nama_kursus' => $request->nama_kursus,
@ -114,12 +99,12 @@ public function store(Request $request)
'deskripsi' => $request->deskripsi, 'deskripsi' => $request->deskripsi,
'paket' => $request->paket, 'paket' => $request->paket,
'metode' => $request->metode, 'metode' => $request->metode,
'fasilitas' => json_encode(json_decode($request->fasilitas, true)), // Pastikan data tersimpan sebagai JSON valid 'fasilitas' => $request->fasilitas,
'lokasi' => $request->lokasi, 'lokasi' => $request->lokasi,
'latitude' => $request->latitude, 'latitude' => $request->latitude, // Menyimpan nilai latitude bebas
'longitude' => $request->longitude, 'longitude' => $request->longitude, // Menyimpan nilai longitude bebas
'popular' => $request->popular, // Menyimpan nilai longitude bebas
'img_konten' => json_encode($imgKontenPaths), 'img_konten' => json_encode($imgKontenPaths),
'user_id' => Auth::id(),
]); ]);
// Redirect setelah berhasil // Redirect setelah berhasil
@ -133,23 +118,17 @@ public function store(Request $request)
public function edit($id) public function edit($id)
{ {
// Ambil data kategori // Ambil record DataKursus berdasarkan ID-nya
$kategori = DataKategori::all(); $kategori = DataKategori::all();
// Ambil data kursus berdasarkan ID
$dataKursus = DataKursus::findOrFail($id); $dataKursus = DataKursus::findOrFail($id);
// Decode JSON fasilitas agar bisa ditampilkan dalam bentuk array // Decode field JSON untuk nama gambar jika ada
$fasilitas = json_decode($dataKursus->fasilitas, true) ?? [];
// Decode JSON untuk daftar gambar konten (jika ada)
$imageName = $dataKursus->img_konten ? json_decode($dataKursus->img_konten, true) : []; $imageName = $dataKursus->img_konten ? json_decode($dataKursus->img_konten, true) : [];
// Kirim data ke view // Kirim data ke view
return view('admin.ubahDataKursusAdmin', compact('dataKursus', 'imageName', 'kategori', 'fasilitas')); return view('admin.ubahDataKursusAdmin', compact('dataKursus', 'imageName', 'kategori'));
} }
public function update(Request $request, $id) public function update(Request $request, $id)
{ {
// Validasi request // Validasi request
@ -161,10 +140,10 @@ public function update(Request $request, $id)
'img_konten.*' => 'nullable|image', 'img_konten.*' => 'nullable|image',
'latitude' => 'required|numeric', 'latitude' => 'required|numeric',
'longitude' => 'required|numeric', 'longitude' => 'required|numeric',
'popular' => 'required|string',
'paket' => 'required|string', 'paket' => 'required|string',
'metode' => 'required|string', 'metode' => 'required|string',
'fasilitas' => 'required|array', // Mengizinkan array 'fasilitas' => 'required|string',
'fasilitas.*' => 'required|string', // Setiap elemen harus string
'lokasi' => 'required|string', 'lokasi' => 'required|string',
], [ ], [
'nama_kursus.required' => 'Nama kursus wajib diisi.', 'nama_kursus.required' => 'Nama kursus wajib diisi.',
@ -176,32 +155,29 @@ public function update(Request $request, $id)
'latitude.numeric' => 'Latitude harus berupa angka.', 'latitude.numeric' => 'Latitude harus berupa angka.',
'longitude.required' => 'Longitude wajib diisi.', 'longitude.required' => 'Longitude wajib diisi.',
'longitude.numeric' => 'Longitude harus berupa angka.', 'longitude.numeric' => 'Longitude harus berupa angka.',
'popular.required' => 'Status popular wajib diisi.',
'paket.required' => 'Paket wajib diisi.', 'paket.required' => 'Paket wajib diisi.',
'metode.required' => 'Metode wajib diisi.', 'metode.required' => 'Metode wajib diisi.',
'fasilitas.required' => 'Fasilitas wajib diisi.', 'fasilitas.required' => 'Fasilitas wajib diisi.',
'fasilitas.array' => 'Fasilitas harus dalam format array.',
'lokasi.required' => 'Lokasi wajib diisi.', 'lokasi.required' => 'Lokasi wajib diisi.',
]); ]);
try {
// Gunakan transaksi database untuk memastikan data aman
DB::beginTransaction();
try {
// Ambil record DataKursus berdasarkan ID-nya // Ambil record DataKursus berdasarkan ID-nya
$dataKursus = DataKursus::findOrFail($id); $dataKursus = DataKursus::findOrFail($id);
// Update fields // Update fields
$dataKursus->update([ $dataKursus->nama_kursus = $request->input('nama_kursus');
'nama_kursus' => $request->input('nama_kursus'), $dataKursus->kategori_id = $request->input('kategori_id');
'kategori_id' => $request->input('kategori_id'), $dataKursus->deskripsi = $request->input('deskripsi');
'deskripsi' => $request->input('deskripsi'), $dataKursus->latitude = $request->input('latitude');
'latitude' => $request->input('latitude'), $dataKursus->longitude = $request->input('longitude');
'longitude' => $request->input('longitude'), $dataKursus->popular = $request->input('popular');
'paket' => $request->input('paket'), $dataKursus->paket = $request->input('paket');
'metode' => $request->input('metode'), $dataKursus->metode = $request->input('metode');
'fasilitas' => json_encode($request->input('fasilitas')), // Simpan sebagai JSON $dataKursus->fasilitas = $request->input('fasilitas');
'lokasi' => $request->input('lokasi'), $dataKursus->lokasi = $request->input('lokasi');
]);
// Update gambar utama jika ada file baru // Update gambar utama jika ada file baru
if ($request->hasFile('img')) { if ($request->hasFile('img')) {
@ -217,7 +193,7 @@ public function update(Request $request, $id)
// Update multiple file upload jika ada file baru // Update multiple file upload jika ada file baru
if ($request->hasFile('img_konten')) { if ($request->hasFile('img_konten')) {
if ($dataKursus->img_konten) { if ($dataKursus->img_konten) {
$oldImages = json_decode($dataKursus->img_konten, true) ?? []; $oldImages = json_decode($dataKursus->img_konten, true);
foreach ($oldImages as $oldImage) { foreach ($oldImages as $oldImage) {
Storage::delete('public/' . $oldImage); Storage::delete('public/' . $oldImage);
} }
@ -225,8 +201,8 @@ public function update(Request $request, $id)
$menuImages = []; $menuImages = [];
foreach ($request->file('img_konten') as $file) { foreach ($request->file('img_konten') as $file) {
$imgKontenPath = $file->store('logo', 'public'); $imgKontenPaths = $file->store('logo', 'public');
$menuImages[] = $imgKontenPath; $menuImages[] = $imgKontenPaths;
} }
$dataKursus->img_konten = json_encode($menuImages); $dataKursus->img_konten = json_encode($menuImages);
} }
@ -234,14 +210,10 @@ public function update(Request $request, $id)
// Simpan perubahan // Simpan perubahan
$dataKursus->save(); $dataKursus->save();
// Commit transaksi
DB::commit();
// Redirect dengan pesan sukses // Redirect dengan pesan sukses
return redirect()->route('admin.dataKursus')->with('success', 'Data berhasil diperbarui.'); return redirect()->route('admin.dataKursus')->with('success', 'Data berhasil diperbarui.');
} catch (\Exception $e) { } catch (\Exception $e) {
// Rollback jika terjadi error // Tangani error dan kirimkan pesan error
DB::rollBack();
return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage()); return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
} }
} }
@ -251,13 +223,8 @@ public function update(Request $request, $id)
public function destroy($id) public function destroy($id)
{ {
try { $dataKursus = DataKursus::findOrFail($id);
$dataKursus = DataKursus::findOrFail($id); $dataKursus->delete();
$dataKursus->delete(); return redirect()->route('admin.dataKursus')->with('success', 'Data berhasil dihapus.');
return redirect()->route('admin.dataKursus')->with('success', 'Data berhasil dihapus.');
} catch (\Exception $e) {
return redirect()->route('admin.dataKursus')->with('error', 'Gagal Menghapus Kursus, Periksa ');
}
} }
} }

View File

@ -1,132 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AdminUserController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$role = $request->get('role'); // Ambil filter role
$search = $request->get('search'); // Ambil input search
$user = User::when($role, function ($query, $role) {
return $query->where('role', $role); // Filter berdasarkan role jika ada
})
->when($search, function ($query, $search) {
return $query->where(function ($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('username', 'like', "%{$search}"); // Cari berdasarkan nama atau email
});
})
->whereIn('role', ['user', 'pengunjung']) // Pastikan hanya user & pengunjung
->paginate(10);
return view('admin.user.index', compact('user'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
try {
// Validasi data yang masuk
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'username' => 'required',
'password' => 'required|min:6',
'verif_password' => 'required|same:password',
]);
// Simpan user baru ke database
User::create([
'name' => $validatedData['name'],
'email' => $validatedData['email'],
'username' => $validatedData['username'],
'password' => Hash::make($validatedData['password']), // Hash password untuk keamanan
'role' => 'user', // Default role untuk user baru
]);
return redirect()->route('user.index')->with('success', 'User berhasil ditambahkan!');
} catch (\Exception $e) {
// Simpan error ke log untuk debugging
return redirect()->route('user.index')->with('error', 'Error: ' . $e->getMessage());
}
}
/**
* Display the specified resource.
*/
public function show(string $id) {}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$request->validate([
'name' => 'required',
'email' => 'email|required'
]);
try {
$user = User::findOrFail($id);
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->save();
return redirect()->route('user.index')->with('success', 'User berhasil diperbarui.');
} catch (\Exception $e) {
return redirect()->route('user.index')->with('error', 'Error:' . $e->getMessage());
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try {
// Cari user berdasarkan ID
$user = User::findOrFail($id);
// Hapus user dari database
$user->delete();
// Redirect dengan pesan sukses
return redirect()->route('user.index')->with('success', 'User berhasil dihapus.');
} catch (\Exception $e) {
return redirect()->route('user.index')->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
}
}

View File

@ -11,23 +11,15 @@ class KategoriController extends Controller
/** /**
* Display a listing of the resource. * Display a listing of the resource.
*/ */
public function index(Request $request) public function index()
{ {
$query = DataKategori::query(); // Mengambil semua data kursus dari model DataKursus
$kategori = DataKategori::paginate(10);
// Cek apakah ada input pencarian // Mengirim data courses dengan gambar ke view
if ($request->has('search') && !empty($request->search)) {
$query->where('nama_kategori', 'like', '%' . $request->search . '%');
}
// Ambil data dengan paginasi
$kategori = $query->paginate(10);
// Kirim data ke view
return view('admin.dataKategoriAdmin', compact('kategori')); return view('admin.dataKategoriAdmin', compact('kategori'));
} }
/** /**
* Show the form for creating a new resource. * Show the form for creating a new resource.
*/ */
@ -112,16 +104,11 @@ public function update(Request $request, string $id)
*/ */
public function destroy(string $id) public function destroy(string $id)
{ {
try { // Temukan kategori berdasarkan ID
// Temukan kategori berdasarkan ID $kategori = DataKategori::findOrFail($id);
$kategori = DataKategori::findOrFail($id);
// Hapus kategori // Hapus kategori
$kategori->delete(); $kategori->delete();
return redirect()->route('kategori.index')->with('success', 'Kategori berhasil dihapus.');
return redirect()->route('kategori.index')->with('success', 'Kategori berhasil dihapus.');
} catch (\Exception $e) {
return redirect()->route('kategori.index')->with('error', 'Gagal menghapus kategori. untuk menghapus kategori tidak boleh ada kursus yang tersambung dengan kategori ');
}
} }
} }

View File

@ -1,62 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\Kunjungan;
use App\Models\DataKursus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class KunjunganController extends Controller
{
// Fungsi untuk mencatat kunjungan
public function visitCourse(Request $request, $kursus_id)
{
// Ambil IP pengguna secara otomatis dari request
$ip_user = $request->ip();
// Cari kursus berdasarkan ID
$kursus = DataKursus::find($kursus_id);
if (!$kursus) {
return response()->json([
'status' => 'error',
'message' => 'Course not found',
], 404);
}
// Cek apakah IP pengguna sudah mengunjungi kursus ini pada hari ini
$today = now()->format('Y-m-d'); // Ambil tanggal hari ini dalam format Y-m-d
$existingVisit = Kunjungan::where('ip_user', $ip_user)
->where('kursus_id', $kursus_id)
->whereDate('created_at', $today) // Cek berdasarkan tanggal
->first();
if ($existingVisit) {
return response()->json([
'status' => 'info',
'message' => 'You have already visited this course today.',
], 200);
}
// Jika belum ada kunjungan, buat data kunjungan baru
try {
$kunjungan = Kunjungan::create([
'ip_user' => $ip_user,
'kursus_id' => $kursus_id,
]);
return response()->json([
'status' => 'success',
'message' => 'Successfully recorded visit.',
'data' => $kunjungan
], 201);
} catch (\Exception $e) {
return response()->json([
'status' => 'error',
'message' => 'Failed to record visit: ' . $e->getMessage(),
], 500);
}
}
}

View File

@ -4,7 +4,6 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class LoginController extends Controller class LoginController extends Controller
{ {
@ -15,65 +14,43 @@ public function index()
public function authenticate(Request $request) public function authenticate(Request $request)
{ {
// Validasi input (login bisa berupa email atau username, dan password) // Validasi input
$credentials = $request->validate([ $credentials = $request->validate([
'login' => ['required'], // Input login (email atau username) 'email' => ['required', 'email'],
'password' => ['required'], 'password' => ['required'],
]); ]);
// Ambil nilai "remember" dari request (default false jika tidak dicentang) // Ambil nilai "remember" dari request (default false jika tidak dicentang)
$remember = $request->has('remember'); $remember = $request->has('remember');
// Logout pengguna lama untuk mencegah konflik sesi // Coba autentikasi dengan kredensial dan parameter "remember"
Auth::logout(); if (Auth::attempt($credentials, $remember)) {
// Cek apakah input login berupa email atau username
$user = null;
if (filter_var($credentials['login'], FILTER_VALIDATE_EMAIL)) {
// Jika input adalah email, cari berdasarkan email
$user = \App\Models\User::where('email', $credentials['login'])->first();
} else {
// Jika input adalah username, cari berdasarkan username
$user = \App\Models\User::where('username', $credentials['login'])->first();
}
// Cek apakah pengguna ditemukan
if ($user && Hash::check($credentials['password'], $user->password)) {
// Jika password cocok, login
Auth::login($user, $remember);
$request->session()->regenerate(); $request->session()->regenerate();
// Ambil role user yang sedang login // Periksa role dan arahkan sesuai dengan role
$role = Auth::user()->role; $role = Auth::user()->role;
// Simpan status login sesuai dengan role
if ($role === 'admin') { if ($role === 'admin') {
session(['is_admin_logged_in' => true]); // Status admin session(['is_pengunjung_logged_in' => true]); // Menyimpan status pengunjung dalam sesi
return redirect()->route('admin.home'); return redirect()->route('admin.home');
} }
if ($role === 'user') { // Jika pengunjung, simpan sesi dan arahkan ke halaman depan
session(['is_user_logged_in' => true]); // Status user
return redirect()->route('user.home'); // Redirect ke halaman user
}
if ($role === 'pengunjung') { if ($role === 'pengunjung') {
session(['is_pengunjung_logged_in' => true]); // Status pengunjung session(['is_pengunjung_logged_in' => true]); // Menyimpan status pengunjung dalam sesi
return redirect()->route('user.home'); // Redirect ke halaman pengunjung return redirect()->route('user.home');
} }
} }
// Jika gagal login, kembali dengan error // Jika gagal login, kembali dengan error
return back()->withErrors([ return back()->withErrors([
'login' => 'Email/Username atau password salah.', 'email' => 'Email atau password salah.',
]); ]);
} }
public function logout(Request $request) public function logout(Request $request)
{ {
Auth::logout(); Auth::logout();

View File

@ -2,10 +2,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Kunjungan;
use App\Models\DataKursus; use App\Models\DataKursus;
use App\Models\DataUlasan; use App\Models\DataUlasan;
use Illuminate\Support\Str;
use App\Models\DataKategori; use App\Models\DataKategori;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Dflydev\DotAccessData\Data; use Dflydev\DotAccessData\Data;
@ -17,21 +15,18 @@ class PengunjungController extends Controller
// PENGUNJUNG // PENGUNJUNG
public function home() public function home()
{ {
$landingpage = DataKursus::withCount('kunjungan') // Menghitung jumlah kunjungan tanpa filter waktu // Ambil 3 data yang populer dari tabel DataKursus
->orderByDesc('kunjungan_count') // Mengurutkan berdasarkan jumlah kunjungan terbanyak $landingpage = DataKursus::where('popular', 'Popular')
->limit(3) // Mengambil 4 kursus terpopuler ->limit(3)
->get(); ->get();
// Potong deskripsi agar hanya terdiri dari 22 kata // Potong deskripsi agar hanya terdiri dari 22 kata
foreach ($landingpage as $item) { foreach ($landingpage as $item) {
$item->deskripsi = \Illuminate\Support\Str::words($item->deskripsi, 22, '...'); $item->deskripsi = \Illuminate\Support\Str::words($item->deskripsi, 22, '...');
} }
$peta = DataKursus::with('kategoris')->get();
// Kembalikan view dengan data yang sudah diproses // Kembalikan view dengan data yang sudah diproses
return view('user.home', compact('landingpage', 'peta')); return view('user.home', compact('landingpage'));
} }
@ -53,8 +48,7 @@ public function kursus(Request $request)
} }
// Ambil data kursus secara acak dengan kategori // Ambil data kursus secara acak dengan kategori
$data_kursus = $query->with('kategoris')->paginate(12); $data_kursus = $query->with('kategoris')->inRandomOrder()->paginate(10);
// Ambil daftar kategori untuk dropdown // Ambil daftar kategori untuk dropdown
$kategori = DataKategori::all(); $kategori = DataKategori::all();
@ -84,44 +78,20 @@ public function maps()
public function detail(string $id) public function detail(string $id)
{ {
// Cek apakah sudah ada ID perangkat dalam cookie
$deviceId = request()->cookie('device_id');
if (!$deviceId) {
// Jika tidak ada, buat ID baru dan simpan dalam cookie
$deviceId = Str::uuid()->toString();
cookie()->queue('device_id', $deviceId, 60 * 24 * 365); // Simpan selama setahun
}
// Cek apakah deviceId sudah ada pada kursus_id yang sama pada hari yang sama
$existingVisit = Kunjungan::where('device_id', $deviceId)
->where('kursus_id', $id) // Cek apakah sudah ada kunjungan untuk kursus_id yang sama
->whereDate('created_at', today()) // Cek apakah ada kunjungan pada hari yang sama
->exists();
if (!$existingVisit) {
// Simpan kunjungan jika belum ada kunjungan dengan deviceId dan kursus_id yang sama pada hari ini
Kunjungan::create([
'device_id' => $deviceId,
'kursus_id' => $id,
]);
}
// Ambil data kursus beserta ulasan dan kategorinya // Ambil data kursus beserta ulasan dan kategorinya
$data = DataKursus::with('kategoris', 'ulasan')->find($id); $data = DataKursus::with('kategoris', 'ulasan')->find($id);
$data->fasilitas = json_decode($data->fasilitas, true);
if (!$data) { if (!$data) {
abort(404, 'Kursus tidak ditemukan'); abort(404, 'Kursus tidak ditemukan');
} }
// Ambil data ulasan terkait, urutkan berdasarkan created_at terbaru // Ambil data ulasan terkait, urutkan berdasarkan created_at terbaru
$imageNames = json_decode($data->img_konten, true); $imageNames = json_decode($data->img_konten, true);
$ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3); $ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3); // Membatasi hanya 3 ulasan per halaman, urutan terbaru
// Hitung rata-rata rating // Hitung rata-rata rating
$averageRating = $ulasan->avg('rating'); $averageRating = $ulasan->avg('rating'); // Mengambil rata-rata rating
$totalRatings = $ulasan->count(); $totalRatings = $ulasan->count(); // Menghitung total jumlah ulasan
// Kirim data ke view // Kirim data ke view
return view('user.detailKursus', compact('data', 'imageNames', 'ulasan', 'averageRating', 'totalRatings')); return view('user.detailKursus', compact('data', 'imageNames', 'ulasan', 'averageRating', 'totalRatings'));
@ -132,9 +102,6 @@ public function detail(string $id)
public function rute(string $id) public function rute(string $id)
{ {
// Ambil kursus berdasarkan ID // Ambil kursus berdasarkan ID

View File

@ -20,7 +20,7 @@ public function handle($request, Closure $next, $role)
return $next($request); return $next($request);
} }
// Redirect kembali ke halaman sebelumnya dengan pesan error // Redirect jika tidak memiliki akses
return back()->with('error', 'You do not have access to this page.'); return redirect()->route('gagal.home')->with('error', 'You do not have access to this page.');
} }
} }

View File

@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use App\Models\Kunjungan;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -26,9 +25,7 @@ class DataKursus extends Model
'latitude', 'latitude',
'longitude', // Pastikan nama kolom sesuai dengan migrasi 'longitude', // Pastikan nama kolom sesuai dengan migrasi
'popular', // Pastikan nama kolom sesuai dengan migrasi 'popular', // Pastikan nama kolom sesuai dengan migrasi
'img_konten', 'img_konten'
'user_id'
]; ];
public $timestamps = true; public $timestamps = true;
@ -37,18 +34,8 @@ public function kategoris(): BelongsTo
{ {
return $this->belongsTo(DataKategori::class, 'kategori_id', 'id'); // Menentukan foreign key dan local key return $this->belongsTo(DataKategori::class, 'kategori_id', 'id'); // Menentukan foreign key dan local key
} }
public function kunjungan(): HasMany
{
return $this->hasMany(Kunjungan::class, 'kursus_id', 'id'); // Menentukan foreign key dan local key
}
public function ulasan(): HasMany public function ulasan(): HasMany
{ {
return $this->hasMany(DataUlasan::class, 'kursus_id', 'id'); // Menentukan foreign key dan local key return $this->hasMany(DataUlasan::class, 'kursus_id', 'id'); // Menentukan foreign key dan local key
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id', 'id'); // Menentukan foreign key dan local key
}
} }

View File

@ -1,21 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Kunjungan extends Model
{
use HasFactory;
protected $table = 'kunjungan';
protected $fillable = ['device_id', 'kursus_id'];
// Relasi ke Kursus
public function kursuses(): BelongsTo
{
return $this->belongsTo(DataKursus::class, 'kursus_id', 'id');
}
}

View File

@ -4,11 +4,10 @@
// use Illuminate\Contracts\Auth\MustVerifyEmail; // use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Laravel\Sanctum\HasApiTokens; use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
@ -25,7 +24,6 @@ class User extends Authenticatable implements MustVerifyEmail
protected $fillable = [ protected $fillable = [
'name', 'name',
'email', 'email',
'username',
'password', 'password',
'role' 'role'
]; ];
@ -33,10 +31,6 @@ public function ulasans(): HasMany
{ {
return $this->hasMany(DataUlasan::class, 'user_id', 'id'); // Menentukan foreign key dan local key return $this->hasMany(DataUlasan::class, 'user_id', 'id'); // Menentukan foreign key dan local key
} }
public function users(): HasMany
{
return $this->hasMany(User::class, 'user_id', 'id'); // Menentukan foreign key dan local key
}
/** /**
* The attributes that should be hidden for serialization. * The attributes that should be hidden for serialization.

View File

@ -2,8 +2,6 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
@ -19,8 +17,8 @@ public function register(): void
/** /**
* Bootstrap any application services. * Bootstrap any application services.
*/ */
public function boot() public function boot(): void
{ {
App::setLocale(Session::get('locale', 'id')); // Default ke Bahasa Indonesia //
} }
} }

View File

@ -9,8 +9,7 @@
"guzzlehttp/guzzle": "^7.2", "guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0", "laravel/framework": "^10.0",
"laravel/sanctum": "^3.2", "laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8", "laravel/tinker": "^2.8"
"laravolt/indonesia": "^0.36.0"
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",

84
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "08dbb25675a803a24f2b8a6421dd5c41", "content-hash": "85309d4524da1baae35ac151622b248f",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@ -1512,88 +1512,6 @@
}, },
"time": "2024-09-23T13:32:56+00:00" "time": "2024-09-23T13:32:56+00:00"
}, },
{
"name": "laravolt/indonesia",
"version": "v0.36",
"source": {
"type": "git",
"url": "https://github.com/laravolt/indonesia.git",
"reference": "f1499a4cecf83b6f09a40a61aff084f7445bee4c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravolt/indonesia/zipball/f1499a4cecf83b6f09a40a61aff084f7445bee4c",
"reference": "f1499a4cecf83b6f09a40a61aff084f7445bee4c",
"shasum": ""
},
"require": {
"illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0",
"php": "^7.3|^8.0"
},
"require-dev": {
"orchestra/testbench": "^6.0|^7.0|^8.0|^9.0|^10.0",
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^9.0|^10.5|^11.5.3"
},
"suggest": {
"laravolt/suitable": "Required if you want to access editor panel",
"spatie/geocoder": "Synchronize latitude longitude data directly using Google's Geocoding Service"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"Indonesia": "Laravolt\\Indonesia\\Facade"
},
"providers": [
"Laravolt\\Indonesia\\ServiceProvider"
]
},
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Laravolt\\Indonesia\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bayu Hendra Winata",
"email": "bayu.hendra@javan.co.id"
},
{
"name": "Akbar Adhatama",
"email": "am.adhatama@gmail.com"
},
{
"name": "Deri Ramdani",
"email": "deri.ramdani1@gmail.com"
}
],
"description": "Package Laravel yang berisi data Provinsi, Kabupaten/Kota, Kecamatan, dan Keluarahan/Desa di seluruh Indonesia.",
"keywords": [
"desa",
"indonesia",
"kabupaten",
"kecamatan",
"kelurahan",
"kota",
"laravel",
"laravolt",
"provinsi"
],
"support": {
"issues": "https://github.com/laravolt/indonesia/issues",
"source": "https://github.com/laravolt/indonesia/tree/v0.36"
},
"time": "2025-02-28T12:19:57+00:00"
},
{ {
"name": "league/commonmark", "name": "league/commonmark",
"version": "2.6.1", "version": "2.6.1",

View File

@ -82,7 +82,7 @@
| |
*/ */
'locale' => 'id', 'locale' => 'en',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -15,12 +15,15 @@ public function definition()
return [ return [
'kategori_id' => DataKategori::factory(), // Relasi dengan kategori 'kategori_id' => DataKategori::factory(), // Relasi dengan kategori
'nama_kursus' => $this->faker->sentence(3), // Nama kursus random 'nama_kursus' => $this->faker->sentence(3), // Nama kursus random
'img' => $this->faker->imageUrl(640, 480, 'education', true, 'kursus'), // Gambar kursus random
'deskripsi' => $this->faker->paragraph(), // Deskripsi kursus random 'deskripsi' => $this->faker->paragraph(), // Deskripsi kursus random
'paket' => $this->faker->word(), // Paket kursus random 'paket' => $this->faker->word(), // Paket kursus random
'metode' => $this->faker->randomElement(['Online', 'Offline', 'Hybrid']), // Metode random 'metode' => $this->faker->randomElement(['Online', 'Offline', 'Hybrid']), // Metode random
'fasilitas' => $this->faker->sentence(), // Fasilitas random
'lokasi' => $this->faker->address(), // Lokasi random 'lokasi' => $this->faker->address(), // Lokasi random
'latitude' => $this->faker->latitude(-90, 90), // Latitude random 'latitude' => $this->faker->latitude(-90, 90), // Latitude random
'longitude' => $this->faker->longitude(-180, 180), // Longitude random 'longitude' => $this->faker->longitude(-180, 180), // Longitude random
'popular' => $this->faker->boolean(), // True/false untuk popular
]; ];
} }
} }

View File

@ -16,9 +16,8 @@ public function up(): void
$table->id(); $table->id();
$table->string('name'); $table->string('name');
$table->string('email')->unique(); $table->string('email')->unique();
$table->string('username')->unique();
$table->timestamp('email_verified_at')->nullable(); $table->timestamp('email_verified_at')->nullable();
$table->enum('role', ['admin', 'user', 'pengunjung'])->default('pengunjung')->index(); // Tambahkan index $table->enum('role', ['admin', 'pengunjung'])->default('pengunjung')->index(); // Tambahkan index
$table->string('password'); $table->string('password');
$table->rememberToken(); $table->rememberToken();
$table->timestamps(); $table->timestamps();

View File

@ -18,22 +18,18 @@ public function up()
$table->longText('deskripsi'); $table->longText('deskripsi');
$table->longText('paket'); $table->longText('paket');
$table->longText('metode'); $table->longText('metode');
$table->text('fasilitas');
$table->longText('lokasi'); $table->longText('lokasi');
$table->json('fasilitas')->nullable(); $table->string('latitude');
$table->string('latitude')->nullable(); $table->string('longitude');
$table->string('longitude')->nullable(); $table->string('popular');
$table->json('img_konten')->nullable(); $table->json('img_konten')->nullable();
$table->timestamps(); $table->timestamps();
$table->foreignId('user_id')
->nullable() // Membuat kolom ini bisa NULL
->constrained('users') // Nama tabel yang dijadikan referensi
->onDelete('restrict') // Aturan saat data dihapus
->onUpdate('cascade'); // Aturan saat data diupdate
$table->foreignId('kategori_id') $table->foreignId('kategori_id')
->nullable() // Membuat kolom ini bisa NULL ->nullable() // Membuat kolom ini bisa NULL
->constrained('kategori') // Nama tabel yang dijadikan referensi ->constrained('kategori') // Nama tabel yang dijadikan referensi
->onDelete('restrict') // Aturan saat data dihapus ->onDelete('set null') // Aturan saat data dihapus
->onUpdate('cascade'); // Aturan saat data diupdate ->onUpdate('cascade'); // Aturan saat data diupdate
}); });
} }

View File

@ -17,18 +17,17 @@ public function up()
$table->text('comment')->nullable(); $table->text('comment')->nullable();
$table->timestamps(); $table->timestamps();
// Foreign key constraint untuk kursus_id // Foreign key constraint
$table->foreignId('kursus_id') $table->foreignId('kursus_id')
->nullable() // Membuat kolom ini bisa NULL ->nullable() // Membuat kolom ini bisa NULL
->constrained('data_kursus') // Mengarah ke tabel kursus, bukan kategori ->constrained('kategori') // Nama tabel yang dijadikan referensi
->onDelete('cascade') // Aturan saat data dihapus, akan menghapus ulasan terkait ->onDelete('set null') // Aturan saat data dihapus
->onUpdate('cascade'); // Aturan saat data diupdate ->onUpdate('cascade'); // Aturan saat data diupdate
// Foreign key constraint untuk user_id
$table->foreignId('user_id') $table->foreignId('user_id')
->nullable() // Membuat kolom ini bisa NULL ->nullable() // Membuat kolom ini bisa NULL
->constrained('users') // Nama tabel yang dijadikan referensi ->constrained('users') // Nama tabel yang dijadikan referensi
->onDelete('cascade') // Aturan saat data dihapus, akan menghapus ulasan terkait ->onDelete('set null') // Aturan saat data dihapus
->onUpdate('cascade'); // Aturan saat data diupdate ->onUpdate('cascade'); // Aturan saat data diupdate
}); });
} }

View File

@ -1,32 +0,0 @@
<?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('kunjungan', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('device_id'); // Bisa menyimpan IPv4 (15 char) atau IPv6 (45 char)
$table->timestamps();
// Foreign key constraint
$table->foreignId('kursus_id')
->nullable()
->constrained('data_kursus')
->onDelete('cascade') // Hapus kunjungan jika kursus dihapus
->onUpdate('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('kunjungan');
}
};

View File

@ -15,43 +15,27 @@ class DatabaseSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
// User::create([
// 'name' => 'Salma Admin',
// 'email' => 'salma@gmail.com',
// 'username' => 'salma',
// 'password' => bcrypt('salma281103'), // Ganti dengan password pilihan Anda
// 'role' => 'admin',
// ]);
User::create([ User::create([
'name' => 'Admin', 'name' => 'Salma Admin',
'email' => 'admin@gmail.com', 'email' => 'salma@gmail.com',
'username' => 'admin', 'password' => bcrypt('salma281103'), // Ganti dengan password pilihan Anda
'password' => bcrypt('admin123'), // Ganti dengan password pilihan Anda
'role' => 'admin', 'role' => 'admin',
]); ]);
User::create([ DataKategori::insert([
'name' => 'User', ['nama_kategori' => 'Speaking'],
'email' => 'user@gmail.com', ['nama_kategori' => 'Reading'],
'username' => 'user', ['nama_kategori' => 'Good Looking'],
'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda ['nama_kategori' => 'Good Evening'],
'role' => 'user',
]); ]);
User::create([
'name' => 'pengunjung',
'username' => 'pengunjung',
'email' => 'pengunjung@gmail.com',
'password' => bcrypt('pengunjung123'), // Ganti dengan password pilihan Anda
'role' => 'pengunjung',
]);
// DataKategori::insert([
// ['nama_kategori' => 'Speaking'],
// ['nama_kategori' => 'Reading'],
// ['nama_kategori' => 'Good Looking'],
// ['nama_kategori' => 'Good Evening'],
// ]);
// // // Buat 3 kategori, setiap kategori memiliki banyak kursus // User::create([
// // // Buat 3 kategori // 'name' => 'user',
// 'email' => 'user@gmail.com',
// 'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda
// 'role' => 'pengunjung',
// ]);
// // Buat 3 kategori, setiap kategori memiliki banyak kursus
// // Buat 3 kategori
// $kategoris = DataKategori::factory(3)->create(); // $kategoris = DataKategori::factory(3)->create();
// // Buat kursus hingga total 20 data // // Buat kursus hingga total 20 data

9218
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,8 +9,7 @@
"alpinejs": "^3.4.2", "alpinejs": "^3.4.2",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"axios": "^1.1.2", "axios": "^1.1.2",
"flowbite": "^3.1.2", "flowbite": "^3.0.0",
"laravel-mix": "^6.0.49",
"laravel-vite-plugin": "^0.7.2", "laravel-vite-plugin": "^0.7.2",
"postcss": "^8.5.1", "postcss": "^8.5.1",
"tailwindcss": "^3.4.17", "tailwindcss": "^3.4.17",

View File

@ -1,271 +0,0 @@
.pacifico-regular {
font-family: "Pacifico", cursive;
font-weight: 400;
font-style: normal;
}
.archivo-black-regular {
font-family: "Archivo Black", sans-serif;
font-weight: 400;
font-style: normal;
}
.archivo-uniquifier {
font-family: "Archivo", sans-serif;
font-optical-sizing: auto;
font-weight: weight;
font-style: normal;
font-variation-settings: "wdth" 100;
}
.rubik-mono-one-regular {
font-family: "Rubik Mono One", monospace;
font-weight: 400;
font-style: normal;
}
.playfair-display-uniquifier {
font-family: "Playfair Display", serif;
font-optical-sizing: auto;
font-weight: weight;
font-style: normal;
}
.dm-sans {
font-family: "DM Sans", serif;
font-optical-sizing: auto;
font-weight: weight;
font-style: normal;
}
.castoro-regular {
font-family: "Castoro", serif;
font-weight: 400;
font-style: normal;
}
.castoro-regular-italic {
font-family: "Castoro", serif;
font-weight: 400;
font-style: italic;
}
.poppins-thin {
font-family: "Poppins", serif;
font-weight: 100;
font-style: normal;
}
.poppins-extralight {
font-family: "Poppins", serif;
font-weight: 200;
font-style: normal;
}
.poppins-light {
font-family: "Poppins", serif;
font-weight: 300;
font-style: normal;
}
.poppins-regular {
font-family: "Poppins", serif;
font-weight: 400;
font-style: normal;
}
.poppins-medium {
font-family: "Poppins", serif;
font-weight: 500;
font-style: normal;
}
.poppins-semibold {
font-family: "Poppins", serif;
font-weight: 600;
font-style: normal;
}
.poppins-bold {
font-family: "Poppins", serif;
font-weight: 700;
font-style: normal;
}
.poppins-extrabold {
font-family: "Poppins", serif;
font-weight: 800;
font-style: normal;
}
.poppins-black {
font-family: "Poppins", serif;
font-weight: 900;
font-style: normal;
}
.poppins-thin-italic {
font-family: "Poppins", serif;
font-weight: 100;
font-style: italic;
}
.poppins-extralight-italic {
font-family: "Poppins", serif;
font-weight: 200;
font-style: italic;
}
.poppins-light-italic {
font-family: "Poppins", serif;
font-weight: 300;
font-style: italic;
}
.poppins-regular-italic {
font-family: "Poppins", serif;
font-weight: 400;
font-style: italic;
}
.poppins-medium-italic {
font-family: "Poppins", serif;
font-weight: 500;
font-style: italic;
}
.poppins-semibold-italic {
font-family: "Poppins", serif;
font-weight: 600;
font-style: italic;
}
.poppins-bold-italic {
font-family: "Poppins", serif;
font-weight: 700;
font-style: italic;
}
.poppins-extrabold-italic {
font-family: "Poppins", serif;
font-weight: 800;
font-style: italic;
}
.poppins-black-italic {
font-family: "Poppins", serif;
font-weight: 900;
font-style: italic;
}
.bebas-neue-regular {
font-family: "Bebas Neue", sans-serif;
font-weight: 400;
font-style: normal;
}
.barlow-condensed-thin {
font-family: "Barlow Condensed", sans-serif;
font-weight: 100;
font-style: normal;
}
.barlow-condensed-extralight {
font-family: "Barlow Condensed", sans-serif;
font-weight: 200;
font-style: normal;
}
.barlow-condensed-light {
font-family: "Barlow Condensed", sans-serif;
font-weight: 300;
font-style: normal;
}
.barlow-condensed-regular {
font-family: "Barlow Condensed", sans-serif;
font-weight: 400;
font-style: normal;
}
.barlow-condensed-medium {
font-family: "Barlow Condensed", sans-serif;
font-weight: 500;
font-style: normal;
}
.barlow-condensed-semibold {
font-family: "Barlow Condensed", sans-serif;
font-weight: 600;
font-style: normal;
}
.barlow-condensed-bold {
font-family: "Barlow Condensed", sans-serif;
font-weight: 700;
font-style: normal;
}
.barlow-condensed-extrabold {
font-family: "Barlow Condensed", sans-serif;
font-weight: 800;
font-style: normal;
}
.barlow-condensed-black {
font-family: "Barlow Condensed", sans-serif;
font-weight: 900;
font-style: normal;
}
.barlow-condensed-thin-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 100;
font-style: italic;
}
.barlow-condensed-extralight-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 200;
font-style: italic;
}
.barlow-condensed-light-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 300;
font-style: italic;
}
.barlow-condensed-regular-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 400;
font-style: italic;
}
.barlow-condensed-medium-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 500;
font-style: italic;
}
.barlow-condensed-semibold-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 600;
font-style: italic;
}
.barlow-condensed-bold-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 700;
font-style: italic;
}
.barlow-condensed-extrabold-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 800;
font-style: italic;
}
.barlow-condensed-black-italic {
font-family: "Barlow Condensed", sans-serif;
font-weight: 900;
font-style: italic;
}

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

2
public/storage/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -1,280 +0,0 @@
<x-adminlayout>
<div class="px-10">
<div class="py-10 md:px-0 px-4">
<div class="flex justify-end items-center pb-4 ">
<button data-modal-target="default-modal-tambah-users" data-modal-toggle="default-modal-tambah-users"
class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-md shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular"
href="{{ route('kategori.create') }}">Tambah Data</button>
</div>
<div class="flex justify-end items-center pb-4 w-full">
<form class="max-w-lg w-full" method="GET" action="{{ route('user.index') }}">
<div class="flex">
<select name="role" id="role"
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-300 rounded-s-lg hover:bg-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100">
<option value="" selected>All Roles</option>
<option value="user" {{ request('role') == 'user' ? 'selected' : '' }}>User</option>
<option value="pengunjung" {{ request('role') == 'pengunjung' ? 'selected' : '' }}>
Pengunjung</option>
</select>
<div class="relative w-full">
<input type="search" name="search" value="{{ request('search') }}"
class="block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-e-lg border-s-gray-50 border-s-2 border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Search users..." />
<button type="submit"
class="absolute top-0 end-0 p-2.5 text-sm font-medium h-full text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-e-lg border border-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search</span>
</button>
</div>
</div>
</form>
</div>
{{ $user->links() }}
<div class="relative overflow-x-auto sm:rounded-lg">
<table class="w-full text-sm text-gray-700 shadow-md border border-gray-300 rounded-lg overflow-hidden">
<thead class="text-xs uppercase bg-gray-100 border-b border-gray-300">
<tr>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">No</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Nama</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Email</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Role</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Terdaftar</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Diperbarui</th>
<th scope="col" class="py-3 px-4 text-end">Aksi</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-300">
@foreach ($user as $no => $index)
<tr class="odd:bg-white even:bg-gray-50 hover:bg-gray-200 transition">
<th scope="row"
class="py-4 px-4 font-medium text-gray-900 text-end border-r border-gray-300">
{{ ($user->currentPage() - 1) * $user->perPage() + $no + 1 }}
</th>
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $index->name }}
</td>
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $index->email }}
</td>
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $index->role }}
</td>
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $index->created_at }}
</td>
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $index->updated_at }}
</td>
<td class="py-4 px-4 text-end">
<div class="flex justify-end space-x-2">
<!-- Tombol Edit -->
<button data-modal-target="modal-edit-users-{{ $index->id }}"
data-modal-toggle="modal-edit-users-{{ $index->id }}"
class="font-extrabold text-xs shadow-md hover:bg-green-700 text-white py-2 px-2 bg-green-600 rounded-lg transition">
<i class="fas fa-edit text-xs"></i>
</button>
<!-- Tombol Hapus -->
<button data-modal-target="modal-delete-user-{{ $index->id }}"
data-modal-toggle="modal-delete-user-{{ $index->id }}"
class="font-extrabold text-xs shadow-md hover:bg-red-700 text-white py-2 px-2 bg-red-600 rounded-lg transition">
<i class="fas fa-trash text-xs"></i>
</button>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="py-4">
{{ $user->links() }}
</div>
</div>
</div>
<!-- Modal Tambah Kategoris -->
<div id="default-modal-tambah-users" data-modal-backdrop="static" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white rounded-lg shadow ">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t ">
<h3 class="text-xl font-semibold text-gray-900 ">
Tambah User
</h3>
<button type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center "
data-modal-hide="default-modal-tambah-users">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<form action="{{ route('user.store') }}" method="POST">
@csrf
<div class="p-4 items-center">
<label for="name" class="block text-gray-700 font-bold mb-1">Nama</label>
<input type="text" id="name" name="name"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Nama" required autocomplete="off">
</div>
<div class="p-4 items-center">
<label for="email" class="block text-gray-700 font-bold mb-1">Email</label>
<input type="email" id="email" name="email"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Email" required autocomplete="off">
</div>
<div class="p-4 items-center">
<label for="Username" class="block text-gray-700 font-bold mb-1">Username</label>
<input type="Username" id="Username" name="username"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Username" required autocomplete="off">
</div>
<div class="p-4 items-center">
<label for="password" class="block text-gray-700 font-bold mb-1">Password</label>
<input type="password" id="password" name="password"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Password" required autocomplete="off">
</div>
<div class="p-4 items-center">
<label for="verif_password" class="block text-gray-700 font-bold mb-1">Verifikasi
Password</label>
<input type="password" id="verif_password" name="verif_password"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Ulang Password" required autocomplete="off">
</div>
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b ">
<button type="submit"
class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-md shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular">
Tambah
</button>
<button type="button" onclick="history.back();"
class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700">
Batal
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Modal EDIT Kategori -->
@foreach ($user as $index)
<div id="modal-edit-users-{{ $index->id }}" data-modal-backdrop="static" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white rounded-lg shadow ">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t ">
<h3 class="text-xl font-semibold text-gray-900 ">
Edit User
</h3>
<button type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center "
data-modal-hide="modal-edit-users-{{ $index->id }}">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<form id="edit-user-form" method="POST" action="{{ route('user.update', $index->id) }}">
@csrf <!-- Token CSRF -->
@method('PUT') <!-- Menggunakan metode PUT -->
<input hidden value="{{ $index->id }}" type="text" id="edit-idkategori" name="id" required>
<div class="px-4 pb-4 items-center">
<label for="Name" class="block mt-4 text-gray-700 font-bold mb-1">Nama</label>
<input type="text" id="edit-nama" name="name" value="{{ $index->name }}"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan user" required required required autocomplete="off">
</div>
<div class="px-4 pb-4 items-center">
<label for="email" class="block mt-4 text-gray-700 font-bold mb-1">Email</label>
<input type="text" id="edit-nama" name="email" value="{{ $index->email }}"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan user" required required required autocomplete="off">
</div>
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b ">
<button type="submit"
class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-md shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular">
Update
</button>
<button data-modal-hiden="modal-edit-users-{{ $index->id }}" type="button"
class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 ">
Batal
</button>
</div>
</form>
</div>
</div>
</div>
@endforeach
{{-- Modal DELETE Kategori --}}
@foreach ($user as $index)
<div id="modal-delete-user-{{ $index->id }}" data-modal-backdrop="static" tabindex="-1"
class="hidden fixed inset-0 z-50 items-center justify-center bg-black bg-opacity-50">
<div class="relative p-4 w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow ">
<button type="button" data-modal-hide="modal-delete-user-{{ $index->id }}"
class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center "
id="close-modal">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Close modal</span>
</button>
<div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 " aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
<h3 class="mb-5 text-lg font-normal text-gray-500 ">Anda yakin ingin
menghapus?</h3>
<div class="flex justify-center">
<form id="delete-user" method="POST" action="{{ route('user.destroy', $index->id) }}">
@csrf <!-- Token CSRF -->
@method('DELETE') <!-- Menggunakan metode DELETE -->
<button type="submit"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
Ya, Saya Yakin
</button>
</form>
<button type="button" id="cancel-logout" data-modal-hide="modal-delete-user-{{ $index->id }}"
class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 ">
Tidak, Batal
</button>
</div>
</div>
</div>
</div>
</div>
@endforeach
</x-adminlayout>

View File

@ -4,7 +4,7 @@
<!-- Bagian atas menampilkan satu gambar secara acak --> <!-- Bagian atas menampilkan satu gambar secara acak -->
<div class="relative"> <div class="relative">
<div class="flex m-auto justify-center items-center responsive-container"> <div class="flex m-auto justify-center items-center responsive-container">
<img src="{{ asset('img/bg-home.jpg') }}" class="w-full h-full" alt=""> <img src="{{ asset('img/Rectangle 227.png') }}" class="w-full h-full" alt="">
</div> </div>
</div> </div>

View File

@ -1,76 +1,64 @@
<x-adminlayout> <x-adminlayout>
<div class="px-10"> <div class="container">
<div class="py-10 md:px-0 px-4"> <div class="py-10 md:px-0 px-4">
<div class="flex justify-end items-center pb-4 "> <div class="flex justify-end items-center pb-4 ">
<button data-modal-target="default-modal-tambah-kategori" <button data-modal-target="default-modal-tambah-kategori"
data-modal-toggle="default-modal-tambah-kategori" data-modal-toggle="default-modal-tambah-kategori"
class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-md shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular" class="bg-[#4F7F81] py-2 px-4 rounded-xl shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-xs font-bold"
href="{{ route('kategori.create') }}">Tambah Data</button> href="{{ route('kategori.create') }}">Tambah Data</button>
</div> </div>
<div class="flex justify-end items-center pb-4 ">
<form class="max-w-lg w-full" method="GET" action="{{ route('kategori.index') }}">
<div
class="relative w-full overflow-hidden rounded-lg border border-gray-300 focus-within:ring-2 focus-within:ring-blue-500">
<input type="search" name="search" value="{{ request('search') }}"
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 border-none focus:ring-0"
placeholder="Search Kategori..." />
<button type="submit"
class="absolute top-0 end-0 p-2.5 h-full text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] hover:bg-green-800 focus:ring-2 focus:ring-blue-300">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search</span>
</button>
</div>
</form>
</div>
{{ $kategori->links() }} {{ $kategori->links() }}
<div class="relative overflow-x-auto sm:rounded-lg poppins-regular">
<table class="w-full text-sm text-gray-700 shadow-md border border-gray-300 rounded-lg overflow-hidden"> <div class="relative overflow-x-auto sm:rounded-lg">
<thead class="text-xs uppercase bg-gray-100 border-b border-gray-300"> <table class="w-full text-sm text-end rtl:text-right shadow-gray-600 text-gray-500">
<thead class="text-xs text-gray-700 uppercase shadow-gray-600 bg-gray-50 pb-4">
<tr> <tr>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">No</th> <th scope="col" class=" py-3 text-end">No</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Nama Kategori</th> <!-- Menambahkan text-end untuk penataan -->
<th scope="col" class="py-3 px-4 text-end">Aksi</th> <th scope="col" class=" py-3 text-end">Nama Kategori</th>
<!-- Menambahkan text-end untuk penataan -->
<th scope="col" class=" py-3 text-end">Aksi</th>
<!-- Menambahkan text-end untuk penataan -->
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-300"> <tbody class="shadow-gray-600">
@foreach ($kategori as $index => $kategoris) @foreach ($kategori as $index => $kategoris)
<tr class="odd:bg-white even:bg-gray-50 hover:bg-gray-200 transition"> <tr class="odd:bg-white even:bg-gray-50 shadow-gray-600 ">
<th scope="row" <th scope="row" class=" py-4 font-medium text-gray-900 text-end">
class="py-4 px-4 font-medium text-gray-900 text-end border-r border-gray-300"> <!-- Menambahkan text-end untuk penataan -->
{{ ($kategori->currentPage() - 1) * $kategori->perPage() + $index + 1 }} <p class="m-auto space-x-2 flex justify-end">
{{ ($kategori->currentPage() - 1) * $kategori->perPage() + $index + 1 }}
</p>
</th> </th>
<td class="py-4 px-4 text-end border-r border-gray-300"> <td class=" py-4 text-end">
{{ $kategoris->nama_kategori }} {{ $kategoris->nama_kategori }}
</td> </td>
<td class="py-4 px-4 text-end"> <td class=" py-4 text-end">
<div class="flex justify-end space-x-2"> <!-- Menambahkan text-end untuk penataan -->
<div class="flex justify-end space-x-4"> <!-- Menyusun ikon sejajar -->
<!-- Tombol Edit --> <!-- Tombol Edit -->
<button data-modal-target="default-modal-edit-kategori{{ $kategoris->id }}" <button data-modal-target="default-modal-edit-kategori{{ $kategoris->id }}"
data-modal-toggle="default-modal-edit-kategori{{ $kategoris->id }}" data-modal-toggle="default-modal-edit-kategori{{ $kategoris->id }}"
class="font-extrabold text-xs shadow-md hover:bg-green-700 text-white py-2 px-2 bg-green-600 rounded-lg transition"> class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white py-2 px-2 bg-[#4F7F81] rounded-lg h-fit">
<i class="fas fa-edit text-xs"></i> <i class="fas fa-edit text-xs"></i> <!-- Icon Edit -->
</button> </button>
<!-- Tombol Hapus --> <!-- Tombol Hapus -->
<button data-modal-target="default-modal-delete-kategori{{ $kategoris->id }}" <button data-modal-target="default-modal-delete-kategori{{ $kategoris->id }}"
data-modal-toggle="default-modal-delete-kategori{{ $kategoris->id }}" data-modal-toggle="default-modal-delete-kategori{{ $kategoris->id }}"
class="font-extrabold text-xs shadow-md hover:bg-red-700 text-white py-2 px-2 bg-red-600 rounded-lg transition"> class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white py-2 px-2 bg-[#4F7F81] rounded-lg h-fit">
<i class="fas fa-trash text-xs"></i> <i class="fas fa-trash text-xs"></i> <!-- Icon Hapus -->
</button> </button>
</div> </div>
</td> </td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="py-4"> <div class="py-4">
@ -84,13 +72,13 @@ class="font-extrabold text-xs shadow-md hover:bg-red-700 text-white py-2 px-2 bg
<div id="default-modal-tambah-kategori" tabindex="-1" aria-hidden="true" <div id="default-modal-tambah-kategori" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"> class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full"> <div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white rounded-lg shadow "> <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t "> <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
<h3 class="text-xl poppins-regular text-green-800 "> <h3 class="text-xl font-semibold text-gray-900 dark:text-white">
Tambahkan Kategori Tambahkan Kategori
</h3> </h3>
<button type="button" <button type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center " class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="default-modal-tambah-kategori"> data-modal-hide="default-modal-tambah-kategori">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14"> viewBox="0 0 14 14">
@ -103,19 +91,19 @@ class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounde
<form action="{{ route('kategori.store') }}" method="POST"> <form action="{{ route('kategori.store') }}" method="POST">
@csrf @csrf
<div class="p-4 items-center"> <div class="p-4 items-center">
<label for="nama_kategori" class="block text-gray-700 poppins-regular mb-1">Kategori</label> <label for="nama_kategori" class="block text-gray-700 font-bold mb-1">Kategori</label>
<input type="text" id="nama_kategori" name="nama_kategori" <input type="text" id="nama_kategori" name="nama_kategori"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300" class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Kategori" required required autocomplete="off"> placeholder="Masukkan Kategori" required required autocomplete="off">
</div> </div>
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b "> <div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
<button type="submit" <button type="submit"
class="text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg text-sm poppins-regular px-5 py-2.5 text-end "> class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-end dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
Tambah Tambah
</button> </button>
<button data-modal-hide="default-modal-tambah-kategori" type="button" <button data-modal-hide="default-modal-tambah-kategori" type="button"
class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-green-800 focus:z-10 focus:ring-4 focus:ring-gray-100 "> class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
Batal Batal
</button> </button>
</div> </div>
@ -128,16 +116,16 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
<div id="default-modal-edit-kategori{{ $kategoris->id }}" tabindex="-1" aria-hidden="true" <div id="default-modal-edit-kategori{{ $kategoris->id }}" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"> class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl max-h-full"> <div class="relative p-4 w-full max-w-2xl max-h-full">
<div class="relative bg-white rounded-lg shadow "> <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t "> <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
<h3 class="text-xl poppins-regular text-gray-900 "> <h3 class="text-xl font-semibold text-gray-900 dark:text-white">
Edit Kategori Edit Kategori
</h3> </h3>
<button type="button" <button type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center " class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="default-modal-edit-kategori{{ $kategoris->id }}"> data-modal-hide="default-modal-edit-kategori{{ $kategoris->id }}">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
fill="none" viewBox="0 0 14 14"> viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" /> stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg> </svg>
@ -153,19 +141,20 @@ class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounde
<div class="px-4 pb-4 items-center"> <div class="px-4 pb-4 items-center">
<label for="detail_kategori" <label for="detail_kategori"
class="block mt-4 text-gray-700 poppins-regular mb-1">Kategori</label> class="block mt-4 text-gray-700 font-bold mb-1">Kategori</label>
<input type="text" id="edit-namaKategori" name="nama_kategori" <input type="text" id="edit-namaKategori" name="nama_kategori"
value="{{ $kategoris->nama_kategori }}" value="{{ $kategoris->nama_kategori }}"
class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300" class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-blue-300"
placeholder="Masukkan Kategori" required required required autocomplete="off"> placeholder="Masukkan Kategori" required required required autocomplete="off">
</div> </div>
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b "> <div
class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
<button type="submit" <button type="submit"
class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-md shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular"> class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
Update Update
</button> </button>
<button data-modal-hiden="default-modal-edit-kategori{{ $kategoris->id }}" type="button" <button data-modal-hiden="default-modal-edit-kategori{{ $kategoris->id }}" type="button"
class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 "> class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
Batal Batal
</button> </button>
</div> </div>
@ -180,9 +169,9 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
<div id="default-modal-delete-kategori{{ $kategoris->id }}" tabindex="-1" <div id="default-modal-delete-kategori{{ $kategoris->id }}" tabindex="-1"
class="hidden fixed inset-0 z-50 items-center justify-center bg-black bg-opacity-50"> class="hidden fixed inset-0 z-50 items-center justify-center bg-black bg-opacity-50">
<div class="relative p-4 w-full max-w-md max-h-full"> <div class="relative p-4 w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow "> <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<button type="button" data-modal-hide="default-modal-delete-kategori{{ $kategoris->id }}" <button type="button" data-modal-hide="default-modal-delete-kategori{{ $kategoris->id }}"
class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center " class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
id="close-modal"> id="close-modal">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14"> viewBox="0 0 14 14">
@ -192,12 +181,12 @@ class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hov
<span class="sr-only">Close modal</span> <span class="sr-only">Close modal</span>
</button> </button>
<div class="p-4 md:p-5 text-center"> <div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 " aria-hidden="true" <svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20"> xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg> </svg>
<h3 class="mb-5 text-lg poppins-regular text-gray-500 ">Anda yakin ingin <h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">Anda yakin ingin
menghapus?</h3> menghapus?</h3>
<div class="flex justify-center"> <div class="flex justify-center">
<form id="edit-kategori-form" method="POST" <form id="edit-kategori-form" method="POST"
@ -205,14 +194,14 @@ class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hov
@csrf <!-- Token CSRF --> @csrf <!-- Token CSRF -->
@method('DELETE') <!-- Menggunakan metode DELETE --> @method('DELETE') <!-- Menggunakan metode DELETE -->
<button type="submit" <button type="submit"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm poppins-regular inline-flex items-center px-5 py-2.5 text-center"> class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
Ya, Saya Yakin Ya, Saya Yakin
</button> </button>
</form> </form>
<button type="button" <button type="button"
id="cancel-logout"data-modal-hide="default-modal-delete-kategori{{ $kategoris->id }}" id="cancel-logout"data-modal-hide="default-modal-delete-kategori{{ $kategoris->id }}"
class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 "> class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
Tidak, Batal Tidak, Batal
</button> </button>
</div> </div>

View File

@ -1,142 +1,102 @@
<x-adminlayout> <x-adminlayout>
<div class="lg:px-10"> <div class="container">
<div class="py-10 px-4 md:px-0"> <div class="py-10 px-4 md:px-0">
<div class="flex justify-end items-center pb-4 "> <div class="flex justify-end items-center pb-4 ">
<a class="bg-gradient-to-tr from-[#60BC9D] to-[#12372A] py-2 px-4 rounded-xl shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-5x1 poppins-regular" <a class="bg-[#4F7F81] py-2 px-4 rounded-xl shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-xs font-bold"
href="{{ route('admin.create') }}">Tambah Data</a> href="{{ route('admin.create') }}">Tambah Data</a>
</div> </div>
<div class="flex justify-end items-center pb-4 ">
<form class="max-w-lg w-full" method="GET" action="{{ route('admin.dataKursus') }}">
<div class="flex">
<select name="role" id="role"
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-300 rounded-s-lg hover:bg-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100">
<option value="" {{ request('role') == '' ? 'selected' : '' }}>All Categories</option>
@foreach ($kategoriList as $kategori)
<option value="{{ $kategori->nama_kategori }}"
{{ request('role') == $kategori->nama_kategori ? 'selected' : '' }}>
{{ $kategori->nama_kategori }}
</option>
@endforeach
</select>
<div class="relative w-full">
<input type="search" name="search" value="{{ request('search') }}"
class="block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-e-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Search kursus..." />
<button type="submit"
class="absolute top-0 end-0 p-2.5 h-full text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-e-lg border border-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search</span>
</button>
</div>
</div>
</form>
</div>
{{ $courses->links() }} {{ $courses->links() }}
<div class="relative overflow-x-auto sm:rounded-lg"> <div class="relative overflow-x-auto sm:rounded-lg">
<table class="w-full text-sm text-gray-700 shadow-md border border-gray-300 rounded-lg overflow-hidden"> <table class="w-full text-sm text-right rtl:text-right shadow-gray-600 text-gray-500">
<thead class="text-xs uppercase bg-gray-100 border-b border-gray-300"> <thead class="text-xs text-gray-700 uppercase shadow-gray-600 bg-gray-50">
<tr> <tr>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">No</th> <th scope="col" class=" py-3 px-4 text-end">No</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Nama Kursus</th> <th scope="col" class=" py-3 px-4 text-end">Nama Kursus</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Kategori</th> <th scope="col" class=" py-3 px-4 text-end">Kategori</th>
{{-- <th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Paket</th> <th scope="col" class=" py-3 px-4 text-end">Paket</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Metode</th> <th scope="col" class=" py-3 px-4 text-end">Metode</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Lokasi</th> --}} <th scope="col" class=" py-3 px-4 text-end">Fasilitas</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Fasilitas</th> <th scope="col" class=" py-3 px-4 text-end">Lokasi</th>
<th scope="col" class="py-3 px-4 text-end border-r border-gray-300">Latitude-Longitude <th scope="col" class=" py-3 px-4 text-end">Aksi</th>
</th>
<th scope="col" class="py-3 px-4 text-end">Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-300"> <tbody class="shadow-gray-600">
@foreach ($courses as $index => $course) @foreach ($courses as $index => $course)
<tr <tr class="odd:bg-white even:bg-gray-50 shadow-gray-600 ">
class="odd:bg-white even:bg-gray-50 hover:bg-gray-200 transition border-b border-gray-300"> <th scope="row" class="px-4 py-4 text-end font-medium text-gray-900 whitespace-nowrap">
<th scope="row"
class="px-4 py-4 text-end poppins-regular text-gray-900 whitespace-nowrap border-r border-gray-300">
{{ ($courses->currentPage() - 1) * $courses->perPage() + $loop->iteration }} {{ ($courses->currentPage() - 1) * $courses->perPage() + $loop->iteration }}
</th> </th>
<td class="py-4 text-end px-4 border-r border-gray-300"> <td class=" py-4 text-end px-4">
<div class="flex justify-end flex-row gap-3 items-center"> <div class="flex justify-end flex-row gap-3 items-center w-full h-full">
<div class="form-control flex-1"> <div class="form-control flex-1">
<span class="text-sm uppercase font-semibold"> <span class="text-sm uppercase font-semibold">
{{ $course->nama_kursus }} {{ $course->nama_kursus }}
</span> </span>
@php <span class="text-xs text-gray-400 line-clamp-2">
$words = explode(' ', Str::limit($course->deskripsi, 200, '...')); {{ Str::limit($course->deskripsi, 200, '...') }}
$firstPart = implode(' ', array_slice($words, 0, 15)); // Ambil 15 kata pertama
$secondPart = implode(' ', array_slice($words, 15)); // Sisanya
@endphp
<span
class="text-xs text-gray-400 break-words whitespace-normal leading-tight max-w-xs sm:max-w-sm md:max-w-md">
<br> {{ $firstPart }} <br> {{ $secondPart }}
</span> </span>
</div> </div>
<div <div class="w-8 h-8 rounded-md overflow-hidden">
class="sm:w-14 lg:w-24 2xl:w-32 sm:h-14 lg:h-24 2xl:h-32 rounded-md overflow-hidden border border-gray-300">
<img src="{{ asset('storage/' . $course->img) }}" <img src="{{ asset('storage/' . $course->img) }}"
class="aspect-square shadow-md shadow-gray-500 object-cover" class="aspect-square shadow-md shadow-gray-500 object-cover" alt="">
alt="">
</div> </div>
</div> </div>
</td> </td>
<td class="py-4 text-end px-4 border-r border-gray-300"> <td class=" py-4 text-end px-4">
<div class="flex flex-col justify-center text-end poppins-regular"> <div class="flex flex-col justify-center text-end">
<span class="mb-2"> <span class="mb-2">
{{ $course->kategoris ? $course->kategoris->nama_kategori : 'Kategori tidak tersedia' }} {{ $course->kategoris ? $course->kategoris->nama_kategori : 'Kategori tidak tersedia' }}
</span> </span>
<span>{{ $course->popular }}</span>
</div> </div>
</td> </td>
{{-- <td class="py-4 text-end px-4 border-r border-gray-300">{!! Str::limit($course->paket, 50, '...') !!}</td> <td class=" py-4 text-end items-center px-4">
<td class="py-4 text-end px-4 border-r border-gray-300">{!! Str::limit($course->metode, 50, '...') !!}</td> <div> {!! Str::limit($course->paket, 50, '...') !!}</div>
<td class="py-4 text-end px-4 border-r border-gray-300">{!! Str::limit($course->lokasi, 50, '...') !!}</td> --}}
<td class="py-4 text-end px-4 border-r border-gray-300 uppercase">
@php
$fasilitasArray = json_decode($course->fasilitas, true);
$fasilitasText = $fasilitasArray ? implode(', ', $fasilitasArray) : '-';
@endphp
{!! Str::limit($fasilitasText, 50, '...') !!}
</td> </td>
<td class=" py-4 text-end items-center px-4">
<td class="py-4 text-end px-4 border-r border-gray-300"> <div> {!! Str::limit($course->metode, 50, '...') !!}</div>
{{ $course->latitude }},{{ $course->longitude }}</td> </td>
<td class="py-4 text-end px-4"> <td class=" py-4 text-end items-center px-4">
<div> {!! Str::limit($course->fasilitas, 50, '...') !!}</div>
</td>
<td class=" py-4 text-end items-center px-4">
<div> {!! Str::limit($course->lokasi, 50, '...') !!}</div>
</td>
<td class=" py-4 text-end items-center px-4">
<div class="flex justify-end items-center space-x-1 md:space-x-2"> <div class="flex justify-end items-center space-x-1 md:space-x-2">
<!-- Detail Button with Icon --> <!-- Detail Button with Icon -->
<button data-modal-target="modal-detail{{ $course->id }}" <div>
data-modal-toggle="modal-detail{{ $course->id }}" <button data-modal-target="modal-detail{{ $course->id }}"
class="font-extrabold text-xs shadow-md hover:bg-blue-600 text-white py-2 px-2 bg-blue-500 rounded-lg transition"> data-modal-toggle="modal-detail{{ $course->id }}"
<i class="fas fa-info-circle text-xs"></i> class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white py-2 px-2 bg-[#4F7F81] rounded-lg h-fit">
</button> <i class="fas fa-info-circle text-xs"></i> <!-- Icon Detail -->
</button>
</div>
<!-- Edit Button with Icon --> <!-- Edit Button with Icon -->
<a href="/admin/{{ $course->id }}/edit-kursus" <div>
class="font-extrabold text-xs shadow-md hover:bg-yellow-600 text-white py-2 px-2 bg-yellow-500 rounded-lg transition"> <a href="/admin/{{ $course->id }}/edit-kursus"
<i class="fas fa-edit text-xs"></i> class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white py-2 px-2 bg-[#4F7F81] rounded-lg h-fit">
</a> <i class="fas fa-edit text-xs"></i> <!-- Icon Edit -->
</a>
</div>
<!-- Delete Button with Icon --> <!-- Delete Button with Icon -->
<button data-modal-target="popup-modal-{{ $course->id }}" <div>
data-modal-toggle="popup-modal-{{ $course->id }}" <button data-modal-target="popup-modal-{{ $course->id }}"
class="font-extrabold text-xs shadow-md hover:bg-red-600 text-white py-2 px-2 bg-red-500 rounded-lg transition"> data-modal-toggle="popup-modal-{{ $course->id }}"
<i class="fas fa-trash-alt text-xs"></i> class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white py-2 px-2 bg-[#4F7F81] rounded-lg h-fit">
</button> <i class="fas fa-trash-alt text-xs"></i> <!-- Icon Delete -->
</button>
</div>
</div> </div>
</td> </td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
</table> </table>
</div> </div>
@foreach ($courses as $course) @foreach ($courses as $course)
@ -161,7 +121,7 @@ class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hov
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg> </svg>
<h3 class="text-black mb-5 text-lg poppins-regular "> <h3 class="text-black mb-5 text-lg font-normal ">
Apakah Anda yakin ingin menghapus kursus ini?</h3> Apakah Anda yakin ingin menghapus kursus ini?</h3>
<!-- Form Hapus --> <!-- Form Hapus -->
<form id="delete-form-{{ $course->id }}" <form id="delete-form-{{ $course->id }}"
@ -172,11 +132,11 @@ class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hov
</form> </form>
<button type="button" <button type="button"
onclick="document.getElementById('delete-form-{{ $course->id }}').submit()" onclick="document.getElementById('delete-form-{{ $course->id }}').submit()"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 poppins-regular rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-start"> class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-start">
Hapus Hapus
</button> </button>
<button type="button" <button type="button"
class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-gray-800 focus:z-10 focus:ring-4 focus:ring-gray-100 " class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-gray-800 focus:z-10 focus:ring-4 focus:ring-gray-100 "
data-modal-hide="popup-modal-{{ $course->id }}">Tidak, data-modal-hide="popup-modal-{{ $course->id }}">Tidak,
Batal</button> Batal</button>
</div> </div>
@ -219,7 +179,7 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
class="hidden overflow-y-auto fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"> class="hidden overflow-y-auto fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl xl:max-w-5xl max-h-full"> <div class="relative p-4 w-full max-w-2xl xl:max-w-5xl max-h-full">
<!-- Modal content --> <!-- Modal content -->
<div class="relative rounded-lg shadow bg-[#4F7F81]"> <div class="relative rounded-lg shadow dark:bg-gray-700 bg-[#4F7F81]">
<!-- Modal body --> <!-- Modal body -->
<div class="p-4 md:p-5"> <div class="p-4 md:p-5">
<div class=""> <div class="">

View File

@ -1,5 +1,5 @@
<x-adminlayout> <x-adminlayout>
<div class=""> <div class="container">
<div class="py-10 px-4"> <div class="py-10 px-4">
<div class="pb-4 flex"> <div class="pb-4 flex">
<a class="px-4 flex text-white text-lg justify-center shadow-md shadow-gray-600 items-center py-2 rounded-xl bg-[#4F7F81]" <a class="px-4 flex text-white text-lg justify-center shadow-md shadow-gray-600 items-center py-2 rounded-xl bg-[#4F7F81]"
@ -23,7 +23,7 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
required /> required />
</div> </div>
<div class="hidden"> <div>
<label for="popular" class="block mb-2 text-sm font-medium text-gray-900">Pilih <label for="popular" class="block mb-2 text-sm font-medium text-gray-900">Pilih
Popular</label> Popular</label>
<select id="popular" name="popular" <select id="popular" name="popular"
@ -50,11 +50,11 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
</div> </div>
<!-- Input File Single --> <!-- Input File Single -->
<div> <div>
<label for="deskripsi" class="block mb-2 text-sm font-medium text-gray-900 "> <label for="deskripsi" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Deskripsi Deskripsi
</label> </label>
<textarea id="deskripsi" name="deskripsi" rows="4" <textarea id="deskripsi" name="deskripsi" rows="4"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 " class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:placeholder-gray-400"
placeholder="KAMPUNG INGGRIS LC LANGUAGE CENTER Adalah . . . ." required>{{ old('deskripsi') }}</textarea> placeholder="KAMPUNG INGGRIS LC LANGUAGE CENTER Adalah . . . ." required>{{ old('deskripsi') }}</textarea>
</div> </div>
<div class="flex justify-between w-full gap-4"> <div class="flex justify-between w-full gap-4">
@ -102,7 +102,13 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
</div> </div>
<!-- Fasilitas --> <!-- Fasilitas -->
<div>
<label for="fasilitas" class="block mb-2 text-sm font-medium text-gray-900">Fasilitas</label>
<input id="fasilitas" name="fasilitas" type="hidden" value="{{ old('fasilitas') }}" />
<trix-editor input="fasilitas"
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Write your thoughts here..."></trix-editor>
</div>
<!-- Lokasi --> <!-- Lokasi -->
<div> <div>
@ -112,93 +118,6 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Write your thoughts here..."></trix-editor> placeholder="Write your thoughts here..."></trix-editor>
</div> </div>
<div>
<label for="fasilitas" class="block mb-2 text-sm font-medium text-gray-900">Fasilitas</label>
<input id="fasilitas" name="fasilitas" type="hidden" value="{{ old('fasilitas') }}" />
<!-- Tombol tambah fasilitas -->
<div id="facility-inputs" class=" grid grid-cols-4 gap-4">
<!-- Input fasilitas akan ditambahkan di sini -->
</div>
<button id="add-facility-btn" type="button"
class="mt-3 px-4 py-2 text-xs bg-blue-500 text-white rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Tambah Fasilitas
</button>
</div>
<!-- Script untuk menambah input fasilitas -->
<script>
let facilityIndex = 0; // Untuk memastikan setiap input memiliki ID unik
// Fungsi untuk menambahkan input fasilitas
function addFacilityInput() {
// Buat div baru untuk input fasilitas
const facilityDiv = document.createElement('div');
facilityDiv.classList.add('facility-input', 'bg-gray-100', 'rounded-lg');
// Buat label untuk input fasilitas
const label = document.createElement('label');
label.setAttribute('for', 'fasilitas_' + facilityIndex);
label.classList.add('block', 'text-sm', 'font-medium', 'text-gray-700');
// Buat input untuk fasilitas
const input = document.createElement('input');
input.id = 'fasilitas_' + facilityIndex;
input.name = 'fasilitas_' + facilityIndex;
input.type = 'text';
input.classList.add('block', 'w-full', 'px-3', 'py-2', 'border', 'border-gray-300', 'rounded-md',
'shadow-sm');
input.placeholder = 'Masukkan fasilitas';
// Buat tombol hapus untuk input fasilitas ini
const deleteButton = document.createElement('button');
deleteButton.type = 'button';
deleteButton.classList.add('ml-2', 'text-red-500', 'hover:text-red-700');
deleteButton.textContent = 'Hapus';
deleteButton.addEventListener('click', function() {
facilityDiv.remove();
updateFasilitasInput();
});
// Menambahkan elemen-elemen ke dalam div fasilitas
facilityDiv.appendChild(label);
facilityDiv.appendChild(input);
facilityDiv.appendChild(deleteButton);
// Menambahkan div fasilitas ke dalam kontainer
document.getElementById('facility-inputs').appendChild(facilityDiv);
// Update indeks fasilitas untuk input selanjutnya
facilityIndex++;
// Update input tersembunyi dengan nilai terbaru JSON
updateFasilitasInput();
}
// Tambahkan fasilitas pertama kali saat halaman dimuat
addFacilityInput();
// Event listener untuk tombol tambah fasilitas
document.getElementById('add-facility-btn').addEventListener('click', function() {
addFacilityInput();
});
// Fungsi untuk memperbarui nilai JSON di input tersembunyi
function updateFasilitasInput() {
const fasilitasArray = [];
const facilityInputs = document.querySelectorAll('.facility-input input');
// Ambil nilai dari semua input fasilitas
facilityInputs.forEach(input => {
if (input.value.trim() !== '') {
fasilitasArray.push(input.value.trim());
}
});
// Setel nilai JSON di input tersembunyi
document.getElementById('fasilitas').value = JSON.stringify(fasilitasArray);
}
</script>
<div> <div>
<label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Uplaud <label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Uplaud
Gambar</label> Gambar</label>
@ -206,18 +125,18 @@ function updateFasilitasInput() {
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<label for="file_input" <label for="file_input"
class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 "> class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
<div class="flex flex-col items-center justify-center pt-5 pb-6"> <div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true" <svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16"> viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round" <path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" stroke-linejoin="round" stroke-width="2"
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" /> d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" />
</svg> </svg>
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
to upload Single</p> class="font-semibold">Click to upload Single</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF <p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
</p> </p>
<input id="file_input" type="file" name="img" class="hidden" <input id="file_input" type="file" name="img" class="hidden"
onchange="previewImage(event)" /> onchange="previewImage(event)" />
@ -238,18 +157,18 @@ class="aspect-video h-40 object-contain" />
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<label for="multiple_files" <label for="multiple_files"
class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 "> class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
<div class="flex flex-col items-center justify-center pt-5 pb-6"> <div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true" <svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16"> viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round" <path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" stroke-linejoin="round" stroke-width="2"
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" /> d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" />
</svg> </svg>
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
to upload Multi</p> class="font-semibold">Click to upload Multi</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF <p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
</p> </p>
<input id="multiple_files" type="file" name="img_konten[]" multiple <input id="multiple_files" type="file" name="img_konten[]" multiple
onchange="previewMultipleImages(event)" class="hidden" /> onchange="previewMultipleImages(event)" class="hidden" />

View File

@ -1,5 +1,5 @@
<x-adminlayout> <x-adminlayout>
<div class=""> <div class="container">
<div class="py-10 px-4"> <div class="py-10 px-4">
<div class="pb-4 flex"> <div class="pb-4 flex">
<a class="px-4 flex text-white text-lg justify-center items-center py-2 rounded-xl bg-[#4F7F81]" <a class="px-4 flex text-white text-lg justify-center items-center py-2 rounded-xl bg-[#4F7F81]"
@ -27,11 +27,12 @@
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Kampung Inggris LC - Language Center" required /> placeholder="Kampung Inggris LC - Language Center" required />
</div> </div>
<div class="hidden"> <div>
<label for="countries" class="block mb-2 text-sm font-medium text-gray-900 ">Pilih <label for="countries"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Pilih
Popular</label> Popular</label>
<select id="countries" name="popular" <select id="countries" name="popular"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 "> class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
<option selected>{{ $dataKursus->popular }}</option> <option selected>{{ $dataKursus->popular }}</option>
@if ($dataKursus->popular === 'popular') @if ($dataKursus->popular === 'popular')
<option value="Tidak">Tidak</option> <option value="Tidak">Tidak</option>
@ -111,7 +112,15 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
placeholder="Write your thoughts here..."></trix-editor> placeholder="Write your thoughts here..."></trix-editor>
</div> </div>
<!-- Fasilitas -->
<div>
<label for="fasilitas" class="block mb-2 text-sm font-medium text-gray-900">Fasilitas</label>
<input id="fasilitas" name="fasilitas" type="hidden"
value="{{ old('fasilitas', $dataKursus->fasilitas) }}" />
<trix-editor input="fasilitas"
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Write your thoughts here..."></trix-editor>
</div>
<!-- Lokasi --> <!-- Lokasi -->
<div> <div>
@ -122,87 +131,6 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500"
placeholder="Write your thoughts here..."></trix-editor> placeholder="Write your thoughts here..."></trix-editor>
</div> </div>
<!-- Fasilitas -->
<div>
<label for="fasilitas" class="block mb-2 text-sm font-medium text-gray-900">Fasilitas</label>
<input id="fasilitas" name="fasilitas" type="hidden" value='{!! json_encode($fasilitas ?? []) !!}' />
<!-- Inputan dinamis untuk fasilitas -->
<div id="facility-inputs" class="grid grid-cols-4 gap-4">
@foreach ($fasilitas as $index => $item)
<div class="facility-input bg-gray-100 p-2 rounded-lg flex gap-2 items-center">
<input type="text" name="fasilitas[]" value="{{ $item }}"
class="block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm" />
<button type="button"
class="remove-facility text-red-500 hover:text-red-700">Hapus</button>
</div>
@endforeach
</div>
<!-- Tombol tambah fasilitas -->
<button id="add-facility-btn" type="button"
class="mt-3 px-4 py-2 text-xs bg-blue-500 text-white rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Tambah Fasilitas
</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const facilityContainer = document.getElementById('facility-inputs');
const hiddenFasilitasInput = document.getElementById('fasilitas');
function updateFasilitas() {
let fasilitasArray = [];
facilityContainer.querySelectorAll("input[name='fasilitas[]']").forEach(input => {
if (input.value.trim() !== '') {
fasilitasArray.push(input.value.trim());
}
});
hiddenFasilitasInput.value = JSON.stringify(fasilitasArray);
}
// Event listener untuk tombol tambah fasilitas
document.getElementById('add-facility-btn').addEventListener('click', function() {
const div = document.createElement('div');
div.classList.add('facility-input', 'bg-gray-100', 'p-2', 'rounded-lg', 'flex', 'gap-2',
'items-center');
const input = document.createElement('input');
input.type = 'text';
input.name = 'fasilitas[]';
input.classList.add('block', 'w-full', 'px-3', 'py-2', 'border', 'border-gray-300',
'rounded-md', 'shadow-sm');
input.placeholder = 'Masukkan fasilitas';
const deleteButton = document.createElement('button');
deleteButton.type = 'button';
deleteButton.textContent = 'Hapus';
deleteButton.classList.add('text-red-500', 'hover:text-red-700');
deleteButton.addEventListener('click', function() {
div.remove();
updateFasilitas();
});
div.appendChild(input);
div.appendChild(deleteButton);
facilityContainer.appendChild(div);
});
// Event listener untuk tombol hapus
facilityContainer.addEventListener('click', function(event) {
if (event.target.classList.contains('remove-facility')) {
event.target.parentElement.remove();
updateFasilitas();
}
});
// Perbarui input fasilitas setiap kali terjadi perubahan
facilityContainer.addEventListener('input', updateFasilitas);
});
</script>
<div> <div>
<label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Upload <label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Upload
Gambar</label> Gambar</label>
@ -210,19 +138,19 @@ function updateFasilitas() {
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<label for="file_input" <label for="file_input"
class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 "> class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
<div class="flex flex-col items-center justify-center pt-5 pb-6"> <div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true" <svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16"> viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round" <path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" stroke-linejoin="round" stroke-width="2"
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" /> d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" />
</svg> </svg>
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
to class="font-semibold">Click to
upload Single</p> upload Single</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF <p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
</p> </p>
<input id="file_input" type="file" name="img" class="hidden" <input id="file_input" type="file" name="img" class="hidden"
onchange="previewImage(event)" /> onchange="previewImage(event)" />
@ -252,19 +180,19 @@ class="block w-full text-white bg-[#4F7F81] hover:bg-[#3F6A6B] focus:ring-4 focu
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<label for="multiple_files" <label for="multiple_files"
class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 "> class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
<div class="flex flex-col items-center justify-center pt-5 pb-6"> <div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true" <svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16"> viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round" <path stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" stroke-linejoin="round" stroke-width="2"
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" /> d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" />
</svg> </svg>
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
to class="font-semibold">Click to
upload Multi</p> upload Multi</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF <p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
</p> </p>
<input id="multiple_files" type="file" name="img_konten[]" multiple <input id="multiple_files" type="file" name="img_konten[]" multiple
onchange="previewMultipleImages(event)" class="hidden" /> onchange="previewMultipleImages(event)" class="hidden" />
@ -317,7 +245,8 @@ class="object-contain max-h-48 mx-auto" alt="Gambar">
<!-- Multiple Files Modal --> <!-- Multiple Files Modal -->
<div id="multiple-files-modal" tabindex="-1" aria-hidden="true" <div id="multiple-files-modal" tabindex="-1" aria-hidden="true"
class="hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full px-4"> class="hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full px-4">
<div class="relative overflow-x-auto p-4 w-full max-w-2xl max-h-full rounded-lg"> <div
class="relative overflow-x-auto p-4 w-full max-w-2xl max-h-full rounded-lg">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<!-- Flex container to arrange images horizontally --> <!-- Flex container to arrange images horizontally -->
@if (!empty($dataKursus->img_konten)) @if (!empty($dataKursus->img_konten))

View File

@ -1,7 +1,6 @@
@include('partials.head') @include('partials.head')
@include('partials.font') @include('partials.font')
<!--
<div class="bg-[#4F7F81]"> <div class="bg-[#4F7F81]">
<nav class="border-gray-200 container bg-[#4F7F81]"> <nav class="border-gray-200 container bg-[#4F7F81]">
<div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4"> <div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4">
@ -10,19 +9,19 @@
<span <span
class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span> class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a> </a>
</div> --> </div>
</nav> </nav>
</div> </div>
<body> <body>
<div class="container py-10 px-8 lg:px-0 "> <div class="container py-10 px-8 lg:px-0">
<div class="grid lg:grid-cols-2 grid-cols-1"> <div class="grid lg:grid-cols-2 grid-cols-1">
<div class="hidden lg:block justify-center items-center "> <div class="hidden lg:block justify-center items-center">
<img src="{{ asset('img/bg-forgot pw.jpg') }}" alt=""> <img src="{{ asset('img/login.png') }}" alt="">
</div> </div>
<div class="border border-slate-500"> <div class="border border-slate-500">
<p class="p-8 flex justify-center items-center text-green-800 barlow-condensed-semibold text-6xl">FORGOT PASSWORD</p> <p class="p-8 flex justify-center items-center poppins-semibold text-4xl">Forgot Password</p>
<div class="mb-4 text-sm poppins-regular text-gray-600 px-8"> <div class="mb-4 text-sm text-gray-600 px-8">
Forgot your password? No problem. Just let us know your email address and we will email you a Forgot your password? No problem. Just let us know your email address and we will email you a
password reset link that will allow you to choose a new one. password reset link that will allow you to choose a new one.
</div> </div>
@ -42,9 +41,9 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-green-500 text-white p
<!-- Email Address --> <!-- Email Address -->
<div class="mb-5"> <div class="mb-5">
<label for="email" class="block mb-2 text-sm poppins-regular text-gray-900">Your Email</label> <label for="email" class="block mb-2 text-sm font-medium text-gray-900">Your Email</label>
<input type="email" id="email" name="email" <input type="email" id="email" name="email"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm poppins-regular rounded-lg focus:ring-green-800 focus:border-green-800 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="email@gmail.com" :value="old('email')" required autofocus /> placeholder="email@gmail.com" :value="old('email')" required autofocus />
@error('email') @error('email')
<span class="text-sm text-red-600 mt-1">{{ $message }}</span> <span class="text-sm text-red-600 mt-1">{{ $message }}</span>
@ -52,13 +51,13 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm poppins-regular r
</div> </div>
<button type="submit" <button type="submit"
class="text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center poppins-regular">Send class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center">Send
Password Reset Link</button> Password Reset Link</button>
</form> </form>
<!-- Back to Login --> <!-- Back to Login -->
<div class="text-center mt-4"> <div class="text-center mt-4">
<a href="{{ route('login') }}" class="text-green-800 hover:text-blue-800 poppins-regular">Back to <a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 font-semibold">Back to
Login</a> Login</a>
</div> </div>
</div> </div>

View File

@ -30,7 +30,7 @@ class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclo
<label for="email" class="block mb-2 text-sm font-medium text-gray-900">Your Email</label> <label for="email" class="block mb-2 text-sm font-medium text-gray-900">Your Email</label>
<input type="email" id="email" name="email" <input type="email" id="email" name="email"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="email@gmail.com" :value="old('email', $request -> email)" required autofocus placeholder="email@gmail.com" :value="old('email', $request - > email)" required autofocus
autocomplete="username" /> autocomplete="username" />
@error('email') @error('email')
<span class="text-sm text-red-600 mt-1">{{ $message }}</span> <span class="text-sm text-red-600 mt-1">{{ $message }}</span>

View File

@ -2,24 +2,40 @@
<html lang="en"> <html lang="en">
<head> <head>
{{-- @vite(['resources/css/app.css', 'resources/js/app.js']) --}}
{{-- <script src="../path/to/flowbite/dist/flowbite.min.js"></script> --}} @include('components.navbarAdmin')
{{-- <script src="https://cdn.jsdelivr.net/npm/flowbite@3.0.0/dist/flowbite.min.js"></script> --}}
@include('partials.head') @include('partials.head')
@vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css']) @vite(['resources/css/app.css', 'resources/js/app.js'])
@include('partials.font') @include('partials.font')
@include('partials.notification')
</head> </head>
<body> <body>
@if (session('success'))
@include('components.navbarAdmin') <div id="notification"
<div class="p-4 sm:ml-64"> class="fixed top-4 left-1/2 transform -translate-x-1/2 bg-green-50 text-green-800 border border-green-300 rounded-lg p-4 z-20">
<div class="p-4 border-2 border-gray-200 border-dashed rounded-lg mt-14"> <div class="flex items-center">
{{ $slot }} <svg class="flex-shrink-0 w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 20">
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z" />
</svg>
<span class="font-medium">{{ session('success') }}</span>
</div>
</div> </div>
</div> @endif
<script>
document.addEventListener('DOMContentLoaded', function() {
const notification = document.getElementById('notification');
if (notification) {
setTimeout(() => {
notification.classList.add('hidden');
}, 5000); // 5000 milliseconds = 5 seconds
}
});
</script>
<script src="../path/to/flowbite/dist/flowbite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flowbite@3.0.0/dist/flowbite.min.js"></script>
{{ $slot }}
</body> </body>

View File

@ -1,25 +1,25 @@
<footer class="bg-green-900"> <footer class="bg-[#85A7A8]">
<div class="mx-auto container w-full px-4 py-6 lg:py-8"> <div class="mx-auto container w-full py-6 lg:py-8">
<div class="space-y-10 md:flex md:justify-between"> <div class="space-y-10 md:flex md:justify-between">
<div> <div>
<a href="#" class="flex items-start justify-start ml-[-10px]"> <a href="#" class="flex items-start justify-start ml-[-10px]">
<img src="{{ asset('img/logo2.png') }}" class="h-20 w-20 object-cover" <img src="{{ asset('img/Rectangle 65.png') }}" class="h-20 w-20 object-cover"
alt="Flowbite Logo" /> alt="Flowbite Logo" />
<span <span
class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace-nowrap aclonica-regular">LearnMap</span> class="self-center pt-6 text-4xl text-white font-semibold whitespace-nowrap aclonica-regular">LearnMap</span>
</a> </a>
<p class="md:px-4 max-w-3xl xl:text-2x1 poppins-regular text-white"> <p class="md:px-4 max-w-3xl xl:text-xl aclonica-regular">
LearnMap adalah aplikasi web SIG pemetaan lokasi bimbingan belajar bahasa Inggris yang LearnMap adalah aplikasi web SIG pemetaan lokasi bimbingan belajar bahasa Inggris yang
membantu Anda menemukan tempat kursus terbaik di sekitar Anda. membantu Anda menemukan tempat kursus terbaik di sekitar Anda.
</p> </p>
</div> </div>
<div class="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3"> <div class="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3">
<div> <div>
<h2 class="mb-6 text-sm poppins-semibold text-white uppercase">Resources <h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase">Resources
</h2> </h2>
<ul class="text-white poppins-regular space-y-4"> <ul class="text-gray-600 font-medium space-y-4">
<li class=""> <li class="">
<a href="/" class="hover:underline">Beranda</a> <a href="/beranda" class="hover:underline">Beranda</a>
</li> </li>
<li> <li>
<a href="/kursus" class="hover:underline">Kursus</a> <a href="/kursus" class="hover:underline">Kursus</a>
@ -30,11 +30,12 @@ class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace
</ul> </ul>
</div> </div>
<div> <div>
<h2 class="mb-6 text-sm poppins-semibold text-white uppercase">Follow us <h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase">Follow us
</h2> </h2>
<ul class="text-white poppins-regular space-y-4"> <ul class="text-gray-600 font-medium space-y-4">
<li class=""> <li class="">
<a href="#" class="hover:underline ">Github</a> <a href="#"
class="hover:underline ">Github</a>
</li> </li>
<li> <li>
<a href="#" class="hover:underline">Discord</a> <a href="#" class="hover:underline">Discord</a>
@ -42,9 +43,9 @@ class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace
</ul> </ul>
</div> </div>
<div> <div>
<h2 class="mb-6 text-sm poppins-semibold text-white uppercase">Legal <h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase">Legal
</h2> </h2>
<ul class="text-white poppins-regular"> <ul class="text-gray-600 font-medium">
<li class="mb-4"> <li class="mb-4">
<a href="#" class="hover:underline">Privacy Policy</a> <a href="#" class="hover:underline">Privacy Policy</a>
</li> </li>
@ -57,11 +58,11 @@ class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace
</div> </div>
<hr class="my-6 border-gray-200 sm:mx-auto lg:my-8" /> <hr class="my-6 border-gray-200 sm:mx-auto lg:my-8" />
<div class="sm:flex sm:items-center sm:justify-between"> <div class="sm:flex sm:items-center sm:justify-between">
<span class="text-sm text-white sm:text-center">© 2024 <a href="https://flowbite.com/" <span class="text-sm text-gray-600 sm:text-center">© 2024 <a href="https://flowbite.com/"
class="hover:underline ">LearnMap™</a>. All Rights Reserved. class="hover:underline">LearnMap™</a>. All Rights Reserved.
</span> </span>
<div class="flex mt-4 sm:justify-center sm:mt-0"> <div class="flex mt-4 sm:justify-center sm:mt-0">
<a href="#" class="text-white hover:text-gray-900"> <a href="#" class="text-gray-600 hover:text-gray-900">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 8 19"> fill="currentColor" viewBox="0 0 8 19">
<path fill-rule="evenodd" <path fill-rule="evenodd"
@ -70,7 +71,7 @@ class="hover:underline ">LearnMap™</a>. All Rights Reserved.
</svg> </svg>
<span class="sr-only">Facebook page</span> <span class="sr-only">Facebook page</span>
</a> </a>
<a href="#" class="text-white hover:text-gray-900 ms-5"> <a href="#" class="text-gray-600 hover:text-gray-900 ms-5">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 21 16"> fill="currentColor" viewBox="0 0 21 16">
<path <path
@ -78,7 +79,7 @@ class="hover:underline ">LearnMap™</a>. All Rights Reserved.
</svg> </svg>
<span class="sr-only">Discord community</span> <span class="sr-only">Discord community</span>
</a> </a>
<a href="#" class="text-white hover:text-gray-900 ms-5"> <a href="#" class="text-gray-600 hover:text-gray-900 ms-5">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 17"> fill="currentColor" viewBox="0 0 20 17">
<path fill-rule="evenodd" <path fill-rule="evenodd"
@ -87,7 +88,7 @@ class="hover:underline ">LearnMap™</a>. All Rights Reserved.
</svg> </svg>
<span class="sr-only">Twitter page</span> <span class="sr-only">Twitter page</span>
</a> </a>
<a href="#" class="text-white hover:text-gray-900 ms-5"> <a href="#" class="text-gray-600 hover:text-gray-900 ms-5">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 20"> fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" <path fill-rule="evenodd"
@ -96,7 +97,7 @@ class="hover:underline ">LearnMap™</a>. All Rights Reserved.
</svg> </svg>
<span class="sr-only">GitHub account</span> <span class="sr-only">GitHub account</span>
</a> </a>
<a href="#" class="text-white hover:text-gray-900 ms-5"> <a href="#" class="text-gray-600 hover:text-gray-900 ms-5">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 20"> fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" <path fill-rule="evenodd"

View File

@ -1,11 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="scroll-smooth"> <html lang="en">
<head> <head>
@vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css']) @vite(['resources/css/app.css', 'resources/js/app.js'])
@include('components.navbar') @include('components.navbar')
@include('partials.font') @include('partials.font')
@include('partials.head')
</head> </head>

View File

@ -1,145 +1,104 @@
<div class="flex justify-center "> <div class="bg-[#4F7F81]">
<nav class="w-full md:container md:px-4 md:top-4 fixed z-[999] "> <nav class="border-gray-200 container bg-[#4F7F81] ">
<div class="flex justify-between py-1 md:py-2 items-center shadow-lg bg-white px-4 md:rounded-full text-white"> <div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4">
<a href="#" class="flex items-center"> <a href="{{ route('user.home') }}" class="flex items-center ">
<svg class="h-7 w-7 text-green-700" viewBox="0 0 24 24" fill="currentColor" <img src="{{ asset('img/Rectangle 65.png') }}" class="h-14 object-cover w-14 lg:mw-20 lg:h-20"
xmlns="http://www.w3.org/2000/svg"> alt="Flowbite Logo" />
<path <span
d="M12 2C8 2 5 5 5 9c0 5 7 11 7 11s7-6 7-11c0-4-3-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5S10.62 6.5 12 6.5s2.5 1.12 2.5 2.5S13.38 11.5 12 11.5z" /> class="self-center text-2xl sm:text-3xl lg:text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</svg>
<span class="text-sm lg:text-xl 2xl:text-2xl font-semibold text-green-800">LearnMap</span>
</a> </a>
<div class="hidden md:flex" id="navbar-menu"> <button data-collapse-toggle="navbar-solid-bg" type="button"
<ul class="flex space-x-8 text-sm lg:text-base 2xl:text-lg poppins-regular"> class="inline-flex text-white items-center p-2 w-10 h-10 justify-center text-sm rounded-lg md:hidden focus:outline-none focus:ring-2 focus:ring-gray-200 "
<li> aria-controls="navbar-solid-bg" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M1 1h15M1 7h15M1 13h15" />
</svg>
</button>
<div class="hidden w-full md:block md:w-auto" id="navbar-solid-bg">
<ul
class="flex flex-col items-center font-medium mt-4 rounded-lg bg-white md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 md:border-0 md:bg-transparent">
<li class="">
<a href="{{ route('user.home') }}" <a href="{{ route('user.home') }}"
class="text-black hover:text-green-600 {{ Request::routeIs('user.home') ? 'text-green-700 ' : '' }}"> class="{{ request()->is('/') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 rounded hover:bg-[#EBFEA1] md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm ">
Beranda Beranda
</a> </a>
</li> </li>
<li> <li class="">
<a href="{{ route('user.kursus') }}" <a href="{{ route('user.kursus') }}"
class="text-black hover:text-green-600 {{ Request::routeIs('user.kursus') ? 'text-green-700 ' : '' }}"> class="{{ request()->is('kursus', 'kursus/*/detail', 'kursus/*/rute') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 rounded hover:bg-[#EBFEA1] md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm ">
Kursus Kursus
</a> </a>
</li> </li>
<li> <li class="">
<a href="{{ route('user.peta') }}" <a href="{{ route('user.peta') }}"
class="text-black hover:text-green-600 {{ Request::routeIs('user.peta') ? 'text-green-700 ' : '' }}"> class="{{ request()->is('peta') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 rounded hover:bg-[#EBFEA1] md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm ">
Peta Peta
</a> </a>
</li> </li>
</ul>
</div>
<div class="flex items-center">
<!-- Login / Dropdown User -->
<div class="ml-4">
@if (Auth::check()) @if (Auth::check())
<div class="relative" data-dropdown> <li>
<button type="button" <button type="button"
class="flex items-center text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300" class="flex text-sm bg-gray-800 rounded-full md:me-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown"> id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown"
data-dropdown-placement="bottom">
<span class="sr-only">Open user menu</span> <span class="sr-only">Open user menu</span>
<!-- Menggunakan foto default dari Google jika tidak ada foto di profil pengguna -->
<img class="w-8 h-8 rounded-full" <img class="w-8 h-8 rounded-full"
src="{{ Auth::user()->avatar ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim(Auth::user()->email))) }}?d=identicon" src="{{ Auth::user()->avatar ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim(Auth::user()->email))) }}?d=identicon"
alt="user photo"> alt="user photo">
</button> </button>
<!-- Dropdown Menu --> </li>
<div id="user-dropdown"
class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow" <!-- Dropdown menu -->
data-popper-placement="bottom"> <div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600"
<div class="px-4 py-3"> id="user-dropdown">
<span class="block text-sm text-gray-900">{{ Auth::user()->name }}</span> <div class="px-4 py-3">
<span class="block text-sm text-gray-500 truncate">{{ Auth::user()->email }}</span> <span
<span class="block text-sm text-gray-900 dark:text-white">{{ Auth::user()->name }}</span>
class="block text-sm text-gray-500 truncate">{{ Auth::user()->username }}</span> <span
</div> class="block text-sm text-gray-500 truncate dark:text-gray-400">{{ Auth::user()->email }}</span>
<ul class="py-2" aria-labelledby="user-menu-button">
@if (in_array(Auth::user()->role, ['admin', 'user']))
<li>
<a href="{{ route('admin.home') }}"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Dashboard</a>
</li>
@endif
<li>
<a href="{{ route('password.edit') }}"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Setting</a>
</li>
<li>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button type="submit"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Sign
out</button>
</form>
</li>
</ul>
</div> </div>
<ul class="py-2" aria-labelledby="user-menu-button">
@if (Auth::user() && Auth::user()->role === 'admin')
<li>
<a href="{{ route('admin.home') }}">
<button type="submit"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white text-left">Dashboard</button>
</a>
</li>
@endif
<li>
<a href="{{ route('password.edit') }}">
<button type="submit"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white text-left">Setting</button>
</a>
</li>
<li>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button type="submit"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white text-left">Sign
out</button>
</form>
</li>
</ul>
</div> </div>
@else @else
<a href="{{ route('login') }}" <a href="{{ route('login') }}"
class="bg-green-900 text-white px-4 lg:px-5 py-1.5 text-xs lg:text-sm rounded-full hover:bg-green-700">Login</a> class="{{ request()->is('peta') ? 'bg-[#EBFEA1] text-gray-800' : 'bg-white text-gray-900' }}
block py-2 px-3 rounded-2xl border-2 border-gray-300 hover:bg-[#EBFEA1]
hover:text-gray-800 hover:border-gray-500 transition-all duration-200 md:inline-block
poppins-extrabold text-sm">
Login
</a>
@endif @endif
</div>
<!-- Hamburger Button (hanya tampil di mobile) -->
<button data-drawer-target="default-sidebar" data-drawer-toggle="default-sidebar"
aria-controls="default-sidebar" type="button"
class="ml-2 md:hidden inline-flex items-center p-2 w-10 h-10 justify-center text-gray-500 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200"
aria-controls="navbar-menu" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5 " aria-hidden="true" fill="none" viewBox="0 0 17 14"
xmlns="http://www.w3.org/2000/svg">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M1 1h15M1 7h15M1 13h15"></path>
</svg>
</button>
<aside id="default-sidebar"
class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full "
aria-label="Sidebar">
<div class="h-full px-3 py-4 overflow-y-auto bg-gray-50 ">
<ul class="space-y-2 font-medium">
<li> </ul>
<a href="#" class="flex items-center">
<svg class="h-7 w-7 text-green-700" viewBox="0 0 24 24" fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path
d="M12 2C8 2 5 5 5 9c0 5 7 11 7 11s7-6 7-11c0-4-3-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5S10.62 6.5 12 6.5s2.5 1.12 2.5 2.5S13.38 11.5 12 11.5z" />
</svg>
<span
class="text-sm lg:text-xl 2xl:text-2xl font-semibold text-green-800">LearnMap</span>
</a>
</li>
<li class="border border-b-2">
</li>
<li>
<a href="{{ route('user.home') }}"
class="text-black hover:text-green-600 {{ Request::routeIs('user.home') ? 'text-green-700 ' : '' }}">
Beranda
</a>
</li>
<li>
<a href="{{ route('user.kursus') }}"
class="text-black hover:text-green-600
{{ Request::routeIs('user.kursus', 'user.rute', 'kursus.detail', 'kursus.visit') ? 'text-green-700' : '' }}">
Kursus
</a>
</li>
<li>
<a href="{{ route('user.peta') }}"
class="text-black hover:text-green-600 {{ Request::routeIs('user.peta') ? 'text-green-700 ' : '' }}">
Peta
</a>
</li>
</ul>
</div>
</aside>
</div> </div>
</div> </div>
</nav> </nav>
</div> </div>

View File

@ -1,211 +1,152 @@
{{-- <div class=" flex justify-center relative"> <div class="bg-[#4F7F81]">
<nav <nav class="border-gray-200 container bg-[#4F7F81]">
class="z-50 container bg-white text-white rounded-full fixed top-4 p-2 flex items-center justify-between shadow-lg w-full mx-auto"> <div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4">
<!-- Logo dan Nama Aplikasi --> <a href="{{ route('user.home') }}" class="flex items-center">
<a href="{{ route('user.home') }}" class="flex items-center"> <img src="{{ asset('img/Rectangle 65.png') }}" class="h-14 object-cover w-14 lg:mw-20 lg:h-20"
<img src="{{ asset('img/logo3.png') }}" class="h-10 w-10" alt="Logo LearnMap" /> alt="Flowbite Logo" />
<span class="ml-2 text-2xl barlow-condensed-semibold text-green-800">LearnMap</span> <span
</a> class="self-center text-2xl sm:text-3xl lg:text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">
LearnMap
<!-- Menu Navigasi --> </span>
@if (Auth::user() && in_array(Auth::user()->role, ['admin', 'user'])) </a>
<ul class="flex space-x-8 text-lg poppins-regular"> <button data-collapse-toggle="navbar-solid-bg" type="button"
<li><a href="{{ route('admin.home') }}" class="text-black hover:text-green-600">Beranda</a></li> class="inline-flex text-white items-center p-2 w-10 h-10 justify-center text-sm rounded-lg md:hidden focus:outline-none focus:ring-2 focus:ring-gray-200"
<li><a href="{{ route('kategori.index') }}" class="text-black hover:text-green-600">Kategori</a></li> aria-controls="navbar-solid-bg" aria-expanded="false">
<li><a href="{{ route('user.index') }}" class="text-black hover:text-green-600">User</a></li> <span class="sr-only">Open main menu</span>
</ul> <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
@else viewBox="0 0 17 14">
@endif <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
<!-- Tombol Login atau Dropdown User --> d="M1 1h15M1 7h15M1 13h15" />
@if (Auth::check()) </svg>
<div class="relative"> </button>
<button type="button" class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300" <div class="hidden w-full md:block md:w-auto py-4" id="navbar-solid-bg">
id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown"> <ul
<span class="sr-only">Open user menu</span> class="flex flex-col py-2 md:px-4 items-center font-medium rounded-lg bg-white md:space-x-8 space-y-2 md:space-y-0 md:flex-row md:mt-0 md:border-0 md:bg-transparent">
<img class="w-8 h-8 rounded-full" <li class="">
src="{{ Auth::user()->avatar ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim(Auth::user()->email))) }}?d=identicon" <a href="{{ route('admin.home') }}"
alt="user photo"> class="{{ request()->is('admin/dashboard') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 hover:bg-[#EBFEA1] rounded-lg md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm">
</button> Dashboard
<!-- Dropdown Menu --> </a>
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow" </li>
id="user-dropdown"> <li class="">
<div class="px-4 py-3"> <a href="{{ route('kategori.index') }}"
<span class="block text-sm text-gray-900">{{ Auth::user()->name }}</span> class="{{ request()->is('admin/kategori') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 hover:bg-[#EBFEA1] rounded-lg md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm">
<span class="block text-sm text-gray-500 truncate">{{ Auth::user()->email }}</span> Kategori
</div> </a>
<ul class="py-2" aria-labelledby="user-menu-button"> </li>
@if (Auth::user() && in_array(Auth::user()->role, ['admin', 'user'])) <li class="">
<li> <a href="{{ route('admin.dataKursus') }}"
<a href="{{ route('admin.home') }}" class="{{ request()->is('admin/data-kursus', 'admin/create-data', 'admin/*/edit-kursus') ? 'bg-[#EBFEA1] md:bg-transparent md:text-white md:underline' : 'text-gray-900' }} block py-2 px-3 md:p-0 hover:bg-[#EBFEA1] md:hover:bg-transparent md:border-0 md:hover:text-white poppins-extrabold text-sm">
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Dashboard</a> Data Kursus
</li> </a>
@endif </li>
<li> <li class="">
<a href="{{ route('password.edit') }}"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Setting</a>
</li>
<li>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button type="submit"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left">Sign
out</button>
</form>
</li>
</ul>
</div>
</div>
@else
<a href="{{ route('login') }}"
class="bg-green-900 text-white px-4 py-2 rounded-full hover:bg-green-700">Login</a>
@endif
</nav>
</div> --}}
<nav class="fixed top-0 z-50 w-full bg-white border-b border-gray-200 ">
<div class="px-3 py-3 lg:px-5 lg:pl-3">
<div class="flex items-center justify-between">
<div class="flex items-center justify-start rtl:justify-end">
<button data-drawer-target="logo-sidebar" data-drawer-toggle="logo-sidebar" aria-controls="logo-sidebar"
type="button"
class="inline-flex items-center p-2 text-sm text-gray-500 rounded-lg sm:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 ">
<span class="sr-only">Open sidebar</span>
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path clip-rule="evenodd" fill-rule="evenodd"
d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z">
</path>
</svg>
</button>
<a href="{{ route('user.home') }}" class="flex items-center">
<svg class="h-7 w-7 text-green-700" viewBox="0 0 24 24" fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path
d="M12 2C8 2 5 5 5 9c0 5 7 11 7 11s7-6 7-11c0-4-3-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5S10.62 6.5 12 6.5s2.5 1.12 2.5 2.5S13.38 11.5 12 11.5z" />
</svg>
<span class="text-2xl font-semibold text-green-800">LearnMap</span>
</a>
</div>
<div class="flex items-center">
<div class="flex items-center ms-3">
<div>
<button type="button" <button type="button"
class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300 " class="flex text-sm bg-gray-800 rounded-full md:me-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
aria-expanded="false" data-dropdown-toggle="dropdown-user"> id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown"
data-dropdown-placement="bottom">
<span class="sr-only">Open user menu</span> <span class="sr-only">Open user menu</span>
<img class="w-8 h-8 rounded-full" <img class="w-8 h-8 rounded-full"
src="https://flowbite.com/docs/images/people/profile-picture-5.jpg" alt="user photo"> src="{{ Auth::user()->avatar ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim(Auth::user()->email))) }}?d=identicon"
alt="user photo">
</button> </button>
</div> </li>
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-sm shadow-sm "
id="dropdown-user"> <!-- Dropdown menu -->
<div class="px-4 py-3" role="none"> <div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600"
<p class="text-sm text-green-900 " role="none"> id="user-dropdown">
{{ Auth::user()->email }} <div class="px-4 py-3">
</p> <span class="block text-sm text-gray-900 dark:text-white">{{ Auth::user()->name }}</span>
<p class="text-sm font-medium text-green-900 truncate d" role="none"> <span
{{ Auth::user()->name }} class="block text-sm text-gray-500 truncate dark:text-gray-400">{{ Auth::user()->email }}</span>
</p>
</div> </div>
<ul class="py-1" role="none"> <ul class="py-2" aria-labelledby="user-menu-button">
<li> <li>
<a href="{{ route('admin.home') }}" <a href="{{ route('admin.home') }}">
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 " <button type="submit"
role="menuitem">Dashboard</a> class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Dashboard</button>
</a>
</li> </li>
<li> <li>
<a href="{{ route('password.edit') }}" <a href="{{ route('password.edit') }}">
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 " <button type="submit"
role="menuitem">Settings</a> class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Setting</button>
</a>
</li> </li>
<li> <li>
<form action="{{ route('logout') }}" method="POST" <form action="{{ route('logout') }}" method="POST">
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 ">
@csrf @csrf
<button type="submit" class="w-full text-left">Sign out</button> <button type="submit"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Sign
out</button>
</form> </form>
</li> </li>
</ul> </ul>
</div> </div>
</ul>
</div>
</div>
</nav>
</div>
<!-- Modal Konfirmasi -->
<div id="popup-modal" tabindex="-1"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow">
<button type="button"
class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center"
data-modal-hide="popup-modal">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Close modal</span>
</button>
<div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-[#3F6A6B] w-12 h-12" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
<h3 class="mb-5 text-lg font-normal text-black">
Apakah Anda yakin ingin keluar?
</h3>
<div class="flex justify-center">
<form id="logout-form" method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit"
class="text-white bg-[#4F7F81] hover:bg-[#3F6A6B] focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
Ya, Keluar
</button>
</form>
<button type="button"
class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-[#3F6A6B] focus:z-10 focus:ring-4 focus:ring-gray-100"
data-modal-hide="popup-modal">
Tidak, Batal
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</nav> </div>
<aside id="logo-sidebar" <script>
class="fixed top-0 left-0 z-40 w-64 h-screen pt-20 transition-transform -translate-x-full bg-white border-r border-gray-200 sm:translate-x-0" document.addEventListener('DOMContentLoaded', () => {
aria-label="Sidebar"> document.querySelectorAll('[data-modal-toggle]').forEach(button => {
<div class="h-full px-3 pb-4 overflow-y-auto bg-white"> button.addEventListener('click', () => {
<ul class="space-y-2 font-medium"> const targetId = button.getAttribute('data-modal-target');
<li> document.getElementById(targetId).classList.remove('hidden');
@if (Auth::user() && in_array(Auth::user()->role, ['admin', 'user'])) });
<a href="{{ route('admin.home') }}" });
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-green-100 group {{ request()->routeIs('admin.home') ? 'bg-green-200 text-green-700' : 'hover:bg-green-100 hover:text-green-600' }}">
<svg class="w-5 h-5 transition duration-75 group-hover:text-green-700 {{ request()->routeIs('admin.home') ? 'text-green-700' : 'text-gray-500' }}"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 22 21">
<path
d="M16.975 11H10V4.025a1 1 0 0 0-1.066-.998 8.5 8.5 0 1 0 9.039 9.039.999.999 0 0 0-1-1.066h.002Z" />
<path
d="M12.5 0c-.157 0-.311.01-.565.027A1 1 0 0 0 11 1.02V10h8.975a1 1 0 0 0 1-.935c.013-.188.028-.374.028-.565A8.51 8.51 0 0 0 12.5 0Z" />
</svg>
<span class="ms-3">Dashboard</span>
</a>
@else
@endif
</li>
@if (Auth::user() && in_array(Auth::user()->role, ['user'])) document.querySelectorAll('[data-modal-hide]').forEach(button => {
<li> button.addEventListener('click', () => {
<a href="{{ route('admin.dataKursus') }}" const targetId = button.getAttribute('data-modal-hide');
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-green-100 group document.getElementById(targetId).classList.add('hidden');
{{ request()->routeIs(['admin.create', 'admin.dataKursus', 'admin.edit']) ? 'bg-green-200 text-green-700' : 'hover:bg-green-100 hover:text-green-600' }}"> });
});
<svg class="w-5 h-5 transition duration-75 group-hover:text-green-700 });
{{ request()->routeIs(['admin.create', 'admin.dataKursus', 'admin.edit']) ? 'text-green-700' : 'text-gray-500' }}" </script>
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 18 20">
<path
d="M17 5.923A1 1 0 0 0 16 5h-3V4a4 4 0 1 0-8 0v1H2a1 1 0 0 0-1 .923L.086 17.846A2 2 0 0 0 2.08 20h13.84a2 2 0 0 0 1.994-2.153L17 5.923ZM7 9a1 1 0 0 1-2 0V7h2v2Zm0-5a2 2 0 1 1 4 0v1H7V4Zm6 5a1 1 0 1 1-2 0V7h2v2Z" />
</svg>
<span class="ms-3">Kursus</span>
</a>
</li>
@else
<li>
<a href="{{ route('kategori.index') }}"
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-green-100 group {{ request()->routeIs('kategori.index') ? 'bg-green-200 text-green-700' : 'hover:bg-green-100 hover:text-green-600' }}">
<svg class="w-5 h-5 transition duration-75 group-hover:text-green-700 {{ request()->routeIs('kategori.index') ? 'text-green-700' : 'text-gray-500' }}"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 18 18">
<path
d="M6.143 0H1.857A1.857 1.857 0 0 0 0 1.857v4.286C0 7.169.831 8 1.857 8h4.286A1.857 1.857 0 0 0 8 6.143V1.857A1.857 1.857 0 0 0 6.143 0Zm10 0h-4.286A1.857 1.857 0 0 0 10 1.857v4.286C10 7.169 10.831 8 11.857 8h4.286A1.857 1.857 0 0 0 18 6.143V1.857A1.857 1.857 0 0 0 16.143 0Zm-10 10H1.857A1.857 1.857 0 0 0 0 11.857v4.286C0 17.169.831 18 1.857 18h4.286A1.857 1.857 0 0 0 8 16.143v-4.286A1.857 1.857 0 0 0 6.143 10Zm10 0h-4.286A1.857 1.857 0 0 0 10 11.857v4.286c0 1.026.831 1.857 1.857 1.857h4.286A1.857 1.857 0 0 0 18 16.143v-4.286A1.857 1.857 0 0 0 16.143 10Z" />
</svg>
<span class="ms-3">Kategori</span>
</a>
</li>
<li>
<a href="{{ route('user.index') }}"
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-green-100 group {{ request()->routeIs('user.index') ? 'bg-green-200 text-green-700' : 'hover:bg-green-100 hover:text-green-600' }}">
<svg class="w-5 h-5 transition duration-75 group-hover:text-green-700 {{ request()->routeIs('user.index') ? 'text-green-700' : 'text-gray-500' }}"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 20 18">
<path
d="M14 2a3.963 3.963 0 0 0-1.4.267 6.439 6.439 0 0 1-1.331 6.638A4 4 0 1 0 14 2Zm1 9h-1.264A6.957 6.957 0 0 1 15 15v2a2.97 2.97 0 0 1-.184 1H19a1 1 0 0 0 1-1v-1a5.006 5.006 0 0 0-5-5ZM6.5 9a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9ZM8 10H5a5.006 5.006 0 0 0-5 5v2a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1v-2a5.006 5.006 0 0 0-5-5Z" />
</svg>
<span class="ms-3">Users</span>
</a>
</li>
@endif
</ul>
</div>
</aside>

View File

@ -1,33 +1,26 @@
<!DOCTYPE html> @include('partials.head')
<html lang="en"> @include('partials.font')
<head> <div class="bg-[#4F7F81]">
<meta charset="utf-8" /> <nav class="border-gray-200 container bg-[#4F7F81] ">
<meta content="width=device-width, initial-scale=1.0" name="viewport" /> <div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4">
<title>Login</title> <a href="#" class="flex items-center">
<script src="https://cdn.tailwindcss.com"></script> <img src="{{ asset('img/Rectangle 65.png') }}" class="h-20 object-cover w-20" alt="Flowbite Logo" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet" /> <span
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" /> class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
<style> </a>
body { </div>
font-family: 'Inter', sans-serif; </nav>
} </div>
</style>
</head>
<body class="bg-gray-100"> <body>
@if (session('success')) @if (session('success'))
<div <div
class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-green-500 text-white px-6 py-3 rounded-md shadow-lg z-50"> class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-green-500 text-white px-6 py-3 rounded-md shadow-lg z-50">
{{ session('success') }} {{ session('success') }}
</div> </div>
@endif @endif
@if (session('error'))
<div
class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50">
{{ session('error') }}
</div>
@endif
@if ($errors->any()) @if ($errors->any())
<div <div
class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50"> class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50">
@ -39,55 +32,47 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-
</div> </div>
@endif @endif
<div class="flex min-h-screen"> <div class="container py-10 px-8 lg:px-0">
<!-- Left Side --> <div class="grid lg:grid-cols-2 grid-cols-1">
<div class="w-full lg:w-1/2 flex flex-col justify-center items-center bg-white p-8"> <div class="hidden lg:block justify-center items-center">
<div class="w-full max-w-md"> <img src="{{ asset('img/login.png') }}" alt="">
<div class="mb-8">
<!--
<a href="/" class="flex items-center">
<img src="{{ asset('img/Rectangle 65.png') }}" class="h-20 object-cover w-20" alt="Logo"/>
<span class="self-center text-2xl text-[#4F7F81] font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a> -->
<h1 class="text-5xl text-green-800 barlow-condensed-semibold mt-4">LOGIN</h1>
</div>
<form method="POST">
@csrf
<div class="mb-4">
<label class="block text-sm poppins-regular mb-1" for="login">Email/Username*</label>
<input class="w-full border border-gray-300 rounded-lg py-2 px-3" id="login" name="login"
placeholder="Enter your email or username" type="text" required />
</div>
<div class="mb-4">
<label class="block text-sm poppins-regular mb-1" for="password">Password*</label>
<input class="w-full border border-gray-300 rounded-lg py-2 px-3" id="password" name="password"
placeholder="Enter your password" type="password" required />
<a href="{{ route('password.forget') }}"
class="text-sm text-green-800 poppins-regular mt-2 inline-block">Forgot password?</a>
</div>
<button class="w-full bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white rounded-lg py-2 poppins-regular
transition delay-100 duration-300 ease-in-out hover:-translate-y-1 hover:scale-110 hover:bg-green-800" type="submit">Log In</button>
</form>
<p class="mt-4 poppins-regula text-sm text-gray-500">
Don't have an account?
<a href="{{ route('register.index') }}" class="text-black poppins-regular">Register here</a>
</p>
</div> </div>
</div> <div class="border border-slate-500">
<!-- Right Side --> <p class="p-8 flex justify-center font-semibold items-center poppins-semibold text-4xl">Login</p>
<div class="hidden lg:flex lg:w-1/2 flex items-center justify-center bg-cover bg-center relative" <form class="px-8 mx-auto" method="POST">
style="background-image: url('{{ asset('img/bg-login.jpg') }}'); background-size: object-contain;"> @csrf
<div class="absolute inset-0 opacity-25"></div> <div class="mb-5">
<div class="relative z-10 p-8"> <label for="email" class="block mb-2 text-sm font-medium text-gray-900 ">Your email</label>
<!-- <h2 class="text-5xl barlow-condensed-semibold text-green-800 mb-4">MARI TEMUKAN KURSUS IMPIANMU BERSAMA <input type="email" id="email" name="email"
LEARN MAP.</h2> class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 "
<p class="text-black poppins-regular ">Jelajahi kursus berkualitas bersama Learn Map, sekarang juga. placeholder="email@gmail.com" required />
Temukan berbagai pilihan kursus yang dirancang untuk meningkatkan keterampilan dan pengetahuanmu. --> </div>
</p> <div class="mb-5">
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 ">Your
password</label>
<input type="password" id="password" name="password"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 "
required placeholder="********" />
</div>
<div class="flex items-ded justify-end mb-5">
<!-- Lupa Password -->
<a href="{{ route('password.forget') }}"
class="text-blue-600 hover:text-blue-800 text-sm font-medium">Forgot password?</a>
</div>
<button type="submit"
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center">Log In</button>
</form>
<!-- Tombol Register -->
<div class="text-center mt-4">
<p class="text-sm text-gray-600">Don't have an account?</p>
<a href="{{ route('register.index') }}"
class="text-blue-600 hover:text-blue-800 font-semibold">Register here</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</body>
</html> </body>

View File

@ -1,6 +1,6 @@
@include('partials.head') @include('partials.head')
@include('partials.font') @include('partials.font')
<!--
<div class="bg-[#4F7F81]"> <div class="bg-[#4F7F81]">
<nav class="border-gray-200 container bg-[#4F7F81]"> <nav class="border-gray-200 container bg-[#4F7F81]">
<div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4"> <div class="max-w-screen-2xl flex flex-wrap items-center justify-between mx-auto p-4">
@ -9,7 +9,7 @@
<span <span
class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span> class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a> </a>
</div> --> </div>
</nav> </nav>
</div> </div>
@ -22,39 +22,39 @@ class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclo
@endif @endif
<div class="border border-slate-500 pb-4"> <div class="border border-slate-500 pb-4">
<p class="p-8 flex justify-center items-center barlow-condensed-semibold text-green-800 text-6xl">REGISTER</p> <p class="p-8 flex justify-center items-center poppins-semibold text-4xl">Register</p>
<form class="px-8 mx-auto" method="POST" action="{{ route('register.account') }}"> <form class="px-8 mx-auto" method="POST" action="{{ route('register.account') }}">
@csrf @csrf
<div class="mb-5"> <div class="mb-5">
<label for="name" class="block mb-2 text-sm poppins-regular text-gray-900">Your Name</label> <label for="name" class="block mb-2 text-sm font-medium text-gray-900">Your Name</label>
<input type="text" id="name" name="name" value="{{ old('name') }}" <input type="text" id="name" name="name" value="{{ old('name') }}"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Full Name" required /> placeholder="Full Name" required />
</div> </div>
<div class="mb-5"> <div class="mb-5">
<label for="email" class="block mb-2 text-sm poppins-regular text-gray-900">Your Email</label> <label for="email" class="block mb-2 text-sm font-medium text-gray-900">Your Email</label>
<input type="email" id="email" name="email" <input type="email" id="email" name="email"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="email@example.com" required /> placeholder="email@example.com" required />
</div> </div>
<div class="mb-5"> <div class="mb-5">
<label for="email_confirmation" class="block mb-2 text-sm poppins-regular text-gray-900">Confirm Your <label for="email_confirmation" class="block mb-2 text-sm font-medium text-gray-900">Confirm Your
Email</label> Email</label>
<input type="email" id="email_confirmation" name="email_confirmation" <input type="email" id="email_confirmation" name="email_confirmation"
value="{{ old('email_confirmation') }}" value="{{ old('email_confirmation') }}"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Confirm email@example.com" required /> placeholder="Confirm email@example.com" required />
</div> </div>
<div class="mb-5"> <div class="mb-5">
<label for="password" class="block mb-2 text-sm poppins-regular text-gray-900">Your Password</label> <label for="password" class="block mb-2 text-sm font-medium text-gray-900">Your Password</label>
<input type="password" id="password" name="password" value="{{ old('password') }}" <input type="password" id="password" name="password" value="{{ old('password') }}"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="********" required /> placeholder="********" required />
</div> </div>
<div class="mb-5"> <div class="mb-5">
<label for="password_confirmation" class="block mb-2 text-sm poppins-regular text-gray-900">Confirm <label for="password_confirmation" class="block mb-2 text-sm font-medium text-gray-900">Confirm
Password</label> Password</label>
<input type="password" id="password_confirmation" name="password_confirmation" <input type="password" id="password_confirmation" name="password_confirmation"
value="{{ old('password_confirmation') }}" value="{{ old('password_confirmation') }}"
@ -71,11 +71,11 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
</div> </div>
@endif @endif
<button type="submit" <button type="submit"
class="text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 poppins-regular rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center">Register</button> class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center">Register</button>
</form> </form>
<div class="text-center mt-4"> <div class="text-center mt-4">
<p class="text-sm poppins-regular text-gray-600">Already have an account?</p> <p class="text-sm text-gray-600">Already have an account?</p>
<a href="{{ route('login') }}" class="text-green-700 hover:text-blue-800 poppins-regular">Login here</a> <a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 font-semibold">Login here</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,312 +0,0 @@
<div class="grid lg:grid-cols-2 gap-10 pb-10 px-4 md:px-0">
<div class=" space-y-4 lg:pr-28">
<div class="">
<div class="flex justify-start mb-4 mt-2">
<a href="/kursus/{{ $data->id }}/rute" target="_blank"
class="inline-flex items-center gap-2 px-5 py-2 text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] hover:brightness-110 transition-all duration-200 rounded-full shadow-md poppins-medium text-sm">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 20l-5.447-2.724A2 2 0 013 15.382V8.618a2 2 0 01.553-1.382L9 4m6 16l5.447-2.724A2 2 0 0021 15.382V8.618a2 2 0 00-.553-1.382L15 4M9 4v16m6-16v16" />
</svg>
Lihat Rute
</a>
</div>
<p class="font-bold pb-2">
{{ $data->nama_kursus }}
</p>
<h1 class="poppins-reguler text-xl">{{ $data->deskripsi }}</h1>
</div>
<div>
<p class="poppins-semibold text-2xl">Fasilitas</p>
@if (!empty($data->fasilitas) && is_array($data->fasilitas))
<div class="pl-2 poppins-reguler text-xl space-y-1">
@foreach ($data->fasilitas as $item)
<p>* {{ $item }}</p>
@endforeach
</div>
@else
<p class="text-gray-500 italic">Tidak ada data fasilitas.</p>
@endif
</div>
</div>
<div class=" space-y-2">
@if (!empty($imageNames) && is_array($imageNames) && count($imageNames) > 0)
{{-- Gambar utama di atas --}}
<div>
<img src="{{ asset('storage/' . $imageNames[0]) }}" alt="Gambar Utama"
class="w-full h-[320px] object-cover rounded-lg shadow-lg cursor-pointer" onclick="openModal()">
</div>
@if (count($imageNames) > 1)
<div class="grid grid-cols-12 gap-2 mt-2">
{{-- Gambar kiri --}}
<div class="col-span-7">
<img src="{{ asset('storage/' . $imageNames[1]) }}" alt="Gambar Detail 1"
class="w-full h-80 object-cover rounded-lg cursor-pointer" onclick="openModal()">
</div>
{{-- Gambar kanan --}}
<div class="col-span-5 relative">
@if (count($imageNames) > 2)
<img src="{{ asset('storage/' . $imageNames[2]) }}" alt="Gambar Detail 2"
class="w-full h-80 object-cover rounded-lg cursor-pointer" onclick="openModal()">
{{-- Tombol +n jika lebih dari 3 gambar --}}
@if (count($imageNames) > 3)
<button data-modal-toggle="imageModal"
class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50 text-white text-lg font-bold rounded-lg cursor-pointer">
+{{ count($imageNames) - 3 }}
</button>
@endif
@endif
</div>
</div>
@endif
{{-- Modal untuk menampilkan semua gambar --}}
<div id="imageModal" tabindex="-1" aria-hidden="true"
class="fixed inset-0 hidden z-[999] overflow-y-auto overflow-x-hidden bg-black bg-opacity-80 flex items-center justify-center">
<div class="relative p-4 w-full max-w-6xl max-h-full">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow">
<!-- Close button di pojok kanan atas -->
<button type="button"
class="absolute top-2 right-2 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center z-50"
onclick="toggleModal('imageModal')">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M1 1l6 6m0 0l6 6M7 7l6-6M7 7L1 13" />
</svg>
<span class="sr-only">Tutup modal</span>
</button>
<div class="grid grid-cols-1 gap-4 p-6 overflow-y-auto max-h-[80vh]">
@foreach ($imageNames as $image)
<img src="{{ asset('storage/' . $image) }}" alt="Gambar Detail"
class="w-full h-auto object-contain rounded-lg shadow-md">
@endforeach
</div>
</div>
</div>
</div>
<script>
// Toggle modal visibility
function toggleModal(id) {
const modal = document.getElementById(id);
modal.classList.toggle('hidden');
}
// Klik di luar modal content = close
window.addEventListener('click', function (event) {
const modal = document.getElementById('imageModal');
if (!modal.classList.contains('hidden') && event.target === modal) {
modal.classList.add('hidden');
}
});
// Untuk tombol dengan data-modal-toggle
document.querySelectorAll('[data-modal-toggle]').forEach(button => {
button.addEventListener('click', () => {
const targetId = button.getAttribute('data-modal-toggle');
toggleModal(targetId);
});
});
</script>
@else
<p class="text-gray-500 italic text-center">Tidak ada gambar yang tersedia.</p>
@endif
</div>
</div>
<div class="grid grid-cols-6 gap-4 py-20 ">
<!-- Left Column: Comment Form -->
<!-- Right Column: Ratings and Reviews -->
<div class="col-span-4 ">
<!-- Ratings Section -->
<div class="bg-gray-50">
<div class=" flex justify-between items-center">
<div class="flex w-full items-center">
<div class="flex items-center">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= round($averageRating) ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
<span class="text-sm pl-4">Rata-rata: {{ round($averageRating, 1) }} / 5</span>
</div>
<div class=" md:ml-4">
<p class="poppins-medium poppins-regular text-sm xl:text-xl text-black">
(Total: {{ $totalRatings }} ulasan)
</p>
</div>
</div>
<div class="w-full">
{{ $ulasan->links() }}
</div>
</div>
<!-- Reviews Section -->
</div>
<div class="grid lg:grid-cols-3 w-full gap-4 items-center justify-start lg:justify-end rtl">
@foreach ($ulasan as $review)
<div class="mb-6 mt-4 p-4 bg-white rounded-lg shadow-xl w-full">
<!-- Reviewer Info -->
<div class="flex items-center mb-3 w-full">
<img src="/img/profil.png" alt="User Avatar" class="w-10 h-10 rounded-full mr-4">
<div>
<h4 class="font-bold text-gray-800">{{ $review->user->name ?? 'Anonim' }}</h4>
<p class="text-sm text-gray-500">
{{ $review->created_at->diffForHumans() }}
</p>
</div>
</div>
<!-- Reviewer Rating -->
<div class="flex items-center mb-2">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= $review->rating ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
</div>
<p id="comment-text-{{ $review->id }}" class="text-gray-700">
@if (strlen($review->comment) > 100)
{{ Str::limit($review->comment, 100) }}
<button class="text-blue-600 underline ml-2" data-id="{{ $review->id }}"
data-full="{{ e($review->comment) }}" onclick="showFullComment(this)">
Lihat Selengkapnya
</button>
@else
{{ $review->comment }}
@endif
</p>
<script>
function showFullComment(button) {
const id = button.getAttribute('data-id');
const fullText = button.getAttribute('data-full');
const el = document.getElementById('comment-text-' + id);
el.innerHTML = fullText.replace(/\n/g, "<br>");
}
</script>
</div>
@endforeach
</div>
<!-- Pagination Links -->
</div>
<div class="col-span-2">
@auth
<form action="{{ route('storeUlasan') }}" method="POST">
@csrf
<div class="max-w-xl mb-4 border border-gray-200 rounded-lg bg-gray-50">
<!-- Comment Input -->
<div class="hidden">
<input name="user_id" value="{{ Auth::user()->id }}" type="text">
<input name="kursus_id" value="{{ $data->id }}" type="text">
</div>
<div class="px-4 py-2 bg-white rounded-t-lg">
<label for="comment" class="sr-only">Your comment</label>
<textarea id="comment" name="comment" rows="4"
class="w-full px-0 text-sm text-gray-900 bg-white border-0 focus:ring-0 placeholder-gray-400"
placeholder="Write a comment..." required></textarea>
</div>
<!-- Rating Stars and Submit Button -->
<div class="flex items-center justify-between px-3 py-2 border-t border-gray-200">
<!-- Rating Stars -->
<div class="flex items-center space-x-2" id="rating-stars">
@for ($i = 1; $i <= 5; $i++)
<label class="cursor-pointer">
<input type="radio" name="rating" value="{{ $i }}" class="hidden" />
<svg class="w-6 h-6 text-gray-300 hover:text-yellow-400 transition-colors duration-200"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
</label>
@endfor
</div>
<script>
// JavaScript for managing star ratings
const starsContainer = document.getElementById('rating-stars');
const stars = starsContainer.querySelectorAll('svg');
const inputs = starsContainer.querySelectorAll('input[type="radio"]');
stars.forEach((star, index) => {
star.addEventListener('click', () => {
// Set all previous stars to active
stars.forEach((s, i) => {
if (i <= index) {
s.classList.add('text-yellow-400');
s.classList.remove('text-gray-300');
} else {
s.classList.add('text-gray-300');
s.classList.remove('text-yellow-400');
}
});
// Set the corresponding radio input
inputs[index].checked = true;
});
});
</script>
<!-- Submit Button -->
<button type="submit"
class="inline-flex items-center py-2.5 px-4 text-xs font-medium text-center text-white bg-blue-700 rounded-lg focus:ring-4 focus:ring-blue-200 hover:bg-blue-800">
Post Comment
</button>
</div>
</div>
</form>
@endauth
@guest
<p class="text-sm poppins-regular text-gray-500">
Anda harus <a href="{{ route('login') }}" class="text-green-800 poppins-semibold hover:underline">login</a>
untuk
memberikan ulasan.
</p>
@endguest
<!-- Community Guidelines -->
<p class="ms-auto text-xs poppins-regular text-gray-500">
Remember, contributions to this topic should follow our
<a href="#" class="text-green-800 poppins-semibold hover:underline">Community
Guidelines</a>.
</p>
</div>
</div>

View File

@ -1,84 +0,0 @@
<div class="w-full mb-10 border p-10 grid grid-cols-1 lg:grid-cols-2 gap-4">
<!-- Bagian Map - Order pertama di mobile, kedua di lg -->
<div class="">
<div class="aspect-[5/3] min-h-[300px]" id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const mapElement = document.getElementById('map');
if (!mapElement) {
console.warn("Element dengan ID 'map' tidak ditemukan.");
return;
}
const map = L.map('map').setView(
[{{ $data->latitude ?? '-7.7560717' }}, {{ $data->longitude ?? '112.1823541' }}],
15
);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
@if (!empty($data->latitude) && !empty($data->longitude))
L.marker([{{ $data->latitude }}, {{ $data->longitude }}]).addTo(map)
.bindPopup(`
<b>{{ addslashes($data->nama_kursus) }}</b><br>
<img class="w-32 h-20 object-cover" src="{{ asset('storage/' . $data->img) }}" alt="{{ addslashes($data->nama_kursus) }}" /><br>
<a href="{{ url('/kursus/' . $data->id . '/detail') }}" class="text-blue-500 underline">Selengkapnya</a>
`);
@else
L.marker([-7.7560717, 112.1823541]).addTo(map)
.bindPopup('<b>Default Marker: Pusat Kota Pare</b>');
@endif
// Gunakan whenReady untuk pastikan map siap
map.whenReady(() => {
setTimeout(() => {
map.invalidateSize();
}, 300); // Lebih responsif
});
});
</script>
</div>
<!-- Bagian Lokasi - Order kedua di mobile, pertama di lg -->
<div class="">
<p class="poppins-semibold text-2xl text-black ">
Lokasi
</p>
<p class="poppins-semibold pb-4">{{ $data->nama_kursus }}</p>
<p class="pl-4 poppins-regular text-lg text-black" id="lokasi-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->lokasi, '<br><p><strong><em>'), 400, '...')) !!}
</p>
@if (strlen(strip_tags($data->lokasi)) > 400)
<button id="toggle-lokasi" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
<script>
document.addEventListener("DOMContentLoaded", function() {
const lokasiText = document.getElementById("lokasi-text");
const toggleButton = document.getElementById("toggle-lokasi");
if (lokasiText && toggleButton) {
const fullText = `{!! addslashes($data->lokasi) !!}`;
const shortText = `{!! addslashes(
htmlspecialchars_decode(Str::limit(strip_tags($data->lokasi, '<br><p><strong><em>'), 400, '...')),
) !!}`;
let expanded = false;
toggleButton.addEventListener("click", function() {
lokasiText.innerHTML = expanded ? shortText : fullText;
toggleButton.textContent = expanded ? "Lihat Selengkapnya" : "Sembunyikan";
expanded = !expanded;
});
}
});
</script>
</div>
</div>

View File

@ -1,41 +0,0 @@
<div class="w-full mb-10 border p-10">
<p class="poppins-semibold text-2xl text-black ">
Metode Pembelajaran
</p>
<p class="poppins-semibold pb-4">{{ $data->nama_kursus }}</p>
<p class="pl-4 poppins-regular text-lg text-black" id="metode-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->metode, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->metode)) > 250)
<button id="toggle-metode" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
<script>
document.addEventListener("DOMContentLoaded", function() {
const metodeText = document.getElementById("metode-text");
const toggleButton = document.getElementById("toggle-metode");
if (toggleButton && metodeText) {
const fullText = `{!! addslashes($data->metode) !!}`;
const shortText = `{!! addslashes(
htmlspecialchars_decode(Str::limit(strip_tags($data->metode, '<br><p><strong><em>'), 250, '...')),
) !!}`;
let expanded = false;
toggleButton.addEventListener("click", function() {
if (expanded) {
metodeText.innerHTML = shortText;
toggleButton.textContent = "Lihat Selengkapnya";
} else {
metodeText.innerHTML = fullText;
toggleButton.textContent = "Sembunyikan";
}
expanded = !expanded;
});
}
});
</script>
</div>

View File

@ -1,37 +0,0 @@
<div class="w-full mb-10 border p-10">
<p class="poppins-semibold font-semibold text-2xl text-black ">
Paket
</p>
<p class="poppins-semibold pb-4">{{ $data->nama_kursus }}</p>
<p class="pl-4 poppins-regular text-lg text-black" id="paket-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->paket, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->paket)) > 200)
<button id="toggle-paket" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const paketText = document.getElementById("paket-text");
const toggleButton = document.getElementById("toggle-paket");
if (toggleButton && paketText) {
const fullText = `{!! addslashes($data->paket) !!}`;
const shortText = `{!! addslashes(htmlspecialchars_decode(Str::limit(strip_tags($data->paket, '<br><p><strong><em>'), 250, '...'))) !!}`;
let expanded = false;
toggleButton.addEventListener("click", function() {
if (expanded) {
paketText.innerHTML = shortText;
toggleButton.textContent = "Lihat Selengkapnya";
} else {
paketText.innerHTML = fullText;
toggleButton.textContent = "Sembunyikan";
}
expanded = !expanded;
});
}
});
</script>

View File

@ -7,7 +7,4 @@
<link <link
href="https://fonts.googleapis.com/css2?family=Aclonica&family=Archivo+Black&family=Pacifico&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" href="https://fonts.googleapis.com/css2?family=Aclonica&family=Archivo+Black&family=Pacifico&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"> rel="stylesheet">
<link <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet">
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Bebas+Neue&display=swap" rel="stylesheet">

View File

@ -2,8 +2,8 @@
<!-- CSS Aplikasi --> <!-- CSS Aplikasi -->
<!-- @vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css']) --> @vite(['resources/css/app.css', 'resources/js/app.js'])
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<!-- Viewport untuk Responsif --> <!-- Viewport untuk Responsif -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -15,23 +15,8 @@
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- Leaflet Routing Machine CSS dan JS --> <!-- Leaflet Routing Machine CSS dan JS -->
{{--
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.css" />
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script> --}} <script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>
<!-- LEAFLET CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<!-- LEAFLET JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
@stack('script') @stack('script')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
<!-- link font -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet">
</style>

View File

@ -1,36 +0,0 @@
@if (session('success'))
<div id="notification"
class="fixed top-10 left-1/2 transform -translate-x-1/2 bg-green-50 text-green-800 border border-green-300 rounded-lg p-4 z-[99]">
<div class="flex items-center">
<svg class="flex-shrink-0 w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 20">
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z" />
</svg>
<span class="font-medium">{{ session('success') }}</span>
</div>
</div>
@endif
@if (session('error'))
<div id="notification"
class="fixed top-10 left-1/2 transform -translate-x-1/2 bg-red-50 text-red-800 border border-red-300 rounded-lg p-4 z-[99]">
<div class="flex items-center">
<svg class="flex-shrink-0 w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 20 20">
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z" />
</svg>
<span class="font-medium">{{ session('error') }}</span>
</div>
</div>
@endif
<script>
document.addEventListener('DOMContentLoaded', function() {
const notification = document.getElementById('notification');
if (notification) {
setTimeout(() => {
notification.classList.add('hidden');
}, 5000); // 5000 milliseconds = 5 seconds
}
});
</script>

View File

@ -1,4 +1,11 @@
<x-layout> <x-layout>
<div class="py-10 bg-white ">
<div class="bg-[#EBFEA1] container poppins-extrabold m-auto flex items-center justify-center p-2">
<p>Halaman ini berisi tentang kursus di Pare! </p>
</div>
</div>
@if (session('error')) @if (session('error'))
<div <div
class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50"> class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50">
@ -8,96 +15,319 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-
@error('rating') @error('rating')
<div <div
class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50"> class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-md shadow-lg z-50">
{{ $message }} {{ $message }}</div>
</div>
@enderror @enderror
<div class="container flex justify-center items-center pb-16">
<section id="gambarutama">
<div class="h-auto w-full ">
<img src=" {{ asset('storage/' . $data->img) }}" alt=""
class="h-[350px] sm:h-[400px] md:h-[450px] lg:h-[500px] xl:h-[ ] w-full">
</div>
<div class="flex justify-center items-center p-4 pt-20 md:pt-4"> </section>
<div class="h-auto w-full relative ">
<img src="{{ asset('storage/' . $data->img) }}" alt=""
class="aspect-[4/3] lg:aspect-[655px] 2xl:h-[895px] w-full object-cover brightness-75 rounded-2xl">
<figcaption class="container w-full">
<div
class="absolute container bottom-4 lg:bottom-12 left-1/2 transform -translate-x-1/2 space-y-10 text-center px-4">
<p class="poppins-bold text-start text-5xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl 2xl:text-9xl text-green-800 pr-16 w-3/4 xl:w-1/2"
style="text-shadow: 2px 2px 4px white;">
{{ $data->nama_kursus }}
</p>
<div class="flex justify-between w-full text-white text-[10px] lg:text-sm" id="tab-buttons">
<button data-target="overview"
class="tab-btn px-8 py-1.5 sm:px-12 md:px-16 sm:py-2 2xl:px-20 xl:py-3 poppins-regular border-white border-2 rounded-3xl bg-white/10 backdrop-blur">Deskripsi</button>
<button data-target="paket"
class="tab-btn px-8 py-1.5 sm:px-12 md:px-16 sm:py-2 2xl:px-20 xl:py-3 poppins-regular border-white border-2 rounded-3xl bg-white/10 backdrop-blur">Paket</button>
<button data-target="metode"
class="tab-btn px-8 py-1.5 sm:px-12 md:px-16 sm:py-2 2xl:px-20 xl:py-3 poppins-regular border-white border-2 rounded-3xl bg-white/10 backdrop-blur">Metode</button>
<button data-target="lokasi"
class="tab-btn px-8 py-1.5 sm:px-12 md:px-16 sm:py-2 2xl:px-20 xl:py-3 poppins-regular border-white border-2 rounded-3xl bg-white/10 backdrop-blur">Lokasi</button>
</div>
</div>
</figcaption>
</div>
</div> </div>
<div class="container px-0 lg:px-4">
<div id="overview" class="tab-content"> <div class="container">
@include('partials.detail.deskripsi') <p class="poppins-medium font-semibold text-3xl xl:text-4xl text-black">{{ $data->nama_kursus }}</p>
<p class="poppins-medium font-semibold text-sm xl:text-xl text-black pb-4">
({{ optional($data->kategoris)->nama_kategori ?? 'Kategori tidak tersedia' }}
)</p>
<a href="/kursus/{{ $data->id }}/rute" target="_blank"
class="poppins-medium py-2 px-4 bg-[#4F7F81] text-white rounded-xl text-sm shadow-xl">Rute Terdekat</a>
<button data-modal-target="default-modal-detail-gambar" data-modal-toggle="default-modal-detail-gambar"
class="poppins-medium py-2 px-4 bg-[#4F7F81] text-white rounded-xl text-sm shadow-xl">Foto Detail</button>
<!-- Main modal -->
<div id="default-modal-detail-gambar" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl xl:max-w-3xl 2xl:max-w-4xl max-h-full">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="p-4 md:p-5 space-y-4">
<div class="relative overflow-hidden rounded-lg gap-4 space-y-4 ">
@if (!empty($imageNames) && count($imageNames) > 0)
@foreach ($imageNames as $index => $img_konten)
<div class="border border-slate-300 rounded-md p-4">
<img src="{{ asset('storage/' . $img_konten) }}"
class="w-full h-auto object-contain" alt="Image {{ $index + 1 }}">
</div>
@endforeach
@else
<div class="block duration-1000 ease-in-out" data-carousel-item>
<img src="https://via.placeholder.com/600x400" class="w-full h-auto object-contain"
alt="No image available">
</div>
@endif
</div>
</div>
</div>
</div>
</div> </div>
<div id="paket" class="tab-content hidden">
@include('partials.detail.paket')
<div class="text-black poppins-medium font-semibold pb-2 text-2xl pt-4 poppins-semibold">
<p>Deskripsi</p>
</div> </div>
<div id="metode" class="tab-content hidden"> <div>
@include('partials.detail.metode') <p class="poppins-medium text-black text-lg pb-2" id="deskripsi-text">
{{ Str::limit($data->deskripsi, 500, '...') }}
</p>
@if (strlen($data->deskripsi) > 500)
<button id="toggle-deskripsi" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div> </div>
<div id="lokasi" class="tab-content hidden">
@include('partials.detail.lokasi') <div class="grid grid-cols-1 gap-4 py-10">
{{-- Bagian Paket --}}
<div class="w-auto xl:max-w-max space-y-2">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Paket
</p>
<p class="poppins-medium text-lg text-black" id="paket-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->paket, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->paket)) > 250)
<button id="toggle-paket" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
{{-- Bagian Metode Pembelajaran --}}
<div class="w-auto xl:max-w-max space-y-2">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Metode Pembelajaran
</p>
<p class="poppins-medium text-lg text-black" id="metode-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->metode, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->metode)) > 250)
<button id="toggle-metode" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
{{-- Bagian Fasilitas --}}
<div class="w-auto xl:max-w-max space-y-2">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Fasilitas
</p>
<p class="poppins-medium text-lg text-black" id="fasilitas-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->fasilitas, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->fasilitas)) > 250)
<button id="toggle-fasilitas" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
{{-- Bagian Lokasi --}}
<div class="w-auto xl:max-w-max space-y-2">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Lokasi
</p>
<p class="poppins-medium text-lg text-black" id="lokasi-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->lokasi, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->lokasi)) > 250)
<button id="toggle-lokasi" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
</div> </div>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const buttons = document.querySelectorAll('.tab-btn'); // Fungsi reusable untuk mengatur toggle teks
const contents = document.querySelectorAll('.tab-content'); function toggleText(elementId, buttonId, fullText) {
const textElement = document.getElementById(elementId);
const toggleButton = document.getElementById(buttonId);
function activateTab(targetId) { if (toggleButton) {
// Sembunyikan semua konten const shortText = textElement.innerHTML; // Teks pendek yang sudah dirender
contents.forEach(content => content.classList.add('hidden')); toggleButton.addEventListener('click', function() {
if (textElement.innerHTML === shortText) {
// Reset semua tombol // Tampilkan teks penuh
buttons.forEach(btn => { textElement.innerHTML = fullText;
btn.classList.remove('bg-gradient-to-tr', 'from-[#60BC9D]', 'to-[#12372A]', toggleButton.innerText = 'Tampilkan Lebih Sedikit';
'ring-white', 'scale-105'); } else {
btn.classList.add('bg-white/10', 'backdrop-blur'); // Kembalikan ke teks pendek
}); textElement.innerHTML = shortText;
toggleButton.innerText = 'Lihat Selengkapnya';
// Tampilkan konten sesuai target }
const targetContent = document.getElementById(targetId); });
if (targetContent) targetContent.classList.remove('hidden');
// Aktifkan tombol terkait
const activeButton = document.querySelector(`.tab-btn[data-target="${targetId}"]`);
if (activeButton) {
activeButton.classList.remove('bg-white/10', 'backdrop-blur');
activeButton.classList.add('bg-gradient-to-tr', 'from-[#60BC9D]', 'to-[#12372A]',
'ring-white', 'scale-105');
} }
} }
// Default tab // Terapkan fungsi ke setiap bagian
activateTab('overview'); toggleText('paket-text', 'toggle-paket', @json($data->paket));
toggleText('metode-text', 'toggle-metode', @json($data->metode));
// Tambahkan event ke semua tombol toggleText('fasilitas-text', 'toggle-fasilitas', @json($data->fasilitas));
buttons.forEach(button => { toggleText('lokasi-text', 'toggle-lokasi', @json($data->lokasi));
button.addEventListener('click', function() { toggleText('deskripsi-text', 'toggle-deskripsi', @json($data->deskripsi));
const target = this.getAttribute('data-target');
activateTab(target);
});
});
}); });
</script> </script>
<div class="grid grid-cols-6 gap-4 py-20 ">
<!-- Left Column: Comment Form -->
<!-- Right Column: Ratings and Reviews -->
<div class="col-span-4 ">
<!-- Ratings Section -->
<div class="bg-gray-50">
<div class=" flex justify-between items-center">
<div class="flex w-full items-center">
<div class="flex items-center">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= round($averageRating) ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
<span class="text-sm pl-4">Rata-rata: {{ round($averageRating, 1) }} / 5</span>
</div>
<div class=" md:ml-4">
<p class="poppins-medium font-semibold text-sm xl:text-xl text-black">
(Total: {{ $totalRatings }} ulasan)
</p>
</div>
</div>
<div class="w-full">
{{ $ulasan->links() }}
</div>
</div>
<!-- Reviews Section -->
</div>
<div class="grid md:grid-cols-3 gap-4 items-center justify-end rtl">
@foreach ($ulasan as $review)
<div class="mb-6 mt-4 p-4 bg-white rounded-lg shadow-xl">
<!-- Reviewer Info -->
<div class="flex items-center mb-3">
<img src="/img/profil.png" alt="User Avatar" class="w-10 h-10 rounded-full mr-4">
<div>
<h4 class="font-bold text-gray-800">{{ $review->user->name ?? 'Anonim' }}</h4>
<p class="text-sm text-gray-500">
{{ $review->created_at->diffForHumans() }}
</p>
</div>
</div>
<!-- Reviewer Rating -->
<div class="flex items-center mb-2">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= $review->rating ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
</div>
<!-- Review Comment -->
<p class="text-gray-700">{{ $review->comment }}</p>
</div>
@endforeach
</div>
<!-- Pagination Links -->
</div>
<div class="col-span-2">
@auth
<form action="{{ route('storeUlasan') }}" method="POST">
@csrf
<div class="max-w-xl mb-4 border border-gray-200 rounded-lg bg-gray-50">
<!-- Comment Input -->
<div class="hidden">
<input name="user_id" value="{{ Auth::user()->id }}" type="text">
<input name="kursus_id" value="{{ $data->id }}" type="text">
</div>
<div class="px-4 py-2 bg-white rounded-t-lg">
<label for="comment" class="sr-only">Your comment</label>
<textarea id="comment" name="comment" rows="4"
class="w-full px-0 text-sm text-gray-900 bg-white border-0 focus:ring-0 placeholder-gray-400"
placeholder="Write a comment..." required></textarea>
</div>
<!-- Rating Stars and Submit Button -->
<div class="flex items-center justify-between px-3 py-2 border-t border-gray-200">
<!-- Rating Stars -->
<div class="flex items-center space-x-2" id="rating-stars">
@for ($i = 1; $i <= 5; $i++)
<label class="cursor-pointer">
<input type="radio" name="rating" value="{{ $i }}"
class="hidden" />
<svg class="w-6 h-6 text-gray-300 hover:text-yellow-400 transition-colors duration-200"
xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
</label>
@endfor
</div>
<script>
// JavaScript for managing star ratings
const starsContainer = document.getElementById('rating-stars');
const stars = starsContainer.querySelectorAll('svg');
const inputs = starsContainer.querySelectorAll('input[type="radio"]');
stars.forEach((star, index) => {
star.addEventListener('click', () => {
// Set all previous stars to active
stars.forEach((s, i) => {
if (i <= index) {
s.classList.add('text-yellow-400');
s.classList.remove('text-gray-300');
} else {
s.classList.add('text-gray-300');
s.classList.remove('text-yellow-400');
}
});
// Set the corresponding radio input
inputs[index].checked = true;
});
});
</script>
<!-- Submit Button -->
<button type="submit"
class="inline-flex items-center py-2.5 px-4 text-xs font-medium text-center text-white bg-blue-700 rounded-lg focus:ring-4 focus:ring-blue-200 hover:bg-blue-800">
Post Comment
</button>
</div>
</div>
</form>
@endauth
@guest
<p class="text-sm text-gray-500">
Anda harus <a href="{{ route('login') }}" class="text-blue-600 hover:underline">login</a> untuk
memberikan ulasan.
</p>
@endguest
<!-- Community Guidelines -->
<p class="ms-auto text-xs text-gray-500">
Remember, contributions to this topic should follow our
<a href="#" class="text-blue-600 hover:underline">Community Guidelines</a>.
</p>
</div>
</div>
</div> </div>
{{-- @include('partials.detail.deskripsi') --}}
</x-layout> </x-layout>

View File

@ -1,210 +1,99 @@
<x-layout> <x-layout>
<div class="bg-gray-100"> <div class="container">
<!-- Hero Section --> <div class="py-10 bg-white ">
<div class="relative"> <div class="bg-[#EBFEA1] poppins-extrabold m-auto flex items-center justify-center p-2">
<!-- Gambar --> <p>Holaa, Selamat Datang Di LearnMap</p>
<img alt="LearnMap Hero Image"
class="h-[420px] sm:h-[450px] md:h-[480px] lg:h-[545px] xl:h-[645px] 2xl:h-[945px] brightness-100 w-full object-cover "
src="{{ asset('img/bg-home.jpg') }}">
<!-- Overlay Teks -->
<div
class="absolute inset-0 flex items-center justify-center mb-14 sm:mb-14 md:mb-20 lg:mb-32 xl:mb-44 2xl:mb-72">
<div class="text-white">
<div>
<h1 class=" text-green-600 text-5xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl 2xl:text-9xl
font-bold text-center barlow-condensed-semibold drop-shadow-lg"
style="text-shadow: 2px 2px 4px white;">
PARE EDUCATION <br> ENGLISH LANGUAGE
</h1>
<p
class="px-4 container text-xs sm:text-sm md:text-md lg:text-base xl:text-xl 2xl:text-2xl text-center text-green-700 font-weight-bold poppins-bold mb-2 xl:mb-6 barlow-condensed-semibold drop-shadow-lg">
Belajar bahasa Inggris dengan metode menarik dan akses mudah di LearnMap.
</p>
</div>
<div class="flex justify-center">
<a class="text-white text-xs sm:text-xs md:text-base xl:text-2xl uppercase barlow-condensed-semibold px-4 py-1 xl:px-8 xl:py-2 rounded-md xl:rounded-xl bg-gradient-to-tr from-[#60BC9D] to-[#12372A]"
href="{{ route('user.kursus') }}">
Jelajahi
</a>
</div>
</div>
</div> </div>
</div> </div>
<!-- About Section --> </div>
<div class="flex m-auto justify-center items-center responsive-container">
<img src="{{ asset('img/Rectangle 227.png') }}" class="w-full h-full" alt="">
</div>
<div class="pt-8 bg-[#86A7A8] ">
<div class="container pb-20">
<div class="flex justify-between items-center pb-4 ">
<!-- Popular Courses Section --> <p class="text-black poppins-semibold text-xl">
<div class="container px-4 space-y-8 lg:space-y-12 2xl:space-y-20 py-10 xl:py-16"> Kursus Populer
{{-- Tentang Kami --}}
<div class="">
<div class="flex ">
<div class="">
<h2
class="text-2xl lg:text-3xl 2xl:text-5xl barlow-condensed-semibold text-green-800 font-bold mb-1">
TENTANG KAMI
</h2>
<h2
class="text-start poppins-regular text-xs lg:text-base 2xl:text-xl text-gray-600 mb-2 lg:mb-6">
LearnMap adalah sebuah aplikasi website Sistem Informasi Geografis (SIG) yang dirancang
khusus
untuk memudahkan Anda menemukan tempat bimbingan belajar bahasa Inggris terbaik di Kecamatan
Pare,
Kabupaten Kediri. Kami menyediakan berbagai pilihan kursus berkualitas tinggi dengan tutor
berpengalaman,
metode pembelajaran yang interaktif dan menarik, serta akses yang mudah dan cepat melalui
platform digital
kami. Dengan LearnMap, Anda dapat menjelajahi informasi lengkap tentang lokasi, program, dan
fasilitas
bimbingan belajar, sehingga membantu Anda meningkatkan keterampilan bahasa Inggris secara
efektif dan
mewujudkan mimpi Anda untuk menguasai bahasa internasional ini dengan lebih percaya diri.
</h2>
<div class="flex">
<a class="text-xs lg:text-sm 2xl:text-lg poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white px-4 py-2 2xl:px-6 2xl:py-3 rounded-md"
href="">
Pelajari Lebih Lanjut
</a>
</div>
</div>
{{-- <img alt="About LearnMap" class="w-auto h-128 object-contain "
src="{{ asset('img/img/tentang kami.jpg') }}" /> --}}
</div>
</div>
<!-- PETA -->
<div id="" class=" relative z-[1] ">
<div class=" flex justify-between">
<!-- Section Title -->
<div class="w-full ">
<p
class="text-2xl lg:text-3xl 2xl:text-5xl font-bold text-start barlow-condensed-semibold text-green-800">
PERSEBARAN KURSUS</p>
<h5 class="text-start poppins-regular mb-4 text-xs lg:text-base 2xl:text-xl text-gray-600">
Berikut adalah persebaran
seluruh wisata saat ini
</h5>
<div class="aspect-[5/3] lg:aspect-[5/2]" id="map"></div>
</div>
</div>
<!-- LEAFLET JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const mapElement = document.getElementById('map');
if (!mapElement) {
console.warn("Element dengan ID 'map' tidak ditemukan.");
return;
}
// Tentukan zoom level berdasarkan ukuran layar
let zoomLevel = 15; // default
const width = window.innerWidth;
if (width < 640) { // sm
zoomLevel = 13;
} else if (width < 768) { // md
zoomLevel = 13.5;
} else if (width < 1024) { // lg
zoomLevel = 14;
} else if (width < 1280) { // xl
zoomLevel = 14.5;
} else { // 2xl dan ke atas
zoomLevel = 15;
}
// Inisialisasi Leaflet map
const map = L.map('map').setView([-7.7560717, 112.1823541], zoomLevel);
// Tambahkan tile layer
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Tambahkan marker dari database jika ada data
@if ($peta->isNotEmpty())
@foreach ($peta as $latlong)
L.marker([{{ $latlong->latitude }}, {{ $latlong->longitude }}]).addTo(map)
.bindPopup(`
<b>{{ addslashes($latlong->nama_kursus) }}</b> <br>
<img class="w-32 h-20 object-cover" src="{{ asset('storage/' . $latlong->img) }}" alt="{{ addslashes($latlong->nama_kursus) }}" /> <br>
<a href="{{ url('/kursus/' . $latlong->id . '/detail') }}" class="text-blue-500 underline">Selengkapnya</a>
`);
@endforeach
@else
// Jika tidak ada data, tambahkan titik default
L.marker([-7.7560717, 112.1823541]).addTo(map)
.bindPopup('<b>Default Marker: Pusat Kota Pare</b>');
@endif
// Pastikan peta menyesuaikan ukuran container
setTimeout(() => {
map.invalidateSize();
}, 500);
});
</script>
</div>
{{-- Kursus Populer --}}
<div>
<h2
class="text-2xl lg:text-3xl 2xl:text-5xl font-bold text-start barlow-condensed-semibold text-green-800">
KURSUS POPULER
</h2>
<p class="text-start poppins-regular mb-4 text-xs lg:text-base 2xl:text-xl text-gray-600">
Pilih kursus yang sesuai dengan kebutuhan Anda
</p> </p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8"> <a href="/kursus" class="py-1 px-4 rounded-full bg-white font-bold text-lg ">
@if ($landingpage->isNotEmpty()) Lihat Semua Kursus
@foreach ($landingpage as $landingpage) </a>
<div </div>
class="bg-white rounded-lg shadow-md overflow-hidden transition ease-in-out delay-0 hover:-translate-y-1 hover:scale-100 duration-300 h-full flex flex-col">
<div class="grid grid-cols-1 md:grid-cols-1 xl:grid-cols-3 gap-8 m-auto justify-center items-center">
@if ($landingpage->isNotEmpty())
@foreach ($landingpage as $landingpage)
<div
class="w-full h-full bg-white border border-gray-200 rounded-lg transition ease-in-out delay-0 hover:-translate-y-1 hover:scale-100 duration-300">
<div class="">
<a href="#"> <a href="#">
<img class="w-full h-48 object-cover" <img class="rounded-lg m-auto flex justify-center items-center w-full h-72 object-cover"
src="{{ asset('storage/' . $landingpage->img) }}" src="{{ asset('storage/' . $landingpage->img) }}" alt="" />
alt="{{ $landingpage->nama_kursus }}" />
</a> </a>
<div class="p-4 flex flex-col flex-grow "> <div class="p-5 h-44">
<h3 <a href="#">
class="text-base lg:text-lg 2xl:text-xl font-semibold poppins-bold uppercase text-green-800"> <h5
{{ $landingpage->nama_kursus }} class="mb-2 text-2xl poppins-regular font-extrabold tracking-tight text-gray-900 ">
</h3> {{ $landingpage->nama_kursus }}</h5>
<p </a>
class="pb-8 text-xs lg:text-sm 2xl:text-base text-gray-700 poppins-regular flex-grow"> <p class="mb-3 font-normal poppins-regular text-gray-700">
{{ Str::words($landingpage->deskripsi, 20, '...') }} {{ Str::words($landingpage->deskripsi, 30, '...') }}
</p> </p>
<a class="poppins-regular mt-auto inline-block bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white py-2 lg:py-3 rounded-md text-center text-sm lg:text-base" </div>
href="/kursus/{{ $landingpage->id }}/detail"> </div>
Lihat Detail <div class="flex items-end justify-end bg-white rounded-b-lg ">
<div class="mb-4 mr-4 ">
<a href="/kursus/{{ $landingpage->id }}/detail"
class="inline-flex items-center px-6 py-2 text-sm font-extrabold text-black ring-2 ring-black rounded-full hover:text-white hover:bg-[#4F7F81] hover:ring-[#4F7F81] focus:ring-4 focus:outline-none focus:ring-blue-300">
Lihat
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9" />
</svg>
</a> </a>
</div> </div>
</div> </div>
@endforeach
@else </div>
<div @endforeach
class="col-span-3 py-10 bg-[#EBFEA1] poppins-extrabold flex items-center justify-center p-2"> @else
<div class="py-10 flex col-span-3">
<div class="bg-[#EBFEA1] w-full poppins-extrabold m-auto flex items-center justify-center p-2">
<p>Tidak Tersedia Kursus</p> <p>Tidak Tersedia Kursus</p>
</div> </div>
@endif </div>
</div> @endif
</div> </div>
</div> </div>
</div>
<div class="container py-16">
<p class="text-xl poppins-semibold ">Tentang Kami</p>
<div class="grid xl:grid-cols-2 grid-cols-1 ">
<div class="text-xl poppins-semibold">
<p class="py-4">
Tingkatkan Kemampuan Bahasa Inggris Anda dengan LearnMap!
</p>
<p>
Selamat datang di LearnMap, aplikasi website Sistem Informasi Geografis bimbingan belajar bahasa
Inggris di Kecamatan Pare, yang didirikan dengan semangat memberdayakan individu melalui
pengetahuan. Kami menyediakan berbagai kursus berkualitas tinggi, metode belajar menarik, dan
akses mudah untuk membantu Anda meningkatkan keterampilan dan mencapai mimpi. Mulailah
perjalanan Anda untuk menguasai bahasa Inggris
</p>
</div>
<div class="flex items-center justify-center">
<img src="{{ asset('img/imgcewe.png') }}" alt="">
</div>
</div>
</div>
</x-layout> </x-layout>

View File

@ -1,10 +1,16 @@
<x-layout> <x-layout>
<div class="container pb-20 pt-20 px-4"> <div class="py-10 bg-white container">
<div class="bg-[#EBFEA1] poppins-extrabold m-auto flex items-center justify-center p-2">
<p>Halaman ini berisi tentang kursus di Pare! </p>
</div>
</div>
<div class="container pb-20">
<div class="flex justify-end space-x-2 py-4"> <div class="flex justify-end space-x-2 py-4">
<form method="GET" action="{{ route('user.kursus') }}" class="flex space-x-2"> <form method="GET" action="{{ route('user.kursus') }}" class="flex space-x-2">
<!-- Dropdown Kategori --> <!-- Dropdown Kategori -->
<select name="kategori" onchange="this.form.submit()" <select name="kategori" onchange="this.form.submit()"
class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm poppins-regular"> class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm">
<option value="">Semua Kategori</option> <option value="">Semua Kategori</option>
@foreach ($kategori as $item) @foreach ($kategori as $item)
<option value="{{ $item->id }}" {{ request('kategori') == $item->id ? 'selected' : '' }}> <option value="{{ $item->id }}" {{ request('kategori') == $item->id ? 'selected' : '' }}>
@ -16,34 +22,33 @@ class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm poppins-regul
<!-- Search Input --> <!-- Search Input -->
<div class="relative"> <div class="relative">
<input type="text" name="search" id="search-dropdown" <input type="text" name="search" id="search-dropdown"
class="pr-14 pl-4 p-2.5 w-full text-sm text-black bg-white border border-gray-300 rounded-md poppins-regular" class="pr-14 pl-4 p-2.5 w-full text-sm text-gray-900 bg-gray-50 border border-gray-300 rounded-md"
placeholder="Pencarian Kursus" value="{{ request('search') }}" /> placeholder="Pencarian Nama Kursus" value="{{ request('search') }}" />
<button type="submit" <button type="submit"
class="absolute top-0 end-0 px-4 h-full text-sm font-medium text-white bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-e-lg"> class="absolute top-0 end-0 px-4 h-full text-sm font-medium text-white bg-[#4F7F81] rounded-e-lg">
🔍 🔍
</button> </button>
</div> </div>
</form> </form>
</div> </div>
{{-- {{ $data_kursus->links() }} --}}
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 justify-center pb-4 items-center gap-4 !important"> <div class="grid md:grid-cols-1 lg:grid-cols-3 justify-center items-center gap-4 !important">
@foreach ($data_kursus as $kursus) @foreach ($data_kursus as $kursus)
<div class="kursus-item max-w-xl h-ful mx-auto shadow-2xl rounded-lg"> <div class="kursus-item h-ful shadow-2xl rounded-lg ">
<div> <div>
<div> <div>
<img class=" flex justify-center items-center w-full h-64 object-cover rounded-lg" <img class=" flex justify-center items-center w-full h-64 object-cover"
src="{{ asset('storage/' . $kursus->img) }}" alt="" /> src="{{ asset('storage/' . $kursus->img) }}" alt="" />
</div> </div>
<div class="p-5 h-44"> <div class="p-5 h-44">
<div> <div>
<h5 <h5
class="barlow-condensed-semibold text-green-800 nama-kursus mb-2 text-2xl poppins-regular font-extrabold tracking-tight "> class="nama-kursus mb-2 text-xl poppins-regular font-extrabold tracking-tight text-gray-900">
{{ $kursus->nama_kursus }} {{ $kursus->nama_kursus }}
</h5> </h5>
<h5 <h5
class="poppins-regular text-black nama-kursus mb-2 text-sm poppins-regular font-extrabold tracking-tight "> class="nama-kursus mb-2 text-sm poppins-regular font-extrabold tracking-tight text-gray-900">
{{ optional($kursus->kategoris)->nama_kategori ?? 'Kategori tidak tersedia' }} {{ optional($kursus->kategoris)->nama_kategori ?? 'Kategori tidak tersedia' }}
</h5> </h5>
</div> </div>
@ -55,7 +60,7 @@ class="poppins-regular text-black nama-kursus mb-2 text-sm poppins-regular font-
<div class="flex items-end justify-end rounded-b-lg"> <div class="flex items-end justify-end rounded-b-lg">
<div class="my-4 mr-4"> <div class="my-4 mr-4">
<a href="/kursus/{{ $kursus->id }}/detail" <a href="/kursus/{{ $kursus->id }}/detail"
class="poppins-regular inline-flex items-center px-6 py-2 text-sm font-extrabold text-slate-700 ring-1 ring-slate-500 rounded-full hover:text-white hover:bg-green-800 hover:ring-green-800 focus:ring-4 focus:outline-none focus:ring-blue-300"> class="inline-flex items-center px-6 py-2 text-sm font-extrabold text-slate-700 ring-1 ring-slate-500 rounded-full hover:text-white hover:bg-[#4F7F81] hover:ring-[#4F7F81] focus:ring-4 focus:outline-none focus:ring-blue-300">
Lihat Lihat
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" <svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"> xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
@ -68,10 +73,6 @@ class="poppins-regular inline-flex items-center px-6 py-2 text-sm font-extrabold
</div> </div>
@endforeach @endforeach
</div> </div>
{{ $data_kursus->links() }}
</div> </div>
{{-- <script> {{-- <script>

View File

@ -4,40 +4,17 @@
max-width: 100%; max-width: 100%;
} }
</style> </style>
<div class="container py-14 px-4"> <div class="container flex flex-col">
<div class="py-10 lg:py-16 2xl:py-20"> <div class="py-10 bg-white">
<div class="bg-[#EBFEA1] poppins-extrabold m-auto flex items-center justify-center p-2">
<p>Halaman ini berisi tentang kursus di Pare!</p>
</div>
</div>
<div class="pb-10">
<!-- Peta Leaflet --> <!-- Peta Leaflet -->
<div id="map1" <div id="map1"
class="w-full h-56 sm:h-64 md:h-96 lg:h-[500px] xl:h-[650px] max-w-4xl rounded-lg shadow-lg"></div> class="w-full h-56 sm:h-64 md:h-96 lg:h-[500px] xl:h-[650px] max-w-4xl rounded-lg shadow-lg"></div>
</div> </div>
<div class="">
<h2 class="text-2xl lg:text-3xl 2xl:text-5xl barlow-condensed-semibold text-green-800 font-bold mb-1">
PETA LEARN-MAP
</h2>
<h2 class="text-start poppins-regular text-xs lg:text-base 2xl:text-xl text-gray-600 mb-2 lg:mb-6">
LearnMap adalah sebuah aplikasi website Sistem Informasi Geografis (SIG) yang dirancang
khusus
untuk memudahkan Anda menemukan tempat bimbingan belajar bahasa Inggris terbaik di Kecamatan
Pare,
Kabupaten Kediri. Kami menyediakan berbagai pilihan kursus berkualitas tinggi dengan tutor
berpengalaman,
metode pembelajaran yang interaktif dan menarik, serta akses yang mudah dan cepat melalui
platform digital
kami. Dengan LearnMap, Anda dapat menjelajahi informasi lengkap tentang lokasi, program, dan
fasilitas
bimbingan belajar, sehingga membantu Anda meningkatkan keterampilan bahasa Inggris secara
efektif dan
mewujudkan mimpi Anda untuk menguasai bahasa internasional ini dengan lebih percaya diri.
</h2>
<div class="flex">
<a class="text-xs lg:text-sm 2xl:text-lg poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white px-4 py-2 2xl:px-6 2xl:py-3 rounded-md"
href="">
Pelajari Lebih Lanjut
</a>
</div>
</div>
</div> </div>
<!-- Leaflet CSS dan JS --> <!-- Leaflet CSS dan JS -->
@ -49,35 +26,32 @@ class="w-full h-56 sm:h-64 md:h-96 lg:h-[500px] xl:h-[650px] max-w-4xl rounded-l
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
// Pastikan elemen "map1" ada sebelum inisialisasi // Inisialisasi peta dengan koordinat dan tingkat zoom
var mapElement = document.getElementById('map1'); const map = L.map('map1').setView([-7.7517397, 112.1780461],
if (!mapElement) { 13); // Gunakan 'map1' untuk ID peta yang sesuai
console.warn("Elemen dengan ID 'map1' tidak ditemukan.");
return;
}
// Inisialisasi Leaflet Map // Tambahkan lapisan ubin dari OpenStreetMap
const map = L.map('map1').setView([-7.7560717, 112.1823541], 15);
// Tambahkan tile layer dari OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map); }).addTo(map);
// Tambahkan marker dari data Blade // Menambahkan marker secara dinamis dengan data dari Blade
@foreach ($latilongti as $data) @foreach ($latilongti as $latilongti)
L.marker([{{ $data->latitude }}, {{ $data->longitude }}]).addTo(map) L.marker([{{ $latilongti->latitude }}, {{ $latilongti->longitude }}])
.bindPopup(` .addTo(map)
<div class="h-auto w-full"> .bindPopup(
<img src="{{ asset('storage/' . $data->img) }}" alt="{{ addslashes($data->nama_kursus) }}" class="w-full h-20 object-contain"> '<div class="h-auto w-full">' +
</div> '<img src="{{ asset('storage/' . $latilongti->img) }}" alt="" class="w-full h-20 object-contain">' +
<p> '</div>' +
<b>{{ addslashes($data->nama_kursus) }}</b> <br> '<p>' +
<a href="{{ url('/kursus/' . $data->id . '/detail') }}" class="text-blue-500 underline">Selengkapnya</a> '{{ $latilongti->nama_kursus }} <br>' +
</p>
`); '<a href="/kursus/{{ $latilongti->id }}/detail">Selengkapnya</a>'
)
.openPopup();
@endforeach @endforeach
}); });
</script> </script>
</x-layout> </x-layout>

View File

@ -1,46 +0,0 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -1,88 +0,0 @@
@if ($paginator->hasPages())
<nav class="d-flex justify-items-center justify-content-between">
<div class="d-flex justify-content-between flex-fill d-sm-none">
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
</div>
<div class="d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between">
<div>
<p class="small text-muted">
{!! __('Showing') !!}
<span class="fw-semibold">{{ $paginator->firstItem() }}</span>
{!! __('to') !!}
<span class="fw-semibold">{{ $paginator->lastItem() }}</span>
{!! __('of') !!}
<span class="fw-semibold">{{ $paginator->total() }}</span>
{!! __('results') !!}
</p>
</div>
<div>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</div>
</div>
</nav>
@endif

View File

@ -1,46 +0,0 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span aria-hidden="true">&lsaquo;</span>
</li>
@else
<li>
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li>
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -1,36 +0,0 @@
@if ($paginator->hasPages())
<div class="ui pagination menu" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@else
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
@else
<a class="item" href="{{ $url }}">{{ $page }}</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@else
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@endif
</div>
@endif

View File

@ -1,27 +0,0 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -1,29 +0,0 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation">
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">{!! __('pagination.previous') !!}</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">
{!! __('pagination.previous') !!}
</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">{!! __('pagination.next') !!}</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">{!! __('pagination.next') !!}</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@ -1,19 +0,0 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
@else
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
@endif
</ul>
</nav>
@endif

View File

@ -1,25 +0,0 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md ">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 ">
{!! __('pagination.previous') !!}
</a>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 ">
{!! __('pagination.next') !!}
</a>
@else
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md ">
{!! __('pagination.next') !!}
</span>
@endif
</nav>f
@endif

View File

@ -1,130 +0,0 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
<div class="flex justify-between flex-1 sm:hidden">
@if ($paginator->onFirstPage())
<span
class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md ">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}"
class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 ">
{!! __('pagination.previous') !!}
</a>
@endif
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}"
class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 ">
{!! __('pagination.next') !!}
</a>
@else
<span
class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md ">
{!! __('pagination.next') !!}
</span>
@endif
</div>
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p class="text-sm text-gray-700 leading-5 ">
{!! __('Showing') !!}
@if ($paginator->firstItem())
<span class="font-medium">{{ $paginator->firstItem() }}</span>
{!! __('to') !!}
<span class="font-medium">{{ $paginator->lastItem() }}</span>
@else
{{ $paginator->count() }}
@endif
{!! __('of') !!}
<span class="font-medium">{{ $paginator->total() }}</span>
{!! __('results') !!}
</p>
</div>
<div>
<span class="relative z-0 inline-flex rtl:flex-row-reverse shadow-sm rounded-md">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
<span
class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5 "
aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd" />
</svg>
</span>
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev"
class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 "
aria-label="{{ __('pagination.previous') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd" />
</svg>
</a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<span aria-disabled="true">
<span
class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5 ">{{ $element }}</span>
</span>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<span aria-current="page">
<span
class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 ">{{ $page }}</span>
</span>
@else
<a href="{{ $url }}"
class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 "
aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
{{ $page }}
</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next"
class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 "
aria-label="{{ __('pagination.next') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd" />
</svg>
</a>
@else
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
<span
class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5 "
aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd" />
</svg>
</span>
</span>
@endif
</span>
</div>
</div>
</nav>
@endif

View File

@ -1,4 +1,4 @@
{{-- {{-- <!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@ -137,290 +137,4 @@
</div> </div>
</div> </div>
</body> </body>
</html> --}} </html>
<div class="container">
<p class="poppins-medium font-semibold text-sm xl:text-xl text-black pb-4">
({{ optional($data->kategoris)->nama_kategori ?? 'Kategori tidak tersedia' }}
)</p>
<!-- Main modal -->
<div id="default-modal-detail-gambar" tabindex="-1" aria-hidden="true"
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full max-w-2xl xl:max-w-3xl 2xl:max-w-4xl max-h-full">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="p-4 md:p-5 space-y-4">
<div class="relative overflow-hidden rounded-lg gap-4 space-y-4 ">
@if (!empty($imageNames) && count($imageNames) > 0)
@foreach ($imageNames as $index => $img_konten)
<div class="border border-slate-300 rounded-md p-4">
<img src="{{ asset('storage/' . $img_konten) }}"
class="w-full h-auto object-contain" alt="Image {{ $index + 1 }}">
</div>
@endforeach
@else
<div class="block duration-1000 ease-in-out" data-carousel-item>
<img src="https://via.placeholder.com/600x400" class="w-full h-auto object-contain"
alt="No image available">
</div>
@endif
</div>
</div>
</div>
</div>
</div>
<div class="text-black poppins-medium font-semibold pb-2 text-2xl pt-4 poppins-semibold">
<p>Deskripsi</p>
</div>
<div>
<p class="poppins-regular text-black text-lg pb-2" id="deskripsi-text">
{{ Str::limit($data->deskripsi, 500, '...') }}
</p>
@if (strlen($data->deskripsi) > 500)
<button id="toggle-deskripsi" class="text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
<div class="grid grid-cols-1 gap-4 py-10">
{{-- Bagian Paket --}}
<div class="w-auto xl:max-w-max space-y-4">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Paket
</p>
<p class="pl-4 poppins-regular text-lg text-black" id="paket-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->paket, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->paket)) > 200)
<button id="toggle-paket" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
{{-- Bagian Metode Pembelajaran --}}
<div class="w-auto xl:max-w-max space-y-4">
<p class="poppins-semibold text-2xl text-black underline">
Metode Pembelajaran
</p>
<p class="pl-4 poppins-regular text-lg text-black" id="metode-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->metode, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->metode)) > 250)
<button id="toggle-metode" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
{{-- Bagian Lokasi --}}
<div class="w-auto xl:max-w-max space-y-4">
<p class="poppins-semibold font-semibold text-2xl text-black underline">
Lokasi
</p>
<p class="pl-4 poppins-regular text-lg text-black" id="lokasi-text">
{!! htmlspecialchars_decode(Str::limit(strip_tags($data->lokasi, '<br><p><strong><em>'), 250, '...')) !!}
</p>
@if (strlen(strip_tags($data->lokasi)) > 250)
<button id="toggle-lokasi" class="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
Lihat Selengkapnya
</button>
@endif
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Fungsi reusable untuk mengatur toggle teks
function toggleText(elementId, buttonId, fullText) {
const textElement = document.getElementById(elementId);
const toggleButton = document.getElementById(buttonId);
if (toggleButton) {
const shortText = textElement.innerHTML; // Teks pendek yang sudah dirender
toggleButton.addEventListener('click', function() {
if (textElement.innerHTML === shortText) {
// Tampilkan teks penuh
textElement.innerHTML = fullText;
toggleButton.innerText = 'Tampilkan Lebih Sedikit';
} else {
// Kembalikan ke teks pendek
textElement.innerHTML = shortText;
toggleButton.innerText = 'Lihat Selengkapnya';
}
});
}
}
// Terapkan fungsi ke setiap bagian
toggleText('paket-text', 'toggle-paket', @json($data->paket));
toggleText('metode-text', 'toggle-metode', @json($data->metode));
toggleText('fasilitas-text', 'toggle-fasilitas', @json($data->fasilitas));
toggleText('lokasi-text', 'toggle-lokasi', @json($data->lokasi));
toggleText('deskripsi-text', 'toggle-deskripsi', @json($data->deskripsi));
});
</script>
<div class="grid grid-cols-6 gap-4 py-20 ">
<!-- Left Column: Comment Form -->
<!-- Right Column: Ratings and Reviews -->
<div class="col-span-4 ">
<!-- Ratings Section -->
<div class="bg-gray-50">
<div class=" flex justify-between items-center">
<div class="flex w-full items-center">
<div class="flex items-center">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= round($averageRating) ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
<span class="text-sm pl-4">Rata-rata: {{ round($averageRating, 1) }} / 5</span>
</div>
<div class=" md:ml-4">
<p class="poppins-medium poppins-regular text-sm xl:text-xl text-black">
(Total: {{ $totalRatings }} ulasan)
</p>
</div>
</div>
<div class="w-full">
{{ $ulasan->links() }}
</div>
</div>
<!-- Reviews Section -->
</div>
<div class="grid md:grid-cols-3 gap-4 items-center justify-end rtl">
@foreach ($ulasan as $review)
<div class="mb-6 mt-4 p-4 bg-white rounded-lg shadow-xl">
<!-- Reviewer Info -->
<div class="flex items-center mb-3">
<img src="/img/profil.png" alt="User Avatar" class="w-10 h-10 rounded-full mr-4">
<div>
<h4 class="font-bold text-gray-800">{{ $review->user->name ?? 'Anonim' }}</h4>
<p class="text-sm text-gray-500">
{{ $review->created_at->diffForHumans() }}
</p>
</div>
</div>
<!-- Reviewer Rating -->
<div class="flex items-center mb-2">
@for ($i = 1; $i <= 5; $i++)
<svg class="w-5 h-5 {{ $i <= $review->rating ? 'text-yellow-400' : 'text-gray-300' }}"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
@endfor
</div>
<!-- Review Comment -->
<p class="text-gray-700">{{ $review->comment }}</p>
</div>
@endforeach
</div>
<!-- Pagination Links -->
</div>
<div class="col-span-2">
@auth
<form action="{{ route('storeUlasan') }}" method="POST">
@csrf
<div class="max-w-xl mb-4 border border-gray-200 rounded-lg bg-gray-50">
<!-- Comment Input -->
<div class="hidden">
<input name="user_id" value="{{ Auth::user()->id }}" type="text">
<input name="kursus_id" value="{{ $data->id }}" type="text">
</div>
<div class="px-4 py-2 bg-white rounded-t-lg">
<label for="comment" class="sr-only">Your comment</label>
<textarea id="comment" name="comment" rows="4"
class="w-full px-0 text-sm text-gray-900 bg-white border-0 focus:ring-0 placeholder-gray-400"
placeholder="Write a comment..." required></textarea>
</div>
<!-- Rating Stars and Submit Button -->
<div class="flex items-center justify-between px-3 py-2 border-t border-gray-200">
<!-- Rating Stars -->
<div class="flex items-center space-x-2" id="rating-stars">
@for ($i = 1; $i <= 5; $i++)
<label class="cursor-pointer">
<input type="radio" name="rating" value="{{ $i }}"
class="hidden" />
<svg class="w-6 h-6 text-gray-300 hover:text-yellow-400 transition-colors duration-200"
xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z" />
</svg>
</label>
@endfor
</div>
<script>
// JavaScript for managing star ratings
const starsContainer = document.getElementById('rating-stars');
const stars = starsContainer.querySelectorAll('svg');
const inputs = starsContainer.querySelectorAll('input[type="radio"]');
stars.forEach((star, index) => {
star.addEventListener('click', () => {
// Set all previous stars to active
stars.forEach((s, i) => {
if (i <= index) {
s.classList.add('text-yellow-400');
s.classList.remove('text-gray-300');
} else {
s.classList.add('text-gray-300');
s.classList.remove('text-yellow-400');
}
});
// Set the corresponding radio input
inputs[index].checked = true;
});
});
</script>
<!-- Submit Button -->
<button type="submit"
class="inline-flex items-center py-2.5 px-4 text-xs font-medium text-center text-white bg-blue-700 rounded-lg focus:ring-4 focus:ring-blue-200 hover:bg-blue-800">
Post Comment
</button>
</div>
</div>
</form>
@endauth
@guest
<p class="text-sm poppins-regular text-gray-500">
Anda harus <a href="{{ route('login') }}"
class="text-green-800 poppins-semibold hover:underline">login</a> untuk
memberikan ulasan.
</p>
@endguest
<!-- Community Guidelines -->
<p class="ms-auto text-xs poppins-regular text-gray-500">
Remember, contributions to this topic should follow our
<a href="#" class="text-green-800 poppins-semibold hover:underline">Community
Guidelines</a>.
</p>
</div>
</div>
</div> --}}

View File

@ -3,13 +3,10 @@
use App\Models\User; use App\Models\User;
use App\Models\PendingUser; use App\Models\PendingUser;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
use App\Http\Controllers\LoginController; use App\Http\Controllers\LoginController;
use App\Http\Controllers\ProfileController; use App\Http\Controllers\ProfileController;
use App\Http\Controllers\KategoriController; use App\Http\Controllers\KategoriController;
use App\Http\Controllers\RegisterController; use App\Http\Controllers\RegisterController;
use App\Http\Controllers\AdminUserController;
use App\Http\Controllers\KunjunganController;
use App\Http\Controllers\PengunjungController; use App\Http\Controllers\PengunjungController;
use App\Http\Controllers\ProfileNewController; use App\Http\Controllers\ProfileNewController;
use App\Http\Controllers\AdminDashboardController; use App\Http\Controllers\AdminDashboardController;
@ -43,55 +40,36 @@
Route::post('reset-password', [NewPasswordController::class, 'store']) Route::post('reset-password', [NewPasswordController::class, 'store'])
->name('password.store'); ->name('password.store');
// ADMIN
Route::prefix('admin')->middleware(['auth', 'role:admin'])->group(function () {
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('admin.home');
Route::get('/data-kursus', [AdminDataKursusController::class, 'dataKursus'])->name('admin.dataKursus');
Route::get('/create-data', [AdminDataKursusController::class, 'create'])->name('admin.create');
Route::get('/{id}/edit-kursus', [AdminDataKursusController::class, 'edit'])->name('admin.edit');
// Fungsi di admin
Route::put('/update/{id}', [AdminDataKursusController::class, 'update'])->name('admin.update');
Route::post('/store', [AdminDataKursusController::class, 'store'])->name('kursus.store');
Route::delete('/delete/{id}', [AdminDataKursusController::class, 'destroy'])->name('delete');
Route::resource('kategori', KategoriController::class);
});
// USER
Route::get('/', [PengunjungController::class, 'home'])->name('user.home');
Route::get('/gagal-login', [PengunjungController::class, 'gagal'])->name('gagal.home');
Route::get('/kursus', [PengunjungController::class, 'kursus'])->name('user.kursus');
Route::get('/peta', [PengunjungController::class, 'maps'])->name('user.peta');
Route::get('/kursus/{id}/rute', [PengunjungController::class, 'rute'])->name('user.rute');
Route::get('/kursus/{id}/detail', [PengunjungController::class, 'detail'])->name('kursus.detail');
Route::post('/store-ulasan', [PengunjungController::class, 'storeUlasann'])->name('storeUlasan');
Route::middleware(['auth'])->group(function () { Route::middleware(['auth'])->group(function () {
Route::get('/password/edit', [ProfileNewController::class, 'edit'])->name('password.edit'); Route::get('/password/edit', [ProfileNewController::class, 'edit'])->name('password.edit');
Route::put('/password/update', [ProfileNewController::class, 'update'])->name('password.update'); // Ubah dari POST ke PUT Route::put('/password/update', [ProfileNewController::class, 'update'])->name('password.update'); // Ubah dari POST ke PUT
}); });
// ADMIN & USER
Route::prefix('admin')->middleware(['auth'])->group(function () {
Route::get('dashboard', [AdminDashboardController::class, 'index'])->name('admin.home');
Route::resource('/user', AdminUserController::class);
});
// Route untuk ADMIN (Hanya Admin)
Route::prefix('admin')->middleware(['auth', 'role:admin'])->group(function () {
Route::resource('/kategori', KategoriController::class);
Route::resource('/user', AdminUserController::class);
});
// Route untuk USER (Hanya User)
Route::prefix('admin')->middleware(['auth', 'role:user'])->group(function () {
Route::get('/create-data', [AdminDataKursusController::class, 'create'])->name('admin.create');
Route::get('/data-kursus', [AdminDataKursusController::class, 'dataKursus'])->name('admin.dataKursus');
Route::get('/{id}/edit-kursus', [AdminDataKursusController::class, 'edit'])->name('admin.edit');
// Fungsi CRUD kursus untuk user
Route::put('/update/{id}', [AdminDataKursusController::class, 'update'])->name('admin.update');
Route::post('/store', [AdminDataKursusController::class, 'store'])->name('kursus.store');
Route::delete('/delete/{id}', [AdminDataKursusController::class, 'destroy'])->name('delete');
});
// PENGUNJUNG
Route::get('/', [PengunjungController::class, 'home'])->name('user.home');
Route::get('/gagal-login', [PengunjungController::class, 'gagal'])->name('gagal.home');
Route::get('/kursus', [PengunjungController::class, 'kursus'])->name('user.kursus');
Route::get('/peta', [PengunjungController::class, 'maps'])->name('user.peta');
Route::post('/store-ulasan', [PengunjungController::class, 'storeUlasann'])->name('storeUlasan');
Route::get('/kursus/{id}/rute', [PengunjungController::class, 'rute'])->name('user.rute');
Route::get('/kursus/{id}/detail', [PengunjungController::class, 'detail'])->name('kursus.detail');
Route::post('/kursus/{id}/detail', [KunjunganController::class, 'visitCourse'])->name('kursus.visit');
Route::get('/set-locale/{lang}', function ($lang) {
Session::put('locale', $lang);
return back();
})->name('set.locale');
require __DIR__ . '/auth.php'; require __DIR__ . '/auth.php';

Binary file not shown.

View File

@ -12,18 +12,12 @@ export default {
padding: { padding: {
DEFAULT: "0rem", DEFAULT: "0rem",
sm: "0rem", sm: "0rem",
lg: "1rem", lg: "2rem",
xl: "2rem", xl: "3rem",
"2xl": "3rem", "2xl": "4rem",
}, },
// Tambahkan opsi `center` untuk margin auto // Tambahkan opsi `center` untuk margin auto
center: true, center: true,
},
extend: {
// Tambahkan font Bebas Neue di sini
fontFamily: {
"bebas-neue": ['"Bebas Neue"', "sans-serif"],
},
dropShadow: { dropShadow: {
"1xl": "0 10px 20px rgba(0, 0, 0, 0.15)", // Light shadow for minimal depth "1xl": "0 10px 20px rgba(0, 0, 0, 0.15)", // Light shadow for minimal depth
"2xl": "0 20px 30px rgba(0, 0, 0, 0.2)", // More noticeable shadow "2xl": "0 20px 30px rgba(0, 0, 0, 0.2)", // More noticeable shadow
@ -34,6 +28,7 @@ export default {
], ],
}, },
}, },
extend: {},
}, },
plugins: [require("flowbite/plugin")], plugins: [require("flowbite/plugin")],
}; };

View File

@ -7,13 +7,4 @@ export default defineConfig({
refresh: true, refresh: true,
}), }),
], ],
// // RUN DI MOBILE
// server: {
// host: '0.0.0.0', // Akses dari HP bisa
// port: 5173, // Default Vite port
// strictPort: true,
// hmr: {
// host: '192.168.1.4' // IP MENYESUAIKAN laptop kamu
// }
// },
}); });