First Commit

This commit is contained in:
marco
2026-09-01 10:46:29 -03:00
commit bf96b77e9c
10000 changed files with 3508600 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">{% if banner.affiliate_banners_id %}Editar Banner{% else %}Criar Novo Banner{% endif %}</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item"><a href="/admin/affiliatesadmin/affiliates">Afiliados</a></li>
<li class="breadcrumb-item"><a href="/admin/affiliatesadmin/banners">Banners</a></li>
<li class="breadcrumb-item active">{% if banner.affiliate_banners_id %}Editar{% else %}Novo{% endif %}</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="card mb-4">
<div class="card-header">
<i class="bi bi-image me-1"></i>
Formulário de Banner
</div>
<div class="card-body">
<form action="{% if banner.affiliate_banners_id %}/admin/affiliatesadmin/banners/{{ banner.affiliate_banners_id }}/update{% else %}/admin/affiliatesadmin/banners/store{% endif %}" method="POST" enctype="multipart/form-data">
<div class="mb-3">
<label for="affiliate_banners_name" class="form-label">Nome:</label>
<input type="text" class="form-control" id="affiliate_banners_name" name="affiliate_banners_name" value="{{ banner.affiliate_banners_name ?? '' }}" required>
</div>
<div class="mb-3">
<label for="affiliate_banners_description" class="form-label">Descrição:</label>
<textarea class="form-control" id="affiliate_banners_description" name="affiliate_banners_description" rows="2">{{ banner.affiliate_banners_description ?? '' }}</textarea>
</div>
<div class="mb-3">
<label for="banner_file" class="form-label">Arquivo do Banner:</label>
<input type="file" class="form-control" id="banner_file" name="banner_file" {% if not banner.affiliate_banners_id %}required{% endif %}>
<div class="form-text text-muted">Selecione uma imagem para o banner (JPG, PNG, GIF).</div>
{% if banner.affiliate_banners_image_url %}
<div class="mt-2">
<p class="small mb-1">Banner Atual:</p>
<img src="/storage/uploads/affiliatesadmin/{{ banner.affiliate_banners_image_url }}" alt="Banner Atual" class="img-thumbnail" style="max-height: 150px;">
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="affiliate_banners_target_url" class="form-label">URL de Destino:</label>
<input type="url" class="form-control" id="affiliate_banners_target_url" name="affiliate_banners_target_url" value="{{ banner.affiliate_banners_target_url ?? '' }}">
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="affiliate_banners_width" class="form-label">Largura (px):</label>
<input type="number" class="form-control" id="affiliate_banners_width" name="affiliate_banners_width" value="{{ banner.affiliate_banners_width ?? '' }}">
</div>
<div class="col-md-6 mb-3">
<label for="affiliate_banners_height" class="form-label">Altura (px):</label>
<input type="number" class="form-control" id="affiliate_banners_height" name="affiliate_banners_height" value="{{ banner.affiliate_banners_height ?? '' }}">
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="affiliate_banners_is_active" name="affiliate_banners_is_active" value="1" {% if banner.affiliate_banners_is_active ?? true %}checked{% endif %}>
<label class="form-check-label" for="affiliate_banners_is_active">Banner Ativo</label>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="bi bi-save"></i> Salvar
</button>
<a href="/admin/affiliatesadmin/banners" class="btn btn-secondary">
<i class="bi bi-arrow-left"></i> Cancelar
</a>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
+90
View File
@@ -0,0 +1,90 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">Gerenciamento de Banners</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item"><a href="/admin/affiliatesadmin/affiliates">Afiliados</a></li>
<li class="breadcrumb-item active">Banners</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="card mb-4">
<div class="card-header d-flex align-items-center justify-content-between">
<div>
<i class="bi bi-image me-1"></i>
Lista de Banners
</div>
<a href="/admin/affiliatesadmin/banners/create" class="btn btn-primary btn-sm">
<i class="bi bi-plus-lg"></i> Novo Banner
</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Imagem</th>
<th>URL de Destino</th>
<th>Ativo</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
{% for banner in banners %}
<tr>
<td>{{ banner.affiliate_banners_id }}</td>
<td>{{ banner.affiliate_banners_name }}</td>
<td>
<a href="/storage/uploads/affiliatesadmin/{{ banner.affiliate_banners_image_url }}" data-lightbox="banner-{{ banner.affiliate_banners_id }}">
<img src="/storage/uploads/affiliatesadmin/{{ banner.affiliate_banners_image_url }}" alt="{{ banner.affiliate_banners_name }}" class="img-thumbnail" style="max-width: 80px;">
</a>
</td>
<td>
<a href="{{ banner.affiliate_banners_target_url }}" target="_blank" class="text-truncate d-inline-block" style="max-width: 200px;">
{{ banner.affiliate_banners_target_url }}
</a>
</td>
<td>
<span class="badge bg-{{ banner.affiliate_banners_is_active ? 'success' : 'secondary' }}">
{{ banner.affiliate_banners_is_active ? 'Sim' : 'Não' }}
</span>
</td>
<td>
<div class="btn-group" role="group">
<a href="/admin/affiliatesadmin/banners/{{ banner.affiliate_banners_id }}/edit" class="btn btn-info btn-sm" title="Editar">
<i class="bi bi-pencil"></i>
</a>
<form action="/admin/affiliatesadmin/banners/{{ banner.affiliate_banners_id }}/delete" method="POST" onsubmit="return confirm('Tem certeza que deseja excluir este banner?')">
<button type="submit" class="btn btn-danger btn-sm" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(document).ready(function() {
$('#dataTable').DataTable({
language: {
url: '//cdn.datatables.net/plug-ins/1.13.7/i18n/pt-BR.json'
},
order: [[0, 'desc']]
});
});
</script>
{% endblock %}
+95
View File
@@ -0,0 +1,95 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">Gerenciamento de Comissões</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item"><a href="/admin/affiliatesadmin/affiliates">Afiliados</a></li>
<li class="breadcrumb-item active">Comissões</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="card mb-4">
<div class="card-header">
<i class="bi bi-currency-dollar me-1"></i>
Lista de Comissões
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>Afiliado</th>
<th>ID do Pedido</th>
<th>Valor</th>
<th>Taxa (%)</th>
<th>Status</th>
<th>Notas</th>
<th>Data</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
{% for commission in commissions %}
<tr>
<td>{{ commission.affiliate_commissions_id }}</td>
<td>{{ commission.affiliate.affiliates_name ?? 'N/A' }} <br><small class="text-muted">({{ commission.affiliate.affiliates_code ?? 'N/A' }})</small></td>
<td>{{ commission.affiliate_commissions_order_id ?? 'N/A' }}</td>
<td>R$ {{ commission.affiliate_commissions_amount|number_format(2, ',', '.') }}</td>
<td>{{ commission.affiliate_commissions_commission_rate }}%</td>
<td>
{% set statusColors = {
'pending': 'warning',
'approved': 'success',
'rejected': 'danger',
'paid': 'info'
} %}
<span class="badge bg-{{ statusColors[commission.affiliate_commissions_status] ?? 'secondary' }}">
{{ commission.affiliate_commissions_status }}
</span>
</td>
<td>{{ commission.affiliate_commissions_notes ?? 'N/A' }}</td>
<td>{{ commission.created_at|date("d/m/Y H:i") }}</td>
<td>
{% if commission.affiliate_commissions_status == 'pending' %}
<div class="btn-group" role="group">
<form action="/admin/affiliatesadmin/commissions/{{ commission.affiliate_commissions_id }}/approve" method="POST">
<button type="submit" class="btn btn-success btn-sm" title="Aprovar">
<i class="bi bi-check-lg"></i>
</button>
</form>
<form action="/admin/affiliatesadmin/commissions/{{ commission.affiliate_commissions_id }}/reject" method="POST">
<button type="submit" class="btn btn-warning btn-sm" title="Rejeitar">
<i class="bi bi-x-lg"></i>
</button>
</form>
</div>
{% else %}
<span class="text-muted small">Processado</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(document).ready(function() {
$('#dataTable').DataTable({
language: {
url: '//cdn.datatables.net/plug-ins/1.13.7/i18n/pt-BR.json'
},
order: [[0, 'desc']]
});
});
</script>
{% endblock %}
+90
View File
@@ -0,0 +1,90 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">{% if affiliate.affiliates_id %}Editar Afiliado{% else %}Criar Novo Afiliado{% endif %}</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item"><a href="/admin/affiliatesadmin/affiliates">Afiliados</a></li>
<li class="breadcrumb-item active">{% if affiliate.affiliates_id %}Editar{% else %}Novo{% endif %}</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="card mb-4">
<div class="card-header">
<i class="bi bi-person-plus me-1"></i>
Formulário de Afiliado
</div>
<div class="card-body">
<form action="{% if affiliate.affiliates_id %}/admin/affiliatesadmin/{{ affiliate.affiliates_id }}/update{% else %}/admin/affiliatesadmin/store{% endif %}" method="POST">
<div class="row">
<div class="col-md-6 mb-3">
<label for="affiliates_name" class="form-label">Nome:</label>
<input type="text" class="form-control" id="affiliates_name" name="affiliates_name" value="{{ affiliate.affiliates_name ?? '' }}" required>
</div>
<div class="col-md-6 mb-3">
<label for="affiliates_email" class="form-label">Email:</label>
<input type="email" class="form-control" id="affiliates_email" name="affiliates_email" value="{{ affiliate.affiliates_email ?? '' }}" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="affiliates_phone" class="form-label">Telefone:</label>
<input type="text" class="form-control" id="affiliates_phone" name="affiliates_phone" value="{{ affiliate.affiliates_phone ?? '' }}">
</div>
{% if not affiliate.affiliates_id %}
<div class="col-md-6 mb-3">
<label for="password" class="form-label">Senha do Usuário:</label>
<input type="password" class="form-control" id="password" name="password">
<div class="form-text text-muted">Obrigatória apenas para novos cadastros. Se o e-mail já existir no sistema, esta senha será ignorada e o usuário será vinculado.</div>
</div>
{% else %}
<div class="col-md-6 mb-3">
<label for="affiliates_website" class="form-label">Website:</label>
<input type="url" class="form-control" id="affiliates_website" name="affiliates_website" value="{{ affiliate.affiliates_website ?? '' }}">
</div>
{% endif %}
</div>
{% if not affiliate.affiliates_id %}
<div class="mb-3">
<label for="affiliates_website" class="form-label">Website:</label>
<input type="url" class="form-control" id="affiliates_website" name="affiliates_website" value="{{ affiliate.affiliates_website ?? '' }}">
</div>
{% endif %}
<div class="mb-3">
<label for="affiliates_address" class="form-label">Endereço:</label>
<textarea class="form-control" id="affiliates_address" name="affiliates_address" rows="3">{{ affiliate.affiliates_address ?? '' }}</textarea>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="affiliates_commission_rate" class="form-label">Taxa de Comissão (%):</label>
<input type="number" step="0.01" class="form-control" id="affiliates_commission_rate" name="affiliates_commission_rate" value="{{ affiliate.affiliates_commission_rate ?? '10.00' }}" required>
</div>
<div class="col-md-6 mb-3">
<label for="affiliates_status" class="form-label">Status:</label>
<select class="form-select" id="affiliates_status" name="affiliates_status" required>
<option value="active" {% if affiliate.affiliates_status ?? '' == 'active' %}selected{% endif %}>Ativo</option>
<option value="pending" {% if affiliate.affiliates_status ?? '' == 'pending' %}selected{% endif %}>Pendente</option>
<option value="suspended" {% if affiliate.affiliates_status ?? '' == 'suspended' %}selected{% endif %}>Suspenso</option>
</select>
</div>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="bi bi-save"></i> Salvar
</button>
<a href="/admin/affiliatesadmin/affiliates" class="btn btn-secondary">
<i class="bi bi-arrow-left"></i> Cancelar
</a>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
+83
View File
@@ -0,0 +1,83 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">Gerenciamento de Afiliados</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item active">Afiliados</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="card mb-4">
<div class="card-header">
<i class="bi bi-people me-1"></i>
Lista de Afiliados
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Email</th>
<th>Código</th>
<th>Comissão</th>
<th>Status</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
{% for affiliate in affiliates %}
<tr>
<td>{{ affiliate.affiliates_id }}</td>
<td>{{ affiliate.affiliates_name }}</td>
<td>{{ affiliate.affiliates_email }}</td>
<td><span class="badge bg-secondary">{{ affiliate.affiliates_code }}</span></td>
<td>{{ affiliate.affiliates_commission_rate }}%</td>
<td>
{% set statusColors = {
'active': 'success',
'pending': 'warning',
'suspended': 'danger'
} %}
<span class="badge bg-{{ statusColors[affiliate.affiliates_status] ?? 'secondary' }}">
{{ affiliate.affiliates_status }}
</span>
</td>
<td>
<div class="btn-group" role="group">
<a href="/admin/affiliatesadmin/{{ affiliate.affiliates_id }}/edit" class="btn btn-info btn-sm" title="Editar">
<i class="bi bi-pencil"></i>
</a>
<form action="/admin/affiliatesadmin/{{ affiliate.affiliates_id }}/delete" method="POST" onsubmit="return confirm('Tem certeza que deseja excluir este afiliado?')">
<button type="submit" class="btn btn-danger btn-sm" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(document).ready(function() {
$('#dataTable').DataTable({
language: {
url: '//cdn.datatables.net/plug-ins/1.13.7/i18n/pt-BR.json'
},
order: [[0, 'desc']]
});
});
</script>
{% endblock %}
+19
View File
@@ -0,0 +1,19 @@
<div class="mb-4 d-print-none">
<div class="btn-group flex-wrap" role="group" aria-label="Navegação de Afiliados">
<a href="/admin/affiliatesadmin/statistics" class="btn btn-outline-primary">
<i class="bi bi-speedometer2"></i> Dashboard
</a>
<a href="/admin/affiliatesadmin/affiliates" class="btn btn-outline-primary">
<i class="bi bi-people"></i> Afiliados
</a>
<a href="/admin/affiliatesadmin/commissions" class="btn btn-outline-primary">
<i class="bi bi-currency-dollar"></i> Comissões
</a>
<a href="/admin/affiliatesadmin/banners" class="btn btn-outline-primary">
<i class="bi bi-image"></i> Banners
</a>
<a href="/admin/affiliatesadmin/create" class="btn btn-primary">
<i class="bi bi-plus-lg"></i> Novo Afiliado
</a>
</div>
</div>
+39
View File
@@ -0,0 +1,39 @@
{% extends "layouts/dashboard.twig" %}
{% block title %}{{ affiliate.name }} - {{ __("affiliatesadmin.affiliate_details") }}{% endblock %}
{% block content %}
<div class="card">
<div class="card-header">
<h3 class="card-title">{{ affiliate.name }}</h3>
<div class="card-tools">
<a href="/admin/affiliatesadmin/{{ affiliate.id }}/edit" class="btn btn-sm btn-primary">
<i class="fas fa-edit"></i> {{ __("affiliatesadmin.edit") }}
</a>
<a href="/admin/affiliatesadmin" class="btn btn-sm btn-secondary">
<i class="fas fa-list"></i> {{ __("affiliatesadmin.back_to_list") }}
</a>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>{{ __("affiliatesadmin.affiliate_code") }}:</strong> {{ affiliate.affiliate_code }}</p>
<p><strong>{{ __("affiliatesadmin.name") }}:</strong> {{ affiliate.name }}</p>
<p><strong>{{ __("affiliatesadmin.email") }}:</strong> {{ affiliate.email }}</p>
<p><strong>{{ __("affiliatesadmin.phone") }}:</strong> {{ affiliate.phone }}</p>
<p><strong>{{ __("affiliatesadmin.address") }}:</strong> {{ affiliate.address }}</p>
<p><strong>{{ __("affiliatesadmin.website") }}:</strong> {{ affiliate.website }}</p>
</div>
<div class="col-md-6">
<p><strong>{{ __("affiliatesadmin.commission_rate") }}:</strong> {{ affiliate.commission_rate }}%</p>
<p><strong>{{ __("affiliatesadmin.total_earned") }}:</strong> {{ affiliate.total_earned|number_format(2, ',', '.') }}</p>
<p><strong>{{ __("affiliatesadmin.total_paid") }}:</strong> {{ affiliate.total_paid|number_format(2, ',', '.') }}</p>
<p><strong>{{ __("affiliatesadmin.status") }}:</strong> {{ affiliate.status }}</p>
<p><strong>{{ __("affiliatesadmin.created_at") }}:</strong> {{ affiliate.created_at|date("d/m/Y H:i") }}</p>
<p><strong>{{ __("affiliatesadmin.updated_at") }}:</strong> {{ affiliate.updated_at|date("d/m/Y H:i") }}</p>
</div>
</div>
</div>
</div>
{% endblock %}
+103
View File
@@ -0,0 +1,103 @@
{% extends "layouts/dashboard.twig" %}
{% block content %}
<div class="container-fluid px-4">
<h1 class="mt-4">Estatísticas de Afiliados</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/admin/dashboard">Dashboard</a></li>
<li class="breadcrumb-item active">Estatísticas</li>
</ol>
{% include '@affiliatesadmin/nav.twig' %}
<div class="row">
<div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white mb-4">
<div class="card-body">Total de Afiliados</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<h4 class="mb-0">{{ stats.total_affiliates ?? 0 }}</h4>
<i class="bi bi-people-fill fs-2 opacity-50"></i>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-success text-white mb-4">
<div class="card-body">Comissões Aprovadas</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<h4 class="mb-0">R$ {{ stats.total_commissions_approved ?? 0|number_format(2, ',', '.') }}</h4>
<i class="bi bi-cash-stack fs-2 opacity-50"></i>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-warning text-white mb-4">
<div class="card-body">Cliques nos Banners</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<h4 class="mb-0">{{ stats.total_clicks ?? 0 }}</h4>
<i class="bi bi-mouse2 fs-2 opacity-50"></i>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-info text-white mb-4">
<div class="card-body">Conversão Média</div>
<div class="card-footer d-flex align-items-center justify-content-between">
<h4 class="mb-0">{{ stats.conversion_rate ?? 0 }}%</h4>
<i class="bi bi-graph-up-arrow fs-2 opacity-50"></i>
</div>
</div>
</div>
</div>
<div class="card mb-4">
<div class="card-header">
<i class="bi bi-graph-up me-1"></i>
Gráfico de Ganhos por Mês
</div>
<div class="card-body">
<canvas id="myAreaChart" width="100%" height="40"></canvas>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var ctx = document.getElementById("myAreaChart");
if (ctx) {
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
datasets: [{
label: "Comissões (R$)",
lineTension: 0.3,
backgroundColor: "rgba(78, 115, 223, 0.05)",
borderColor: "rgba(78, 115, 223, 1)",
pointRadius: 3,
pointBackgroundColor: "rgba(78, 115, 223, 1)",
pointBorderColor: "rgba(78, 115, 223, 1)",
pointHoverRadius: 3,
pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
pointHoverBorderColor: "rgba(78, 115, 223, 1)",
pointHitRadius: 10,
pointBorderWidth: 2,
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Dados reais viriam do controller
}],
},
options: {
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
});
</script>
{% endblock %}