PageSourceSearch

https://zerowaste.org/assets/controllers/event_planner_controller-86367e92.js

js zerowaste.org collected 2026-09-26 00:00:11 UTC 3,886 bytes, 133 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3export default class extends Controller {
4  static targets = ["checkbox", "notes", "timeline", "item"]
5  static values = { eventType: String, eventTitle: String }
6
7  toggle(event) {
8    const checkbox = event.currentTarget
9    const item = checkbox.closest("[data-event-planner-target='item']")
10    const notesWrapper = item.querySelector("[data-notes-wrapper]")
11
12    if (checkbox.checked) {
13      item.classList.add("bg-primary-50", "border-primary-200")
14      item.classList.remove("border-stone-200")
15      if (notesWrapper) notesWrapper.classList.remove("hidden")
16    } else {
17      item.classList.remove("bg-primary-50", "border-primary-200")
18      item.classList.add("border-stone-200")
19      if (notesWrapper) notesWrapper.classList.add("hidden")
20    }
21  }
22
23  async downloadPdf() {
24    const { jsPDF } = await import("jspdf")
25    const doc = new jsPDF()
26    const pageWidth = doc.internal.pageSize.getWidth()
27    const margin = 20
28    const maxWidth = pageWidth - margin * 2
29    let y = 20
30
31    // Header
32    doc.setFontSize(20)
33    doc.setFont("helvetica", "bold")
34    doc.text(this.eventTitleValue + " Planning Guide", margin, y)
35    y += 8
36
37    doc.setFontSize(10)
38    doc.setFont("helvetica", "normal")
39    doc.setTextColor(100)
40    doc.text("Generated from ZeroWaste.Org", margin, y)
41    doc.setTextColor(0)
42    y += 12
43
44    // Divider
45    doc.setDrawColor(200)
46    doc.line(margin, y, pageWidth - margin, y)
47    y += 10
48
49    // Checklist
50    doc.setFontSize(14)
51    doc.setFont("helvetica", "bold")
52    doc.text("Planning Checklist", margin, y)
53    y += 8
54
55    this.checkboxTargets.forEach((checkbox, index) => {
56      if (y > 270) {
57        doc.addPage()
58        y = 20
59      }
60
61      const item = checkbox.closest("[data-event-planner-target='item']")
62      const label = item.querySelector("[data-label]").textContent.trim()
63      const checked = checkbox.checked
64
65      // Checkbox symbol
66      doc.setFontSize(11)
67      doc.setFont("helvetica", "normal")
68      const symbol = checked ? "[\u2713]" : "[  ]"
69      doc.text(symbol, margin, y)
70
71      // Label text (wrapped)
72      const lines = doc.splitTextToSize(label, maxWidth - 12)
73      doc.text(lines, margin + 12, y)
74      y += lines.length * 5 + 2
75
76      // Notes if present
77      if (this.notesTargets[index]) {
78        const notesText = this.notesTargets[index].value.trim()
79        if (notesText) {
80          doc.setFontSize(9)
81          doc.setTextColor(100)
82          const noteLines = doc.splitTextToSize("Notes: " + notesText, maxWidth - 16)
83          doc.text(noteLines, margin + 16, y)
84          y += noteLines.length * 4 + 2
85          doc.setTextColor(0)
86        }
87      }
88
89      y += 3
90    })
91
92    // Timeline section
93    const timelineEntries = this.timelineTargets.filter(t => t.value)
94    if (timelineEntries.length > 0) {
95      y += 5
96      if (y > 250) {
97        doc.addPage()
98        y = 20
99      }
100
101      doc.setDrawColor(200)
102      doc.line(margin, y, pageWidth - margin, y)
103      y += 10
104
105      doc.setFontSize(14)
106      doc.setFont("helvetica", "bold")
107      doc.setTextColor(0)
108      doc.text("Your Timeline", margin, y)
109      y += 8
110
111      doc.setFontSize(11)
112      doc.setFont("helvetica", "normal")
113      timelineEntries.forEach(field => {
114        if (y > 270) {
115          doc.addPage()
116          y = 20
117        }
118        const label = field.closest("[data-timeline-item]").querySelector("label").textContent.trim()
119        doc.text(label + ": " + field.value, margin, y)
120        y += 7
121      })
122    }
123
124    // Footer on last page
125    const pageHeight = doc.internal.pageSize.getHeight()
126    doc.setFontSize(8)
127    doc.setTextColor(150)
128    doc.text("ZeroWaste.Org \u2014 Plan your zero waste event", margin, pageHeight - 10)
129
130    const filename = this.eventTypeValue.replace(/_/g, "-") + "-planning-guide.pdf"
131    doc.save(filename)
132  }
133}

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.