From 8f0b98e62f11837a1120287ced7e0f3d535dcd45 Mon Sep 17 00:00:00 2001 From: HANIF FEBRIANSYAH Date: Wed, 12 Mar 2025 20:34:04 +0700 Subject: [PATCH] Done123 --- app/Http/Controllers/KunjunganController.php | 62 +++++++ app/Http/Controllers/PengunjungController.php | 45 ++++- app/Models/DataKursus.php | 9 +- app/Models/Kunjungan.php | 21 +++ .../2025_03_07_060837_kunjungan.php | 32 ++++ public/css/font.css | 156 ++++++++++++++++++ .../admin/tambahDataKursusAdmin.blade.php | 2 +- .../views/admin/ubahDataKursusAdmin.blade.php | 2 +- resources/views/components/layout.blade.php | 2 +- resources/views/login/login.blade.php | 4 +- resources/views/user/detailKursus.blade.php | 28 ++-- resources/views/user/kursus.blade.php | 9 +- resources/views/user/peta.blade.php | 4 +- routes/web.php | 3 + 14 files changed, 348 insertions(+), 31 deletions(-) create mode 100644 app/Http/Controllers/KunjunganController.php create mode 100644 app/Models/Kunjungan.php create mode 100644 database/migrations/2025_03_07_060837_kunjungan.php create mode 100644 public/css/font.css diff --git a/app/Http/Controllers/KunjunganController.php b/app/Http/Controllers/KunjunganController.php new file mode 100644 index 0000000..c025f3e --- /dev/null +++ b/app/Http/Controllers/KunjunganController.php @@ -0,0 +1,62 @@ +ip(); + + // Cari kursus berdasarkan ID + $kursus = DataKursus::find($kursus_id); + + if (!$kursus) { + return response()->json([ + 'status' => 'error', + 'message' => 'Course not found', + ], 404); + } + + // Cek apakah IP pengguna sudah mengunjungi kursus ini pada hari ini + $today = now()->format('Y-m-d'); // Ambil tanggal hari ini dalam format Y-m-d + + $existingVisit = Kunjungan::where('ip_user', $ip_user) + ->where('kursus_id', $kursus_id) + ->whereDate('created_at', $today) // Cek berdasarkan tanggal + ->first(); + + if ($existingVisit) { + return response()->json([ + 'status' => 'info', + 'message' => 'You have already visited this course today.', + ], 200); + } + + // Jika belum ada kunjungan, buat data kunjungan baru + try { + $kunjungan = Kunjungan::create([ + 'ip_user' => $ip_user, + 'kursus_id' => $kursus_id, + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Successfully recorded visit.', + 'data' => $kunjungan + ], 201); + } catch (\Exception $e) { + return response()->json([ + 'status' => 'error', + 'message' => 'Failed to record visit: ' . $e->getMessage(), + ], 500); + } + } +} diff --git a/app/Http/Controllers/PengunjungController.php b/app/Http/Controllers/PengunjungController.php index 5f17ff3..3daef62 100644 --- a/app/Http/Controllers/PengunjungController.php +++ b/app/Http/Controllers/PengunjungController.php @@ -2,8 +2,10 @@ namespace App\Http\Controllers; +use App\Models\Kunjungan; use App\Models\DataKursus; use App\Models\DataUlasan; +use Illuminate\Support\Str; use App\Models\DataKategori; use Illuminate\Http\Request; use Dflydev\DotAccessData\Data; @@ -15,11 +17,12 @@ class PengunjungController extends Controller // PENGUNJUNG public function home() { - // Ambil 3 data yang populer dari tabel DataKursus - $landingpage = DataKursus::where('popular', 'Popular') - ->limit(3) + $landingpage = DataKursus::withCount('kunjungan') // Menghitung jumlah kunjungan tanpa filter waktu + ->orderByDesc('kunjungan_count') // Mengurutkan berdasarkan jumlah kunjungan terbanyak + ->limit(3) // Mengambil 4 kursus terpopuler ->get(); + // Potong deskripsi agar hanya terdiri dari 22 kata foreach ($landingpage as $item) { $item->deskripsi = \Illuminate\Support\Str::words($item->deskripsi, 22, '...'); @@ -48,7 +51,8 @@ public function kursus(Request $request) } // Ambil data kursus secara acak dengan kategori - $data_kursus = $query->with('kategoris')->inRandomOrder()->paginate(10); + $data_kursus = $query->with('kategoris')->paginate(12); + // Ambil daftar kategori untuk dropdown $kategori = DataKategori::all(); @@ -78,6 +82,30 @@ public function maps() public function detail(string $id) { + // Cek apakah sudah ada ID perangkat dalam cookie + $deviceId = request()->cookie('device_id'); + + if (!$deviceId) { + // Jika tidak ada, buat ID baru dan simpan dalam cookie + $deviceId = Str::uuid()->toString(); + cookie()->queue('device_id', $deviceId, 60 * 24 * 365); // Simpan selama setahun + } + + // Cek apakah deviceId sudah ada pada kursus_id yang sama pada hari yang sama + $existingVisit = Kunjungan::where('device_id', $deviceId) + ->where('kursus_id', $id) // Cek apakah sudah ada kunjungan untuk kursus_id yang sama + ->whereDate('created_at', today()) // Cek apakah ada kunjungan pada hari yang sama + ->exists(); + + if (!$existingVisit) { + // Simpan kunjungan jika belum ada kunjungan dengan deviceId dan kursus_id yang sama pada hari ini + Kunjungan::create([ + 'device_id' => $deviceId, + 'kursus_id' => $id, + ]); + } + + // Ambil data kursus beserta ulasan dan kategorinya $data = DataKursus::with('kategoris', 'ulasan')->find($id); @@ -87,11 +115,11 @@ public function detail(string $id) // Ambil data ulasan terkait, urutkan berdasarkan created_at terbaru $imageNames = json_decode($data->img_konten, true); - $ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3); // Membatasi hanya 3 ulasan per halaman, urutan terbaru + $ulasan = $data->ulasan()->orderBy('created_at', 'desc')->paginate(3); // Hitung rata-rata rating - $averageRating = $ulasan->avg('rating'); // Mengambil rata-rata rating - $totalRatings = $ulasan->count(); // Menghitung total jumlah ulasan + $averageRating = $ulasan->avg('rating'); + $totalRatings = $ulasan->count(); // Kirim data ke view return view('user.detailKursus', compact('data', 'imageNames', 'ulasan', 'averageRating', 'totalRatings')); @@ -102,6 +130,9 @@ public function detail(string $id) + + + public function rute(string $id) { // Ambil kursus berdasarkan ID diff --git a/app/Models/DataKursus.php b/app/Models/DataKursus.php index c95255c..33ef93f 100644 --- a/app/Models/DataKursus.php +++ b/app/Models/DataKursus.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Models\Kunjungan; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -29,11 +30,17 @@ class DataKursus extends Model ]; public $timestamps = true; - + public function kategoris(): BelongsTo { return $this->belongsTo(DataKategori::class, 'kategori_id', 'id'); // Menentukan foreign key dan local key } + + public function kunjungan(): HasMany + { + return $this->hasMany(Kunjungan::class, 'kursus_id', 'id'); // Menentukan foreign key dan local key + } + public function ulasan(): HasMany { return $this->hasMany(DataUlasan::class, 'kursus_id', 'id'); // Menentukan foreign key dan local key diff --git a/app/Models/Kunjungan.php b/app/Models/Kunjungan.php new file mode 100644 index 0000000..de7f7f8 --- /dev/null +++ b/app/Models/Kunjungan.php @@ -0,0 +1,21 @@ +belongsTo(DataKursus::class, 'kursus_id', 'id'); + } +} diff --git a/database/migrations/2025_03_07_060837_kunjungan.php b/database/migrations/2025_03_07_060837_kunjungan.php new file mode 100644 index 0000000..cdfad56 --- /dev/null +++ b/database/migrations/2025_03_07_060837_kunjungan.php @@ -0,0 +1,32 @@ +bigIncrements('id'); + $table->string('device_id'); // Bisa menyimpan IPv4 (15 char) atau IPv6 (45 char) + $table->timestamps(); + + // Foreign key constraint + $table->foreignId('kursus_id') + ->nullable() + ->constrained('data_kursus') + ->onDelete('cascade') // Hapus kunjungan jika kursus dihapus + ->onUpdate('cascade'); + }); + } + + public function down(): void + { + Schema::dropIfExists('kunjungan'); + } +}; diff --git a/public/css/font.css b/public/css/font.css new file mode 100644 index 0000000..6603b22 --- /dev/null +++ b/public/css/font.css @@ -0,0 +1,156 @@ +.pacifico-regular { + font-family: "Pacifico", cursive; + font-weight: 400; + font-style: normal; +} +.archivo-black-regular { + font-family: "Archivo Black", sans-serif; + font-weight: 400; + font-style: normal; +} + +.archivo-uniquifier { + font-family: "Archivo", sans-serif; + font-optical-sizing: auto; + font-weight: weight; + font-style: normal; + font-variation-settings: "wdth" 100; +} + +.rubik-mono-one-regular { + font-family: "Rubik Mono One", monospace; + font-weight: 400; + font-style: normal; +} + +.playfair-display-uniquifier { + font-family: "Playfair Display", serif; + font-optical-sizing: auto; + font-weight: weight; + font-style: normal; +} +.dm-sans { + font-family: "DM Sans", serif; + font-optical-sizing: auto; + font-weight: weight; + font-style: normal; +} +.castoro-regular { + font-family: "Castoro", serif; + font-weight: 400; + font-style: normal; +} + +.castoro-regular-italic { + font-family: "Castoro", serif; + font-weight: 400; + font-style: italic; +} + +.poppins-thin { + font-family: "Poppins", serif; + font-weight: 100; + font-style: normal; +} + +.poppins-extralight { + font-family: "Poppins", serif; + font-weight: 200; + font-style: normal; +} + +.poppins-light { + font-family: "Poppins", serif; + font-weight: 300; + font-style: normal; +} + +.poppins-regular { + font-family: "Poppins", serif; + font-weight: 400; + font-style: normal; +} + +.poppins-medium { + font-family: "Poppins", serif; + font-weight: 500; + font-style: normal; +} + +.poppins-semibold { + font-family: "Poppins", serif; + font-weight: 600; + font-style: normal; +} + +.poppins-bold { + font-family: "Poppins", serif; + font-weight: 700; + font-style: normal; +} + +.poppins-extrabold { + font-family: "Poppins", serif; + font-weight: 800; + font-style: normal; +} + +.poppins-black { + font-family: "Poppins", serif; + font-weight: 900; + font-style: normal; +} + +.poppins-thin-italic { + font-family: "Poppins", serif; + font-weight: 100; + font-style: italic; +} + +.poppins-extralight-italic { + font-family: "Poppins", serif; + font-weight: 200; + font-style: italic; +} + +.poppins-light-italic { + font-family: "Poppins", serif; + font-weight: 300; + font-style: italic; +} + +.poppins-regular-italic { + font-family: "Poppins", serif; + font-weight: 400; + font-style: italic; +} + +.poppins-medium-italic { + font-family: "Poppins", serif; + font-weight: 500; + font-style: italic; +} + +.poppins-semibold-italic { + font-family: "Poppins", serif; + font-weight: 600; + font-style: italic; +} + +.poppins-bold-italic { + font-family: "Poppins", serif; + font-weight: 700; + font-style: italic; +} + +.poppins-extrabold-italic { + font-family: "Poppins", serif; + font-weight: 800; + font-style: italic; +} + +.poppins-black-italic { + font-family: "Poppins", serif; + font-weight: 900; + font-style: italic; +} diff --git a/resources/views/admin/tambahDataKursusAdmin.blade.php b/resources/views/admin/tambahDataKursusAdmin.blade.php index ce2c379..0d9cb7d 100644 --- a/resources/views/admin/tambahDataKursusAdmin.blade.php +++ b/resources/views/admin/tambahDataKursusAdmin.blade.php @@ -23,7 +23,7 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus: required /> -
+