/* 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 Secretariates
Secure System Access
Dashboard Overview
Total Members
0
Monthly Subs Collected
$0
Pledges Owed
$0
Today’s Bookings
0
Recent Offerings & Income
| Date | Type | Description | Amount |
Member Registry
| Name | Phone | Address | Branch | Role | Relation | Action |
Financial Management
Members Status (Subs: $1/mo | Funeral: $1/mo)
| Member |
Subs Debt/Credit |
Funeral Debt/Credit |
Pledge Balance |
Last Tithe |
Apostle Office Bookings
| Date | Client Name | Fee Paid | Details | Status |
Church Calendar
Branch Teachings & Attendance
| Date | Branch | Topic | Attendance | Offering |
Admin Settings
Add Secretary
Full Access
Limited (Bookings Only)
Record Payment / Income
Monthly Subscription ($1)
Funeral Subscription ($1)
Tithe
Seed Money
Pay towards Pledge
Add / Update Pledge
Use this to record a PROMISE to pay.
Record Expense
New Consultation
Add Event
Branch Report
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