Sfoglia il codice sorgente

feat: :sparkles: feat (suporte) adicionada opcao de registrar suporte

adicionada funcao do usuario preencher formulario e enviar para suporte com duvidas/ajudas que precisa. Visualizacao e interacao via backoffice

fase:staging | origin:escopo
Gustavo Zanatta 3 settimane fa
parent
commit
ec029b245b

+ 2 - 0
.env.example

@@ -31,6 +31,8 @@ MAIL_ENCRYPTION=null
 MAIL_FROM_ADDRESS="hello@example.com"
 MAIL_FROM_NAME="${APP_NAME}"
 
+SUPPORT_EMAIL="ajuda@diaria.app.br"
+
 VITE_APP_NAME="${APP_NAME}"
 
 FILESYSTEM_DISK=local

+ 15 - 0
app/Enums/SupportRequestCategoryEnum.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace App\Enums;
+
+use App\Traits\EnumHelper;
+
+enum SupportRequestCategoryEnum: string
+{
+    use EnumHelper;
+
+    case PAYMENT   = 'payment';
+    case SCHEDULE  = 'schedule';
+    case ACCOUNT   = 'account';
+    case OTHER     = 'other';
+}

+ 14 - 0
app/Enums/SupportRequestStatusEnum.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Enums;
+
+use App\Traits\EnumHelper;
+
+enum SupportRequestStatusEnum: string
+{
+    use EnumHelper;
+
+    case PENDING     = 'pending';
+    case IN_PROGRESS = 'in_progress';
+    case RESOLVED    = 'resolved';
+}

+ 73 - 0
app/Http/Controllers/SupportRequestController.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Requests\SupportRequestRequest;
+use App\Http\Resources\SupportRequestResource;
+use App\Services\SupportRequestService;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+
+class SupportRequestController extends Controller
+{
+    public function __construct(
+        protected SupportRequestService $service,
+    ) {}
+
+    public function index(Request $request): JsonResponse
+    {
+        $paginated = $this->service->paginate(
+            status:  $request->input('status'),
+            search:  $request->input('filter'),
+            page:    $request->integer('page', 1),
+            perPage: $request->integer('per_page', 10),
+        );
+
+        return $this->successResponse(payload: [
+            'data'  => SupportRequestResource::collection($paginated->items()),
+            'total' => $paginated->total(),
+            'from'  => $paginated->firstItem() ?? 0,
+            'to'    => $paginated->lastItem() ?? 0,
+        ]);
+    }
+
+    public function show(int $id): JsonResponse
+    {
+        $item = $this->service->findById($id);
+
+        if (! $item) {
+            return $this->errorResponse(message: __('messages.not_found'));
+        }
+
+        return $this->successResponse(payload: new SupportRequestResource($item));
+    }
+
+    public function store(SupportRequestRequest $request): JsonResponse
+    {
+        $user = Auth::user();
+
+        $data = array_merge($request->validated(), [
+            'user_id'   => $user?->id,
+            'user_type' => $user?->type?->value,
+            'name'      => $request->input('name', $user?->name),
+            'email'     => $request->input('email', $user?->email),
+            'phone'     => $request->input('phone', $user?->phone),
+        ]);
+
+        $item = $this->service->create($data);
+
+        return $this->successResponse(payload: new SupportRequestResource($item), message: __('messages.created'), code: 201);
+    }
+
+    public function update(SupportRequestRequest $request, int $id): JsonResponse
+    {
+        $item = $this->service->updateStatus($id, $request->validated()['status'], Auth::id());
+
+        if (! $item) {
+            return $this->errorResponse(message: __('messages.not_found'));
+        }
+
+        return $this->successResponse(payload: new SupportRequestResource($item), message: __('messages.updated'));
+    }
+}

