/* ════════════════════════════════════════════════════
MHMA Shared Navigation, Footer & Prayer Times
Include at end of
Expects:
════════════════════════════════════════════════════ */
/* ── SVG icon helpers ──────────────────────────── */
const _ic = {
phone: ``,
mail: ``,
pin: ``,
chevron: ``,
chevronM: ``,
close: ``,
burger: ``,
fb: ``,
ig: ``,
yt: ``,
x: ``,
clock: ``,
send: ``,
lock: ``,
};
/* ── Dropdown builder helper ───────────────────── */
function _dd(label, items) {
const links = items.map((it, i) =>
`${it[0]}`
).join(”);
return `
`;
}
function _ddM(label, items) {
const links = items.map((it, i) =>
`${it[0]}`
).join(”);
return `
`;
}
/* ── Nav data ──────────────────────────────────── */
const NAV_PROGRAMS = [
[‘All Programs’, ‘programs.html’],
[‘Sunday School’, ‘programs.html#sunday-school’],
[“After-School Qur’an Classes”, ‘programs.html#quran’],
[“Children’s Arabic Program”, ‘programs.html#arabic’],
[‘MHMA Maktab’, ‘programs.html#maktab’],
[‘Friday Night Girls Halaqa’, ‘programs.html#girls-halaqa’],
[‘Youth Programs’, ‘programs.html#youth’],
[“Sister’s Programs”, ‘programs.html#sisters’],
[‘Marhaba: Convert Care & Community’, ‘programs.html#marhaba’],
[‘Cub Scouts’, ‘programs.html#scouts’],
[“Women’s Halaqa”, ‘programs.html#womens-halaqa’],
];
const NAV_SERVICES = [
[‘All Services’, ‘services.html’],
[“Du’a Request”, ‘services.html#dua’],
[‘Mental Health Counseling’, ‘services.html#mental-health’],
[‘Ask an Imam’, ‘services.html#ask-imam’],
[‘Suggest a Program or Speaker’, ‘services.html#suggest’],
[‘Islamic Divorce Services’, ‘services.html#divorce’],
[‘Facility Rental Form’, ‘services.html#rental’],
[‘Feedback’, ‘feedback.html’],
];
const NAV_ASSISTANCE = [
[‘Explore All’, ‘assistance.html’],
[‘Zakat & Sadaqa’, ‘assistance.html#zakat’],
[‘Food Pantry’, ‘assistance.html#food-pantry’],
[‘Refugee Support’, ‘assistance.html#refugee’],
[‘Funeral & Burial’,’assistance.html#funeral’],
[‘Bay Area Nonprofits’,’assistance.html#nonprofits’],
[‘Clothing Donations’, ‘assistance.html#clothing’],
];
const NAV_ABOUT = [
[‘About MHMA’, ‘about.html’],
[‘Become a Member’, ‘about.html#membership’],
[‘Committee’, ‘about.html#committee’],
[‘Bylaws’, ‘about.html#bylaws’],
[‘Meeting Minutes’, ‘about.html#minutes’],
[‘Annual Recap’, ‘https://mhma.us/recap/’],
[‘Ways to Give’, ‘donate.html#ways’],
[‘Volunteer’, ‘about.html#volunteer’],
[‘Our Team’, ‘about.html#team’],
[‘Board of Directors’, ‘about.html#board’],
[‘MHMA Newsletters’, ‘about.html#newsletters’],
[‘Contact Us’, ‘contact.html’],
[‘Board Elections’, ‘about.html#elections’],
];
/* ── Build HTML strings ────────────────────────── */
const UTILITY_HTML = `
`;
const MAINNAV_HTML = `
`;
const MOBILEMENU_HTML = `
`;
const FOOTER_HTML = `
`;
/* ── Inject into DOM ───────────────────────────── */
const _main = document.querySelector(‘main’);
if (_main) {
_main.insertAdjacentHTML(‘beforebegin’,
‘Skip to content‘ +
UTILITY_HTML + MAINNAV_HTML + MOBILEMENU_HTML
);
_main.insertAdjacentHTML(‘afterend’, FOOTER_HTML);
}
/* ── Active nav link ───────────────────────────── */
(function highlightActive() {
const path = window.location.pathname.split(‘/’).pop() || ‘index.html’;
document.querySelectorAll(‘#main-nav .nav-links a.nav-link, #main-nav .nav-links .dropdown a’).forEach(a => {
const href = a.getAttribute(‘href’).split(‘#’)[0].split(‘/’).pop();
if (href === path) {
const topLink = a.closest(‘.has-dropdown’)
? a.closest(‘.has-dropdown’).querySelector(‘button.nav-link’)
: a;
if (topLink) { topLink.classList.add(‘active’); }
}
});
})();
/* ── Mobile Menu ───────────────────────────────── */
window._mhmaOpenMenu = function() {
const menu = document.getElementById(‘mobile-menu’);
const btn = document.getElementById(‘hamburger-btn’);
menu.classList.add(‘open’);
btn.setAttribute(‘aria-expanded’, ‘true’);
document.body.style.overflow = ‘hidden’;
const close = menu.querySelector(‘button.mobile-close’);
if (close) close.focus();
};
window._mhmaCloseMenu = function() {
const menu = document.getElementById(‘mobile-menu’);
const btn = document.getElementById(‘hamburger-btn’);
menu.classList.remove(‘open’);
btn.setAttribute(‘aria-expanded’, ‘false’);
document.body.style.overflow = ”;
btn.focus();
};
window._mhmaTglSub = function(btn) {
const sub = btn.nextElementSibling;
document.querySelectorAll(‘.mobile-sub’).forEach(s => { if (s !== sub) s.classList.remove(‘open’); });
sub.classList.toggle(‘open’);
};
document.addEventListener(‘keydown’, e => {
const menu = document.getElementById(‘mobile-menu’);
if (e.key === ‘Escape’ && menu && menu.classList.contains(‘open’)) window._mhmaCloseMenu();
});
/* ── Sticky Nav ────────────────────────────────── */
const _nav = document.getElementById(‘main-nav’);
if (_nav) {
window.addEventListener(‘scroll’, () => {
_nav.classList.toggle(‘scrolled’, window.scrollY > 24);
}, { passive: true });
}
/* ── Scroll Reveal ─────────────────────────────── */
const _revObs = new IntersectionObserver(
entries => entries.forEach(e => { if (e.isIntersecting) e.target.classList.add(‘visible’); }),
{ threshold: 0.1, rootMargin: ‘0px 0px -40px 0px’ }
);
document.querySelectorAll(‘.reveal’).forEach(el => _revObs.observe(el));
/* ════════════════════════════════════════════════════
PRAYER TIMES — shared (strip + footer)
Show fallback immediately, then update from API.
════════════════════════════════════════════════════ */
const _PRAYERS = [‘Fajr’, ‘Dhuhr’, ‘Asr’, ‘Maghrib’, ‘Isha’];
const _FALLBACK = { Fajr: ‘5:12′, Dhuhr: ’13:15′, Asr: ’16:38′, Maghrib: ’19:52′, Isha: ’21:14’ };
function _fmt(t) {
const clean = (t || ”).split(‘ ‘)[0];
const parts = clean.split(‘:’).map(Number);
const h = parts[0] || 0, m = parts[1] || 0;
const ampm = h >= 12 ? ‘PM’ : ‘AM’;
const hr = h > 12 ? h – 12 : h === 0 ? 12 : h;
return `${hr}:${String(m).padStart(2,’0′)} ${ampm}`;
}
function _nextPrayer(timings) {
const now = new Date();
const nowM = now.getHours() * 60 + now.getMinutes();
for (const name of _PRAYERS) {
const parts = (timings[name] || ”).split(‘ ‘)[0].split(‘:’).map(Number);
if ((parts[0] || 0) * 60 + (parts[1] || 0) > nowM) return name;
}
return ‘Fajr’;
}
function _renderStrip(timings, next) {
const el = document.getElementById(‘prayer-strip-times’);
if (!el) return;
el.innerHTML = _PRAYERS.map((name, i) => {
const isNext = name === next;
const sep = i > 0 ? ‘
‘ : ”;
return `${sep}
`;
}).join(”);
}
function _renderFooter(timings) {
const el = document.getElementById(‘footer-prayer-row’);
if (!el) return;
el.innerHTML = _PRAYERS.map(name => `
${_fmt(timings[name])}
`).join(‘‘);
}
/* Also exposed for the prayer-times full widget on index.html */
window._mhmaRenderCards = function(timings, next) {
const grid = document.getElementById(‘prayer-cards-grid’);
if (!grid) return;
grid.innerHTML = _PRAYERS.map(name => {
const isNext = name === next;
return `
`;
}).join(”);
};
window._mhmaSetWidgetDate = function(dateStr, hijriStr) {
const el = document.getElementById(‘prayer-widget-date’);
if (el) el.innerHTML = dateStr + (hijriStr ? ` · ${hijriStr}` : ”);
};
/* Show fallback immediately */
(function initPrayer() {
const next = _nextPrayer(_FALLBACK);
_renderStrip(_FALLBACK, next);
_renderFooter(_FALLBACK);
window._mhmaRenderCards(_FALLBACK, next);
const d = new Date();
window._mhmaSetWidgetDate(
d.toLocaleDateString(‘en-US’, { weekday:’long’, year:’numeric’, month:’long’, day:’numeric’ }),
null
);
})();
/* Then attempt live update from aladhan.com */
(async function fetchPrayer() {
try {
const ts = Math.floor(Date.now() / 1000);
const res = await fetch(`https://api.aladhan.com/v1/timings/${ts}?latitude=37.7784&longitude=-121.5388&method=2`);
if (!res.ok) throw new Error(‘HTTP ‘ + res.status);
const { data } = await res.json();
const { timings, date } = data;
const next = _nextPrayer(timings);
_renderStrip(timings, next);
_renderFooter(timings);
window._mhmaRenderCards(timings, next);
const g = date.gregorian, h = date.hijri;
window._mhmaSetWidgetDate(
`${g.weekday.en}, ${g.day} ${g.month.en} ${g.year}`,
`${h.day} ${h.month.en} ${h.year} AH`
);
} catch (e) {
/* fallback already rendered — nothing to do */
console.info(‘MHMA: using fallback prayer times.’, e.message);
}
})();