Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions app/Http/Controllers/FrontEnd/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
use App\Models\Event;
use App\Models\Kategori;
use App\Models\Survei;
use App\Models\TipePotensi;
use App\Services\DesaService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
Expand Down Expand Up @@ -140,12 +141,23 @@ public function filterFeeds(Request $request): JsonResponse
return response()->json(compact('html'));
}

public function PotensiByKategory(string $slug): View
public function PotensiIndex(): View
{
$page_title = 'Potensi';
$page_description = 'Potensi-Potensi';
$page_description = 'Potensi-Potensi Kecamatan';
$kategori_potensi = TipePotensi::all();

return view('pages.potensi.index', compact(['page_title', 'page_description', 'kategori_potensi']));
}

public function PotensiByKategory(string $slug): View
{
$kategori = TipePotensi::where('slug', $slug)->first();
$page_title = 'Potensi' . ($kategori ? ' - ' . $kategori->nama_kategori : '');
$page_description = 'Potensi-Potensi Kecamatan' . ($kategori ? ' Kategori ' . $kategori->nama_kategori : '');
$kategori_potensi = TipePotensi::all();

return view('pages.potensi.index', compact(['page_title', 'page_description', 'slug']));
return view('pages.potensi.index', compact(['page_title', 'page_description', 'slug', 'kategori', 'kategori_potensi']));
}

public function PotensiShow(string $kategori, string $id): View
Expand Down
14 changes: 10 additions & 4 deletions app/Http/Controllers/Setting/NavMenuController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@

use App\Http\Controllers\Controller;
use App\Models\Artikel;
use App\Models\JenisDokumen;
use App\Models\Kategori;
use App\Models\NavMenu;
use App\Models\JenisDokumen;
use App\Models\TipePotensi;
use Illuminate\Http\Request;

class NavMenuController extends Controller
{

public function index()
{
$page_title = 'Pengaturan Menu';
Expand All @@ -65,12 +65,17 @@ public function index()
),
'Kategori' => Kategori::cursor()->pluck('nama', 'link')->toArray(),
'Dokumen' => JenisDokumen::cursor()->pluck('nama', 'link')->toArray(),
'Potensi' => array_merge(
['/potensi' => 'Semua Potensi'],
TipePotensi::cursor()->mapWithKeys(function ($item) {
return ['/potensi/' . $item->slug => $item->nama_kategori];
})->toArray()
),
];

return view('setting.nav_menu.index', compact('page_title', 'page_description', 'nav_menus', 'sourceItem'));
}


