Files
Kol-Manager/app/Http/Controllers/RateCardController.php

241 lines
8.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\RateCard;
use App\Models\RateCardProfile;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
class RateCardController extends Controller
{
public function index(): View
{
$rateCards = RateCard::orderBy('sort_order')->orderBy('platform')->get();
$profile = RateCardProfile::getSingleton();
return view('rate-cards.index', compact('rateCards', 'profile'));
}
public function create(): View
{
return view('rate-cards.create');
}
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'service_name' => 'required|string|max:255',
'description' => 'nullable|string',
'platform' => 'required|in:instagram,tiktok,youtube,general',
'content_type' => 'nullable|string|max:50',
'price' => 'required|numeric|min:0',
'currency' => 'required|string|max:10',
'price_unit' => 'required|in:per_content,per_month,per_campaign',
'is_negotiable' => 'boolean',
'sort_order' => 'nullable|integer',
]);
$validated['is_negotiable'] = $request->boolean('is_negotiable');
$validated['is_active'] = true;
RateCard::create($validated);
return redirect()->route('rate-cards.index')
->with('success', '💰 Rate card entry added!');
}
public function edit(RateCard $rateCard): View
{
return view('rate-cards.edit', compact('rateCard'));
}
public function update(Request $request, RateCard $rateCard): RedirectResponse
{
$validated = $request->validate([
'service_name' => 'required|string|max:255',
'description' => 'nullable|string',
'platform' => 'required|in:instagram,tiktok,youtube,general',
'content_type' => 'nullable|string|max:50',
'price' => 'required|numeric|min:0',
'currency' => 'required|string|max:10',
'price_unit' => 'required|in:per_content,per_month,per_campaign',
'is_negotiable' => 'boolean',
'is_active' => 'boolean',
'sort_order' => 'nullable|integer',
]);
$validated['is_negotiable'] = $request->boolean('is_negotiable');
$validated['is_active'] = $request->boolean('is_active');
$rateCard->update($validated);
return redirect()->route('rate-cards.index')
->with('success', '💰 Rate card updated!');
}
public function destroy(RateCard $rateCard): RedirectResponse
{
$rateCard->delete();
return redirect()->route('rate-cards.index')->with('success', 'Entry removed.');
}
// ── Public Page ──────────────────────────────────────────────
public function public(): View
{
$profile = RateCardProfile::getSingleton();
$rateCards = RateCard::where('is_active', true)
->orderBy('sort_order')
->orderBy('platform')
->get()
->groupBy('platform');
return view('rate-cards.public', compact('rateCards', 'profile'));
}
// ── Profile Settings ─────────────────────────────────────────
public function profilePage(): View
{
$profile = RateCardProfile::getSingleton();
return view('rate-cards.profile', compact('profile'));
}
public function profileUpdate(Request $request): RedirectResponse
{
$validated = $request->validate([
'owner_name' => 'required|string|max:100',
'tagline' => 'nullable|string|max:200',
'whatsapp' => 'nullable|string|max:30',
'ig_handle' => 'nullable|string|max:60',
'tiktok_handle' => 'nullable|string|max:60',
'youtube_handle'=> 'nullable|string|max:60',
'email' => 'nullable|email|max:150',
'bg_color' => 'nullable|string|max:20',
'accent_color' => 'nullable|string|max:20',
'text_color' => 'nullable|string|max:20',
'custom_footer' => 'nullable|string|max:255',
'show_prices' => 'nullable|boolean',
'terms_and_conditions' => 'nullable|string',
'brand_logo_size' => 'nullable|in:small,medium,large',
'contact_person_html' => 'nullable|string',
'logo' => 'nullable|image|max:2048',
]);
$profile = RateCardProfile::getSingleton();
if ($request->hasFile('logo')) {
$path = $request->file('logo')->store('profile', 'private');
$validated['logo_path'] = $path;
}
$validated['show_prices'] = $request->has('show_prices');
unset($validated['logo']);
$profile->update($validated);
return back()->with('success', '🎨 Profile updated!');
}
public function uploadLogo(Request $request)
{
$request->validate([
'logo' => 'required|image|max:2048',
]);
$profile = RateCardProfile::getSingleton();
if ($profile->logo_path) {
\Storage::disk('private')->delete($profile->logo_path);
}
$path = $request->file('logo')->store('profile', 'private');
$profile->update(['logo_path' => $path]);
return response()->json([
'url' => route('files.serve-profile-logo'),
]);
}
public function deleteLogo()
{
$profile = RateCardProfile::getSingleton();
if ($profile->logo_path) {
\Storage::disk('private')->delete($profile->logo_path);
$profile->update(['logo_path' => null]);
}
return response()->json(['success' => true]);
}
public function uploadBrandLogo(Request $request)
{
$request->validate(['logo' => 'required|image|max:2048']);
$profile = RateCardProfile::getSingleton();
$path = $request->file('logo')->store('brands', 'public');
$brands = $profile->past_brands ?? [];
$brands[] = $path;
$profile->update(['past_brands' => $brands]);
return response()->json([
'path' => $path,
'url' => asset('storage/' . $path)
]);
}
public function deleteBrandLogo(Request $request)
{
$path = $request->input('path');
$profile = RateCardProfile::getSingleton();
$brands = $profile->past_brands ?? [];
if (($key = array_search($path, $brands)) !== false) {
unset($brands[$key]);
$profile->update(['past_brands' => array_values($brands)]);
Storage::disk('public')->delete($path);
}
return response()->json(['success' => true]);
}
public function serveProfileLogo(): Response
{
$profile = RateCardProfile::getSingleton();
if (! $profile->logo_path || ! \Storage::disk('private')->exists($profile->logo_path)) {
abort(404);
}
$contents = \Storage::disk('private')->get($profile->logo_path);
$mime = \Storage::disk('private')->mimeType($profile->logo_path);
return response($contents, 200)->header('Content-Type', $mime);
}
// ── PDF Download ─────────────────────────────────────────────
public function pdf(): \Illuminate\Http\Response
{
$profile = RateCardProfile::getSingleton();
$rateCards = RateCard::where('is_active', true)
->orderBy('sort_order')
->orderBy('platform')
->get()
->groupBy('platform');
$pdf = Pdf::loadView('rate-cards.pdf', compact('rateCards', 'profile'))
->setPaper('a4', 'landscape');
$filename = 'rate-card-' . now()->format('Y-m-d') . '.pdf';
return $pdf->download($filename);
}
}