Divine Secretaries

/* Modern Dashboard Styling */ :root { –primary: #1e3a8a; –accent: #f59e0b; –bg: #f3f4f6; –text: #1f2937; –white: #ffffff; –green: #10b981; –red: #ef4444; } #dfm-root { font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif; background: var(–bg); min-height: 800px; display: flex; flex-direction: column; border: 1px solid #ccc; } /* Login Screen */ #dfm-login { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 600px; background: var(–primary); color: white; } .login-box { background: white; padding: 40px; border-radius: 8px; color: var(–text); width: 300px; text-align: center; box-shadow: 0 10px 25px rgba(0,0,0,0.2); } .login-box input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .btn-main { background: var(–primary); color: white; border: none; padding: 10px 20px; cursor: pointer; border-radius: 4px; font-weight: bold; width: 100%; } .btn-main:hover { background: #172554; } /* Dashboard Layout */ #dfm-main { display: none; flex: 1; display: flex; height: 100%; } .dfm-sidebar { width: 250px; background: var(–primary); color: white; display: flex; flex-direction: column; padding-top: 20px; flex-shrink: 0; } .dfm-sidebar h3 { text-align: center; margin-bottom: 30px; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 15px; } .nav-item { padding: 15px 20px; cursor: pointer; transition: 0.2s; color: #dbeafe; display: flex; align-items: center; gap: 10px; } .nav-item:hover, .nav-item.active { background: rgba(255,255,255,0.1); color: var(–accent); border-left: 4px solid var(–accent); } .dfm-content { flex: 1; padding: 30px; overflow-y: auto; background: var(–bg); } .section-view { display: none; } .section-view.active { display: block; animation: fadeIn 0.3s; } /* Cards & Tables */ .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; } .stat-card { background: var(–white); padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-top: 4px solid var(–primary); } .stat-card h2 { margin: 0; font-size: 2em; color: var(–primary); } .dfm-panel { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); margin-bottom: 20px; } table.dfm-table { width: 100%; border-collapse: collapse; margin-top: 15px; font-size: 0.9em; } table.dfm-table th { background: #f8fafc; text-align: left; padding: 12px; border-bottom: 2px solid #e2e8f0; color: #64748b; } table.dfm-table td { padding: 12px; border-bottom: 1px solid #e2e8f0; } .btn { padding: 8px 15px; border-radius: 4px; border: none; cursor: pointer; font-size: 0.9em; margin-right: 5px; } .btn-sm { padding: 4px 8px; font-size: 0.8em; } .btn-green { background: var(–green); color: white; } .btn-red { background: var(–red); color: white; } .btn-blue { background: var(–primary); color: white; } /* Modals */ .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; justify-content: center; align-items: center; } .modal-box { background: white; padding: 25px; border-radius: 8px; width: 450px; max-width: 90%; max-height: 90vh; overflow-y: auto; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; font-weight: 600; font-size: 0.9em; } .form-group input, .form-group select, .form-group textarea { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } .status-debt { color: var(–red); font-weight: bold; } .status-good { color: var(–green); font-weight: bold; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

DFM Portal

Dashboard Overview

Total Members

0

Monthly Subs Collected

$0

Pledges Owed

$0

Today’s Bookings

0

Recent Offerings & Income

DateTypeDescriptionAmount

Member Registry

NamePhoneAddressBranchRoleRelationAction

Financial Management

Members Status (Subs: $1/mo | Funeral: $1/mo)

Member Subs Debt/Credit Funeral Debt/Credit Pledge Balance Last Tithe

Apostle Office Bookings

DateClient NameFee PaidDetailsStatus

Church Calendar

    Branch Teachings & Attendance

    DateBranchTopicAttendanceOffering

    Admin Settings

    Add Secretary

    Full Access Limited (Bookings Only)
    const API_URL = ‘/wp-admin/admin-ajax.php’; // — APP LOGIC — const DFM = { user: null, data: { members:[], transactions:[], bookings:[], events:[], teachings:[] }, init: function() { // Check session? For now, clean slate. }, login: function() { let u = $(‘#log-user’).val(); let p = $(‘#log-pass’).val(); $(‘#log-msg’).text(“Verifying…”); $.post(API_URL, { action: ‘dfm_master_api’, request: ‘login’, u:u, p:p }, function(res) { if(res.status === ‘success’) { DFM.user = res.user; $(‘#dfm-login’).hide(); $(‘#dfm-main’).css(‘display’, ‘flex’); if(DFM.user.username === ‘Tafadzwa’) $(‘#nav-admin’).show(); DFM.loadData(); } else { $(‘#log-msg’).text(res.msg); } }, ‘json’); }, loadData: function() { $.post(API_URL, { action: ‘dfm_master_api’, request: ‘load_data’ }, function(res) { DFM.data = res; DFM.renderAll(); }, ‘json’); }, renderAll: function() { // 1. Members Table & Selects let mRows = ”; let mOpts = ‘Select Member’; DFM.data.members.forEach(m => { mRows += ` ${m.first_name} ${m.last_name} ${m.phone} ${m.address} ${m.branch} ${m.church_title} ${m.relation} `; mOpts += `${m.first_name} ${m.last_name}`; }); $(‘#tbl-members tbody’).html(mRows); $(‘#t-mem, #p-mem’).html(mOpts); $(‘#d-mem’).text(DFM.data.members.length); // 2. Financials (Complex Logic) let fRows = ”; let totalSub = 0; let totalPledgeDebt = 0; DFM.data.members.forEach(m => { let trans = DFM.data.transactions.filter(t => t.member_id == m.id); // Sub Logic (Assume $1/mo since join date. For simplified prototype, assume 12 months due) let subPaid = trans.filter(t => t.type == ‘subscription’).reduce((a,b)=>a+parseFloat(b.amount),0); let funPaid = trans.filter(t => t.type == ‘funeral’).reduce((a,b)=>a+parseFloat(b.amount),0); // Dynamic Date Diff could go here. Hardcoding 12 months for prototype stability. let monthsDue = 12; let subBal = subPaid – monthsDue; let funBal = funPaid – monthsDue; // Pledge Logic let pCommitted = trans.filter(t => t.type == ‘pledge_commit’).reduce((a,b)=>a+parseFloat(b.amount),0); let pPaid = trans.filter(t => t.type == ‘pledge_pay’).reduce((a,b)=>a+parseFloat(b.amount),0); let pBal = pCommitted – pPaid; // Tithe let tithes = trans.filter(t => t.type == ‘tithe’); let lastTithe = tithes.length > 0 ? ‘$’+tithes[0].amount : ‘-‘; // Formatting let subClass = subBal < 0 ? 'status-debt' : 'status-good'; let subText = subBal < 0 ? `Owes $${Math.abs(subBal)}` : `Paid (+$${subBal})`; let funClass = funBal < 0 ? 'status-debt' : 'status-good'; let funText = funBal 0 ? `Owes $${pBal}` : `Clear`; fRows += ` ${m.first_name} ${m.last_name} ${subText} ${funText} ${pledgeText} ${lastTithe} `; totalSub += subPaid; totalPledgeDebt += pBal; }); $(‘#tbl-finance tbody’).html(fRows); $(‘#d-sub’).text(‘$’+totalSub); $(‘#d-pledge’).text(‘$’+totalPledgeDebt); // 3. Bookings let bRows = ”; DFM.data.bookings.forEach(b => { bRows += `${b.booking_date}${b.client_name}$${b.fee_paid}${b.details}${b.status}`; }); $(‘#tbl-bookings tbody’).html(bRows); $(‘#d-book’).text(DFM.data.bookings.length); // Should filter by today ideally // 4. Calendar let cHtml = ”; DFM.data.events.forEach(e => { cHtml += `
  • ${e.start_date}: ${e.title}
    ${e.details}
  • `; }); $(‘#list-calendar’).html(cHtml); // 5. Teachings let tRows = ”; DFM.data.teachings.forEach(t => { tRows += `${t.date}${t.branch}${t.topic}${t.attendance}$${t.offering_collected}`; }); $(‘#tbl-teachings tbody’).html(tRows); // 6. Recent Dashboard Trans let rRows = ”; DFM.data.transactions.slice(0, 10).forEach(t => { rRows += `${t.date}${t.type}${t.description}$${t.amount}`; }); $(‘#tbl-dash tbody’).html(rRows); }, // — NAVIGATION — nav: function(view) { $(‘.section-view’).removeClass(‘active’); $(‘#view-‘+view).addClass(‘active’); $(‘.nav-item’).removeClass(‘active’); // rudimentary active state toggle }, // — ACTIONS — addMember: function() { let d = { action: ‘dfm_master_api’, request: ‘add_member’, fname: $(‘#m-fn’).val(), lname: $(‘#m-ln’).val(), phone: $(‘#m-ph’).val(), addr: $(‘#m-ad’).val(), branch: $(‘#m-br’).val(), title: $(‘#m-ti’).val(), rel: $(‘#m-rl’).val() }; $.post(API_URL, d, function() { alert(‘Member Added’); Modals.close(); DFM.loadData(); }); }, deleteMember: function(id) { if(confirm(‘Are you sure? This deletes their financial history too.’)) { $.post(API_URL, { action: ‘dfm_master_api’, request: ‘delete_member’, id: id }, function() { DFM.loadData(); }); } }, addTrans: function(mode) { let d = { action: ‘dfm_master_api’, request: ‘add_transaction’ }; if(mode === ‘income’) { d.mid = $(‘#t-mem’).val(); d.type = $(‘#t-type’).val(); d.amt = $(‘#t-amt’).val(); d.desc = $(‘#t-desc’).val() || ‘Payment’; } else if (mode === ‘pledge’) { d.mid = $(‘#p-mem’).val(); d.type = ‘pledge_commit’; d.amt = $(‘#p-amt’).val(); d.desc = ‘Pledge Commitment’; } else if (mode === ‘expense’) { d.mid = 0; d.type = ‘expense’; d.amt = $(‘#e-amt’).val(); d.desc = $(‘#e-desc’).val(); } $.post(API_URL, d, function() { alert(‘Transaction Saved’); Modals.close(); DFM.loadData(); }); }, addBooking: function() { let d = { action: ‘dfm_master_api’, request: ‘add_booking’, client: $(‘#b-cli’).val(), date: $(‘#b-dat’).val(), fee: $(‘#b-fee’).val(), details: $(‘#b-det’).val() }; $.post(API_URL, d, function() { alert(‘Booking Added’); Modals.close(); DFM.loadData(); }); }, addEvent: function() { let d = { action: ‘dfm_master_api’, request: ‘add_event’, title: $(‘#ev-tit’).val(), date: $(‘#ev-dat’).val(), desc: $(‘#ev-det’).val() }; $.post(API_URL, d, function() { alert(‘Event Added’); Modals.close(); DFM.loadData(); }); }, addTeaching: function() { let d = { action: ‘dfm_master_api’, request: ‘add_teaching’, branch: $(‘#tch-br’).val(), date: $(‘#tch-dat’).val(), topic: $(‘#tch-top’).val(), att: $(‘#tch-att’).val(), offering: $(‘#tch-off’).val() }; $.post(API_URL, d, function() { alert(‘Report Added’); Modals.close(); DFM.loadData(); }); }, addSecretary: function() { $.post(API_URL, { action: ‘dfm_master_api’, request: ‘add_secretary’, new_u: $(‘#sec-user’).val(), new_p: $(‘#sec-pass’).val(), rights: $(‘#sec-rights’).val() }, function() { alert(‘User Created’); }); }, filterMembers: function() { var value = $(“#search-mem”).val().toLowerCase(); $(“#tbl-members tbody tr”).filter(function() { $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) }); }, exportPDF: function() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.text(“DFM Full Church Report”, 10, 10); doc.text(“1. Member Registry”, 10, 20); doc.autoTable({ html: ‘#tbl-members’, startY: 25 }); let finalY = doc.lastAutoTable.finalY + 10; doc.text(“2. Financial Status”, 10, finalY); doc.autoTable({ html: ‘#tbl-finance’, startY: finalY + 5 }); finalY = doc.lastAutoTable.finalY + 10; doc.text(“3. Branch Teachings”, 10, finalY); doc.autoTable({ html: ‘#tbl-teachings’, startY: finalY + 5 }); doc.save(‘DFM_Full_Report.pdf’); } }; const Modals = { open: function(id) { $(‘#modal-‘+id).css(‘display’, ‘flex’); }, close: function() { $(‘.modal-overlay’).hide(); } }; Panda express kalispell