diff options
Diffstat (limited to 'examples/portfolio/src/pages')
-rw-r--r-- | examples/portfolio/src/pages/404.astro | 8 | ||||
-rw-r--r-- | examples/portfolio/src/pages/about.astro | 120 | ||||
-rw-r--r-- | examples/portfolio/src/pages/index.astro | 252 | ||||
-rw-r--r-- | examples/portfolio/src/pages/work.astro | 39 | ||||
-rw-r--r-- | examples/portfolio/src/pages/work/[...slug].astro | 152 |
5 files changed, 571 insertions, 0 deletions
diff --git a/examples/portfolio/src/pages/404.astro b/examples/portfolio/src/pages/404.astro new file mode 100644 index 000000000..e3995899a --- /dev/null +++ b/examples/portfolio/src/pages/404.astro @@ -0,0 +1,8 @@ +--- +import Hero from '../components/Hero.astro'; +import BaseLayout from '../layouts/BaseLayout.astro'; +--- + +<BaseLayout title="Not Found" description="404 Error — this page was not found"> + <Hero title="Page Not Found" tagline="Not found" /> +</BaseLayout> diff --git a/examples/portfolio/src/pages/about.astro b/examples/portfolio/src/pages/about.astro new file mode 100644 index 000000000..14e34ba81 --- /dev/null +++ b/examples/portfolio/src/pages/about.astro @@ -0,0 +1,120 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; + +import ContactCTA from '../components/ContactCTA.astro'; +import Hero from '../components/Hero.astro'; +--- + +<BaseLayout title="About | Jeanine White" description="About Jeanine White Lorem Ipsum"> + <div class="stack gap-20"> + <main class="wrapper about"> + <Hero + title="About" + tagline="Thanks for stopping by. Read below to learn more about myself and my background." + > + <img + width="1553" + height="873" + src="/assets/at-work.jpg" + alt="Jeanine White at work with a colleague" + /> + </Hero> + + <section> + <h2 class="section-title">Background</h2> + <div class="content"> + <p> + Lorem ipsum dolor sit amet, <a href="https://astro.build/">Astro</a> makes people happy. + Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin nibh nisl condimentum + id venenatis a condimentum vitae. Dapibus ultrices in iaculis nunc. Arcu odio ut sem nulla + pharetra diam sit amet. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare. + </p> + <p> + Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Eget gravida cum sociis + natoque penatibus. Cras fermentum odio eu feugiat pretium nibh. Proin nibh nisl + condimentum id venenatis. Porta nibh venenatis cras sed felis eget velit. Id diam vel + quam elementum pulvinar etiam non. + </p> + <p> + Ultrices tincidunt arcu non sodales neque sodales ut. Sed enim ut sem viverra aliquet + eget sit amet. Lacus luctus accumsan tortor posuere ac ut consequat semper viverra. + Viverra accumsan in nisl nisi scelerisque eu ultrices. In massa tempor nec feugiat nisl + pretium fusce. + </p> + </div> + </section> + <section> + <h2 class="section-title">Education</h2> + <div class="content"> + <p>Corporis voluptates tenetur laudantium.</p> + </div> + </section> + <section> + <h2 class="section-title">Skills</h2> + <div class="content"> + <p>officia unde omnis</p> + </div> + </section> + </main> + + <ContactCTA /> + </div> +</BaseLayout> + +<style> + .about { + display: flex; + flex-direction: column; + gap: 3.5rem; + } + + img { + margin-top: 1.5rem; + border-radius: 1.5rem; + box-shadow: var(--shadow-md); + } + + section { + display: flex; + flex-direction: column; + gap: 0.5rem; + color: var(--gray-200); + } + + .section-title { + grid-column-start: 1; + font-size: var(--text-xl); + color: var(--gray-0); + } + + .content { + grid-column: 2 / 4; + } + + .content :global(a) { + text-decoration: 1px solid underline transparent; + text-underline-offset: 0.25em; + transition: text-decoration-color var(--theme-transition); + } + + .content :global(a:hover), + .content :global(a:focus) { + text-decoration-color: currentColor; + } + + @media (min-width: 50em) { + .about { + display: grid; + grid-template-columns: 1fr 60% 1fr; + } + + .about > :global(:first-child) { + grid-column-start: 2; + } + + section { + display: contents; + font-size: var(--text-lg); + } + } +</style> diff --git a/examples/portfolio/src/pages/index.astro b/examples/portfolio/src/pages/index.astro new file mode 100644 index 000000000..5f67e3860 --- /dev/null +++ b/examples/portfolio/src/pages/index.astro @@ -0,0 +1,252 @@ +--- +import { getCollection } from 'astro:content'; + +// Layout import — provides basic page elements: <head>, <nav>, <footer> etc. +import BaseLayout from '../layouts/BaseLayout.astro'; + +// Component Imports +import CallToAction from '../components/CallToAction.astro'; +import Grid from '../components/Grid.astro'; +import Hero from '../components/Hero.astro'; +import Icon from '../components/Icon.astro'; +import Pill from '../components/Pill.astro'; +import PortfolioPreview from '../components/PortfolioPreview.astro'; + +// Page section components +import ContactCTA from '../components/ContactCTA.astro'; +import Skills from '../components/Skills.astro'; + +// Content Fetching: List four most recent work projects +const projects = (await getCollection('work')) + .sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()) + .slice(0, 4); + +// Full Astro Component Syntax: +// https://docs.astro.build/basics/astro-components/ +--- + +<BaseLayout> + <div class="stack gap-20 lg:gap-48"> + <div class="wrapper stack gap-8 lg:gap-20"> + <header class="hero"> + <Hero + title="Hello, my name is Jeanine White" + tagline="I am a Creative Developer who is currently based in Portland, Oregon." + align="start" + > + <div class="roles"> + <Pill><Icon icon="code" size="1.33em" /> Developer</Pill> + <Pill><Icon icon="microphone-stage" size="1.33em" /> Speaker</Pill> + <Pill><Icon icon="pencil-line" size="1.33em" /> Writer</Pill> + </div> + </Hero> + + <img + alt="Jeanine White smiling in a red plaid shirt and tortoise shell glasses" + width="480" + height="620" + src="/assets/portrait.jpg" + /> + </header> + + <Skills /> + </div> + + <main class="wrapper stack gap-20 lg:gap-48"> + <section class="section with-background with-cta"> + <header class="section-header stack gap-2 lg:gap-4"> + <h3>Selected Work</h3> + <p>Take a look below at some of my featured work for clients from the past few years.</p> + </header> + + <div class="gallery"> + <Grid variant="offset"> + { + projects.map((project) => ( + <li> + <PortfolioPreview project={project} /> + </li> + )) + } + </Grid> + </div> + + <div class="cta"> + <CallToAction href="/work/"> + View All + <Icon icon="arrow-right" size="1.2em" /> + </CallToAction> + </div> + </section> + + <section class="section with-background bg-variant"> + <header class="section-header stack gap-2 lg:gap-4"> + <h3>Mentions</h3> + <p> + I have been fortunate enough to receive praise for my work in several publications. Take + a look below to learn more. + </p> + </header> + + <div class="gallery"> + <Grid variant="small"> + { + ['Medium', 'BuzzFeed', 'The Next Web', 'awwwards.', 'TechCrunch'].map((brand) => ( + <li class="mention-card"> + <p>{brand}</p> + </li> + )) + } + </Grid> + </div> + </section> + </main> + + <ContactCTA /> + </div> +</BaseLayout> + +<style> + .hero { + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; + } + + .roles { + display: none; + } + + .hero img { + aspect-ratio: 5 / 4; + object-fit: cover; + object-position: top; + border-radius: 1.5rem; + box-shadow: var(--shadow-md); + } + + @media (min-width: 50em) { + .hero { + display: grid; + grid-template-columns: 6fr 4fr; + padding-inline: 2.5rem; + gap: 3.75rem; + } + + .roles { + margin-top: 0.5rem; + display: flex; + gap: 0.5rem; + } + + .hero img { + aspect-ratio: 3 / 4; + border-radius: 4.5rem; + object-fit: cover; + } + } + + /* ====================================================== */ + + .section { + display: grid; + gap: 2rem; + } + + .with-background { + position: relative; + } + + .with-background::before { + --hero-bg: var(--bg-image-subtle-2); + + content: ''; + position: absolute; + pointer-events: none; + left: 50%; + width: 100vw; + aspect-ratio: calc(2.25 / var(--bg-scale)); + top: 0; + transform: translateY(-75%) translateX(-50%); + background: + url('/assets/backgrounds/noise.png') top center/220px repeat, + var(--hero-bg) center center / var(--bg-gradient-size) no-repeat, + var(--gray-999); + background-blend-mode: overlay, normal, normal, normal; + mix-blend-mode: var(--bg-blend-mode); + z-index: -1; + } + + .with-background.bg-variant::before { + --hero-bg: var(--bg-image-subtle-1); + } + + .section-header { + justify-self: center; + text-align: center; + max-width: 50ch; + font-size: var(--text-md); + color: var(--gray-300); + } + + .section-header h3 { + font-size: var(--text-2xl); + } + + @media (min-width: 50em) { + .section { + grid-template-columns: repeat(4, 1fr); + grid-template-areas: 'header header header header' 'gallery gallery gallery gallery'; + gap: 5rem; + } + + .section.with-cta { + grid-template-areas: 'header header header cta' 'gallery gallery gallery gallery'; + } + + .section-header { + grid-area: header; + font-size: var(--text-lg); + } + + .section-header h3 { + font-size: var(--text-4xl); + } + + .with-cta .section-header { + justify-self: flex-start; + text-align: left; + } + + .gallery { + grid-area: gallery; + } + + .cta { + grid-area: cta; + } + } + + /* ====================================================== */ + + .mention-card { + display: flex; + height: 7rem; + justify-content: center; + align-items: center; + text-align: center; + border: 1px solid var(--gray-800); + border-radius: 1.5rem; + color: var(--gray-300); + background: var(--gradient-subtle); + box-shadow: var(--shadow-sm); + } + + @media (min-width: 50em) { + .mention-card { + border-radius: 1.5rem; + height: 9.5rem; + } + } +</style> diff --git a/examples/portfolio/src/pages/work.astro b/examples/portfolio/src/pages/work.astro new file mode 100644 index 000000000..233c760bf --- /dev/null +++ b/examples/portfolio/src/pages/work.astro @@ -0,0 +1,39 @@ +--- +import { getCollection } from 'astro:content'; + +import BaseLayout from '../layouts/BaseLayout.astro'; + +import ContactCTA from '../components/ContactCTA.astro'; +import PortfolioPreview from '../components/PortfolioPreview.astro'; +import Hero from '../components/Hero.astro'; +import Grid from '../components/Grid.astro'; + +const projects = (await getCollection('work')).sort( + (a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf(), +); +--- + +<BaseLayout + title="My Work | Jeanine White" + description="Learn about Jeanine White's most recent projects" +> + <div class="stack gap-20"> + <main class="wrapper stack gap-8"> + <Hero + title="My Work" + tagline="See my most recent projects below to get an idea of my past experience." + align="start" + /> + <Grid variant="offset"> + { + projects.map((project) => ( + <li> + <PortfolioPreview project={project} /> + </li> + )) + } + </Grid> + </main> + <ContactCTA /> + </div> +</BaseLayout> diff --git a/examples/portfolio/src/pages/work/[...slug].astro b/examples/portfolio/src/pages/work/[...slug].astro new file mode 100644 index 000000000..90eb3ba8d --- /dev/null +++ b/examples/portfolio/src/pages/work/[...slug].astro @@ -0,0 +1,152 @@ +--- +import { type CollectionEntry, getCollection } from 'astro:content'; + +import BaseLayout from '../../layouts/BaseLayout.astro'; + +import ContactCTA from '../../components/ContactCTA.astro'; +import Hero from '../../components/Hero.astro'; +import Icon from '../../components/Icon.astro'; +import Pill from '../../components/Pill.astro'; +import { render } from 'astro:content'; + +interface Props { + entry: CollectionEntry<'work'>; +} + +// This is a dynamic route that generates a page for every Markdown file in src/content/ +// Read more about dynamic routes and this `getStaticPaths` function in the Astro docs: +// https://docs.astro.build/en/core-concepts/routing/#dynamic-routes +export async function getStaticPaths() { + const work = await getCollection('work'); + return work.map((entry) => ({ + params: { slug: entry.id }, + props: { entry }, + })); +} + +const { entry } = Astro.props; +const { Content } = await render(entry); +--- + +<BaseLayout title={entry.data.title} description={entry.data.description}> + <div class="stack gap-20"> + <div class="stack gap-15"> + <header> + <div class="wrapper stack gap-2"> + <a class="back-link" href="/work/"><Icon icon="arrow-left" /> Work</a> + <Hero title={entry.data.title} align="start"> + <div class="details"> + <div class="tags"> + {entry.data.tags.map((t) => <Pill>{t}</Pill>)} + </div> + <p class="description">{entry.data.description}</p> + </div> + </Hero> + </div> + </header> + <main class="wrapper"> + <div class="stack gap-10 content"> + {entry.data.img && <img src={entry.data.img} alt={entry.data.img_alt || ''} />} + <div class="content"> + <Content /> + </div> + </div> + </main> + </div> + <ContactCTA /> + </div> +</BaseLayout> + +<style> + header { + padding-bottom: 2.5rem; + border-bottom: 1px solid var(--gray-800); + } + + .back-link { + display: none; + } + + .details { + display: flex; + flex-direction: column; + padding: 0.5rem; + gap: 1.5rem; + justify-content: space-between; + align-items: center; + } + + .tags { + display: flex; + gap: 0.5rem; + } + + .description { + font-size: var(--text-lg); + max-width: 54ch; + } + + .content { + max-width: 65ch; + margin-inline: auto; + } + + .content > :global(* + *) { + margin-top: 1rem; + } + + .content :global(h1), + .content :global(h2), + .content :global(h3), + .content :global(h4), + .content :global(h5) { + margin: 1.5rem 0; + } + + .content :global(img) { + border-radius: 1.5rem; + box-shadow: var(--shadow-sm); + background: var(--gradient-subtle); + border: 1px solid var(--gray-800); + } + + .content :global(blockquote) { + font-size: var(--text-lg); + font-family: var(--font-brand); + font-weight: 600; + line-height: 1.1; + padding-inline-start: 1.5rem; + border-inline-start: 0.25rem solid var(--accent-dark); + color: var(--gray-0); + } + + .back-link, + .content :global(a) { + text-decoration: 1px solid underline transparent; + text-underline-offset: 0.25em; + transition: text-decoration-color var(--theme-transition); + } + + .back-link:hover, + .back-link:focus, + .content :global(a:hover), + .content :global(a:focus) { + text-decoration-color: currentColor; + } + + @media (min-width: 50em) { + .back-link { + display: block; + align-self: flex-start; + } + + .details { + flex-direction: row; + gap: 2.5rem; + } + + .content :global(blockquote) { + font-size: var(--text-2xl); + } + } +</style> |