PageSourceSearch

http://www.cremz.com/assets/controllers/report_submission_controller-21a17041.js

js cremz.com collected 2026-10-09 04:23:26 UTC 3,412 bytes, 98 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3export default class extends Controller {
4
5    submit(event) {
6        event.preventDefault()
7
8        const form = event.currentTarget
9        const submitBtn = form.querySelector('input[type="submit"], button[type="submit"]')
10        const originalBtnText = submitBtn ? submitBtn.value : "Submit"
11
12        if (submitBtn) {
13            submitBtn.disabled = true
14            submitBtn.value = "Submitting..."
15        }
16
17        fetch(form.action, {
18            method: "POST",
19            headers: {
20                "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content,
21                "Accept": "application/json"
22            },
23            body: new FormData(form)
24        })
25            .then(response => {
26                if (!response.ok) throw new Error("Network response was not ok")
27                return response.json()
28            })
29            .then(data => {
30                this.closeModal()
31                this.showToast(data.message || "Report submitted successfully", "success")
32                form.reset()
33            })
34            .catch(error => {
35                console.error("Error:", error)
36                this.showToast("Failed to submit report. Please try again.", "error")
37            })
38            .finally(() => {
39                if (submitBtn) {
40                    submitBtn.disabled = false
41                    submitBtn.value = originalBtnText
42                }
43            })
44    }
45
46    closeModal() {
47        // Find the close button in the specific modal instance and click it
48        // This assumes the form is inside the modal
49        const modalContent = this.element.closest('.modal-content')
50        if (modalContent) {
51            const closeBtn = modalContent.querySelector('.close-modal-btn')
52            if (closeBtn) closeBtn.click()
53        }
54    }
55
56    showToast(message, type) {
57        // Check if toast container exists
58        let container = document.getElementById("toast-container")
59        if (!container) {
60            container = document.createElement("div")
61            container.id = "toast-container"
62            container.style.cssText = "position: fixed; bottom: 20px; right: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 10px;"
63            document.body.appendChild(container)
64        }
65
66        const toast = document.createElement("div")
67        toast.textContent = message
68        // Base styles
69        Object.assign(toast.style, {
70            padding: "12px 24px",
71            borderRadius: "8px",
72            color: "white",
73            fontWeight: "500",
74            backgroundColor: type === 'success' ? '#22c55e' : '#ef4444', // Green or Red
75            boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
76            transition: "all 0.3s ease",
77            opacity: "0",
78            transform: "translateY(20px)",
79            fontSize: "14px",
80            minWidth: "300px"
81        })
82
83        container.appendChild(toast)
84
85        // Animate in
86        requestAnimationFrame(() => {
87            toast.style.opacity = "1"
88            toast.style.transform = "translateY(0)"
89        })
90
91        // Remove after 3s
92        setTimeout(() => {
93            toast.style.opacity = "0"
94            toast.style.transform = "translateY(20px)"
95            setTimeout(() => toast.remove(), 300)
96        }, 3000)
97    }
98}

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.