import React, { useState, useEffect } from "react";
import { Program, Event, Gallery } from "@/entities/all";
import { Button } from "@/components/ui/button";
import { Link } from "react-router-dom";
import { createPageUrl } from "@/utils";
import { Zap, ArrowRight } from "lucide-react";
import { motion } from "framer-motion";
import HeroSection from "../components/home/HeroSection";
import HomepageSlideshow from "../components/home/HomepageSlideshow";
import FeaturedPrograms from "../components/home/FeaturedPrograms";
import UpcomingEvents from "../components/home/UpcomingEvents";
import StatsSection from "../components/home/StatsSection";
import TestimonialsSection from "../components/home/TestimonialsSection";
export default function Home() {
const [programs, setPrograms] = useState([]);
const [events, setEvents] = useState([]);
// Removed galleries and its loading state as it's not directly used on this page for display
const [isLoading, setIsLoading] = useState(true); // General loading for programs/events
useEffect(() => {
loadData();
}, []);
const loadData = async () => {
setIsLoading(true); // Set loading true at the start of data fetching
try {
const [programsData, eventsData] = await Promise.all([
Program.filter({ is_featured: true }, '-created_date', 3),
Event.list('-date', 4),
// Gallery.filter({ is_featured: true }, '-created_date', 6) // Removed gallery fetch
]);
setPrograms(programsData);
setEvents(eventsData);
// setGalleries(galleriesData); // Removed
} catch (error) {
console.error("Error loading data:", error);
} finally {
setIsLoading(false);
}
};
return (
{/* Added the slideshow component */}
{/* Pass loading state */}
{/* Pass loading state */}
{/* Call to Action Section */}
{/* ... (rest of CTA section code remains the same) ... */}
Ready to EMPOWER Your Child?
Join hundreds of families who trust EMPOWER Martial Academy for their children's growth, confidence, and character development.
);
}
import React, { useState, useEffect } from "react";
import { Program } from "@/entities/all";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
Shield,
Users,
Clock,
ArrowRight,
Search,
Filter,
Star,
DollarSign,
Sun,
Sparkles,
Bus,
Cake,
User,
Baby,
Briefcase
} from "lucide-react";
import { motion } from "framer-motion";
import { Skeleton } from "@/components/ui/skeleton";
import { Link } from "react-router-dom";
import { createPageUrl } from "@/utils";
import EditableImage from '../components/admin/EditableImage';
import EditableText from '../components/admin/EditableText';
const programCategoryConfig = {
little_ninjas: { label: "Little Ninjas (3-5)", icon: Baby, order: 1 },
kids_martial_arts: { label: "Kids Martial Arts (5-12)", icon: Shield, order: 2 },
teen_martial_arts: { label: "Teen Martial Arts (13-17)", icon: Users, order: 3 },
adult_martial_arts: { label: "Adult Martial Arts (18+)", icon: User, order: 4 },
krav_maga: { label: "Krav Maga", icon: Briefcase, order: 5 },
summer_camp: { label: "Summer Camp", icon: Sun, order: 6 },
after_school_program: { label: "After School Program", icon: Clock, order: 7 },
birthday_parties: { label: "Birthday Parties", icon: Cake, order: 8 },
private_lessons: { label: "Private Lessons", icon: Star, order: 9 },
student_advancement: { label: "Student Advancement", icon: Star, order: 10 },
parents_event: { label: "Parents' Events", icon: Users, order: 11 },
day_camp_specific: { label: "Day Camps", icon: Sun, order: 12 },
summer_camp_activity_field_trip: { label: "Camp Field Trips", icon: Bus, order: 13, isHighlight: true },
arts_crafts_activity: { label: "Arts & Crafts", icon: Sparkles, order: 20, hiddenFilter: true },
outdoor_themed_activity: { label: "Outdoor Activities", icon: Sun, order: 21, hiddenFilter: true },
special_event_general: { label: "Special Events", icon: Sparkles, order: 22, hiddenFilter: true },
};
const ProgramCard = ({ program }) => {
const [imageUrl, setImageUrl] = useState(program.image_url || "https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80");
const [name, setName] = useState(program.name);
const [description, setDescription] = useState(program.description);
const [ageGroup, setAgeGroup] = useState(program.age_group);
const [schedule, setSchedule] = useState(program.schedule_summary);
const [costDescription, setCostDescription] = useState(program.cost_description);
const handleImageUpdate = (newUrl) => {
setImageUrl(newUrl);
};
return (
{program.is_featured && (
Featured
)}
{(programCategoryConfig[program.category]?.label || program.category.replace(/_/g, ' '))}
top of page
bottom of page
import React, { useState, useEffect } from 'react';
import { Event } from '@/entities/all';
import { Calendar } from "@/components/ui/calendar"; // shadcn Calendar
import { format, isSameDay, parseISO, startOfMonth, endOfMonth, isWithinInterval } from 'date-fns';
import { AlertTriangle, CalendarDays, Loader2, Clock, MapPin, Users, DollarSign, Info, ArrowRight } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { motion } from 'framer-motion';
const getEventTypeColorClasses = (type) => {
const colors = {
martial_arts: {
bg: "bg-red-600",
text: "text-white",
border: "border-red-700",
badgeBg: "bg-red-100",
badgeText: "text-red-800"
},
field_trip: {
bg: "bg-yellow-500",
text: "text-black",
border: "border-yellow-600",
badgeBg: "bg-yellow-100",
badgeText: "text-yellow-800"
},
special_event: {
bg: "bg-purple-600",
text: "text-white",
border: "border-purple-700",
badgeBg: "bg-purple-100",
badgeText: "text-purple-800"
},
arts_crafts: {
bg: "bg-blue-500",
text: "text-white",
border: "border-blue-600",
badgeBg: "bg-blue-100",
badgeText: "text-blue-800"
},
outdoor_activity: {
bg: "bg-green-500",
text: "text-white",
border: "border-green-600",
badgeBg: "bg-green-100",
badgeText: "text-green-800"
},
default: {
bg: "bg-gray-500",
text: "text-white",
border: "border-gray-600",
badgeBg: "bg-gray-100",
badgeText: "text-gray-800"
}
};
return colors[type] || colors.default;
};
export default function CalendarPage() {
const [allEvents, setAllEvents] = useState([]);
const [selectedDate, setSelectedDate] = useState(new Date());
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [selectedEvent, setSelectedEvent] = useState(null);
const [currentMonth, setCurrentMonth] = useState(new Date());
useEffect(() => {
const fetchEvents = async () => {
setIsLoading(true);
setError(null);
try {
// Fetch all events. If performance becomes an issue for very many events,
// this could be optimized to fetch by month, but for now, get all.
const data = await Event.list('-date');
setAllEvents(data.map(e => ({ ...e, dateObj: parseISO(e.date) })));
} catch (err) {
console.error("Error fetching events:", err);
setError("Failed to load events. Please try again later.");
} finally {
setIsLoading(false);
}
};
fetchEvents();
}, []);
const eventsForSelectedDate = allEvents.filter(event =>
isSameDay(event.dateObj, selectedDate)
);
const eventsForCurrentMonth = allEvents.filter(event =>
isWithinInterval(event.dateObj, { start: startOfMonth(currentMonth), end: endOfMonth(currentMonth) })
);
const eventDaysInMonth = React.useMemo(() => {
const days = new Set();
eventsForCurrentMonth.forEach(event => {
days.add(format(event.dateObj, "yyyy-MM-dd"));
});
return days;
}, [eventsForCurrentMonth]);
const dayHasEvent = (day) => {
return eventDaysInMonth.has(format(day, "yyyy-MM-dd"));
};
return (