Skip to content

Commit

Permalink
feat(ui): create projects page
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusfg7 committed Jul 19, 2023
1 parent eede1a2 commit 41252ff
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/app/(main)/projects/components/project-card-effect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { ReactNode } from 'react'
import Tilt from 'react-parallax-tilt'

export function ProjectCardEffect({
children,
className
}: {
children: ReactNode
className?: string
}) {
return (
<Tilt
className={className}
tiltMaxAngleY={5}
glarePosition="all"
glareBorderRadius="1.5rem"
glareMaxOpacity={0.05}
glareEnable
glareReverse
gyroscope
tiltReverse
tiltAxis="y"
>
{children}
</Tilt>
)
}
106 changes: 106 additions & 0 deletions src/app/(main)/projects/components/project-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import Image from 'next/image'
import { Project } from 'contentlayer/generated'
import { FiFolder, FiGithub, FiGlobe } from 'react-icons/fi'
import { BsDot } from 'react-icons/bs'
import { techIcons } from './tech-icons'
import { ProjectCardEffect } from './project-card-effect'

interface Props {
data: Project
}

export function ProjectCard({ data }: Props) {
const Title = () => (
<div className="mb-10 flex flex-col items-center gap-5 text-2xl dark:text-neutral-50 md:mb-4 md:flex-row">
<h2 className="font-bold">{data.title}</h2>
<span className="hidden md:inline">
<BsDot />
</span>
<span className="flex items-center gap-3">
{data.core_techs.map(coreTech => {
const TechIcon = techIcons[coreTech]
return (
<span key={coreTech} className="text-xl hover:cursor-pointer">
<TechIcon />
</span>
)
})}
</span>
</div>
)
const Tags = () => (
<div className="mt-4 hidden flex-wrap items-center gap-2 md:flex">
{data.tags.map(tag => (
<span
key={tag}
className="rounded-xl bg-neutral-700/10 py-1 px-2 text-sm text-neutral-700 dark:bg-neutral-200/10 dark:text-neutral-200"
>
{tag}
</span>
))}
</div>
)

return (
<ProjectCardEffect className="overflow-hidden rounded-3xl shadow-2xl shadow-black/30">
<div className="flex h-full flex-col bg-neutral-100 dark:bg-neutral-900">
{data.image && (
<div className="h-56 w-full">
<Image
src={data.image}
width={2700}
height={2025}
alt="Project image"
className="h-full w-full object-cover object-top"
/>
</div>
)}
<div className="flex flex-1 flex-col p-5">
<div>
<Title />
<p className="text-justify md:text-left">{data.description}</p>
<Tags />
</div>
<div className="mt-9 flex flex-1 items-end justify-center gap-6">
{data.repository && (
<>
<a
href={data.repository}
target="_blank"
rel="noreferrer"
className="flex items-center gap-2 rounded-2xl border border-[#181717] p-4 text-[#181717] hover:bg-[#181717] hover:text-[#F6F8FA] dark:border-[#F6F8FA] dark:text-[#F6F8FA] dark:hover:bg-[#F6F8FA] hover:dark:text-[#181717]"
>
Repositório <FiGithub />
</a>
</>
)}
{data.files && (
<>
<a
href={data.files}
target="_blank"
rel="noreferrer"
className="flex items-center gap-2 rounded-2xl border border-blue-500 p-4 text-blue-500 hover:bg-blue-500 hover:text-neutral-50"
>
Arquivos <FiFolder />
</a>
</>
)}
{data.website && (
<>
<a
href={data.website}
target="_blank"
rel="noreferrer"
className="flex items-center gap-2 rounded-2xl border border-blue-700 bg-blue-700/10 p-4 text-blue-700 hover:bg-blue-700 hover:text-neutral-50 dark:border-blue-600 dark:bg-blue-600/5 dark:text-blue-600 dark:hover:bg-blue-600 dark:hover:text-neutral-50"
>
Website <FiGlobe />
</a>
</>
)}
</div>
</div>
</div>
</ProjectCardEffect>
)
}
38 changes: 38 additions & 0 deletions src/app/(main)/projects/components/tech-icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
SiTypescript,
SiReact,
SiExpo,
SiNextdotjs,
SiTailwindcss,
SiVite,
SiNodedotjs,
SiPrisma,
SiVuedotjs,
SiMdx,
SiJavascript
} from 'react-icons/si'

export const techIcons = {
javascript: () => (
<SiJavascript className="hover:text-[#F7DF1E]" title="Javascript" />
),
typescript: () => (
<SiTypescript className="hover:text-[#358EF1]" title="Typescript" />
),
'react-native': () => (
<SiReact className="hover:text-[#61DBFB]" title="React Native" />
),
expo: () => <SiExpo title="Expo" />,
reactjs: () => <SiReact className="hover:text-[#61DBFB]" title="React.js" />,
nextjs: () => <SiNextdotjs title="Next.js" />,
tailwindcss: () => (
<SiTailwindcss className="hover:text-[#38BDF8]" title="Tailwind CSS" />
),
vite: () => <SiVite className="hover:text-[#FFC119]" title="Vite" />,
nodejs: () => (
<SiNodedotjs className="hover:text-[#66CC33]" title="Node.js" />
),
prisma: () => <SiPrisma className="hover:text-[#4C51BF]" title="Prisma" />,
vue: () => <SiVuedotjs className="hover:text-[#4FC08D]" title="Vue.js" />,
mdx: () => <SiMdx className="hover:text-[#1B1F24]" title="MDX" />
}
14 changes: 14 additions & 0 deletions src/app/(main)/projects/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Projects',
description: 'My personal projects and apps'
}

export default function AboutLayout({
children
}: {
children: React.ReactNode
}) {
return <div className="content-vertical-spaces">{children}</div>
}
36 changes: 36 additions & 0 deletions src/app/(main)/projects/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { allProjects } from 'contentlayer/generated'
import { ProjectCard } from './components/project-card'

export default function Page() {
const featuredProjects = allProjects
.filter(project => project.featured)
.sort((a, b) => Number(a.priority) - Number(b.priority))
const otherProjectsWithImage = allProjects
.filter(project => !project.featured && project.image)
.sort((a, b) => Number(a.priority) - Number(b.priority))
const otherProjectsWithoutImage = allProjects
.filter(project => !project.featured && !project.image)
.sort((a, b) => Number(a.priority) - Number(b.priority))

return (
<div className="blog-content-w m-auto">
<h1 className="mb-8 bg-gradient-to-br from-blue-700 to-blue-400 bg-clip-text text-center text-4xl font-bold text-transparent md:w-fit md:text-left">
Projects
</h1>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
{featuredProjects.length > 0 &&
featuredProjects.map(project => (
<ProjectCard data={project} key={project._id} />
))}
{otherProjectsWithImage.length > 0 &&
otherProjectsWithImage.map(project => (
<ProjectCard data={project} key={project._id} />
))}
{otherProjectsWithoutImage.length > 0 &&
otherProjectsWithoutImage.map(project => (
<ProjectCard data={project} key={project._id} />
))}
</div>
</div>
)
}

0 comments on commit 41252ff

Please sign in to comment.