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:500', 'show_prices' => 'boolean', '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->boolean('show_prices'); unset($validated['logo']); $profile->update($validated); return back()->with('success', '🎨 Profile updated!'); } 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', 'portrait'); $filename = 'rate-card-' . now()->format('Y-m-d') . '.pdf'; return $pdf->download($filename); } }