Skip to content
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

landing page updates #121

Merged
merged 3 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions app/components/layout/marketing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createContainerComponent } from './utils'

const MarketingMainLayout = createContainerComponent({
defaultTagName: 'main',
defaultClassName: 'font-poppins grid h-full place-items-center',
displayName: 'MarketingMainLayout',
})

const MarketingContentSection = createContainerComponent({
defaultTagName: 'div',
defaultClassName:
'grid place-items-center px-4 py-16 xl:grid-cols-2 xl:gap-4',
displayName: 'MarketingContentSection',
})

const MarketingDetailsSection = createContainerComponent({
defaultTagName: 'div',
defaultClassName:
'mb-4 flex max-w-lg flex-col items-center text-left xl:order-2 xl:mt-16 xl:items-start xl:self-start',
displayName: 'MarketingDetailsSection',
})

const MarketingLogoLink = createContainerComponent({
defaultTagName: 'a',
defaultClassName:
'animate-slide-top [animation-fill-mode:backwards] xl:animate-slide-left xl:[animation-delay:0.5s] xl:[animation-fill-mode:backwards]',
displayName: 'MarketingLogoLink',
})

const MarketingHeader = createContainerComponent({
defaultTagName: 'h1',
defaultClassName:
'mt-8 animate-slide-top text-4xl font-medium text-foreground [animation-delay:0.3s] [animation-fill-mode:backwards] md:text-5xl xl:mt-4 xl:animate-slide-left xl:text-6xl xl:[animation-delay:0.8s] xl:[animation-fill-mode:backwards]',
displayName: 'MarketingHeader',
})

const MarketingContent = createContainerComponent({
defaultTagName: 'p',
defaultClassName:
'mt-6 animate-slide-top text-xl/7 text-muted-foreground [animation-delay:0.8s] [animation-fill-mode:backwards] xl:mt-8 xl:animate-slide-left xl:text-xl/6 xl:leading-10 xl:[animation-delay:1s] xl:[animation-fill-mode:backwards]',
displayName: 'MarketingContent',
})

const MarketingSocialLinksList = createContainerComponent({
defaultTagName: 'ul',
defaultClassName:
'mt-6 flex animate-slide-top space-x-6 [animation-delay:1.2s] [animation-fill-mode:backwards] xl:mt-8 xl:animate-slide-left xl:[animation-delay:1.2s] xl:[animation-fill-mode:backwards]',
displayName: 'MarketingSocialLinksList',
})

const MarketingImagesGrid = createContainerComponent({
defaultTagName: 'div',
defaultClassName:
'mt-16 flex max-w-3xl flex-wrap gap-8 xl:mt-0 xl:grid xl:grid-flow-col xl:grid-cols-2 xl:grid-rows-2',
displayName: 'MarketingImagesGrid',
})

const MarketingImageContainer = createContainerComponent({
defaultTagName: 'div',
defaultClassName: 'relative',
displayName: 'MarketingImageContainer',
})

const MarketingImage = createContainerComponent({
defaultTagName: 'img',
defaultClassName: 'relative left-0 top-0 h-full w-full object-cover',
displayName: 'MarketingImage',
})

export {
MarketingMainLayout,
MarketingContentSection,
MarketingDetailsSection,
MarketingLogoLink,
MarketingHeader,
MarketingContent,
MarketingSocialLinksList,
MarketingImagesGrid,
MarketingImageContainer,
MarketingImage,
}
23 changes: 22 additions & 1 deletion app/models/user/user.get.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from 'zod'
import { prisma } from '#app/utils/db.server'
import { type IUserBasic } from './user.server'
import { type IUser, type IUserBasic } from './user.server'

