Compare commits

...

10 Commits

Author SHA1 Message Date
Salma Banafsha S. F. c71c012977 update 2025-06-18 09:07:41 +07:00
Salma Banafsha S. F. 799f4ee480 update 2025-06-18 08:50:05 +07:00
Salma Banafsha S. F. 7c904f3bdf Coba 2025-04-06 11:53:19 +07:00
HANIF FEBRIANSYAH f38438a1e1 OKe 2025-04-05 12:53:27 +07:00
HANIF FEBRIANSYAH fce63d76a2 Done Bismillah 2025-04-04 22:43:13 +07:00
HANIF FEBRIANSYAH e718c10a60 Takut hilang 2025-04-03 07:28:44 +07:00
Salma Banafsha S. F. a1ef885081 Merge branch 'main' of https://github.com/hanzhighmekaniq/SIG-Salma 2025-03-24 12:57:37 +07:00
Salma Banafsha S. F. 265a8960c0 Salma FE 2025-03-24 12:48:39 +07:00
HANIF FEBRIANSYAH e7054e55d5 Perbaikan Sedikit 2025-03-13 01:33:00 +07:00
HANIF FEBRIANSYAH 8f0b98e62f Done123 2025-03-12 20:34:04 +07:00
73 changed files with 12810 additions and 1075 deletions

View File

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

@ -0,0 +1,132 @@
<?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,15 +11,23 @@ class KategoriController extends Controller
/**
* Display a listing of the resource.
*/
public function index()
public function index(Request $request)
{
// Mengambil semua data kursus dari model DataKursus
$kategori = DataKategori::paginate(10);
$query = DataKategori::query();
// Mengirim data courses dengan gambar ke view
// Cek apakah ada input pencarian
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'));
}
/**
* Show the form for creating a new resource.
*/
@ -104,11 +112,16 @@ public function update(Request $request, string $id)
*/
public function destroy(string $id)
{
// Temukan kategori berdasarkan ID
$kategori = DataKategori::findOrFail($id);
try {
// Temukan kategori berdasarkan ID
$kategori = DataKategori::findOrFail($id);
// Hapus kategori
$kategori->delete();
return redirect()->route('kategori.index')->with('success', 'Kategori berhasil dihapus.');
// Hapus kategori
$kategori->delete();
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

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

View File

@ -2,8 +2,10 @@
namespace App\Http\Controllers;
use App\Models\Kunjungan;
use App\Models\DataKursus;
use App\Models\DataUlasan;
use Illuminate\Support\Str;
use App\Models\DataKategori;
use Illuminate\Http\Request;
use Dflydev\DotAccessData\Data;
@ -15,18 +17,21 @@ class PengunjungController extends Controller
// PENGUNJUNG
public function home()
{
// Ambil 3 data yang populer dari tabel DataKursus
$landingpage = DataKursus::where('popular', 'Popular')
->limit(3)
$landingpage = DataKursus::withCount('kunjungan') // Menghitung jumlah kunjungan tanpa filter waktu
->orderByDesc('kunjungan_count') // Mengurutkan berdasarkan jumlah kunjungan terbanyak
->limit(3) // Mengambil 4 kursus terpopuler
->get();
// Potong deskripsi agar hanya terdiri dari 22 kata
foreach ($landingpage as $item) {
$item->deskripsi = \Illuminate\Support\Str::words($item->deskripsi, 22, '...');
}
$peta = DataKursus::with('kategoris')->get();
// Kembalikan view dengan data yang sudah diproses
return view('user.home', compact('landingpage'));
return view('user.home', compact('landingpage', 'peta'));
}
@ -48,7 +53,8 @@ public function kursus(Request $request)
}
// Ambil data kursus secara acak dengan kategori
$data_kursus = $query->with('kategoris')->inRandomOrder()->paginate(10);
$data_kursus = $query->with('kategoris')->paginate(12);
// Ambil daftar kategori untuk dropdown
$kategori = DataKategori::all();
@ -78,20 +84,44 @@ public function maps()
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
$data = DataKursus::with('kategoris', 'ulasan')->find($id);
$data->fasilitas = json_decode($data->fasilitas, true);
if (!$data) {
abort(404, 'Kursus tidak ditemukan');
}
// Ambil data ulasan terkait, urutkan berdasarkan created_at terbaru
$imageNames = json_decode($data->img_konten, true);
$ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3); // Membatasi hanya 3 ulasan per halaman, urutan terbaru
$ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3);
// Hitung rata-rata rating
$averageRating = $ulasan->avg('rating'); // Mengambil rata-rata rating
$totalRatings = $ulasan->count(); // Menghitung total jumlah ulasan
$averageRating = $ulasan->avg('rating');
$totalRatings = $ulasan->count();
// Kirim data ke view
return view('user.detailKursus', compact('data', 'imageNames', 'ulasan', 'averageRating', 'totalRatings'));
@ -102,6 +132,9 @@ public function detail(string $id)
public function rute(string $id)
{
// Ambil kursus berdasarkan ID

View File

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

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Kunjungan;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -25,17 +26,29 @@ class DataKursus extends Model
'latitude',
'longitude', // Pastikan nama kolom sesuai dengan migrasi
'popular', // Pastikan nama kolom sesuai dengan migrasi
'img_konten'
'img_konten',
'user_id'
];
public $timestamps = true;
public function kategoris(): BelongsTo
{
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
{
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
}
}

21
app/Models/Kunjungan.php Normal file
View File

