Skip to content

Commit

Permalink
Merge pull request #5 from martapanc/feat/layout
Browse files Browse the repository at this point in the history
Feat: layout
  • Loading branch information
martapanc authored Jul 5, 2023
2 parents 68257df + fa5a5ca commit 3f30025
Show file tree
Hide file tree
Showing 18 changed files with 1,211 additions and 76 deletions.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.13.5",
"classnames": "^2.3.2",
"clsx": "^1.2.1",
"focus-trap-react": "^10.1.4",
"framer-motion": "^10.12.18",
"inquirer-fuzzy-path": "^2.3.0",
"next": "^13.4.4",
"next-themes": "^0.2.1",
"plop": "^3.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-headroom": "^3.2.1",
"react-icons": "^4.10.1",
"react-tippy": "^1.4.0",
"tailwind-merge": "^1.12.0"
},
"devDependencies": {
Expand All @@ -48,6 +54,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/react": "^18.2.7",
"@types/react-headroom": "^3.2.0",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "^10.4.14",
Expand Down
22 changes: 22 additions & 0 deletions src/components/atoms/BurgerIcon/BurgerIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import classNames from 'classnames';

export interface BurgerIconProps {
isOpen: boolean;
}

const BurgerIcon = ({ isOpen }: BurgerIconProps) => {
return (
<div
className={classNames('burger-icon', {
open: isOpen,
})}
>
<span />
<span />
<span />
<span />
</div>
);
};

export { BurgerIcon };
1 change: 1 addition & 0 deletions src/components/atoms/BurgerIcon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './BurgerIcon';
50 changes: 50 additions & 0 deletions src/components/atoms/NavigationItem/NavigationItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use client';

import classNames from 'classnames';
import { motion, Variants } from 'framer-motion';
import Link from 'next/link';
import { usePathname } from 'next/navigation';

export interface NavigationItemProps {
href: string;
title: string;
variants: Variants;
initial: string;
animate: string;
customDelay?: number;
}

const NavigationItem = ({
href,
title,
variants,
initial,
animate,
customDelay,
}: NavigationItemProps) => {
const pathname = usePathname();
const isActive = pathname?.startsWith(href);

return (
<motion.li
variants={variants}
initial={initial}
animate={animate}
custom={customDelay}
>
<Link
href={href}
className={classNames(
isActive
? 'text-off-black dark:text-off-white font-bold'
: 'hover:text-off-black dark:hover:text-off-white font-medium text-slate-700 dark:text-slate-400 md:text-slate-500 md:dark:text-slate-400',
'md:underlined relative block whitespace-nowrap text-2xl transition md:text-lg'
)}
>
{title}
</Link>
</motion.li>
);
};

export { NavigationItem };
3 changes: 3 additions & 0 deletions src/components/atoms/NavigationItem/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use client';

export * from './NavigationItem';
36 changes: 36 additions & 0 deletions src/components/buttons/ModeToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import clsx from 'clsx';
import { useTheme } from 'next-themes';
import * as React from 'react';
import { useEffect, useState } from 'react';
import { FiMoon, FiSun } from 'react-icons/fi';

type ThemeButtonProps = React.ComponentPropsWithoutRef<'button'>;

export default function ModeToggleButton({
className,
...rest
}: ThemeButtonProps) {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);

useEffect(() => setMounted(true), []);

function toggleMode() {
return setTheme(theme === 'dark' ? 'light' : 'dark');
}

return (
<button
className={clsx(
'flex items-center justify-center rounded-md border-2 ' +
'border-grey-300 ring-grey-300 bg-transparent p-2 transition-all hover:ring-2 hover:ring-offset-2 ' +
'dark:border-grey-700 dark:ring-grey-200 dark:bg-transparent dark:hover:ring-2 dark:hover:ring-offset-2',
className
)}
{...rest}
onClick={toggleMode}
>
{mounted ? <>{theme === 'light' ? <FiMoon /> : <FiSun />}</> : <FiSun />}
</button>
);
}
168 changes: 168 additions & 0 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { useTheme } from 'next-themes';
import { IconType } from 'react-icons';
import { FiMail } from 'react-icons/fi';
import {
SiGithub,
SiGoodreads,
SiInstagram,
SiLinkedin,
SiMedium,
SiSteam,
SiYoutube,
} from 'react-icons/si';