export type queryWhereArgsType = z.infer<typeof queryWhereArgs>
const queryWhereArgs = z.object({
Expand Down Expand Up @@ -33,3 +33,24 @@ export const getUserBasic = async ({
image,
}
}

export const getFirstUser = async (): Promise<Pick<
IUser,
| 'name'
| 'username'
| 'bio'
| 'sm_url_instagram'
| 'sm_url_github'
| 'createdAt'
> | null> => {
return await prisma.user.findFirst({
select: {
name: true,
username: true,
bio: true,
sm_url_instagram: true,
sm_url_github: true,
createdAt: true,
},
})
}
95 changes: 42 additions & 53 deletions app/routes/_marketing+/components/content.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {
MarketingContent,
MarketingHeader,
MarketingLogoLink,
MarketingSocialLinksList,
} from '#app/components/layout/marketing'
import { Icon } from '#app/components/ui/icon'

export const ContentLogo = () => {
return (
<a
href="https://github.com/goodeats/epic-pppaaattt.xyz"
className="animate-slide-top [animation-fill-mode:backwards] xl:animate-slide-left xl:[animation-delay:0.5s] xl:[animation-fill-mode:backwards]"
>
<MarketingLogoLink href="https://github.com/goodeats/epic-pppaaattt.xyz">
<svg
className="size-20 text-foreground xl:-mt-4"
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -19,66 +22,52 @@ export const ContentLogo = () => {
points="52.5,64.33 40.5,44.66 64.5,44.66"
/>
</svg>
</a>
</MarketingLogoLink>
)
}

export const ContentHeader = () => {
return (
<h1
data-heading
className="mt-8 animate-slide-top text-4xl font-medium text-foreground [animation-fill-mode:backwards] [animation-delay:0.3s] md:text-5xl xl:mt-4 xl:animate-slide-left xl:text-6xl xl:[animation-fill-mode:backwards] xl:[animation-delay:0.8s]"
>
<MarketingHeader data-heading>
<a href="https://github.com/goodeats/epic-pppaaattt.xyz">PPPAAATTT</a>
</h1>
</MarketingHeader>
)
}

export const ContentBody = () => {
return (
<div>
<p
data-paragraph
className="mt-6 animate-slide-top text-xl/7 text-muted-foreground [animation-fill-mode:backwards] [animation-delay:0.8s] xl:mt-8 xl:animate-slide-left xl:text-xl/6 xl:leading-10 xl:[animation-fill-mode:backwards] xl:[animation-delay:1s]"
>
Welcome to my digital gallery. My name is Pat and I am a software
engineer turned generative artist from Maine, now living in New York
City.
</p>
<p
data-paragraph
className="mt-6 animate-slide-top text-xl/7 text-muted-foreground [animation-fill-mode:backwards] [animation-delay:0.8s] xl:mt-8 xl:animate-slide-left xl:text-xl/6 xl:leading-10 xl:[animation-fill-mode:backwards] xl:[animation-delay:1s]"
>
My art consists of bridging the gap between the precision of programming
and the boundless world of art. It is a celebration of simplicity and
complexity, where equilateral triangles become the building blocks for a
series of algorithms that produce mesmerizing visual displays.
</p>
</div>
)
export const ContentBody = ({ bio }: { bio: string }) => {
const bioParagraphs = bio.split('\n').map((paragraph, index) => (
<MarketingContent key={index} data-paragraph>
{paragraph}
</MarketingContent>
))
return <div>{bioParagraphs.map(paragraph => paragraph)}</div>
}

export const ContentContact = () => {
// quick and dirty solution to add social links from strings
// will add OAuth2 later
export const ContentContact = ({
ig,
gh,
}: {
ig: string | null
gh: string | null
}) => {
return (
<ul className="mt-6 flex animate-slide-top space-x-6 [animation-fill-mode:backwards] [animation-delay:1.2s] xl:mt-8 xl:animate-slide-left xl:[animation-fill-mode:backwards] xl:[animation-delay:1.2s]">
<li>
<a
href="https://www.instagram.com/pppaaattt.xyz"
target="_blank"
rel="noopener noreferrer"
>
<Icon name="instagram-logo" size="xl" />
</a>
</li>
<li>
<a
href="https://github.com/goodeats"
target="_blank"
rel="noopener noreferrer"
>
<Icon name="github-logo" size="xl" />
</a>
</li>
</ul>
<MarketingSocialLinksList>
{ig && (
<li>
<a href={ig} target="_blank" rel="noopener noreferrer">
<Icon name="instagram-logo" size="xl" />
</a>
</li>
)}
{gh && (
<li>
<a href={gh} target="_blank" rel="noopener noreferrer">
<Icon name="github-logo" size="xl" />
</a>
</li>
)}
</MarketingSocialLinksList>
)
}
29 changes: 13 additions & 16 deletions app/routes/_marketing+/components/images-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
MarketingImage,
MarketingImageContainer,
MarketingImagesGrid,
} from '#app/components/layout/marketing'
import { cn } from '#app/utils/misc.tsx'
import { images } from '../images/images'

Expand All @@ -20,25 +25,17 @@ const rowClasses: Record<(typeof images)[number]['row'], string> = {

export const ImagesGrid = () => {
return (
<div className="mt-16 flex max-w-3xl flex-wrap gap-8 xl:mt-0 xl:grid xl:grid-flow-col xl:grid-cols-2 xl:grid-rows-2">
{images.map((image, index) => {
<MarketingImagesGrid>
{images.map(image => {
return (
<div
key={index}
className={cn(
columnClasses[image.column],
rowClasses[image.row],
'relative',
)}
<MarketingImageContainer
key={image.src}
className={cn(columnClasses[image.column], rowClasses[image.row])}
>
<img
src={image.src}
alt={image.alt}
className="relative left-0 top-0 h-full w-full object-cover"
/>
</div>
<MarketingImage src={image.src} alt={image.alt} />
</MarketingImageContainer>
)
})}
</div>
</MarketingImagesGrid>
)
}
59 changes: 42 additions & 17 deletions app/routes/_marketing+/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { type MetaFunction } from '@remix-run/node'
import { invariantResponse } from '@epic-web/invariant'
import {
type LoaderFunctionArgs,
json,
type MetaFunction,
} from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import {
MarketingContentSection,
MarketingDetailsSection,
MarketingMainLayout,
} from '#app/components/layout/marketing.tsx'
import { getFirstUser } from '#app/models/user/user.get.server.ts'
import {
ContentBody,
ContentContact,
Expand All @@ -7,6 +19,35 @@ import {
} from './components/content.tsx'
import { ImagesGrid } from './components/images-grid.tsx'

export async function loader({ params, request }: LoaderFunctionArgs) {
const user = await getFirstUser()
invariantResponse(user, 'Nothing to show today', { status: 404 })

return json({
user,
})
}

export default function Index() {
const data = useLoaderData<typeof loader>()
const { user } = data
console.log(user)

return (
<MarketingMainLayout>
<MarketingContentSection>
<MarketingDetailsSection>
<ContentLogo />
<ContentHeader />
<ContentBody bio={user.bio} />
<ContentContact ig={user.sm_url_instagram} gh={user.sm_url_github} />
</MarketingDetailsSection>
<ImagesGrid />
</MarketingContentSection>
</MarketingMainLayout>
)
}

export const meta: MetaFunction = () => {
const title = 'PPPAAATTT'
const titleElements = [
Expand Down Expand Up @@ -58,19 +99,3 @@ export const meta: MetaFunction = () => {
},
]
}

export default function Index() {
return (
<main className="font-poppins grid h-full place-items-center">
<div className="grid place-items-center px-4 py-16 xl:grid-cols-2 xl:gap-4">
<div className="mb-4 flex max-w-lg flex-col items-center text-left xl:order-2 xl:mt-16 xl:items-start xl:self-start">
<ContentLogo />
<ContentHeader />
<ContentBody />
<ContentContact />
</div>
<ImagesGrid />
</div>
</main>
)
}
Loading
Loading