-
-
Notifications
You must be signed in to change notification settings - Fork 208
feat: add tags to project metadata #69 #164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
0ec3280
2a6ad06
560a8c5
0764d44
b0dfbed
8b9c380
01d66ef
327ee17
79d0517
9d6fc5a
bea4d7a
b1e7043
8ea4942
6c7edc3
0066619
d6e9634
b263aaa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| --- | ||
| import DefaultLayout from '@layouts/DefaultLayout.astro' | ||
| import PageHeader from '@components/PageHeader.astro' | ||
| import { Badge, Card, Heading, Link, Pagination } from 'accessible-astro-components' | ||
| import { getCollection } from 'astro:content' | ||
| import type { GetStaticPaths, Page } from 'astro' | ||
| import type { CollectionEntry } from 'astro:content' | ||
|
|
||
| // Import images directly for optimization | ||
| import projectImage1 from '@assets/images/projects/project-image-1.png' | ||
| import projectImage2 from '@assets/images/projects/project-image-2.png' | ||
| import projectImage3 from '@assets/images/projects/project-image-3.png' | ||
| import projectImage4 from '@assets/images/projects/project-image-4.png' | ||
| import projectImage5 from '@assets/images/projects/project-image-5.png' | ||
| import projectImage6 from '@assets/images/projects/project-image-6.png' | ||
|
|
||
| export const getStaticPaths = (async ({ paginate }) => { | ||
| const projects = await getCollection('projects') | ||
| const allTags = projects.map((project) => project.data.tags).flat() | ||
| const uniqueTags = [...new Set(allTags)].sort((a, b) => a.localeCompare(b)) | ||
|
peterpadberg marked this conversation as resolved.
Outdated
|
||
|
|
||
| const projectImages = [projectImage1, projectImage2, projectImage3, projectImage4, projectImage5, projectImage6] | ||
|
|
||
| const projectsWithImages = projects.map((project, index) => { | ||
| return { | ||
| ...project, | ||
| featuredImage: projectImages[index % projectImages.length], | ||
| } | ||
| }) | ||
|
|
||
| // Generate paginated pages for each tag | ||
| const allPaginatedPages = [] | ||
|
|
||
| for (const tag of uniqueTags) { | ||
| const filteredProjects = projectsWithImages.filter((project) => project.data.tags.includes(tag)) | ||
|
|
||
| const paginatedPages = paginate(filteredProjects, { | ||
| pageSize: 6, | ||
| params: { tag }, | ||
| props: { | ||
| currentTag: tag, | ||
| uniqueTags, | ||
| }, | ||
| }) | ||
|
|
||
| allPaginatedPages.push(...paginatedPages) | ||
| } | ||
|
|
||
| return allPaginatedPages | ||
| }) satisfies GetStaticPaths | ||
|
|
||
| interface Props { | ||
| page: Page<CollectionEntry<'projects'> & { featuredImage: any }> | ||
| currentTag: string | ||
| uniqueTags: string[] | ||
| } | ||
|
|
||
| const { page, currentTag, uniqueTags } = Astro.props | ||
| --- | ||
|
|
||
| <DefaultLayout | ||
| title={`Portfolio - ${currentTag}`} | ||
| description={`Projects filtered by ${currentTag} tag. Discover our work in ${currentTag} and related technologies.`} | ||
| > | ||
| <PageHeader | ||
| title={`Portfolio: ${currentTag}`} | ||
| subtitle={`Showing ${page.total} project${page.total !== 1 ? 's' : ''} tagged with "${currentTag}". <a href="/portfolio">View all projects</a> or filter by other tags below.`} | ||
| bgType="bordered" | ||
|
Comment on lines
+73
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct the subtitle project count.
- subtitle={`Showing ${page.total} project${page.total !== 1 ? 's' : ''} tagged with "${currentTag.label}". <a href="/portfolio">View all projects</a> or filter by other tags below.`}
+ subtitle={`Showing ${page.end - page.start + 1} project${page.end - page.start + 1 !== 1 ? 's' : ''} tagged with "${currentTag.label}". <a href="/portfolio">View all projects</a> or filter by other tags below.`}
🤖 Prompt for AI Agents |
||
| /> | ||
| <section class="my-12"> | ||
| <div class="container"> | ||
| <div class="grid grid-cols-1 gap-8 md:grid-cols-[300px_1fr]"> | ||
| <div class="mb-6"> | ||
| <Heading level="h2" size="h5" class="mb-2">Tags</Heading> | ||
| <p class="mb-4"> | ||
| <Link href="/portfolio">← All projects</Link> | ||
| </p> | ||
| <div class="flex flex-wrap gap-4"> | ||
| { | ||
| uniqueTags.map((tag: string) => { | ||
| const isCurrentTag = tag === currentTag | ||
| return isCurrentTag ? ( | ||
| <Link isButton size="sm" href={'/portfolio/tag/' + tag} disabled class="disabled"> | ||
| {tag} | ||
| </Link> | ||
| ) : ( | ||
| <Link isButton size="sm" href={'/portfolio/tag/' + tag}> | ||
| {tag} | ||
| </Link> | ||
| ) | ||
| }) | ||
| } | ||
| </div> | ||
| </div> | ||
| <div class="mb-6"> | ||
| <p class="text-sm"> | ||
| <em | ||
| >Project {page.start + 1} through {page.end + 1} of {page.total} total projects tagged with "{ | ||
| currentTag | ||
| }"</em | ||
| > | ||
| </p> | ||
| <ul class="mt-3 grid grid-cols-1 gap-6 lg:grid-cols-2"> | ||
| { | ||
| page.data.map((project) => ( | ||
| <li> | ||
| <Card | ||
| imageComponent={project.featuredImage} | ||
| url={'/portfolio/' + project.id} | ||
| title={project.data.title} | ||
| headingLevel="h2" | ||
| footer={'Author: ' + project.data.author} | ||
| fullHeight={true} | ||
| > | ||
| <span slot="meta"> | ||
| {project.data.tags.map((tag) => { | ||
| const isCurrentTag = tag === currentTag | ||
| return isCurrentTag ? <Badge class="bg-blue-600 text-white">{tag}</Badge> : <Badge>{tag}</Badge> | ||
| })} | ||
| </span> | ||
| {project.data.description} | ||
| </Card> | ||
| </li> | ||
| )) | ||
| } | ||
| </ul> | ||
| </div> | ||
| </div> | ||
|
|
||
| <!-- Pagination --> | ||
| { | ||
| page && Math.ceil(page.total / 6) > 1 && ( | ||
|
peterpadberg marked this conversation as resolved.
Outdated
|
||
| <div class="mt-12 grid place-content-center"> | ||
| <Pagination | ||
| firstPage={page.url.prev ? `/portfolio/tag/${currentTag}` : null} | ||
| previousPage={page.url.prev ? page.url.prev : null} | ||
| nextPage={page.url.next ? page.url.next : null} | ||
| lastPage={page.url.next ? `/portfolio/tag/${currentTag}/${Math.ceil(page.total / 6)}` : null} | ||
|
peterpadberg marked this conversation as resolved.
Outdated
|
||
| currentPage={`${page.currentPage}`} | ||
| totalPages={`${Math.ceil(page.total / 6)}`} | ||
|
peterpadberg marked this conversation as resolved.
Outdated
|
||
| ariaLabel={`${currentTag} portfolio pagination`} | ||
| /> | ||
| </div> | ||
| ) | ||
| } | ||
| </div> | ||
| </section> | ||
| </DefaultLayout> | ||
Uh oh!
There was an error while loading. Please reload this page.