Skip to content

Commit

Permalink
Refactored Navigation Bar
Browse files Browse the repository at this point in the history
1. Refactored Navigation Bar
2. Added SEO
3. Fixed styling for resume page
  • Loading branch information
kmiguel10 committed Oct 11, 2023
1 parent f8a252b commit 61b6ca3
Show file tree
Hide file tree
Showing 19 changed files with 540 additions and 119 deletions.
7 changes: 3 additions & 4 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from "react";
import Base from "../components/layouts/base";
import ProfileHeader from "../components/ui/header";
import ContainerLayout from "../components/layouts/container";
import Base from "@components/layouts/base";
import ContainerLayout from "@components/layouts/container";
import InProgressImage from "../../public/aboutme-option12.webp";
import Image from "next/image";

const page = () => {
return (
<Base>
<Base subtitle="About Me" pageSlug="/about">
<ContainerLayout className="flex flex-col space-y-4">
<h1 className="text-3xl font-semibold tracking-tight text-gray-12 md:text-4xl">
About Me
Expand Down
21 changes: 11 additions & 10 deletions app/components/layouts/base.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { ReactNode } from "react";
import NavBar from "../ui/nav-bar";
import SeoBase from "@components/layouts/seo-base";
import NavBar from "@components/ui/nav-bar/nav-bar";

interface Props {
children: ReactNode;
}

const Base = ({ children }: Props) => {
export default function Base({
title,
subtitle,
pageSlug,
children,
}: BaseLayoutProps) {
return (
<>
<NavBar />
<SeoBase title={title} subtitle={subtitle} />
<NavBar selected={pageSlug} />
<main className="relative flex grow flex-col">{children}</main>
</>
);
};

export default Base;
}
26 changes: 26 additions & 0 deletions app/components/layouts/seo-base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Head from "next/head";

// -----------------------------------------------------------------------------
// Component
// -----------------------------------------------------------------------------

export default function SeoBase({
title = "Kent Miguel",
subtitle,
}: SeoBaseProps) {
const fullTitle =
subtitle && subtitle.length > 0 ? `${title} | ${subtitle}` : title;

return (
<Head>
{/* <link rel="shortcut icon" href="/images/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png" /> */}

<title>{fullTitle}</title>
<meta name="title" content={fullTitle} />
<meta name="theme-color" content="#000" />
</Head>
);
}
77 changes: 77 additions & 0 deletions app/components/ui/button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Link from 'next/link';
import { type ForwardedRef, forwardRef } from 'react';

import { buttonIconVariants, buttonVariants } from './styles';
import type { ButtonProps } from './types';
import { cx } from 'class-variance-authority';
import { twMerge } from 'tailwind-merge';

const Button = forwardRef(
(
{
className,
size = 'md',
variant = 'primary',
intent = 'none',
disabled = false,
href,
leftIcon,
rightIcon,
newTab,
title,
onClick,
children,
...rest
}: ButtonProps,
ref: ForwardedRef<HTMLButtonElement>,
) => {
const props = {
className: twMerge(
cx(
buttonVariants({ size, variant, intent: !disabled ? intent : undefined, disabled }),
className,
),
),
title: title || href || undefined,
'data-variant': variant,
'data-disabled': disabled,
'aria-disabled': disabled,
disabled,
ref,
onClick: newTab && href ? () => window.open(href, '_blank') : onClick,
...rest,
};

if (href && !newTab) {
return (
<Link href={href} passHref legacyBehavior>
<button {...props}>
{leftIcon && variant !== 'text' ? (
<span className={buttonIconVariants({ size })}>{leftIcon}</span>
) : null}
<span>{children}</span>
{rightIcon && variant !== 'text' ? (
<span className={buttonIconVariants({ size })}>{rightIcon}</span>
) : null}
</button>
</Link>
);
}

return (
<button {...props}>
{leftIcon && variant !== 'text' ? (
<span className={buttonIconVariants({ size })}>{leftIcon}</span>
) : null}
<span>{children}</span>
{rightIcon && variant !== 'text' ? (
<span className={buttonIconVariants({ size })}>{rightIcon}</span>
) : null}
</button>
);
},
);

Button.displayName = 'Button';

export default Button;
206 changes: 206 additions & 0 deletions app/components/ui/button/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import { cva } from 'class-variance-authority';

export const buttonIconVariants = cva(['flex', 'items-center', 'justify-center'], {
variants: {
size: {
sm: ['w-3', 'h-3'],
md: ['w-4', 'h-4'],
lg: ['w-4', 'h-4'],
xl: ['w-5', 'h-5'],
},
},
});

export const buttonVariants = cva(
[
'rounded',
'w-fit',
'flex',
'justify-center',
'items-center',
'font-medium',
'transition-colors',
'focus-visible:outline-none',
'focus-visible:ring-2',
'focus-visible:ring-blue-9',
],
{
variants: {
size: {
sm: ['px-2', 'h-6', 'text-xs', 'space-x-1'],
md: ['px-3', 'h-8', 'text-sm', 'space-x-1.5'],
lg: ['px-3', 'h-10', 'text-sm', 'space-x-1.5'],
xl: ['px-4', 'h-12', 'text-base', 'space-x-2'],
},
variant: {
primary: ['border'],
secondary: [],
outline: ['border'],
ghost: [],
text: ['hover:underline'],
},
intent: {
none: [
// Primary
'data-[variant=primary]:bg-gray-4',
'data-[variant=primary]:text-gray-12',
'data-[variant=primary]:border-gray-7',
'data-[variant=primary]:hover:border-gray-8',
'data-[variant=primary]:active:bg-gray-5',
// Secondary
'data-[variant=secondary]:bg-gray-4',
'data-[variant=secondary]:text-gray-11',
'data-[variant=secondary]:hover:bg-gray-5',
'data-[variant=secondary]:active:bg-gray-6',
// Outline
'data-[variant=outline]:text-gray-11',
'data-[variant=outline]:border-gray-7',
'data-[variant=outline]:hover:border-gray-8',
'data-[variant=outline]:active:bg-gray-3',
// Ghost
'data-[variant=ghost]:text-gray-11',
'data-[variant=ghost]:hover:bg-gray-4',
'data-[variant=ghost]:active:bg-gray-5',
// Text
'data-[variant=text]:text-gray-11',
],
primary: [
// Primary
'data-[variant=primary]:bg-blue-9',
'data-[variant=primary]:dark:text-gray-12',
'data-[variant=primary]:text-gray-1',
'data-[variant=primary]:border-blue-7',
'data-[variant=primary]:hover:border-blue-8',
'data-[variant=primary]:active:bg-blue-10',
// Secondary
'data-[variant=secondary]:bg-blue-4',
'data-[variant=secondary]:text-blue-11',
'data-[variant=secondary]:hover:bg-blue-5',
'data-[variant=secondary]:active:bg-blue-6',
// Outline
'data-[variant=outline]:text-blue-9',
'data-[variant=outline]:border-blue-7',
'data-[variant=outline]:hover:border-blue-8',
'data-[variant=outline]:active:bg-blue-3',
// Ghost
'data-[variant=ghost]:text-blue-9',
'data-[variant=ghost]:hover:bg-blue-4',
'data-[variant=ghost]:active:bg-blue-5',
// Text
'data-[variant=text]:text-blue-9',
],
success: [
// Primary
'data-[variant=primary]:bg-green-9',
'data-[variant=primary]:dark:text-gray-12',
'data-[variant=primary]:text-gray-1',
'data-[variant=primary]:border-green-7',
'data-[variant=primary]:hover:border-green-8',
'data-[variant=primary]:active:bg-green-10',
// Secondary
'data-[variant=secondary]:bg-green-4',
'data-[variant=secondary]:text-green-11',
'data-[variant=secondary]:hover:bg-green-5',
'data-[variant=secondary]:active:bg-green-6',
// Outline
'data-[variant=outline]:text-green-9',
'data-[variant=outline]:border-green-7',
'data-[variant=outline]:hover:border-green-8',
'data-[variant=outline]:active:bg-green-3',
// Ghost
'data-[variant=ghost]:text-green-9',
'data-[variant=ghost]:hover:bg-green-4',
'data-[variant=ghost]:active:bg-green-5',
// Text
'data-[variant=text]:text-green-9',
],
fail: [
// Primary
'data-[variant=primary]:bg-red-9',
'data-[variant=primary]:dark:text-gray-12',
'data-[variant=primary]:text-gray-1',
'data-[variant=primary]:border-red-7',
'data-[variant=primary]:hover:border-red-8',
'data-[variant=primary]:active:bg-red-10',
// Secondary
'data-[variant=secondary]:bg-red-4',
'data-[variant=secondary]:text-red-11',
'data-[variant=secondary]:hover:bg-red-5',
'data-[variant=secondary]:active:bg-red-6',
// Outline
'data-[variant=outline]:text-red-9',
'data-[variant=outline]:border-red-7',
'data-[variant=outline]:hover:border-red-8',
'data-[variant=outline]:active:bg-red-3',
// Ghost
'data-[variant=ghost]:text-red-9',
'data-[variant=ghost]:hover:bg-red-4',
'data-[variant=ghost]:active:bg-red-5',
// Text
'data-[variant=text]:text-red-9',
],
warning: [
// Primary
'data-[variant=primary]:bg-yellow-9',
'data-[variant=primary]:dark:text-gray-1',
'data-[variant=primary]:text-gray-12',
'data-[variant=primary]:border-yellow-7',
'data-[variant=primary]:hover:border-yellow-8',
'data-[variant=primary]:active:bg-yellow-10',
// Secondary
'data-[variant=secondary]:bg-yellow-4',
'data-[variant=secondary]:text-yellow-11',
'data-[variant=secondary]:hover:bg-yellow-5',
'data-[variant=secondary]:active:bg-yellow-6',
// Outline
'data-[variant=outline]:text-yellow-9',
'data-[variant=outline]:border-yellow-7',
'data-[variant=outline]:hover:border-yellow-8',
'data-[variant=outline]:active:bg-yellow-3',
// Ghost
'data-[variant=ghost]:text-yellow-9',
'data-[variant=ghost]:hover:bg-yellow-4',
'data-[variant=ghost]:active:bg-yellow-5',
// Text
'data-[variant=text]:text-yellow-9',
],
orange: [
// Primary
'data-[variant=primary]:bg-orange-9',
'data-[variant=primary]:dark:text-gray-12',
'data-[variant=primary]:text-gray-1',
'data-[variant=primary]:border-orange-7',
'data-[variant=primary]:hover:border-orange-8',
'data-[variant=primary]:active:bg-orange-10',
// Secondary
'data-[variant=secondary]:bg-orange-4',
'data-[variant=secondary]:text-orange-11',
'data-[variant=secondary]:hover:bg-orange-5',
'data-[variant=secondary]:active:bg-orange-6',
// Outline
'data-[variant=outline]:text-orange-9',
'data-[variant=outline]:border-orange-7',
'data-[variant=outline]:hover:border-orange-8',
'data-[variant=outline]:active:bg-orange-3',
// Ghost
'data-[variant=ghost]:text-orange-9',
'data-[variant=ghost]:hover:bg-orange-4',
'data-[variant=ghost]:active:bg-orange-5',
// Text
'data-[variant=text]:text-orange-9',
],
},
disabled: {
true: 'aria-disabled cursor-not-allowed',
false: '',
},
},
compoundVariants: [
{ variant: 'primary', disabled: true, className: 'bg-gray-3 text-gray-7 border-gray-7' },
{ variant: 'secondary', disabled: true, className: 'bg-gray-9 text-gray-11' },
{ variant: 'outline', disabled: true, className: 'text-gray-7 border-gray-7' },
{ variant: 'ghost', disabled: true, className: 'bg-gray-9 text-gray-11' },
{ variant: 'text', disabled: true, className: 'bg-gray-9 text-gray-11' },
],
},
);
22 changes: 22 additions & 0 deletions app/components/ui/button/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { ReactNode } from 'react';

import { buttonVariants } from './styles';
import type { VariantProps } from 'class-variance-authority';

// -----------------------------------------------------------------------------
// Variant props
// -----------------------------------------------------------------------------

export type ButtonVariantProps = VariantProps<typeof buttonVariants>;

// -----------------------------------------------------------------------------
// Component props
// -----------------------------------------------------------------------------

export type ButtonProps = JSX.IntrinsicElements['button'] &
ButtonVariantProps & {
href?: string;
leftIcon?: ReactNode;
rightIcon?: ReactNode;
newTab?: boolean;
};
Loading

0 comments on commit 61b6ca3

Please sign in to comment.