Skip to content

Commit d7add44

Browse files
Update script.js
1 parent 49d3dbe commit d7add44

File tree

1 file changed

+114
-71
lines changed

1 file changed

+114
-71
lines changed

static/script.js

Lines changed: 114 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,135 +3,178 @@ let refreshInterval;
33
async function loadEmailAccounts() {
44
try {
55
const response = await fetch('/api/email-accounts');
6+
if (!response.ok) {
7+
throw new Error(`HTTP error! status: ${response.status}`);
8+
}
69
const accounts = await response.json();
710
const select = document.getElementById('destination');
811

9-
select.innerHTML = '<option value="">Select destination email</option>';
10-
accounts.forEach(email => {
11-
const option = document.createElement('option');
12-
option.value = email;
13-
option.textContent = email;
14-
select.appendChild(option);
15-
});
12+
if (accounts.error) {
13+
select.innerHTML = '<option value="">Error loading accounts</option>';
14+
console.error('API Error:', accounts.error);
15+
return;
16+
}
17+
18+
// Clear and rebuild options
19+
select.innerHTML = '<option value="">Select destination</option>';
20+
21+
// Add email accounts from DirectAdmin
22+
if (accounts.length > 0) {
23+
const optgroup = document.createElement('optgroup');
24+
optgroup.label = 'Email Accounts';
25+
accounts.forEach(email => {
26+
const option = document.createElement('option');
27+
option.value = email;
28+
option.textContent = email;
29+
optgroup.appendChild(option);
30+
});
31+
select.appendChild(optgroup);
32+
}
33+
34+
// Add custom email option
35+
const customOption = document.createElement('option');
36+
customOption.value = 'custom';
37+
customOption.textContent = '➕ Custom Email Address...';
38+
select.appendChild(customOption);
39+
1640
} catch (error) {
1741
console.error('Error loading email accounts:', error);
42+
document.getElementById('destination').innerHTML = '<option value="">Error loading accounts</option>';
43+
}
44+
}
45+
46+
function toggleCustomEmail() {
47+
const select = document.getElementById('destination');
48+
const customGroup = document.getElementById('customEmailGroup');
49+
const customInput = document.getElementById('customEmail');
50+
51+
if (select.value === 'custom') {
52+
customGroup.style.display = 'block';
53+
customInput.required = true;
54+
customInput.focus();
55+
} else {
56+
customGroup.style.display = 'none';
57+
customInput.required = false;
58+
customInput.value = '';
1859
}
1960
}
2061

2162
async function loadForwarders() {
2263
try {
2364
const response = await fetch('/api/forwarders');
65+
if (!response.ok) {
66+
throw new Error(`HTTP error! status: ${response.status}`);
67+
}
2468
const forwarders = await response.json();
2569
const list = document.getElementById('forwardersList');
2670

71+
if (forwarders.error) {
72+
list.innerHTML = '<p class="error">Error loading forwarders: ' + forwarders.error + '</p>';
73+
return;
74+
}
75+
2776
if (forwarders.length === 0) {
28-
list.innerHTML = '<p>No forwarders configured</p>';
77+
list.innerHTML = '<p class="no-forwarders">No forwarders configured</p>';
2978
return;
3079
}
3180

81+
// Create formatted list of forwarders
3282
list.innerHTML = forwarders.map(f => `
3383
<div class="forwarder-item">
34-
<div>
35-
<strong>${f.alias}</strong> → ${f.destinations.join(', ')}
84+
<div class="forwarder-info">
85+
<span class="forwarder-alias">${f.alias}</span>
86+
<span class="forwarder-arrow">→</span>
87+
<div class="forwarder-destinations">
88+
${f.destinations.map(dest => `<span class="destination-tag">${dest}</span>`).join('')}
89+
</div>
3690
</div>
3791
<button class="delete-btn" onclick="deleteForwarder('${f.alias}')">Delete</button>
3892
</div>
3993
`).join('');
4094
} catch (error) {
4195
console.error('Error loading forwarders:', error);
42-
}
43-
}
44-
45-
async function createForwarder(event) {
46-
event.preventDefault();
47-
48-
const alias = document.getElementById('alias').value;
49-
const destination = document.getElementById('destination').value;
50-
51-
try {
52-
const response = await fetch('/api/forwarders', {
53-
method: 'POST',
54-
headers: {
55-
'Content-Type': 'application/json',
56-
},
57-
body: JSON.stringify({ alias, destination })
58-
});
59-
60-
const result = await response.json();
61-
if (result.success) {
62-
document.getElementById('createForwarderForm').reset();
63-
loadForwarders();
64-
} else {
65-
alert('Failed to create forwarder');
66-
}
67-
} catch (error) {
68-
console.error('Error creating forwarder:', error);
69-
alert('Error creating forwarder');
96+
document.getElementById('forwardersList').innerHTML = '<p class="error">Error loading forwarders</p>';
7097
}
7198
}
7299

