Skip to content
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
382 changes: 382 additions & 0 deletions front_end/src/app/(main)/about/components/AboutHeader.tsx

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions front_end/src/app/(main)/about/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import clsx from "clsx";
import { forwardRef } from "react";

export type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl";

export type ButtonVariant =
| "primary"
| "secondary"
| "tertiary"
| "text"
| "link";

export function buttonVariantClassName(variant: ButtonVariant) {
const className = {
primary:
"border border-metac-blue-900 bg-metac-blue-900 text-metac-gray-200 no-underline hover:border-metac-blue-800 hover:bg-metac-blue-800 active:border-metac-gray-800 active:bg-metac-gray-800 disabled:border-metac-blue-900 disabled:bg-metac-blue-900 dark:border-metac-blue-900-dark dark:bg-metac-blue-900-dark dark:text-metac-gray-200-dark dark:hover:border-metac-blue-800-dark dark:hover:bg-metac-blue-800-dark dark:active:border-metac-gray-800-dark dark:active:bg-metac-gray-800-dark disabled:dark:border-metac-blue-900-dark disabled:dark:bg-metac-blue-900-dark",
secondary:
"border border-metac-gray-900 bg-metac-gray-0 text-metac-gray-900 no-underline hover:bg-metac-gray-200 active:bg-metac-gray-300 disabled:bg-metac-gray-0 dark:border-metac-gray-900-dark dark:bg-metac-gray-0-dark dark:text-metac-gray-900-dark dark:hover:bg-metac-gray-200-dark dark:active:bg-metac-gray-300-dark disabled:dark:bg-metac-gray-0-dark",
tertiary:
"border border-metac-blue-500 bg-metac-gray-0 text-metac-blue-700 no-underline hover:border-metac-blue-600 hover:bg-metac-blue-100 active:border-metac-blue-600 active:bg-metac-blue-200 disabled:border-metac-blue-500 disabled:bg-metac-gray-0 dark:border-metac-blue-500-dark dark:bg-metac-gray-0-dark dark:text-metac-blue-700-dark dark:hover:border-metac-blue-600-dark dark:hover:bg-metac-blue-100-dark dark:active:border-metac-blue-600-dark dark:active:bg-metac-blue-200-dark disabled:dark:border-metac-blue-500-dark disabled:dark:bg-metac-gray-0-dark",
text: "border border-transparent text-metac-blue-800 no-underline hover:text-metac-blue-900 active:text-metac-blue-700 disabled:text-metac-blue-800 dark:text-metac-blue-800-dark dark:hover:text-metac-blue-900-dark dark:active:text-metac-blue-700-dark disabled:dark:text-metac-blue-800-dark",
link: "text-metac-blue-800 underline hover:text-metac-blue-900 active:text-metac-blue-700 disabled:text-metac-blue-800 dark:text-metac-blue-800-dark dark:hover:text-metac-blue-900-dark dark:active:text-metac-blue-700-dark disabled:dark:text-metac-blue-800-dark",
}[variant];

return className;
}

interface ButtonProps extends React.PropsWithChildren {
disabled?: boolean;
size?: ButtonSize;
variant?: ButtonVariant;
className?: string;
}

const Button = forwardRef(function Button(
{
size = "sm",
children,
className,
variant = "secondary",
href,
...props
}: ButtonProps &
React.ButtonHTMLAttributes<HTMLButtonElement> &
React.AnchorHTMLAttributes<HTMLAnchorElement>,
ref: React.Ref<HTMLButtonElement & HTMLAnchorElement>
) {
const Element = href ? "a" : "button";

return (
<Element
ref={ref}
className={clsx(
"inline-flex items-center justify-center rounded-full disabled:opacity-30",
{
xs: "gap-1 text-xs font-normal leading-none",
sm: "gap-2 text-sm font-medium leading-none",
md: "gap-2 text-base font-medium leading-tight",
lg: "gap-3 text-lg font-medium leading-7",
xl: "gap-3 text-2xl font-medium leading-loose",
"2xl": "gap-4 text-3xl font-medium leading-9",
}[size],
variant !== "link" &&
{
xs: "px-2 py-0.5",
sm: "px-3 py-2",
md: "px-4 py-2",
lg: "px-5 py-2",
xl: "px-6 py-2.5",
"2xl": "px-7 py-3.5",
}[size],
buttonVariantClassName(variant),
className
)}
href={href}
{...props}
>
{children}
</Element>
);
});

export default Button;
62 changes: 62 additions & 0 deletions front_end/src/app/(main)/about/components/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import clsx from "clsx";
import { forwardRef } from "react";

import { ButtonSize, ButtonVariant, buttonVariantClassName } from "./Button";

interface IconButtonProps extends React.PropsWithChildren {
"aria-label": string;
disabled?: boolean;
size?: ButtonSize;
variant?: ButtonVariant;
className?: string;
}

