Skip to content

Commit

Permalink
Merge pull request #29 from firehawk89/add-project-page
Browse files Browse the repository at this point in the history
Add Project Page
  • Loading branch information
firehawk89 authored Feb 11, 2024
2 parents f989e8c + 5bf6229 commit 5a2302d
Show file tree
Hide file tree
Showing 38 changed files with 425 additions and 138 deletions.
4 changes: 2 additions & 2 deletions content/projects/itour.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'iTour'
image: '/iTour.jpg'
features: []
technologies: ['JavaScript', 'React', 'Next.js', 'TailwindCSS', 'i18n']
website: 'https://travel-agency-eight-murex.vercel.app/'
---

iTour project info goes here
7 changes: 5 additions & 2 deletions content/projects/skauna.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
---
title: 'Skauna'
image: '/Skauna.jpg'
technologies: ['HTML', 'CSS', 'JavaScript']
features: ['Cascade Slider', 'Animated Site Background']
technologies: ['HTML', 'CSS', 'SCSS', 'JavaScript', 'jQuery']
website: 'https://skauna.com/'
github: 'https://github.com/firehawk89/Skauna-website'
---

Skauna project info goes here
Responsive landing for Skauna.
16 changes: 16 additions & 0 deletions content/projects/yelpcamp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: 'YelpCamp'
image: '/YelpCamp.jpg'
features:
[
'User Authentication (Log In and Register) and Authorization (Post, Edit, Delete or Rate Campground)',
'Campground Star Rating',
'Cluster Map',
'Image Upload'
]
technologies: ['JavaScript', 'Node.js', 'Express', 'EJS', 'MongoDB', 'Bootstrap']
website: 'https://yelp-camp-1s3s.onrender.com/'
github: 'https://github.com/firehawk89/YelpCamp'
---

An upgraded version of Node.js web app project from the "The Web Developer Bootcamp" course on Udemy by Colt Steele.
4 changes: 3 additions & 1 deletion project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Nextdotjs
Tailwindcss
Skauna
hookform
sonner
sonner
Bootcamp
Udemy
Binary file modified public/Skauna.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/YelpCamp.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/iTour.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions src/app/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import ProjectPageChips from '@/components/project-page-chips'
import Card from '@/components/ui/card'
import Chips from '@/components/ui/chips/chips'
import ChipsItem from '@/components/ui/chips/chips-item'
import Content from '@/components/ui/content'
import Heading from '@/components/ui/heading'
import IconsList from '@/components/ui/icons-list/icons-list'
import IconsListItem from '@/components/ui/icons-list/icons-list-item'
import ImagePlaceholder from '@/components/ui/image-placeholder'
import { getProject, getSlugs } from '@/utils/projects'
import Image from 'next/image'
import { FaGithub } from 'react-icons/fa'
import { TfiWorld } from 'react-icons/tfi'

type ProjectPageProps = {
params: { slug: string }
}

export async function generateStaticParams() {
const slugs = await getSlugs()
return slugs.map((slug) => ({ slug }))
}

export default async function Project({ params: { slug } }: ProjectPageProps) {
const { body, features, github, image, technologies, title, website } =
await getProject(slug)

return (
<section className="pt-header">
<Content className="pb-16 pt-12 md:pb-24 md:pt-20" size="tight">
<article className="flex flex-col gap-5 md:gap-7">
<header>
{website || github ? (
<div className="flex items-center justify-between">
<Heading size="h1">{title}</Heading>
<IconsList>
{website && (
<IconsListItem
Icon={TfiWorld}
href={website}
title="Go to Website"
/>
)}
{github && (
<IconsListItem
Icon={FaGithub}
href={github}
title="Go to GitHub repository"
/>
)}
</IconsList>
</div>
) : (
<Heading size="h1">{title}</Heading>
)}
{body && (
<p
className="mt-7 md:text-lg"
dangerouslySetInnerHTML={{ __html: body }}
/>
)}
</header>
<Card className="relative aspect-video">
{image ? (
<Image alt={title || slug} fill sizes="100vw" src={image} />
) : (
<ImagePlaceholder />
)}
</Card>
{!!features.length && (
<div>
<Heading level={2} size="h3">
Features
</Heading>
<ul className="mt-3 list-inside list-disc marker:text-accent md:text-lg">
{features.map((feature) => (
<li key={feature}>{feature}</li>
))}
</ul>
</div>
)}
{!!technologies.length && (
<div>
<Heading level={2} size="h3">
Used Tools & Technologies
</Heading>
<ProjectPageChips className="mt-2 md:mt-3" data={technologies} />
</div>
)}
</article>
</Content>
</section>
)
}
7 changes: 5 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
@tailwind components;
@tailwind utilities;

