communityconnect-hub / resources.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>Resources Library - 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">Resources Library</h1>
<p class="text-xl text-primary-100">Access valuable resources, guides, and tools to support your journey.</p>
</div>
</section>
<!-- Search Bar -->
<section class="py-8 bg-white border-b">
<div class="container mx-auto px-6">
<div class="max-w-2xl mx-auto">
<div class="relative">
<input
type="text"
id="search-input"
placeholder="Search resources..."
class="w-full px-6 py-4 pr-12 border rounded-full focus:outline-none focus:ring-2 focus:ring-primary-500 text-lg"
>
<button class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-primary-600 text-white p-3 rounded-full hover:bg-primary-700 transition-colors">
<i data-feather="search" class="w-5 h-5"></i>
</button>
</div>
<div class="flex flex-wrap gap-2 mt-4 justify-center">
<span class="text-sm text-gray-600">Popular searches:</span>
<button class="search-tag text-sm bg-gray-100 px-3 py-1 rounded-full hover:bg-gray-200 transition-colors">Job Training</button>
<button class="search-tag text-sm bg-gray-100 px-3 py-1 rounded-full hover:bg-gray-200 transition-colors">Health Guide</button>
<button class="search-tag text-sm bg-gray-100 px-3 py-1 rounded-full hover:bg-gray-200 transition-colors">Education</button>
<button class="search-tag text-sm bg-gray-100 px-3 py-1 rounded-full hover:bg-gray-200 transition-colors">Legal Help</button>
</div>
</div>
</div>
</section>
<!-- Categories -->
<section class="py-8">
<div class="container mx-auto px-6">
<div class="flex flex-wrap justify-center gap-4">
<button class="category-btn px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors" data-category="all">
All Resources
</button>
<button class="category-btn px-6 py-2 bg-white border rounded-lg hover:bg-gray-50 transition-colors" data-category="guides">
Guides
</button>
<button class="category-btn px-6 py-2 bg-white border rounded-lg hover:bg-gray-50 transition-colors" data-category="templates">
Templates
</button>
<button class="category-btn px-6 py-2 bg-white border rounded-lg hover:bg-gray-50 transition-colors" data-category="videos">
Videos
</button>
<button class="category-btn px-6 py-2 bg-white border rounded-lg hover:bg-gray-50 transition-colors" data-category="documents">
Documents
</button>
</div>
</div>
</section>
<!-- Featured Resources -->
<section class="py-12 bg-white">
<div class="container mx-auto px-6">
<div class="text-center mb-8">
<h2 class="text-3xl font-bold text-gray-800 mb-4">Featured Resources</h2>
<div class="w-24 h-1 bg-secondary-500 mx-auto"></div>
</div>
<div id="featured-container" class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Featured resources will be loaded here -->
</div>
</div>
</section>
<!-- All Resources -->
<section class="py-12">
<div class="container mx-auto px-6">
<div class="flex justify-between items-center mb-8">
<h2 class="text-2xl font-bold text-gray-800">All Resources</h2>
<select id="sort-select" class="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500">
<option value="recent">Most Recent</option>
<option value="popular">Most Popular</option>
<option value="name">Name (A-Z)</option>
</select>
</div>
<div id="resources-container" class="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Resources will be loaded here -->
</div>
</div>
</section>
<!-- Newsletter Signup -->
<section class="py-20 bg-primary-600 text-white">
<div class="container mx-auto px-6">
<div class="max-w-2xl mx-auto text-center">
<h2 class="text-3xl font-bold mb-4">Stay Updated</h2>
<p class="text-xl mb-8 text-primary-100">Get the latest resources and community updates delivered to your inbox.</p>
<form class="flex flex-col sm:flex-row gap-4 max-w-md mx-auto">
<input type="email" placeholder="Enter your email" class="flex-1 px-4 py-3 rounded-lg text-gray-800 focus:outline-none focus:ring-2 focus:ring-white">
<button type="submit" class="bg-white text-primary-600 px-6 py-3 rounded-lg font-semibold hover:bg-gray-100 transition-colors">
Subscribe
</button>
</form>
</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 allResources = [];
let filteredResources = [];
let currentCategory = 'all';
try {
allResources = await api.getResources();
filteredResources = allResources;
renderFeaturedResources(allResources.filter(r => r.featured));
renderResources(filteredResources);
} catch (error) {
document.getElementById('resources-container').innerHTML = '<div class="col-span-full text-center text-gray-500">Unable to load resources at this time.</div>';
}
// Search functionality
document.getElementById('search-input').addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();
filteredResources = allResources.filter(resource => {
const matchesSearch = resource.title.toLowerCase().includes(searchTerm) ||
resource.description.toLowerCase().includes(searchTerm) ||
resource.tags.some(tag => tag.toLowerCase().includes(searchTerm));
const matchesCategory = currentCategory === 'all' || resource.type === currentCategory;
return matchesSearch && matchesCategory;
});
renderResources(filteredResources);
});
// Category filter
document.querySelectorAll('.category-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
// Update button styles
document.querySelectorAll('.category-btn').forEach(b => {
b.className = 'category-btn px-6 py-2 bg-white border rounded-lg hover:bg-gray-50 transition-colors';
});
e.target.className = 'category-btn px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors';
currentCategory = e.target.dataset.category;
filterResources();
});
});
// Sort functionality
document.getElementById('sort-select').addEventListener('change', (e) => {
const sortBy = e.target.value;
let sorted = [...filteredResources];
switch(sortBy) {
case 'recent':
sorted.sort((a, b) => new Date(b.date) - new Date(a.date));
break;
case 'popular':
sorted.sort((a, b) => b.downloads - a.downloads);
break;
case 'name':
sorted.sort((a, b) => a.title.localeCompare(b.title));
break;
}
renderResources(sorted);
});
// Search tags
document.querySelectorAll('.search-tag').forEach(tag => {
tag.addEventListener('click', () => {
document.getElementById('search-input').value = tag.textContent;
document.getElementById('search-input').dispatchEvent(new Event('input'));
});
});
function filterResources() {
filteredResources = currentCategory === 'all'
? allResources
: allResources.filter(r => r.type === currentCategory);
renderResources(filteredResources);
}
function renderFeaturedResources(resources) {
const container = document.getElementById('featured-container');
container.innerHTML = resources.map(resource => `
<div class="bg-gradient-to-br from-primary-50 to-secondary-50 rounded-xl p-6 hover:shadow-lg transition-shadow">
<div class="bg-white w-12 h-12 rounded-lg flex items-center justify-center mb-4">
<i data-feather="${getResourceIcon(resource.type)}" class="w-6 h-6 text-primary-600"></i>
</div>
<h3 class="text-lg font-semibold mb-2">${resource.title}</h3>
<p class="text-gray-600 mb-4">${resource.description}</p>
<button class="bg-primary-600 text-white px-4 py-2 rounded-lg hover:bg-primary-700 transition-colors">
Download
</button>
</div>
`).join('');
feather.replace();
}
function renderResources(resources) {
const container = document.getElementById('resources-container');
if (resources.length === 0) {
container.innerHTML = '<div class="col-span-full text-center text-gray-500">No resources found.</div>';
return;
}
container.innerHTML = resources.map(resource => `
<div class="bg-white rounded-xl p-6 shadow hover:shadow-lg transition-shadow">
<div class="flex items-start justify-between mb-4">
<div class="bg-${getTypeColor(resource.type)}-100 p-2 rounded-lg">
<i data-feather="${getResourceIcon(resource.type)}" class="w-6 h-6 text-${getTypeColor(resource.type)}-600"></i>
</div>
<span class="text-xs text-gray-500">${resource.downloads || 0} downloads</span>
</div>
<h3 class="font-semibold mb-2 line-clamp-2">${resource.title}</h3>
<p class="text-sm text-gray-600 mb-4 line-clamp-3">${resource.description}</p>
<div class="flex flex-wrap gap-1 mb-4">
${resource.tags.slice(0, 3).map(tag => `
<span class="text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded">${tag}</span>
`).join('')}
</div>
<button onclick="downloadResource('${resource.id}')" class="w-full bg-${getTypeColor(resource.type)}-600 text-white py-2 rounded-lg hover:bg-${getTypeColor(resource.type)}-700 transition-colors text-sm">
Download
</button>
</div>
`).join('');
feather.replace();
}
function getResourceIcon(type) {
const icons = {
guides: 'book-open',
templates: 'file-text',
videos: 'play-circle',
documents: 'folder'
};
return icons[type] || 'file';
}
function getTypeColor(type) {
const colors = {
guides: 'primary',
templates: 'secondary',
videos: 'purple',
documents: 'green'
};
return colors[type] || 'gray';
}
window.downloadResource = async (resourceId) => {
try {
// Simulate download
const resource = allResources.find(r => r.id === resourceId);
if (resource) {
// Increment download count
resource.downloads = (resource.downloads || 0) + 1;
renderResources(filteredResources);
// In a real app, this would trigger a file download
alert(`Downloading: ${resource.title}`);
}
} catch (error) {
alert('Error downloading resource');
}
};
});
</script>
</body>
</html>