PageSourceSearch

https://nutrebem.prod.nutrebem.com.br/assets/controllers/balance_transfer_controller-e7269864.js

js nutrebem.com.br collected 2026-10-01 16:38:25 UTC 2,670 bytes, 76 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2import { paraNumero, paraTexto } from "lib/moeda"
3
4// Transferencia de saldo entre alunos da mesma escola.
5//
6// O impedimento e comunicado em texto e o botao continua clicavel: botao desabilitado
7// sem mensagem foi o impasse que esta tela veio desfazer — inclusive sem aluno destino,
8// que e escolhido pela busca e recarrega a tela.
9export default class extends Controller {
10  static targets = ["busca", "destino", "valor", "motivo", "erroValor", "erroMotivo", "erroDestino", "aviso"]
11  static values = { disponivel: Number, buscaUrl: String, destinoUrl: String }
12
13  connect() {
14    $(this.buscaTarget).autocomplete({
15      source: this.buscaUrlValue,
16      minLength: 2,
17      select: (evento, ui) => {
18        window.location.href = `${this.destinoUrlValue}?target_student_id=${ui.item.value}`
19        return false
20      },
21    })
22    $(".ui-autocomplete").css("z-index", 1000)
23  }
24
25  disconnect() {
26    $(this.buscaTarget).autocomplete("destroy")
27  }
28
29  limparValor() {
30    this.#mostrarProblema(null)
31  }
32
33  limparMotivo() {
34    if (this.motivoTarget.value.trim() !== "") this.erroMotivoTarget.style.display = "none"
35  }
36
37  // Adiado para o fim da fila porque a mascara de moeda reformata o campo no mesmo
38  // evento: lido antes dela, o valor fica uma tecla atrasado (90,01 com 90 disponivel
39  // so reclamava ao apertar Enter).
40  conferirValor() {
41    setTimeout(() => this.#mostrarProblema(this.#problemaDoValor()), 0)
42  }
43
44  enviar(evento) {
45    const semDestino = !this.destinoTarget.value
46    const semMotivo = this.motivoTarget.value.trim() === ""
47    const problema = this.#problemaDoValor()
48
49    this.erroDestinoTarget.style.display = semDestino ? "" : "none"
50    this.erroMotivoTarget.style.display = semMotivo ? "" : "none"
51    this.#mostrarProblema(problema)
52
53    if (!semDestino && !semMotivo && !problema) return
54
55    evento.preventDefault()
56
57    const primeiro = semDestino ? this.buscaTarget : problema ? this.valorTarget : this.motivoTarget
58    primeiro.scrollIntoView({ block: "center" })
59    primeiro.focus()
60  }
61
62  #problemaDoValor() {
63    const valor = paraNumero(this.valorTarget.value)
64    if (Number.isNaN(valor) || valor <= 0) return "Informe um valor maior que zero."
65    if (valor > this.disponivelValue) {
66      return `Valor de transferência não pode ser maior que o saldo do aluno (máximo R$ ${paraTexto(this.disponivelValue)}).`
67    }
68    return null
69  }
70
71  #mostrarProblema(problema) {
72    this.erroValorTarget.textContent = problema || ""
73    this.erroValorTarget.style.display = problema ? "" : "none"
74    this.avisoTarget.style.color = problema ? "#dc2626" : "#94a3b8"
75  }
76}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.