From d491038d404563be4cf9bf09d723459b2a845939 Mon Sep 17 00:00:00 2001 From: "adam.watkins" Date: Fri, 7 Apr 2023 08:43:48 +0300 Subject: [PATCH] :art: Add header --- public/logo-white.svg | 1 + src/components/DottedGridBackground.tsx | 5 +- src/components/Header.tsx | 92 +++++++++++++++++++++++++ src/layout/default.tsx | 33 +++++++++ src/pages/index.tsx | 33 ++++----- src/ui/button.tsx | 55 +++++++++++++++ src/ui/dropdown.tsx | 50 ++++++++++++++ src/ui/input.tsx | 61 ++++++++++++++++ src/ui/loader.tsx | 23 +++++++ src/ui/popin.tsx | 20 ++++++ src/ui/toast.tsx | 77 +++++++++++++++++++++ 11 files changed, 430 insertions(+), 20 deletions(-) create mode 100644 public/logo-white.svg create mode 100644 src/components/Header.tsx create mode 100644 src/layout/default.tsx create mode 100644 src/ui/button.tsx create mode 100644 src/ui/dropdown.tsx create mode 100644 src/ui/input.tsx create mode 100644 src/ui/loader.tsx create mode 100644 src/ui/popin.tsx create mode 100644 src/ui/toast.tsx diff --git a/public/logo-white.svg b/public/logo-white.svg new file mode 100644 index 0000000..85a18fd --- /dev/null +++ b/public/logo-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/DottedGridBackground.tsx b/src/components/DottedGridBackground.tsx index 74435d9..e63e94f 100644 --- a/src/components/DottedGridBackground.tsx +++ b/src/components/DottedGridBackground.tsx @@ -2,11 +2,12 @@ import React from "react"; interface DottedGridBackgroundProps { children: React.ReactNode; + className?: string } -const DottedGridBackground = ({ children }: DottedGridBackgroundProps) => { +const DottedGridBackground = ({ children, className }: DottedGridBackgroundProps) => { return (
{children}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..c67779b --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,92 @@ +// import { AnimatePresence, motion } from "framer-motion"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { + FaAngleDown, + FaGithub, + FaHome, + FaLink, + FaSignOutAlt, +} from "react-icons/fa"; +import Image from "next/image"; + +// import { Dropdown, DropdownItem } from "@/ui/dropdown"; +// import Loader from "@/ui/loader"; +// +// import { useAuth } from "@/hooks/useAuth"; + +const Header: React.FC = () => { + // const { signOut, session, status } = useAuth(); + const router = useRouter(); + + // const authenticated = status == "authenticated" && ( + // } + // loader={false} + // > + //

+ // {session?.user?.name} + //

+ // + // } + // onClick={signOut} + // > + // Sign Out + // + // {router.route != "/" && ( + // }> + // Home + // + // )} + // }> + // + // Report a bug + // + // + //
+ // ); + + // const loading = status == "loading" && ; + // + // const unauthenticated = + // status == "unauthenticated" && router.route != "/auth" ? ( + // Sign In + // ) : ( + // Home + // ); + + const github = ( + + Confetti on GitHub + + + ); + + return ( +
+ yes + {/**/} + {/* */} + {/* {authenticated || loading || unauthenticated}*/} + {/* */} + {/**/} + {github} +
+ ); +}; + +export default Header; diff --git a/src/layout/default.tsx b/src/layout/default.tsx new file mode 100644 index 0000000..b6932d9 --- /dev/null +++ b/src/layout/default.tsx @@ -0,0 +1,33 @@ +// import Footer from "../components/Footer"; +// import Header from "../components/Header"; +import { ReactNode } from "react"; +import Head from "next/head"; +import DottedGridBackground from "../components/DottedGridBackground"; +import Header from "../components/Header"; + +interface LayoutProps { + children: ReactNode; +} + +const DefaultLayout = (props: LayoutProps) => { + return ( +
+ + Agent-GPT + + + + +
+
+ {props.children} +
+ + {/*
*/} +
+ ); +}; + +export default DefaultLayout; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 0a8d704..5b6f24b 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,27 +1,24 @@ -import { type NextPage } from "next"; +import {type NextPage} from "next"; import Head from "next/head"; import DottedGridBackground from "../components/DottedGridBackground"; import Badge from "../components/Badge"; +import Input from "../ui/input"; +import {useState} from "react"; +import DefaultLayout from "../layout/default"; const Home: NextPage = () => { + const input = useState("") - return ( - <> - - Agent-GPT - - - -
- -
-
AgentGPT
- Beta 🚀 -
-
-
- - ); + return ( + +
+
AgentGPT
+ Beta 🚀 + +
+ +
+ ); }; export default Home; \ No newline at end of file diff --git a/src/ui/button.tsx b/src/ui/button.tsx new file mode 100644 index 0000000..3c3c0d7 --- /dev/null +++ b/src/ui/button.tsx @@ -0,0 +1,55 @@ +import type { ForwardedRef } from "react"; +import { forwardRef, useState } from "react"; + +import Loader from "./loader"; + +export interface ButtonProps { + type?: "button" | "submit" | "reset"; + className?: string; + icon?: React.ReactNode; + children?: React.ReactNode; + loader?: boolean; + disabled?: boolean; + onClick?: (e: React.MouseEvent) => Promise | void; +} + +const Button = forwardRef( + (props: ButtonProps, ref: ForwardedRef) => { + const [loading, setLoading] = useState(false); + const onClick = (e: React.MouseEvent) => { + if (props.loader == true) setLoading(true); + + try { + Promise.resolve(props.onClick?.(e)).then(); + } catch (e) { + setLoading(false); + } + }; + + return ( + + ); + } +); + +Button.displayName = "Button"; +export default Button; diff --git a/src/ui/dropdown.tsx b/src/ui/dropdown.tsx new file mode 100644 index 0000000..83278d6 --- /dev/null +++ b/src/ui/dropdown.tsx @@ -0,0 +1,50 @@ +import { Menu, Transition } from "@headlessui/react"; +import { Fragment } from "react"; + +import type { ButtonProps } from "./button"; +import Button from "./button"; + +interface DropdownProps extends ButtonProps { + title?: string | undefined; + onClick?: () => void; +} + +export const Dropdown = (props: DropdownProps) => { + return ( + + + {props.title} + + + +
{props.children}
+
+
+
+ ); +}; + +export const DropdownItem = (props: DropdownProps) => { + return ( + +
+
+ {props.icon &&
{props.icon}
} + {props.children} +
+
+
+ ); +}; diff --git a/src/ui/input.tsx b/src/ui/input.tsx new file mode 100644 index 0000000..f31ea31 --- /dev/null +++ b/src/ui/input.tsx @@ -0,0 +1,61 @@ +// import Loader from "@/motions/loader"; +import type { + Dispatch, + ForwardedRef, + InputHTMLAttributes, + KeyboardEventHandler, + SetStateAction, +} from "react"; +import { forwardRef } from "react"; + +const SHARED_STYLE = "rounded-full "; +const STYLE = + SHARED_STYLE + + " border-gray-300 focus:border-yellow-500 focus:ring-yellow-500 "; +const ERROR_STYLE = + SHARED_STYLE + " border-red-500 focus:border-red-500 focus:ring-red-500 "; + +export interface InputProps extends InputHTMLAttributes { + model: [T, Dispatch>]; + error?: [boolean, Dispatch>]; + enterPressed?: () => void; +} + +const Input = forwardRef( + (props: InputProps, ref: ForwardedRef) => { + const { model, error, enterPressed, onKeyDown, className, ...otherProps } = + props; + const [isError, setIsError] = error || [false, () => undefined]; + + const keyDown: KeyboardEventHandler = (e) => { + try { + if (e.key === "Enter" && enterPressed) { + e.preventDefault(); + enterPressed(); + return; + } + + if (onKeyDown) onKeyDown(e); + } catch (e) { + setIsError(true); + } + }; + + return ( + { + model[1](e.target.value); + setIsError(false); + }} + className={(isError ? ERROR_STYLE : STYLE) + className} + {...otherProps} + /> + ); + } +); + +Input.displayName = "input"; +export default Input; diff --git a/src/ui/loader.tsx b/src/ui/loader.tsx new file mode 100644 index 0000000..d83b1a1 --- /dev/null +++ b/src/ui/loader.tsx @@ -0,0 +1,23 @@ +import { Ring } from "@uiball/loaders"; + +interface LoaderProps { + className?: string; + size?: number; + speed?: number; + lineWeight?: number; +} + +const Loader: React.FC = ({ + className, + size = 16, + speed = 2, + lineWeight = 7, +}) => { + return ( +
+ +
+ ); +}; + +export default Loader; diff --git a/src/ui/popin.tsx b/src/ui/popin.tsx new file mode 100644 index 0000000..4b15c97 --- /dev/null +++ b/src/ui/popin.tsx @@ -0,0 +1,20 @@ +import { motion } from "framer-motion"; +import type { PropsWithChildren } from "react"; + +interface MotionProps extends PropsWithChildren { + className?: string; +} + +const PopIn = (props: MotionProps) => ( + + {props.children} + +); + +PopIn.displayName = "PopIn"; +export default PopIn; diff --git a/src/ui/toast.tsx b/src/ui/toast.tsx new file mode 100644 index 0000000..426bc7d --- /dev/null +++ b/src/ui/toast.tsx @@ -0,0 +1,77 @@ +import * as ToastPrimitive from "@radix-ui/react-toast"; +import cx from "classnames"; +import type { Dispatch, SetStateAction } from "react"; +import React from "react"; + +type Props = { + model: [boolean, Dispatch>]; + onAction?: () => void; + title: string; + description?: string; +}; + +const Toast = (props: Props) => { + const [open, setOpen] = props.model; + + return ( + + +
+
+
+ + {props.title} + + {props.description && ( + +
+                    {props.description}
+                  
+
+ )} +
+
+
+
+ {props.onAction && ( + { + e.preventDefault(); + if (props.onAction) props.onAction(); + setOpen(false); + }} + > + Copy + + )} + + Close + +
+
+
+
+ + +
+ ); +}; + +export default Toast;