Browse Source

Att: Adicionando funcao de mensagens rápidas

Matheus
Felipe Fontana 7 months ago
parent
commit
a9b8de1a1a
  1. 147
      app/Http/Controllers/Admin/QuickMessageController.php
  2. 38
      app/Models/QuickMessage.php
  3. 4
      public/js/views/systemMessages/cadastroSystemMessage.js
  4. 83
      resources/views/admin/cadastros/quickMessage.blade.php
  5. 80
      resources/views/components/modal/edit/modalEditQuickMessage.blade.php
  6. 47
      resources/views/components/modal/insert/modalQuickMessage.blade.php
  7. 9
      resources/views/layouts/menu.blade.php
  8. 2
      routes/web.php

147
app/Http/Controllers/Admin/QuickMessageController.php

@ -0,0 +1,147 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\QuickMessage;
use App\Models\NumberChannel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator;
class QuickMessageController extends Controller
{
public function __construct(
protected QuickMessage $quickMessageRepository,
protected NumberChannel $numberChannelRepository,
) {
}
public function index(Request $request)
{
$user = auth()->user();
if(Gate::forUser($user)->denies('show_quick_messages')){
abort(404);
}
$search = $request->channel;
$id_empresa = Helper::getIdEmpresa();
$channels = $this->numberChannelRepository->list(['id_empresa' => $id_empresa]);
$quickMessages = $this->quickMessageRepository->list(['id_empresa' => $id_empresa, 'id_number' => $search]);
return view('admin.cadastros.quickMessage', compact('quickMessages', 'channels', 'search'));
}
public function store(Request $request)
{
$user = auth()->user();
if(Gate::forUser($user)->denies('store_quick_messages')){
abort(404);
}
$validator = Validator::make($request->all(), [
'channel' => 'required',
'atalho' => [
'required',
function ($attribute, $value, $fail) {
if ($value[0] != '@') {
$fail("É necessário que o atalho começe com @.");
}
},
],
'texto' => 'required',
], [
'required' => 'É preciso informar o campo :attribute.'
]);
if ($validator->fails()) {
return redirect()->back()->with('error', $validator->errors()->first());
}
QuickMessage::create([
'atalho' => $request->atalho,
'texto' => $request->texto,
'id_number' => $request->channel
]);
return redirect('quick_messages');
}
public function edit($id)
{
$user = auth()->user();
if(Gate::forUser($user)->denies('update_quick_messages')){
abort(404);
}
if (empty($id)) {
return redirect('quick_messages');
}
$quickMessage = QuickMessage::find($id);
$id_empresa = Helper::getIdEmpresa();
$channels = $this->numberChannelRepository->list(['id_empresa' => $id_empresa]);
$response = [
'data' => [
'status' => true,
'quickMessage' => $quickMessage,
'channels' => $channels,
],
];
return response()->json($response);
}
public function update(Request $request, $id)
{
$user = auth()->user();
if(Gate::forUser($user)->denies('update_quick_messages')){
abort(404);
}
$validator = Validator::make($request->all(), [
'channel' => 'required',
'atalho' => [
'required',
function ($attribute, $value, $fail) {
if ($value[0] != '@') {
$fail("É necessário que o atalho começe com @.");
}
},
],
'texto' => 'required',
], [
'required' => 'É preciso informar o campo :attribute.'
]);
if ($validator->fails()) {
return redirect()->back()->with('error', $validator->errors()->first());
}
QuickMessage::where("id", $id)
->update([
'atalho' => $request->atalho,
'texto' => $request->texto,
'id_number' => $request->channel
]);
return redirect('quick_messages')->with('status', 'atualizado com sucesso');
}
public function destroy($id)
{
$user = auth()->user();
if(Gate::forUser($user)->denies('destroy_quick_messages')){
abort(404);
}
QuickMessage::where("id", $id)
->delete();
return redirect('quick_messages')->with('status', 'deletado com sucesso');
}
}

38
app/Models/QuickMessage.php