html {
:root {
--header-height: 4.25rem;
@apply scroll-smooth;
}

html {
@apply scroll-p-header scroll-smooth;
}

body {
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import About from '@/components/sections/about'
import About from '@/components/sections/about/about'
import Contact from '@/components/sections/contact/contact'
import Hero from '@/components/sections/hero/hero'
import Projects from '@/components/sections/projects/projects'
Expand Down
2 changes: 1 addition & 1 deletion src/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Socials from '@/components/ui/socials/socials'
import Socials from '@/components/ui/socials'
import { cn } from '@/utils'
import { FC, HTMLAttributes } from 'react'

Expand Down
4 changes: 2 additions & 2 deletions src/components/header/header-navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Menu from '@/components/header/menu/menu'
import MenuItem from '@/components/header/menu/menu-item'
import Socials from '@/components/ui/socials/socials'
import Socials from '@/components/ui/socials'
import useMediaQuery from '@/hooks/use-media-query'
import HeaderContext from '@/store/header-context'
import { MOBILE_BREAKPOINT, cn } from '@/utils'
Expand All @@ -17,7 +17,7 @@ const HeaderNavbar: FC<HeaderNavbarProps> = ({ className, ...props }) => {
return (
<nav
className={cn(
'fixed left-0 right-0 top-0 z-20 -translate-y-full border-b border-accent bg-light py-8 transition-transform duration-500 dark:bg-dark md:static md:translate-y-0 md:border-none md:bg-transparent md:p-0 md:dark:bg-transparent',
'fixed left-0 right-0 top-0 -translate-y-full border-b border-accent bg-light pb-10 pt-20 transition-transform duration-500 dark:bg-dark md:static md:translate-y-0 md:border-none md:bg-transparent md:p-0 md:dark:bg-transparent',
isMenuOpened && 'translate-y-0',
className
)}
Expand Down
17 changes: 11 additions & 6 deletions src/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import HeaderNavbar from '@/components/header/header-navbar'
import Content from '@/components/ui/content'
import Logo from '@/components/ui/logo'
import ThemeToggler from '@/components/ui/theme-toggler'
import { cn } from '@/utils'
import { FC, HTMLAttributes } from 'react'
Expand All @@ -11,16 +13,19 @@ const Header: FC<HeaderProps> = ({ className, ...props }) => {
return (
<header
className={cn(
'fixed left-0 top-0 z-10 w-full bg-light bg-opacity-10 px-8 py-5 shadow-blur backdrop-blur-[8px] lg:px-10',
'fixed left-0 top-0 z-10 w-full bg-light bg-opacity-10 py-5 shadow-blur backdrop-blur-[8px]',
className
)}
{...props}
>
<HeaderNavbar />
<div className="relative z-30 flex items-center justify-between md:static">
<ThemeToggler className="-mx-5 -my-2 md:absolute md:right-5 md:top-1/2 md:m-0 md:-translate-y-1/2" />
<MenuIcon className="md:hidden" />
</div>
<Content className="relative" size="wide">
<Logo className="absolute left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2 md:left-8 md:translate-x-0 lg:left-10" />
<HeaderNavbar className="z-20" />
<div className="relative z-30 flex items-center justify-between md:static">
<ThemeToggler className="-mx-5 -my-2 md:absolute md:right-5 md:top-1/2 md:m-0 md:-translate-y-1/2" />
<MenuIcon className="md:hidden" />
</div>
</Content>
</header>
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/header/menu/menu-icon/menu-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import MenuIconBar from './menu-icon-bar'
interface MenuIconProps extends HTMLAttributes<HTMLDivElement> {}

const MenuIcon: FC<MenuIconProps> = ({ className, ...props }) => {
const { isMenuOpened, toggleMenu } = useContext(HeaderContext)
const { closeMenu, isMenuOpened, openMenu } = useContext(HeaderContext)

return (
<div
className={cn('relative h-5 w-7 cursor-pointer md:static', className)}
onClick={toggleMenu}
onClick={isMenuOpened ? closeMenu : openMenu}
{...props}
>
<MenuIconBar
Expand Down
8 changes: 6 additions & 2 deletions src/components/header/menu/menu-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ const MenuItem: FC<MenuItemProps> = ({
href,
...props
}) => {
const { toggleMenu } = useContext(HeaderContext)
const { closeMenu, isMenuOpened, openMenu } = useContext(HeaderContext)

return (
<li className={className} onClick={toggleMenu} {...props}>
<li
className={className}
onClick={isMenuOpened ? closeMenu : openMenu}
{...props}
>
<Link
className="text-lg font-medium transition-colors md:hover:text-accent"
href={href}
Expand Down
25 changes: 25 additions & 0 deletions src/components/project-page-chips.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client'

import Chips, { ChipsProps } from '@/components/ui/chips/chips'
import ChipsItem from '@/components/ui/chips/chips-item'
import useMediaQuery from '@/hooks/use-media-query'
import { MOBILE_BREAKPOINT } from '@/utils'
import { FC } from 'react'

interface ProjectPageChipsProps extends ChipsProps {
data: string[]
}

const ProjectPageChips: FC<ProjectPageChipsProps> = ({ className, data }) => {
const isMobile = useMediaQuery(MOBILE_BREAKPOINT)

return (
<Chips className={className}>
{data.map((item) => (
<ChipsItem key={item} label={item} size={isMobile ? 'sm' : 'default'} />
))}
</Chips>
)
}

export default ProjectPageChips
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import TechnologyIcons from '@/components/sections/about/technology-icons'
import { buttonVariants } from '@/components/ui/button'
import Content from '@/components/ui/content'
import Heading from '@/components/ui/heading'
import Technologies from '@/components/ui/technologies/technologies'
import { cn } from '@/utils'
import Link from 'next/link'
import { FC, HTMLAttributes } from 'react'

const CV_FILENAME = 'Anton_Bochkovskyi_Front-End_Developer_CV'
const CV_FILE_EXTENSION = '.pdf'

interface AboutProps extends HTMLAttributes<HTMLDivElement> {}

const About: FC<AboutProps> = ({ className, ...props }) => {
return (
<section className={cn('bg-light dark:bg-black', className)} {...props}>
<Content className="flex gap-6 md:gap-10">
<article>
<Heading size="h2" variant="underline">
<Heading level={2} size="h2" variant="underline">
About Me
</Heading>
<div className="mt-6 space-y-4 font-medium md:text-xl">
<div className="mt-6 space-y-4 font-medium md:text-lg">
<p>
I&apos;m a <strong>Front-End Developer</strong> specializing in
React, Next.js, and Tailwind CSS, with a keen focus on crafting{' '}
<b>responsive</b> and visually <b>stunning</b> web applications.
</p>
<p>
I enjoy working closely with cross-functional teams, including
designers and back-end developers, to{' '}
<strong>transform ideas into reality</strong>. Clear
I enjoy working in team and{' '}
<strong>transforming ideas into reality</strong>. Clear
communication, attention to detail, and a commitment to delivering{' '}
<b>high-quality</b> code are values I uphold in my works.
</p>
Expand All @@ -40,15 +42,15 @@ const About: FC<AboutProps> = ({ className, ...props }) => {
</div>
<Link
className={cn('mt-6', buttonVariants())}
download="Anton_Bochkovskyi_Front-End_Developer_CV"
href="/Anton_Bochkovskyi_Front-End_Developer_CV.pdf"
download={CV_FILENAME}
href={`/${CV_FILENAME}${CV_FILE_EXTENSION}`}
rel="noreferrer"
target="_blank"
>
Download CV
</Link>
</article>
<Technologies className="self-start" />
<TechnologyIcons className="self-start" />
</Content>
</section>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { cn } from '@/utils'
import { ComponentType, FC, HTMLAttributes } from 'react'
import { IconBaseProps } from 'react-icons'

interface TechnologiesItemProps extends HTMLAttributes<HTMLLIElement> {
interface TechnologyIconsItemProps extends HTMLAttributes<HTMLLIElement> {
Icon: ComponentType<IconBaseProps>
title: string
}

const TechnologiesItem: FC<TechnologiesItemProps> = ({
const TechnologyIconsItem: FC<TechnologyIconsItemProps> = ({
Icon,
className,
title,
Expand All @@ -28,4 +28,4 @@ const TechnologiesItem: FC<TechnologiesItemProps> = ({
)
}

export default TechnologiesItem
export default TechnologyIconsItem
Loading

0 comments on commit 5a2302d

Please sign in to comment.