| layout | page |
|---|---|
| title | Submissions |
| permalink | /submissions/ |
-
Submissions
-
AI Models
-
Categories
<!-- Search and Filter Section -->
<div class="search-filter-section">
<div class="search-box-container">
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.35-4.35"></path>
</svg>
<input type="text" id="search-input" placeholder="Search by team name, members, or description...">
<button class="clear-search-btn" id="clear-search">×</button>
</div>
<div class="filters-container">
<div class="filter-group">
<label for="category-filter">Category</label>
<select id="category-filter">
<option value="">All Categories</option>
</select>
</div>
<div class="filter-group">
<label for="domain-filter">Domain Area</label>
<select id="domain-filter">
<option value="">All Domains</option>
</select>
</div>
<div class="filter-group">
<label for="award-filter">Award Status</label>
<select id="award-filter">
<option value="">All Submissions</option>
<option value="awarded">Award Winners Only</option>
<option value="not-awarded">Non-Award Winners</option>
</select>
</div>
</div>
<div class="active-filters" id="active-filters"></div>
</div>
<!-- Results Info -->
<div class="results-info" id="results-info" style="display: none;">
<div class="results-count">
Showing <span class="count-number" id="results-count">0</span> of <span id="total-count">0</span> submissions
</div>
<div class="sort-group">
<label for="sort-select">Sort by:</label>
<select id="sort-select">
<option value="default">Default</option>
<option value="name-asc">Team Name (A-Z)</option>
<option value="name-desc">Team Name (Z-A)</option>
</select>
</div>
</div>
<div id="submissions-container" class="loading">
Loading submissions...
</div>
Error loading submissions. Please try again later.
';
});
// Build search indexes asynchronously for faster filtering
function buildIndexes(data) {
// Use setTimeout to make it async and not block rendering
setTimeout(() => {
// Build category index
data.forEach((submission, index) => {
if (submission.primary_category) {
if (!categoryIndex.has(submission.primary_category)) {
categoryIndex.set(submission.primary_category, []);
}
categoryIndex.get(submission.primary_category).push(index);
}
// Build domain index
if (submission.facets && submission.facets.domain_area) {
submission.facets.domain_area.forEach(domain => {
if (!domainIndex.has(domain)) {
domainIndex.set(domain, []);
}
domainIndex.get(domain).push(index);
});
}
});
console.log('Search indexes built: Category entries:', categoryIndex.size, 'Domain entries:', domainIndex.size);
}, 0);
}
function populateFilters(data) {
// Populate categories
const categories = [...new Set(data.map(s => s.primary_category).filter(Boolean))].sort();
const categorySelect = document.getElementById('category-filter');
categories.forEach(cat => {
const option = document.createElement('option');
option.value = cat;
option.textContent = formatCategoryName(cat);
categorySelect.appendChild(option);
});
// Populate domains
const domains = [...new Set(data.flatMap(s => s.facets?.domain_area || []))].sort();
const domainSelect = document.getElementById('domain-filter');
domains.forEach(domain => {
const option = document.createElement('option');
option.value = domain;
option.textContent = domain.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
domainSelect.appendChild(option);
});
}
function setupEventListeners() {
// Search input
const searchInput = document.getElementById('search-input');
const clearSearchBtn = document.getElementById('clear-search');
searchInput.addEventListener('input', (e) => {
filters.search = e.target.value.toLowerCase();
clearSearchBtn.classList.toggle('visible', e.target.value.length > 0);
applyFilters();
});
clearSearchBtn.addEventListener('click', () => {
searchInput.value = '';
filters.search = '';
clearSearchBtn.classList.remove('visible');
applyFilters();
});
// Filter dropdowns
document.getElementById('category-filter').addEventListener('change', (e) => {
filters.category = e.target.value;
applyFilters();
});
document.getElementById('domain-filter').addEventListener('change', (e) => {
filters.domain = e.target.value;
applyFilters();
});
document.getElementById('award-filter').addEventListener('change', (e) => {
filters.award = e.target.value;
applyFilters();
});
// Sort
document.getElementById('sort-select').addEventListener('change', (e) => {
sortSubmissions(e.target.value);
});
}
function applyFilters() {
// Use indexes when available for faster filtering
let candidateIndices = null;
// Start with category filter using index if available
if (filters.category) {
candidateIndices = categoryIndex.has(filters.category)
? new Set(categoryIndex.get(filters.category))
: new Set();
}
// Apply domain filter using index if available
if (filters.domain) {
const domainIndices = domainIndex.has(filters.domain)
? new Set(domainIndex.get(filters.domain))
: new Set();
if (candidateIndices === null) {
candidateIndices = domainIndices;
} else {
// Intersection of category and domain
candidateIndices = new Set([...candidateIndices].filter(x => domainIndices.has(x)));
}
}
// If we have candidate indices from indexed filters, use them
const candidates = candidateIndices !== null
? [...candidateIndices].map(i => allSubmissions[i])
: allSubmissions;
// Apply search and award filters
filteredSubmissions = candidates.filter(submission => {
if (filters.search) {
const searchLower = filters.search;
const matchesSearch =
submission.team_name.toLowerCase().includes(searchLower) ||
submission.team_members.toLowerCase().includes(searchLower) ||
submission.description.toLowerCase().includes(searchLower) ||
(submission.project_novelty && submission.project_novelty.toLowerCase().includes(searchLower));
if (!matchesSearch) return false;
}
// Apply award filter
if (filters.award) {
if (filters.award === 'awarded' && !submission.award) {
return false;
} else if (filters.award === 'not-awarded' && submission.award) {
return false;
}
}
return true;
});
updateActiveFilters();
renderSubmissions(filteredSubmissions);
}
function updateActiveFilters() {
const activeFiltersContainer = document.getElementById('active-filters');
activeFiltersContainer.innerHTML = '';
let hasFilters = false;
if (filters.search) {
hasFilters = true;
addFilterChip('Search: "' + filters.search + '"', 'search');
}
if (filters.category) {
hasFilters = true;
addFilterChip('Category: ' + formatCategoryName(filters.category), 'category');
}
if (filters.domain) {
hasFilters = true;
addFilterChip('Domain: ' + filters.domain.replace(/_/g, ' '), 'domain');
}
if (filters.award) {
hasFilters = true;
const awardLabel = filters.award === 'awarded' ? 'Award Winners Only' : 'Non-Award Winners';
addFilterChip('Award: ' + awardLabel, 'award');
}
if (hasFilters) {
const clearAllBtn = document.createElement('button');
clearAllBtn.className = 'clear-all-filters';
clearAllBtn.textContent = 'Clear All';
clearAllBtn.onclick = clearAllFilters;
activeFiltersContainer.appendChild(clearAllBtn);
}
}
function addFilterChip(text, filterType) {
const activeFiltersContainer = document.getElementById('active-filters');
const chip = document.createElement('div');
chip.className = 'active-filter-chip';
chip.innerHTML = `
${text}
×
`;
activeFiltersContainer.appendChild(chip);
}
window.removeFilter = function(filterType) {
filters[filterType] = '';
// Reset the corresponding UI element
if (filterType === 'search') {
document.getElementById('search-input').value = '';
document.getElementById('clear-search').classList.remove('visible');
} else if (filterType === 'category') {
document.getElementById('category-filter').value = '';
} else if (filterType === 'domain') {
document.getElementById('domain-filter').value = '';
} else if (filterType === 'award') {
document.getElementById('award-filter').value = '';
}
applyFilters();
};
function clearAllFilters() {
filters.search = '';
filters.category = '';
filters.domain = '';
filters.award = '';
document.getElementById('search-input').value = '';
document.getElementById('clear-search').classList.remove('visible');
document.getElementById('category-filter').value = '';
document.getElementById('domain-filter').value = '';
document.getElementById('award-filter').value = '';
applyFilters();
}
function sortSubmissions(sortBy) {
if (sortBy === 'name-asc') {
filteredSubmissions.sort((a, b) => a.team_name.localeCompare(b.team_name));
} else if (sortBy === 'name-desc') {
filteredSubmissions.sort((a, b) => b.team_name.localeCompare(a.team_name));
} else {
// Reset to original order
filteredSubmissions = allSubmissions.filter(s => filteredSubmissions.includes(s));
}
renderSubmissions(filteredSubmissions);
}
function renderSubmissions(submissions) {
const container = document.getElementById('submissions-container');
const resultsInfo = document.getElementById('results-info');
const resultsCount = document.getElementById('results-count');
// Update results count
resultsCount.textContent = submissions.length;
resultsInfo.style.display = 'flex';
// Clear container
container.className = '';
container.innerHTML = '';
if (submissions.length === 0) {
container.innerHTML = `
`;
return;
}
submissions.forEach((submission, index) => {
const card = document.createElement('div');
card.className = 'submission-card';
card.style.animationDelay = `${index * 0.05}s`;
let embedContent = '';
if (submission.submission_link) {
let url = submission.submission_link;
if (url.includes('youtube.com/watch?v=')) {
const videoId = new URL(url).searchParams.get('v');
embedContent = `<iframe src="https://www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe>
`;
} else if (url.includes('youtu.be/')) {
const videoId = url.split('youtu.be/')[1].split('?')[0];
embedContent = `<iframe src="https://www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe>
`;
} else if (url.includes('loom.com/share/')) {
const videoId = url.split('loom.com/share/')[1].split('?')[0];
embedContent = `<iframe src="https://www.loom.com/embed/${videoId}" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
`;
} else if (url.includes('linkedin.com/posts/') || url.includes('linkedin.com/feed/update/')) {
embedContent = `
View LinkedIn Post
Click to view this submission's LinkedIn post
`; } else if (url.includes('x.com/') || url.includes('twitter.com/')) { embedContent = ``; } } // Helper function to format category names function formatCategoryName(category) { return category.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); } // Create award badge let awardBadge = ''; if (submission.award) { awardBadge = `${submission.award}
`;
}
// Create primary category badge
let primaryCategoryBadge = '';
if (submission.primary_category) {
primaryCategoryBadge = `${formatCategoryName(submission.primary_category)}
`;
}
// Create domain area chips
let domainAreaChips = '';
if (submission.facets && submission.facets.domain_area) {
domainAreaChips = submission.facets.domain_area.map(domain =>
`${domain.replace(/_/g, ' ')}`
).join('');
}
// Create modality chips
let modalityChips = '';
if (submission.facets && submission.facets.modality) {
modalityChips = submission.facets.modality.map(modality =>
`${modality.replace(/_/g, ' ')}`
).join('');
}
// Create model chips
let modelsUsedChips = '';
if(submission.models_used){
modelsUsedChips = submission.models_used.split(',').map(model =>
`${model.trim()}`
).join('');
}
card.innerHTML = `
${embedContent}
${awardBadge}
${primaryCategoryBadge}
Team Members
${submission.team_members}
Description
${submission.description}
Project Novelty
${submission.project_novelty}
Domain Areas:
${domainAreaChips}
Modalities:
${modalityChips}
AI Models:
${modelsUsedChips}
View Submission
${submission.code_link ? `
View Code
` : ''}
`;
container.appendChild(card);
});
// Load Twitter widgets if needed
if (document.querySelector('.twitter-tweet')) {
const script = document.createElement('script');
script.src = 'https://platform.twitter.com/widgets.js';
script.charset = 'utf-8';
script.async = true;
document.body.appendChild(script);
}
}
// Helper function to format category names
function formatCategoryName(category) {
return category.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
}
});
</script>