public function store(Request $request)
{
NavMenu::whereNotNull('id')->delete();
Expand All @@ -90,11 +95,12 @@ private function loopTree(array $elements, $parentId = null)
{
$sequence = 1;
foreach ($elements as $element) {
$type = strtolower($element['type'] ?? '');
$input = [
'name' => $element['text'],
'url' => $element['href'],
'target' => $element['target'],
'type' => $element['type'],
'type' => in_array($type, ['link', 'halaman', 'kategori', 'modul', 'dokumen']) ? $type : 'modul',
'is_show' => isset($element['is_show']) ? $element['is_show'] : 1,
'order' => $sequence,
'parent_id' => $parentId,
Expand Down
1 change: 1 addition & 0 deletions catatan_rilis.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Terimakasih [isi disini] yang telah berkontribusi langsung mengembangkan aplikas
12. [#1737](https://github.com/OpenSID/OpenDK/issues/1737) fungsi kirim pesan error 500.
13. [#1761](https://github.com/OpenSID/OpenDK/issues/1761)Perbaikan validasi valid_file menolak PDF sah karena string generik "function".
14. [#1764](https://github.com/OpenSID/OpenDK/issues/1764) Gagal Menampilkan data foto/video dari link pada web dan admin.
15. [#1767](https://github.com/OpenSID/OpenDK/issues/1767)Perbaikan menu potensi pada halaman publik tidak berfungsi.

#### TEKNIS

Expand Down
40 changes: 40 additions & 0 deletions database/migrations/2026_09_30_080000_fix_potensi_nav_menu.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

use App\Models\NavMenu;
use App\Services\CacheService;
use Illuminate\Database\Migrations\Migration;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
NavMenu::where('name', 'Potensi')
->where('url', '#')
->update([
'url' => '/potensi',
'target' => '_self',
'type' => 'modul',
]);

try {
app(CacheService::class)->removeCachePrefix(config('theme-api.website.cache_prefix', 'website:api'));
} catch (\Throwable $e) {
// Abaikan jika cache service belum siap
}
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// Tidak perlu direverse karena perbaikan data
}
};
4 changes: 2 additions & 2 deletions database/seeders/DasNavigationTableSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public function run()
[
'name' => 'Potensi',
'slug' => Str::slug('Potensi'),
'type' => MenuTipe::EKSTERNAL,
'url' => '#',
'type' => MenuTipe::POTENSI,
'url' => 'potensi',
'order' => 4,
'status' => 1,
],
Expand Down
4 changes: 4 additions & 0 deletions resources/views/setting/nav_menu/field.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<label class="form-check-inline">
{!! html()->radio('source', false)->value('Dokumen')->class('form-check-input')->id('sourceDokumen') !!} Dokumen
</label>
<label class="form-check-inline">
{!! html()->radio('source', false)->value('Potensi')->class('form-check-input')->id('sourcePotensi') !!} Potensi
</label>
</div>
</div>

Expand Down Expand Up @@ -63,6 +66,7 @@
case 'Kategori':
case 'Halaman':
case 'Dokumen':
case 'Potensi':
let select = document.querySelector('select[name=sourcelist]');
select.style.display = 'block'; // Tampilkan select sourcelist

Expand Down
2 changes: 2 additions & 0 deletions resources/views/setting/nav_menu/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,15 @@
let sourceKategori = $('#sourceKategori');
let sourceModul = $('#sourceModul');
let sourceDokumen = $('#sourceDokumen');
let sourcePotensi = $('#sourcePotensi');

let source = '';
if (sourceLink.is(':checked')) source = sourceLink.val();
else if (sourceHalaman.is(':checked')) source = sourceHalaman.val();
else if (sourceKategori.is(':checked')) source = sourceKategori.val();
else if (sourceModul.is(':checked')) source = sourceModul.val();
else if (sourceDokumen.is(':checked')) source = sourceDokumen.val();
else if (sourcePotensi.is(':checked')) source = 'modul';

editor.add(source);
});
Expand Down
7 changes: 4 additions & 3 deletions resources/views/setting/navigation/form.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@
@endforeach
</optgroup>
<optgroup label="Potensi">
<option value="4" data-value="potensi" @selected('potensi' == optional($navigation)->url)>Semua Potensi</option>
@foreach (\App\Enums\MenuTipe::getPotensi() as $key => $value)
<option value="3" data-value="{{ 'potensi/' . $key }}" @selected('potensi/' . $key == optional($navigation)->url)>{{ $value }}</option>
<option value="4" data-value="{{ 'potensi/' . $key }}" @selected('potensi/' . $key == optional($navigation)->url)>{{ $value }}</option>
@endforeach
</optgroup>
<optgroup label="Unduhan">
@foreach (\App\Enums\MenuTipe::getUnduhan() as $key => $value)
<option value="4" data-value="{{ 'unduhan/' . $key }}" @selected('unduhan/' . $key == optional($navigation)->url)>{{ $value }}</option>
<option value="5" data-value="{{ 'unduhan/' . $key }}" @selected('unduhan/' . $key == optional($navigation)->url)>{{ $value }}</option>
@endforeach
</optgroup>
<optgroup label="Publikasi">
@foreach (\App\Enums\MenuTipe::getPublikasi() as $key => $value)
<option value="4" data-value="{{ 'publikasi/' . $key }}" @selected('publikasi/' . $key == optional($navigation)->url)>{{ $value }}</option>
<option value="6" data-value="{{ 'publikasi/' . $key }}" @selected('publikasi/' . $key == optional($navigation)->url)>{{ $value }}</option>
@endforeach
</optgroup>
<option value="0" @selected('0' == optional($navigation)->type)>Eksternal</option>
Expand Down
2 changes: 1 addition & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@
});

Route::group(['prefix' => 'potensi'], function () {
Route::permanentRedirect('/', '/');
Route::get('/', 'PageController@PotensiIndex')->name('potensi.index');
Route::get('{slug}', 'PageController@PotensiByKategory')->name('potensi.kategori');
Route::get('{kategori}/{id}', 'PageController@PotensiShow')->name('potensi.kategori.show');
});
Expand Down
73 changes: 73 additions & 0 deletions tests/Feature/Frontend/PotensiPublicTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

use App\Models\NavMenu;
use App\Models\Potensi;
use App\Models\TipePotensi;
use Illuminate\Support\Facades\Cache;

beforeEach(function () {
Cache::flush();
$this->tipePotensi = TipePotensi::firstOrCreate(
['slug' => 'pariwisata'],
['nama_kategori' => 'Pariwisata']
);

$this->potensi = Potensi::firstOrCreate(
['nama_potensi' => 'Air Terjun Indah'],
[
'kategori_id' => $this->tipePotensi->id,
'deskripsi' => 'Deskripsi wisata alam air terjun indah',
'lokasi' => 'Kecamatan Contoh',
'file_gambar' => 'storage/potensi_kecamatan/sample.jpg',
]
);
});

it('displays all potensi page at /potensi successfully', function () {
$response = $this->get('/potensi');

$response->assertOk();
$response->assertViewIs('pages.potensi.index');
$response->assertViewHas('page_title', 'Potensi');
$response->assertViewHas('kategori_potensi');
});

it('displays potensi by category page at /potensi/{slug} successfully', function () {
$response = $this->get('/potensi/' . $this->tipePotensi->slug);

$response->assertOk();
$response->assertViewIs('pages.potensi.index');
$response->assertViewHas('slug', $this->tipePotensi->slug);
$response->assertViewHas('kategori_potensi');
});

it('displays potensi detail page at /potensi/{kategori}/{id} successfully', function () {
$response = $this->get('/potensi/' . $this->tipePotensi->slug . '/' . $this->potensi->id);

$response->assertOk();
$response->assertViewIs('pages.potensi.show');
$response->assertViewHas('id', (string) $this->potensi->id);
});

it('ensures nav_menus table contains /potensi for Potensi menu', function () {
$nav = NavMenu::where('name', 'Potensi')->first();

expect($nav)->not->toBeNull();
expect($nav->url)->toBe('/potensi');
});

it('returns /potensi in the website api navmenus data', function () {
$response = $this->getJson('/api/frontend/v1/website');

$response->assertOk();
$data = $response->json('data');

$navmenusItem = collect($data)->firstWhere('id', 'navmenus');
expect($navmenusItem)->not->toBeNull();

$menus = $navmenusItem['attributes'][0] ?? [];
$potensiMenu = collect($menus)->firstWhere('name', 'Potensi');

expect($potensiMenu)->not->toBeNull();
expect($potensiMenu['url'])->toBe('/potensi');
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
<div class="col-md-8">
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title text-bold"><i id="title-container" class="fa fa-arrow-circle-right fa-lg text-blue"></i> </h3>
<h3 class="box-title text-bold"><i id="title-container" class="fa fa-arrow-circle-right fa-lg text-blue"></i> {{ $page_title ?? 'Potensi' }}</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
@if(isset($kategori_potensi) && $kategori_potensi->count() > 0)
<div style="margin-bottom: 20px;">
<a href="{{ route('potensi.index') }}" class="btn btn-sm {{ empty($slug) ? 'btn-primary' : 'btn-default' }}" style="margin-right: 5px; margin-bottom: 5px;">Semua</a>
@foreach($kategori_potensi as $kat)
<a href="{{ route('potensi.kategori', $kat->slug) }}" class="btn btn-sm {{ ($slug ?? '') === $kat->slug ? 'btn-primary' : 'btn-default' }}" style="margin-right: 5px; margin-bottom: 5px;">{{ $kat->nama_kategori }}</a>
@endforeach
</div>
@endif
<div id="potensi-container">
<div class="post clearfix">
<!-- Loading indicator will be shown here -->
Expand All @@ -26,6 +34,8 @@
@push('scripts')
<script>
$(function(){
var slug = '{!! $slug ?? "" !!}';

function renderPotensi(items) {
if (!items || items.length === 0) {
return '<h4 class="text-center"><span class="fa fa-times"></span> Data tidak ditemukan.</h4>';
Expand All @@ -34,6 +44,8 @@ function renderPotensi(items) {
return items.map(function(item) {
var potensi = item.attributes;
var potensiImage = potensi.file_gambar_path || '{{ asset("/img/no-image.png") }}';
var kategoriSlug = (potensi.tipe && potensi.tipe.slug) ? potensi.tipe.slug : (slug || 'kategori');
var detailUrl = '{{ url("/potensi") }}/' + kategoriSlug + '/' + (item.id || '');

return '<div class="attachment-block clearfix">' +
'<img id="myImg" class="attachment-img responsive" src="' + potensiImage + '" alt="' + (potensi.nama_potensi || '') + '">' +
Expand All @@ -44,11 +56,11 @@ function renderPotensi(items) {
'<div id="caption">' + (potensi.nama_potensi || '') + '</div>' +
'</div>' +
'<div class="attachment-pushed">' +
'<h4 class="attachment-heading"><a href="{{ url("/potensi") }}/' + (potensi.tipe ? potensi.tipe.slug : '') + '/' + (item.id || '') + '"><i class="fa fa-industry" aria-hidden="true"></i> ' + (potensi.nama_potensi || '') + '</a></h4>' +
'<h4 class="attachment-heading"><a href="' + detailUrl + '"><i class="fa fa-industry" aria-hidden="true"></i> ' + (potensi.nama_potensi || '') + '</a></h4>' +
'<div class="attachment-text">' +
(potensi.deskripsi ? (potensi.deskripsi.length > 300 ? potensi.deskripsi.substring(0, 300) + ' ...' : potensi.deskripsi) : '') +
'<div class="pull-right button-group" style="position:relative; bottom:0px; margin-bottom: 0px;">' +
'<a href="{{ url("/potensi") }}/' + (potensi.tipe ? potensi.tipe.slug : '') + '/' + (item.id || '') + '" class="btn btn-xs btn-primary"><i class="fa fa-angle-double-right"></i> Baca Selengkapnya</a>' +
'<a href="' + detailUrl + '" class="btn btn-xs btn-primary"><i class="fa fa-angle-double-right"></i> Baca Selengkapnya</a>' +
'</div>' +
'</div>' +
'</div>' +
Expand All @@ -61,21 +73,31 @@ function loadPotensi(page = 1) {
var $container = $('#potensi-container .post.clearfix');
$container.html(`@include('components.placeholder')`);

var apiUrl = '{!! $urlApi !!}/potensi?include=tipe&page[number]=' + page;
if (slug) {
apiUrl += '&filter[tipe.slug]=' + encodeURIComponent(slug);
}

// Make API call to get potensi
$.ajax({
url: '{!! $urlApi !!}/potensi?filter[tipe.slug]={!! $slug !!}&include=tipe&page[number]=' + page,
url: apiUrl,
method: 'GET',
success: function(response) {
var items = response.data || response;

var html = renderPotensi(items);
$('#title-container').text(items[0].attributes.tipe.nama_kategori)
if (items && items.length > 0 && items[0].attributes && items[0].attributes.tipe && slug) {
$('#title-container').text(items[0].attributes.tipe.nama_kategori);
} else if (slug) {
$('#title-container').text('{{ $page_title ?? "Potensi" }}');
} else {
$('#title-container').text('Semua Potensi');
}
var $container = $('#potensi-container .post.clearfix');

$container.html(html);
initPagination(response, function() {
$('.pagination').on('click', '.btn-page', function() {
var params = {};
var page = $(this).data('page');
loadPotensi(page);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
@section('content')
<div class="col-md-8">
<div class="box box-widget">
<div class="box-header with-border">
<a href="{{ route('potensi.index') }}" class="btn btn-sm btn-default"><i class="fa fa-arrow-left"></i> Kembali ke Daftar Potensi</a>
</div>
<!-- /.box-header -->
<div class="box-body">
<div id="potensi-detail-container">
Expand Down