communityconnect-hub / events.html
dodey917's picture
Create a community organization website with welcome hero, about our mission, programs and services offered, event calendar, member spotlights, resources library, donation/support options, and get involved form. with full backend integration api processor
9d36be7 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Events Calendar - CommunityConnect Hub</title>
<link rel="icon" type="image/x-icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>๐ŸŒŸ</text></svg>">
<link rel="stylesheet" href="style.css">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
secondary: {
50: '#f0fdfa',
100: '#ccfbf1',
200: '#99f6e4',
300: '#5eead4',
400: '#2dd4bf',
500: '#14b8a6',
600: '#0d9488',
700: '#0f766e',
800: '#115e59',
900: '#134e4a',
}
}
}
}
}
</script>
</head>
<body class="bg-gray-50">
<!-- Navigation Component -->
<custom-navbar></custom-navbar>
<!-- Hero Section -->
<section class="bg-gradient-to-r from-primary-600 to-secondary-600 text-white py-20">
<div class="container mx-auto px-6">
<h1 class="text-4xl lg:text-5xl font-bold mb-4">Events Calendar</h1>
<p class="text-xl text-primary-100">Join us for exciting community events and activities.</p>
</div>
</section>
<!-- Calendar View Toggle -->
<section class="py-8 bg-white border-b">
<div class="container mx-auto px-6">
<div class="flex flex-col sm:flex-row justify-between items-center gap-4">
<div class="flex space-x-4">
<button id="list-view-btn" class="px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">
List View
</button>
<button id="calendar-view-btn" class="px-6 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors">
Calendar View
</button>
</div>
<div class="flex items-center space-x-4">
<select id="month-filter" class="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500">
<option value="">All Months</option>
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select id="category-filter" class="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500">
<option value="">All Categories</option>
<option value="workshop">Workshop</option>
<option value="social">Social</option>
<option value="volunteer">Volunteer</option>
<option value="fundraiser">Fundraiser</option>
</select>
</div>
</div>
</div>
</section>
<!-- Events List -->
<section id="events-list" class="py-12">
<div class="container mx-auto px-6">
<div id="events-container" class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Events will be loaded here -->
</div>
</div>
</section>
<!-- Calendar View (Hidden by default) -->
<section id="events-calendar" class="py-12 hidden">
<div class="container mx-auto px-6">
<div class="bg-white rounded-xl shadow-lg p-6">
<div id="calendar-header" class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold"></h2>
<div class="flex space-x-2">
<button id="prev-month" class="p-2 hover:bg-gray-100 rounded-lg">
<i data-feather="chevron-left" class="w-5 h-5"></i>
</button>
<button id="next-month" class="p-2 hover:bg-gray-100 rounded-lg">
<i data-feather="chevron-right" class="w-5 h-5"></i>
</button>
</div>
</div>
<div id="calendar-grid" class="grid grid-cols-7 gap-2">
<!-- Calendar will be generated here -->
</div>
</div>
</div>
</section>
<!-- Footer Component -->
<custom-footer></custom-footer>
<!-- Scripts -->
<script src="components/navbar.js"></script>
<script src="components/footer.js"></script>
<script src="script.js"></script>
<script src="api.js"></script>
<script>
document.addEventListener('DOMContentLoaded', async () => {
feather.replace();
let currentView = 'list';
let events = [];
// Load all events
try {
events = await api.getUpcomingEvents(20);
renderEventsList(events);
initializeCalendar(events);
} catch (error) {
document.getElementById('events-container').innerHTML = '<div class="col-span-full text-center text-gray-500">Unable to load events at this time.</div>';
}
// View toggle
document.getElementById('list-view-btn').addEventListener('click', () => {
currentView = 'list';
document.getElementById('events-list').classList.remove('hidden');
document.getElementById('events-calendar').classList.add('hidden');
document.getElementById('list-view-btn').className = 'px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors';
document.getElementById('calendar-view-btn').className = 'px-6 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors';
});
document.getElementById('calendar-view-btn').addEventListener('click', () => {
currentView = 'calendar';
document.getElementById('events-list').classList.add('hidden');
document.getElementById('events-calendar').classList.remove('hidden');
document.getElementById('calendar-view-btn').className = 'px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors';
document.getElementById('list-view-btn').className = 'px-6 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors';
});
// Filter events
function filterEvents() {
const monthFilter = document.getElementById('month-filter').value;
const categoryFilter = document.getElementById('category-filter').value;
let filtered = events;
if (monthFilter) {
filtered = filtered.filter(event => new Date(event.date).getMonth() + 1 == monthFilter);
}
if (categoryFilter) {
filtered = filtered.filter(event => event.category === categoryFilter);
}
renderEventsList(filtered);
}
document.getElementById('month-filter').addEventListener('change', filterEvents);
document.getElementById('category-filter').addEventListener('change', filterEvents);
function renderEventsList(eventsToRender) {
const container = document.getElementById('events-container');
if (eventsToRender.length === 0) {
container.innerHTML = '<div class="col-span-full text-center text-gray-500">No events found.</div>';
return;
}
container.innerHTML = eventsToRender.map(event => `
<div class="bg-white rounded-xl p-6 shadow-lg hover:shadow-xl transition-shadow">
<div class="flex items-start justify-between mb-4">
<div>
<span class="inline-block px-3 py-1 bg-${getEventColor(event.category)}-100 text-${getEventColor(event.category)}-700 text-sm rounded-full mb-2">
${event.category}
</span>
<h3 class="text-lg font-semibold">${event.title}</h3>
</div>
<button class="text-gray-400 hover:text-primary-600">
<i data-feather="bookmark" class="w-5 h-5"></i>
</button>
</div>
<div class="space-y-2 text-sm text-gray-600 mb-4">
<p class="flex items-center">
<i data-feather="calendar" class="w-4 h-4 mr-2"></i>
${new Date(event.date).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}
</p>
<p class="flex items-center">
<i data-feather="clock" class="w-4 h-4 mr-2"></i>
${event.time}
</p>
<p class="flex items-center">
<i data-feather="map-pin" class="w-4 h-4 mr-2"></i>
${event.location}
</p>
<p class="flex items-center">
<i data-feather="users" class="w-4 h-4 mr-2"></i>
${event.attendees || 'Open to all'}
</p>
</div>
<p class="text-gray-600 mb-4">${event.description}</p>
<button class="w-full bg-primary-600 text-white py-2 rounded-lg hover:bg-primary-700 transition-colors">
Register Now
</button>
</div>
`).join('');
feather.replace();
}
function getEventColor(category) {
const colors = {
workshop: 'primary',
social: 'secondary',
volunteer: 'green',
fundraiser: 'yellow'
};
return colors[category] || 'gray';
}
function initializeCalendar(eventsData) {
const today = new Date();
const currentMonth = today.getMonth();
const currentYear = today.getFullYear();
function renderCalendar(month = currentMonth, year = currentYear) {
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
document.querySelector('#calendar-header h2').textContent = `${monthNames[month]} ${year}`;
let calendarHTML = '';
// Day headers
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
dayNames.forEach(day => {
calendarHTML += `<div class="text-center font-semibold text-gray-600 p-2">${day}</div>`;
});
// Empty cells
for (let i = 0; i < firstDay; i++) {
calendarHTML += '<div></div>';
}
// Days
for (let day = 1; day <= daysInMonth; day++) {
const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
const dayEvents = eventsData.filter(e => e.date.startsWith(dateStr));
const hasEvents = dayEvents.length > 0;
const isToday = today.getDate() === day && today.getMonth() === month && today.getFullYear() === year;
calendarHTML += `
<div class="relative p-2 border rounded-lg ${hasEvents ? 'bg-primary-50 border-primary-200' : ''} ${isToday ? 'bg-primary-100 border-primary-400' : ''} hover:bg-gray-50 cursor-pointer">
<div class="font-semibold text-sm">${day}</div>
${hasEvents ? `
<div class="mt-1">
<span class="text-xs bg-primary-600 text-white px-1 py-0.5 rounded">${dayEvents.length} event${dayEvents.length > 1 ? 's' : ''}</span>
</div>
` : ''}
</div>
`;
}
document.getElementById('calendar-grid').innerHTML = calendarHTML;
}
document.getElementById('prev-month').addEventListener('click', () => {
const month = parseInt(document.querySelector('#calendar-header h2').textContent.split(' ')[0]) - 1;
const year = parseInt(document.querySelector('#calendar-header h2').textContent.split(' ')[1]);
renderCalendar(month - 1 < 0 ? 11 : month - 1, month - 1 < 0 ? year - 1 : year);
});
document.getElementById('next-month').addEventListener('click', () => {
const month = parseInt(document.querySelector('#calendar-header h2').textContent.split(' ')[0]) - 1;
const year = parseInt(document.querySelector('#calendar-header h2').textContent.split(' ')[1]);
renderCalendar(month + 1 > 11 ? 0 : month + 1, month + 1 > 11 ? year + 1 : year);
});
renderCalendar();
}
});
</script>
</body>
</html>