diff --git a/website/src/components/Modal.astro b/website/src/components/Modal.astro deleted file mode 100644 index 82b2e395..00000000 --- a/website/src/components/Modal.astro +++ /dev/null @@ -1,242 +0,0 @@ ---- -// Modal component for viewing file contents ---- - - diff --git a/website/src/integrations/pagefind-resources.ts b/website/src/integrations/pagefind-resources.ts index f68e2e75..bc65bb89 100644 --- a/website/src/integrations/pagefind-resources.ts +++ b/website/src/integrations/pagefind-resources.ts @@ -42,9 +42,7 @@ const TYPE_PAGES: Record = { }; // Resource types that have a dedicated detail page at ///. Search -// results for these should deep-link to the canonical detail page rather than -// the listing page with an inert #file= hash (listing pages no longer open a -// modal from that hash). +// results for these should deep-link to the canonical detail page. const DETAIL_ROUTE_TYPES = new Set([ "agent", "instruction", @@ -118,9 +116,7 @@ export default function pagefindResources(): AstroIntegration { const url = hasDetailPage ? `${base}${record.type}/${encodeURIComponent(record.id)}/` - : `${base}${typePage.slice(1)}#file=${encodeURIComponent( - record.path - )}`; + : `${base}${typePage.slice(1)}`; const typeLabel = TYPE_LABELS[record.type] || record.type; const addResult = await index.addCustomRecord({ diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro index 369ad438..3113a61a 100644 --- a/website/src/pages/index.astro +++ b/website/src/pages/index.astro @@ -1,6 +1,5 @@ --- import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; -import Modal from "../components/Modal.astro"; import Icon from "../components/Icon.astro"; import BackToTop from "../components/BackToTop.astro"; @@ -177,8 +176,6 @@ const base = import.meta.env.BASE_URL; - - diff --git a/website/src/pages/learning-hub/cookbook/[cookbook]/[language]/[recipe].astro b/website/src/pages/learning-hub/cookbook/[cookbook]/[language]/[recipe].astro new file mode 100644 index 00000000..5f52a891 --- /dev/null +++ b/website/src/pages/learning-hub/cookbook/[cookbook]/[language]/[recipe].astro @@ -0,0 +1,229 @@ +--- +import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; +import BackToTop from "../../../../../components/BackToTop.astro"; +import Breadcrumb from "../../../../../components/pages/Breadcrumb.astro"; +import FileBrowser from "../../../../../components/pages/FileBrowser.astro"; +import { readResourceMarkdown } from "../../../../../lib/detail-page"; +import samplesData from "../../../../../../public/data/samples.json"; + +interface RecipeVariant { + doc: string; + example: string | null; +} + +interface Recipe { + id: string; + name: string; + description: string; + tags: string[]; + languages: string[]; + variants: Record; + external?: boolean; + url?: string | null; + author?: { name: string; url?: string } | null; +} + +interface Language { + id: string; + name: string; + icon: string; + extension: string; +} + +interface Cookbook { + id: string; + name: string; + description: string; + path: string; + featured: boolean; + languages: Language[]; + recipes: Recipe[]; +} + +interface SamplesData { + cookbooks: Cookbook[]; +} + +const GITHUB_BASE = "https://github.com/github/awesome-copilot/blob/main"; + +function buildCookbookUrl( + cookbookId: string, + languageId: string, + recipeId: string, + filePath?: string | null +): string { + const basePath = `/learning-hub/cookbook/${encodeURIComponent( + cookbookId + )}/${encodeURIComponent(languageId)}/${encodeURIComponent(recipeId)}/`; + if (!filePath) return basePath; + return `${basePath}#file=${encodeURIComponent(filePath)}`; +} + +export function getStaticPaths() { + const entries = (samplesData as SamplesData).cookbooks.flatMap((cookbook) => + cookbook.recipes.flatMap((recipe) => + Object.keys(recipe.variants ?? {}).map((languageId) => ({ + params: { + cookbook: cookbook.id, + language: languageId, + recipe: recipe.id, + }, + })) + ) + ); + return entries; +} + +const { cookbook, language, recipe } = Astro.params as { + cookbook: string; + language: string; + recipe: string; +}; + +const cookbookEntry = (samplesData as SamplesData).cookbooks.find( + (item) => item.id === cookbook +); +const recipeEntry = cookbookEntry?.recipes.find((item) => item.id === recipe); +const languageEntry = cookbookEntry?.languages.find((item) => item.id === language); +const variant = recipeEntry?.variants?.[language]; + +if (!cookbookEntry || !recipeEntry || !languageEntry || !variant || recipeEntry.external) { + return Astro.redirect("/learning-hub/cookbook/"); +} + +const { markdownHtml } = readResourceMarkdown(variant.doc); +const files = [{ name: variant.doc.split("/").pop() ?? variant.doc, path: variant.doc }]; + +if (variant.example) { + files.push({ + name: variant.example.split("/").pop() ?? variant.example, + path: variant.example, + }); +} + +const recipeUrl = buildCookbookUrl(cookbook, language, recipe); +const exampleUrl = variant.example + ? buildCookbookUrl(cookbook, language, recipe, variant.example) + : null; +--- + + +
+
+ + +
+

{recipeEntry.name}

+

{recipeEntry.description}

+
+ {languageEntry.icon} {languageEntry.name} +
+ {recipeEntry.tags.map((tag) => ( + {tag} + ))} +
+
+ +
+ + +
+
+ + + + + + +
diff --git a/website/src/pages/learning-hub/cookbook/index.astro b/website/src/pages/learning-hub/cookbook/index.astro index b2825f7d..88d473a9 100644 --- a/website/src/pages/learning-hub/cookbook/index.astro +++ b/website/src/pages/learning-hub/cookbook/index.astro @@ -1,7 +1,6 @@ --- import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import samplesData from '../../../../public/data/samples.json'; -import Modal from '../../../components/Modal.astro'; import EmbeddedPageData from '../../../components/EmbeddedPageData.astro'; import { getRecipeResultsCountText, @@ -56,7 +55,6 @@ const languageOptions = Array.from(
-