Skip to content

Commit ba85922

Browse files
committed
Add domain credentials editing functionality
Introduces backend and frontend support for editing domain credentials. Adds an 'Edit Domain' modal, updates CSS for the credentials form, and implements the 'updateDomain' action in PHP to handle credential updates.
1 parent f5029d8 commit ba85922

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

src/public/css/styles.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,3 +691,33 @@ select:focus {
691691
.toggle-cred:hover {
692692
color: var(--primary);
693693
}
694+
695+
#editCredentialsContainer {
696+
display: flex;
697+
flex-direction: column;
698+
gap: 0.75rem;
699+
margin-top: 0.5rem;
700+
}
701+
702+
#editCredentialsContainer label {
703+
font-weight: 600;
704+
font-size: 0.95rem;
705+
color: var(--text);
706+
}
707+
708+
#editCredentialsContainer input {
709+
width: 100%;
710+
padding: 0.65rem 0.9rem;
711+
font-size: 1rem;
712+
border: 1px solid var(--border);
713+
border-radius: 6px;
714+
outline: none;
715+
background: var(--card);
716+
color: var(--text);
717+
transition: border-color 0.2s, box-shadow 0.2s;
718+
}
719+
720+
#editCredentialsContainer input:focus {
721+
border-color: var(--primary);
722+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
723+
}

src/public/domains.php

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,34 @@
2020
try {
2121
switch ($action) {
2222

23+
case 'updateDomain':
24+
$domainName = trim($input['domain'] ?? '');
25+
$credentials = $input['credentials'] ?? [];
26+
27+
if (!$domainName) {
28+
echo json_encode(['success' => false, 'error' => 'Missing domain parameter.']);
29+
exit;
30+
}
31+
32+
$existing = $domainManager->find(['domain' => $domainName]);
33+
if (!$existing) {
34+
echo json_encode(['success' => false, 'error' => 'Domain not found.']);
35+
exit;
36+
}
37+
38+
$existing->credentials = $credentials;
39+
$domainManager->save($existing);
40+
41+
echo json_encode([
42+
'success' => true,
43+
'domain' => [
44+
'domain' => $existing->domain,
45+
'provider' => $existing->provider,
46+
'ip' => gethostbyname($existing->domain),
47+
'updated' => $existing->Updated
48+
]
49+
]);
50+
exit;
2351
case 'createDomain':
2452
$domain = trim($input['domain'] ?? '');
2553
$provider = trim($input['provider'] ?? '');
@@ -174,6 +202,24 @@
174202
</div>
175203
</div>
176204
</div>
205+
<div id="editDomainModal" class="modal">
206+
<div class="modal-content large">
207+
<h3>Edit Domain</h3>
208+
<label for="editDomainName">Domain</label>
209+
<input type="text" id="editDomainName" readonly>
210+
211+
<label for="editProvider">Provider</label>
212+
<input type="text" id="editProvider" readonly>
213+
214+
<div id="editCredentialsContainer" class="credentials-group"></div>
215+
216+
<div class="modal-actions">
217+
<button id="cancelEditDomain" class="secondary">Cancel</button>
218+
<button id="saveEditDomain">Save Changes</button>
219+
</div>
220+
<p id="editDomainError" class="error-text"></p>
221+
</div>
222+
</div>
177223
<script>
178224
document.addEventListener('DOMContentLoaded', () => {
179225
const table = document.getElementById('domainTable');
@@ -364,7 +410,79 @@ function appendDomainRow(d) {
364410
e.target.classList.toggle('ti-eye-off');
365411
}
366412
});
413+
table.addEventListener('click', e => {
414+
if (!e.target.closest('button')) return;
415+
const btn = e.target.closest('button');
416+
if (!btn.textContent.includes('Edit')) return;
417+
418+
const domain = btn.closest('tr').children[0].textContent.trim();
419+
420+
fetch(window.location.href, {
421+
method: 'POST',
422+
headers: { 'Content-Type': 'application/json' },
423+
body: JSON.stringify({ action: 'getDomainDetails', domain })
424+
})
425+
.then(res => res.json())
426+
.then(data => {
427+
if (!data.success) return alert(data.error || 'Failed to load domain info.');
428+
429+
const d = data.domain;
430+
document.getElementById('editDomainName').value = d.domain;
431+
document.getElementById('editProvider').value = d.provider;
432+
433+
const container = document.getElementById('editCredentialsContainer');
434+
container.innerHTML = '';
435+
436+
Object.entries(d.credentials || {}).forEach(([key, val]) => {
437+
const label = document.createElement('label');
438+
label.textContent = key;
439+
const input = document.createElement('input');
440+
input.type = 'text';
441+
input.value = val;
442+
input.dataset.key = key;
443+
container.appendChild(label);
444+
container.appendChild(input);
445+
});
446+
447+
document.getElementById('editDomainError').style.display = 'none';
448+
document.getElementById('editDomainModal').style.display = 'flex';
449+
})
450+
.catch(console.error);
451+
});
452+
453+
document.getElementById('cancelEditDomain').addEventListener('click', () => {
454+
document.getElementById('editDomainModal').style.display = 'none';
455+
});
367456

457+
document.getElementById('saveEditDomain').addEventListener('click', () => {
458+
const domain = document.getElementById('editDomainName').value.trim();
459+
const credentials = {};
460+
document.querySelectorAll('#editCredentialsContainer input').forEach(inp => {
461+
credentials[inp.dataset.key] = inp.value.trim();
462+
});
463+
464+
fetch(window.location.href, {
465+
method: 'POST',
466+
headers: { 'Content-Type': 'application/json' },
467+
body: JSON.stringify({ action: 'updateDomain', domain, credentials })
468+
})
469+
.then(res => res.json())
470+
.then(data => {
471+
const err = document.getElementById('editDomainError');
472+
if (!data.success) {
473+
err.textContent = data.error;
474+
err.style.display = 'block';
475+
return;
476+
}
477+
478+
document.getElementById('editDomainModal').style.display = 'none';
479+
err.style.display = 'none';
480+
481+
// Optional: update "Updated" info visually or re-fetch row
482+
alert('Domain updated successfully!');
483+
})
484+
.catch(console.error);
485+
});
368486
});
369487
</script>
370488
{% endblock %}

0 commit comments

Comments
 (0)