@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class QuickMessage extends Model
{
use HasFactory;
public $timestamps = false;
protected $table = "quick_message";
protected $fillable = [
'atalho',
'texto',
'id_number',
'data_reg'
];
public function list(array $params)
{
$messages = DB::table('quick_message as qm')
->join('number_channel as nc', 'qm.id_number', '=', 'nc.id')
->select('qm.*');
if(isset($params['id_empresa'])){
$messages->where('nc.id_empresa', $params['id_empresa']);
}
if(isset($params['id_number'])){
$messages->where('qm.id_number', $params['id_number']);
}
return $messages->get();
}
}

4
public/js/views/systemMessages/cadastroSystemMessage.js

@ -20,7 +20,7 @@ const valueEspacamento = 50;
const inputs = document.querySelectorAll('.autoCompleteInput');
inputs.forEach(input => {
input.addEventListener('input', (e) => {
input.addEventListener('input', (e) => {
let cont = 0;
fechaBox();
let selectedTexts = '';
@ -57,7 +57,7 @@ input.addEventListener('input', (e) => {
abreBox();
}
}
});
});
});
function selecionaMessage({ target }) {

83
resources/views/admin/cadastros/quickMessage.blade.php

@ -0,0 +1,83 @@
<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
@if(session('error'))
<div class="w-full p-5 bg-red-600 mb-5 text-white rounded uppercase font-bold text-lg">
{{session('error')}}
</div>
@endif
<div class="header flex flex-col items-center gap-4 mt-2 mb-8">
<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">
Mensagens Rápidas
</h1>
@can('store_quick_messages')
<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 Mensagens</button>
@endcan
</div>
<form action="{{route('quick_messages.index')}}" method="GET" class="flex w-full gap-3 flex-col lg:flex-row ">
<div class="flex-1 flex flex-col gap-1">
<label class="text-gray-900 dark:text-gray-100" >Canal: </label>
<select class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" id="channel" name="channel" style="width: 300px;">
<option value="">-----------------</option>
@foreach($channels as $channel)
<option value="{{ $channel->id}}" {{ !empty($search) && ($channel->id == $search) ? 'selected' : '' }}>
{{ $channel->title }}
</option>
@endforeach
</select>
</div>
<div class="flex-1 flex flex-col gap-1" style="background-color: transparent; margin-top: 25px;">
<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>
</div>
</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 ">ID</th>
<th class="p-3 text-sm font-semibold tracking-wide text-left">Atalho</th>
<th class="p-3 text-sm font-semibold tracking-wide text-left">Texto</th>
<th class="p-3 text-sm font-semibold tracking-wide text-left">Canal</th>
<th class="p-3 text-sm font-semibold tracking-wide text-left">Ações</th>
</tr>
</thead>
<tbody>
@foreach($quickMessages as $quickMessage)
<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">{{$quickMessage->id}}</td>
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$quickMessage->atalho}}</td>
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$quickMessage->texto}}</td>
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{$quickMessage->id_number}}</td>
<td class="p-3 text-sm font-bold flex-wrap w-32">
@can('update_quick_messages')
<button class="bg-blue-600 text-white p-2 rounded text-lg w-full mb-2" title="editar mensagem" onclick="atualizaQuickMessage(<?= $quickMessage->id ?>)"><i class="fas fa-edit"></i></button>
@endcan
@can('destroy_quick_messages')
<form method="POST" action="{{ route('quick_messages.destroy', ['quick_message' => $quickMessage->id]) }}" class="w-full flex" title="desativar mensagem" onclick="javascript: if(!confirm('Deseja deletar esses dados?')) return false;">
@csrf
@method('delete')
<button class="bg-red-600 text-white p-2 rounded text-lg w-full">
<i class="fas fa-trash"></i>
</button>
</form>
@endcan
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
<x-modal.insert.modalQuickMessage :channels="$channels"></x-modalQuickMessage>
<x-modal.edit.modalEditQuickMessage :channels="$channels"></x-modalEditQuickMessage>
</x-app-layout>

80
resources/views/components/modal/edit/modalEditQuickMessage.blade.php

