95 lines
4.5 KiB
JavaScript
95 lines
4.5 KiB
JavaScript
async function loadLinks() {
|
|
const container = document.getElementById('links-container');
|
|
if (!container) return;
|
|
|
|
try {
|
|
const response = await fetch('./assets/data/links.json');
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to load links: ${response.status}`);
|
|
}
|
|
|
|
const groups = await response.json();
|
|
|
|
// Helper function to fetch SVG content
|
|
const fetchSvg = async (path) => {
|
|
if (!path) return '';
|
|
try {
|
|
const res = await fetch(path);
|
|
if (!res.ok) return '';
|
|
return await res.text();
|
|
} catch (e) {
|
|
console.error(`Failed to load SVG: ${path}`, e);
|
|
return '';
|
|
}
|
|
};
|
|
|
|
// Process groups and fetch SVGs in parallel
|
|
const groupsWithSvgs = await Promise.all(groups.map(async (group) => {
|
|
const groupIconSvg = await fetchSvg(group.iconPath);
|
|
|
|
const linksWithSvgs = await Promise.all(group.links.map(async (link) => {
|
|
const linkIconSvg = link.iconPath ? await fetchSvg(link.iconPath) : '';
|
|
return { ...link, iconSvg: linkIconSvg };
|
|
}));
|
|
|
|
return { ...group, iconSvg: groupIconSvg, links: linksWithSvgs };
|
|
}));
|
|
|
|
container.innerHTML = groupsWithSvgs.map(group => `
|
|
<!-- ${group.title} Card -->
|
|
<div class="card-hover bg-white rounded-2xl shadow-lg p-6 border border-gray-100">
|
|
<div class="flex items-center space-x-3 mb-6">
|
|
<div class="w-10 h-10 ${group.iconColorClass} rounded-lg flex items-center justify-center">
|
|
${group.iconSvg}
|
|
</div>
|
|
<h3 class="text-xl font-bold text-gray-900">${group.title}</h3>
|
|
</div>
|
|
|
|
<div class="space-y-3">
|
|
${group.links.map(link => {
|
|
const isPrototype = link.url.startsWith('/prototypes/');
|
|
const isVideo = link.isVideo === true;
|
|
const hrefAttr = (isPrototype || isVideo) ? 'href="#"' : `href="${link.url}" target="_blank"`;
|
|
const onclickAttr = (isPrototype || isVideo) ? `onclick="event.preventDefault(); showView('iframe', this, '${link.url}', '${link.title}')"` : '';
|
|
|
|
return `
|
|
<a ${hrefAttr} ${onclickAttr}
|
|
class="flex items-center justify-between p-4 ${link.containerClass} rounded-xl transition-all group">
|
|
<div class="flex items-center space-x-3">
|
|
${link.iconClass ? `<div class="${link.iconClass}"></div>` : link.iconSvg}
|
|
${link.subtitle ? `
|
|
<div>
|
|
<div class="font-medium text-gray-900 ${link.textHoverClass}">${link.title}</div>
|
|
<div class="text-xs text-gray-500">${link.subtitle}</div>
|
|
</div>
|
|
` : `
|
|
<span class="font-medium text-gray-900 ${link.textHoverClass}">${link.title}</span>
|
|
`}
|
|
</div>
|
|
${link.badge ? `
|
|
<span class="px-3 py-1 ${link.badgeColorClass} text-white text-xs font-semibold rounded-full">${link.badge}</span>
|
|
` : ''}
|
|
${link.arrowIcon ? `
|
|
<svg class="w-5 h-5 text-gray-400 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
` : ''}
|
|
</a>
|
|
`}).join('')}
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
} catch (error) {
|
|
console.error('Error loading links:', error);
|
|
container.innerHTML = `
|
|
<div class="col-span-full p-4 bg-red-50 text-red-600 rounded-xl border border-red-200">
|
|
Failed to load application links. Please try refreshing the page.
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
// Load links when the DOM is loaded
|
|
document.addEventListener('DOMContentLoaded', loadLinks);
|