@ -0,0 +1,21 @@
<?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,10 +4,11 @@
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
@ -24,6 +25,7 @@ class User extends Authenticatable implements MustVerifyEmail
protected $fillable = [
'name',
'email',
'username',
'password',
'role'
];
@ -31,6 +33,10 @@ public function ulasans(): HasMany
{
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.

View File

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

View File

@ -9,7 +9,8 @@
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
"laravel/tinker": "^2.8",
"laravolt/indonesia": "^0.36.0"
},
"require-dev": {
"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",
"This file is @generated automatically"
],
"content-hash": "85309d4524da1baae35ac151622b248f",
"content-hash": "08dbb25675a803a24f2b8a6421dd5c41",
"packages": [
{
"name": "brick/math",
@ -1512,6 +1512,88 @@
},
"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",
"version": "2.6.1",

View File

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

View File

@ -15,15 +15,12 @@ public function definition()
return [
'kategori_id' => DataKategori::factory(), // Relasi dengan kategori
'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
'paket' => $this->faker->word(), // Paket kursus random
'metode' => $this->faker->randomElement(['Online', 'Offline', 'Hybrid']), // Metode random
'fasilitas' => $this->faker->sentence(), // Fasilitas random
'lokasi' => $this->faker->address(), // Lokasi random
'latitude' => $this->faker->latitude(-90, 90), // Latitude random
'longitude' => $this->faker->longitude(-180, 180), // Longitude random
'popular' => $this->faker->boolean(), // True/false untuk popular
];
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('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,27 +15,43 @@ class DatabaseSeeder extends Seeder
*/
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([
'name' => 'Salma Admin',
'email' => 'salma@gmail.com',
'password' => bcrypt('salma281103'), // Ganti dengan password pilihan Anda
'name' => 'Admin',
'email' => 'admin@gmail.com',
'username' => 'admin',
'password' => bcrypt('admin123'), // Ganti dengan password pilihan Anda
'role' => 'admin',
]);
DataKategori::insert([
['nama_kategori' => 'Speaking'],
['nama_kategori' => 'Reading'],
['nama_kategori' => 'Good Looking'],
['nama_kategori' => 'Good Evening'],
User::create([
'name' => 'User',
'email' => 'user@gmail.com',
'username' => 'user',
'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda
'role' => 'user',
]);
// User::create([
// 'name' => 'user',
// 'email' => 'user@gmail.com',
// 'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda
// 'role' => 'pengunjung',
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
// // Buat 3 kategori
// // // Buat 3 kategori, setiap kategori memiliki banyak kursus
// // // Buat 3 kategori
// $kategoris = DataKategori::factory(3)->create();
// // Buat kursus hingga total 20 data

9218
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

271
public/css/font.css Normal file
View File

@ -0,0 +1,271 @@
.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;
}

BIN
public/img/bg-forgot pw.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

BIN
public/img/bg-home.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

BIN
public/img/bg-login.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

BIN
public/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/img/logo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
public/img/tentang kami.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

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

View File

@ -1 +1 @@
import 'flowbite';
import 'flowbite';

View File

View File

@ -0,0 +1,280 @@
<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 -->
<div class="relative">
<div class="flex m-auto justify-center items-center responsive-container">
<img src="{{ asset('img/Rectangle 227.png') }}" class="w-full h-full" alt="">
<img src="{{ asset('img/bg-home.jpg') }}" class="w-full h-full" alt="">
</div>
</div>

View File

@ -1,64 +1,76 @@
<x-adminlayout>
<div class="container">
<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-kategori"
data-modal-toggle="default-modal-tambah-kategori"
class="bg-[#4F7F81] py-2 px-4 rounded-xl shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-xs font-bold"
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 ">
<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() }}
<div class="relative overflow-x-auto sm:rounded-lg">
<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">
<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">
<thead class="text-xs uppercase bg-gray-100 border-b border-gray-300">
<tr>
<th scope="col" class=" py-3 text-end">No</th>
<!-- Menambahkan text-end untuk penataan -->
<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 -->
<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 Kategori</th>
<th scope="col" class="py-3 px-4 text-end">Aksi</th>
</tr>
</thead>
<tbody class="shadow-gray-600">
<tbody class="divide-y divide-gray-300">
@foreach ($kategori as $index => $kategoris)
<tr class="odd:bg-white even:bg-gray-50 shadow-gray-600 ">
<th scope="row" class=" py-4 font-medium text-gray-900 text-end">
<!-- Menambahkan text-end untuk penataan -->
<p class="m-auto space-x-2 flex justify-end">
{{ ($kategori->currentPage() - 1) * $kategori->perPage() + $index + 1 }}
</p>
<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">
{{ ($kategori->currentPage() - 1) * $kategori->perPage() + $index + 1 }}
</th>
<td class=" py-4 text-end">
<td class="py-4 px-4 text-end border-r border-gray-300">
{{ $kategoris->nama_kategori }}
</td>
<td class=" py-4 text-end">
<!-- Menambahkan text-end untuk penataan -->
<div class="flex justify-end space-x-4"> <!-- Menyusun ikon sejajar -->
<td class="py-4 px-4 text-end">
<div class="flex justify-end space-x-2">
<!-- Tombol Edit -->
<button data-modal-target="default-modal-edit-kategori{{ $kategoris->id }}"
data-modal-toggle="default-modal-edit-kategori{{ $kategoris->id }}"
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> <!-- Icon Edit -->
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="default-modal-delete-kategori{{ $kategoris->id }}"
data-modal-toggle="default-modal-delete-kategori{{ $kategoris->id }}"
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> <!-- Icon Hapus -->
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">
@ -72,13 +84,13 @@ class="font-extrabold text-xs shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-
<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">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<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 dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
<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 poppins-regular text-green-800 ">
Tambahkan Kategori
</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 dark:hover:bg-gray-600 dark:hover:text-white"
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-kategori">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
@ -91,19 +103,19 @@ class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounde
<form action="{{ route('kategori.store') }}" method="POST">
@csrf
<div class="p-4 items-center">
<label for="nama_kategori" class="block text-gray-700 font-bold mb-1">Kategori</label>
<label for="nama_kategori" class="block text-gray-700 poppins-regular mb-1">Kategori</label>
<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"
placeholder="Masukkan Kategori" required required autocomplete="off">
</div>
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b ">
<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 px-5 py-2.5 text-end dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
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 ">
Tambah
</button>
<button data-modal-hide="default-modal-tambah-kategori" 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 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">
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 ">
Batal
</button>
</div>
@ -116,16 +128,16 @@ class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-
<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">
<div class="relative p-4 w-full max-w-2xl max-h-full">
<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 dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
<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 poppins-regular text-gray-900 ">
Edit Kategori
</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 dark:hover:bg-gray-600 dark:hover:text-white"
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-edit-kategori{{ $kategoris->id }}">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 14 14">
<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>
@ -141,20 +153,19 @@ class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounde
<div class="px-4 pb-4 items-center">
<label for="detail_kategori"
class="block mt-4 text-gray-700 font-bold mb-1">Kategori</label>
class="block mt-4 text-gray-700 poppins-regular mb-1">Kategori</label>
<input type="text" id="edit-namaKategori" name="nama_kategori"
value="{{ $kategoris->nama_kategori }}"
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">
</div>
<div
class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b ">
<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 px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
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="default-modal-edit-kategori{{ $kategoris->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 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">
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 ">
Batal
</button>
</div>
@ -169,9 +180,9 @@ class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-
<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">
<div class="relative p-4 w-full max-w-md max-h-full">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<div class="relative bg-white rounded-lg shadow ">
<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 dark:hover:bg-gray-600 dark:hover:text-white"
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">
@ -181,12 +192,12 @@ class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hov
<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 dark:text-gray-200" aria-hidden="true"
<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 dark:text-gray-400">Anda yakin ingin
<h3 class="mb-5 text-lg poppins-regular text-gray-500 ">Anda yakin ingin
menghapus?</h3>
<div class="flex justify-center">
<form id="edit-kategori-form" method="POST"
@ -194,14 +205,14 @@ class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hov
@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 dark:focus:ring-red-800 font-medium rounded-lg text-sm 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 font-medium rounded-lg text-sm poppins-regular 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="default-modal-delete-kategori{{ $kategoris->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 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">
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 ">
Tidak, Batal
</button>
</div>

View File

@ -1,104 +1,144 @@
<x-adminlayout>
<div class="container">
<div class="lg:px-10">
<div class="py-10 px-4 md:px-0">
<div class="flex justify-end items-center pb-4 ">
<a class="bg-[#4F7F81] py-2 px-4 rounded-xl shadow-md shadow-gray-600 hover:bg-[#3F6A6B] text-white text-xs font-bold"
<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"
href="{{ route('admin.create') }}">Tambah Data</a>
</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() }}
<div class="relative overflow-x-auto sm:rounded-lg">
<table class="w-full text-sm text-right rtl:text-right shadow-gray-600 text-gray-500">
<thead class="text-xs text-gray-700 uppercase shadow-gray-600 bg-gray-50">
<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">No</th>
<th scope="col" class=" py-3 px-4 text-end">Nama Kursus</th>
<th scope="col" class=" py-3 px-4 text-end">Kategori</th>
<th scope="col" class=" py-3 px-4 text-end">Paket</th>
<th scope="col" class=" py-3 px-4 text-end">Metode</th>
<th scope="col" class=" py-3 px-4 text-end">Fasilitas</th>
<th scope="col" class=" py-3 px-4 text-end">Lokasi</th>
<th scope="col" class=" py-3 px-4 text-end">Aksi</th>
<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 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 border-r border-gray-300">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 border-r border-gray-300">Lokasi</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 border-r border-gray-300">Latitude-Longitude
</th>
<th scope="col" class="py-3 px-4 text-end">Aksi</th>
</tr>
</thead>
<tbody class="shadow-gray-600">
<tbody class="divide-y divide-gray-300">
@foreach ($courses as $index => $course)
<tr class="odd:bg-white even:bg-gray-50 shadow-gray-600 ">
<th scope="row" class="px-4 py-4 text-end font-medium text-gray-900 whitespace-nowrap">
<tr
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 poppins-regular text-gray-900 whitespace-nowrap border-r border-gray-300">
{{ ($courses->currentPage() - 1) * $courses->perPage() + $loop->iteration }}
</th>
<td class=" py-4 text-end px-4">
<div class="flex justify-end flex-row gap-3 items-center w-full h-full">
<td class="py-4 text-end px-4 border-r border-gray-300">
<div class="flex justify-end flex-row gap-3 items-center">
<div class="form-control flex-1">
<span class="text-sm uppercase font-semibold">
{{ $course->nama_kursus }}
</span>
<span class="text-xs text-gray-400 line-clamp-2">
{{ Str::limit($course->deskripsi, 200, '...') }}
@php
$words = explode(' ', 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>
</div>
<div class="w-8 h-8 rounded-md overflow-hidden">
<div
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) }}"
class="aspect-square shadow-md shadow-gray-500 object-cover" alt="">
class="aspect-square shadow-md shadow-gray-500 object-cover"
alt="">
</div>
</div>
</td>
<td class=" py-4 text-end px-4">
<div class="flex flex-col justify-center text-end">
<td class="py-4 text-end px-4 border-r border-gray-300">
<div class="flex flex-col justify-center text-end poppins-regular">
<span class="mb-2">
{{ $course->kategoris ? $course->kategoris->nama_kategori : 'Kategori tidak tersedia' }}
</span>
<span>{{ $course->popular }}</span>
</div>
</td>
<td class=" py-4 text-end items-center px-4">
<div> {!! Str::limit($course->paket, 50, '...') !!}</div>
{{-- <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 px-4 border-r border-gray-300">{!! Str::limit($course->metode, 50, '...') !!}</td>
<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 class=" py-4 text-end items-center px-4">
<div> {!! Str::limit($course->metode, 50, '...') !!}</div>
</td>
<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">
<td class="py-4 text-end px-4 border-r border-gray-300">
{{ $course->latitude }},{{ $course->longitude }}</td>
<td class="py-4 text-end px-4">
<div class="flex justify-end items-center space-x-1 md:space-x-2">
<!-- Detail Button with Icon -->
<div>
<button data-modal-target="modal-detail{{ $course->id }}"
data-modal-toggle="modal-detail{{ $course->id }}"
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-info-circle text-xs"></i> <!-- Icon Detail -->
</button>
</div>
<button data-modal-target="modal-detail{{ $course->id }}"
data-modal-toggle="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">
<i class="fas fa-info-circle text-xs"></i>
</button>
<!-- Edit Button with Icon -->
<div>
<a href="/admin/{{ $course->id }}/edit-kursus"
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> <!-- Icon Edit -->
</a>
</div>
<a href="/admin/{{ $course->id }}/edit-kursus"
class="font-extrabold text-xs shadow-md hover:bg-yellow-600 text-white py-2 px-2 bg-yellow-500 rounded-lg transition">
<i class="fas fa-edit text-xs"></i>
</a>
<!-- Delete Button with Icon -->
<div>
<button data-modal-target="popup-modal-{{ $course->id }}"
data-modal-toggle="popup-modal-{{ $course->id }}"
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-alt text-xs"></i> <!-- Icon Delete -->
</button>
</div>
<button data-modal-target="popup-modal-{{ $course->id }}"
data-modal-toggle="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">
<i class="fas fa-trash-alt text-xs"></i>
</button>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@foreach ($courses as $course)
<!-- Modal Konfirmasi -->
<div id="popup-modal-{{ $course->id }}" tabindex="-1"
@ -121,7 +161,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"
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="text-black mb-5 text-lg font-normal ">
<h3 class="text-black mb-5 text-lg poppins-regular ">
Apakah Anda yakin ingin menghapus kursus ini?</h3>
<!-- Form Hapus -->
<form id="delete-form-{{ $course->id }}"
@ -132,11 +172,11 @@ class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hov
</form>
<button type="button"
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 font-medium 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 poppins-regular rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-start">
Hapus
</button>
<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-gray-800 focus:z-10 focus:ring-4 focus:ring-gray-100 "
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 "
data-modal-hide="popup-modal-{{ $course->id }}">Tidak,
Batal</button>
</div>
@ -170,7 +210,7 @@ class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-
</div>
<!-- Main modal -->
@foreach ($courses as $course)
@ -179,7 +219,7 @@ class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-
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">
<!-- Modal content -->
<div class="relative rounded-lg shadow dark:bg-gray-700 bg-[#4F7F81]">
<div class="relative rounded-lg shadow bg-[#4F7F81]">
<!-- Modal body -->
<div class="p-4 md:p-5">
<div class="">

View File

@ -1,5 +1,5 @@
<x-adminlayout>
<div class="container">
<div class="">
<div class="py-10 px-4">
<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]"
@ -23,7 +23,7 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
required />
</div>
<div>
<div class="hidden">
<label for="popular" class="block mb-2 text-sm font-medium text-gray-900">Pilih
Popular</label>
<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>
<!-- Input File Single -->
<div>
<label for="deskripsi" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
<label for="deskripsi" class="block mb-2 text-sm font-medium text-gray-900 ">
Deskripsi
</label>
<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 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:placeholder-gray-400"
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 Adalah . . . ." required>{{ old('deskripsi') }}</textarea>
</div>
<div class="flex justify-between w-full gap-4">
@ -102,13 +102,7 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
</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') }}" />
<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 -->
<div>
@ -118,6 +112,93 @@ 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"
placeholder="Write your thoughts here..."></trix-editor>
</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>
<label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Uplaud
Gambar</label>
@ -125,18 +206,18 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
<div class="grid grid-cols-1 gap-4">
<div>
<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 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">
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 ">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round"
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" />
</svg>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
class="font-semibold">Click to upload Single</p>
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click
to upload Single</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF
</p>
<input id="file_input" type="file" name="img" class="hidden"
onchange="previewImage(event)" />
@ -157,18 +238,18 @@ class="aspect-video h-40 object-contain" />
<div class="grid grid-cols-1 gap-4">
<div>
<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 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">
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 ">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round"
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" />
</svg>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
class="font-semibold">Click to upload Multi</p>
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click
to upload Multi</p>
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF
</p>
<input id="multiple_files" type="file" name="img_konten[]" multiple
onchange="previewMultipleImages(event)" class="hidden" />

View File

@ -1,5 +1,5 @@
<x-adminlayout>
<div class="container">
<div class="">
<div class="py-10 px-4">
<div class="pb-4 flex">
<a class="px-4 flex text-white text-lg justify-center items-center py-2 rounded-xl bg-[#4F7F81]"
@ -27,12 +27,11 @@
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 />
</div>
<div>
<label for="countries"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Pilih
<div class="hidden">
<label for="countries" class="block mb-2 text-sm font-medium text-gray-900 ">Pilih
Popular</label>
<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 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">
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 ">
<option selected>{{ $dataKursus->popular }}</option>
@if ($dataKursus->popular === 'popular')
<option value="Tidak">Tidak</option>
@ -112,15 +111,7 @@ 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>
</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 -->
<div>
@ -131,6 +122,87 @@ 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"
placeholder="Write your thoughts here..."></trix-editor>
</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>
<label for="latitude" class="block mb-2 text-sm font-medium text-gray-900">Upload
Gambar</label>
@ -138,19 +210,19 @@ class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border bor
<div class="grid grid-cols-1 gap-4">
<div>
<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 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">
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 ">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round"
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" />
</svg>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
class="font-semibold">Click to
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click
to
upload Single</p>
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF
</p>
<input id="file_input" type="file" name="img" class="hidden"
onchange="previewImage(event)" />
@ -180,19 +252,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>
<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 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">
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 ">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
<svg class="w-8 h-8 mb-4 text-gray-500 " aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 16">
<path stroke="currentColor" stroke-linecap="round"
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" />
</svg>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
class="font-semibold">Click to
<p class="mb-2 text-sm text-gray-500 "><span class="font-semibold">Click
to
upload Multi</p>
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
<p class="text-xs text-gray-500 ">SVG, PNG, JPG or GIF
</p>
<input id="multiple_files" type="file" name="img_konten[]" multiple
onchange="previewMultipleImages(event)" class="hidden" />
@ -245,8 +317,7 @@ class="object-contain max-h-48 mx-auto" alt="Gambar">
<!-- Multiple Files Modal -->
<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">
<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">
<!-- Flex container to arrange images horizontally -->
@if (!empty($dataKursus->img_konten))

View File

@ -1,6 +1,7 @@
@include('partials.head')
@include('partials.font')
<!--
<div class="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">
@ -9,19 +10,19 @@
<span
class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a>
</div>
</div> -->
</nav>
</div>
<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="hidden lg:block justify-center items-center">
<img src="{{ asset('img/login.png') }}" alt="">
<div class="hidden lg:block justify-center items-center ">
<img src="{{ asset('img/bg-forgot pw.jpg') }}" alt="">
</div>
<div class="border border-slate-500">
<p class="p-8 flex justify-center items-center poppins-semibold text-4xl">Forgot Password</p>
<div class="mb-4 text-sm text-gray-600 px-8">
<p class="p-8 flex justify-center items-center text-green-800 barlow-condensed-semibold text-6xl">FORGOT PASSWORD</p>
<div class="mb-4 text-sm poppins-regular text-gray-600 px-8">
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.
</div>
@ -41,9 +42,9 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-green-500 text-white p
<!-- Email Address -->
<div class="mb-5">
<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 poppins-regular text-gray-900">Your Email</label>
<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 poppins-regular rounded-lg focus:ring-green-800 focus:border-green-800 block w-full p-2.5"
placeholder="email@gmail.com" :value="old('email')" required autofocus />
@error('email')
<span class="text-sm text-red-600 mt-1">{{ $message }}</span>
@ -51,13 +52,13 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
</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">Send
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
Password Reset Link</button>
</form>
<!-- Back to Login -->
<div class="text-center mt-4">
<a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 font-semibold">Back to
<a href="{{ route('login') }}" class="text-green-800 hover:text-blue-800 poppins-regular">Back to
Login</a>
</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>
<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"
placeholder="email@gmail.com" :value="old('email', $request - > email)" required autofocus
placeholder="email@gmail.com" :value="old('email', $request -> email)" required autofocus
autocomplete="username" />
@error('email')
<span class="text-sm text-red-600 mt-1">{{ $message }}</span>

View File

@ -2,40 +2,24 @@
<html lang="en">
<head>
@include('components.navbarAdmin')
{{-- @vite(['resources/css/app.css', 'resources/js/app.js']) --}}
{{-- <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> --}}
@include('partials.head')
@vite(['resources/css/app.css', 'resources/js/app.js'])
@vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css'])
@include('partials.font')
@include('partials.notification')
</head>
<body>
@if (session('success'))
<div id="notification"
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="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>
@include('components.navbarAdmin')
<div class="p-4 sm:ml-64">
<div class="p-4 border-2 border-gray-200 border-dashed rounded-lg mt-14">
{{ $slot }}
</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 }}
</div>
</body>

