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:
Executable
+88
@@ -0,0 +1,88 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Login - Syspanel')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-5">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 bg-primary p-5 text-white text-center">
|
||||
<i class="bi bi-cpu fs-1 mb-3"></i>
|
||||
<h2 class="fw-bold">Bem-vindo de volta!</h2>
|
||||
<p class="mb-0 text-white-50">Acesse sua conta para gerenciar seus serviços.</p>
|
||||
</div>
|
||||
<div class="col-12 p-5 bg-white">
|
||||
@if(session('error'))
|
||||
<div class="alert alert-danger border-0 shadow-sm mb-4">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
<div class="mb-4">
|
||||
<label for="email" class="form-label fw-bold">E-mail</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-envelope text-muted"></i></span>
|
||||
<input type="email" class="form-control bg-light border-start-0 ps-0 @error('email') is-invalid @enderror" id="email" name="email" value="{{ old('email') }}" placeholder="seu@email.com" required autocomplete="email" autofocus>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="d-flex justify-content-between">
|
||||
<label for="password" class="form-label fw-bold">Senha</label>
|
||||
@if (Route::has('password.request'))
|
||||
<a href="{{ route('password.request') }}" class="text-decoration-none small">Esqueceu a senha?</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-lock text-muted"></i></span>
|
||||
<input type="password" class="form-control bg-light border-start-0 border-end-0 ps-0 @error('password') is-invalid @enderror" id="password" name="password" placeholder="••••••••" required autocomplete="current-password">
|
||||
<button class="btn btn-light border-start-0 toggle-password" type="button">
|
||||
<i class="bi bi-eye text-muted"></i>
|
||||
</button>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="remember" name="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
<label class="form-check-label text-muted" for="remember">Lembrar de mim</label>
|
||||
</div>
|
||||
|
||||
@include('partials.captcha')
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100 py-3 fw-bold shadow-sm rounded-pill mb-4">
|
||||
Entrar
|
||||
</button>
|
||||
|
||||
@if(Route::has('register') && \App\Models\Setting::get('public_registration') == 'on')
|
||||
<div class="text-center">
|
||||
<span class="text-muted">Não tem uma conta?</span>
|
||||
<a href="{{ route('register') }}" class="text-decoration-none fw-bold">Cadastre-se</a>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<a href="{{ route('index') }}" class="text-muted text-decoration-none small">
|
||||
<i class="bi bi-arrow-left"></i> Voltar para o site
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Confirm Password') }}</div>
|
||||
|
||||
<div class="card-body">
|
||||
{{ __('Please confirm your password before continuing.') }}
|
||||
|
||||
<form method="POST" action="{{ route('password.confirm') }}">
|
||||
@csrf
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
<button class="btn btn-outline-secondary toggle-password" type="button">
|
||||
<i class="bi bi-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Confirm Password') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Recuperar Senha - Syspanel')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-5">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden">
|
||||
<div class="bg-primary p-5 text-white text-center">
|
||||
<i class="bi bi-key fs-1 mb-3"></i>
|
||||
<h2 class="fw-bold">Recuperar Senha</h2>
|
||||
<p class="mb-0 text-white-50">Enviaremos um link para você redefinir sua senha.</p>
|
||||
</div>
|
||||
<div class="card-body p-5 bg-white">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success border-0 shadow-sm rounded-3 mb-4" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('password.email') }}">
|
||||
@csrf
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="email" class="form-label fw-bold">Endereço de E-mail</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-envelope text-muted"></i></span>
|
||||
<input id="email" type="email" class="form-control bg-light border-start-0 ps-0 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus placeholder="seu@email.com">
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('partials.captcha')
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100 py-3 fw-bold shadow-sm rounded-pill mb-4">
|
||||
Enviar Link de Recuperação
|
||||
</button>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="{{ route('login') }}" class="text-decoration-none fw-bold">Voltar para o Login</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Redefinir Senha - Syspanel')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-5">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden">
|
||||
<div class="bg-primary p-5 text-white text-center">
|
||||
<i class="bi bi-shield-lock fs-1 mb-3"></i>
|
||||
<h2 class="fw-bold">Redefinir Senha</h2>
|
||||
<p class="mb-0 text-white-50">Crie uma nova senha para sua conta.</p>
|
||||
</div>
|
||||
<div class="card-body p-5 bg-white">
|
||||
<form method="POST" action="{{ route('password.update') }}">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="email" class="form-label fw-bold">Endereço de E-mail</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-envelope text-muted"></i></span>
|
||||
<input id="email" type="email" class="form-control bg-light border-start-0 ps-0 @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus placeholder="seu@email.com">
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="password" class="form-label fw-bold">Nova Senha</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-lock text-muted"></i></span>
|
||||
<input id="password" type="password" class="form-control bg-light border-start-0 border-end-0 ps-0 @error('password') is-invalid @enderror" name="password" required autocomplete="new-password" placeholder="••••••••">
|
||||
<button class="btn btn-light border-start-0 toggle-password" type="button">
|
||||
<i class="bi bi-eye text-muted"></i>
|
||||
</button>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="password-confirm" class="form-label fw-bold">Confirmar Nova Senha</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-lock-fill text-muted"></i></span>
|
||||
<input id="password-confirm" type="password" class="form-control bg-light border-start-0 border-end-0 ps-0" name="password_confirmation" required autocomplete="new-password" placeholder="••••••••">
|
||||
<button class="btn btn-light border-start-0 toggle-password" type="button">
|
||||
<i class="bi bi-eye text-muted"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('partials.captcha')
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100 py-3 fw-bold shadow-sm rounded-pill">
|
||||
Redefinir Senha
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Executable
+152
@@ -0,0 +1,152 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Cadastro - Syspanel')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-6">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 bg-primary p-4 text-white text-center">
|
||||
<i class="bi bi-person-plus fs-1 mb-2"></i>
|
||||
<h2 class="fw-bold">Crie sua conta</h2>
|
||||
<p class="mb-0 text-white-50">Junte-se à Syspanel e gerencie seus serviços.</p>
|
||||
</div>
|
||||
<div class="col-12 p-5 bg-white">
|
||||
<form method="POST" action="{{ route('register') }}">
|
||||
@csrf
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label fw-bold">Nome Completo</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-person text-muted"></i></span>
|
||||
<input id="name" type="text" class="form-control bg-light border-start-0 ps-0 @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus placeholder="Seu nome">
|
||||
@error('name')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label fw-bold">E-mail</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-envelope text-muted"></i></span>
|
||||
<input id="email" type="email" class="form-control bg-light border-start-0 ps-0 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" placeholder="seu@email.com">
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="user_type" class="form-label fw-bold">Tipo de Usuário</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-person-badge text-muted"></i></span>
|
||||
<select id="user_type" class="form-select bg-light border-start-0 ps-0 @error('user_type') is-invalid @enderror" name="user_type" required>
|
||||
<option value="" disabled {{ old('user_type') ? '' : 'selected' }}>Selecione o tipo</option>
|
||||
<option value="User" {{ old('user_type') == 'User' ? 'selected' : '' }}>Usuário (User)</option>
|
||||
<option value="Admin" {{ old('user_type') == 'Admin' ? 'selected' : '' }}>Administrador (Admin)</option>
|
||||
</select>
|
||||
@error('user_type')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="company" class="form-label fw-bold">Empresa (Opcional)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-building text-muted"></i></span>
|
||||
<input id="company" type="text" class="form-control bg-light border-start-0 ps-0 @error('company') is-invalid @enderror" name="company" value="{{ old('company') }}" placeholder="Nome da empresa">
|
||||
@error('company')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="website" class="form-label fw-bold">Site (Opcional)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-globe text-muted"></i></span>
|
||||
<input id="website" type="text" class="form-control bg-light border-start-0 ps-0 @error('website') is-invalid @enderror" name="website" value="{{ old('website') }}" placeholder="https://exemplo.com">
|
||||
@error('website')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="whatsapp" class="form-label fw-bold">WhatsApp (Opcional)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-whatsapp text-muted"></i></span>
|
||||
<input id="whatsapp" type="text" class="form-control bg-light border-start-0 ps-0 @error('whatsapp') is-invalid @enderror" name="whatsapp" value="{{ old('whatsapp') }}" placeholder="(00) 00000-0000">
|
||||
@error('whatsapp')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="password" class="form-label fw-bold">Senha</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-lock text-muted"></i></span>
|
||||
<input id="password" type="password" class="form-control bg-light border-start-0 border-end-0 ps-0 @error('password') is-invalid @enderror" name="password" required autocomplete="new-password" placeholder="••••••••">
|
||||
<button class="btn btn-light border-start-0 toggle-password" type="button">
|
||||
<i class="bi bi-eye text-muted"></i>
|
||||
</button>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="password-confirm" class="form-label fw-bold">Confirmar Senha</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="bi bi-lock-fill text-muted"></i></span>
|
||||
<input id="password-confirm" type="password" class="form-control bg-light border-start-0 border-end-0 ps-0" name="password_confirmation" required autocomplete="new-password" placeholder="••••••••">
|
||||
<button class="btn btn-light border-start-0 toggle-password" type="button">
|
||||
<i class="bi bi-eye text-muted"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 small text-muted">
|
||||
Ao se cadastrar, você concorda com nossos <a href="#" class="text-decoration-none">Termos de Uso</a>.
|
||||
</div>
|
||||
|
||||
@include('partials.captcha')
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100 py-3 fw-bold shadow-sm rounded-pill mb-4">
|
||||
Cadastrar Agora
|
||||
</button>
|
||||
|
||||
<div class="text-center">
|
||||
<span class="text-muted">Já tem uma conta?</span>
|
||||
<a href="{{ route('login') }}" class="text-decoration-none fw-bold">Faça login</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Verificar E-mail - Syspanel')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-6">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden text-center">
|
||||
<div class="bg-primary p-5 text-white">
|
||||
<i class="bi bi-envelope-check fs-1 mb-3"></i>
|
||||
<h2 class="fw-bold">Verifique seu E-mail</h2>
|
||||
<p class="mb-0 text-white-50">Enviamos um link de confirmação para o seu endereço de e-mail.</p>
|
||||
</div>
|
||||
<div class="card-body p-5 bg-white">
|
||||
@if (session('resent'))
|
||||
<div class="alert alert-success border-0 shadow-sm rounded-3 mb-4" role="alert">
|
||||
{{ __('Um novo link de verificação foi enviado para o seu endereço de e-mail.') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<p class="lead text-muted mb-4">
|
||||
Antes de prosseguir, por favor verifique seu e-mail em busca do link de confirmação.
|
||||
Se você não recebeu o e-mail, clique no botão abaixo para solicitar outro.
|
||||
</p>
|
||||
|
||||
<form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary btn-lg px-5 py-3 fw-bold shadow-sm rounded-pill">
|
||||
Reenviar E-mail de Verificação
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user