+ 29 - 0
app/Http/Requests/SupportRequestRequest.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Requests;
+
+use App\Enums\SupportRequestCategoryEnum;
+use App\Enums\SupportRequestStatusEnum;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Validation\Rule;
+
+class SupportRequestRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        if ($this->isMethod('PUT') || $this->isMethod('PATCH')) {
+            return [
+                'status' => ['required', Rule::in(SupportRequestStatusEnum::toArray())],
+            ];
+        }
+
+        return [
+            'category' => ['required', Rule::in(SupportRequestCategoryEnum::toArray())],
+            'title'    => ['required', 'string', 'max:150'],
+            'message'  => ['required', 'string', 'max:8000'],
+            'name'     => ['sometimes', 'nullable', 'string', 'max:255'],
+            'email'    => ['sometimes', 'nullable', 'email', 'max:255'],
+            'phone'    => ['sometimes', 'nullable', 'string', 'max:30'],
+        ];
+    }
+}

+ 46 - 0
app/Http/Resources/SupportRequestResource.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Http\Resources;
+
+use App\Models\SupportRequest;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class SupportRequestResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @return array<string, mixed>
+     */
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'          => $this->id,
+            'user_id'     => $this->user_id,
+            'user_type'   => $this->user_type,
+            'name'        => $this->name,
+            'email'       => $this->email,
+            'phone'       => $this->phone,
+            'category'    => $this->category,
+            'title'       => $this->title,
+            'message'     => $this->message,
+            'status'      => $this->status?->value,
+            'handled_by'  => $this->handled_by,
+            'handler'     => $this->whenLoaded('handler', fn () => $this->handler?->name),
+            'resolved_at' => $this->resolved_at?->format('d/m/Y H:i'),
+            'created_at'  => $this->created_at?->format('d/m/Y H:i'),
+            'updated_at'  => $this->updated_at?->format('d/m/Y H:i'),
+        ];
+    }
+
+    /**
+     * @param  \Illuminate\Database\Eloquent\Collection<SupportRequest>  $resource
+     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<SupportRequestResource>
+     */
+    public static function collection($resource): AnonymousResourceCollection
+    {
+        return parent::collection($resource);
+    }
+}

+ 40 - 0
app/Mail/SupportRequestAlert.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Mail;
+
+use App\Models\SupportRequest;
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable;
+use Illuminate\Mail\Mailables\Content;
+use Illuminate\Mail\Mailables\Envelope;
+use Illuminate\Queue\SerializesModels;
+
+class SupportRequestAlert extends Mailable
+{
+    use Queueable, SerializesModels;
+
+    public function __construct(
+        public readonly SupportRequest $supportRequest,
+    ) {}
+
+    public function envelope(): Envelope
+    {
+        return new Envelope(
+            from:    config('services.support.from'),
+            subject: __('mail.support_request.subject', ['title' => $this->supportRequest->title]),
+        );
+    }
+
+    public function content(): Content
+    {
+        return new Content(
+            view: 'emails.support_request',
+            with: ['supportRequest' => $this->supportRequest],
+        );
+    }
+
+    public function attachments(): array
+    {
+        return [];
+    }
+}

+ 71 - 0
app/Models/SupportRequest.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Models;
+
+use App\Enums\SupportRequestStatusEnum;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property int|null $user_id
+ * @property string|null $user_type
+ * @property string|null $name
+ * @property string|null $email
+ * @property string|null $phone
+ * @property string $category
+ * @property string $title
+ * @property string $message
+ * @property SupportRequestStatusEnum $status
+ * @property int|null $handled_by
+ * @property \Illuminate\Support\Carbon|null $resolved_at
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @property \Illuminate\Support\Carbon|null $deleted_at
+ * @property-read \App\Models\User|null $user
+ * @property-read \App\Models\User|null $handler
+ */
+class SupportRequest extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = 'support_requests';
+
+    protected $guarded = [
+        'id',
+    ];
+
+    protected $fillable = [
+        'user_id',
+        'user_type',
+        'name',
+        'email',
+        'phone',
+        'category',
+        'title',
+        'message',
+        'status',
+        'handled_by',
+        'resolved_at',
+    ];
+
+    protected $casts = [
+        'status'      => SupportRequestStatusEnum::class,
+        'resolved_at' => 'datetime',
+        'created_at'  => 'datetime',
+        'updated_at'  => 'datetime',
+        'deleted_at'  => 'datetime',
+    ];
+
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'user_id');
+    }
+
+    public function handler(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'handled_by');
+    }
+}

