forked from felipe.fontana/simples-painel
Felipe Fontana
8 months ago
24 changed files with 1071 additions and 44 deletions
@ -0,0 +1,199 @@
|
||||
<?php |
||||
|
||||
namespace App\Http\Controllers\Admin; |
||||
|
||||
use App\Helpers\Helper; |
||||
use App\Http\Controllers\Controller; |
||||
use App\Models\NumberChannel; |
||||
use App\Models\PesquisaSatisfacao; |
||||
use App\Models\PesquisaSatisfacaoOption; |
||||
use App\Models\PesquisaSatisfacaoResposta; |
||||
use Illuminate\Http\Request; |
||||
use Illuminate\Support\Facades\Gate; |
||||
use Illuminate\Support\Facades\Validator; |
||||
|
||||
class PesquisaSatisfacaoController extends Controller |
||||
{ |
||||
public function __construct( |
||||
protected PesquisaSatisfacao $pesquisaSatisfacaoRepository, |
||||
protected PesquisaSatisfacaoOption $pesquisaSatisfacaoOptionRepository, |
||||
protected NumberChannel $numberChannelRepository, |
||||
protected PesquisaSatisfacaoResposta $pesquisaSatisfacaoRespostaRepository, |
||||
) { |
||||
} |
||||
|
||||
public function index() |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('show_pesquisas')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$empresas = Helper::getEmpresas(); |
||||
|
||||
if (!is_int($empresas)){ |
||||
$empresasIds = $empresas->pluck('id')->toArray(); |
||||
} else { |
||||
$empresasIds = $empresas; |
||||
} |
||||
|
||||
$pesquisas = $this->pesquisaSatisfacaoRepository->list(["id_empresa" => $empresasIds]); |
||||
$numberChannels = $this->numberChannelRepository->list(["id_empresa" => $empresasIds]); |
||||
|
||||
return view('admin.cadastros.pesquisas', compact('pesquisas', 'numberChannels')); |
||||
} |
||||
|
||||
public function store(Request $request) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('store_pesquisas')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$validator = Validator::make($request->all(), [ |
||||
'descricao' => 'string|required', |
||||
'nome' => [ |
||||
'required', |
||||
function ($attribute, $value, $fail){ |
||||
$existingRecord = PesquisaSatisfacao::where('nome', strtoupper($value))->first(); |
||||
|
||||
if ($existingRecord) { |
||||
$fail('O nome já está em uso.'); |
||||
} |
||||
}, |
||||
], |
||||
'status' => 'required', |
||||
'channel' => 'required' |
||||
], [ |
||||
'unique' => 'O nome já está em uso.', |
||||
'required' => 'É preciso informar o campo :attribute.' |
||||
]); |
||||
|
||||
if ($validator->fails()) { |
||||
return redirect()->back()->with('error', $validator->errors()->first()); |
||||
} |
||||
|
||||
$status = $request->status === "on" ? true : false; |
||||
|
||||
$this->pesquisaSatisfacaoRepository->create(strtoupper($request->nome),$request->descricao, $status, $request->channel); |
||||
|
||||
return redirect()->back()->with('status', 'Cadastrado com sucesso'); |
||||
} |
||||
|
||||
public function edit($id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('update_pesquisas')){ |
||||
abort(404); |
||||
} |
||||
|
||||
if (empty($id)) { |
||||
return response()->json(['data' => 'Parametro ID é obrigatório']); |
||||
} |
||||
|
||||
$pesquisaData = PesquisaSatisfacao::find($id); |
||||
$user = auth()->user(); |
||||
$id_empresa = Helper::getEmpresas(); |
||||
|
||||
if (!is_int($id_empresa)){ |
||||
$empresasIds = $id_empresa->pluck('id')->toArray(); |
||||
} else { |
||||
$empresasIds = $id_empresa; |
||||
} |
||||
|
||||
$numberChannels = $this->numberChannelRepository->list(["id_empresa" => $empresasIds]); |
||||
$response = [ |
||||
'data' => [ |
||||
'status' => true, |
||||
'numbers' => $numberChannels, |
||||
'pesquisa_data' => $pesquisaData |
||||
], |
||||
|
||||
]; |
||||
|
||||
return response()->json($response); |
||||
} |
||||
|
||||
public function update(Request $request, $id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('update_pesquisas')){ |
||||
abort(404); |
||||
} |
||||
|
||||
if (!($this->existeResposta($id) && (PesquisaSatisfacao::where('nome', strtoupper($request->nome))->where('id', $id)->where('descricao', $request->descricao)->where('id_number', $request->channel)->first()))){ |
||||
return redirect()->back()->with('error', 'Essa pesquisa já foi respondida e não pode ser alterada!'); |
||||
} |
||||
|
||||
$validator = Validator::make($request->all(), [ |
||||
'descricao' => 'string|required', |
||||
'nome' => [ |
||||
'required', |
||||
function ($attribute, $value, $fail) use ($id){ |
||||
$existingRecord = PesquisaSatisfacao::where('nome', strtoupper($value))->where('id', '!=', $id)->first(); |
||||
|
||||
if ($existingRecord) { |
||||
$fail('O nome já está em uso.'); |
||||
} |
||||
}, |
||||
function ($attribute, $value, $fail) use ($id){ |
||||
$existingRecord = PesquisaSatisfacao::where('nome', strtoupper($value))->where('id', '!=', $id)->first(); |
||||
|
||||
if ($existingRecord) { |
||||
$fail('O nome já está em uso.'); |
||||
} |
||||
}, |
||||
], |
||||
'status' => 'required', |
||||
'channel' => 'required' |
||||
], [ |
||||
'unique' => 'O nome já está em uso.', |
||||
'required' => 'É preciso informar o campo :attribute.' |
||||
]); |
||||
|
||||
if ($validator->fails()) { |
||||
return redirect()->back()->with('error', $validator->errors()->first()); |
||||
} |
||||
|
||||
$status = $request->status === "on" ? true : false; |
||||
|
||||
PesquisaSatisfacao::where("id", $id) |
||||
->update([ |
||||
'nome' => strtoupper($request->nome), |
||||
'descricao' => $request->descricao, |
||||
'status' => $status, |
||||
'id_number' => $request->channel |
||||
]); |
||||
|
||||
return redirect('pesquisas')->with('status', 'Atualizado com sucesso'); |
||||
} |
||||
|
||||
|
||||
public function destroy($id) |
||||
{ |
||||
$user = auth()->user(); |
||||
if(Gate::forUser($user)->denies('destroy_pesquisas')){ |
||||
abort(404); |
||||
} |
||||
|
||||
$pesquisaOptions = $this->pesquisaSatisfacaoOptionRepository->list(['id_pesquisa' => $id]); |
||||
|
||||
if (count($pesquisaOptions) > 0) { |
||||
return redirect()->back()->with('error', 'Primeiramente é necessário deletar as opções da Pesquisa!'); |
||||
} |
||||
|
||||
PesquisaSatisfacao::where("id", $id) |
||||
->delete(); |
||||
|
||||
return redirect('pesquisas')->with('status', 'deletado com sucesso'); |
||||
} |
||||
|
||||
private function existeResposta(int $id_pesquisa) { |
||||
if ($this->pesquisaSatisfacaoRespostaRepository->list(['id_pesquisa' => $id_pesquisa])) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,146 @@
|
||||
<?php |
||||
|
||||
namespace App\Http\Controllers\Admin; |
||||
|
||||
use App\Http\Controllers\Controller; |
||||
use App\Models\PesquisaSatisfacao; |
||||
use App\Models\PesquisaSatisfacaoOption; |
||||
use App\Models\PesquisaSatisfacaoResposta; |
||||
use Illuminate\Http\Request; |
||||
use Illuminate\Support\Facades\Validator; |
||||
|
||||
class PesquisaSatisfacaoOptionController extends Controller |
||||
{ |
||||
public function __construct( |
||||
protected PesquisaSatisfacao $pesquisaSatisfacaoRepository, |
||||
protected PesquisaSatisfacaoOption $pesquisaSatisfacaoOptionRepository, |
||||
protected PesquisaSatisfacaoResposta $pesquisaSatisfacaoRespostaRepository, |
||||
) { |
||||
} |
||||
|
||||
public function index($id) |
||||
{ |
||||
if (empty($id)) { |
||||
return redirect()->back()->with('error', 'O parametro ID é obrigatório.'); |
||||
} |
||||
$options = $this->pesquisaSatisfacaoOptionRepository->list(["id_pesquisa" => $id]); |
||||
$id_pesquisa = $id; |
||||
|
||||
return view('admin.cadastros.pesquisasOption', compact('options', 'id_pesquisa')); |
||||
} |
||||
|
||||
public function store(Request $request) |
||||
{ |
||||
if ($this->existeResposta($request->id_pesquisa)) { |
||||
return redirect()->back()->with('error', 'Essa pesquisa já foi respondida e não pode ser alterada!'); |
||||
} |
||||
|
||||
$validator = Validator::make($request->all(), [ |
||||
'sequencia' => [ |
||||
'required', |
||||
function ($attribute, $value, $fail) use ($request){ |
||||
$existingRecord = PesquisaSatisfacaoOption::where('id_pesquisa', $request->id_pesquisa)->where('opcao', $value)->first(); |
||||
|
||||
if ($existingRecord) { |
||||
$fail('A opção já está em uso.'); |
||||
} |
||||
}, |
||||
], |
||||
], [ |
||||
'unique' => 'O :attribute já está em uso.' |
||||
]); |
||||
|
||||
if ($validator->fails()) { |
||||
return redirect()->back()->with('error', $validator->errors()->first()); |
||||
} |
||||
|
||||
$created = $this->pesquisaSatisfacaoOptionRepository->create($request->sequencia, $request->descricao, $request->id_pesquisa); |
||||
if(!$created){ |
||||
redirect()->back()->with('error', 'Erro ao tentar cadastrar opção'); |
||||
} |
||||
|
||||
return redirect()->back()->with('status', 'Cadastrado com sucesso'); |
||||
} |
||||
|
||||
public function destroy($id_pesquisa, $id_option) |
||||
{ |
||||
if ($this->existeResposta($id_pesquisa)) { |
||||
return redirect()->back()->with('error', 'Essa pesquisa já foi respondida e não pode ser alterada!'); |
||||
} |
||||
|
||||
PesquisaSatisfacaoOption::where("id", $id_option) |
||||
->delete(); |
||||
|
||||
|
||||
return redirect()->back()->with('status', 'Deletado com sucesso'); |
||||
} |
||||
|
||||
public function edit(Request $request) |
||||
{ |
||||
$id = $request->segment(4); |
||||
if (empty($id)) { |
||||
return response()->json(['data' => 'Parametro ID é obrigatório']); |
||||
} |
||||
|
||||
$optionData = PesquisaSatisfacaoOption::find($id); |
||||
$response = [ |
||||
'data' => [ |
||||
'status' => true, |
||||
'option_data' => $optionData |
||||
], |
||||
]; |
||||
|
||||
return response()->json($response); |
||||
} |
||||
|
||||
|
||||
public function update(Request $request) |
||||
{ |
||||
$id = $request->segment(4); |
||||
$id_pesquisa = $request->segment(2); |
||||
|
||||
if ($this->existeResposta($id_pesquisa)) { |
||||
return redirect()->back()->with('error', 'Essa pesquisa já foi respondida e não pode ser alterada!'); |
||||
} |
||||
|
||||
if (!$id) { |
||||
return redirect()->back()->with('error', 'ID não encontrado'); |
||||
} |
||||
|
||||
$validator = Validator::make($request->all(), [ |
||||
'sequencia' => [ |
||||
'required', |
||||
function ($attribute, $value, $fail) use ($id, $id_pesquisa){ |
||||
$existingRecord = PesquisaSatisfacaoOption::where('id_pesquisa', $id_pesquisa)->where('opcao', $value)->where('id', '!=', $id)->first(); |
||||
|
||||
if ($existingRecord) { |
||||
$fail('A opção já está em uso.'); |
||||
} |
||||
}, |
||||
], |
||||
], [ |
||||
'unique' => 'O :attribute já está em uso.' |
||||
]); |
||||
|
||||
if ($validator->fails()) { |
||||
return redirect()->back()->with('error', $validator->errors()->first()); |
||||
} |
||||
|
||||
PesquisaSatisfacaoOption::where("id", $id) |
||||
->update([ |
||||
'opcao' => $request->sequencia, |
||||
'descricao' => $request->descricao, |
||||
'data_reg' => date("Y-m-d") |
||||
]); |
||||
|
||||
return redirect()->back()->with('status', 'Atualizado com sucesso'); |
||||
} |
||||
|
||||
private function existeResposta(int $id_pesquisa) { |
||||
if ($this->pesquisaSatisfacaoRespostaRepository->list(['id_pesquisa' => $id_pesquisa])) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,63 @@
|
||||
<?php |
||||
|
||||
namespace App\Models; |
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
use Illuminate\Database\Eloquent\Model; |
||||
use Illuminate\Support\Facades\DB; |
||||
|
||||
class PesquisaSatisfacao extends Model |
||||
{ |
||||
use HasFactory; |
||||
|
||||
protected $table = "pesquisa_satisfacao"; |
||||
public $timestamps = false; |
||||
|
||||
protected $fillable = [ |
||||
'nome', |
||||
'descricao', |
||||
'id_number', |
||||
'status', |
||||
'data_reg', |
||||
]; |
||||
|
||||
public function list(array $params) |
||||
{ |
||||
$pesquisas = DB::table('pesquisa_satisfacao as p') |
||||
->join('number_channel as nc', 'nc.id', '=', 'p.id_number') |
||||
->select('p.*'); |
||||
|
||||
if (is_array($params['id_empresa'])) { |
||||
// Se $params['id_empresa'] for um array, use a condição whereIn |
||||
$pesquisas->whereIn('nc.id_empresa', $params['id_empresa']); |
||||
} else { |
||||
// Se for um único valor, use a condição normal |
||||
$pesquisas->where('nc.id_empresa', $params['id_empresa']); |
||||
} |
||||
|
||||
if(isset($params['id_number'])){ |
||||
$pesquisas->where('p.id_number', $params['id_number']); |
||||
} |
||||
|
||||
if(isset($params['nome'])){ |
||||
$pesquisas->where('p.nome', $params['nome']); |
||||
} |
||||
|
||||
if(isset($params['status'])){ |
||||
$pesquisas->where('p.status', $params['status']); |
||||
} |
||||
|
||||
return $pesquisas->get(); |
||||
} |
||||
|
||||
public function create(string $nome, string $description, bool $status, string|int $id_number) |
||||
{ |
||||
DB::table('pesquisa_satisfacao')->insert([ |
||||
'nome' => strtoupper($nome), |
||||
'descricao' => $description, |
||||
'status' => $status, |
||||
'id_number' => $id_number, |
||||
'data_reg' => date('Y-m-d') |
||||
]); |
||||
} |
||||
} |
@ -0,0 +1,63 @@
|
||||
<?php |
||||
|
||||
namespace App\Models; |
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
use Illuminate\Database\Eloquent\Model; |
||||
use Illuminate\Support\Facades\DB; |
||||
|
||||
class PesquisaSatisfacaoOption extends Model |
||||
{ |
||||
use HasFactory; |
||||
|
||||
protected $table = "pesquisa_satisfacao_option"; |
||||
public $timestamps = false; |
||||
|
||||
protected $fillable = [ |
||||
'opcao', |
||||
'descricao', |
||||
'id_pesquisa', |
||||
'data_reg', |
||||
]; |
||||
|
||||
public function redirect(): PesquisaSatisfacao |
||||
{ |
||||
return $this->belongsTo(PesquisaSatisfacao::class, 'id_pesquisa')->first(); |
||||
} |
||||
|
||||
public function list(array $params) |
||||
{ |
||||
$options = DB::table('pesquisa_satisfacao_option as po') |
||||
->join("pesquisa_satisfacao as p", "p.id", "=", "po.id_pesquisa") |
||||
->select("po.*", "p.nome as pesquisa_nome"); |
||||
|
||||
if (isset($params['opcao'])) { |
||||
$options->where('po.opcao', $params['opcao']); |
||||
} |
||||
|
||||
if (isset($params['id_pesquisa'])) { |
||||
$options->where('po.id_pesquisa', $params['id_pesquisa']); |
||||
} |
||||
|
||||
return $options->orderBy('opcao', 'asc')->get(); |
||||
} |
||||
|
||||
public function create(string|int $sequence, string $descricao, string|int $id_pesquisa) |
||||
{ |
||||
DB::beginTransaction(); |
||||
try { |
||||
DB::table("pesquisa_satisfacao_option")->insert([ |
||||
'opcao' => $sequence, |
||||
'descricao' => $descricao, |
||||
'id_pesquisa' => $id_pesquisa, |
||||
'data_reg' => date('Y-m-d') |
||||
]); |
||||
|
||||
DB::commit(); |
||||
return true; |
||||
} catch (\Throwable $th) { |
||||
DB::rollBack(); |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
<?php |
||||
|
||||
namespace App\Models; |
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
use Illuminate\Database\Eloquent\Model; |
||||
use Illuminate\Support\Facades\DB; |
||||
|
||||
class PesquisaSatisfacaoResposta extends Model |
||||
{ |
||||
use HasFactory; |
||||
|
||||
protected $table = "pesquisa_satisfacao_resposta"; |
||||
public $timestamps = false; |
||||
|
||||
protected $fillable = [ |
||||
'opcao', |
||||
'id_pesquisa', |
||||
'uniqueid', |
||||
'data_reg', |
||||
]; |
||||
|
||||
public function list(array $params) |
||||
{ |
||||
$pesquisas = DB::table('pesquisa_satisfacao_resposta as psr') |
||||
->select('psr.*'); |
||||
|
||||
if(isset($params['id_pesquisa'])){ |
||||
$pesquisas->where('psr.id_pesquisa', $params['id_pesquisa']); |
||||
} |
||||
|
||||
return $pesquisas->get(); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
function atualizaRedirect(id_pesquisa) { |
||||
$.ajax({ |
||||
type: "get", |
||||
url: `pesquisas/${id_pesquisa}/edit`, |
||||
success: function({ |
||||
data |
||||
}) { |
||||
const pesquisa_data = data.pesquisa_data; |
||||
const numbers_channels = data.numbers; |
||||
const modal = document.querySelector('.modal-edit'); |
||||
modal.style.display = 'block'; |
||||
modal.querySelector('form').action = `pesquisas/${id_pesquisa}`; |
||||
|
||||
modal.querySelector("input[name='nome']").value = pesquisa_data.nome; |
||||
modal.querySelector("textarea[name='descricao']").value = pesquisa_data.descricao; |
||||
|
||||
const containerRadioStatus = document.querySelector(".container-radio-status"); |
||||
|
||||
if (pesquisa_data.status) { |
||||
containerRadioStatus.innerHTML = |
||||
`<input type="radio" name="status" value="on" checked> <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>` |
||||
} else { |
||||
containerRadioStatus.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>` |
||||
} |
||||
|
||||
const containerChannels = modal.querySelector("select[name='channel']"); |
||||
numbers_channels.forEach(channel => { |
||||
if (pesquisa_data.id_number === channel.id) { |
||||
containerChannels.innerHTML = |
||||
` <option value="${channel.id}" selected>${channel.title}</option>` |
||||
|
||||
} else { |
||||
containerChannels.innerHTML = |
||||
` <option value="${channel.id}">${channel.title}</option>` |
||||
|
||||
} |
||||
}) |
||||
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
function fecharModal() { |
||||
document.querySelector('.modal-edit').style.display = 'none'; |
||||
} |
@ -0,0 +1,20 @@
|
||||
function atualizaOptions(id_option) { |
||||
$.ajax({ |
||||
type: "get", |
||||
url: `options/${id_option}/edit`, |
||||
success: function({ |
||||
data |
||||
}) { |
||||
const pesquisa_data = data.option_data; |
||||
const modal = document.querySelector('.modal-edit'); |
||||
modal.style.display = 'block'; |
||||
modal.querySelector('form').action = `options/${id_option}`; |
||||
modal.querySelector("input[name='sequencia']").value = pesquisa_data.opcao; |
||||
modal.querySelector("textarea[name='descricao']").value = pesquisa_data.descricao; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
function fecharModal() { |
||||
document.querySelector('.modal-edit').style.display = 'none'; |
||||
} |
@ -0,0 +1,94 @@
|
||||
<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"> |
||||
Pesquisas de Satisfação |
||||
</h1> |
||||
@can('store_redirect') |
||||
<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 Pesquisa</button> |
||||
@endcan |
||||
</div> |
||||
</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">Nome</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Descrição</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">Opções</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Ações</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
@foreach ($pesquisas as $pesquisa) |
||||
<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">{{ $pesquisa->id }}</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100">{{ $pesquisa->nome }}</td> |
||||
<td |
||||
class="p-3 text-sm text-gray-700 dark:text-gray-100 sequence sequence-{{ $pesquisa->id }}"> |
||||
{{ $pesquisa->descricao }}</td> |
||||
|
||||
@if ($pesquisa->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 text-gray-700 dark:text-gray-100"> |
||||
@can('show_redirect_option') |
||||
<a |
||||
href="{{ route('pesquisas.options.index', ['pesquisa' => $pesquisa->id]) }}" |
||||
class="text-blue-500 hover:underline">Editar Opções</a> |
||||
@endcan |
||||
</td> |
||||
|
||||
<td class="p-3 text-sm font-bold flex-wrap w-32"> |
||||
@can('edit_redirect') |
||||
<button class="bg-blue-600 text-white p-2 rounded text-lg w-full mb-2" title="editar pesquisa" |
||||
onclick="atualizaRedirect( {{ $pesquisa->id }})"><i |
||||
class="fas fa-edit"></i></button> |
||||
@endcan |
||||
@can('destroy_redirect') |
||||
<form method="POST" |
||||
action="{{ route('pesquisas.destroy', ['pesquisa' => $pesquisa->id]) }}" |
||||
class="flex-1 flex" title="deletar pesquisa" |
||||
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.modalPesquisas :numberChannels="$numberChannels"></x-modalPesquisas> |
||||
<x-modal.edit.modalEditPesquisas :numberChannels="$numberChannels"></x-modalEditPesquisas> |
||||
|
||||
<script src="{{ asset('js/views/pesquisas/atualizaPesquisas.js') }}"></script> |
||||
|
||||
</x-app-layout> |
@ -0,0 +1,85 @@
|
||||
<x-app-layout> |
||||
<div class="py-8 px-8"> |
||||
<a href="{{ route('pesquisas.index') }}" style="margin-right: auto;" |
||||
class="text-blue-500 hover:underline mb-5 block">Voltar</a> |
||||
|
||||
@if (session('status')) |
||||
<div class="w-full p-5 bg-blue-600 mb-5 text-white rounded uppercase font-bold text-lg alert"> |
||||
{{ 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 alert"> |
||||
{{ session('error') }} |
||||
</div> |
||||
@endif |
||||
<div class="w-full p-5 bg-blue-600 mb-5 text-white rounded uppercase font-bold text-lg alert hidden act"> |
||||
|
||||
</div> |
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg "> |
||||
<div class="p-6 text-gray-900 dark:text-gray-100"> |
||||
|
||||
<div class="flex items-center"> |
||||
<div> |
||||
<h1 class="text-2xl font-bold">Configuração Options</h1> |
||||
<h2 class="text-lg mt-2">Adicione, edite ou remova suas opções da pesquisa</h2> |
||||
</div> |
||||
@can('store_redirect_option') |
||||
<button class="ml-auto mt-2 bg-blue-600 text-white py-2 px-6 rounded-md text-lg" |
||||
@click="modal = !modal">Adicionar</button> |
||||
@endcan |
||||
</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">Opção</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Descrição</th> |
||||
<th class="p-3 text-sm font-semibold tracking-wide text-left">Ações</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
@foreach ($options as $option) |
||||
<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">{{ $option->id }} |
||||
</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100"> |
||||
{{ $option->opcao }} |
||||
</td> |
||||
<td class="p-3 text-sm text-gray-700 dark:text-gray-100"> |
||||
{{ $option->descricao }} |
||||
</td> |
||||
|
||||
<td class="p-3 text-sm font-bold flex-wrap w-32"> |
||||
@can('edit_redirect_option') |
||||
<button class="bg-blue-600 text-white p-2 rounded text-lg w-full mb-2" title="editar opção" |
||||
onclick="atualizaOptions( {{ $option->id }})"><i |
||||
class="fas fa-edit"></i></button> |
||||
@endcan |
||||
@can('destroy_redirect_option') |
||||
<form method="POST" action="{{ route('pesquisas.options.destroy', ['pesquisa' => $id_pesquisa, 'option' => $option->id]) }}" class="flex-1 flex" title="excluir opção" |
||||
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> |
||||
</div> |
||||
</div> |
||||
<x-modal.insert.modalPesquisaOption :id_pesquisa="$id_pesquisa"></x-modalPesquisaOption> |
||||
<x-modal.edit.modalEditPesquisaOption :id_pesquisa="$id_pesquisa"></x-modalEditPesquisaOption> |
||||
|
||||
<script src="{{ asset('js/views/pesquisas_options/atualizaPesquisasOptions.js') }}"></script> |
||||
</x-app-layout> |
@ -0,0 +1,53 @@
|
||||
@props(['id_pesquisa']) |
||||
|
||||
<!-- 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" |
||||
id="formRedirectOptionEdit"> |
||||
@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"> |
||||
Editar Opção |
||||
</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-5"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Qual é a sequência: </label> |
||||
<input required type="text" value="1" |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 sequence" |
||||
placeholder="Digite a sequência: " name="sequencia" required> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Descrição: </label> |
||||
<textarea required class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" |
||||
placeholder="Digite a descrição: " name="descricao" rows="3" ></textarea> |
||||
</div> |
||||
<input type="hidden" name="id_pesquisa" value="{{ $id_pesquisa }}"> |
||||
</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 btn-sub">Editar</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
<script> |
||||
function fecharModal() { |
||||
$('.modal-edit').hide(); |
||||
$('.modal-edit').find('input.sequence').removeClass('border-red-500 border-2'); |
||||
$('.modal-edit').find('.text-problem').addClass('hidden'); |
||||
} |
||||
</script> |
@ -0,0 +1,60 @@
|
||||
@props(['numberChannels']) |
||||
<!-- 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" id="formStepEdit"> |
||||
@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 Step |
||||
</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"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Nome: </label> |
||||
<input required 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 nome: " name="nome"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Descrição: </label> |
||||
<textarea required placeholder="Digite a descrição: " name="descricao" rows="5" |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100"></textarea> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Selecione o canal: </label> |
||||
<select |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" |
||||
name="channel"> |
||||
@foreach ($numberChannels as $numberChannel) |
||||
<option value="{{ $numberChannel->id }}">{{ $numberChannel->title }}</option> |
||||
@endforeach |
||||
</select> |
||||
</div> |
||||
<div> |
||||
<label for="" class="dark:text-gray-100 block">Ativo: </label> |
||||
<div class="container-radio-status"> |
||||
|
||||
</div> |
||||
</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">Atualizar</button> |
||||
|
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
@ -0,0 +1,46 @@
|
||||
@props(['id_pesquisa']) |
||||
|
||||
<!-- Main modal --> |
||||
<div class="fixed z-50 hidden p-4 bg-gray-900 bg-opacity-60 h-full w-full modal" :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('pesquisas.options.store', ['pesquisa' => $id_pesquisa]) }}" |
||||
class="relative bg-white rounded-lg shadow dark:bg-gray-700" id="formRedirectOption"> |
||||
|
||||
@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 Resposta |
||||
</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-5"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Qual é a sequência: </label> |
||||
<input required type="text" |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100 sequence" |
||||
placeholder="Digite a sequência: " name="sequencia" required> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Descrição: </label> |
||||
<textarea required class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" |
||||
placeholder="Digite a descrição: " name="descricao" rows="3" ></textarea> |
||||
</div> |
||||
<input type="hidden" name="id_pesquisa" value="{{ $id_pesquisa }}"> |
||||
</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 btn-sub">Cadastrar</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
@ -0,0 +1,64 @@
|
||||
@props(['numberChannels']) |
||||
<!-- 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('pesquisas.store') }}" |
||||
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-white pl-3"> |
||||
Cadastrar Pesquisa |
||||
</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-3"> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Nome: </label> |
||||
<input required 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 nome: " name="nome"> |
||||
</div> |
||||
<div class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Selecione o canal: </label> |
||||
<select |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100" |
||||
name="channel"> |
||||
@foreach ($numberChannels as $numberChannel) |
||||
<option value="{{ $numberChannel->id }}">{{ $numberChannel->title }}</option> |
||||
@endforeach |
||||
</select> |
||||
</div> |
||||
<div > |
||||
<label for="" class="dark:text-gray-100 block">Ativo: </label> |
||||
<div class="container-radio"> |
||||
<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 class="flex flex-col gap-2"> |
||||
<label class="dark:text-gray-100">Descrição: </label> |
||||
<textarea required placeholder="Digite a descrição: " name="descricao" rows="5" |
||||
class="w-full dark:bg-gray-800 placeholder:text-gray-800 dark:placeholder:text-gray-100 dark:text-gray-100"></textarea> |
||||
</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