feat: add visibility toggles for content showcase items on public and PDF views

This commit is contained in:
I-Fun
2026-04-06 08:29:47 +07:00
parent 1c73279e52
commit a72eec3ead
4 changed files with 76 additions and 45 deletions

View File

@@ -131,6 +131,8 @@ class RateCardController extends Controller
'content_showcase.*.name' => 'required_with:content_showcase|string|max:255',
'content_showcase.*.url' => 'nullable|url',
'content_showcase.*.thumbnail_path' => 'nullable|string',
'content_showcase.*.show_on_public' => 'nullable',
'content_showcase.*.show_on_pdf' => 'nullable',
]);
$profile = RateCardProfile::getSingleton();
@@ -141,7 +143,12 @@ class RateCardController extends Controller
}
$validated['show_prices'] = $request->has('show_prices');
$validated['content_showcase'] = $request->input('content_showcase', []);
$contentShowcase = $request->input('content_showcase', []);
foreach ($contentShowcase as &$item) {
$item['show_on_public'] = filter_var($item['show_on_public'] ?? true, FILTER_VALIDATE_BOOLEAN);
$item['show_on_pdf'] = filter_var($item['show_on_pdf'] ?? true, FILTER_VALIDATE_BOOLEAN);
}
$validated['content_showcase'] = $contentShowcase;
unset($validated['logo']);
$profile->update($validated);

View File

@@ -299,12 +299,17 @@
</div>
@endif
@if(!empty($profile->content_showcase))
@php
$pdfShowcase = array_filter($profile->content_showcase ?? [], function($item) {
return !isset($item['show_on_pdf']) || $item['show_on_pdf'];
});
@endphp
@if(!empty($pdfShowcase))
<div style="page-break-before: always;"></div>
<div class="platform-section" style="margin-top:20px; page-break-inside:avoid;">
<div class="platform-title" style="text-align:center;">Content Showcase</div>
<div style="text-align:center; padding-top:10px;">
@foreach($profile->content_showcase as $item)
@foreach($pdfShowcase as $item)
@php
$isUrl = ($item['file_id'] === 'url');
$file = !$isUrl ? \App\Models\MediaFile::find($item['file_id']) : null;

View File

