Takut hilang
This commit is contained in:
parent
a1ef885081
commit
e718c10a60
|
@ -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_;
|
||||
|
@ -20,7 +22,9 @@ class AdminDataKursusController extends Controller
|
|||
public function dataKursus()
|
||||
{
|
||||
// Mengambil semua data kursus dari model DataKursus
|
||||
$courses = DataKursus::with('kategoris')->paginate(10);
|
||||
$courses = DataKursus::with('kategoris')
|
||||
->where('user_id', auth()->id()) // Filter berdasarkan user yang login
|
||||
->paginate(10);
|
||||
|
||||
// Mengambil gambar untuk setiap course, jika ada
|
||||
foreach ($courses as $course) {
|
||||
|
@ -53,7 +57,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 +72,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 +93,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 +102,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 +121,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 +149,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 +164,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 +205,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 +213,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 +222,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 +239,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 ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
<?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',
|
||||
'password' => 'required|min:6',
|
||||
'verif_password' => 'required|same:password',
|
||||
]);
|
||||
|
||||
// Simpan user baru ke database
|
||||
User::create([
|
||||
'name' => $validatedData['name'],
|
||||
'email' => $validatedData['email'],
|
||||
'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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -104,11 +104,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 ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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('pengunjung.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();
|
||||
|
|
|
@ -31,7 +31,7 @@ public function home()
|
|||
$peta = DataKursus::with('kategoris')->get();
|
||||
|
||||
// Kembalikan view dengan data yang sudah diproses
|
||||
return view('user.home', compact('landingpage','peta'));
|
||||
return view('user.home', compact('landingpage', 'peta'));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ 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;
|
||||
|
@ -35,7 +37,7 @@ 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
|
||||
|
@ -45,4 +47,8 @@ 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
|
|
||||
*/
|
||||
|
||||
'locale' => 'en',
|
||||
'locale' => 'id',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,9 +18,31 @@ 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' => 'Admin',
|
||||
'email' => 'admin@gmail.com',
|
||||
'username' => 'admin',
|
||||
'password' => bcrypt('admin123'), // Ganti dengan password pilihan Anda
|
||||
'role' => 'admin',
|
||||
]);
|
||||
User::create([
|
||||
'name' => 'User',
|
||||
'email' => 'user@gmail.com',
|
||||
'username' => 'user',
|
||||
'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda
|
||||
'role' => 'user',
|
||||
]);
|
||||
User::create([
|
||||
'name' => 'pengunjung',
|
||||
'username' => 'pengunjung',
|
||||
'email' => 'pengunjung@gmail.com',
|
||||
'password' => bcrypt('pengunjung123'), // Ganti dengan password pilihan Anda
|
||||
'role' => 'pengunjung',
|
||||
]);
|
||||
DataKategori::insert([
|
||||
['nama_kategori' => 'Speaking'],
|
||||
['nama_kategori' => 'Reading'],
|
||||
|
@ -28,31 +50,25 @@ public function run(): void
|
|||
['nama_kategori' => 'Good Evening'],
|
||||
]);
|
||||
|
||||
// User::create([
|
||||
// 'name' => 'user',
|
||||
// 'email' => 'user@gmail.com',
|
||||
// 'password' => bcrypt('user123'), // Ganti dengan password pilihan Anda
|
||||
// 'role' => 'pengunjung',
|
||||
// ]);
|
||||
// // Buat 3 kategori, setiap kategori memiliki banyak kursus
|
||||
// // Buat 3 kategori
|
||||
// $kategoris = DataKategori::factory(3)->create();
|
||||
$kategoris = DataKategori::factory(3)->create();
|
||||
|
||||
// // Buat kursus hingga total 20 data
|
||||
// $totalKursus = 20;
|
||||
// $kategoris->each(function ($kategori) use ($totalKursus, $kategoris) {
|
||||
// $jumlahKursusPerKategori = floor($totalKursus / $kategoris->count());
|
||||
// DataKursus::factory($jumlahKursusPerKategori)->create([
|
||||
// 'kategori_id' => $kategori->id,
|
||||
// ]);
|
||||
// });
|
||||
// Buat kursus hingga total 20 data
|
||||
$totalKursus = 20;
|
||||
$kategoris->each(function ($kategori) use ($totalKursus, $kategoris) {
|
||||
$jumlahKursusPerKategori = floor($totalKursus / $kategoris->count());
|
||||
DataKursus::factory($jumlahKursusPerKategori)->create([
|
||||
'kategori_id' => $kategori->id,
|
||||
]);
|
||||
});
|
||||
|
||||
// // Jika ada sisa karena pembagian tidak rata, tambahkan ke kategori pertama
|
||||
// $sisa = $totalKursus % $kategoris->count();
|
||||
// if ($sisa > 0) {
|
||||
// DataKursus::factory($sisa)->create([
|
||||
// 'kategori_id' => $kategoris->first()->id,
|
||||
// ]);
|
||||
// }
|
||||
// Jika ada sisa karena pembagian tidak rata, tambahkan ke kategori pertama
|
||||
$sisa = $totalKursus % $kategoris->count();
|
||||
if ($sisa > 0) {
|
||||
DataKursus::factory($sisa)->create([
|
||||
'kategori_id' => $kategoris->first()->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
<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="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>
|
|
@ -1,64 +1,58 @@
|
|||
<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-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"
|
||||
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>
|
||||
{{ $kategori->links() }}
|
||||
|
||||
<div class="relative overflow-x-auto sm:rounded-lg poppins-regular">
|
||||
<table class="w-full text-sm text-end rtl:text-right shadow-gray-600 text-gray-500">
|
||||
<thead class="text-8x1 text-gray-700 uppercase shadow-gray-600 bg-gray-50 pb-4">
|
||||
<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-gradient-to-tr from-[#60BC9D] to-[#12372A] 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-gradient-to-tr from-[#60BC9D] to-[#12372A] 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 +66,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 poppins-regular text-green-800 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">
|
||||
|
@ -97,13 +91,13 @@ class="w-full px-3 border rounded-lg focus:outline-none focus:ring focus:border-
|
|||
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-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 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 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 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,13 +110,13 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
|
|||
<div id="default-modal-edit-kategori{{ $kategoris->id }}" tabindex="-1" aria-hidden="true"
|
||||
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 poppins-regular 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">
|
||||
|
@ -136,8 +130,8 @@ class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounde
|
|||
action="{{ route('kategori.update', $kategoris->id) }}">
|
||||
@csrf <!-- Token CSRF -->
|
||||
@method('PUT') <!-- Menggunakan metode PUT -->
|
||||
<input hidden value="{{ $kategoris->id }}" type="text" id="edit-idkategori"
|
||||
name="id" required>
|
||||
<input hidden value="{{ $kategoris->id }}" type="text" id="edit-idkategori" name="id"
|
||||
required>
|
||||
|
||||
<div class="px-4 pb-4 items-center">
|
||||
<label for="detail_kategori"
|
||||
|
@ -147,14 +141,13 @@ class="block mt-4 text-gray-700 poppins-regular mb-1">Kategori</label>
|
|||
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 poppins-regular 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 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 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 +162,9 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
|
|||
<div id="default-modal-delete-kategori{{ $kategoris->id }}" tabindex="-1"
|
||||
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 +174,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 poppins-regular 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 +187,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 poppins-regular inline-flex items-center px-5 py-2.5 text-center">
|
||||
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 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 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 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>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<x-adminlayout>
|
||||
|
||||
<div class="container">
|
||||
<div class="lg:px-10">
|
||||
<div class="py-10 px-4 md:px-0">
|
||||
|
||||
|
||||
|
@ -11,94 +11,104 @@
|
|||
|
||||
{{ $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-6x1 poppins-regular 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 poppins-regular 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">
|
||||
<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-green-800 text-white py-2 px-2 bg-gradient-to-tr from-[#60BC9D] to-[#12372A] 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-green-800 text-white py-2 px-2 bg-gradient-to-tr from-[#60BC9D] to-[#12372A] 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-green-800 text-white py-2 px-2 bg-gradient-to-tr from-[#60BC9D] to-[#12372A] 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"
|
||||
|
@ -170,7 +180,7 @@ class="py-2.5 px-5 ms-3 text-sm poppins-regular text-gray-900 focus:outline-none
|
|||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Main modal -->
|
||||
|
||||
@foreach ($courses as $course)
|
||||
|
|
|
@ -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]"
|
||||
|
@ -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" />
|
||||
|
|
|
@ -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]"
|
||||
|
@ -28,11 +28,10 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
|
|||
placeholder="Kampung Inggris LC - Language Center" required />
|
||||
</div>
|
||||
<div class="hidden">
|
||||
<label for="countries"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Pilih
|
||||
<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))
|
||||
|
|
|
@ -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 dark:border-gray-700 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>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<footer class="bg-green-900">
|
||||
<div class="mx-auto container w-full py-6 lg:py-8">
|
||||
<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]">
|
||||
|
@ -15,7 +15,7 @@ class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace
|
|||
</div>
|
||||
<div class="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3">
|
||||
<div>
|
||||
<h2 class="mb-6 text-sm poppin-semibold text-white uppercase">Resources
|
||||
<h2 class="mb-6 text-sm poppins-semibold text-white uppercase">Resources
|
||||
</h2>
|
||||
<ul class="text-white poppins-regular space-y-4">
|
||||
<li class="">
|
||||
|
@ -34,8 +34,7 @@ class="self-center pt-6 text-4xl text-white barlow-condensed-semibold whitespace
|
|||
</h2>
|
||||
<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>
|
||||
|
|
|
@ -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', 'public/css/font.css'])
|
||||
@include('components.navbar')
|
||||
@include('partials.font')
|
||||
@include('partials.head')
|
||||
|
||||
</head>
|
||||
|
||||
|
|
|
@ -1,61 +1,101 @@
|
|||
<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 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>
|
||||
<div class="flex justify-center ">
|
||||
<nav class="container px-4 top-4 fixed z-[999] ">
|
||||
<div class="flex justify-between py-2 items-center shadow-lg bg-white px-4 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>
|
||||
<span class="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-lg poppins-regular">
|
||||
<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') ? '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>
|
||||
|
||||
<!-- Menu Navigasi -->
|
||||
<ul class="flex space-x-8 text-lg poppins-regular">
|
||||
<li><a href="{{ route('user.home') }}" class="text-black hover:text-green-600">Beranda</a></li>
|
||||
<li><a href="{{ route('user.kursus') }}" class="text-black hover:text-green-600">Kursus</a></li>
|
||||
<li><a href="{{ route('user.peta') }}" class="text-black hover:text-green-600">Peta</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- 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">
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<!-- Hamburger Button (hanya tampil di mobile) -->
|
||||
<button data-collapse-toggle="navbar-menu" type="button"
|
||||
class="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-6 h-6" 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>
|
||||
<!-- 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() && Auth::user()->role === 'admin')
|
||||
<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>
|
||||
|
||||
<!-- Login / Dropdown User -->
|
||||
<div class="ml-4">
|
||||
@if (Auth::check())
|
||||
<div class="relative" data-dropdown>
|
||||
<button type="button"
|
||||
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>
|
||||
<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 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('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-5 py-2 text-xs lg:text-sm rounded-full hover:bg-green-700">Login</a>
|
||||
@endif
|
||||
</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
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
<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 max-w-4xl mx-auto">
|
||||
{{-- <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/Rectangle 65.png') }}" class="h-10 w-10" alt="Logo LearnMap" />
|
||||
<span class="ml-2 text-2xl font-semibold text-black">LearnMap</span>
|
||||
<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 -->
|
||||
<ul class="flex space-x-8 text-lg poppins-regular">
|
||||
<li>
|
||||
<a href="{{ route('admin.home') }}" class="text-black hover:text-green-600 ">
|
||||
Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route('kategori.index') }}" class="text-black hover:text-green-600">
|
||||
Kategori
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route('admin.dataKursus') }}" class="text-black hover:text-green-600">
|
||||
Data Kursus
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@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">
|
||||
|
@ -43,10 +34,12 @@
|
|||
<span class="block text-sm text-gray-500 truncate">{{ Auth::user()->email }}</span>
|
||||
</div>
|
||||
<ul class="py-2" aria-labelledby="user-menu-button">
|
||||
<li>
|
||||
<a href="{{ route('admin.home') }}"
|
||||
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Dashboard</a>
|
||||
</li>
|
||||
@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>
|
||||
|
@ -67,65 +60,152 @@ class="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 text-left"
|
|||
class="bg-green-900 text-white px-4 py-2 rounded-full hover:bg-green-700">Login</a>
|
||||
@endif
|
||||
</nav>
|
||||
</div>
|
||||
</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
|
||||
|
||||
|
||||
|
||||
<nav class="fixed top-0 z-50 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700">
|
||||
<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 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600">
|
||||
<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 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
|
||||
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="https://flowbite.com/docs/images/people/profile-picture-5.jpg" alt="user photo">
|
||||
</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 class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-sm shadow-sm dark:bg-gray-700 dark:divide-gray-600"
|
||||
id="dropdown-user">
|
||||
<div class="px-4 py-3" role="none">
|
||||
<p class="text-sm text-green-900 dark:text-white" role="none">
|
||||
{{ Auth::user()->email }}
|
||||
</p>
|
||||
<p class="text-sm font-medium text-green-900 truncate dark:text-gray-300" role="none">
|
||||
{{ Auth::user()->name }}
|
||||
</p>
|
||||
</div>
|
||||
<ul class="py-1" role="none">
|
||||
<li>
|
||||
<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') }}"
|
||||
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"
|
||||
class="block px-4 py-2 text-sm text-green-700 hover:bg-gray-100 ">
|
||||
@csrf
|
||||
<button type="submit" class="w-full text-left">Sign out</button>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</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>
|
||||
|
|
|
@ -1,27 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<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"/>
|
||||
<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 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">
|
||||
<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">
|
||||
<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">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
|
@ -45,16 +54,22 @@
|
|||
<form method="POST">
|
||||
@csrf
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm poppins-regular mb-1" for="email">Email*</label>
|
||||
<input class="w-full border border-gray-300 rounded-lg py-2 px-3" id="email" name="email" placeholder="Enter your email" type="email" required/>
|
||||
<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>
|
||||
<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" type="submit">Log In</button>
|
||||
<button
|
||||
class="w-full bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white rounded-lg py-2 poppins-regular"
|
||||
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>
|
||||
|
@ -62,13 +77,18 @@
|
|||
</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="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>
|
||||
<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>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<div class="container">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="grid grid-cols-2">
|
||||
|
||||
|
||||
<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>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{-- Bagian Fasilitas --}}
|
||||
<div class="w-auto xl:max-w-max space-y-4">
|
||||
<p class="poppins-semibold font-semibold text-2xl text-black underline">
|
||||
Fasilitas
|
||||
</p>
|
||||
<p class="pl-4 poppins-regular 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="pl-4 text-blue-500 hover:underline poppins-medium text-sm mt-2">
|
||||
Lihat Selengkapnya
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
<!-- CSS Aplikasi -->
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js','public/css/font.css'])
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js', 'public/css/font.css'])
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Viewport untuk Responsif -->
|
||||
|
@ -31,7 +31,7 @@
|
|||
<!-- 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">\
|
||||
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet">
|
||||
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -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>
|
|
@ -12,16 +12,16 @@ class="fixed top-5 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-
|
|||
</div>
|
||||
@enderror
|
||||
|
||||
<div class="flex justify-center items-center pb-16 p-4">
|
||||
<div class="h-auto w-full relative">
|
||||
<img src="{{ asset('storage/' . $data->img) }}" alt="" class="aspect-[4/2] w-full object-cover rounded-2xl">
|
||||
<div class="flex justify-center items-center p-4">
|
||||
<div class="h-auto w-full relative ">
|
||||
<img src="{{ asset('storage/' . $data->img) }}" alt=""
|
||||
class="aspect-[4/2] w-full object-cover rounded-2xl">
|
||||
<figcaption class="container w-full">
|
||||
|
||||
<div class="absolute container bottom-8 left-1/2 transform -translate-x-1/2 space-y-10 text-center">
|
||||
<div class="absolute container bottom-12 left-1/2 transform -translate-x-1/2 space-y-10 text-center">
|
||||
<p class="poppins-bold text-start text-6xl xl:text-8xl text-white pr-16 w-1/2">
|
||||
{{ $data->nama_kursus }}
|
||||
</p>
|
||||
|
||||
<div class="flex justify-start space-x-4">
|
||||
<a href="/kursus/{{ $data->id }}/rute" target="_blank"
|
||||
class="poppins-medium py-3 px-8 bg-[#4F7F81] text-white rounded-xl text-sm shadow-xl">Rute
|
||||
|
@ -32,313 +32,21 @@ class="poppins-medium py-3 px-8 bg-[#4F7F81] text-white rounded-xl text-sm shado
|
|||
Detail</button>
|
||||
</div>
|
||||
<div class="flex justify-between w-full text-white">
|
||||
<button class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Deskripsi</button>
|
||||
<button class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Paket</button>
|
||||
<button class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Metode</button>
|
||||
<button class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Fasilitas</button>
|
||||
<button class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Lokasi</button>
|
||||
<button
|
||||
class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Deskripsi</button>
|
||||
<button
|
||||
class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Paket</button>
|
||||
<button
|
||||
class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Metode</button>
|
||||
<button
|
||||
class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Fasilitas</button>
|
||||
<button
|
||||
class="px-20 py-3 poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] rounded-3xl">Lokasi</button>
|
||||
</div>
|
||||
</div>
|
||||
</figcaption>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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 Fasilitas --}}
|
||||
<div class="w-auto xl:max-w-max space-y-4">
|
||||
<p class="poppins-semibold font-semibold text-2xl text-black underline">
|
||||
Fasilitas
|
||||
</p>
|
||||
<p class="pl-4 poppins-regular 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="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>
|
||||
</x-layout>
|
||||
@include('partials.detail.deskripsi')
|
||||
</x-layout>
|
||||
|
|
|
@ -4,129 +4,176 @@
|
|||
<!-- Hero Section -->
|
||||
<div class="relative">
|
||||
<!-- Gambar -->
|
||||
<img alt="LearnMap Hero Image" class="w-full object-cover" src="{{ asset('img/bg-home.jpg') }}" />
|
||||
|
||||
<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 pl-8">
|
||||
<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-9xl font-bold mb-4 text-center barlow-condensed-semibold">
|
||||
<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">
|
||||
PARE EDUCATION <br> ENGLISH LANGUAGE
|
||||
</h1>
|
||||
<!-- <p class="text-lg mb-6">
|
||||
|
||||
<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> -->
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
|
||||
<a class=" text-white px-6 py-3 rounded-md bg-gradient-to-tr from-[#60BC9D] to-[#12372A]" href="{{route('user.kursus')}}">
|
||||
<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>
|
||||
|
||||
<!-- About Section -->
|
||||
|
||||
|
||||
<!-- Popular Courses Section -->
|
||||
<div class="container mx-auto px-4 py-12">
|
||||
<div class=" py-12">
|
||||
<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="space-y-4">
|
||||
<h2 class="text-5xl barlow-condensed-semibold text-green-800 font-bold ">
|
||||
<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 mb-12 text-xl text-gray-600">
|
||||
<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
|
||||
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 ">
|
||||
<div class="flex">
|
||||
|
||||
<a class="poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white px-6 py-3 rounded-md"
|
||||
<a class="text-xs lg:text-sm 2xl:text-lg poppins-regular bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white px-4 py-2 2xl:px-6 2xl:py-3 rounded-md"
|
||||
href="">
|
||||
Pelajari Lebih Lanjut
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<img alt="About LearnMap" class="w-auto h-128 object-contain "
|
||||
src="{{ asset('img/tentang kami2.jpg') }}" />
|
||||
{{-- <img alt="About LearnMap" class="w-auto h-128 object-contain "
|
||||
src="{{ asset('img/img/tentang kami.jpg') }}" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PETA -->
|
||||
<div id="" class="container px-4 mt-10 relative z-[1] ">
|
||||
<div class="mb-4 flex justify-between">
|
||||
<div id="" class=" relative z-[1] ">
|
||||
<div class=" flex justify-between">
|
||||
<!-- Section Title -->
|
||||
<div>
|
||||
<p class="text-5xl font-bold text-start mb-4 barlow-condensed-semibold text-green-800">PERSEBARAN KURSUS</p>
|
||||
<h5 class="text-start poppins-regular mb-12 text-xl text-gray-600">Berikut adalah persebaran seluruh wisata saat ini
|
||||
<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="p-20 " id="map"></div>
|
||||
<div class="aspect-[5/2]" id="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
/* Bisa disesuaikan */
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 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 () {
|
||||
// Pastikan elemen "map" ada di dalam HTML
|
||||
var map = L.map('map').setView([51.505, -0.09], 13);
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Pastikan elemen "map" ada dalam dokumen sebelum inisialisasi
|
||||
var mapElement = document.getElementById('map');
|
||||
if (!mapElement) {
|
||||
console.warn("Element dengan ID 'map' tidak ditemukan.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Inisialisasi Leaflet map
|
||||
var map = L.map('map').setView([-7.7560717, 112.1823541], 15);
|
||||
|
||||
// Tambahkan tile layer dari OpenStreetMap
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
// Tambahkan marker
|
||||
L.marker([51.5, -0.09]).addTo(map)
|
||||
.bindPopup('<b>Ini Popup</b><br>Anda bisa menyesuaikan teks di sini.')
|
||||
.openPopup();
|
||||
// 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 di pusat kota Pare
|
||||
L.marker([-7.7560717, 112.1823541]).addTo(map)
|
||||
.bindPopup('<b>Default Marker: Pusat Kota Pare</b>');
|
||||
@endif
|
||||
|
||||
// Perbaiki ukuran map jika terjadi masalah dengan tampilan
|
||||
setTimeout(() => {
|
||||
map.invalidateSize();
|
||||
}, 500);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<h2 class="text-5xl font-bold text-start mb-4 barlow-condensed-semibold text-green-800">
|
||||
|
||||
|
||||
|
||||
</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-12 text-xl text-gray-600">
|
||||
<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 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<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">
|
||||
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) }}"
|
||||
<img class="w-full h-48 object-cover"
|
||||
src="{{ asset('storage/' . $landingpage->img) }}"
|
||||
alt="{{ $landingpage->nama_kursus }}" />
|
||||
</a>
|
||||
<div class="p-4">
|
||||
<h3 class="text-xl font-semibold poppins-bold uppercase text-green-800">
|
||||
<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="mt-2 text-gray-700 poppins-regular text-gray-600">
|
||||
<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-4 inline-block bg-gradient-to-tr from-[#60BC9D] to-[#12372A] text-white px-4 py-2 rounded-md"
|
||||
<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>
|
||||
|
@ -135,13 +182,13 @@ class="bg-white rounded-lg shadow-md overflow-hidden transition ease-in-out dela
|
|||
@endforeach
|
||||
@else
|
||||
<div
|
||||
class="poppins-regular text-graycol-span-3 py-10 bg-[#EBFEA1] poppins-extrabold flex items-center justify-center p-2">
|
||||
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>
|
||||
</x-layout>
|
||||
</x-layout>
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
<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 -->
|
||||
|
@ -32,9 +26,9 @@ class="absolute top-0 end-0 px-4 h-full text-sm font-medium text-white bg-gradie
|
|||
</form>
|
||||
</div>
|
||||
|
||||
{{ $data_kursus->links() }}
|
||||
{{-- {{ $data_kursus->links() }} --}}
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 justify-center py-4 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 max-w-xl h-ful mx-auto shadow-2xl rounded-lg">
|
||||
<div>
|
||||
|
@ -45,11 +39,11 @@ class="absolute top-0 end-0 px-4 h-full text-sm font-medium text-white bg-gradie
|
|||
<div class="p-5 h-44">
|
||||
<div>
|
||||
<h5
|
||||
class="barlow-condensed-semibold text-green-800 nama-kursus mb-2 text-2xl 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="poppins-regular text-black 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>
|
||||
|
|
|
@ -4,18 +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 -->
|
||||
|
@ -27,33 +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],
|
||||
15); // 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: '© <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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -3,17 +3,19 @@
|
|||
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;
|
||||
use App\Http\Controllers\AdminDataKursusController;
|
||||
use App\Http\Controllers\Auth\NewPasswordController;
|
||||
use App\Http\Controllers\Auth\PasswordResetLinkController;
|
||||
use App\Http\Controllers\KunjunganController;
|
||||
|
||||
Route::get('/login', [LoginController::class, 'index'])->name('login'); // Halaman login
|
||||
Route::post('/login', [LoginController::class, 'authenticate'])->name('login.process'); // Proses login
|
||||
|
@ -41,23 +43,36 @@
|
|||
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::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 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 di admin
|
||||
// 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');
|
||||
Route::resource('kategori', KategoriController::class);
|
||||
});
|
||||
|
||||
|
||||
// USER
|
||||
// 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');
|
||||
|
@ -67,12 +82,15 @@
|
|||
Route::post('/store-ulasan', [PengunjungController::class, 'storeUlasann'])->name('storeUlasan');
|
||||
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');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
|
||||
require __DIR__ . '/auth.php';
|
||||
|
|
|
@ -22,7 +22,7 @@ export default {
|
|||
extend: {
|
||||
// Tambahkan font Bebas Neue di sini
|
||||
fontFamily: {
|
||||
'bebas-neue': ['"Bebas Neue"', 'sans-serif'],
|
||||
"bebas-neue": ['"Bebas Neue"', "sans-serif"],
|
||||
},
|
||||
dropShadow: {
|
||||
"1xl": "0 10px 20px rgba(0, 0, 0, 0.15)", // Light shadow for minimal depth
|
||||
|
@ -36,4 +36,4 @@ export default {
|
|||
},
|
||||
},
|
||||
plugins: [require("flowbite/plugin")],
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue