Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.566
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. Finalmente, consegui trabalhar com o wire:model do Livewire com o MySQL. O Copilot me ajudou bastante a criar o código sem receber a mensagem "Livewire encountered corrupted data" no Hostinger: Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Livewire\Component; class Lteste extends Component { public $previsao; function mount() { $this->previsao =tbprevisao::orderBy('conta') ->take(3)->get()->toArray(); } function updated($propertyName) { $parts=explode(".",$propertyName); $index=$parts[1]; $id=$this->previsao[$index]['id']; $valor=data_get($this,$propertyName); tbprevisao::where('id',$id) ->update(['valor'=>$valor]); } } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="previsao.0.valor" wire:change="$refresh" /> <flux:input wire:model="previsao.1.valor" wire:change="$refresh" /> <flux:input wire:model="previsao.2.valor" wire:change="$refresh" /> <pre>{{ print_r($previsao) }}</pre> </div>
  2. Testando um objeto: Lteste.php <?php namespace App\Livewire; use Livewire\Component; class Lteste extends Component { public $objeto = ['vetor' => [1,2,3]]; } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="objeto.vetor.0" wire:change="$refresh" /> <flux:input wire:model="objeto.vetor.1" wire:change="$refresh" /> <flux:input wire:model="objeto.vetor.2" wire:change="$refresh" /> <pre>{{ print_r($objeto['vetor']) }}</pre> </div>
  3. Eu já aprendi que o meu código no notebook nem sempre funciona no Hostinger. Hoje eu decidi estudar o Livewire diretamente no Hostinger, usando o file manager do CloudPanel. Esse é o meu primeiro código, por enquanto não recebi nenhuma mensagem de erro: Lteste.php <?php namespace App\Livewire; use Livewire\Component; class Lteste extends Component { public $vetor=[1,2,3]; } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="vetor.0" wire:change="$refresh" /> <flux:input wire:model="vetor.1" wire:change="$refresh" /> <flux:input wire:model="vetor.2" wire:change="$refresh" /> <div>{{ $vetor[0]." ".$vetor[1]." ".$vetor[2] }}</div> </div>
  4. Eu publiquei a minha dúvida no fórum do Laracasts.com, mas eu tenho pouca esperança. Enquanto isso, pensei em transformar o Livewire num roteador, ficou uma grande gambiarra, mas pelo menos funciona no Hostinger: arquivo app > Livewire > Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Illuminate\Support\Facades\DB; use Livewire\Component; class Lteste extends Component { public $id,$modal,$previsoes; function mount() { if(request()->input("novoValor")){ if(session()->has('id')){ $this->id=session('id'); } $this->modal=false; $valor=deca(request()->input("novoValor")); tbprevisao::where('id',$this->id)->update(['valor'=>$valor]); } if(request()->input("id")){ $this->modal=true; $this->id=request()->input("id"); session(['id'=>$this->id]); } $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } } arquivo resources > views > livewire > lteste.blade.php <div> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right">Conta</div> <div class="w-[188px] px-2">Descricao</div> <div class="w-[130px] text-right">Previsão</div> <div class="w-[130px] text-right">Diario</div> <div class="w-[130px] text-right">Divergência</div> </div> @foreach($previsoes as $p) <div class="odd:bg-gray-200 flex"> <div class="w-[50px] text-right">{{$p->conta}}</div> <div class="w-[188px] px-2 truncate">{{$p->descricao}}</div> @if($modal && $id == $p->id) <div class="w-[130px] text-right border border-black"> <form><input name="novoValor" wire:on class="w-[130px]" /></form> </div> @else <a href="?id={{$p->id}}" class="w-[130px] text-right">{{dec($p->valor)}}</a> @endif <div class="w-[130px] text-right">{{dec($p->fim)}}</div> <div class="w-[130px] text-right"> {{dec(abs(round($p->valor - $p->fim + 0.0001,2)))}} </div> </div> @endforeach </div>
  5. O código a seguir funciona no meu Window 11 / Apache. Na Hostinger Ubuntu / nginx, eu recebo a mensagem no web console assim: https://meusite/livewire/update, ele aparece na lista do php artisan list:route, eu só não sei como ver se o Laravel tem condição de ver essa pasta no ambiente do Hostinger, pelo menos eu não consigo ver essa pasta nem aqui no Windows. Acredito que esse é um dos melhores códigos que eu já fiz, é uma pena que não funciona na Hostinger: arquivo app > Livewire > Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Illuminate\Support\Facades\DB; use Livewire\Component; class Lteste extends Component { public $id,$novoValor,$modal,$previsoes; function update() { $this->modal = false; $valor=deca($this->novoValor); tbprevisao::where('id',$this->id)->update(['valor'=>$valor]); $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } function mount() { $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } function selecionado($id) { $this->id = $id; $this->modal = true; } } arquivo resources > views >livewire > lteste.blade.php <div> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right">Conta</div> <div class="w-[188px] px-2">Descricao</div> <div class="w-[130px] text-right">Previsão</div> <div class="w-[130px] text-right">Diario</div> <div class="w-[130px] text-right">Divergência</div> </div> @foreach($previsoes as $p) <div class="odd:bg-gray-200 flex" wire:click="selecionado({{ $p->id }})"> <div class="w-[50px] text-right">{{$p->conta}}</div> <div class="w-[188px] px-2 truncate">{{$p->descricao}}</div> @if($modal && $id == $p->id) <div class="w-[130px] text-right"> <flux:input wire:model="novoValor" wire:change="update" size="xs" /> </div> @else <div class="w-[130px] text-right">{{dec($p->valor)}}</div> @endif <div class="w-[130px] text-right">{{dec($p->fim)}}</div> <div class="w-[130px] text-right"> {{dec(abs(round($p->valor - $p->fim + 0.0001,2)))}} </div> </div> @endforeach </div>
  6. Eu tenho uma rotina chamada previsão que funciona no meu notebook, mas lá na Hostinger apareceu uma estranha mensagem "Livewire encountered corrupt data". Passei horas estudando o código, mas não consegui achar o problema. Na internet encontrei algumas mensagens reclamando que o "wire:model" não funciona adequadamente com o array e alguém sugeriu usar a propriedade protected na variável ao invés do public. Até que eu tentei, mas não funcionou. A minha única saída provisória foi usar o <form>, mas eu só encontrei exemplo usando apenas um <form> e não um monte delas. Eu improvisei assim: arquivo resources > views > livewire > lprevisão.blade.php <?php foreach($painel as $key => $p): ?> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right"><?=$p->conta?></div> <div class="w-[188px] px-2 truncate"><?=$p->descricao?></div> <div class="w-[130px] py-0"> <form > <input name='{{$p->conta}}' class="w-[130px] text-right py-0 border-none" value='{{dec($p->valor)}}' wire:change="atualizar({{$p->conta}})"> </form> </div> <div class="w-[130px] text-right"><?=dec($p->fim)?></div> <div class="w-[130px] text-right"> <?=dec(abs(round($p->valor - $p->fim + 0.0001,2)))?> </div> </div> <?php endforeach;?> O comando wire:change não funciona como eu esperava, mas ele conseguiu simular o botão "submit", e assim eu consegui jogar no cabeçalho do navegador algo do tipo lteste?112=70. 112 é o número da conta que usei para dar o nome ao <input> e 70 é o número que eu digitei no <input>. Como o comando wire:change não funciona, a minha pergunta foi: e agora, como faço para pegar o número que eu digitei? A minha intuição mandou pegar a função mount( ) no componente, assim: arquivo app > Livewire > Lprevisao.php <?php //... function mount() { if(request()->input()){ foreach(request()->input() as $conta => $valor){} $valor=deca($valor); tbprevisao::where('conta',$conta)->update(['valor'=>$valor]); } $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } E aqui é só gambiarra, usei o mount( ) como uma espécie de roteador, ele pega o conteúdo do cabeçalho pelo request()->input(), depois joga a chave na variável $conta e o conteúdo na variável $valor através do comando foreach( ) que não faz absolutamente nada { }, mas consegue pegar o conteúdo do cabeçalho e jogar nas variáveis. Isso é um péssimo exemplo de programação. A ideia deu certo lá no Hostinger, mas o Livewire não foi feito para usar o <form>, mas a gambiarra deu certo. A mágica do Livewire está no componente wire:model, fazer isso funcionar com o array que é o problema.
  7. arquivo resources > views > livewire > lteste.blade.php <div> <div class="mt-5 flex"> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 1</flux:input.group.prefix> <flux:input wire:model="teste" placeholder="Olá mundo" /> </flux:input.group> </div> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 2</flux:input.group.prefix> <flux:input wire:model="teste2" placeholder="Olá mundo" /> </flux:input.group> </div> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 3</flux:input.group.prefix> <flux:input wire:model="teste3" placeholder="Olá mundo" /> </flux:input.group> </div> </div> </div>
  8. arquivo resources > views > livewire > ldiario-lcto.blade.php (parcial) <flux:field> <div class="w-[130px]""> <flux:input.group> <flux:input.group.prefix>Dia</flux:input.group.prefix> <flux:input type="date" wire:model="dia" wire:change="data" onclick=this.showPicker() /> </flux:input.group> </div> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>Lçto</flux:input.group.prefix> <flux:input wire:model="lcto" onclick=this.showPicker() /> </flux:input.group> </div> <div class="flex items-center"> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>ContaD</flux:input.group.prefix> <flux:input wire:model="ctaD" wire:click="abrirModal('ctaD')" /> </flux:input.group> </div> <div class='px-2'>{{$descD}}</div> </div> <div class="flex items-center"> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>ContaC</flux:input.group.prefix> <flux:input wire:model="ctaC" wire:click="abrirModal('ctaC')" /> </flux:input.group> </div> <div class='px-2'>{{$descC}}</div> </div> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>Valor</flux:input.group.prefix> <flux:input wire:model="valor" /> </flux:input.group> </div> <div> <flux:input.group> <flux:input.group.prefix>Histórico</flux:input.group.prefix> <flux:input wire:model="hist" /> </flux:input.group> </div> <div class="w-[130px]"> <flux:button wire:click="salvar" variant="primary"> Registrar </flux:button> </div> </flux:field>
  9. Hoje de manhã pensei em instalar uma rotina para acrescentar um registro contábil, mas na hora de testar o modal do plano de contas não funcionou. No console da web, eu só vi a mensagem de que o problema é o livewire.js, isso não ajuda nada. Não tive outra escolha, senão começar do zero. Deixei vazio o arquivo app.livewire.LdiarioLcto.php e o arquivo resources.views.livewire.ldiario-lcto.blade.php, e o primeiro que reclamou foi o roteador web.php. Defini a classe no LdiarioLcto, e o roteador me colocou direto on line com o blade, e assim acabei descobrindo que eu não preciso do atributo layout e nem da function render( ), o roteador já faz isso automaticamente, quando você invoca uma classe do tipo Livewire. Fui testando peça por peça, até que cheguei nesse código: @if($comando=="Editar Lançamento") <div class="py-2"> <div wire:click="acrescentar(<?=$consulta->lcto?>)" class="text-gray-500 font-semibold hover:bg-gray-200 p-1 rounded-lg"> Acrescentar no lançamento <?=$consulta->lcto?> </a> </div> @endif Eu perdi o meu domingo só por causa de um erro de digitação, onde deveria escrever </div> eu escrevi </a>. Joguei todo o meu código no Copilot e ele encontrou alguns erros, mas não o marcador que eu usei errado. O Copilot sugeriu para eu instalar o HTMLhint no VS Code, isso sim foi pura perda de tempo, o HTMLhint disse que não encontrou nenhum erro no meu código. Eu estou gostando do Livewire, principalmente quando o meu código funciona. Hoje eu aprendi que o que trava o Livewire é o erro de digitação (80%), erro de lógica (10%) e ausência do tutorial (hoje só temos o counter no portal do Liveware, já o Chirper do Laravel desapareceu). Ou seja, estou fazendo tudo na base da tentativa e erro.
  10. [Copilot] Sub ExtrairLinksParaPlanilha() Dim ie As Object Dim elem As Object Dim links As Object Dim i As Integer Dim ws As Worksheet ' Definir a planilha de destino Set ws = ThisWorkbook.Sheets("Plan1") ' Criar uma instância do Internet Explorer Set ie = CreateObject("InternetExplorer.Application") ' Definir a URL ie.Navigate "https://www.exemplo.com" ' Esperar a página carregar Do While ie.Busy Or ie.ReadyState <> 4 DoEvents Loop ' Capturar todos os links (tag <a>) Set links = ie.Document.getElementsByTagName("a") ' Percorrer os links e inserir na planilha For i = 0 To links.Length - 1 ws.Cells(i + 1, 1).Value = links(i).href Next i ' Fechar o Internet Explorer ie.Quit Set ie = Nothing End Sub
  11. [Copilot] CREATE TABLE exemplo ( id INT PRIMARY KEY, valor INT CHECK (valor > 0) );
  12. Tentei incluir alguns registros pelo blade através de um <form>, mas o Livewire não incluia coisa aguma. Estudando o código, o Livewire começa apagando a tabela tbmercado. Ou seja, toda vez que submetia o <form> ele chamava novamente a rotina inicial do Livewire. Para resolver o problema, eu simplesmente joguei fora o marcador <form>, e ele ficou assim: arquivo resources > views > livewire > lprevisao.blade.php (parcial) <div class="flex"> <input class="w-[100px] text-right border py-0" wire:model=venda name=venda autofocus autocomplete="off" required> <input class="w-[100px] text-right border py-0" wire:model=tarifa wire:change="incluir" name=tarifa required autocomplete="off"> </div> arquivo app > Livewire > Lprevisao.php <?php namespace App\Livewire; use App\Models\tbdiario; use App\Models\tbmercado; use App\Models\tbprevisao; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['titulo'=>'Previsão'])] class Lprevisao extends Component { public $liquido,$mercado,$painel,$tarifa,$total,$venda; public $inputs=[]; function apagar() { tbmercado::truncate(); $this->mercado=tbmercado::all(); } function atualizar($index,$conta) { $valor=deca($this->inputs[$index]); tbprevisao::where('conta',$conta)->update(['valor'=>$valor]); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); $this->inputs=[]; foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } function incluir() { $this->venda=deca($this->venda); $this->tarifa=deca($this->tarifa); $this->liquido=$this->venda - $this->tarifa; tbmercado::create(['venda'=>$this->venda,'tarifa'=>$this->tarifa,'conta'=>$this->liquido]); $this->venda=$this->tarifa=$this->liquido=''; $this->mercado=tbmercado::all(); } function mount() { $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } }
  13. Encontrei uma diferença de R$ 0,01 entre o meu relatório de venda e o relatório da Bling. Eu pensei que a função do PHP round($number,2) iria acabar com o meu pesadelo, mas não resolveu, eu tive que apelar para um episolon de décimo de milésima: <?php //... dec é uma função personalizada que troca o ponto flutuante de ponto para vírgula // e só mostra duas casas decimais $venda=dec(round($venda->total+.0001,2));
  14. arquivo app > Livewire > LdiarioLcto.php <?php namespace App\Livewire; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app')] class LdiarioLcto extends Component { public function delete() { $this->modal('edit-profile')->show(); $this->modal('edit-profile')->close(); } } ?> arquivo resources > views > livewire > ldiario-lcto.blade.php <div> <flux:modal.trigger name="edit-profile"> <flux:button>Edit profile</flux:button> </flux:modal.trigger> <flux:modal name="edit-profile" class="md:w-96"> <div class="space-y-6"> <div> <flux:heading size="lg">Update profile</flux:heading> <flux:text class="mt-2">Make changes to your personal details.</flux:text> </div> <flux:input wire:model="nome" label="Name" placeholder="Your name" /> <flux:input wire:model="dia" label="Date of birth" type="date" /> <div class="flex"> <flux:spacer /> <flux:button wire:click="delete" type="submit" variant="primary">Save changes</flux:button> </div> </div> </flux:modal> </div>
  15. arquivo app > Livewire > LdiarioLcto.php <?php namespace App\Livewire; use App\Models\tbconta; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app')] class LdiarioLcto extends Component { public $ativo,$contaPassivo,$modal,$passivo; public function abrirModal() { $this->modal = true; } public function fecharModal() { $this->modal = false; } public function mount() { $this->ativo=tbconta::where('conta','<',201)->get(); $this->passivo=tbconta::where('conta','>=',201)->get(); $this->contaPassivo=count($this->passivo); } ?> arquivo resources > views > livewire > ldiario-lcto.blade.php <div> <button wire:click="abrirModal">Abrir Modal</button> @if($modal) @foreach($ativo as $a) <div>{{$a->conta}}</div> @endforeach <button wire:click="fecharModal">Fechar Modal</button> @endif </div> } Hoje eu decidi desabafar com o Copilot, reclamando que o Livewire é uma porcaria, e mostrei a mensagem de erro para o Copilot. O Copilot disse que tudo indicava que a minha tbconta não tinha o campo id. Fui verificar no MySQL, e a tbconta não tinha nenhum id, a conta em si era a minha chave primária. Decidi criar o campo id, e não é que o danado do Livewire começou a funcionar!
  16. O modal da gambiarra deu certo no meu código principal. Guardei todas as variáveis que foram utilizadas na NFview numa session( ), depois que o JavaScript chama a função custo, a função custo recupera todas as variáveis da session( ) e em seguida invoca a NFview novamente. Isso é um serviço mal feito, mas como ele funciona, vou deixar a suposta solução Livewire para frente. O que eu gostei mesmo é do componente <flux>, a maioria está amarrada no Livewire, mas alguns deles facilitam a codificação no Laravel, principalmente porque o Tailwind não é nada fácil.
  17. O <flux:modal> não funcionou comigo, acredito que ele só vai funcionar se eu licenciar o flux, mas não tenho certeza. O JavaScript funciona no Laravel 12 Livewire, mas eu não consigo fazer funcionar a classe XMLHttp nesse código: <script> function atualizar(custoAtual, custoAnterior, codprod) { confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior); if (confirma) { xmlhttp = new XMLHttpRequest() url = "nfCusto" formData = new FormData() formData.append('custoAtual', custoAtual) formData.append('codprod', codprod) xmlhttp.open("POST", url, true) xmlhttp.send(formData) location.replace("nfAtualiza") } } </script> A minha saída foi apelar para a ignorância, assim: arquivo resources > views > teste.blade.php @vite(['resources/css/app.css', 'resources/js/app.js']) <title>Teste</title> <script> function atualizar(custoAtual, custoAnterior, codprod) { confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior); if (confirma) { location.replace("nfCusto?custoAtual="+custoAtual+"&codprod="+codprod) } } </script> custo anterior da maçã <?=$custo?> <div class="flex w-[300px]"> <div class="w-[200px]">Custo Atual</div> <input onchange="atualizar(this.value,<?=$custo?>,343)" class="border"/> </div> Para isso funcionar, tive que inventar moda no arquivo web.php: arquivo routes > web.php Route::get('nfCusto',[NF::class,'custo']); Para voltar na página teste.blade.php, fiz mais gambiarra: arquivo app > Http > Controllers > NF.php (parcial) <?php // ... function custo(Request $request) { $marg=tbprod::where('codprod',$request->codprod)->value('marg'); $venda=pvenda($request->custoAtual,$marg); tbprod::where('codprod',$request->codprod) ->update(['custo'=>$request->custoAtual,'venda'=>$venda]); $class="class='w-[70px] text-right'"; tbnf::where('codprod',$request->codprod) ->update(['custoanterior'=>$request->custoAtual,'class'=>$class]); $teste=tbprod::where('codprod',$request->codprod)->value('custo'); return view('teste',['custo'=>$teste]) ; } Fazer teste é fácil, o meu drama é que o meu arquivo original veio de um download da nota fornecedor, e certamente a minha gambiarra não vai funcionar.
  18. arquivo resources > views > teste.blade.php @vite(['resources/css/app.css', 'resources/js/app.js']) <div class="relative group"> <flux:button>Modal do Tailwinds</flux:button> <div class="hidden group-hover:block"> Olá mundo </div> </div>
  19. arquivo resources > views > menuView.blade.php <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ $menu ?? 'Menu' }}</title> </head> @vite(['resources/css/app.css', 'resources/js/app.js']) <body class="w-[630px] m-0 m-auto"> <header class="bg-white shadow-sm flex p-1 items-center justify-between mb-2"> Laravel 12 <flux:separator vertical /> <div class="ml-10 flex items-baseline space-x-4"> <div class="relative group"> <button class="inline-flex px-3 py-2 rounded-md text-sm font-medium"> {{ $menu ?? 'Menu'}} <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40"> <?php if(auth()->user()->id==1): ?> <a href=diarioInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Diário</a> <a href=balanceteInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Balancete</a> <a href=pagarInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Pagar</a> <a href=outrosInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Outros</a> <?php endif; ?> <a href=orcamentoMenu class="block px-4 py-2 text-sm hover:bg-gray-200">Orçamento</a> <a href=pessoaInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Pessoa</a> <a href=produtoInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Produto</a> <a href=vendaInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Relatório de Venda</a> </div> </div> <flux:separator vertical /> <div class="relative group"> <button class="inline-flex px-3 py-2 rounded-md text-sm font-medium"> {{ auth()->user()->nome}} <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40"> <form method=post action=logout class="block px-4 py-2 text-sm hover:bg-gray-200"> @csrf <input type="submit" value="Sair"> </form> <a class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200" href=#>Mudar Senha</a> </div> </header> Hoje eu decidi consertar a barra de menu. Tanto na Hostinger como no Notebook, eu precisava atualizar o navegador para a barra funcionar. Pedi para o Copilot, um código básico de uma barra de menu com Tailwinds e em cima dele eu fui acrescentando os atalhos. Em comparação com o meu código antigo, eu precisei jogar fora o código JavaScript que fazia o menu aparecer e desaparecer, o Tailwind tem um outro jeito de fazer isso. Como deu tudo certo, eu me atrevi a testar o componente <flux>, e deu certo aqui no notebook como lá na Hostinger. Todo o meu projeto do orçamento está na pasta app > Http > Controllers, não preciso reescrever para colocar na pasta app > Livewire, e eu só preciso dar um jeito de jogar fora todos os códigos em JavaScript que embuti nos arquivos blade da pasta resources > views, eles é que estavam impedindo do Laravel 12 com Livewire funcionar tanto no notebook quanto na Hostinger.
  20. [Copilot] é possível reaproveitar tanto o Controller quanto a View existente ao trabalhar com Livewire. Isso pode ser feito ajustando seu fluxo para reutilizar o máximo possível do código já existente, sem perder a funcionalidade específica do Livewire. Aqui está uma abordagem geral: ### Reaproveitar o Controller Você pode manter a lógica do Controller para realizar as operações principais e utilizá-lo como um serviço dentro do componente Livewire, como mostramos anteriormente. ### Reaproveitar a View As views do Livewire funcionam com componentes renderizados, mas você pode incluir sua View existente dentro do Livewire com `@include`. Assim, você reutiliza sua View enquanto aproveita as funcionalidades interativas do Livewire. ### Exemplo de Código Imagine que você tem uma View tradicional associada ao seu Controller, chamada `calculadora.blade.php`: ```html <!-- calculadora.blade.php --> <div> <form> <input name="numero1" type="text" placeholder="Número 1"> <input name="numero2" type="text" placeholder="Número 2"> <button type="submit">Somar</button> </form> </div> ``` Você pode incluir esta View dentro do Livewire: #### Componente Livewire ```php namespace App\Http\Livewire; use Livewire\Component; use App\Http\Controllers\CalculadoraController; class CalculadoraLivewire extends Component { public $numero1; public $numero2; public $resultado; protected $calculadora; public function __construct(CalculadoraController $calculadora) { $this->calculadora = $calculadora; } public function calcular() { $this->resultado = $this->calculadora->somar($this->numero1, $this->numero2); } public function render() { // Reutilizando a View existente return view('livewire.calculadora-livewire')->with('viewContent', view('calculadora')); } } ``` #### View do Livewire ```html <!-- livewire/calculadora-livewire.blade.php --> <div> {{-- Incluindo a View existente --}} {{ $viewContent }} <h4>Resultado: {{ $resultado }}</h4> </div> ``` ### Benefício Essa abordagem combina o poder das funcionalidades Livewire com a reutilização do que você já criou, mantendo sua aplicação mais eficiente e modular. Assim, você reaproveita o Controller para lógica e a View para layout, enquanto habilita interatividade com o Livewire.
  21. O meu roteador é enorme, para cada tarefa dentro da página blade precisei criar várias rotas. Esse não é o caso do Livewire, ele só precisa do roteador para chamar a classe Route::get('ldiario',Ldiario::class); O grande problema é na hora de mudar o formulário. Ontem, o Copilot mostrou um interessante código chamado MainComponent onde o Liveware alterna os formulários. O código é bem engenhoso, aquilo é para programador profissional que trabalha com a abstração de nível 2, eu ainda estou no nível 0, assim eu fiz a seguinte gambiarra: arquivo routes > web.php (parcial) <?php // ... Route::get('ldiario',Ldiario::class); Route::get('ldiarioHistorico',LdiarioHistorico::class)->name('ldiarioHistorico'); ?> arquivo resources > view > livewire > ldiario.blade.php (parcial) <input wire:model="hist" placeholder="Procurar no Histórico" wire:change="historico" class="rounded py-0 ml-2 border-none bg-transparent text-black font-semibold" autocomplete=off> arquivo app > Liveware > Ldiario.php (parcial) <?php public $hist; public function historico() { return redirect()->route('ldiarioHistorico',['filtro'=>$this->hist]); } ?> arquivo app > Livewire > LdiarioHistorico.php <?php namespace App\Livewire; use Illuminate\Http\Request; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['title'=>'Historico'])] class LdiarioHistorico extends Component { public $filtro; public function mount(Request $request) { $this->filtro=$request->input('filtro'); } } ?> arquivo resources > views > liveware > ldiario-historico.blade.php <div> {{ $filtro}} </div> // note que o nome da classe é LdiarioHistorico, mas a diretiva #[layout( )] vai buscar o ldiario-historico.blade.php
  22. O código que eu publiquei não funcionou na Hostinger, há muito erro de lógica que o Copilot encontrou. Ele disse que eu não posso executar a função mount( ) mais de uma vez. Para emparelhar a variável array( ) do Livewire com wire:model no blade, você precisa ter cereteza que o array( ) não está vazio, senão não vai aparecer nada no Blade. arquivo app > Livewire > lprevisao.php <?php namespace App\Livewire; use App\Models\tbdiario; use App\Models\tbmercado; use App\Models\tbprevisao; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['title'=>'Previsão'])] class Lprevisao extends Component { public $mercado,$painel,$total; public $inputs=[]; public function atualizar($index,$conta) { $valor=deca($this->inputs[$index]); tbprevisao::where('conta',$conta)->update(['valor'=>$valor]); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); $this->inputs=[]; foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } public function mount() { $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } } arquivo lprevisao.blade.php div> <div class="flex"> <a href=diarioInicio class="w-[100px] text-blue-700">Diario</a> <a href=previsaoPoupanca class="w-[100px] text-blue-700">Poupança</a> </div> <div class="flex"> <div class="w-[50px] text-right">Conta</div> <div class="w-[130px] px-2">Descricao</div> <div class="w-[150px] text-right">Previsão</div> <div class="w-[150px] text-right">Contábil</div> <div class="w-[150px] text-right">Divergência</div> </div> <?php foreach($painel as $key => $p): ?> <div class=flex> <div class="w-[50px] text-right"><?=$p->conta?></div> <div class="w-[188px] ml-2 truncate"><?=$p->descricao?></div> <div class="w-[130px] py-0"> <input class="w-[130px] text-right py-0 border-none" wire:model.defer="inputs.{{$key}}" wire:change="atualizar({{$key}},{{$p->conta}})"> </div> <div class="w-[130px] text-right"><?=dec($p->fim)?></div> <div class="w-[130px] text-right"> <?=dec(abs(round($p->valor - $p->fim,2)))?> </div> </div> <?php endforeach;?> </div>
  23. arquivo app > Liveware > Lprevisao.php <?php namespace App\Livewire; use App\Models\tbdiario; use App\Models\tbmercado; use App\Models\tbprevisao; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['title'=>'Previsão'])] class Lprevisao extends Component { public $conta,$mercado,$painel,$total,$valor=[]; public function alterar($index,$conta) { $valor=deca($this->valor[$index]); tbprevisao::where('conta',$conta)->update( ['valor'=>$valor]); return $this->mount(); } public function mount() { $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } } arquivo resources > views > livewire > lprevisao.blade.php <div> <div class="flex"> <div class="w-[50px] text-right">Conta</div> <div class="w-[130px] px-2">Descricao</div> <div class="w-[150px] text-right">Previsão</div> <div class="w-[150px] text-right">Contábil</div> <div class="w-[150px] text-right">Divergência</div> </div> <?php foreach($painel as $index => $p): ?> <div class=flex> <div class="w-[50px] text-right"><?=$p->conta?></div> <div class="w-[188px] ml-2 truncate"><?=$p->descricao?></div> <div class="w-[130px] py-0"> <input class="w-[130px] text-right py-0 border-none" wire:model="valor.{{$index}}" wire:change="alterar({{$index}},{{$p->conta}})" value=<?=dec($p->valor)?>> </div> <div class="w-[130px] text-right"><?=dec($p->fim)?></div> <div class="w-[130px] text-right"> <?=dec(abs(round($p->valor - $p->fim,2)))?> </div> </div> <?php endforeach;?> </div>
  24. Ontem, eu gastei o dia todo só para mudar a data do lançamento contábil. Foram várias tentativas e erros, tem muitas dicas do Copilot e do portal do Livewire que não funcionam, até eu conseguir isso: arquivo app > Livewire > Ldiario.php <?php namespace App\Livewire; use App\Models\tbdiario; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['title'=>'Diário'])] class Ldiario extends Component { public $dia, $mensagem, $dataAtual, $lctos, $somaDebito, $somaCredito; public function mount() { $this->dia=(session()->has('dia')) ? session('dia') : date('Y-m-d'); session(['dia'=>$this->dia]); $this->mensagem=""; $this->dataAtual=date('Y-m-d'); if($this->dataAtual!==$this->dia) { $this->mensagem="Hoje é " . dbr($this->dataAtual) . " "; } $this->lctos=tbdiario::where('dia',$this->dia)->orderBy('lcto')->get(); $this->somaDebito=tbdiario::where('contad','>',0)->where('dia',$this->dia)->sum('valor'); $this->somaCredito=tbdiario::where('contac','>',0)->where('dia',$this->dia)->sum('valor'); } public function ldiarioData() { session(['dia'=>$this->dia]); return $this->mount(); } } arquivo resources > views > components > layouts > app.blade.php <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ $title ?? 'Page Title' }}</title> </head> @vite(['resources/css/app.css', 'resources/js/app.js']) <body class="w-[630px] m-0 m-auto"> <div> <nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="flex items-center justify-between h-16"> <div class="flex items-center"> <a href="#" class="text-sm font-medium">Laravel 12</a> <div class="ml-10 flex items-baseline space-x-4"> <div class="relative group"> <button class="px-3 py-2 rounded-md text-sm font-medium"> {{ $title }} </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40" > <a href="ldiario" class="block px-4 py-2 text-sm hover:bg-gray-200">Diário</a> <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-200">Opção 2</a> <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-200">Opção 3</a> </div> </div> <div class="relative group"> <button class="px-3 py-2 rounded-md text-sm font-medium"> {{ auth()->user()->nome}} </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40" > <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-200">Sair</a> <a href="#" class="block px-4 py-2 text-sm hover:bg-gray-200">Mudar Senha</a> </div> </div> </div> </div> </div> </nav> </div> {{ $slot }} </body> </html> arquivo resources > views > livewire > ldiario.blade.php (parcial) <div> <input type="date" wire:model="dia" id="dia" value='<?=$dia?>' wire:change="ldiarioData" class="border-none font-semibold py-1 px-2 w-[130px] hover:bg-gray-200 rounded text-gray-500"> </div> O mais importante é que consegui rodar na Hostinger (claro que precisei rodar npm install - onde recebi várias mensagens, bem como o npm run build pelo ssh do terminal VS Code). O que eu gostei é que não tem <form>, não tem @csrf e também não tem web.php para funcionar o método ldiarioData, e lá no controlador não tem nenhum Request, tudo é bem mágico mesmo. A variável $dia no controlador está amarrado com o <input wire:model="dia">, mas eu não consegui fazer funcionar o método updatedDia( ), eu desisti e improvisei, definindo mais um serviço no mesmo input, o wire:change="ldiarioData", e isso deu certo.
  25. Eu pensei que bastava definir a variável na classe Liveware para ela mostrar o conteúdo dela no navegador. O Copilot explicou que o Liveware não é nada disso, primeiro ela carrega o layout (onde está a variável que você quer mostrar), depois ela lê a classe (onde você define a variável) e finalmente ela carrega o resto do HTML. Ou seja, ela sempre vai reclamar que a variável não está definida. Para resolver esse contratempo, o Copilot sugeriu isso: public function render() { return view('sua-visao-componente') ->layout('layouts.app', ['menu' => $this->menu]); } O Copilot é muito bacana, mas aí eu lembrei do código do login que vem embutido na hora de instalar o Laravel 12 com Liveware, e tentei usar no meu aplicativo: <?php namespace App\Livewire; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['menu'=>'Laranja'])] class Lmenu extends Component { } E deu certo! O único problema é que o arquivo lmenu.blade.php (note que o nome da classe está em maiúsculo e o do blade em minúsculo) tem que estar no diretório resources.views.liveware, eu não posso mais colocar no diretório raiz do resources.views. Note que nessa classe, não existe nenhum comando; o arquivo blade também não tem nada. Tudo o que ele faz é botar a barra de navegação no topo da tela, mas ele precisa da variável $menu já definida.
×
×
  • Criar Novo...