show(), hide(), visible. font-light, normal, medium, semibold, bold, extrabold, black. protocol connection pooling. fetch() with GURT. DNS from HTTP to GURT.
This commit is contained in:
@@ -1,44 +1,103 @@
|
||||
<head>
|
||||
<title>Domain Dashboard</title>
|
||||
<icon src="https://cdn-icons-png.flaticon.com/512/295/295128.png">
|
||||
<meta name="theme-color" content="#0891b2">
|
||||
<meta name="description" content="Manage your domains and registrations">
|
||||
<meta name="theme-color" content="#0891b2">
|
||||
<meta name="description" content="Manage your domains and registrations">
|
||||
|
||||
<style>
|
||||
body { bg-[#f8fafc] p-6 font-sans }
|
||||
h1 { text-[#0891b2] text-3xl font-bold text-center }
|
||||
h2 { text-[#0f766e] text-xl font-semibold }
|
||||
h3 { text-[#374151] text-lg font-medium }
|
||||
.container { bg-[#ffffff] p-6 rounded-lg shadow-lg max-w-6xl mx-auto }
|
||||
.primary-btn { px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#0891b2] text-white hover:bg-[#0e7490] }
|
||||
.success-btn { px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#059669] text-white hover:bg-[#047857] }
|
||||
.danger-btn { px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white hover:bg-[#b91c1c] }
|
||||
.secondary-btn { px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#6b7280] text-white hover:bg-[#4b5563] }
|
||||
.warning-btn { px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#f59e0b] text-white hover:bg-[#d97706] }
|
||||
.form-group { flex flex-col gap-2 mb-4 }
|
||||
.form-input { w-full p-3 border border-gray-300 rounded-md }
|
||||
.card { bg-[#ffffff] p-4 rounded-lg shadow border }
|
||||
.stats-card { bg-[#f0f9ff] p-4 rounded-lg border border-[#0891b2] }
|
||||
.domain-item { bg-[#f8fafc] p-4 rounded-lg border mb-2 flex justify-between items-center }
|
||||
.log-area { bg-[#1f2937] text-white p-4 rounded-lg font-mono text-sm max-h-64 overflow-auto }
|
||||
.error-text { text-[#dc2626] text-sm }
|
||||
.modal { w-full h-full bg-[rgba(0,0,0,0.5)] flex items-center justify-center z-50 }
|
||||
.modal-content { bg-white p-6 rounded-lg max-w-md w-full mx-4 }
|
||||
.tld-selector { flex flex-wrap gap-2 }
|
||||
.tld-option { px-3 py-1 rounded border cursor-pointer hover:bg-[#f3f4f6] }
|
||||
.tld-selected { bg-[#0891b2] text-white hover:bg-[#0e7490] }
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
bg-[#171616] font-sans text-white
|
||||
}
|
||||
|
||||
<script src="dashboard.lua" />
|
||||
h1 {
|
||||
text-[#ef4444] text-3xl font-bold text-center
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-[#dc2626] text-xl font-semibold
|
||||
}
|
||||
|
||||
h3 {
|
||||
text-[#fca5a5] text-lg font-medium
|
||||
}
|
||||
|
||||
.container {
|
||||
bg-[#262626] p-6 rounded-lg shadow-lg max-w-6xl mx-auto
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
|
||||
}
|
||||
|
||||
.success-btn {
|
||||
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#ef4444] text-white
|
||||
}
|
||||
|
||||
.danger-btn {
|
||||
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#b91c1c] text-white
|
||||
}
|
||||
|
||||
.secondary-btn {
|
||||
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#525252] text-white w-32 h-12
|
||||
}
|
||||
|
||||
.warning-btn {
|
||||
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
|
||||
}
|
||||
|
||||
.form-group {
|
||||
flex flex-col gap-2 mb-4 w-full
|
||||
}
|
||||
|
||||
.form-input {
|
||||
w-full p-3 border border-gray-600 rounded-md bg-[#374151] text-white
|
||||
}
|
||||
|
||||
.card {
|
||||
bg-[#262626] p-4 rounded-lg shadow border border-gray-700
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
bg-[#1f1f1f] p-4 rounded-lg border border-[#dc2626]
|
||||
}
|
||||
|
||||
.domain-item {
|
||||
bg-[#374151] p-4 rounded-lg border border-gray-700 mb-2 flex justify-between items-center
|
||||
}
|
||||
|
||||
.log-area {
|
||||
bg-[#111827] text-white p-4 rounded-lg font-mono text-sm max-h-64 overflow-auto
|
||||
}
|
||||
|
||||
.error-text {
|
||||
text-[#fca5a5] text-sm
|
||||
}
|
||||
|
||||
.tld-selector {
|
||||
flex flex-wrap gap-2
|
||||
}
|
||||
|
||||
.tld-option {
|
||||
px-3 py-1 rounded border border-gray-600 cursor-pointer bg-[#374151] text-white w-12 h-12
|
||||
}
|
||||
|
||||
.tld-selected {
|
||||
bg-[#dc2626] text-white
|
||||
}
|
||||
|
||||
.invite-code-display {
|
||||
bg-[#374151] p-3 rounded font-mono text-center mb-2 text-white
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="dashboard.lua" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>🌐 Domain Management Dashboard</h1>
|
||||
|
||||
<div style="container mt-6">
|
||||
<div style="stats-card mb-6">
|
||||
<div style="flex justify-between items-center">
|
||||
<div id="user-info" style="text-lg font-semibold">Loading...</div>
|
||||
<div style="flex justify-between items-center w-full">
|
||||
<p id="user-info" style="text-white text-lg font-semibold">Loading...</p>
|
||||
<button id="logout-btn" style="secondary-btn">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,17 +105,17 @@
|
||||
<div style="card mb-6">
|
||||
<h2>Register New Domain</h2>
|
||||
<div style="form-group">
|
||||
<label>Domain Name:</label>
|
||||
<p>Domain Name:</p>
|
||||
<input id="domain-name" type="text" style="form-input" placeholder="myawesome" />
|
||||
</div>
|
||||
<div style="form-group">
|
||||
<label>Select TLD:</label>
|
||||
<p>Select TLD:</p>
|
||||
<div id="tld-selector" style="tld-selector">
|
||||
Loading TLDs...
|
||||
<p id="tld-loading">Loading TLDs...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="form-group">
|
||||
<label>IP Address:</label>
|
||||
<p>IP Address:</p>
|
||||
<input id="domain-ip" type="text" style="form-input" placeholder="192.168.1.100" />
|
||||
</div>
|
||||
<div id="domain-error" style="error-text hidden mb-2"></div>
|
||||
@@ -65,49 +124,29 @@
|
||||
|
||||
<div style="card mb-6">
|
||||
<h2>Invite System</h2>
|
||||
<p style="text-[#6b7280] mb-4">Create invite codes to share with friends, or redeem codes to get more domain registrations.</p>
|
||||
|
||||
<div style="flex flex-row gap-4">
|
||||
<div style="flex-1">
|
||||
<h3>Create Invite</h3>
|
||||
<button id="create-invite-btn" style="warning-btn">Generate Invite Code</button>
|
||||
</div>
|
||||
<div style="flex-1">
|
||||
<h3>Redeem Invite</h3>
|
||||
<div style="flex gap-2">
|
||||
<input id="invite-code-input" type="text" style="form-input" placeholder="Enter invite code" />
|
||||
<button id="redeem-invite-btn" style="primary-btn">Redeem</button>
|
||||
</div>
|
||||
<div id="redeem-error" style="error-text hidden mt-2"></div>
|
||||
<p style="text-[#6b7280] mb-4">Create invite codes to share with friends, or redeem codes to get more domain
|
||||
registrations.</p>
|
||||
|
||||
<p id="invite-code-display" style="invite-code-display mt-2">Placeholder</p>
|
||||
|
||||
<div style="flex flex-col gap-4 items-center justify-center mx-auto">
|
||||
<h3>Create Invite</h3>
|
||||
<button id="create-invite-btn" style="warning-btn">Generate Invite Code</button>
|
||||
</div>
|
||||
<div style="flex flex-col gap-4 mx-auto">
|
||||
<h3>Redeem Invite</h3>
|
||||
<div style="flex gap-2">
|
||||
<input id="invite-code-input" type="text" style="form-input" placeholder="Enter invite code" />
|
||||
<button id="redeem-invite-btn" style="primary-btn">Redeem</button>
|
||||
</div>
|
||||
<div id="redeem-error" style="error-text hidden mt-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="card mb-6">
|
||||
<h2>My Domains</h2>
|
||||
<div id="domains-list">
|
||||
Loading domains...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="card">
|
||||
<h2>Activity Log</h2>
|
||||
<div style="log-area">
|
||||
<pre id="log-area">Initializing...</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="invite-modal" style="modal hidden">
|
||||
<div style="modal-content">
|
||||
<h3>Invite Code Generated</h3>
|
||||
<p>Share this code with friends to give them 3 additional domain registrations:</p>
|
||||
<div style="bg-[#f3f4f6] p-3 rounded font-mono text-center mb-4">
|
||||
<span id="invite-code-display">Loading...</span>
|
||||
</div>
|
||||
<div style="flex gap-2 justify-center">
|
||||
<button id="copy-invite-code" style="primary-btn">Copy Code</button>
|
||||
<button id="close-invite-modal" style="secondary-btn">Close</button>
|
||||
<p id="domains-loading">Loading domains...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,19 +5,11 @@ local authToken = nil
|
||||
|
||||
local userInfo = gurt.select('#user-info')
|
||||
local domainsList = gurt.select('#domains-list')
|
||||
local logArea = gurt.select('#log-area')
|
||||
local inviteModal = gurt.select('#invite-modal')
|
||||
local tldSelector = gurt.select('#tld-selector')
|
||||
local loadingElement = gurt.select('#tld-loading')
|
||||
local displayElement = gurt.select('#invite-code-display')
|
||||
|
||||
local logMessages = {}
|
||||
|
||||
local function addLog(message)
|
||||
table.insert(logMessages, Time.format(Time.now(), '%H:%M:%S') .. ' - ' .. message)
|
||||
if #logMessages > 50 then
|
||||
table.remove(logMessages, 1)
|
||||
end
|
||||
logArea.text = table.concat(logMessages, '\n')
|
||||
end
|
||||
displayElement:hide()
|
||||
|
||||
local function showError(elementId, message)
|
||||
local element = gurt.select('#' .. elementId)
|
||||
@@ -32,189 +24,51 @@ local function hideError(elementId)
|
||||
element.classList:add('hidden')
|
||||
end
|
||||
|
||||
local function showModal(modalId)
|
||||
local modal = gurt.select('#' .. modalId)
|
||||
|
||||
modal.classList:remove('hidden')
|
||||
end
|
||||
|
||||
local function hideModal(modalId)
|
||||
local modal = gurt.select('#' .. modalId)
|
||||
|
||||
modal.classList:add('hidden')
|
||||
end
|
||||
|
||||
local function makeRequest(url, options)
|
||||
options = options or {}
|
||||
if authToken then
|
||||
options.headers = options.headers or {}
|
||||
options.headers.Authorization = 'Bearer ' .. authToken
|
||||
end
|
||||
return fetch(url, options)
|
||||
end
|
||||
|
||||
local function checkAuth()
|
||||
authToken = gurt.crumbs.get("auth_token")
|
||||
|
||||
if authToken then
|
||||
addLog('Found auth token, checking validity...')
|
||||
local response = makeRequest('gurt://localhost:4878/auth/me')
|
||||
print(table.tostring(response))
|
||||
if response:ok() then
|
||||
user = response:json()
|
||||
addLog('Authentication successful for user: ' .. user.username)
|
||||
updateUserInfo()
|
||||
loadDomains()
|
||||
loadTLDs()
|
||||
else
|
||||
addLog('Token invalid, redirecting to login...')
|
||||
--gurt.crumbs.delete('auth_token')
|
||||
--gurt.location.goto('../')
|
||||
end
|
||||
else
|
||||
addLog('No auth token found, redirecting to login...')
|
||||
gurt.location.goto('../')
|
||||
end
|
||||
end
|
||||
|
||||
local function logout()
|
||||
gurt.crumbs.delete('auth_token')
|
||||
addLog('Logged out successfully')
|
||||
gurt.location.goto("../")
|
||||
end
|
||||
|
||||
local function loadDomains()
|
||||
addLog('Loading domains...')
|
||||
local response = makeRequest('gurt://localhost:4878/domains?page=1&size=100')
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
domains = data.domains or {}
|
||||
addLog('Loaded ' .. #domains .. ' domains')
|
||||
renderDomains()
|
||||
else
|
||||
addLog('Failed to load domains: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function loadTLDs()
|
||||
addLog('Loading available TLDs...')
|
||||
local response = fetch('gurt://localhost:4878/tlds')
|
||||
|
||||
if response:ok() then
|
||||
tlds = response:json()
|
||||
addLog('Loaded ' .. #tlds .. ' TLDs')
|
||||
renderTLDSelector()
|
||||
else
|
||||
addLog('Failed to load TLDs: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function submitDomain(name, tld, ip)
|
||||
hideError('domain-error')
|
||||
addLog('Submitting domain: ' .. name .. '.' .. tld)
|
||||
|
||||
local response = makeRequest('gurt://localhost:4878/domain', {
|
||||
method = 'POST',
|
||||
headers = { ['Content-Type'] = 'application/json' },
|
||||
body = JSON.stringify({ name = name, tld = tld, ip = ip })
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
addLog('Domain submitted successfully: ' .. data.domain)
|
||||
|
||||
-- Update user registrations remaining
|
||||
user.registrations_remaining = user.registrations_remaining - 1
|
||||
updateUserInfo()
|
||||
|
||||
-- Clear form
|
||||
gurt.select('#domain-name').text = ''
|
||||
gurt.select('#domain-ip').text = ''
|
||||
|
||||
-- Refresh domains list
|
||||
loadDomains()
|
||||
else
|
||||
local error = response:text()
|
||||
showError('domain-error', 'Domain submission failed: ' .. error)
|
||||
addLog('Domain submission failed: ' .. error)
|
||||
end
|
||||
end
|
||||
|
||||
local function createInvite()
|
||||
addLog('Creating invite code...')
|
||||
local response = makeRequest('gurt://localhost:4878/auth/invite', { method = 'POST' })
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
local inviteCode = data.invite_code
|
||||
gurt.select('#invite-code-display').text = inviteCode
|
||||
addLog('Invite code created: ' .. inviteCode)
|
||||
showModal('invite-modal')
|
||||
else
|
||||
addLog('Failed to create invite: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function redeemInvite(code)
|
||||
hideError('redeem-error')
|
||||
addLog('Redeeming invite code: ' .. code)
|
||||
|
||||
local response = makeRequest('gurt://localhost:4878/auth/redeem-invite', {
|
||||
method = 'POST',
|
||||
headers = { ['Content-Type'] = 'application/json' },
|
||||
body = JSON.stringify({ invite_code = code })
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
addLog('Invite redeemed: +' .. data.registrations_added .. ' registrations')
|
||||
|
||||
-- Update user info
|
||||
user.registrations_remaining = user.registrations_remaining + data.registrations_added
|
||||
updateUserInfo()
|
||||
|
||||
-- Clear form
|
||||
gurt.select('#invite-code-input').text = ''
|
||||
else
|
||||
local error = response:text()
|
||||
showError('redeem-error', 'Failed to redeem invite: ' .. error)
|
||||
addLog('Failed to redeem invite: ' .. error)
|
||||
end
|
||||
end
|
||||
|
||||
-- UI rendering functions
|
||||
local function updateUserInfo()
|
||||
if user then
|
||||
userInfo.text = 'Welcome, ' .. user.username .. ' | Registrations remaining: ' .. user.registrations_remaining
|
||||
end
|
||||
userInfo.text = 'Welcome, ' .. user.username .. '!'
|
||||
end
|
||||
|
||||
local function renderTLDSelector()
|
||||
loadingElement:remove()
|
||||
|
||||
tldSelector.text = ''
|
||||
for i, tld in ipairs(tlds) do
|
||||
local option = gurt.create('div', {
|
||||
local i = 1
|
||||
local total = #tlds
|
||||
local intervalId
|
||||
|
||||
intervalId = gurt.setInterval(function()
|
||||
if i > total then
|
||||
gurt.clearInterval(intervalId)
|
||||
return
|
||||
end
|
||||
|
||||
local tld = tlds[i]
|
||||
local option = gurt.create('button', {
|
||||
text = '.' .. tld,
|
||||
style = 'tld-option',
|
||||
['data-tld'] = tld
|
||||
})
|
||||
|
||||
|
||||
option:on('click', function()
|
||||
-- Clear previous selection
|
||||
local options = gurt.selectAll('.tld-option')
|
||||
for j = 1, #options do
|
||||
options[j].classList:remove('tld-selected')
|
||||
end
|
||||
|
||||
|
||||
-- Select this option
|
||||
option.classList:add('tld-selected')
|
||||
end)
|
||||
|
||||
|
||||
tldSelector:append(option)
|
||||
end
|
||||
i = i + 1
|
||||
end, 16)
|
||||
end
|
||||
|
||||
local function renderDomains()
|
||||
local loadingElement = gurt.select('#domains-loading')
|
||||
loadingElement:remove()
|
||||
|
||||
domainsList.text = ''
|
||||
|
||||
if #domains == 0 then
|
||||
@@ -281,35 +135,153 @@ local function renderDomains()
|
||||
end
|
||||
end
|
||||
|
||||
local function updateDomainIP(name, tld, ip)
|
||||
addLog('Updating IP for ' .. name .. '.' .. tld .. ' to ' .. ip)
|
||||
|
||||
local response = makeRequest('gurt://localhost:4878/domain/' .. name .. '/' .. tld, {
|
||||
method = 'PUT',
|
||||
headers = { ['Content-Type'] = 'application/json' },
|
||||
body = JSON.stringify({ ip = ip })
|
||||
local function loadDomains()
|
||||
print('Loading domains...')
|
||||
local response = fetch('gurt://localhost:8877/domains?page=1&size=100', {
|
||||
headers = {
|
||||
Authorization = 'Bearer ' .. authToken
|
||||
}
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
addLog('Domain IP updated successfully')
|
||||
loadDomains()
|
||||
local data = response:json()
|
||||
domains = data.domains or {}
|
||||
print('Loaded ' .. #domains .. ' domains')
|
||||
renderDomains()
|
||||
else
|
||||
addLog('Failed to update domain IP: ' .. response:text())
|
||||
print('Failed to load domains: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function deleteDomain(name, tld)
|
||||
addLog('Deleting domain: ' .. name .. '.' .. tld)
|
||||
local function loadTLDs()
|
||||
print('Loading available TLDs...')
|
||||
local response = fetch('gurt://localhost:8877/tlds')
|
||||
|
||||
local response = makeRequest('gurt://localhost:4878/domain/' .. name .. '/' .. tld, {
|
||||
method = 'DELETE'
|
||||
if response:ok() then
|
||||
tlds = response:json()
|
||||
print('Loaded ' .. #tlds .. ' TLDs')
|
||||
renderTLDSelector()
|
||||
else
|
||||
print('Failed to load TLDs: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function checkAuth()
|
||||
authToken = gurt.crumbs.get("auth_token")
|
||||
|
||||
if authToken then
|
||||
print('Found auth token, checking validity...')
|
||||
local response = fetch('gurt://localhost:8877/auth/me', {
|
||||
headers = {
|
||||
Authorization = 'Bearer ' .. authToken
|
||||
}
|
||||
})
|
||||
print(table.tostring(response))
|
||||
if response:ok() then
|
||||
user = response:json()
|
||||
print('Authentication successful for user: ' .. user.username)
|
||||
updateUserInfo()
|
||||
loadDomains()
|
||||
loadTLDs()
|
||||
else
|
||||
print('Token invalid, redirecting to login...')
|
||||
gurt.crumbs.delete('auth_token')
|
||||
gurt.location.goto('../')
|
||||
end
|
||||
else
|
||||
print('No auth token found, redirecting to login...')
|
||||
gurt.location.goto('../')
|
||||
end
|
||||
end
|
||||
|
||||
local function logout()
|
||||
gurt.crumbs.delete('auth_token')
|
||||
print('Logged out successfully')
|
||||
gurt.location.goto("../")
|
||||
end
|
||||
|
||||
local function submitDomain(name, tld, ip)
|
||||
hideError('domain-error')
|
||||
print('Submitting domain: ' .. name .. '.' .. tld)
|
||||
|
||||
local response = fetch('gurt://localhost:8877/domain', {
|
||||
method = 'POST',
|
||||
headers = {
|
||||
['Content-Type'] = 'application/json',
|
||||
Authorization = 'Bearer ' .. authToken
|
||||
},
|
||||
body = JSON.stringify({ name = name, tld = tld, ip = ip })
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
addLog('Domain deleted successfully')
|
||||
local data = response:json()
|
||||
print('Domain submitted successfully: ' .. data.domain)
|
||||
|
||||
-- Update user registrations remaining
|
||||
user.registrations_remaining = user.registrations_remaining - 1
|
||||
updateUserInfo()
|
||||
|
||||
-- Clear form
|
||||
gurt.select('#domain-name').text = ''
|
||||
gurt.select('#domain-ip').text = ''
|
||||
|
||||
-- Refresh domains list
|
||||
loadDomains()
|
||||
else
|
||||
addLog('Failed to delete domain: ' .. response:text())
|
||||
local error = response:text()
|
||||
showError('domain-error', 'Domain submission failed: ' .. error)
|
||||
print('Domain submission failed: ' .. error)
|
||||
end
|
||||
end
|
||||
|
||||
local function createInvite()
|
||||
print('Creating invite code...')
|
||||
local response = fetch('gurt://localhost:8877/auth/invite', {
|
||||
method = 'POST',
|
||||
headers = {
|
||||
Authorization = 'Bearer ' .. authToken
|
||||
}
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
local inviteCode = data.invite_code
|
||||
displayElement.text = 'Invite code: ' .. inviteCode .. ' (copied to clipboard)'
|
||||
displayElement:show()
|
||||
Clipboard.write(inviteCode)
|
||||
print('Invite code created and copied to clipboard: ' .. inviteCode)
|
||||
else
|
||||
print('Failed to create invite: ' .. response:text())
|
||||
end
|
||||
end
|
||||
|
||||
local function redeemInvite(code)
|
||||
hideError('redeem-error')
|
||||
print('Redeeming invite code: ' .. code)
|
||||
|
||||
local response = fetch('gurt://localhost:8877/auth/redeem-invite', {
|
||||
method = 'POST',
|
||||
headers = {
|
||||
['Content-Type'] = 'application/json',
|
||||
Authorization = 'Bearer ' .. authToken
|
||||
},
|
||||
body = JSON.stringify({ invite_code = code })
|
||||
})
|
||||
|
||||
if response:ok() then
|
||||
local data = response:json()
|
||||
print('Invite redeemed: +' .. data.registrations_added .. ' registrations')
|
||||
|
||||
-- Update user info
|
||||
user.registrations_remaining = user.registrations_remaining + data.registrations_added
|
||||
updateUserInfo()
|
||||
|
||||
-- Clear form
|
||||
gurt.select('#invite-code-input').text = ''
|
||||
else
|
||||
local error = response:text()
|
||||
showError('redeem-error', 'Failed to redeem invite: ' .. error)
|
||||
print('Failed to redeem invite: ' .. error)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -349,16 +321,6 @@ gurt.select('#redeem-invite-btn'):on('click', function()
|
||||
end
|
||||
end)
|
||||
|
||||
gurt.select('#close-invite-modal'):on('click', function()
|
||||
hideModal('invite-modal')
|
||||
end)
|
||||
|
||||
gurt.select('#copy-invite-code'):on('click', function()
|
||||
local inviteCode = gurt.select('#invite-code-display').text
|
||||
Clipboard.write(inviteCode)
|
||||
addLog('Invite code copied to clipboard')
|
||||
end)
|
||||
|
||||
-- Initialize
|
||||
addLog('Dashboard initialized')
|
||||
print('Dashboard initialized')
|
||||
checkAuth()
|
||||
@@ -1,3 +1,7 @@
|
||||
if gurt.crumbs.get("auth_token") then
|
||||
gurt.location.goto("/dashboard.html")
|
||||
end
|
||||
|
||||
local submitBtn = gurt.select('#submit')
|
||||
local username_input = gurt.select('#username')
|
||||
local password_input = gurt.select('#password')
|
||||
@@ -8,7 +12,6 @@ function addLog(message)
|
||||
log_output.text = log_output.text .. message .. '\\n'
|
||||
end
|
||||
|
||||
print(gurt.location.href)
|
||||
submitBtn:on('submit', function(event)
|
||||
local username = event.data.username
|
||||
local password = event.data.password
|
||||
@@ -18,7 +21,7 @@ submitBtn:on('submit', function(event)
|
||||
password = password
|
||||
})
|
||||
print(request_body)
|
||||
local url = 'gurt://localhost:8080/auth/login'
|
||||
local url = 'gurt://localhost:8877/auth/login'
|
||||
local headers = {
|
||||
['Content-Type'] = 'application/json'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user