import UnstyledLink from '@/components/links/UnstyledLink';

export default function Footer() {
const { theme } = useTheme();

return (
<footer
className={`${
theme === 'dark'
? 'to-dark bg-gradient-to-r from-sky-950'
: 'bg-gradient-to-r from-blue-300 to-sky-100'
}`}
>
<main className='layout flex flex-col items-center py-6'>
<div className='flex flex-wrap justify-center gap-x-8 gap-y-4'>
<FooterLinks />
</div>

<div className='mt-4 flex w-full flex-col-reverse items-center md:flex-row md:justify-between'>
<Copyright />

<SocialLinks />
</div>
</main>
</footer>
);
}

function FooterLinks() {
return (
<div className='flex flex-wrap justify-center gap-x-8 gap-y-4'>
{footerLinks.map(({ href, label }) => (
<UnstyledLink
key={label}
className='animated-underline focus-visible:ring-primary-300 rounded-sm text-sm font-medium text-blue-950 focus:outline-none focus-visible:ring dark:text-gray-200'
href={href}
>
{label}
</UnstyledLink>
))}
</div>
);
}

function SocialLinks() {
const emailAddress = 'info@martacodes.it';

return (
<div className='mt-8 flex space-x-4 md:mt-2'>
<div className='flex items-center'>
<a
href={'mailto:' + emailAddress}
className='focus-visible:ring-primary-300 rounded-sm align-middle focus:outline-none focus-visible:ring'
>
<FiMail className='hover:text-primary-500 dark:hover:text-primary-300 h-7 w-7 align-middle text-blue-900 dark:text-gray-300' />
</a>
</div>
{socialLinks.map((socialLink) => (
<UnstyledLink
key={socialLink.id}
className='focus-visible:ring-primary-300 inline-flex items-center justify-center rounded-sm focus:outline-none focus-visible:ring'
href={socialLink.href}
>
<socialLink.icon className='hover:text-primary-500 dark:hover:text-primary-300 my-auto h-6 w-6 align-middle text-blue-900 transition-colors dark:text-gray-300' />
</UnstyledLink>
))}
</div>
);
}

function Copyright() {
const year = new Date().getFullYear();

return <div className='mt-10 flex md:mt-0'>© {year} Marta Pancaldi</div>;
}

type FooterLink = {
href: string;
label: string;
};
const footerLinks: FooterLink[] = [
{
href: 'https://martas.links',
label: 'Links',
},
{
href: 'https://github.com/martapanc/martacodes.it',
label: 'Source Code',
},
{
href: 'https://martapancaldi.hashnode.dev/',
label: 'Blog',
},
{
href: 'https://www.polywork.com/marta_pancaldi',
label: 'Updates',
},
{
href: '/',
label: 'Analytics',
},
{
href: '/',
label: 'Guestbook',
},
{
href: '/',
label: 'Feedback',
},
];

type SocialLink = {
href: string;
icon: IconType;
id: string;
};
const socialLinks: SocialLink[] = [
{
href: 'https://github.com/martapanc',
icon: SiGithub,
id: 'Github',
},
{
href: 'https://www.linkedin.com/in/martapancaldi',
icon: SiLinkedin,
id: 'Linkedin',
},
{
href: 'https://www.instagram.com/pancakemarta',
icon: SiInstagram,
id: 'Instagram',
},
{
href: 'https://medium.com/@marta.panc',
icon: SiMedium,
id: 'Medium',
},
{
href: 'https://www.goodreads.com/topolinamarta',
icon: SiGoodreads,
id: 'Goodreads',
},
{
href: 'https://www.youtube.com/channel/UCvQWDSKE8fY7srB8hO1vWNw',
icon: SiYoutube,
id: 'Youtube',
},
{
href: 'https://steamcommunity.com/id/martap/',
icon: SiSteam,
id: 'Steam',
},
];

//TODO: extract links
Loading

1 comment on commit 3f30025

@vercel
Copy link

@vercel vercel bot commented on 3f30025 Jul 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.