PageSourceSearch

https://comsyoknyakaunseling-production.up.railway.app/assets/controllers/working_day_controller-0e1e0648.js

js comsyoknyakaunseling-production.up.railway.app collected 2026-10-03 12:13:11 UTC 2,611 bytes, 73 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3// Connects to data-controller="working-day"
4//
5// One controller instance per weekday row on the practitioner working-hours
6// form. Handles:
7//   - toggling the whole day open/closed (enables / disables every input)
8//   - adding a new time-range row (start/end pair)
9//   - removing a range row (always keeps at least one when the day is active)
10//   - re-indexing the range input names so Rails sees a clean array
11//     (availabilities[<day>][ranges][0][start_time], [1][start_time], ...)
12export default class extends Controller {
13  // statusLabel is optional: the practitioner form shows an "Open / Closed"
14  // caption beside the toggle, the admin form does not.
15  static targets = ["activeToggle", "rangesContainer", "range", "addButton", "statusLabel"]
16  static values = { dayOfWeek: Number, active: Boolean }
17
18  toggleDay() {
19    const active = this.activeToggleTarget.checked
20    this.activeValue = active
21    this.element.querySelectorAll("input[type='time'], button[data-action*='working-day#']").forEach(el => {
22      el.disabled = !active
23    })
24    if (this.hasStatusLabelTarget) {
25      this.statusLabelTarget.textContent = active ? "Open" : "Closed"
26    }
27  }
28
29  addRange(event) {
30    event.preventDefault()
31    if (!this.activeToggleTarget.checked) return
32
33    const template = this.rangeTargets[0]
34    if (!template) return
35
36    const clone = template.cloneNode(true)
37    clone.querySelectorAll("input[type='time']").forEach(input => {
38      input.disabled = false
39      // Cleared so the new range looks blank; admin fills it in.
40      input.value = ""
41    })
42    clone.querySelectorAll("button").forEach(btn => { btn.disabled = false })
43
44    this.rangesContainerTarget.insertBefore(clone, this.addButtonTarget)
45    this.reindexRanges()
46  }
47
48  removeRange(event) {
49    event.preventDefault()
50    const row = event.currentTarget.closest("[data-working-day-target='range']")
51    if (!row) return
52
53    // Keep at least one row visible so the day always has a UI starting point.
54    if (this.rangeTargets.length <= 1) {
55      row.querySelectorAll("input[type='time']").forEach(input => { input.value = "" })
56      return
57    }
58    row.remove()
59    this.reindexRanges()
60  }
61
62  reindexRanges() {
63    const day = this.dayOfWeekValue
64    this.rangeTargets.forEach((row, idx) => {
65      row.querySelectorAll("input[type='time']").forEach(input => {
66        const field = input.name.match(/\[(start_time|end_time)\]$/)?.[1]
67        if (field) {
68          input.name = `availabilities[${day}][ranges][${idx}][${field}]`
69        }
70      })
71    })
72  }
73}

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.