Files
SkinbaseNova/resources/js/username-availability.js

63 lines
2.0 KiB
JavaScript

const debounce = (fn, wait = 350) => {
let timeoutId
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => fn(...args), wait)
}
}
const setStatus = (target, message, tone = 'neutral') => {
if (!target) return
target.textContent = message || ''
target.classList.remove('text-green-600', 'text-red-600', 'text-gray-500')
if (tone === 'success') target.classList.add('text-green-600')
else if (tone === 'error') target.classList.add('text-red-600')
else target.classList.add('text-gray-500')
}
const initUsernameAvailability = () => {
const fields = document.querySelectorAll('[data-username-field="true"]')
fields.forEach((field) => {
const url = field.getAttribute('data-availability-url') || '/api/username/availability'
const statusId = field.getAttribute('data-availability-target')
const statusEl = statusId ? document.getElementById(statusId) : null
const check = debounce(async () => {
const raw = String(field.value || '')
const username = raw.trim().toLowerCase()
if (!username) {
setStatus(statusEl, '')
return
}
setStatus(statusEl, 'Checking availability...')
try {
const response = await window.axios.get(url, { params: { username } })
const data = response?.data || {}
if (data.available) {
setStatus(statusEl, `Available: ${data.normalized || username}`, 'success')
} else {
setStatus(statusEl, `Taken: ${data.normalized || username}`, 'error')
}
} catch (error) {
if (error?.response?.status === 422) {
const message = error?.response?.data?.errors?.username?.[0] || 'Invalid username.'
setStatus(statusEl, message, 'error')
return
}
setStatus(statusEl, 'Could not check availability right now.', 'error')
}
})
field.addEventListener('input', check)
})
}
document.addEventListener('DOMContentLoaded', initUsernameAvailability)