import { categories } from './config/tools.js';
import { dom, switchView, hideAlert } from './ui.js';
import { setupToolInterface } from './handlers/toolSelectionHandler.js';
import { createIcons, icons } from 'lucide';
import * as pdfjsLib from 'pdfjs-dist';
import '../css/styles.css';
import { formatStars } from './utils/helpers.js';
const init = () => {
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url
).toString();
// Handle simple mode - hide branding sections but keep logo and copyright
if (__SIMPLE_MODE__) {
const hideBrandingSections = () => {
// Hide navigation but keep logo
const nav = document.querySelector('nav');
if (nav) {
// Hide the entire nav but we'll create a minimal one with just logo
nav.style.display = 'none';
// Create a simple nav with just logo on the right
const simpleNav = document.createElement('nav');
simpleNav.className =
'bg-gray-800 border-b border-gray-700 sticky top-0 z-30';
simpleNav.innerHTML = `
BentoPDF
`;
document.body.insertBefore(simpleNav, document.body.firstChild);
}
const heroSection = document.getElementById('hero-section');
if (heroSection) {
heroSection.style.display = 'none';
}
const githubLink = document.querySelector('a[href*="github.com/alam00000/bentopdf"]');
if (githubLink) {
(githubLink as HTMLElement).style.display = 'none';
}
const featuresSection = document.getElementById('features-section');
if (featuresSection) {
featuresSection.style.display = 'none';
}
const securitySection = document.getElementById(
'security-compliance-section'
);
if (securitySection) {
securitySection.style.display = 'none';
}
const faqSection = document.getElementById('faq-accordion');
if (faqSection) {
faqSection.style.display = 'none';
}
const testimonialsSection = document.getElementById(
'testimonials-section'
);
if (testimonialsSection) {
testimonialsSection.style.display = 'none';
}
const supportSection = document.getElementById('support-section');
if (supportSection) {
supportSection.style.display = 'none';
}
// Hide footer but keep copyright
const footer = document.querySelector('footer');
if (footer) {
footer.style.display = 'none';
const simpleFooter = document.createElement('footer');
simpleFooter.className = 'mt-16 border-t-2 border-gray-700 py-8';
simpleFooter.innerHTML = `
BentoPDF
© 2025 BentoPDF. All rights reserved.
Version 1.6.2
`;
document.body.appendChild(simpleFooter);
}
const sectionDividers = document.querySelectorAll('.section-divider');
sectionDividers.forEach((divider) => {
(divider as HTMLElement).style.display = 'none';
});
document.title = 'BentoPDF - PDF Tools';
const toolsHeader = document.getElementById('tools-header');
if (toolsHeader) {
const title = toolsHeader.querySelector('h2');
const subtitle = toolsHeader.querySelector('p');
if (title) {
title.textContent = 'PDF Tools';
title.className = 'text-4xl md:text-5xl font-bold text-white mb-3';
}
if (subtitle) {
subtitle.textContent = 'Select a tool to get started';
subtitle.className = 'text-lg text-gray-400';
}
}
const app = document.getElementById('app');
if (app) {
app.style.paddingTop = '1rem';
}
};
hideBrandingSections();
}
dom.toolGrid.textContent = '';
categories.forEach((category) => {
const categoryGroup = document.createElement('div');
categoryGroup.className = 'category-group col-span-full';
const title = document.createElement('h2');
title.className = 'text-xl font-bold text-indigo-400 mb-4 mt-8 first:mt-0 text-white';
title.textContent = category.name;
const toolsContainer = document.createElement('div');
toolsContainer.className =
'grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 md:gap-6';
category.tools.forEach((tool) => {
let toolCard: HTMLDivElement | HTMLAnchorElement;
if (tool.href) {
toolCard = document.createElement('a');
toolCard.href = tool.href;
toolCard.className =
'tool-card block bg-gray-800 rounded-xl p-4 cursor-pointer flex flex-col items-center justify-center text-center no-underline hover:shadow-lg transition duration-200';
} else {
toolCard = document.createElement('div');
toolCard.className =
'tool-card bg-gray-800 rounded-xl p-4 cursor-pointer flex flex-col items-center justify-center text-center hover:shadow-lg transition duration-200';
toolCard.dataset.toolId = tool.id;
}
const icon = document.createElement('i');
icon.className = 'w-10 h-10 mb-3 text-indigo-400';
icon.setAttribute('data-lucide', tool.icon);
const toolName = document.createElement('h3');
toolName.className = 'font-semibold text-white';
toolName.textContent = tool.name;
toolCard.append(icon, toolName);
if (tool.subtitle) {
const toolSubtitle = document.createElement('p');
toolSubtitle.className = 'text-xs text-gray-400 mt-1 px-2';
toolSubtitle.textContent = tool.subtitle;
toolCard.appendChild(toolSubtitle);
}
toolsContainer.appendChild(toolCard);
});
categoryGroup.append(title, toolsContainer);
dom.toolGrid.appendChild(categoryGroup);
});
const searchBar = document.getElementById('search-bar');
const categoryGroups = dom.toolGrid.querySelectorAll('.category-group');
searchBar.addEventListener('input', () => {
// @ts-expect-error TS(2339) FIXME: Property 'value' does not exist on type 'HTMLEleme... Remove this comment to see the full error message
const searchTerm = searchBar.value.toLowerCase().trim();
categoryGroups.forEach((group) => {
const toolCards = group.querySelectorAll('.tool-card');
let visibleToolsInCategory = 0;
toolCards.forEach((card) => {
const toolName = card.querySelector('h3').textContent.toLowerCase();
const toolSubtitle =
card.querySelector('p')?.textContent.toLowerCase() || '';
const isMatch =
toolName.includes(searchTerm) || toolSubtitle.includes(searchTerm);
card.classList.toggle('hidden', !isMatch);
if (isMatch) {
visibleToolsInCategory++;
}
});
group.classList.toggle('hidden', visibleToolsInCategory === 0);
});
});
window.addEventListener('keydown', function (e) {
const key = e.key.toLowerCase();
const isMac = navigator.userAgent.toUpperCase().includes('MAC');
const isCtrlK = e.ctrlKey && key === 'k';
const isCmdK = isMac && e.metaKey && key === 'k';
if (isCtrlK || isCmdK) {
e.preventDefault();
searchBar.focus();
}
});
const shortcutK = document.getElementById('shortcut');
const isIosOrAndroid = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
if (isIosOrAndroid) {
shortcutK.style.display = 'none';
} else {
shortcutK.textContent = navigator.userAgent.toUpperCase().includes('MAC')
? '⌘ + K'
: 'Ctrl + K';
}
dom.toolGrid.addEventListener('click', (e) => {
// @ts-expect-error TS(2339) FIXME: Property 'closest' does not exist on type 'EventTa... Remove this comment to see the full error message
const card = e.target.closest('.tool-card');
if (card) {
const toolId = card.dataset.toolId;
setupToolInterface(toolId);
}
});
dom.backToGridBtn.addEventListener('click', () => switchView('grid'));
dom.alertOkBtn.addEventListener('click', hideAlert);
const faqAccordion = document.getElementById('faq-accordion');
if (faqAccordion) {
faqAccordion.addEventListener('click', (e) => {
// @ts-expect-error TS(2339) FIXME: Property 'closest' does not exist on type 'EventTa... Remove this comment to see the full error message
const questionButton = e.target.closest('.faq-question');
if (!questionButton) return;
const faqItem = questionButton.parentElement;
const answer = faqItem.querySelector('.faq-answer');
faqItem.classList.toggle('open');
if (faqItem.classList.contains('open')) {
answer.style.maxHeight = answer.scrollHeight + 'px';
} else {
answer.style.maxHeight = '0px';
}
});
}
createIcons({ icons });
console.log('Please share our tool and share the love!');
const githubStarsElement = document.getElementById('github-stars');
if (githubStarsElement && !__SIMPLE_MODE__) {
fetch('https://api.github.com/repos/alam00000/bentopdf')
.then((response) => response.json())
.then((data) => {
if (data.stargazers_count !== undefined) {
githubStarsElement.textContent = formatStars(data.stargazers_count);
}
})
.catch(() => {
githubStarsElement.textContent = '-';
});
}
};
document.addEventListener('DOMContentLoaded', init);