/* Shared components: Header, Footer, EnrollmentModal, FloatingShapes, helpers */
const useState = React.useState;
const useEffect = React.useEffect;
const useRef = React.useRef;
const PHONE = "011 5771 7095";
const PHONE_TEL = "+601157717095";
const WA_LINK = "https://wa.me/601157717095";
const NAV_LINKS = [
{ href: "index.html", label: "Home", key: "home" },
{ href: "about.html", label: "About Us", key: "about" },
{ href: "programmes.html", label: "Programmes", key: "programmes" },
{ href: "gallery.html", label: "Gallery", key: "gallery" },
{ href: "fees.html", label: "Fees", key: "fees" },
{ href: "find-us.html", label: "Find Us", key: "find" }];
function Brand({ inverse }) {
return (
Islamic English Preschool
);
}
function Header({ active, onEnroll }) {
const [open, setOpen] = useState(false);
return (
);
}
function PlaygroundScene() {
return (
);
}
function Footer() {
return (
);
}
function FloatingShapes({ variant = 'default' }) {
// Decorative shapes layered behind hero / content. variant changes mix.
const shapes = variant === 'minimal' ? [
{ type: 'cloud', size: 120, top: '8%', left: '4%', delay: 0 },
{ type: 'cloud', size: 80, top: '20%', right: '8%', delay: 1.5 }] :
[
{ type: 'cloud', size: 120, top: '8%', left: '4%', delay: 0 },
{ type: 'cloud', size: 80, top: '20%', right: '8%', delay: 1.5 },
{ type: 'cloud', size: 100, top: '60%', left: '2%', delay: 0.8 },
{ type: 'dot', color: 'var(--rose)', size: 16, top: '14%', left: '52%' },
{ type: 'dot', color: 'var(--mint)', size: 12, top: '32%', left: '14%' },
{ type: 'dot', color: 'var(--orange-warm)', size: 18, top: '70%', right: '14%' },
{ type: 'ring', color: 'var(--orange-warm)', size: 80, top: '40%', right: '4%' },
{ type: 'star', color: 'var(--yellow)', size: 26, top: '50%', left: '40%' }];
return (
{shapes.map((s, i) => {
const baseStyle = {
top: s.top, left: s.left, right: s.right,
animation: `float-slow ${6 + i}s ease-in-out infinite`,
animationDelay: `${s.delay || 0}s`
};
if (s.type === 'cloud') return ;
if (s.type === 'dot') return ;
if (s.type === 'ring') return ;
if (s.type === 'star') return ;
return null;
})}
);
}
function Cloud({ size = 100, style, color = '#fff' }) {
// Simple cloud shape via SVG
return (
);
}
function Star({ size = 28, color = 'var(--yellow)', style }) {
return (
);
}
function ScribbleArrow({ style, color = 'var(--orange)' }) {
return (
);
}
function Kite({ style }) {
// small drawn kite mascot
return (
);
}
function Pencil({ style }) {
return (
);
}
function Planet({ style, color = 'var(--lilac)' }) {
return (
);
}
/* Enrollment modal */
function EnrollmentModal({ open, onClose }) {
const [submitted, setSubmitted] = useState(false);
const [form, setForm] = useState({ parent: '', child: '', age: '', branch: 'Bukit Jelutong', programme: 'Preschool', phone: '', email: '', notes: '' });
useEffect(() => {
if (open) setSubmitted(false);
document.body.style.overflow = open ? 'hidden' : '';
return () => {document.body.style.overflow = '';};
}, [open]);
if (!open) return null;
const handleChange = (k, v) => setForm((f) => ({ ...f, [k]: v }));
const handleSubmit = (e) => {
e.preventDefault();
setSubmitted(true);
};
return (
e.stopPropagation()}>
{!submitted ?
<>
Enrollment 2026
Let's get your little one started 🌟
Fill in a few details and our team will reach out within 24 hours, InsyaAllah.
> :
🌟
Terima kasih!
We've received your interest for {form.child || 'your little one'} at {form.branch}. Our team will WhatsApp you within 24 hours.
}
);
}
/* Counter that animates when in view */
function Counter({ to, duration = 1600, suffix = '' }) {
const [val, setVal] = useState(0);
const ref = useRef(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
let raf;
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
const start = performance.now();
const tick = (now) => {
const t = Math.min(1, (now - start) / duration);
const eased = 1 - Math.pow(1 - t, 3);
setVal(Math.round(to * eased));
if (t < 1) raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
observer.disconnect();
}
}, { threshold: 0.4 });
observer.observe(el);
return () => {observer.disconnect();cancelAnimationFrame(raf);};
}, [to, duration]);
return {val.toLocaleString()}{suffix};
}
/* Hook for parallax scroll */
function useParallax(speed = 0.3) {
const [y, setY] = useState(0);
useEffect(() => {
const handler = () => setY(window.scrollY * speed);
window.addEventListener('scroll', handler, { passive: true });
return () => window.removeEventListener('scroll', handler);
}, [speed]);
return y;
}
/* WhatsApp + Phone floating CTA */
function FloatingCTAs() {
return (
);
}
/* Tag pill */
function Pill({ color, children, style }) {
const palette = {
sky: { bg: 'var(--sky)', fg: '#0a4858' },
mint: { bg: 'var(--mint)', fg: '#3a4a14' },
rose: { bg: 'var(--rose)', fg: '#7a2424' },
orange: { bg: 'var(--orange)', fg: '#fff' },
yellow: { bg: 'var(--yellow)', fg: '#5a4400' },
lilac: { bg: 'var(--lilac)', fg: '#36246e' }
}[color] || { bg: 'var(--orange-soft)', fg: 'var(--orange)' };
return (
{children});
}
/* Image placeholder cloud */
function ClueCloudPlaceholder({ label, color = 'var(--sky)', height = 280 }) {
// SVG cloud-shaped placeholder with label
return (
);
}
/* Toast helper */
function useToast() {
const [msg, setMsg] = useState(null);
useEffect(() => {
if (!msg) return;
const t = setTimeout(() => setMsg(null), 2500);
return () => clearTimeout(t);
}, [msg]);
return { msg, show: setMsg };
}
Object.assign(window, {
Header, Footer, FloatingShapes, Cloud, Star, ScribbleArrow, Kite, Pencil, Planet,
EnrollmentModal, FloatingCTAs, Brand, Counter, useParallax, Pill, ClueCloudPlaceholder, useToast,
PHONE, PHONE_TEL, WA_LINK, NAV_LINKS
});