First Commit

This commit is contained in:
marco
2026-09-01 09:22:30 -03:00
commit a43ae23eb4
407 changed files with 36138 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
@extends('layouts.app')
@section('header', 'Novo Provedor')
@section('breadcrumbs')
@php
$breadcrumbs = [
'Provedores' => route('ai-providers.index'),
'Novo' => null
];
@endphp
@endsection
@section('content')
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 fw-bold text-primary">Cadastrar Provedor</h6>
</div>
<div class="card-body">
<form method="POST" action="{{ route('ai-providers.store') }}">
@csrf
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control" id="name" name="name" value="{{ old('name') }}" required>
@error('name') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="slug" class="form-label">Slug</label>
<input type="text" class="form-control" id="slug" name="slug" value="{{ old('slug') }}" required>
@error('slug') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="type" class="form-label">Tipo</label>
<select class="form-select" id="type" name="type" required>
<option value="">Selecione...</option>
<option value="openrouter" {{ old('type') == 'openrouter' ? 'selected' : '' }}>OpenRouter</option>
<option value="stepfun" {{ old('type') == 'stepfun' ? 'selected' : '' }}>StepFun</option>
<option value="llamacpp" {{ old('type') == 'llamacpp' ? 'selected' : '' }}>Llama.cpp</option>
</select>
@error('type') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="api_key" class="form-label">API Key</label>
<input type="password" class="form-control" id="api_key" name="api_key" value="{{ old('api_key') }}" required>
<i class="bi bi-eye-slash" id="toggleApiKey" style="cursor:pointer; position:relative; top:-30px; left:calc(100% - 30px);"></i>
@error('api_key') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="base_url" class="form-label">Base URL</label>
<input type="text" class="form-control" id="base_url" name="base_url" value="{{ old('base_url') }}" required>
@error('base_url') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="is_active" name="is_active" value="1" {{ old('is_active', true) ? 'checked' : '' }}>
<label class="form-check-label" for="is_active">Ativo</label>
</div>
<button type="submit" class="btn btn-primary"><i class="bi bi-save"></i> Salvar</button>
<a href="{{ route('ai-providers.index') }}" class="btn btn-secondary">Cancelar</a>
</form>
</div>
</div>
@endsection
@section('scripts')
<script>
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
initApiKeyToggle();
initSlugGenerator();
});
} else {
initApiKeyToggle();
initSlugGenerator();
}
function initApiKeyToggle() {
const toggle = document.getElementById('toggleApiKey');
const input = document.getElementById('api_key');
if (toggle && input) {
toggle.addEventListener('click', function() {
const type = input.getAttribute('type') === 'password' ? 'text' : 'password';
input.setAttribute('type', type);
toggle.classList.toggle('bi-eye');
toggle.classList.toggle('bi-eye-slash');
});
}
}
function initSlugGenerator() {
const nameInput = document.getElementById('name');
const slugInput = document.getElementById('slug');
if (nameInput && slugInput) {
nameInput.addEventListener('input', function() {
slugInput.value = this.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
});
}
}
</script>
@endsection
+82
View File
@@ -0,0 +1,82 @@
@extends('layouts.app')
@section('header', 'Editar Provedor')
@section('breadcrumbs')
@php
$breadcrumbs = [
'Provedores' => route('ai-providers.index'),
'Editar' => null
];
@endphp
@endsection
@section('content')
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 fw-bold text-primary">Editar Provedor</h6>
</div>
<div class="card-body">
<form method="POST" action="{{ route('ai-providers.update', $aiProvider) }}">
@csrf @method('PUT')
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control" id="name" name="name" value="{{ old('name', $aiProvider->name) }}" required>
@error('name') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="type" class="form-label">Tipo</label>
<select class="form-select" id="type" name="type" required>
<option value="">Selecione...</option>
<option value="openrouter" {{ old('type', $aiProvider->type) == 'openrouter' ? 'selected' : '' }}>OpenRouter</option>
<option value="stepfun" {{ old('type', $aiProvider->type) == 'stepfun' ? 'selected' : '' }}>StepFun</option>
<option value="llamacpp" {{ old('type', $aiProvider->type) == 'llamacpp' ? 'selected' : '' }}>Llama.cpp</option>
</select>
@error('type') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="api_key" class="form-label">API Key</label>
<input type="password" class="form-control" id="api_key" name="api_key" value="{{ old('api_key', $aiProvider->api_key) }}" required>
<i class="bi bi-eye-slash" id="toggleApiKey" style="cursor:pointer; position:relative; top:-30px; left:calc(100% - 30px);"></i>
@error('api_key') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3">
<label for="base_url" class="form-label">Base URL</label>
<input type="text" class="form-control" id="base_url" name="base_url" value="{{ old('base_url', $aiProvider->base_url) }}" required>
@error('base_url') <div class="text-danger small">{{ $message }}</div> @enderror
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="is_active" name="is_active" value="1" {{ old('is_active', $aiProvider->is_active) ? 'checked' : '' }}>
<label class="form-check-label" for="is_active">Ativo</label>
</div>
<button type="submit" class="btn btn-primary"><i class="bi bi-save"></i> Atualizar</button>
<a href="{{ route('ai-providers.index') }}" class="btn btn-secondary">Cancelar</a>
</form>
</div>
</div>
@endsection
@section('scripts')
<script>
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
initApiKeyToggle();
});
} else {
initApiKeyToggle();
}
function initApiKeyToggle() {
const toggle = document.getElementById('toggleApiKey');
const input = document.getElementById('api_key');
if (toggle && input) {
toggle.addEventListener('click', function() {
const type = input.getAttribute('type') === 'password' ? 'text' : 'password';
input.setAttribute('type', type);
toggle.classList.toggle('bi-eye');
toggle.classList.toggle('bi-eye-slash');
});
}
}
</script>
@endsection
+70
View File
@@ -0,0 +1,70 @@
@extends('layouts.app')
@section('header', 'Provedores de IA')
@section('breadcrumbs')
@php
$breadcrumbs = [
'Provedores' => route('ai-providers.index')
];
@endphp
@endsection
@section('content')
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 fw-bold text-primary">Lista de Provedores</h6>
<a href="{{ route('ai-providers.create') }}" class="btn btn-primary btn-sm">
<i class="bi bi-plus-circle"></i> Novo Provedor
</a>
</div>
<div class="card-body">
@if(isset($providers) && count($providers) > 0)
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Nome</th>
<th>Tipo</th>
<th>Status</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
@foreach($providers as $provider)
<tr>
<td>{{ $provider->name }}</td>
<td>{{ $provider->type ?? 'N/A' }}</td>
<td>
<span class="badge bg-{{ $provider->is_active ? 'success' : 'secondary' }}">
{{ $provider->is_active ? 'Ativo' : 'Inativo' }}
</span>
</td>
<td>
<a href="{{ route('ai-providers.show', $provider) }}" class="btn btn-info btn-sm">
<i class="bi bi-eye"></i>
</a>
<a href="{{ route('ai-providers.edit', $provider) }}" class="btn btn-warning btn-sm">
<i class="bi bi-pencil"></i>
</a>
<form action="{{ route('ai-providers.destroy', $provider) }}" method="POST" class="d-inline" onsubmit="return confirm('Tem certeza?')">
@csrf @method('DELETE')
<button class="btn btn-danger btn-sm"><i class="bi bi-trash"></i></button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@if(is_object($providers) && method_exists($providers, 'links'))
<div class="mt-3">
{{ $providers->links() }}
</div>
@endif
@else
<p class="text-muted">Nenhum provedor encontrado.</p>
@endif
</div>
</div>
@endsection
+51
View File
@@ -0,0 +1,51 @@
@extends('layouts.app')
@section('header', $aiProvider->name)
@section('breadcrumbs')
@php
$breadcrumbs = [
'Provedores' => route('ai-providers.index'),
$aiProvider->name => null
];
@endphp
@endsection
@section('content')
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 fw-bold text-primary">Detalhes do Provedor</h6>
<div>
<a href="{{ route('ai-providers.edit', $aiProvider) }}" class="btn btn-warning btn-sm me-2">
<i class="bi bi-pencil"></i> Editar
</a>
<form action="{{ route('ai-providers.destroy', $aiProvider) }}" method="POST" class="d-inline" onsubmit="return confirm('Tem certeza?')">
@csrf @method('DELETE')
<button class="btn btn-danger btn-sm"><i class="bi bi-trash"></i> Excluir</button>
</form>
</div>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">Nome</dt>
<dd class="col-sm-9">{{ $aiProvider->name }}</dd>
<dt class="col-sm-3">Descrição</dt>
<dd class="col-sm-9">{{ $aiProvider->description ?: '-' }}</dd>
<dt class="col-sm-3">Base URL</dt>
<dd class="col-sm-9">{{ $aiProvider->base_url }}</dd>
<dt class="col-sm-3">Status</dt>
<dd class="col-sm-9">
<span class="badge bg-{{ $aiProvider->is_active ? 'success' : 'secondary' }}">
{{ $aiProvider->is_active ? 'Ativo' : 'Inativo' }}
</span>
</dd>
<dt class="col-sm-3">Criado em</dt>
<dd class="col-sm-9">{{ $aiProvider->created_at->format('d/m/Y H:i') }}</dd>
</dl>
</div>
</div>
@endsection