function parseCSV(csv) {
const lines = csv.split("\n");
const headers = lines[0]
.split(",")
.map((header) => header.replace(/"/g, "").trim());
return lines
.slice(1)
.map((line) => {
const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
const entry = {};
headers.forEach((header, index) => {
let value = values[index] ? values[index].replace(/"/g, "").trim() : "";
// Remove backticks from the act/title
if (header === "app") {
value = value.replace(/`/g, "");
}
entry[header] = value;
});
return entry;
})
.filter((entry) => entry.app && entry.prompt);
}
// Load prompts from CSV
async function loadPrompts() {
const response = await fetch('/vibeprompts.csv');
const text = await response.text();
return parseCSV(text);
}
// Update prompt count
function updatePromptCount(filteredCount, totalCount) {
const countElement = document.getElementById('promptCount');
const countNumber = countElement.getElementsByClassName('count-number')[0];
if (countElement) {
countNumber.textContent = `${filteredCount}`;
}
}
// Render prompts in the main content area
async function renderMainPrompts() {
const prompts = await loadPrompts();
const container = document.querySelector('#promptContent');
if (container) {
container.innerHTML = `
${prompts.map(({ app, prompt, contributor, techstack }) => `
${prompt.replace(/\\n/g, '
')}
`).join('')}
`;
// Add click handlers for modal
const cards = container.querySelectorAll('.prompt-card:not(.contribute-card)');
cards.forEach((card, index) => {
card.addEventListener('click', (e) => {
// Don't open modal if clicking on buttons or links
if (!e.target.closest('.copy-button') && !e.target.closest('.contributor-badge')) {
const promptData = prompts[index];
showModal(promptData.app, promptData.prompt, promptData.contributor);
}
});
});
}
updatePromptCount(prompts.length, prompts.length);
}
// Render prompts in the sidebar
async function renderSidebarPrompts() {
const prompts = await loadPrompts();
const searchResults = document.getElementById('searchResults');
if (searchResults) {
searchResults.innerHTML = prompts.map(({ app }) => `
${app}
`).join('');
}
}
// Scroll to prompt card function
function scrollToPrompt(title, prompt) {
// Find the prompt card with matching title
const cards = document.querySelectorAll('.prompt-card');
const targetCard = Array.from(cards).find(card => {
const cardTitle = card.querySelector('.prompt-title').textContent
.replace(/\s+/g, ' ') // Normalize whitespace
.replace(/[\n\r]/g, '') // Remove newlines
.trim();
const searchTitle = title
.replace(/\s+/g, ' ') // Normalize whitespace
.replace(/[\n\r]/g, '') // Remove newlines
.trim();
return cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) ||
searchTitle.toLowerCase().includes(cardTitle.toLowerCase());
});
if (targetCard) {
// Remove highlight from all cards
cards.forEach(card => {
card.style.transition = 'all 0.3s ease';
card.style.transform = 'none';
card.style.boxShadow = 'none';
card.style.borderColor = '';
});
// Different scroll behavior for mobile and desktop
const isMobile = window.innerWidth <= 768;
const headerHeight = document.querySelector('.site-header').offsetHeight;
if (isMobile) {
// On mobile, scroll the window
const cardRect = targetCard.getBoundingClientRect();
const scrollTop = window.pageYOffset + cardRect.top - headerHeight - 20;
window.scrollTo({
top: scrollTop,
behavior: 'smooth'
});
} else {
// On desktop, scroll the main-content container
const mainContent = document.querySelector('.main-content');
const cardRect = targetCard.getBoundingClientRect();
const scrollTop = mainContent.scrollTop + cardRect.top - headerHeight - 20;
mainContent.scrollTo({
top: scrollTop,
behavior: 'smooth'
});
}
// Add highlight effect after scrolling completes
setTimeout(() => {
targetCard.style.transform = 'scale(1.02)';
targetCard.style.boxShadow = '0 0 0 2px var(--accent-color)';
targetCard.style.borderColor = 'var(--accent-color)';
// Remove highlight after animation
setTimeout(() => {
targetCard.style.transform = 'none';
targetCard.style.boxShadow = 'none';
targetCard.style.borderColor = '';
}, 2000);
}, 500); // Wait for scroll to complete
}
}
// Search functionality
function setupSearch() {
const searchInput = document.getElementById('searchInput');
const searchResults = document.getElementById('searchResults');
if (searchInput && searchResults) {
searchInput.addEventListener('input', async (e) => {
const query = e.target.value.toLowerCase();
const prompts = await loadPrompts();
const filtered = prompts.filter(({ act, prompt }) =>
act.toLowerCase().includes(query) || prompt.toLowerCase().includes(query)
);
// Update prompt count
updatePromptCount(filtered.length, prompts.length);
// Show filtered results
if (window.innerWidth <= 768 && !query.trim()) {
searchResults.innerHTML = ''; // Clear results on mobile if no search query
} else {
searchResults.innerHTML = filtered.length === 0
? ``
: filtered.map(({ act, prompt }) => `
${act}
`).join('');
}
});
}
}
// Fetch GitHub stars
async function fetchGitHubStars() {
try {
const response = await fetch("https://api.github.com/repos/f/awesome-chatgpt-prompts");
const data = await response.json();
const stars = data.stargazers_count;
const starCount = document.getElementById("starCount");
if (starCount) {
starCount.textContent = stars.toLocaleString();
}
} catch (error) {
console.error("Error fetching star count:", error);
const starCount = document.getElementById("starCount");
if (starCount) {
starCount.textContent = "122k+";
}
}
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
renderMainPrompts();
renderSidebarPrompts();
setupSearch();
fetchGitHubStars();
});
// Dark mode toggle
function toggleDarkMode() {
document.body.classList.toggle('dark-mode');
const isDark = document.body.classList.contains('dark-mode');
localStorage.setItem('darkMode', isDark);
}
// Initialize dark mode from localStorage
const savedDarkMode = localStorage.getItem('darkMode') === 'true';
if (savedDarkMode) {
document.body.classList.add('dark-mode');
}
// Copy prompt to clipboard
async function copyPrompt(button, encodedPrompt) {
try {
const promptText = decodeURIComponent(encodedPrompt);
await navigator.clipboard.writeText(promptText);
const originalHTML = button.innerHTML;
button.innerHTML = `
`;
setTimeout(() => {
button.innerHTML = originalHTML;
}, 2000);
} catch (err) {
console.error("Failed to copy text: ", err);
}
}
// Open prompt in AI chat
function openInChat(button, encodedPrompt) {
const promptText = decodeURIComponent(encodedPrompt);
const platform = document.querySelector(".platform-tag.active");
if (!platform) return;
const baseUrl = platform.dataset.url;
let url;
switch (platform.dataset.platform) {
case "github-copilot":
url = `${baseUrl}?prompt=${encodeURIComponent(promptText)}`;
break;
case "chatgpt":
url = `${baseUrl}?prompt=${encodeURIComponent(promptText)}`;
break;
case "grok":
url = `${baseUrl}&q=${encodeURIComponent(promptText)}`;
break;
case "claude":
url = `${baseUrl}?q=${encodeURIComponent(promptText)}`;
break;
case "perplexity":
url = `${baseUrl}/search?q=${encodeURIComponent(promptText)}`;
break;
case "mistral":
url = `${baseUrl}?q=${encodeURIComponent(promptText)}`;
break;
default:
url = `${baseUrl}?q=${encodeURIComponent(promptText)}`;
}
window.open(url, "_blank");
}
// Add modal functionality
function showModal(app, prompt, contributor) {
let modalOverlay = document.getElementById('modalOverlay');
if (!modalOverlay) {
// Create modal if it doesn't exist
const modalHTML = `
`;
document.body.insertAdjacentHTML('beforeend', modalHTML);
modalOverlay = document.getElementById('modalOverlay');
// Add event listeners
const modalClose = modalOverlay.querySelector('.modal-close');
modalClose.addEventListener('click', hideModal);
modalOverlay.addEventListener('click', (e) => {
if (e.target === modalOverlay) {
hideModal();
}
});
// Add copy functionality
const modalCopyButton = modalOverlay.querySelector('.modal-copy-button');
modalCopyButton.addEventListener('click', () => {
copyPrompt(modalCopyButton, encodeURIComponent(prompt));
});
}
const modalTitle = modalOverlay.querySelector('.modal-title');
const modalCode = modalOverlay.querySelector('.modal-content code');
const modalContributor = modalOverlay.querySelector('.modal-contributor');
modalTitle.textContent = app;
modalCode.innerHTML = prompt.replace(/\\n/g, '
');
if (contributor) {
modalContributor.href = `https://github.com/${contributor.replace('@', '')}`;
modalContributor.textContent = `Contributed by ${contributor}`;
}
modalOverlay.style.display = 'block';
document.body.style.overflow = 'hidden';
}
function hideModal() {
const modalOverlay = document.getElementById('modalOverlay');
if (!modalOverlay) return;
modalOverlay.style.display = 'none';
document.body.style.overflow = '';
}
// Add global event listener for Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
hideModal();
}
});