diff --git a/app/Http/Controllers/Frontdesk/IssueReportController.php b/app/Http/Controllers/Frontdesk/IssueReportController.php new file mode 100644 index 0000000..30c88a3 --- /dev/null +++ b/app/Http/Controllers/Frontdesk/IssueReportController.php @@ -0,0 +1,70 @@ +user()), 403); + + return view('frontdesk.issues.create'); + } + + public function store(Request $request, IdentityTeamClient $identity): RedirectResponse + { + abort_unless(! StaffUx::showBilling($request->user()), 403); + + $validated = $request->validate([ + 'subject' => ['required', 'string', 'max:255'], + 'message' => ['required', 'string', 'max:5000'], + 'priority' => ['required', 'in:low,normal,high'], + ]); + + $user = $request->user(); + $organization = $this->organization($request); + $member = $this->member($request); + + $context = trim(implode("\n", array_filter([ + 'App: Ladill Frontdesk', + 'Organization: '.($organization->name ?? '—'), + 'Role: '.($member?->role ?? '—'), + 'Reporter: '.($user->email ?? $user->ownerRef()), + '', + $validated['message'], + ]))); + + try { + $ticket = $identity->createSupportTicket($user->ownerRef(), [ + 'subject' => $validated['subject'], + 'message' => $context, + 'priority' => $validated['priority'], + 'tags' => ['staff_issue', 'app:frontdesk'], + ], 'frontdesk'); + } catch (\Throwable $e) { + report($e); + + return back() + ->withInput() + ->with('error', 'Could not send your report right now. Please try again in a moment.'); + } + + $ref = (string) ($ticket['ticket_ref'] ?? ''); + + return redirect() + ->route('frontdesk.dashboard') + ->with('success', $ref !== '' + ? "Issue reported to Ladill support ({$ref}). Our team will follow up." + : 'Issue reported to Ladill support. Our team will follow up.'); + } +} diff --git a/app/Services/Identity/IdentityTeamClient.php b/app/Services/Identity/IdentityTeamClient.php index fbb3e2a..f8a9e63 100644 --- a/app/Services/Identity/IdentityTeamClient.php +++ b/app/Services/Identity/IdentityTeamClient.php @@ -78,6 +78,24 @@ class IdentityTeamClient return (array) $response->json('data', []); } + /** + * @param array{subject: string, message: string, priority?: string, tags?: list} $payload + * @return array + */ + public function createSupportTicket(string $userPublicId, array $payload, string $app = 'frontdesk'): array + { + $response = $this->request('post', '/identity/support/tickets', array_filter([ + 'user' => $userPublicId, + 'subject' => $payload['subject'] ?? '', + 'message' => $payload['message'] ?? '', + 'priority' => $payload['priority'] ?? 'normal', + 'app' => $app, + 'tags' => $payload['tags'] ?? ['staff_issue'], + ], fn ($value) => $value !== null && $value !== '')); + + return (array) $response->json('data', []); + } + private function request(string $method, string $path, array $query = []): Response { $url = rtrim((string) config('identity.api_url'), '/').$path; diff --git a/resources/views/frontdesk/issues/create.blade.php b/resources/views/frontdesk/issues/create.blade.php new file mode 100644 index 0000000..a2e9214 --- /dev/null +++ b/resources/views/frontdesk/issues/create.blade.php @@ -0,0 +1,43 @@ + +
+
+

Report an issue

+

Send a problem to Ladill support. Account owners manage billing upgrades — staff use this for help with Frontdesk.

+
+ + @if (session('error')) +

{{ session('error') }}

+ @endif + +
+ @csrf + +
+ + + @error('subject')

{{ $message }}

@enderror +
+ +
+ + +
+ +
+ + + @error('message')

{{ $message }}

@enderror +
+ + +
+
+
diff --git a/resources/views/partials/sidebar.blade.php b/resources/views/partials/sidebar.blade.php index 291f1da..b5d5dd0 100644 --- a/resources/views/partials/sidebar.blade.php +++ b/resources/views/partials/sidebar.blade.php @@ -146,16 +146,27 @@ Settings - @php $proActive = request()->routeIs('frontdesk.pro.*'); @endphp - @if (! empty($hasPaidPlan) || ! empty($isEnterprise)) - - - {{ ! empty($isEnterprise) ? 'Frontdesk Enterprise' : 'Frontdesk Pro' }} - + @php + $proActive = request()->routeIs('frontdesk.pro.*'); + $issueActive = request()->routeIs('frontdesk.issues.*'); + $isAccountOwner = \App\Support\StaffUx::showBilling(auth()->user()); + @endphp + @if ($isAccountOwner) + @if (! empty($hasPaidPlan) || ! empty($isEnterprise)) + + + {{ ! empty($isEnterprise) ? 'Frontdesk Enterprise' : 'Frontdesk Pro' }} + + @else + + + Upgrade to Pro + + @endif @else - - - Upgrade to Pro + + + Report Issue @endif diff --git a/routes/web.php b/routes/web.php index a738923..0199c72 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,6 +14,7 @@ use App\Http\Controllers\Frontdesk\EmployeePortalController; use App\Http\Controllers\Frontdesk\HostController; use App\Http\Controllers\Frontdesk\HostPortalController; use App\Http\Controllers\Frontdesk\IntegrationController; +use App\Http\Controllers\Frontdesk\IssueReportController; use App\Http\Controllers\Frontdesk\KioskController; use App\Http\Controllers\Frontdesk\KioskDeviceController; use App\Http\Controllers\Frontdesk\MemberController; @@ -180,6 +181,9 @@ Route::middleware(['auth', 'platform.session'])->group(function () { Route::post('/pro/subscribe-prepaid', [ProController::class, 'subscribePrepaid'])->name('frontdesk.pro.subscribe-prepaid'); Route::get('/pro/paystack/callback', [ProController::class, 'paystackCallback'])->name('frontdesk.pro.paystack.callback'); + Route::get('/report-issue', [IssueReportController::class, 'create'])->name('frontdesk.issues.create'); + Route::post('/report-issue', [IssueReportController::class, 'store'])->name('frontdesk.issues.store'); + Route::get('/settings', [SettingsController::class, 'edit'])->name('frontdesk.settings'); Route::put('/settings', [SettingsController::class, 'update'])->name('frontdesk.settings.update'); Route::post('/settings/upgrade', [ProController::class, 'subscribe'])->name('frontdesk.settings.upgrade');