local user = nil local domain = nil local records = {} local authToken = nil local domainName = nil local domainTitle = gurt.select('#domain-title') local domainStatus = gurt.select('#domain-status') local recordsList = gurt.select('#records-list') local loadingElement = gurt.select('#records-loading') local function showError(elementId, message) local element = gurt.select('#' .. elementId) element.text = message element.classList:remove('hidden') end local function hideError(elementId) local element = gurt.select('#' .. elementId) element.classList:add('hidden') end -- Forward declarations local loadRecords local renderRecords local function deleteRecord(recordId) print('Deleting DNS record: ' .. recordId) local response = fetch('gurt://localhost:8877/domain/' .. domainName .. '/records/' .. recordId, { method = 'DELETE', headers = { Authorization = 'Bearer ' .. authToken } }) if response:ok() then print('DNS record deleted successfully') -- Remove the record from local records array for i = #records, 1, -1 do if records[i].id == recordId then table.remove(records, i) break end end -- Re-render the entire list from scratch renderRecords() else print('Failed to delete DNS record: ' .. response:text()) end end -- Actual implementation loadRecords = function() print('Loading DNS records for: ' .. domainName) local response = fetch('gurt://localhost:8877/domain/' .. domainName .. '/records', { headers = { Authorization = 'Bearer ' .. authToken } }) if response:ok() then records = response:json() print('Loaded ' .. #records .. ' DNS records') renderRecords() else print('Failed to load DNS records: ' .. response:text()) records = {} renderRecords() end end renderRecords = function(appendOnly) if loadingElement then loadingElement:remove() loadingElement = nil end -- Clear everything if not appending if not appendOnly then local children = recordsList.children while #children > 0 do children[1]:remove() children = recordsList.children end end if #records == 0 then local emptyMessage = gurt.create('div', { text = 'No DNS records found. Add your first record below!', style = 'text-center text-[#6b7280] py-8', id = '404' }) recordsList:append(emptyMessage) return else local err = gurt.select('#404') if err then gurt.select('#404'):remove() end end -- Create header only if not appending or if list is empty if not appendOnly or #recordsList.children == 0 then local header = gurt.create('div', { style = 'w-full flex justify-between gap-4 p-4 bg-gray-600 font-bold border-b rounded-xl' }) local typeHeader = gurt.create('div', { text = 'Type' }) local nameHeader = gurt.create('div', { text = 'Name' }) local valueHeader = gurt.create('div', { text = 'Value' }) local ttlHeader = gurt.create('div', { text = 'TTL' }) local actionsHeader = gurt.create('div', { text = 'Actions' }) header:append(typeHeader) header:append(nameHeader) header:append(valueHeader) header:append(ttlHeader) header:append(actionsHeader) recordsList:append(header) end -- Create records list - when appending, only render the last record; otherwise render all local startIndex = appendOnly and #records or 1 for i = startIndex, #records do local record = records[i] local row = gurt.create('div', { style = 'w-full flex justify-between gap-4 p-4 border-b border-gray-600 hover:bg-[rgba(244, 67, 54, 0.2)]' }) local typeCell = gurt.create('div', { text = record.type, style = 'font-bold' }) local nameCell = gurt.create('div', { text = record.name or '@' }) local valueCell = gurt.create('div', { text = record.value, style = 'font-mono text-sm break-all' }) local ttlCell = gurt.create('div', { text = record.ttl or '3600' }) local actionsCell = gurt.create('div') local deleteBtn = gurt.create('button', { text = 'Delete', style = 'danger-btn text-xs px-2 py-1' }) deleteBtn:on('click', function() if deleteBtn.text == 'Delete' then deleteBtn.text = 'Confirm Delete' else deleteRecord(record.id) end end) actionsCell:append(deleteBtn) row:append(typeCell) row:append(nameCell) row:append(valueCell) row:append(ttlCell) row:append(actionsCell) recordsList:append(row) end end local function getDomainNameFromURL() local nameParam = gurt.location.query.get('name') if nameParam then return nameParam:gsub('%%%.', '.') end return nil end local function updateDomainInfo() if domain then domainTitle.text = domain.name .. '.' .. domain.tld domainStatus.text = 'Status: ' .. (domain.status or 'Unknown') end end local function loadDomain() print('Loading domain details for: ' .. domainName) local response = fetch('gurt://localhost:8877/domain/' .. domainName, { headers = { Authorization = 'Bearer ' .. authToken } }) if response:ok() then domain = response:json() print('Loaded domain details') updateDomainInfo() loadRecords() else print('Failed to load domain: ' .. response:text()) --gurt.location.goto('/dashboard.html') 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 } }) if response:ok() then user = response:json() print('Authentication successful for user: ' .. user.username) domainName = getDomainNameFromURL() if domainName then loadDomain() else print('No domain name in URL, redirecting to dashboard') --gurt.location.goto('/dashboard.html') end 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 addRecord(type, name, value, ttl) hideError('record-error') print('Adding DNS record: ' .. type .. ' ' .. name .. ' ' .. value) print('Network request details:') print(' URL: gurt://localhost:8877/domain/' .. domainName .. '/records') print(' Method: POST') print(' Auth token: ' .. (authToken and 'present' or 'missing')) print(' Domain name: ' .. (domainName or 'nil')) local response = fetch('gurt://localhost:8877/domain/' .. domainName .. '/records', { method = 'POST', headers = { ['Content-Type'] = 'application/json', Authorization = 'Bearer ' .. authToken }, body = JSON.stringify({ type = type, name = name, value = value, ttl = ttl }) }) print('Response received: ' .. tostring(response)) if response then print('Response status: ' .. tostring(response.status)) print('Response ok: ' .. tostring(response:ok())) if response:ok() then print('DNS record added successfully') -- Clear form gurt.select('#record-name').value = '' gurt.select('#record-value').value = '' gurt.select('#record-ttl').value = '3600' -- Add the new record to existing records array local newRecord = response:json() if newRecord and newRecord.id then -- Server returned the created record, add it to our local array table.insert(records, newRecord) -- Check if we had no records before (showing empty message) local wasEmpty = (#records == 1) -- If this is the first record if wasEmpty then -- Full re-render to replace empty message with proper table renderRecords(false) else -- Just append the new record to existing table renderRecords(true) end else -- Server didn't return record details, reload to get the actual data loadRecords() end else local error = response:text() showError('record-error', 'Failed to add record: ' .. error) print('Failed to add DNS record: ' .. error) end else print('No response received from server') showError('record-error', 'No response from server - connection failed') print('Failed to add DNS record: No response') end end local function logout() gurt.crumbs.delete('auth_token') print('Logged out successfully') --gurt.location.goto("../") end local function goBack() --gurt.location.goto("/dashboard.html") end -- Function to update help text based on record type local function updateHelpText() local recordType = gurt.select('#record-type').value -- Hide all help texts local helpTypes = {'A', 'AAAA', 'CNAME', 'TXT', 'NS'} for _, helpType in ipairs(helpTypes) do local helpElement = gurt.select('#help-' .. helpType) if helpElement then helpElement.classList:add('hidden') end end -- Show the relevant help text local currentHelp = gurt.select('#help-' .. recordType) if currentHelp then currentHelp.classList:remove('hidden') end -- Update placeholder text based on record type local valueInput = gurt.select('#record-value') if recordType == 'A' then valueInput.placeholder = '192.168.1.1' elseif recordType == 'AAAA' then valueInput.placeholder = '2001:db8::1' elseif recordType == 'CNAME' or recordType == 'NS' then valueInput.placeholder = 'example.com' elseif recordType == 'TXT' then valueInput.placeholder = 'Any text content' end end -- Event handlers gurt.select('#logout-btn'):on('click', logout) gurt.select('#back-btn'):on('click', goBack) gurt.select('#record-type'):on('change', updateHelpText) gurt.select('#add-record-btn'):on('click', function() local recordType = gurt.select('#record-type').value local recordName = gurt.select('#record-name').value local recordValue = gurt.select('#record-value').value local recordTTL = tonumber(gurt.select('#record-ttl').value) or 3600 if not recordValue or recordValue == '' then showError('record-error', 'Record value is required') return end if not recordName or recordName == '' then recordName = '@' end addRecord(recordType, recordName, recordValue, recordTTL) end) -- Initialize print('Domain management page initialized') updateHelpText() -- Set initial help text checkAuth()