feat(cms): implement complete SysSiteCMS content management system

Initial implementation of the HomeSysPanel CMS built with Laravel 13.0.
Includes complete admin panel, content management, user authentication,
modular architecture for products/services/chatbot, and marketing tools.

Key features:
- User authentication with email verification and password reset
- Role-based access control (Admin/User with granular permissions)
- Content management (pages, news, FAQ, downloads, galleries, banners)
- Contact management system with subjects and responses
- Marketing tools (email campaigns, visitor analytics, social sharing)
- Modular architecture (Products, Services, Chatbot modules)
- AI Chatbot integration with OpenRouter.ai and LlamaCpp support
- Visitor tracking with geolocation
- SEO optimization with meta tags and Open Graph
- Responsive design with Bootstrap 5
- Dark mode support
- Maintenance mode
- Feature request system
This commit is contained in:
marco
2026-09-07 19:06:53 -03:00
commit 38295e7e88
279 changed files with 33691 additions and 0 deletions
@@ -0,0 +1,119 @@
@extends('layouts.admin')
@section('title', 'Chatbot - Nova Regra')
@section('content')
<div class="container-fluid px-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 text-gray-800">
<i class="bi bi-shield-lock me-2"></i>Nova Regra para a IA
</h1>
<a href="{{ route('admin.chatbot.rules.index') }}" class="btn btn-secondary btn-sm">
<i class="bi bi-arrow-left me-1"></i>Voltar
</a>
</div>
@if($errors->any())
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong><i class="bi bi-exclamation-triangle me-1"></i>Erro(s):</strong>
<ul class="mb-0">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Fechar">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Dados da Regra</h6>
</div>
<div class="card-body">
<form action="{{ route('admin.chatbot.rules.store') }}" method="POST">
@csrf
<div class="form-group row">
<label for="title" class="col-sm-3 col-form-label">Título <span class="text-danger">*</span></label>
<div class="col-sm-9">
<input type="text" class="form-control" id="title" name="title"
value="{{ old('title') }}" required maxlength="255"
placeholder="Ex: Sempre oferecer WhatsApp para agendamentos">
<small class="text-muted">Nome curto para identificar a regra na listagem.</small>
</div>
</div>
<div class="form-group row">
<label for="content" class="col-sm-3 col-form-label">Conteúdo da Regra <span class="text-danger">*</span></label>
<div class="col-sm-9">
<textarea class="form-control" id="content" name="content" rows="4" required maxlength="2000"
placeholder="Ex: Sempre que o visitante demonstrar interesse em agendar um serviço, ofereça o WhatsApp (48) 99999-9999 como canal preferencial de agendamento.">{{ old('content') }}</textarea>
<small class="text-muted">A instrução completa que será enviada à IA. Máximo de 2000 caracteres.</small>
</div>
</div>
<div class="form-group row">
<label for="order" class="col-sm-3 col-form-label">Ordem</label>
<div class="col-sm-9">
<input type="number" class="form-control" id="order" name="order"
value="{{ old('order', 0) }}" min="0" max="9999">
<small class="text-muted">Define a prioridade da regra (menor número = maior prioridade). Padrão: 0.</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Status</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="active" name="active"
{{ old('active', true) ? 'checked' : '' }}>
<label class="custom-control-label" for="active">
<strong>Regra Ativa</strong> — Quando marcada, a regra será seguida pela IA nas conversas.
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-sm-9 offset-sm-3">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle me-1"></i>Salvar Regra
</button>
<a href="{{ route('admin.chatbot.rules.index') }}" class="btn btn-secondary ml-2">Cancelar</a>
</div>
</div>
</form>
</div>
</div>
<!-- Examples Card -->
<div class="card border-info mb-4">
<div class="card-header bg-info text-white py-3">
<h6 class="m-0 font-weight-bold"><i class="bi bi-lightbulb me-1"></i>Exemplos de Regras Úteis</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p class="small mb-1"><strong>🎯 Direcionar para contato humano:</strong></p>
<p class="small text-muted">"Sempre que o visitante tiver uma dúvida complexa ou reclamação, sugira entrar em contato pelo telefone (XX) XXXX-XXXX."</p>
</div>
<div class="col-md-6">
<p class="small mb-1"><strong>💬 Tom de voz:</strong></p>
<p class="small text-muted">"Use sempre linguagem formal e profissional. Trate o visitante por 'você' mas evite gírias."</p>
</div>
<div class="col-md-6">
<p class="small mb-1"><strong>🚫 Proibir descontos:</strong></p>
<p class="small text-muted">"NUNCA ofereça descontos, promova valores ou negocie preços. Indique que valores são praticados apenas pela equipe comercial."</p>
</div>
<div class="col-md-6">
<p class="small mb-1"><strong>📍 Atendimento regional:</strong></p>
<p class="small text-muted">"Atendemos apenas as cidades de Florianópolis, São José e Biguaçu. Para outras regiões, informe que não há cobertura."</p>
</div>
</div>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,91 @@
@extends('layouts.admin')
@section('title', 'Chatbot - Editar Regra')
@section('content')
<div class="container-fluid px-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 text-gray-800">
<i class="bi bi-shield-lock me-2"></i>Editar Regra da IA
</h1>
<a href="{{ route('admin.chatbot.rules.index') }}" class="btn btn-secondary btn-sm">
<i class="bi bi-arrow-left me-1"></i>Voltar
</a>
</div>
@if($errors->any())
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong><i class="bi bi-exclamation-triangle me-1"></i>Erro(s):</strong>
<ul class="mb-0">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Fechar">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Dados da Regra</h6>
</div>
<div class="card-body">
<form action="{{ route('admin.chatbot.rules.update', $rule) }}" method="POST">
@csrf
@method('PUT')
<div class="form-group row">
<label for="title" class="col-sm-3 col-form-label">Título <span class="text-danger">*</span></label>
<div class="col-sm-9">
<input type="text" class="form-control" id="title" name="title"
value="{{ old('title', $rule->title) }}" required maxlength="255">
<small class="text-muted">Nome curto para identificar a regra na listagem.</small>
</div>
</div>
<div class="form-group row">
<label for="content" class="col-sm-3 col-form-label">Conteúdo da Regra <span class="text-danger">*</span></label>
<div class="col-sm-9">
<textarea class="form-control" id="content" name="content" rows="4" required maxlength="2000">{{ old('content', $rule->content) }}</textarea>
<small class="text-muted">A instrução completa que será enviada à IA. Máximo de 2000 caracteres.</small>
</div>
</div>
<div class="form-group row">
<label for="order" class="col-sm-3 col-form-label">Ordem</label>
<div class="col-sm-9">
<input type="number" class="form-control" id="order" name="order"
value="{{ old('order', $rule->order) }}" min="0" max="9999">
<small class="text-muted">Define a prioridade da regra (menor número = maior prioridade).</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Status</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="active" name="active"
{{ old('active', $rule->active) ? 'checked' : '' }}>
<label class="custom-control-label" for="active">
<strong>Regra Ativa</strong> — Quando marcada, a regra será seguida pela IA nas conversas.
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-sm-9 offset-sm-3">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle me-1"></i>Salvar Alterações
</button>
<a href="{{ route('admin.chatbot.rules.index') }}" class="btn btn-secondary ml-2">Cancelar</a>
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,110 @@
@extends('layouts.admin')
@section('title', 'Chatbot - Regras da IA')
@section('content')
<div class="container-fluid px-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 text-gray-800">
<i class="bi bi-shield-lock me-2"></i>Chatbot - Regras da IA
</h1>
<a href="{{ route('admin.chatbot.rules.create') }}" class="btn btn-primary btn-sm">
<i class="bi bi-plus-circle me-1"></i>Nova Regra
</a>
</div>
<!-- Info Card -->
<div class="card border-info mb-4">
<div class="card-body">
<h6 class="card-title mb-2"><i class="bi bi-info-circle me-1 text-info"></i>Como funcionam as Regras</h6>
<p class="small text-muted mb-0">
As regras são instruções obrigatórias que a IA <strong>deve seguir</strong> em todas as respostas.
Elas são enviadas automaticamente no início do prompt do sistema, antes das informações da base de conhecimento.
Use para definir tom de voz, proibições específicas, fluxos obrigatórios ou qualquer comportamento desejado.
Regras desativadas são ignoradas. Use o campo <strong>Ordem</strong> para definir a prioridade (menor = mais importante).
</p>
</div>
</div>
@if(session('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle me-1"></i>{{ session('success') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Fechar">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<!-- Rules List -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex align-items-center">
<h6 class="m-0 font-weight-bold text-primary">Regras Configuradas</h6>
</div>
<div class="card-body p-0">
@if($rules->isEmpty())
<div class="text-center py-5">
<i class="bi bi-shield-lock" style="font-size:3rem;color:#dddfeb;"></i>
<p class="mt-3 text-muted">Nenhuma regra configurada ainda.</p>
<p class="text-muted small">Adicione regras para definir como a IA deve se comportar no atendimento.</p>
<a href="{{ route('admin.chatbot.rules.create') }}" class="btn btn-primary btn-sm">
<i class="bi bi-plus-circle me-1"></i>Adicionar Primeira Regra
</a>
</div>
@else
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="thead-light">
<tr>
<th width="60">Ordem</th>
<th>Título</th>
<th>Conteúdo da Regra</th>
<th width="100">Status</th>
<th width="140">Ações</th>
</tr>
</thead>
<tbody>
@foreach($rules as $rule)
<tr>
<td>
<span class="badge badge-secondary">{{ $rule->order }}</span>
</td>
<td>
<strong>{{ $rule->title }}</strong>
</td>
<td>
<span class="text-muted">{{ \Illuminate\Support\Str::limit($rule->content, 150) }}</span>
</td>
<td>
@if($rule->active)
<span class="badge badge-success"><i class="bi bi-check-circle"></i> Ativa</span>
@else
<span class="badge badge-secondary"><i class="bi bi-pause-circle"></i> Inativa</span>
@endif
</td>
<td>
<a href="{{ route('admin.chatbot.rules.edit', $rule) }}" class="btn btn-sm btn-outline-primary" title="Editar">
<i class="bi bi-pencil"></i>
</a>
<form action="{{ route('admin.chatbot.rules.destroy', $rule) }}" method="POST" class="d-inline" onsubmit="return confirm('Tem certeza que deseja excluir esta regra?');">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-outline-danger" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="p-3">
{{ $rules->withQueryString()->links() }}
</div>
@endif
</div>
</div>
</div>
@endsection