appearence overhall

This commit is contained in:
Brandon4466
2025-06-07 03:08:38 -07:00
parent 5b86d31cfd
commit f2503d5ec9
4 changed files with 337 additions and 78 deletions

154
main.js
View File

@@ -59,7 +59,7 @@ if (document.getElementById('loginForm')) {
}
// Inbox
if (document.getElementById('inboxList')) {
if (document.getElementById('email-list')) {
const { username, password } = getCredentials();
if (!username || !password) {
window.location.href = 'login.html';
@@ -70,8 +70,6 @@ if (document.getElementById('inboxList')) {
.then(res => res.json())
.then(emails => {
if (!Array.isArray(emails)) throw new Error('Invalid mailbox response');
// Determine current user's full address (username!domain if possible)
// Try to find domain from any received or sent email
let userDomain = null;
for (const email of emails) {
if (email.to === username && email.domain) {
@@ -84,50 +82,85 @@ if (document.getElementById('inboxList')) {
}
}
const userFull = userDomain ? `${username}!${userDomain}` : username;
// Inbox: emails where 'to!domain' matches current user
const inboxEmails = emails.filter(email => {
if (!email.to) return false;
const toFull = email.domain ? `${email.to}!${email.domain}` : email.to;
return toFull === userFull;
});
// Sent: emails where 'from!domain' matches current user
const sentEmails = emails.filter(email => {
if (!email.from) return false;
const fromFull = email.domain ? `${email.from}!${email.domain}` : email.from;
return fromFull === userFull;
});
let html = '';
html += '<h3>Inbox</h3>';
if (inboxEmails.length === 0) {
html += '<p>No emails.</p>';
} else {
html += inboxEmails.map(email => {
const fromDisplay = email.domain ? `${email.from}!${email.domain}` : email.from;
return `
<div class="email-item">
<strong>From:</strong> ${fromDisplay}<br>
<strong>Subject:</strong> ${email.subject}<br>
<div>${email.body}</div>
</div>
`;
}).join('');
let currentFolder = 'inbox';
let selectedEmail = null;
function renderList() {
const list = currentFolder === 'inbox' ? inboxEmails : sentEmails;
let html = `<div class="email-list-section"><div class="email-list-title">${currentFolder === 'inbox' ? 'Inbox' : 'Sent'}</div>`;
if (list.length === 0) {
html += '<p>No emails.</p>';
} else {
html += list.map((email, idx) => {
const display = currentFolder === 'inbox'
? (email.domain ? `${email.from}!${email.domain}` : email.from)
: (email.domain ? `${email.to}!${email.domain}` : email.to);
const fromto = currentFolder === 'inbox' ? `From: ${display}` : `To: ${display}`;
return `<div class="email-list-item${selectedEmail === idx ? ' selected' : ''}" data-idx="${idx}">
<div class="subject">${email.subject}</div>
<div class="fromto">${fromto}</div>
</div>`;
}).join('');
}
html += '</div>';
document.getElementById('email-list').innerHTML = html;
// Add click listeners
document.querySelectorAll('.email-list-item').forEach(item => {
item.onclick = function() {
selectedEmail = parseInt(this.getAttribute('data-idx'));
renderList();
renderDetail();
};
});
}
html += '<h3>Sent</h3>';
if (sentEmails.length === 0) {
html += '<p>No sent emails.</p>';
} else {
html += sentEmails.map(email => {
const toDisplay = email.domain ? `${email.to}!${email.domain}` : email.to;
return `
<div class="email-item">
<strong>To:</strong> ${toDisplay}<br>
<strong>Subject:</strong> ${email.subject}<br>
<div>${email.body}</div>
function renderDetail() {
const list = currentFolder === 'inbox' ? inboxEmails : sentEmails;
if (selectedEmail == null || !list[selectedEmail]) {
document.getElementById('email-detail').innerHTML = '';
return;
}
const email = list[selectedEmail];
const fromDisplay = email.domain ? `${email.from}!${email.domain}` : email.from;
const toDisplay = email.domain ? `${email.to}!${email.domain}` : email.to;
document.getElementById('email-detail').innerHTML = `
<div class="email-detail-content">
<div class="email-detail-header">
<div><strong>From:</strong> ${fromDisplay}</div>
<div><strong>To:</strong> ${toDisplay}</div>
<div><strong>Subject:</strong> ${email.subject}</div>
</div>
`;
}).join('');
<div class="email-detail-body">${email.body}</div>
</div>
`;
}
document.getElementById('inboxList').innerHTML = html;
// Sidebar folder switching
document.getElementById('sidebar-inbox').onclick = function() {
currentFolder = 'inbox';
selectedEmail = null;
document.getElementById('sidebar-inbox').classList.add('active');
document.getElementById('sidebar-sent').classList.remove('active');
renderList();
renderDetail();
};
document.getElementById('sidebar-sent').onclick = function() {
currentFolder = 'sent';
selectedEmail = null;
document.getElementById('sidebar-inbox').classList.remove('active');
document.getElementById('sidebar-sent').classList.add('active');
renderList();
renderDetail();
};
renderList();
renderDetail();
})
.catch(err => {
document.getElementById('inboxError').innerText = 'Failed to load inbox.';
@@ -174,3 +207,56 @@ if (document.getElementById('sendForm')) {
}
};
}
// Compose Overlay logic
if (document.getElementById('openComposeBtn')) {
const overlay = document.getElementById('composeOverlay');
const openBtn = document.getElementById('openComposeBtn');
const closeBtn = document.getElementById('closeComposeBtn');
const form = document.getElementById('composeForm');
const errorP = document.getElementById('composeError');
openBtn.onclick = function() {
overlay.style.display = 'flex';
form.reset();
errorP.innerText = '';
};
closeBtn.onclick = function() {
overlay.style.display = 'none';
};
form.onsubmit = async function(e) {
e.preventDefault();
const { username, password } = getCredentials();
if (!username || !password) {
window.location.href = 'login.html';
return;
}
const toField = document.getElementById('composeTo').value.trim();
if (!/^\w+!.+/.test(toField)) {
errorP.innerText = 'Recipient must be in the format username!domain';
return;
}
let to = toField;
let domain = '';
if (toField.includes('!')) {
[to, domain] = toField.split('!');
}
const subject = document.getElementById('composeSubject').value;
const body = document.getElementById('composeBody').value;
const email = domain ? { from: username, to, domain, subject, body } : { from: username, to, subject, body };
const res = await fetch('http://localhost:8080/email', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa(username + ':' + password)
},
body: JSON.stringify(email)
});
if (res.ok) {
overlay.style.display = 'none';
location.reload();
} else {
const err = await res.text();
errorP.innerText = err;
}
};
}