// pages/AreaPage.js - Single-topic view for area pages
import { getFeaturedArtifacts } from '../init.js';
import { createArtifactCarousel } from '../cards/ArtifactSummaryCard.js';
import { renderAreaNavigation } from '../components/PageNavigation.js';
import { renderContentSection, renderOpennessCallout } from '../components/ContentSection.js';
// Use global areasData (loaded in index.html
)
const areasData = window.areasData;
export function renderAreaPage(areaId, topicId = null) {
const area = areasData[areaId];
if (!area) {
return {
content: `Area not found
`,
init: () => {}
};
}
// If no topic specified, show overview of the area
if (!topicId) {
return renderAreaOverview(area, areaId);
}
// Show specific topic
const topic = area.topics[topicId];
if (!topic) {
return {
content: `Topic not found
`,
init: () => {}
};
}
return renderTopicView(area, areaId, topic, topicId);
}
function renderAreaOverview(area, areaId) {
// Get topics as array
const topics = Object.entries(area.topics).map(([key, value]) => ({
id: key,
name: typeof value === 'string' ? value : value.name,
navName: typeof value === 'string' ? value : (value.navName || value.name),
description: typeof value === 'string' ? '' : (value.description || ''),
color: typeof value === 'object' ? value.color : 'bg-gray-200 text-gray-700'
}));
const content = `
${renderAreaNavigation(areaId, area.navTitle, topics, null)}
${renderContentSection('overview', `
${area.title}
${area.description.paragraphs ?
area.description.paragraphs.map(p => `
${p}
`).join('')
: `
${area.description.short || area.description}
`
}
Topics in this area:
${topics.map(topic => {
// Extract colors from topic.color
let bgColor = 'bg-gray-200';
let textColor = 'text-gray-700';
if (topic.color) {
const bgMatch = topic.color.match(/bg-(\w+)-(\d+)/);
const textMatch = topic.color.match(/text-(\w+)-(\d+)/);
if (bgMatch) bgColor = `bg-${bgMatch[1]}-${bgMatch[2]}`;
if (textMatch) textColor = `text-${textMatch[1]}-700`;
}
// Get short description for tooltip
const shortDesc = topic.description?.short || (typeof topic.description === 'string' ? topic.description.split('.')[0] + '.' : '');
const titleAttr = shortDesc ? ` title="${shortDesc}"` : '';
return `
${topic.navName}
`;
}).join('')}
`)}
`;
return {
content,
init: () => {
initializeAreaArtifactsCarousel(areaId);
}
};
}
function renderTopicView(area, areaId, topic, topicId) {
const topicName = topic.navName || topic.name;
const topicDescription = topic.description?.paragraphs
? topic.description.paragraphs.map(p => `${p}
`).join('')
: (topic.description?.short || topic.description || '');
// Get all topics for navigation
const allTopics = Object.entries(area.topics).map(([key, value]) => ({
id: key,
navName: typeof value === 'string' ? value : (value.navName || value.name)
}));
const content = `
${renderAreaNavigation(areaId, area.navTitle, allTopics, topicId)}
${renderContentSection(topicId, `
${topic.name}
${topicDescription ? `
${topicDescription}
` : ''}
Related Research & Resources
`)}
`;
return {
content,
init: () => {
// Initialize artifact carousel for this topic
setTimeout(async () => {
try {
const allArtifacts = window.allArtifacts || [];
// Filter artifacts by this specific topic
const filteredArtifacts = allArtifacts.filter(artifact =>
artifact.topics && artifact.topics.includes(topicId)
);
// Transform field names to match expected format
const transformedArtifacts = filteredArtifacts.map(artifact => ({
...artifact,
areaTags: artifact.areas,
subAreaTags: artifact.topics,
sourceUrl: artifact.url
}));
const carouselId = `${topicId}-artifacts-carousel`;
createArtifactCarousel(transformedArtifacts.length > 0 ? transformedArtifacts : getFeaturedArtifacts(), carouselId);
} catch (error) {
console.error(`Error creating carousel for ${topicId}:`, error);
const carouselId = `${topicId}-artifacts-carousel`;
createArtifactCarousel(getFeaturedArtifacts(), carouselId);
}
}, 50);
}
};
}
// Helper function to initialize area artifacts carousel
function initializeAreaArtifactsCarousel(areaId) {
// Wait for DOM to be ready
setTimeout(() => {
try {
const allArtifacts = window.allArtifacts || [];
// Filter artifacts by area
const filteredArtifacts = allArtifacts.filter(artifact =>
artifact.areas && artifact.areas.includes(areaId)
);
// Transform field names to match what the carousel expects
const transformedArtifacts = filteredArtifacts.map(artifact => ({
...artifact,
areaTags: artifact.areas,
subAreaTags: artifact.topics,
sourceUrl: artifact.url
}));
const carouselId = `area-artifacts-carousel-${areaId}`;
createArtifactCarousel(transformedArtifacts.length > 0 ? transformedArtifacts : getFeaturedArtifacts(), carouselId);
} catch (error) {
console.error(`Error creating carousel for area ${areaId}:`, error);
const carouselId = `area-artifacts-carousel-${areaId}`;
createArtifactCarousel(getFeaturedArtifacts(), carouselId);
}
}, 50);
}