Compare commits
No commits in common. "0518c06ebe32967e409a17db3306e0402f977813" and "3b4de82f9268617213ae83d32a265a2e1b028bd1" have entirely different histories.
0518c06ebe
...
3b4de82f92
|
|
@ -3,43 +3,53 @@
|
||||||
namespace App\Livewire\Admin;
|
namespace App\Livewire\Admin;
|
||||||
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Services\ClientService;
|
|
||||||
use App\Livewire\Forms\ClientForm; // 1. Importa seu Form Object
|
use App\Livewire\Forms\ClientForm; // 1. Importa seu Form Object
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithFileUploads;
|
use Livewire\WithFileUploads;
|
||||||
use Illuminate\Support\Facades\Crypt;
|
use Livewire\Attributes\On;
|
||||||
|
|
||||||
|
|
||||||
class AddClient extends Component
|
class AddClient extends Component
|
||||||
{
|
{
|
||||||
use WithFileUploads;
|
use WithFileUploads;
|
||||||
|
|
||||||
|
// 1. Declara as propriedades principais
|
||||||
public ClientForm $form;
|
public ClientForm $form;
|
||||||
public function save(ClientService $clientService)
|
/**
|
||||||
|
* Método principal chamado pelo wire:submit="save".
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Valida os dados usando as 'rules' do ClientForm.php
|
||||||
$this->form->validate();
|
$this->form->validate();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$data = $this->form->all();
|
$data = $this->form->all();
|
||||||
$data['name'] = $data['client_name'];
|
$data['name'] = $data['client_name'];
|
||||||
|
// 4. Lida com o upload do arquivo de imagem
|
||||||
|
|
||||||
if ($this->form->profile_image_path) {
|
if ($this->form->profile_image_path) {
|
||||||
$path = $this->form->profile_image_path->store('client_logos', 'public');
|
$path = $this->form->profile_image_path->store('client_logos', 'public');
|
||||||
$data['profile_image_path'] = $path;
|
$data['profile_image_path'] = $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['root_password'] = Crypt::encryptString($data['root_password']);
|
// 5. Cria o cliente no banco de dados
|
||||||
|
Client::create($data);
|
||||||
$clientService->addClient($data);
|
// 6. Despacha um evento para atualizar outros componentes (ex: o grid de clientes)
|
||||||
|
|
||||||
$this->dispatch('client-added');
|
$this->dispatch('client-added');
|
||||||
|
// (Opcional) Envia uma notificação de sucesso
|
||||||
$this->dispatch('notify', message: 'Cliente adicionado com sucesso!');
|
$this->dispatch('notify', message: 'Cliente adicionado com sucesso!');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
dd($e);
|
||||||
$this->dispatch('notify', message: 'Ocorreu um erro inesperado ao salvar.', type: 'error');
|
$this->dispatch('notify', message: 'Ocorreu um erro inesperado ao salvar.', type: 'error');
|
||||||
}
|
}
|
||||||
|
// 3. Pega todos os dados validados
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renderiza a view do modal.
|
||||||
|
*/
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.admin.add-client');
|
return view('livewire.admin.add-client');
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,27 @@
|
||||||
|
|
||||||
namespace App\Livewire\Admin;
|
namespace App\Livewire\Admin;
|
||||||
|
|
||||||
use App\Services\UserService;
|
use App\Services\UserService; // <-- Importe seu Service
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class CreateUser extends Component
|
class CreateUser extends Component
|
||||||
{
|
{
|
||||||
|
// 1. Propriedades públicas (os campos do formulário)
|
||||||
|
// Elas substituem o 'Request $request'
|
||||||
public string $name = '';
|
public string $name = '';
|
||||||
public string $email = '';
|
public string $email = '';
|
||||||
public string $password = '';
|
public string $password = '';
|
||||||
public string $password_confirm = '';
|
public string $password_confirm = ''; // <-- Você também precisa deste
|
||||||
public bool $permissions = false;
|
public bool $permission_level = false;
|
||||||
|
|
||||||
|
// 2. As regras de validação (copiadas do seu controller)
|
||||||
|
// Nota: Adicionei 'same:password' para garantir que as senhas batem.
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'name' => 'required|string|max:255',
|
'name' => 'required|string|max:255',
|
||||||
'email' => 'required|email|unique:users,email',
|
'email' => 'required|email|unique:users,email',
|
||||||
'password' => 'required|string|min:8',
|
'password' => 'required|string|min:8',
|
||||||
'password_confirm' => 'required|string|same:password',
|
'password_confirm' => 'required|string|same:password', // <-- Regra importante!
|
||||||
'permissions' => 'required|boolean'
|
'permission_level' => 'required|boolean' // ou 'required|in:0,1'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $messages = [
|
protected $messages = [
|
||||||
|
|
@ -28,32 +31,48 @@ class CreateUser extends Component
|
||||||
'email.unique' => 'O email informado já foi cadastrado anteriormente.',
|
'email.unique' => 'O email informado já foi cadastrado anteriormente.',
|
||||||
'password' => 'A senha precisa ter 8 ou mais caracteres.',
|
'password' => 'A senha precisa ter 8 ou mais caracteres.',
|
||||||
'password_confirm' => 'As senhas não coincidem.',
|
'password_confirm' => 'As senhas não coincidem.',
|
||||||
'permissions' => 'Defina o nível de autorização do usuário.',
|
'permission_level' => 'Defina o nível de autorização do usuário.'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* O método de "salvar", que substitui o seu 'createUsers'.
|
||||||
|
*
|
||||||
|
* Note como injetamos o UserService direto no método!
|
||||||
|
* O Livewire cuida disso para você, assim como o Laravel faz nos controllers.
|
||||||
|
*/
|
||||||
public function createUser(UserService $userService)
|
public function createUser(UserService $userService)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// 3. Valida as propriedades públicas ($this->name, $this->email, etc.)
|
||||||
$validated = $this->validate($this->rules, $this->messages);
|
$validated = $this->validate($this->rules, $this->messages);
|
||||||
|
// 4. Seu 'try...catch' - praticamente idêntico
|
||||||
if ($validated['permissions'] === true) {
|
|
||||||
$validated['permissions'] = array('admin');
|
|
||||||
} else {
|
|
||||||
$validated['permissions'] = array('user');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$this->authorize('createUser', Auth::user());
|
// 5. CHAMA O MESMO SERVICE! Nenhuma lógica de negócio é duplicada.
|
||||||
$user = $userService->createUser($validated);
|
$user = $userService->createUser($validated);
|
||||||
|
|
||||||
|
// 6. O "Sucesso" (Tradução do Redirect)
|
||||||
|
|
||||||
|
// Limpa o formulário
|
||||||
$this->reset();
|
$this->reset();
|
||||||
|
|
||||||
|
// Dispara um evento para o Alpine.js fechar o modal
|
||||||
$this->dispatch('user-created');
|
$this->dispatch('user-created');
|
||||||
|
|
||||||
|
// Envia a mesma mensagem de sucesso do seu controller
|
||||||
$this->dispatch('notify', message: 'Usuário cadastrado com sucesso!');
|
$this->dispatch('notify', message: 'Usuário cadastrado com sucesso!');
|
||||||
|
|
||||||
|
|
||||||
|
// (Opcional) Se sua tabela de usuários for outro componente Livewire,
|
||||||
|
// você pode mandar ela atualizar assim:
|
||||||
|
// $this->dispatch('refreshUserList');
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
// 7. O "Erro" (Tradução do Redirect de Erro)
|
||||||
|
// Em vez de redirecionar, adicionamos o erro ao formulário
|
||||||
|
// para que o usuário veja na tela, sem refresh.
|
||||||
|
|
||||||
$this->addError('general', $e->getMessage());
|
$this->addError('general', $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire\Admin;
|
|
||||||
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class ShowUsers extends Component
|
|
||||||
{
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.admin.show-users');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,6 @@ class User extends Authenticatable
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
'email',
|
'email',
|
||||||
'permissions',
|
|
||||||
'password',
|
'password',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public function register(): void
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
Gate::define('createUser', function (User $user) {
|
Gate::define('createUser', function (User $user) {
|
||||||
return isset($user->permissions) ? in_array('admin', $user->permissions) : false;
|
return $user->permissions;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Client;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
@ -21,7 +20,5 @@ public function run(): void
|
||||||
'email' => 'inglinesystemsadmin@inglinesystems.com.br',
|
'email' => 'inglinesystemsadmin@inglinesystems.com.br',
|
||||||
'password' => Hash::make('*Ingline.Sys#9420%SECURITY#')
|
'password' => Hash::make('*Ingline.Sys#9420%SECURITY#')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Client::factory()->create([]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ @layer components {
|
||||||
@apply absolute right-5;
|
@apply absolute right-5;
|
||||||
@apply rounded-xl;
|
@apply rounded-xl;
|
||||||
@apply max-w-7 max-h-7;
|
@apply max-w-7 max-h-7;
|
||||||
@apply shadow-md shadow-blue-400;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-list-items {
|
.profile-list-items {
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
|
|
@ -3,7 +3,6 @@
|
||||||
@section('content')
|
@section('content')
|
||||||
<livewire:admin.create-user />
|
<livewire:admin.create-user />
|
||||||
<livewire:admin.add-client />
|
<livewire:admin.add-client />
|
||||||
<livewire:admin.show-users />
|
|
||||||
|
|
||||||
<div class="container grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
<div class="container grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="{{ route('dashboard') }}">Início</a>
|
<a href="{{ route('dashboard') }}">Início</a>
|
||||||
<div class="nav-bar-logo">
|
<div class="nav-bar-logo">
|
||||||
<a href="{{ route('dashboard') }}">
|
<a href="{{ route('dashboard') }}">
|
||||||
<img src="{{ Vite::asset('resources/images/newlogo.png') }}" alt="Logo">
|
<img src="{{ Vite::asset('resources/images/logo.png') }}" alt="Logo">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -42,25 +42,8 @@
|
||||||
src="{{ Vite::asset('resources/images/avatar-nexus.svg') }}" alt="Avatar">
|
src="{{ Vite::asset('resources/images/avatar-nexus.svg') }}" alt="Avatar">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul class="profile-list-items" x-show="open" x-transition:enter.duration.300ms
|
<ul class="profile-list-items" x-show="open">
|
||||||
x-transition:leave.duration.300ms>
|
<h2 class="font-weight-bold text-center">Nexus</h2>
|
||||||
<h2 class="font-bold text-center" x-show="open" x-transition:enter="transition ease-out duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100"
|
|
||||||
x-transition:leave="transition ease-in duration-300"
|
|
||||||
x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90">Nexus
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<li class="profile-items">
|
|
||||||
<a href="" class="profile-link">
|
|
||||||
Início
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="profile-items">
|
|
||||||
<a @click="$dispatch('show-users')" class="profile-link">
|
|
||||||
Administração
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="profile-items">
|
<li class="profile-items">
|
||||||
<a @click="$dispatch('open-create-user')" class="profile-link">
|
<a @click="$dispatch('open-create-user')" class="profile-link">
|
||||||
|
|
@ -68,6 +51,18 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li class="profile-items">
|
||||||
|
<a href="" class="profile-link">
|
||||||
|
Visualizar Clientes
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="profile-items">
|
||||||
|
<a href="" class="profile-link">
|
||||||
|
Administração
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="profile-items">
|
<li class="profile-items">
|
||||||
<a @click="$dispatch('open-add-client')" class="profile-link">
|
<a @click="$dispatch('open-add-client')" class="profile-link">
|
||||||
Adicionar clientes
|
Adicionar clientes
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div x-data="{ showModal: false }" x-on:user-created.window="showModal = false"
|
<div x-data="{ showModal: false }" x-on:user-created.window="showModal = false"
|
||||||
x-on:open-create-user.window="showModal = true">
|
x-on:open-create-user.window="showModal = true">
|
||||||
|
|
||||||
<div x-show="showModal" class="modal-overlay" x-transition:enter.duration.300ms x-transition:leave.duration.300ms>
|
<div x-show="showModal" class="modal-overlay">
|
||||||
<div x-on:click.outside="showModal = false" x-show="showModal" x-transition:enter="transition-enter"
|
<div x-on:click.outside="showModal = false" x-show="showModal" x-transition:enter="transition-enter"
|
||||||
x-transition:enter-start="transition-enter-start" x-transition:enter-end="transition-enter-end"
|
x-transition:enter-start="transition-enter-start" x-transition:enter-end="transition-enter-end"
|
||||||
x-transition:leave="transition-leave" x-transition:leave-start="transition-leave-start"
|
x-transition:leave="transition-leave" x-transition:leave-start="transition-leave-start"
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
<div x-data="{
|
<div x-data="{
|
||||||
open: false,
|
open: false,
|
||||||
selected: @entangle('permissions'),
|
selected: @entangle('permission_level'),
|
||||||
options: { '0': 'Usuário', '1': 'Admin' }
|
options: { '0': 'Usuário', '1': 'Admin' }
|
||||||
}" x-on:click.outside="open = false" class="select-wrapper">
|
}" x-on:click.outside="open = false" class="select-wrapper">
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@error('permissions') <span class="error-text">{{ $message }}</span> @enderror
|
@error('permission_level') <span class="error-text">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-footer">
|
<div class="form-footer">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
<div x-data="{showUsers: false}" x-on:show-users.window="showUsers = true">
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h1>Bem vindo a página de criação dos usuários, <span style="background-color:rgb(89, 255, 255); border-radius: 0.3em; padding: 0.2em">{{Auth::user()->name}}!</span></h1>
|
||||||
|
|
||||||
|
<form action="{{ route('users.create') }}" method="POST" class="form-class">
|
||||||
|
@csrf
|
||||||
|
<input type="text" name="name" placeholder="Nome do usuário" class="form-input-class">
|
||||||
|
<input type="email" name="email" placeholder="Email do usuário" class="form-input-class">
|
||||||
|
<input type="password" name="password" placeholder="8 a 20 caracteres" class="form-input-class">
|
||||||
|
<button type="submit" class="form-button-class">Criar usuário</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endsection
|
||||||
Loading…
Reference in New Issue