View File

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

View File

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

View File

@ -1,104 +1,145 @@
<div class="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">
<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"
alt="Flowbite Logo" />
<span
class="self-center text-2xl sm:text-3xl lg:text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a>
<button data-collapse-toggle="navbar-solid-bg" type="button"
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 "
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" />
<div class="flex justify-center ">
<nav class="w-full md:container md:px-4 md:top-4 fixed z-[999] ">
<div class="flex justify-between py-1 md:py-2 items-center shadow-lg bg-white px-4 md:rounded-full text-white">
<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>
</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="">
<span class="text-sm lg:text-xl 2xl:text-2xl font-semibold text-green-800">LearnMap</span>
</a>
<div class="hidden md:flex" id="navbar-menu">
<ul class="flex space-x-8 text-sm lg:text-base 2xl:text-lg poppins-regular">
<li>
<a href="{{ route('user.home') }}"
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 ">
class="text-black hover:text-green-600 {{ Request::routeIs('user.home') ? 'text-green-700 ' : '' }}">
Beranda
</a>
</li>
<li class="">
<li>
<a href="{{ route('user.kursus') }}"
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 ">
class="text-black hover:text-green-600 {{ Request::routeIs('user.kursus') ? 'text-green-700 ' : '' }}">
Kursus
</a>
</li>
<li class="">
<li>
<a href="{{ route('user.peta') }}"
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 ">
class="text-black hover:text-green-600 {{ Request::routeIs('user.peta') ? 'text-green-700 ' : '' }}">
Peta
</a>
</li>
</ul>
</div>
<div class="flex items-center">
<!-- Login / Dropdown User -->
<div class="ml-4">
@if (Auth::check())
<li>
<div class="relative" data-dropdown>
<button type="button"
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"
data-dropdown-placement="bottom">
class="flex items-center text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300"
id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown">
<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"
src="{{ Auth::user()->avatar ?: 'https://www.gravatar.com/avatar/' . md5(strtolower(trim(Auth::user()->email))) }}?d=identicon"
alt="user photo">
</button>
</li>
<!-- Dropdown menu -->
<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"
id="user-dropdown">
<div class="px-4 py-3">
<span
class="block text-sm text-gray-900 dark:text-white">{{ Auth::user()->name }}</span>
<span
class="block text-sm text-gray-500 truncate dark:text-gray-400">{{ Auth::user()->email }}</span>
</div>
<ul class="py-2" aria-labelledby="user-menu-button">
@if (Auth::user() && Auth::user()->role === 'admin')
<!-- Dropdown Menu -->
<div id="user-dropdown"
class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow"
data-popper-placement="bottom">
<div class="px-4 py-3">
<span class="block text-sm text-gray-900">{{ Auth::user()->name }}</span>
<span class="block text-sm text-gray-500 truncate">{{ Auth::user()->email }}</span>
<span
class="block text-sm text-gray-500 truncate">{{ Auth::user()->username }}</span>
</div>
<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('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>
<a href="{{ route('password.edit') }}"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Setting</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>
<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="{{ 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>
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>
@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">
</ul>
<li>
<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>
</nav>
</div>

View File

@ -1,152 +1,211 @@
<div class="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">
<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"
alt="Flowbite Logo" />
<span
class="self-center text-2xl sm:text-3xl lg:text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">
LearnMap
</span>
</a>
<button data-collapse-toggle="navbar-solid-bg" type="button"
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"
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 py-4" id="navbar-solid-bg">
<ul
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">
<li class="">
<a href="{{ route('admin.home') }}"
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">
Dashboard
</a>
</li>
<li class="">
<a href="{{ route('kategori.index') }}"
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">
Kategori
</a>
</li>
<li class="">
<a href="{{ route('admin.dataKursus') }}"
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">
Data Kursus
</a>
</li>
<li class="">
{{-- <div class=" flex justify-center relative">
<nav
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">
<!-- Logo dan Nama Aplikasi -->
<a href="{{ route('user.home') }}" class="flex items-center">
<img src="{{ asset('img/logo3.png') }}" class="h-10 w-10" alt="Logo LearnMap" />
<span class="ml-2 text-2xl barlow-condensed-semibold text-green-800">LearnMap</span>
</a>
<!-- Menu Navigasi -->
@if (Auth::user() && in_array(Auth::user()->role, ['admin', 'user']))
<ul class="flex space-x-8 text-lg poppins-regular">
<li><a href="{{ route('admin.home') }}" class="text-black hover:text-green-600">Beranda</a></li>
<li><a href="{{ route('kategori.index') }}" class="text-black hover:text-green-600">Kategori</a></li>
<li><a href="{{ route('user.index') }}" class="text-black hover:text-green-600">User</a></li>
</ul>
@else
@endif
<!-- Tombol Login atau Dropdown User -->
@if (Auth::check())
<div class="relative">
<button type="button" class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300"
id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown">
<span class="sr-only">Open user menu</span>
<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"
alt="user photo">
</button>
<!-- Dropdown Menu -->
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow"
id="user-dropdown">
<div class="px-4 py-3">
<span class="block text-sm text-gray-900">{{ Auth::user()->name }}</span>
<span class="block text-sm text-gray-500 truncate">{{ Auth::user()->email }}</span>
</div>
<ul class="py-2" aria-labelledby="user-menu-button">
@if (Auth::user() && 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>
@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"
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"
data-dropdown-placement="bottom">
class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300 "
aria-expanded="false" data-dropdown-toggle="dropdown-user">
<span class="sr-only">Open user menu</span>
<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"
alt="user photo">
src="https://flowbite.com/docs/images/people/profile-picture-5.jpg" alt="user photo">
</button>
</li>
<!-- Dropdown menu -->
<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"
id="user-dropdown">
<div class="px-4 py-3">
<span class="block text-sm text-gray-900 dark:text-white">{{ Auth::user()->name }}</span>
<span
class="block text-sm text-gray-500 truncate dark:text-gray-400">{{ Auth::user()->email }}</span>
</div>
<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">
<div class="px-4 py-3" role="none">
<p class="text-sm text-green-900 " role="none">
{{ Auth::user()->email }}
</p>
<p class="text-sm font-medium text-green-900 truncate d" role="none">
{{ Auth::user()->name }}
</p>
</div>
<ul class="py-2" aria-labelledby="user-menu-button">
<ul class="py-1" role="none">
<li>
<a href="{{ route('admin.home') }}">
<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">Dashboard</button>
</a>
<a href="{{ route('admin.home') }}"
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 "
role="menuitem">Dashboard</a>
</li>
<li>
<a href="{{ route('password.edit') }}">
<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">Setting</button>
</a>
<a href="{{ route('password.edit') }}"
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 "
role="menuitem">Settings</a>
</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
<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>
<button type="submit" class="w-full text-left">Sign out</button>
</form>
</li>
</ul>
</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>
</nav>
<script>
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-modal-toggle]').forEach(button => {
button.addEventListener('click', () => {
const targetId = button.getAttribute('data-modal-target');
document.getElementById(targetId).classList.remove('hidden');
});
});
<aside id="logo-sidebar"
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"
aria-label="Sidebar">
<div class="h-full px-3 pb-4 overflow-y-auto bg-white">
<ul class="space-y-2 font-medium">
<li>
@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>
document.querySelectorAll('[data-modal-hide]').forEach(button => {
button.addEventListener('click', () => {
const targetId = button.getAttribute('data-modal-hide');
document.getElementById(targetId).classList.add('hidden');
});
});
});
</script>
@if (Auth::user() && in_array(Auth::user()->role, ['user']))
<li>
<a href="{{ route('admin.dataKursus') }}"
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-green-100 group
{{ 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' }}"
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,26 +1,33 @@
@include('partials.head')
@include('partials.font')
<!DOCTYPE html>
<html lang="en">
<div class="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">
<a href="#" class="flex items-center">
<img src="{{ asset('img/Rectangle 65.png') }}" class="h-20 object-cover w-20" alt="Flowbite Logo" />
<span
class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a>
</div>
</nav>
</div>
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>Login</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" />
<style>
body {
font-family: 'Inter', sans-serif;
}
</style>
</head>
<body>
<body class="bg-gray-100">
@if (session('success'))
<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">
{{ session('success') }}
</div>
@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())
<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">
@ -32,47 +39,55 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-
</div>
@endif
<div class="container py-10 px-8 lg:px-0">
<div class="grid lg:grid-cols-2 grid-cols-1">
<div class="hidden lg:block justify-center items-center">
<img src="{{ asset('img/login.png') }}" alt="">
</div>
<div class="border border-slate-500">
<p class="p-8 flex justify-center font-semibold items-center poppins-semibold text-4xl">Login</p>
<form class="px-8 mx-auto" method="POST">
@csrf
<div class="mb-5">
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 ">Your email</label>
<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 "
placeholder="email@gmail.com" required />
</div>
<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 class="flex min-h-screen">
<!-- Left Side -->
<div class="w-full lg:w-1/2 flex flex-col justify-center items-center bg-white p-8">
<div class="w-full max-w-md">
<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>
<!-- Right Side -->
<div class="hidden lg:flex lg:w-1/2 flex items-center justify-center bg-cover bg-center relative"
style="background-image: url('{{ asset('img/bg-login.jpg') }}'); background-size: object-contain;">
<div class="absolute inset-0 opacity-25"></div>
<div class="relative z-10 p-8">
<!-- <h2 class="text-5xl barlow-condensed-semibold text-green-800 mb-4">MARI TEMUKAN KURSUS IMPIANMU BERSAMA
LEARN MAP.</h2>
<p class="text-black poppins-regular ">Jelajahi kursus berkualitas bersama Learn Map, sekarang juga.
Temukan berbagai pilihan kursus yang dirancang untuk meningkatkan keterampilan dan pengetahuanmu. -->
</p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,6 +1,6 @@
@include('partials.head')
@include('partials.font')
<!--
<div class="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">
@ -9,7 +9,7 @@
<span
class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclonica-regular">LearnMap</span>
</a>
</div>
</div> -->
</nav>
</div>
@ -22,39 +22,39 @@ class="self-center text-4xl text-white font-semibold whitespace-nowrap pt-4 aclo
@endif
<div class="border border-slate-500 pb-4">
<p class="p-8 flex justify-center items-center poppins-semibold text-4xl">Register</p>
<p class="p-8 flex justify-center items-center barlow-condensed-semibold text-green-800 text-6xl">REGISTER</p>
<form class="px-8 mx-auto" method="POST" action="{{ route('register.account') }}">
@csrf
<div class="mb-5">
<label for="name" class="block mb-2 text-sm font-medium text-gray-900">Your Name</label>
<label for="name" class="block mb-2 text-sm poppins-regular text-gray-900">Your Name</label>
<input type="text" id="name" name="name" value="{{ old('name') }}"
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 poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Full Name" required />
</div>
<div class="mb-5">
<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 poppins-regular text-gray-900">Your Email</label>
<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 poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="email@example.com" required />
</div>
<div class="mb-5">
<label for="email_confirmation" class="block mb-2 text-sm font-medium text-gray-900">Confirm Your
<label for="email_confirmation" class="block mb-2 text-sm poppins-regular text-gray-900">Confirm Your
Email</label>
<input type="email" id="email_confirmation" name="email_confirmation"
value="{{ old('email_confirmation') }}"
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 poppins-regular rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Confirm email@example.com" required />
</div>
<div class="mb-5">
<label for="password" class="block mb-2 text-sm font-medium text-gray-900">Your Password</label>
<label for="password" class="block mb-2 text-sm poppins-regular text-gray-900">Your Password</label>
<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"
placeholder="********" required />
</div>
<div class="mb-5">
<label for="password_confirmation" class="block mb-2 text-sm font-medium text-gray-900">Confirm
<label for="password_confirmation" class="block mb-2 text-sm poppins-regular text-gray-900">Confirm
Password</label>
<input type="password" id="password_confirmation" name="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>
@endif
<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">Register</button>
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>
</form>
<div class="text-center mt-4">
<p class="text-sm text-gray-600">Already have an account?</p>
<a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 font-semibold">Login here</a>
<p class="text-sm poppins-regular 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>
</div>
</div>
</div>

View File

@ -0,0 +1,312 @@
<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

@ -0,0 +1,84 @@
<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

@ -0,0 +1,41 @@
<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

@ -0,0 +1,37 @@
<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,4 +7,7 @@
<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"
rel="stylesheet">
<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">
<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">
<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 -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
<!-- @vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css']) -->
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<!-- Viewport untuk Responsif -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -15,8 +15,23 @@
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- Leaflet Routing Machine CSS dan JS -->
{{--
<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')
<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

@ -0,0 +1,36 @@
@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,11 +1,4 @@
<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'))
<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">
@ -15,319 +8,96 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-
@error('rating')
<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">
{{ $message }}</div>
{{ $message }}
</div>
@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>
</section>
</div>
<div class="flex justify-center items-center p-4 pt-20 md:pt-4">
<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="container">
<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>
<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>
<!-- 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 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>
</div>
</figcaption>
</div>
<div class="text-black poppins-medium font-semibold pb-2 text-2xl pt-4 poppins-semibold">
<p>Deskripsi</p>
</div>
<div class="container px-0 lg:px-4">
<div id="overview" class="tab-content">
@include('partials.detail.deskripsi')
</div>
<div>
<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 id="paket" class="tab-content hidden">
@include('partials.detail.paket')
</div>
<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 id="metode" class="tab-content hidden">
@include('partials.detail.metode')
</div>
<div id="lokasi" class="tab-content hidden">
@include('partials.detail.lokasi')
</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);
const buttons = document.querySelectorAll('.tab-btn');
const contents = document.querySelectorAll('.tab-content');
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';
}
});
function activateTab(targetId) {
// Sembunyikan semua konten
contents.forEach(content => content.classList.add('hidden'));
// Reset semua tombol
buttons.forEach(btn => {
btn.classList.remove('bg-gradient-to-tr', 'from-[#60BC9D]', 'to-[#12372A]',
'ring-white', 'scale-105');
btn.classList.add('bg-white/10', 'backdrop-blur');
});
// 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');
}
}
// 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));
// Default tab
activateTab('overview');
// Tambahkan event ke semua tombol
buttons.forEach(button => {
button.addEventListener('click', function() {
const target = this.getAttribute('data-target');
activateTab(target);
});
});
});
</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>
{{-- @include('partials.detail.deskripsi') --}}
</x-layout>