@@ -361,9 +361,9 @@
<h2 class="font-bold text-gray-700">Content Showcase</h2>
</div>
<div class="p-5" x-data="{
items: {{ Illuminate\Support\Js::from(old('content_showcase', $profile->content_showcase ?? [])) }}.map(i => ({ file_id: i.file_id || '', name: i.name || '', url: i.url || '', thumbnail_path: i.thumbnail_path || '', uploading: false })),
items: {{ Illuminate\Support\Js::from(old('content_showcase', $profile->content_showcase ?? [])) }}.map(i => ({ file_id: i.file_id || '', name: i.name || '', url: i.url || '', thumbnail_path: i.thumbnail_path || '', show_on_public: i.show_on_public ?? true, show_on_pdf: i.show_on_pdf ?? true, uploading: false })),
addItem() {
this.items.push({ file_id: '', name: '', url: '', thumbnail_path: '', uploading: false });
this.items.push({ file_id: '', name: '', url: '', thumbnail_path: '', show_on_public: true, show_on_pdf: true, uploading: false });
},
removeItem(index) {
this.items.splice(index, 1);
@@ -421,48 +421,62 @@
</div>
<template x-if="item.file_id">
<div class="w-full border-t border-pink-100 pt-3 flex flex-wrap gap-3 items-center">
<div class="shrink-0 flex items-center justify-center">
<input type="hidden" :name="'content_showcase['+index+'][thumbnail_path]'"
x-model="item.thumbnail_path">
<template x-if="item.thumbnail_path">
<div class="relative rounded-xl border border-pink-100 p-1 flex items-center justify-center bg-white group shrink-0"
style="width: 54px; height: 54px;">
<img :src="'/storage/' + item.thumbnail_path"
class="max-w-full max-h-full object-contain rounded">
<button type="button" @click="item.thumbnail_path = ''"
class="absolute -top-2 -right-2 bg-red-100 text-red-500 rounded-full w-5 h-5 flex items-center justify-center hover:bg-red-200 shadow text-[9px] z-10 transition-colors">🗑️</button>
<div class="w-full">
<div class="w-full border-t border-pink-100 pt-3 flex flex-wrap gap-3 items-center">
<div class="shrink-0 flex items-center justify-center">
<input type="hidden" :name="'content_showcase['+index+'][thumbnail_path]'"
x-model="item.thumbnail_path">
<template x-if="item.thumbnail_path">
<div class="relative rounded-xl border border-pink-100 p-1 flex items-center justify-center bg-white group shrink-0"
style="width: 54px; height: 54px;">
<img :src="'/storage/' + item.thumbnail_path"
class="max-w-full max-h-full object-contain rounded">
<button type="button" @click="item.thumbnail_path = ''"
class="absolute -top-2 -right-2 bg-red-100 text-red-500 rounded-full w-5 h-5 flex items-center justify-center hover:bg-red-200 shadow text-[9px] z-10 transition-colors">🗑️</button>
</div>
</template>
<template x-if="!item.thumbnail_path">
<label
class="rounded-xl border-2 border-dashed border-pink-200 flex items-center justify-center text-pink-300 hover:bg-pink-50 hover:text-pink-400 cursor-pointer transition-colors shrink-0"
style="width: 54px; height: 54px;"
:class="{'opacity-50 pointer-events-none': item.uploading}"
title="Upload Thumbnail (Optional)">
<span x-show="!item.uploading"
class="text-xl font-light leading-none mb-1">+</span>
<span x-show="item.uploading" class="text-[10px]">...</span>
<input type="file" accept="image/*" class="hidden"
@change="uploadThumb($event.target, item)">
</label>
</template>
</div>
<template x-if="item.file_id === 'url'">
<div class="flex-1 min-w-[200px]">
<input type="url" :name="'content_showcase['+index+'][url]'" x-model="item.url"
class="input-soft w-full py-2 px-3 text-xs"
placeholder="URL (https://instagram.com/p/...)" required>
</div>
</template>
<template x-if="!item.thumbnail_path">
<label
class="rounded-xl border-2 border-dashed border-pink-200 flex items-center justify-center text-pink-300 hover:bg-pink-50 hover:text-pink-400 cursor-pointer transition-colors shrink-0"
style="width: 54px; height: 54px;"
:class="{'opacity-50 pointer-events-none': item.uploading}"
title="Upload Thumbnail (Optional)">
<span x-show="!item.uploading"
class="text-xl font-light leading-none mb-1">+</span>
<span x-show="item.uploading" class="text-[10px]">...</span>
<input type="file" accept="image/*" class="hidden"
@change="uploadThumb($event.target, item)">
</label>
<template x-if="item.file_id !== 'url'">
<div class="flex-1 text-xs text-gray-400">
Uploaded Thumbnail: Use this to override the default display icon for videos and documents.
</div>
</template>
</div>
<template x-if="item.file_id === 'url'">
<div class="flex-1 min-w-[200px]">
<input type="url" :name="'content_showcase['+index+'][url]'" x-model="item.url"
class="input-soft w-full py-2 px-3 text-xs"
placeholder="URL (https://instagram.com/p/...)" required>
</div>
</template>
<template x-if="item.file_id !== 'url'">
<div class="flex-1 text-xs text-gray-400">
Uploaded Thumbnail: Use this to override the default display icon for videos and documents.
</div>
</template>
<div class="w-full border-t border-pink-100 pt-3 flex flex-wrap gap-4 items-center mt-2">
<label class="flex items-center gap-2 cursor-pointer text-[11px] font-semibold text-gray-600">
<input type="hidden" :name="'content_showcase['+index+'][show_on_public]'" value="0">
<input type="checkbox" :name="'content_showcase['+index+'][show_on_public]'" value="1" x-model="item.show_on_public" class="w-4 h-4 accent-pink-400 rounded cursor-pointer shrink-0">
Show on Public Page
</label>
<label class="flex items-center gap-2 cursor-pointer text-[11px] font-semibold text-gray-600">
<input type="hidden" :name="'content_showcase['+index+'][show_on_pdf]'" value="0">
<input type="checkbox" :name="'content_showcase['+index+'][show_on_pdf]'" value="1" x-model="item.show_on_pdf" class="w-4 h-4 accent-pink-400 rounded cursor-pointer shrink-0">
Show on PDF
</label>
</div>
</div>
</template>
</div>

View File

@@ -329,11 +329,16 @@
</div>
@endif
@if(!empty($profile->content_showcase))
@php
$publicShowcase = array_filter($profile->content_showcase ?? [], function($item) {
return !isset($item['show_on_public']) || $item['show_on_public'];
});
@endphp
@if(!empty($publicShowcase))
<div class="platform-section" style="margin-top:40px;">
<div class="platform-title" style="justify-content:center;">Content Showcase</div>
<div class="cards">
@foreach($profile->content_showcase as $item)
@foreach($publicShowcase as $item)
@php
$isUrl = ($item['file_id'] === 'url');
$file = !$isUrl ? \App\Models\MediaFile::find($item['file_id']) : null;