const IconButton = forwardRef(function IconButton(
{
size = "sm",
children,
className,
variant = "secondary",
href,
...props
}: IconButtonProps &
React.ButtonHTMLAttributes<HTMLButtonElement> &
React.AnchorHTMLAttributes<HTMLAnchorElement>,
ref: React.Ref<HTMLButtonElement & HTMLAnchorElement>
) {
const Element = href ? "a" : "button";

return (
<Element
ref={ref}
className={clsx(
"inline-flex items-center justify-center rounded-full disabled:opacity-30",
{
xs: "text-xs",
sm: "text-sm",
md: "text-base",
lg: "text-lg",
xl: "text-2xl",
"2xl": "text-3xl",
}[size],
variant !== "link" &&
{
xs: "h-6 w-6",
sm: "h-6 w-6",
md: "h-8 w-8",
lg: "h-10 w-10",
xl: "h-12 w-12",
"2xl": "h-16 w-16",
}[size],
buttonVariantClassName(variant),
className
)}
href={href}
{...props}
>
{children}
</Element>
);
});

export default IconButton;
18 changes: 18 additions & 0 deletions front_end/src/app/(main)/about/components/MetacLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";

const MetacLogo = ({ className = "" }) => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path d="M7.76271 17V7.11394L9.52542 17H10.4294L12.1921 7.11394V17H14V3H11.4689L9.9774 9.96852L8.48588 3H6V17H7.76271Z" />
</svg>
);
};

export default MetacLogo;
75 changes: 75 additions & 0 deletions front_end/src/app/(main)/about/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Dialog, DialogPanel, DialogTitle } from "@headlessui/react";
import clsx from "clsx";
import { useEffect } from "react";

import IconButton from "./IconButton";

interface ModalPanelProps extends React.PropsWithChildren {
className?: string;
title?: string;
hideClose?: boolean;
onClose: () => void;
beforePanel?: JSX.Element;
afterPanel?: JSX.Element;
}

function ModalPanel({
children,
className,
title,
hideClose,
onClose,
beforePanel,
afterPanel,
}: ModalPanelProps) {
return (
<DialogPanel className={clsx("flex max-h-full", className || "max-w-full")}>
{beforePanel}
<div className="relative max-h-full w-full rounded bg-white text-blue-900 dark:bg-gray-900 dark:text-white">
{!hideClose && (
<IconButton
variant="text"
size="xl"
aria-label="Close"
onClick={onClose}
className="absolute right-0 top-0"
>
<FontAwesomeIcon icon={faXmark} />
</IconButton>
)}
<div className="max-h-full overflow-auto p-7">
{title ? (
<DialogTitle
className={clsx(
"mb-4 mt-0 text-blue-900 dark:text-blue-900-dark",
{ "mr-3": !hideClose }
)}
>
{title}
</DialogTitle>
) : null}
{children}
</div>
</div>
{afterPanel}
</DialogPanel>
);
}

export interface ModalProps extends ModalPanelProps {
open: boolean;
}

export default function Modal({ onClose, open, ...props }: ModalProps) {
return (
<Dialog
className="fixed inset-0 z-50 flex items-center justify-center before:absolute before:size-full before:bg-blue-900 before:opacity-50 before:content-[''] dark:before:bg-black"
open={open}
onClose={onClose}
>
<ModalPanel onClose={onClose} {...props} />
</Dialog>
);
}
48 changes: 48 additions & 0 deletions front_end/src/app/(main)/about/components/ModalWithArrows.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
faChevronLeft,
faChevronRight,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import Modal, { ModalProps } from "./Modal";

interface ModalWithArrowsProps extends ModalProps {
onPrevious: () => void;
previousDisabled?: boolean;
onNext: () => void;
nextDisabled?: boolean;
}

export default function ModalWithArrows({
onPrevious,
previousDisabled,
onNext,
nextDisabled,
...rest
}: ModalWithArrowsProps) {
return (
<Modal
{...rest}
beforePanel={
<button
className="text-metac-gray-0 self-center px-1 py-4 text-5xl opacity-50 hover:opacity-95 disabled:opacity-25 xs:px-3 md:mr-4"
aria-label="Next"
onClick={onPrevious}
disabled={previousDisabled}
>
<FontAwesomeIcon icon={faChevronLeft} />
</button>
}
afterPanel={
<button
className="text-metac-gray-0 self-center px-1 py-4 text-5xl opacity-50 hover:opacity-95 disabled:opacity-25 xs:px-3 md:ml-4"
aria-label="Next"
onClick={onNext}
disabled={nextDisabled}
>
<FontAwesomeIcon icon={faChevronRight} />
</button>
}
/>
);
}
Binary file added front_end/src/app/(main)/about/img/person.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading