// ===== Supabase Config =====
const SUPABASE_URL = "PASTE_SUPABASE_PROJECT_URL";
const SUPABASE_ANON_KEY = "PASTE_SUPABASE_ANON_KEY";
// CDN client exposed as "supabase" global, we create instance as "sb"
const sb = window.supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
// ===== Helpers =====
function toDateStr(d) {
const dt = new Date(d);
const y = dt.getFullYear();
const m = String(dt.getMonth() + 1).padStart(2, "0");
const day = String(dt.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
}
function addMonths(dateStr, months) {
const d = new Date(dateStr);
const day = d.getDate();
d.setMonth(d.getMonth() + months);
if (d.getDate() < day) d.setDate(0);
return toDateStr(d);
}
function addYears(dateStr, years) {
const d = new Date(dateStr);
const m = d.getMonth();
d.setFullYear(d.getFullYear() + years);
if (d.getMonth() !== m) d.setDate(0);
return toDateStr(d);
}
function daysLeft(renewalDateStr) {
const today = new Date(); today.setHours(0,0,0,0);
const r = new Date(renewalDateStr); r.setHours(0,0,0,0);
return Math.ceil((r - today) / (1000 * 60 * 60 * 24));
}
function statusFromDays(d) {
if (d < 0) return "overdue";
if (d <= 7) return "urgent";
if (d <= 30) return "due";
return "ok";
}
function badgeHTML(st, d) {
if (st === "overdue") return `Overdue (${d})`;
if (st === "urgent") return `Urgent (${d})`;
if (st === "due") return `Due Soon (${d})`;
return `Active (${d})`;
}
function escapeHtml(str){
return String(str ?? "").replace(/[&<>"']/g, s => ({
"&":"&","<":"<",">":">",'"':""","'":"'"
}[s]));
}
// ===== Backup / Anti-Data-Loss (JSON Export from DB) =====
async function exportBackupJSON(){
const [clients, services, payments] = await Promise.all([
sb.from("clients").select("*").order("created_at", {ascending:false}),
sb.from("services").select("*").order("created_at", {ascending:false}),
sb.from("payments").select("*").order("created_at", {ascending:false}),
]);
if (clients.error || services.error || payments.error) {
alert("Backup export failed. Check console.");
console.error(clients.error, services.error, payments.error);
return;
}
const payload = {
exported_at: new Date().toISOString(),
clients: clients.data,
services: services.data,
payments: payments.data
};
const blob = new Blob([JSON.stringify(payload, null, 2)], {type:"application/json"});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "hosting-renewals-backup.json";
a.click();
URL.revokeObjectURL(url);
}