+ 1 - 1
app/Services/AuthService.php

@@ -318,7 +318,7 @@ class AuthService
             $user->load('provider');
             $provider = $user->provider ?? null;
 
-            if (! $user->registration_complete || ! $provider) {
+            if (! $provider) {
                 return ['error' => 'registration_incomplete'];
             }
 

+ 90 - 0
app/Services/SupportRequestService.php

@@ -0,0 +1,90 @@
+<?php
+
+namespace App\Services;
+
+use App\Enums\SupportRequestStatusEnum;
+use App\Mail\SupportRequestAlert;
+use App\Models\SupportRequest;
+use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Mail;
+
+class SupportRequestService
+{
+    public function paginate(
+        ?string $status = null,
+        ?string $search = null,
+        int $page = 1,
+        int $perPage = 10,
+    ): LengthAwarePaginator {
+        return SupportRequest::query()
+            ->with('handler:id,name')
+            ->when($status, fn ($query) => $query->where('status', $status))
+            ->when($search, function ($query) use ($search) {
+                $query->where(function ($sub) use ($search) {
+                    $sub->where('title', 'like', "%{$search}%")
+                        ->orWhere('name', 'like', "%{$search}%")
+                        ->orWhere('email', 'like', "%{$search}%");
+                });
+            })
+            ->orderByRaw("CASE status WHEN 'pending' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'resolved' THEN 2 ELSE 3 END")
+            ->orderBy('created_at', 'desc')
+            ->paginate($perPage, ['*'], 'page', $page);
+    }
+
+    public function findById(int $id): ?SupportRequest
+    {
+        return SupportRequest::with('handler')->find($id);
+    }
+
+    public function create(array $data): SupportRequest
+    {
+        $data['status'] ??= SupportRequestStatusEnum::PENDING->value;
+
+        $supportRequest = SupportRequest::create($data);
+
+        $this->sendAlert($supportRequest);
+
+        return $supportRequest;
+    }
+
+    public function updateStatus(int $id, string $status, ?int $handledBy = null): ?SupportRequest
+    {
+        $supportRequest = $this->findById($id);
+
+        if (! $supportRequest) {
+            return null;
+        }
+
+        $payload = ['status' => $status];
+
+        if ($status === SupportRequestStatusEnum::IN_PROGRESS->value && ! $supportRequest->handled_by) {
+            $payload['handled_by'] = $handledBy;
+        }
+
+        $payload['resolved_at'] = $status === SupportRequestStatusEnum::RESOLVED->value ? now() : null;
+
+        $supportRequest->update($payload);
+
+        return $supportRequest->fresh('handler');
+    }
+
+    private function sendAlert(SupportRequest $supportRequest): void
+    {
+        $recipient = config('services.support.email');
+
+        if (! $recipient) {
+            return;
+        }
+
+        try {
+            Mail::to($recipient)->send(new SupportRequestAlert($supportRequest));
+        } catch (\Throwable $e) {
+            // Alerta é best-effort: o registro no backoffice continua sendo a fonte da verdade.
+            Log::error('Support request alert email failed', [
+                'support_request_id' => $supportRequest->id,
+                'error'              => $e->getMessage(),
+            ]);
+        }
+    }
+}

+ 5 - 0
config/services.php

@@ -39,6 +39,11 @@ return [
         'api_key' => env('GEMINI_API_KEY'),
     ],
 
+    'support' => [
+        'email' => env('SUPPORT_EMAIL'),
+        'from'  => env('SUPPORT_FROM_EMAIL', env('MAIL_FROM_ADDRESS')),
+    ],
+
     'pagarme' => [
         'secret_key'            => env('PAGARME_SECRET_KEY'),
         'service_referer_name'  => env('PAGARME_SERVICE_REFERER_NAME', env('APP_NAME', 'Laravel')),

+ 41 - 0
database/migrations/2026_07_03_093450_create_support_requests_table.php

@@ -0,0 +1,41 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('support_requests', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
+            $table->string('user_type')->nullable();
+            $table->string('name')->nullable();
+            $table->string('email')->nullable();
+            $table->string('phone')->nullable();
+            $table->string('category');
+            $table->string('title');
+            $table->text('message');
+            $table->enum('status', ['pending', 'in_progress', 'resolved'])->default('pending');
+            $table->foreignId('handled_by')->nullable()->constrained('users')->nullOnDelete();
+            $table->timestamp('resolved_at')->nullable();
+            $table->timestamps();
+            $table->softDeletes();
+
+            $table->index(['status', 'created_at']);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('support_requests');
+    }
+};

+ 6 - 0
database/seeders/PermissionSeeder.php

@@ -218,6 +218,12 @@ class PermissionSeeder extends Seeder
                     ],
                 ],
             ],
