forked from felipe.fontana/simples-painel
Felipe Fontana
10 months ago
14 changed files with 504 additions and 11 deletions
@ -0,0 +1,132 @@
|
||||
<?php |
||||
|
||||
namespace App\Http\Controllers\Admin; |
||||
|
||||
use App\Helpers\Helper; |
||||
use App\Http\Controllers\Controller; |
||||
use App\Models\NumberChannel; |
||||
use Illuminate\Http\Request; |
||||
use Illuminate\Support\Facades\Gate; |
||||
|
||||
class NumberChannelController extends Controller |
||||
{ |
||||
|
||||
public function __construct( |
||||
protected NumberChannel $numberChannelRepository, |
||||
) { |
||||
} |
||||
|
||||
public function index(Request $request) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('show_channels')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$id_empresa = Helper::getIdEmpresa(); |
||||
$search = strtolower($request->pesquisa); |
||||
$status = $request->status === "desativado" ? false : true; |
||||
|
||||
$channels = $this->numberChannelRepository->list(["id_empresa" => $id_empresa, "status" => $status, "search" => $search]); |
||||
|
||||
return view('admin.cadastros.channels', compact('channels', 'status', 'search')); |
||||
} |
||||
|
||||
public function store(Request $request) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('store_channels')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$request->validate([ |
||||
'name' => ['required'], |
||||
'id_empresa' => ['required'], |
||||
'number' => ['required'], |
||||
'token' => ['required'], |
||||
'channel' => ['required'], |
||||
'work_space' => ['required'], |
||||
'title' => ['required'], |
||||
]); |
||||
|
||||
|
||||
$status = $request->status === 'on' ? true : false; |
||||
$created = $this->numberChannelRepository->create($request->name, $request->id_empresa, $request->number, $request->token, $request->channel, $request->work_space, $request->title, $status); |
||||
if(!$created){ |
||||
return redirect()->back()->with('status', 'Erro ao tentar criar channel'); |
||||
} |
||||
|
||||
return redirect()->back()->with('status', ' Cadastrado com sucesso'); |
||||
} |
||||
|
||||
public function edit($id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('edit_channels')){ |
||||
abort(404); |
||||
} |
||||
|
||||
if (empty($id)) { |
||||
return redirect('channels'); |
||||
} |
||||
|
||||
$channelData = NumberChannel::find($id); |
||||
$response = [ |
||||
'status' => true, |
||||
'data' => $channelData |
||||
]; |
||||
|
||||
return response()->json($response); |
||||
} |
||||
|
||||
public function destroy($id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('destroy_channels')){ |
||||
abort(404); |
||||
} |
||||
|
||||
if (empty($id)) { |
||||
return redirect('channels'); |
||||
} |
||||
|
||||
NumberChannel::where('id', $id)->update([ |
||||
"status" => false |
||||
]); |
||||
|
||||
return redirect('channels')->with('status', 'desativado com sucesso'); |
||||
} |
||||
|
||||
public function update(Request $request, $id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('update_channels')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$request->validate([ |
||||
'name' => ['required'], |
||||
'id_empresa' => ['required'], |
||||
'number' => ['required'], |
||||
'token' => ['required'], |
||||
'channel' => ['required'], |
||||
'work_space' => ['required'], |
||||
'title' => ['required'], |
||||
]); |
||||
|
||||
$status = $request->status === "on" ? true : false; |
||||
|
||||
NumberChannel::where("id", $id)->update([ |
||||
'name' => $request->name, |
||||
'id_empresa' => $request->id_empresa, |
||||
'number' => $request->number, |
||||
'token' => $request->token, |
||||
'channel' => $request->channel, |
||||
'work_space' => $request->work_space, |
||||
'title' => $request->title, |
||||
'status' => $status, |
||||
]); |
||||
|
||||
return redirect('channels')->with('status', 'atualizado com sucesso'); |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
function atualizaChannel(id_channel) { |
||||
$.ajax({ |
||||
type: "get", |
||||
url: `channels/editar/${id_channel}`, |
||||
success: function ({ |
||||
data |
||||
}) { |
||||
const modal = document.querySelector('.modal-edit'); |
||||
modal.style.display = 'block'; |
||||
modal.querySelector('form').action = `/channels/editar/${data.id}`; |
||||
modal.querySelector("input[name='name']").value = data.name; |
||||
modal.querySelector("input[name='id_empresa']").value = data.id_empresa; |
||||
modal.querySelector("input[name='number']").value = data.number; |
||||
modal.querySelector("input[name='token']").value = data.token; |
||||
modal.querySelector("select[name='channel']").value = data.channel; |
||||
modal.querySelector("input[name='work_space']").value = data.work_space; |
||||
modal.querySelector("input[name='title']").value = data.title; |
||||
const containerCheckbox = modal.querySelector(".container-checkbox"); |
||||
if (!data.status) { |
||||
containerCheckbox.innerHTML = `<input type="radio" name="status" value="on"> <span class="mr-3 dark:text-gray-100">Sim</span>
|
||||
<input type="radio" name="status" value="off" checked> <span class="dark:text-gray-100">Não</span>` |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
function fecharModal() { |
||||
document.querySelector('.modal-edit').style.display = 'none'; |
||||
} |
@ -0,0 +1,95 @@
|
||||
<x-app-layout> |
||||
<div class="py-8 px-8"> |
||||
@if(session('status')) |
||||
<div class="w-full p-5 bg-blue-600 mb-5 text-white rounded uppercase font-bold text-lg"> |
||||
{{session('status')}} |
||||
</div> |
||||
@endif |
||||
<div class="header flex flex-col items-center gap-4 "> |
||||
<div class="flex justify-between items-center w-full mb-5"> |
||||
<h1 class=" text-gray-900 dark:text-gray-100 text-3xl font-bold text-center"> |
||||
Channels |
||||
</h1> |
||||
@can('store_channels') |
||||
<button class="bg-blue-500 hover:bg-opacity-90 transition-all text-white py-2 px-6 rounded text-base overflow-hidden" @click="modal = !modal" type="button">Cadastrar Channel</button> |
||||
@endcan |
||||
</div> |
||||
<form action="{{route('channels')}}" method="GET" class="flex w-full gap-3 flex-col lg:flex-row "> |
||||
<div class="search bg-white dark:bg-gray-800 rounded px-3 py-1 overflow-hidden"> |
||||
<i class="fas fa-search dark:text-gray-100"></i> |
||||
<input type="text" name="pesquisa" class="border-none bg-transparent focus:ring-transparent placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Pesquise channels" value="{{$search}}"> |
||||
</div> |
||||
<select class="border-none rounded overflow-hidden dark:bg-gray-800 dark:text-gray-100" name="status"> |
||||
@if($status) |
||||
<option value="ativo" selected>Ativos</option> |
||||
<option value="desativado">Desativados</option> |
||||
@else |
||||
<option value="ativo">Ativos</option> |
||||
<option value="desativado" selected>Desativados</option> |
||||
@endif |
||||
</select> |
||||
<button class="lg:ml-auto ml-0 bg-blue-900 hover:bg-opacity-90 transition-all text-white py-2 px-6 rounded text-lg overflow-hidden">Pesquisar</button> |
||||
</form> |
||||
</div> |
||||
<div class="body mt-4 overflow-auto rounded-lg shadow"> |
||||
<table class="w-full"> |
||||
<thead class="bg-gray-50 dark:bg-gray-700 dark:text-gray-100"> |
||||
<tr> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left pl-5">ID</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Nome</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left pl-5">ID Empresa</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Número</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Token</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Channel</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Workspace</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Título</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Status</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Ações</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
@foreach($channels as $channel) |
||||
<tr class="bg-white dark:bg-gray-800 dark:border-gray-600 border-b-2"> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100 pl-5">{{$channel->id}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->name}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100 pl-5">{{$channel->id_empresa}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->number}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->token}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->channel}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->work_space}}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$channel->title}}</td> |
||||
@if($channel->status) |
||||
<td class="p-3 text-sm text-green-500 font-bold">ATIVO</td> |
||||
@else |
||||
<td class="p-3 text-sm text-red-500 font-bold">DESATIVADO</td> |
||||
@endif |
||||
<td class="p-3 text-sm font-bold w-32"> |
||||
@can('edit_channels') |
||||
<button class="bg-blue-600 text-white p-2 rounded text-lg text-center w-full mb-2" onclick="atualizaChannel(<?= $channel->id ?>)" title="editar channel"><i class="fas fa-edit"></i></button>
|
||||
@endcan |
||||
|
||||
@if($channel->status) |
||||
@can('destroy_channels') |
||||
<form method="POST" id="formulario" action="channels/deletar/{{$channel->id}}" title="desativar channel" onclick="javascript: if(!confirm('Deseja desativar esse channel?')) return false;"> |
||||
@csrf |
||||
@method('delete') |
||||
<button class="bg-red-600 text-white p-2 rounded text-lg w-full"> |
||||
<i class="fas fa-ban"></i> |
||||
</button> |
||||
</form> |
||||
@endcan |
||||
@endif |
||||
</td> |
||||
</tr> |
||||
@endforeach |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</div> |
||||
|
||||
<x-modal.insert.modalChannels></x-modal> |
||||
<x-modal.edit.modalEditChannels></x-modalEditChannels> |
||||
|
||||
<script src="{{ asset('js/views/channels/atualizaChannel.js') }}"></script> |
||||
|
||||
</x-app-layout> |
@ -0,0 +1,66 @@
|
||||
<!-- Main modal --> |
||||
<div class="fixed z-50 hidden p-4 bg-gray-900 bg-opacity-60 h-full w-full modal-edit"> |
||||
<div class="fixed w-full max-w-2xl md:h-auto top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]"> |
||||
<!-- Modal content --> |
||||
<form method="POST" action="" class="relative bg-white rounded-lg shadow dark:bg-gray-700"> |
||||
|
||||
@csrf |
||||
<!-- Modal header --> |
||||
<div class="flex items-start justify-between border-b rounded-t dark:border-gray-600 px-3 py-4"> |
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-gray-100 pl-3"> |
||||
Atualizar channel |
||||
</h3> |
||||
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-xl ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" @click="modal = false" onclick="fecharModal()"> |
||||
<i class="fas fa-times"></i> |
||||
</button> |
||||
</div> |
||||
<!-- Modal body --> |
||||
<div class="p-6 space-y-6"> |
||||
<div class="flex flex-col gap-4"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Nome: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o nome: " name="name"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">ID Empresa: </label> |
||||
<input type="text" pattern="[0-9]*" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o id da empresa: " name="id_empresa"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Número: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o numero do canal: " name="number"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Token: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o token do canal: " name="token"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Channel: </label> |
||||
<select class="w-full dark:bg-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" name="channel"> |
||||
<option value="positus">Positus</option> |
||||
</select> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Workspace: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o numero do workspace: " name="work_space"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Título: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o titulo: " name="title"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<div> |
||||
<label for="" class="dark:text-gray-100 block">Ativo: </label> |
||||
<div class="container-checkbox"> |
||||
<input type="radio" name="status" checked value="on"> <span class="mr-3 dark:text-gray-100">Sim</span> |
||||
<input type="radio" name="status" value="off"> <span class="dark:text-gray-100">Não</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<!-- Modal footer --> |
||||
<div class="flex items-center space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600"> |
||||
<button type="submit" class="bg-blue-500 hover:bg-opacity-90 transition-all text-white py-2 px-6 rounded text-lg">Atualizar</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
@ -0,0 +1,64 @@
|
||||
<!-- Main modal --> |
||||
<div class="fixed z-50 hidden p-4 bg-gray-900 bg-opacity-60 h-full w-full modal-agentes" :class="{'block': modal, 'hidden': !modal}"> |
||||
<div class="fixed w-full max-w-2xl md:h-auto top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]"> |
||||
<!-- Modal content --> |
||||
<form method="POST" action="{{ route('channels') }}" class="relative bg-white rounded-lg shadow dark:bg-gray-700"> |
||||
|
||||
@csrf |
||||
<!-- Modal header --> |
||||
<div class="flex items-start justify-between border-b rounded-t dark:border-gray-600 px-3 py-4"> |
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-gray-100 pl-3"> |
||||
Cadastrar Channel |
||||
</h3> |
||||
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-xl ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" @click="modal = false"> |
||||
<i class="fas fa-times"></i> |
||||
</button> |
||||
</div> |
||||
<!-- Modal body --> |
||||
<div class="p-6 space-y-6"> |
||||
<div class="flex flex-col gap-4"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Nome: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 " placeholder="Informe o nome: " name="name" > |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">ID Empresa: </label> |
||||
<input type="text" pattern="[0-9]*" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Informe o id da empresa: " name="id_empresa"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Número: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Informe o numero do canal: " name="number"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Token: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Informe o token do canal: " name="token"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Channel: </label> |
||||
<select class="w-full dark:bg-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" name="channel"> |
||||
<option value="positus">Positus</option> |
||||
</select> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Workspace: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Informe o numero do workspace: " name="work_space"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label for="" class="dark:text-gray-100">Título: </label> |
||||
<input type="text" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Informe o titulo do canal: " name="title"> |
||||
</div> |
||||
<div> |
||||
<label for="" class="dark:text-gray-100 block">Ativo: </label> |
||||
<input type="radio" name="status" checked value="on"> <span class="mr-3 dark:text-gray-100">Sim</span> |
||||
<input type="radio" name="status" value="off"> <span class="dark:text-gray-100">Não</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<!-- Modal footer --> |
||||
<div class="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600"> |
||||
<button type="submit" class="bg-blue-500 hover:bg-opacity-90 transition-all text-white py-2 px-6 rounded text-lg">Cadastrar</button> |
||||
|
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
Loading…
Reference in new issue