I Love Web

Sprint 15: week 2

Oct 21 2024

Dit is mijn learning journal van week 2 van sprint 15

21.10

I love web

json

I Love Web-site geupdate: ik ben begonnen aan een soort portfolio pagina. Ik doe dit met .json files.

Dit is het schema wat ik in /content/config.ts heb gemaakt:

const portfolioCollection = defineCollection({
  type: 'data',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    text: z.string(),
    live: z.string().url().optional(), // Optional live URL
    repo: z.string().url().optional(), // Optional repo URL
    image: z.object({
      url: z.string(),
      alt: z.string()
    }),
    tags: z.array(z.string()).optional(), // Optional tags array
    completed: z.boolean(), // Boolean to show project completion status,
    slug: z.string()  // Ensure slug is required
  })
});

Het grootste verschil met de anderen, waar ik markdown gebruik, is dat er hiet type: 'data aan toegevoegd moet worden, zodat het bekend is dat het om json gaat en niet om markdown.

component

Ik gebruik een component om het kaartje te maken:

---
import { Picture } from 'astro:assets';

const { title, description, url, image, tags } = Astro.props;
---
<li>
  <a href={url} class="element">
    <h3>{title}</h3>

    <Picture src={image.url} formats={['avif', 'webp']} alt="" height="167" width="200"/>

    <p class="description">{description}</p>
    <!-- Loop through the tags and display each one -->
    <ul class="tags">
      {tags.map((tag) => <li class="tag">{tag}</li>)}
    </ul>
    <p class="view">View</p>
  </a>
</li>

Ik heb hier ook een scroll animatie aan toegevoegd:

@media (prefers-reduced-motion: no-preference) {
    li {
      animation: linear animate-in-and-out;
      animation-timeline: view();
    }
    @keyframes animate-in-and-out {
      entry 0% {
        opacity: 0;
        transform: translateY(50%);
      }
      entry 100% {
        opacity: 1;
        transform: translateY(0);
      }

      exit 0% {
        opacity: 1;
        transform: translateY(0);
      }
      exit 110% {
        opacity: 0;
        transform: translateY(-50%);
      }
    }
  }

Ik heb in de CSS ook voor de tags een stukje zodat niet alle tags dezelfde kleur hebben:

  .tag:nth-of-type(2n + 1) {
    background-color: var(--accent-one);
  }

  .tag:nth-of-type(2n + 2) {
    background-color: var(--accent-two);
  }

Dit is hoe het component op de betreffende pagina word gebruikt:

---
import "../styles/global.css";
import Layout from "../layouts/Layout.astro";
import WorkLink from "../components/WorkLink.astro";

import { getCollection } from "astro:content";
const PortfolioCollection = await getCollection("portfolio");

const pageTitle = "Gallery";
---
 <ul>
    {PortfolioCollection.map((portfolio) => (
        <WorkLink
          url={`/portfolio/${portfolio.data.slug}`}
          title={portfolio.data.title}
          image={portfolio.data.image}
          description={portfolio.data.description}
          tags={portfolio.data.tags}
        />))}
  </ul>