diff --git a/app/Http/Controllers/Dashboard/DatatableController.php b/app/Http/Controllers/Dashboard/DatatableController.php index 0a31045..941f083 100644 --- a/app/Http/Controllers/Dashboard/DatatableController.php +++ b/app/Http/Controllers/Dashboard/DatatableController.php @@ -8,6 +8,7 @@ use App\Models\ContentRecap; use App\Models\GovernmentAgency; use App\Models\Location; +use App\Models\MediaMonitoring; use App\Models\News; use App\Models\Role; use App\Models\SubClassification; @@ -481,6 +482,64 @@ public function contentRecap(Request $request){ } + public function mediaMonitoring(Request $request){ + if ($request->ajax()) { + + + + $data = MediaMonitoring::with(['enhancer'])->get(); + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('enhancer', function ($data) { + return $data->enhancer->name; + }) + ->addColumn('input_date', function ($data) { + return idn_date($data->input_date, 'd F Y'); + }) + ->addColumn('title', function ($data) { + return shorten_text($data->title, 40); + }) + ->addColumn('link', function ($data) { + return ''.$data->link.''; + }) + ->addColumn('action', function ($data) { + $showUrl = route('dashboard.media.monitoring.show', ['id' => encrypt_id($data->id)]); + + $editUrl = route('dashboard.media.monitoring.edit', ['id' => encrypt_id($data->id)]); + + $deleteUrl = route('dashboard.media.monitoring.destroy', ['id' => encrypt_id($data->id)]); + + $dropdown = '
'; + + return $dropdown; + }) + + ->rawColumns(['link', 'action']) + ->make(true); + } + + return response()->json(['error' => 'Unauthorized'], 401); + + } + public function user(Request $request){ if ($request->ajax()) { diff --git a/app/Http/Controllers/Dashboard/MediaMonitoringController.php b/app/Http/Controllers/Dashboard/MediaMonitoringController.php new file mode 100644 index 0000000..329b3cb --- /dev/null +++ b/app/Http/Controllers/Dashboard/MediaMonitoringController.php @@ -0,0 +1,110 @@ + 'Monitoring Media' + ]); + } + + public function create(){ + return view('dashboard.media-monitorings.create', [ + 'title' => 'Tambah Monitoring Media' + ]); + } + + public function store(MediaMonitoringRequest $request){ + $validatedData = $request->validated(); + $validatedData['enhancer_id'] = Auth::id(); + + $latestCode = MediaMonitoring::max('code'); + $lastNumber = $latestCode ? intval(substr($latestCode, 3)) : 0; + $newNumber = str_pad($lastNumber + 1, 6, '0', STR_PAD_LEFT); + $code = 'ADN'.$newNumber; + + $validatedData['code'] = $code; + $validatedData['image'] = store_file($validatedData['image'], 'uploads/media-monitorings', 'public')['randomFileName']; + + $createMediaMonitoring = MediaMonitoring::create($validatedData); + + if($createMediaMonitoring){ + return redirect()->back()->with('success-status', 'Berhasil menambahkan monitoring media.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal menambahkan monitoring media.'); + } + } + + public function edit($id){ + + $mediaMonitoring = MediaMonitoring::findOrFail(decrypt_id($id)); + + return view('dashboard.media-monitorings.edit', [ + 'title' => 'Ubah Monitoring Media', + 'mediaMonitoring' => $mediaMonitoring + ]); + } + + public function update(MediaMonitoringRequest $request, $id){ + $validatedData = $request->validated(); + + $mediaMonitoring = MediaMonitoring::findOrFail(decrypt_id($id)); + $validatedData['enhancer_id'] = Auth::id(); + $validatedData['code'] = $mediaMonitoring->code; + + if($request->has('image')){ + delete_file('app/public/uploads/media-monitorings/'.$mediaMonitoring->image); + $validatedData['image'] = store_file($validatedData['image'], '/uploads/media-monitorings', 'public')['randomFileName']; + }else{ + $validatedData['image'] = $mediaMonitoring->image; + } + + $updatedMediaMonitoring = $mediaMonitoring->update($validatedData); + + if($updatedMediaMonitoring){ + return redirect()->back()->with('success-status', 'Berhasil mengubah monitoring media.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal mengubah monitoring media.'); + } + } + + public function show($id){ + + $mediaMonitoring = MediaMonitoring::findOrFail(decrypt_id($id)); + + return view('dashboard.media-monitorings.show', [ + 'title' => 'Detail Monitoring Media', + 'mediaMonitoring' => $mediaMonitoring + ]); + } + + public function destroy($id){ + try { + $mediaMonitoring = MediaMonitoring::findOrFail(decrypt_id($id)); + delete_file('app/public/uploads/media-monitorings/'.$mediaMonitoring->image); + $mediaMonitoring->delete(); + + + return response()->json(['message' => 'Berhasil menghapus monitoring media.']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus monitoring media.'], 500); + } + } + + public function checkLink(Request $request) + { + $linkExists = MediaMonitoring::where('link', $request->link)->exists(); + + return response()->json([ + 'exists' => $linkExists + ]); + } +} diff --git a/app/Http/Requests/MediaMonitoringRequest.php b/app/Http/Requests/MediaMonitoringRequest.php new file mode 100644 index 0000000..d938747 --- /dev/null +++ b/app/Http/Requests/MediaMonitoringRequest.php @@ -0,0 +1,84 @@ +|string> + */ + public function rules(): array + { + $rules = [ + 'media_name' => ['required', 'max:100'], + 'theme' => ['required', 'max:100'], + 'title' => ['required'], + 'link' => ['nullable', 'url'], + 'writter' => ['required'], + 'channel'=> ['required', 'in:website,tiktok,youtube,instagram,facebook,twitter,cetak'], + 'content' => ['required'], + 'influencer' => ['nullable'], + 'keyword' => ['required'], + 'quote' => ['nullable'], + 'release_date' => ['required', 'date'], + ]; + + if($this->isMethod('post')){ + $rules['image'] = ['required', 'image', 'mimes:png,jpg,jpeg', 'max:2048']; + }else if($this->isMethod('put')){ + $rules['image'] = ['nullable', 'image', 'mimes:png,jpg,jpeg', 'max:2048']; + } + + return $rules; + } + + public function messages() +{ + return [ + 'media_name.required' => 'Nama media wajib diisi.', + 'media_name.max' => 'Nama media tidak boleh lebih dari 100 karakter.', + + 'theme.required' => 'Tema wajib diisi.', + 'theme.max' => 'Tema tidak boleh lebih dari 100 karakter.', + + 'title.required' => 'Judul wajib diisi.', + + 'link.url' => 'Link harus dalam format URL yang valid.', + + 'writter.required' => 'Nama penulis wajib diisi.', + + 'channel.required' => 'Channel wajib dipilih.', + 'channel.in' => 'Channel yang dipilih tidak valid.', + + 'content.required' => 'Konten wajib diisi.', + + 'influencer.nullable' => 'Nama influencer boleh dikosongkan.', + + 'keyword.required' => 'Keyword wajib diisi.', + + 'quote.nullable' => 'Quote boleh dikosongkan.', + + 'release_date.required' => 'Tanggal rilis wajib diisi.', + 'release_date.date' => 'Tanggal rilis harus dalam format tanggal yang valid.', + + 'image.required' => 'Gambar wajib diunggah.', + 'image.image' => 'File yang diunggah harus berupa gambar.', + 'image.mimes' => 'Gambar hanya boleh berformat PNG, JPG, atau JPEG.', + 'image.max' => 'Gambar tidak boleh lebih dari 2MB.', + ]; +} + +} diff --git a/app/Models/MediaMonitoring.php b/app/Models/MediaMonitoring.php new file mode 100644 index 0000000..6081747 --- /dev/null +++ b/app/Models/MediaMonitoring.php @@ -0,0 +1,34 @@ +belongsTo(User::class, 'enhancer_id', 'id'); + } + +} diff --git a/database/migrations/2025_02_28_134617_create_media_monitorings_table.php b/database/migrations/2025_02_28_134617_create_media_monitorings_table.php new file mode 100644 index 0000000..9200692 --- /dev/null +++ b/database/migrations/2025_02_28_134617_create_media_monitorings_table.php @@ -0,0 +1,43 @@ +id(); + $table->string('code'); + $table->string('media_name'); + $table->string('theme'); + $table->text('title'); + $table->string('channel'); + $table->string('writter'); + $table->string('link')->nullable(); + $table->string('news_page')->nullable(); + $table->text('quote')->nullable(); + $table->text('content'); + $table->string('influencer')->nullable(); + $table->string('keyword'); + $table->string('image'); + $table->date('release_date'); + $table->unsignedBigInteger('enhancer_id'); + $table->foreign('enhancer_id')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('media_monitorings'); + } +}; diff --git a/database/seeders/MediaMonitoringSeeder.php b/database/seeders/MediaMonitoringSeeder.php new file mode 100644 index 0000000..b849879 --- /dev/null +++ b/database/seeders/MediaMonitoringSeeder.php @@ -0,0 +1,17 @@ +]/.test(password); // Memeriksa simbol +// // Regex untuk memeriksa kriteria kata sandi +// var hasUpper = /[A-Z]/.test(password); // Memeriksa huruf besar +// var hasLower = /[a-z]/.test(password); // Memeriksa huruf kecil +// var hasNumber = /\d/.test(password); // Memeriksa angka +// var hasSymbol = /[!@#$%^&*(),.?":{}|<>]/.test(password); // Memeriksa simbol - // Cek apakah kata sandi memenuhi semua kriteria - if (hasUpper && hasLower && hasNumber && hasSymbol) { - strengthStatus.textContent = 'Kata sandi valid'; - colorClass = 'valid'; // Jika valid, set warna hijau - } else { - strengthStatus.textContent = 'Kata sandi tidak memenuhi syarat'; - colorClass = 'invalid'; // Jika tidak memenuhi syarat, set warna merah - } +// // Cek apakah kata sandi memenuhi semua kriteria +// if (hasUpper && hasLower && hasNumber && hasSymbol) { +// strengthStatus.textContent = 'Kata sandi valid'; +// colorClass = 'valid'; // Jika valid, set warna hijau +// } else { +// strengthStatus.textContent = 'Kata sandi tidak memenuhi syarat'; +// colorClass = 'invalid'; // Jika tidak memenuhi syarat, set warna merah +// } - // Ubah warna input dan border sesuai dengan status - this.classList.remove("invalid", "valid"); - this.classList.add(colorClass); +// // Ubah warna input dan border sesuai dengan status +// this.classList.remove("invalid", "valid"); +// this.classList.add(colorClass); - // Set warna indikator kekuatan - strengthStatus.className = colorClass; +// // Set warna indikator kekuatan +// strengthStatus.className = colorClass; +// }); + +$(document).ready(function() { + // Setup CSRF token untuk semua AJAX request + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }); + + let typingTimer; + let delay = 500; + + $('#link').on('keyup', function() { + clearTimeout(typingTimer); + let inputField = $(this); + let linkValue = inputField.val(); + + if (linkValue.length > 0) { + typingTimer = setTimeout(function() { + $.ajax({ + url: '/dashboard/media-monitorings/check-link', // Sesuaikan dengan route yang benar + method: 'POST', + data: { link: linkValue }, // CSRF sudah otomatis ditambahkan + success: function(response) { + console.log('Response:', response); + if (response.exists) { + $('#linkFeedback') + .removeClass('d-none text-success') + .addClass('text-danger') + .text('Link tersebut sudah ada di database!'); + inputField.addClass('is-invalid').removeClass('is-valid'); + } else { + $('#linkFeedback') + .removeClass('d-none text-danger') + .addClass('text-success') + .text('Link tidak ada di database.'); + inputField.addClass('is-valid').removeClass('is-invalid'); + } + }, + error: function(xhr, status, error) { + console.error('AJAX Error:', error); // Debugging + } + }); + }, delay); + } else { + $('#linkFeedback').addClass('d-none'); + inputField.removeClass('is-invalid is-valid'); + } + }); }); + + diff --git a/resources/views/dashboard/media-monitorings/create.blade.php b/resources/views/dashboard/media-monitorings/create.blade.php new file mode 100644 index 0000000..898ec13 --- /dev/null +++ b/resources/views/dashboard/media-monitorings/create.blade.php @@ -0,0 +1,170 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'media_monitorings']) +@include('partials.dashboard.header') + +Basic info, like your name and address, that you use on Nio Platform.
+