@ -0,0 +1,80 @@
<!-- 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" >
@method('PUT')
@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-white pl-3">
Atualizar Resposta Rápida
</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" 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-3">
<p class="dark:text-gray-100"><strong>Mensagem</strong>: No campo abaixo, utilize palavras-chave reservadas para servirem de atalho para respostas rápidas. Use a anotação @ seguida do texto do atalho.</p>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Atalho: </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="Digite o atalho: " name="atalho">
</div>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Resposta: </label>
<textarea rows="3" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Digite o texto da resposta: " name="texto"></textarea>
</div>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Canal:</label>
<select name="channel" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 container-select">
</select>
</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">Atualizar</button>
</div>
</form>
</div>
</div>
<script>
function atualizaQuickMessage(id) {
$.ajax({
type: "get",
url: `quick_messages/${id}/edit`,
success: function({
data
}) {
const systemMessageData = data.quickMessage;
const channels = data.channels;
const modal = document.querySelector('.modal-edit');
modal.style.display = 'block';
modal.querySelector('form').action = `/quick_messages/${id}`;
modal.querySelector("input[name='atalho']").value = systemMessageData.atalho;
modal.querySelector("textarea[name='texto']").value = systemMessageData.texto;
const containerSelect = modal.querySelector(".container-select");
containerSelect.innerHTML = '';
channels.forEach(channel => {
if (systemMessageData.id_number == channel.id) {
containerSelect.innerHTML += `<option value="${channel.id}" selected>${channel.title}</option>`
} else {
containerSelect.innerHTML += `<option value="${channel.id}" >${channel.title}</option>`
}
})
}
});
}
function fecharModal() {
$('.modal-edit').hide();
}
</script>

47
resources/views/components/modal/insert/modalQuickMessage.blade.php

@ -0,0 +1,47 @@
<!-- Main modal -->
<div class="fixed z-50 hidden p-4 bg-gray-900 bg-opacity-60 h-full w-full" :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('quick_messages.store') }}" class="relative bg-white rounded-lg shadow dark:bg-gray-700" id="formSystemMessage">
@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-white pl-3">
Cadastrar Mensagem Rápida
</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-3">
<p class="dark:text-gray-100"><strong>Mensagem</strong>: No campo abaixo, utilize palavras-chave reservadas para servirem de atalho para respostas rápidas. Use a anotação @ seguida do texto do atalho.</p>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Atalho: </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="Digite o atalho: " name="atalho">
</div>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Resposta: </label>
<textarea rows="3" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" placeholder="Digite o texto da resposta: " name="texto"></textarea>
</div>
<div class="flex flex-col gap-2 mt-2">
<label class="dark:text-gray-100">Canal:</label>
<select name="channel" class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100">
@foreach($channels as $channel)
<option value="{{ $channel->id }}">{{$channel->title}}</option>
@endforeach
</select>
</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>

9
resources/views/layouts/menu.blade.php

@ -107,6 +107,15 @@
</li>
@endcan
@can('show_quick_messages')
<li>
<x-nav-link class="p-2 mt-3 flex ml-4 items-center flex-row rounded-md px-2 md:px-4 duration-300 cursor-pointer hover:bg-blue-600 text-white" :href="route('quick_messages.index')" :active="request()->routeIs('quick_messages.index')">
<i class="fas fa-reply-all text-sm"></i>
<span class="text-[14px] ml-3 text-gray-300">Mensagens Rápidas</span>
</x-nav-link>
</li>
@endcan
@can('show_empresas')
<li>
<x-nav-link class="p-2 mt-3 ml-4 flex items-center flex-row rounded-md px-2 md:px-4 duration-300 cursor-pointer hover:bg-blue-600 text-white" :href="route('empresas.index')" :active="request()->routeIs('empresas.index')">

2
routes/web.php

@ -24,6 +24,7 @@ use App\Http\Controllers\Admin\TemplatesController;
use App\Http\Controllers\Admin\NumberChannelController;
use App\Http\Controllers\Admin\PesquisaSatisfacaoController;
use App\Http\Controllers\Admin\PesquisaSatisfacaoPerguntaController;
use App\Http\Controllers\Admin\QuickMessageController;
use Illuminate\Support\Facades\Route;
Route::middleware(['auth', 'verified'])->group(function () {
@ -39,6 +40,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
'horarios.options' => HorariosOptionController::class,
'pesquisas' => PesquisaSatisfacaoController::class,
'pesquisas.perguntas' => PesquisaSatisfacaoPerguntaController::class,
'quick_messages' => QuickMessageController::class,
]);
Route::delete('/templates/deletar/{id}', [TemplatesController::class, 'deletar'])->name('templatesDeletar');

Loading…
Cancel
Save