+            [
+                'scope'       => 'support.request',
+                'description' => 'Solicitações de Atendimento',
+                'bits'        => 271,
+                'children'    => [],
+            ],
         ];
 
         $this->createPermissionsAndChildren(permissions: $permissions);

+ 1 - 0
database/seeders/UserTypePermissionSeeder.php

@@ -57,6 +57,7 @@ class UserTypePermissionSeeder extends Seeder
                         ['scope' => 'notification',                    'bits' => 271],
                         ['scope' => 'payment',                         'bits' => 257],
                         ['scope' => 'payment-split',                   'bits' => 1],
+                        ['scope' => 'support.request',                 'bits' => 271],
                     ];
 
                     $this->seedUserTypePermissions($userPermissions, UserTypeEnum::USER->value);

+ 13 - 0
lang/en/mail.php

@@ -1,6 +1,19 @@
 <?php
 
 return [
+    'support_request' => [
+        'subject'        => 'New support request: :title',
+        'title'          => 'Human support request',
+        'subtitle'       => 'A user asked to talk to a human agent through the chatbot.',
+        'field_name'     => 'Name',
+        'field_type'     => 'Type',
+        'field_email'    => 'Email',
+        'field_phone'    => 'Phone',
+        'field_category' => 'Category',
+        'field_title'    => 'Subject',
+        'field_message'  => 'Message',
+        'footer_note'    => 'This request is also recorded in the backoffice. This is an automated email, please do not reply.',
+    ],
     'send_code' => [
         'subject'            => 'Your verification code',
         'header_subtitle'    => 'Access verification',

+ 1 - 0
lang/en/messages.php

@@ -5,6 +5,7 @@ return [
     'created'                              => 'Created successfully',
     'updated'                              => 'Updated successfully',
     'deleted'                              => 'Deleted successfully',
+    'not_found'                            => 'Record not found',
     'email_sent'                           => 'Email sent successfully',
     'email_not_sent'                       => 'Email not sent',
     'imported'                             => 'Imported successfully',

+ 13 - 0
lang/es/mail.php

@@ -1,6 +1,19 @@
 <?php
 
 return [
+    'support_request' => [
+        'subject'        => 'Nueva solicitud de atención: :title',
+        'title'          => 'Solicitud de atención humana',
+        'subtitle'       => 'Un usuario pidió hablar con un agente a través del chatbot.',
+        'field_name'     => 'Nombre',
+        'field_type'     => 'Tipo',
+        'field_email'    => 'Correo',
+        'field_phone'    => 'Teléfono',
+        'field_category' => 'Categoría',
+        'field_title'    => 'Asunto',
+        'field_message'  => 'Mensaje',
+        'footer_note'    => 'Esta solicitud también está registrada en el backoffice. Este es un correo automático, por favor no respondas.',
+    ],
     'send_code' => [
         'subject'            => 'Tu código de verificación',
         'header_subtitle'    => 'Verificación de acceso',

+ 1 - 0
lang/es/messages.php

@@ -5,6 +5,7 @@ return [
     'created'                              => 'Creado exitosamente',
     'updated'                              => 'Actualizado exitosamente',
     'deleted'                              => 'Eliminado exitosamente',
+    'not_found'                            => 'Registro no encontrado',
     'email_sent'                           => 'Email enviado exitosamente',
     'email_not_sent'                       => 'Email no enviado',
     'imported'                             => 'Importado exitosamente',

+ 13 - 0
lang/pt/mail.php

@@ -1,6 +1,19 @@
 <?php
 
 return [
+    'support_request' => [
+        'subject'        => 'Nova solicitação de atendimento: :title',
+        'title'          => 'Solicitação de atendimento humano',
+        'subtitle'       => 'Um usuário pediu para falar com um atendente pelo chatbot.',
+        'field_name'     => 'Nome',
+        'field_type'     => 'Tipo',
+        'field_email'    => 'E-mail',
+        'field_phone'    => 'Telefone',
+        'field_category' => 'Categoria',
+        'field_title'    => 'Assunto',
+        'field_message'  => 'Mensagem',
+        'footer_note'    => 'Esta solicitação também está registrada no backoffice. Este é um e-mail automático, não responda esta mensagem.',
+    ],
     'send_code' => [
         'subject'            => 'Seu código de verificação',
         'header_subtitle'    => 'Verificação de acesso',

+ 1 - 0
lang/pt/messages.php

@@ -5,6 +5,7 @@ return [
     'created'                              => 'Criado com sucesso',
     'updated'                              => 'Atualizado com sucesso',
     'deleted'                              => 'Excluído com sucesso',
+    'not_found'                            => 'Registro não encontrado',
     'email_sent'                           => 'Email enviado com sucesso',
     'email_not_sent'                       => 'Email não enviado',
     'imported'                             => 'Importado com sucesso',

+ 17 - 0
resources/chatbot/restricoes.md

@@ -58,6 +58,23 @@ Quando detectar qualquer uma das situações acima, responda APENAS:
 
 Não explique o motivo da recusa, não confirme nem negue a existência de restrições, não negocie e não ofereça alternativas. Apenas aplique a resposta padrão e encerre o assunto.
 
+========================================================
+ATENDIMENTO HUMANO — FALAR COM UM ATENDENTE
+========================================================
+
+Esta seção se aplica a AMBOS os apps (Cliente e Prestador) e tem prioridade sobre as orientações genéricas de "entrar em contato com o administrador".
+
+QUANDO ACIONAR:
+Sempre que o usuário pedir para falar com um atendente humano, com o suporte, com uma pessoa de verdade, com um humano; OU quando você perceber que não conseguiu resolver o problema dele e ele precisa de ajuda de uma pessoa; OU em qualquer situação em que uma regra mande "entrar em contato com o administrador".
+
+COMO ORIENTAR (responda de forma natural, com este conteúdo):
+"Para falar com um atendente humano, toque no botão de atendente — o ícone de uma pessoa com fone de ouvido — no canto superior direito, aqui no topo desta conversa. Vai abrir um formulário rápido para você enviar sua solicitação, e nossa equipe de suporte entrará em contato com você."
+
+REGRAS:
+- NÃO peça dados pessoais nem tente coletar a mensagem ou o problema você mesmo; apenas direcione o usuário ao botão de atendente no cabeçalho.
+- Esse botão é o canal OFICIAL de contato com o suporte e fica SEMPRE visível no topo desta tela de chat.
+- Não execute nem prometa executar o contato; apenas oriente o usuário a usar o botão.
+
 ========================================================
 RESTRIÇÕES DE ESCOPO — APP CLIENTE
 ========================================================

+ 85 - 0
resources/views/emails/support_request.blade.php

@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html lang="pt-BR">
+
+<head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>{{ __('mail.support_request.subject', ['title' => $supportRequest->title]) }}</title>
+</head>
+
+<body style="margin:0;padding:0;background:#f5f5f7;font-family:Arial,Helvetica,sans-serif;">
+
+    <table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="#f5f5f7">
+        <tr>
+            <td align="center" style="padding:25px;">
+
+                <table width="650" cellpadding="0" cellspacing="0" border="0" bgcolor="#ffffff"
+                    style="border-radius:24px;overflow:hidden;">
+
+                    <!-- HEADER -->
+                    <tr>
+                        <td style="background:#5a22d6;padding:40px;color:white;">
+                            <div style="font-size:28px;font-weight:bold;line-height:1.2;">
+                                {{ __('mail.support_request.title') }}
+                            </div>
+                            <div style="font-size:16px;margin-top:12px;line-height:1.6;">
+                                {{ __('mail.support_request.subtitle') }}
+                            </div>
+                        </td>
+                    </tr>
+
+                    <!-- BODY -->
+                    <tr>
+                        <td style="padding:32px 40px;color:#2c2c2c;">
+
+                            <table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size:15px;line-height:1.6;">
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;width:150px;">{{ __('mail.support_request.field_name') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->name ?: '-' }}</td>
+                                </tr>
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;">{{ __('mail.support_request.field_type') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->user_type ?: '-' }}</td>
+                                </tr>
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;">{{ __('mail.support_request.field_email') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->email ?: '-' }}</td>
+                                </tr>
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;">{{ __('mail.support_request.field_phone') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->phone ?: '-' }}</td>
+                                </tr>
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;">{{ __('mail.support_request.field_category') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->category }}</td>
+                                </tr>
+                                <tr>
+                                    <td style="padding:6px 0;color:#777;">{{ __('mail.support_request.field_title') }}</td>
+                                    <td style="padding:6px 0;font-weight:bold;">{{ $supportRequest->title }}</td>
+                                </tr>
+                            </table>
+
+                            <div style="margin-top:24px;font-size:13px;color:#777;text-transform:uppercase;letter-spacing:0.5px;">
+                                {{ __('mail.support_request.field_message') }}
+                            </div>
+                            <div style="margin-top:8px;padding:16px;background:#f5f5f7;border-radius:12px;font-size:15px;line-height:1.6;white-space:pre-wrap;">{{ $supportRequest->message }}</div>
+
+                        </td>
+                    </tr>
+
+                    <!-- FOOTER -->
+                    <tr>
+                        <td style="background:#faf9ff;padding:24px 40px;color:#777;font-size:13px;line-height:1.6;">
+                            {{ __('mail.support_request.footer_note') }}
+                        </td>
+                    </tr>
+
+                </table>
+
+            </td>
+        </tr>
+    </table>
+
+</body>
+
+</html>

+ 10 - 0
routes/authRoutes/support_request.php

@@ -0,0 +1,10 @@
+<?php
+
+use App\Http\Controllers\SupportRequestController;
+use Illuminate\Support\Facades\Route;
+
+Route::post('/support-request', [SupportRequestController::class, 'store']);
+
+Route::get('/support-requests',     [SupportRequestController::class, 'index'])->middleware('permission:support.request,view');
+Route::get('/support-request/{id}', [SupportRequestController::class, 'show'])->middleware('permission:support.request,view');
+Route::put('/support-request/{id}', [SupportRequestController::class, 'update'])->middleware('permission:support.request,edit');