73100
async function deleteForwarder(alias) {
74-
if (!confirm(`Delete forwarder ${alias}?`)) return;
101+
if (!confirm(`Are you sure you want to delete the forwarder "${alias}"?`)) {
102+
return;
103+
}
75104

76105
try {
77-
const response = await fetch(`/api/forwarders/${alias}`, {
106+
const response = await fetch(`/api/forwarders/${encodeURIComponent(alias)}`, {
78107
method: 'DELETE'
79108
});
80109

81-
const result = await response.json();
82-
if (result.success) {
110+
if (response.ok) {
83111
loadForwarders();
84112
} else {
85113
alert('Failed to delete forwarder');
86114
}
87115
} catch (error) {
88-
console.error('Error deleting forwarder:', error);
116+
console.error('Error:', error);
89117
alert('Error deleting forwarder');
90118
}
91119
}
92120

93-
async function toggle2FA() {
94-
const action = confirm('Toggle 2FA status?');
95-
if (!action) return;
121+
document.getElementById('createForwarderForm').addEventListener('submit', async (e) => {
122+
e.preventDefault();
123+
124+
const alias = document.getElementById('alias').value;
125+
const destinationSelect = document.getElementById('destination').value;
126+
let destination;
127+
128+
// Check if custom email is selected
129+
if (destinationSelect === 'custom') {
130+
destination = document.getElementById('customEmail').value;
131+
if (!destination) {
132+
alert('Please enter a custom email address');
133+
return;
134+
}
135+
} else {
136+
destination = destinationSelect;
137+
}
138+
139+
if (!destination) {
140+
alert('Please select or enter a destination email');
141+
return;
142+
}
96143

97144
try {
98-
const response = await fetch('/setup-2fa', {
145+
const response = await fetch('/api/forwarders', {
99146
method: 'POST',
100147
headers: {
101-
'Content-Type': 'application/x-www-form-urlencoded',
148+
'Content-Type': 'application/json',
102149
},
103-
body: 'enable=true'
150+
body: JSON.stringify({ alias, destination })
104151
});
105152

106-
if (response.redirected) {
107-
window.location.reload();
153+
if (response.ok) {
154+
document.getElementById('createForwarderForm').reset();
155+
document.getElementById('customEmailGroup').style.display = 'none';
156+
loadForwarders();
108157
} else {
109-
const data = await response.json();
110-
if (data.qr_code) {
111-
document.getElementById('qrCode').innerHTML =
112-
`<img src="data:image/png;base64,${data.qr_code}" alt="QR Code">`;
113-
document.getElementById('totpSecret').textContent = data.secret;
114-
document.getElementById('qrModal').style.display = 'flex';
115-
}
158+
alert('Failed to create forwarder');
116159
}
117160
} catch (error) {
118-
console.error('Error toggling 2FA:', error);
161+
console.error('Error:', error);
162+
alert('Error creating forwarder');
119163
}
120-
}
121-
122-
function closeModal() {
123-
document.getElementById('qrModal').style.display = 'none';
124-
window.location.reload();
125-
}
164+
});
126165

127166
// Initialize
128167
document.addEventListener('DOMContentLoaded', () => {
129-
if (document.getElementById('createForwarderForm')) {
130-
document.getElementById('createForwarderForm').addEventListener('submit', createForwarder);
131-
loadEmailAccounts();
132-
loadForwarders();
168+
loadEmailAccounts();
169+
loadForwarders();
170+
171+
// Refresh forwarders every 60 seconds
172+
refreshInterval = setInterval(loadForwarders, 60000);
173+
});
133174

134-
// Refresh every 60 seconds
135-
refreshInterval = setInterval(loadForwarders, 60000);
175+
// Cleanup on page unload
176+
window.addEventListener('beforeunload', () => {
177+
if (refreshInterval) {
178+
clearInterval(refreshInterval);
136179
}
137180
});

0 commit comments

Comments
 (0)