View File

@ -1,99 +1,210 @@
<x-layout>
<div class="container">
<div class="bg-gray-100">
<div class="py-10 bg-white ">
<div class="bg-[#EBFEA1] poppins-extrabold m-auto flex items-center justify-center p-2">
<p>Holaa, Selamat Datang Di LearnMap</p>
<!-- Hero Section -->
<div class="relative">
<!-- Gambar -->
<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 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">
<!-- About Section -->
<div class="flex justify-between items-center pb-4 ">
<p class="text-black poppins-semibold text-xl">
Kursus Populer
</p>
<a href="/kursus" class="py-1 px-4 rounded-full bg-white font-bold text-lg ">
Lihat Semua Kursus
</a>
</div>
<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="#">
<img class="rounded-lg m-auto flex justify-center items-center w-full h-72 object-cover"
src="{{ asset('storage/' . $landingpage->img) }}" alt="" />
</a>
<div class="p-5 h-44">
<a href="#">
<h5
class="mb-2 text-2xl poppins-regular font-extrabold tracking-tight text-gray-900 ">
{{ $landingpage->nama_kursus }}</h5>
</a>
<p class="mb-3 font-normal poppins-regular text-gray-700">
{{ Str::words($landingpage->deskripsi, 30, '...') }}
</p>
</div>
</div>
<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>
</div>
</div>
<!-- Popular Courses Section -->
<div class="container px-4 space-y-8 lg:space-y-12 2xl:space-y-20 py-10 xl:py-16">
{{-- 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">
</div>
@endforeach
@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>
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>
@endif
{{-- <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>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
@if ($landingpage->isNotEmpty())
@foreach ($landingpage as $landingpage)
<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">
<a href="#">
<img class="w-full h-48 object-cover"
src="{{ asset('storage/' . $landingpage->img) }}"
alt="{{ $landingpage->nama_kursus }}" />
</a>
<div class="p-4 flex flex-col flex-grow ">
<h3
class="text-base lg:text-lg 2xl:text-xl font-semibold poppins-bold uppercase text-green-800">
{{ $landingpage->nama_kursus }}
</h3>
<p
class="pb-8 text-xs lg:text-sm 2xl:text-base text-gray-700 poppins-regular flex-grow">
{{ Str::words($landingpage->deskripsi, 20, '...') }}
</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"
href="/kursus/{{ $landingpage->id }}/detail">
Lihat Detail
</a>
</div>
</div>
@endforeach
@else
<div
class="col-span-3 py-10 bg-[#EBFEA1] poppins-extrabold flex items-center justify-center p-2">
<p>Tidak Tersedia Kursus</p>
</div>
@endif
</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>

View File

@ -1,16 +1,10 @@
<x-layout>
<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="container pb-20 pt-20 px-4">
<div class="flex justify-end space-x-2 py-4">
<form method="GET" action="{{ route('user.kursus') }}" class="flex space-x-2">
<!-- Dropdown Kategori -->
<select name="kategori" onchange="this.form.submit()"
class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm">
class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm poppins-regular">
<option value="">Semua Kategori</option>
@foreach ($kategori as $item)
<option value="{{ $item->id }}" {{ request('kategori') == $item->id ? 'selected' : '' }}>
@ -22,33 +16,34 @@ class="p-2 border border-gray-300 rounded-md text-gray-700 text-sm">
<!-- Search Input -->
<div class="relative">
<input type="text" name="search" id="search-dropdown"
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 Nama Kursus" value="{{ request('search') }}" />
class="pr-14 pl-4 p-2.5 w-full text-sm text-black bg-white border border-gray-300 rounded-md poppins-regular"
placeholder="Pencarian Kursus" value="{{ request('search') }}" />
<button type="submit"
class="absolute top-0 end-0 px-4 h-full text-sm font-medium text-white bg-[#4F7F81] rounded-e-lg">
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">
🔍
</button>
</div>
</form>
</div>
{{-- {{ $data_kursus->links() }} --}}
<div class="grid md:grid-cols-1 lg:grid-cols-3 justify-center items-center gap-4 !important">
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 justify-center pb-4 items-center gap-4 !important">
@foreach ($data_kursus as $kursus)
<div class="kursus-item h-ful shadow-2xl rounded-lg ">
<div class="kursus-item max-w-xl h-ful mx-auto shadow-2xl rounded-lg">
<div>
<div>
<img class=" flex justify-center items-center w-full h-64 object-cover"
<img class=" flex justify-center items-center w-full h-64 object-cover rounded-lg"
src="{{ asset('storage/' . $kursus->img) }}" alt="" />
</div>
<div class="p-5 h-44">
<div>
<h5
class="nama-kursus mb-2 text-xl poppins-regular font-extrabold tracking-tight text-gray-900">
class="barlow-condensed-semibold text-green-800 nama-kursus mb-2 text-2xl poppins-regular font-extrabold tracking-tight ">
{{ $kursus->nama_kursus }}
</h5>
<h5
class="nama-kursus mb-2 text-sm poppins-regular font-extrabold tracking-tight text-gray-900">
class="poppins-regular text-black nama-kursus mb-2 text-sm poppins-regular font-extrabold tracking-tight ">
{{ optional($kursus->kategoris)->nama_kategori ?? 'Kategori tidak tersedia' }}
</h5>
</div>
@ -60,7 +55,7 @@ class="nama-kursus mb-2 text-sm poppins-regular font-extrabold tracking-tight te
<div class="flex items-end justify-end rounded-b-lg">
<div class="my-4 mr-4">
<a href="/kursus/{{ $kursus->id }}/detail"
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">
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">
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">
@ -73,6 +68,10 @@ class="inline-flex items-center px-6 py-2 text-sm font-extrabold text-slate-700
</div>
@endforeach
</div>
{{ $data_kursus->links() }}
</div>
{{-- <script>

View File

@ -4,17 +4,40 @@
max-width: 100%;
}
</style>
<div class="container flex flex-col">
<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">
<div class="container py-14 px-4">
<div class="py-10 lg:py-16 2xl:py-20">
<!-- Peta Leaflet -->
<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>
</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>
<!-- Leaflet CSS dan JS -->
@ -26,32 +49,35 @@ class="w-full h-56 sm:h-64 md:h-96 lg:h-[500px] xl:h-[650px] max-w-4xl rounded-l
<script>
document.addEventListener('DOMContentLoaded', function() {
// Inisialisasi peta dengan koordinat dan tingkat zoom
const map = L.map('map1').setView([-7.7517397, 112.1780461],
13); // Gunakan 'map1' untuk ID peta yang sesuai
// Pastikan elemen "map1" ada sebelum inisialisasi
var mapElement = document.getElementById('map1');
if (!mapElement) {
console.warn("Elemen dengan ID 'map1' tidak ditemukan.");
return;
}
// Tambahkan lapisan ubin dari OpenStreetMap
// Inisialisasi Leaflet Map
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', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Menambahkan marker secara dinamis dengan data dari Blade
@foreach ($latilongti as $latilongti)
L.marker([{{ $latilongti->latitude }}, {{ $latilongti->longitude }}])
.addTo(map)
.bindPopup(
'<div class="h-auto w-full">' +
'<img src="{{ asset('storage/' . $latilongti->img) }}" alt="" class="w-full h-20 object-contain">' +
'</div>' +
'<p>' +
'{{ $latilongti->nama_kursus }} <br>' +
'<a href="/kursus/{{ $latilongti->id }}/detail">Selengkapnya</a>'
)
.openPopup();
// Tambahkan marker dari data Blade
@foreach ($latilongti as $data)
L.marker([{{ $data->latitude }}, {{ $data->longitude }}]).addTo(map)
.bindPopup(`
<div class="h-auto w-full">
<img src="{{ asset('storage/' . $data->img) }}" alt="{{ addslashes($data->nama_kursus) }}" class="w-full h-20 object-contain">
</div>
<p>
<b>{{ addslashes($data->nama_kursus) }}</b> <br>
<a href="{{ url('/kursus/' . $data->id . '/detail') }}" class="text-blue-500 underline">Selengkapnya</a>
</p>
`);
@endforeach
});
</script>
</x-layout>

View File

@ -0,0 +1,46 @@
@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

@ -0,0 +1,88 @@
@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

@ -0,0 +1,46 @@
@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

@ -0,0 +1,36 @@
@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

@ -0,0 +1,27 @@
@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

@ -0,0 +1,29 @@
@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

@ -0,0 +1,19 @@
@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

@ -0,0 +1,25 @@
@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

@ -0,0 +1,130 @@
@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()) }}">
<head>
<meta charset="utf-8">
@ -137,4 +137,290 @@
</div>
</div>
</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,10 +3,13 @@
use App\Models\User;
use App\Models\PendingUser;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
use App\Http\Controllers\LoginController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\KategoriController;
use App\Http\Controllers\RegisterController;
use App\Http\Controllers\AdminUserController;
use App\Http\Controllers\KunjunganController;
use App\Http\Controllers\PengunjungController;
use App\Http\Controllers\ProfileNewController;
use App\Http\Controllers\AdminDashboardController;
@ -40,36 +43,55 @@
Route::post('reset-password', [NewPasswordController::class, '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::get('/password/edit', [ProfileNewController::class, 'edit'])->name('password.edit');
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';

BIN
storage.rar Normal file

Binary file not shown.

View File

@ -12,12 +12,18 @@ export default {
padding: {
DEFAULT: "0rem",
sm: "0rem",
lg: "2rem",
xl: "3rem",
"2xl": "4rem",
lg: "1rem",
xl: "2rem",
"2xl": "3rem",
},
// Tambahkan opsi `center` untuk margin auto
center: true,
},
extend: {
// Tambahkan font Bebas Neue di sini
fontFamily: {
"bebas-neue": ['"Bebas Neue"', "sans-serif"],
},
dropShadow: {
"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
@ -28,7 +34,6 @@ export default {
],
},
},
extend: {},
},
plugins: [require("flowbite/plugin")],
};

View File

@ -7,4 +7,13 @@ export default defineConfig({
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
// }
// },
});