UI enhancement

This commit is contained in:
debu-2 2026-10-03 22:34:34 +05:30
parent 23239c5cb6
commit 53922952c6
13 changed files with 1076 additions and 260 deletions

View file

@ -1,3 +1,5 @@
import { senderDisplayName } from "./senderAvatar";
const CATEGORY_ORDER = ["Primary", "Updates", "Promotions", "Social", "Finance"];
export function emailSearchText(email) {
@ -88,6 +90,95 @@ export function attachmentCount(email) {
return Number(email.attachment_count || 0);
}
function emailTimestamp(email) {
const value = email.received_at || email.sent_at || email.created_at || email.updated_at;
if (!value) return null;
const date = new Date(value);
return Number.isNaN(date.getTime()) ? null : date;
}
function formatRelativeAge(date) {
if (!date) return "";
const hours = Math.floor((Date.now() - date.getTime()) / 3600000);
if (hours < 1) return "<1h";
if (hours < 24) return `${hours}h`;
return `${Math.floor(hours / 24)}d`;
}
function extractMeetingTime(text) {
const match = text.match(/\b(\d{1,2}:\d{2})\s*(am|pm)?/i)
|| text.match(/\b(\d{1,2})\s*(am|pm)\b/i);
if (!match) return null;
return match[0].replace(/\s+/g, "").toUpperCase();
}
function extractDeadline(text) {
if (/tomorrow/i.test(text)) return "Tomorrow";
const weekday = text.match(/\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/i);
if (weekday) {
return weekday[1].charAt(0).toUpperCase() + weekday[1].slice(1);
}
if (/today/i.test(text)) return "Today";
return null;
}
export function inboxContext(emails) {
const stats = inboxIntelligence(emails);
const needsReply = emails
.filter((email) =>
/please|reply|respond|confirm|review|attached|need your|waiting|action required/.test(
emailSearchText(email),
),
)
.sort((left, right) => {
const leftDate = emailTimestamp(left)?.getTime() || 0;
const rightDate = emailTimestamp(right)?.getTime() || 0;
return rightDate - leftDate;
})
.slice(0, 4)
.map((email) => ({
id: email.id,
name: senderDisplayName(email),
age: formatRelativeAge(emailTimestamp(email)),
}));
const today = [];
emails.forEach((email) => {
const text = emailSearchText(email);
if (!/meet|meeting|call|interview|sync|calendar/.test(text)) return;
const time = extractMeetingTime(text);
if (!time) return;
const label = (email.subject || "Meeting").trim().slice(0, 42);
if (!today.some((item) => item.time === time && item.label === label)) {
today.push({ time, label });
}
});
const deadlines = [];
emails.forEach((email) => {
const text = emailSearchText(email);
if (!/invoice|proposal|payment|due|deadline|bill/.test(text)) return;
const due = extractDeadline(text);
if (!due) return;
const label = (email.subject || "Deadline")
.split(/[-–:|]/)
.map((part) => part.trim())
.find(Boolean)
?.slice(0, 28) || "Deadline";
if (!deadlines.some((item) => item.label === label && item.due === due)) {
deadlines.push({ label, due });
}
});
return {
stats,
needsReply,
today: today.slice(0, 4),
deadlines: deadlines.slice(0, 4),
};
}
export function labelCounts(emails) {
const counts = {
Important: 0,