Skip to content

Commit d491038

Browse files
author
adam.watkins
committedApr 7, 2023
🎨 Add header
1 parent 34efb14 commit d491038

11 files changed

+430
-20
lines changed
 

‎public/logo-white.svg

+1
Loading

‎src/components/DottedGridBackground.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import React from "react";
22

33
interface DottedGridBackgroundProps {
44
children: React.ReactNode;
5+
className?: string
56
}
6-
const DottedGridBackground = ({ children }: DottedGridBackgroundProps) => {
7+
const DottedGridBackground = ({ children, className }: DottedGridBackgroundProps) => {
78
return (
89
<div
9-
className="flex flex-col justify-center items-center bg-gradient-to-b from-gray-100 to-transparent w-screen h-screen background"
10+
className={`${className ? className + " " : ""} background`}
1011
>
1112
{children}
1213
</div>

‎src/components/Header.tsx

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// import { AnimatePresence, motion } from "framer-motion";
2+
import Link from "next/link";
3+
import { useRouter } from "next/router";
4+
import {
5+
FaAngleDown,
6+
FaGithub,
7+
FaHome,
8+
FaLink,
9+
FaSignOutAlt,
10+
} from "react-icons/fa";
11+
import Image from "next/image";
12+
13+
// import { Dropdown, DropdownItem } from "@/ui/dropdown";
14+
// import Loader from "@/ui/loader";
15+
//
16+
// import { useAuth } from "@/hooks/useAuth";
17+
18+
const Header: React.FC = () => {
19+
// const { signOut, session, status } = useAuth();
20+
const router = useRouter();
21+
22+
// const authenticated = status == "authenticated" && (
23+
// <Dropdown
24+
// title={session?.user?.name || ""}
25+
// icon={<FaAngleDown className="h-5 text-inherit" />}
26+
// loader={false}
27+
// >
28+
// <h1 className="border-white/5 border-b-2 font-bold px-3 pb-1 text-md">
29+
// {session?.user?.name}
30+
// </h1>
31+
//
32+
// <DropdownItem
33+
// icon={<FaSignOutAlt className="h-4 text-inherit text-white" />}
34+
// onClick={signOut}
35+
// >
36+
// Sign Out
37+
// </DropdownItem>
38+
// {router.route != "/" && (
39+
// <DropdownItem icon={<FaHome className="h-4 text-inherit" />}>
40+
// <Link href="/">Home</Link>
41+
// </DropdownItem>
42+
// )}
43+
// <DropdownItem icon={<FaLink className="h-4 text-inherit" />}>
44+
// <a
45+
// href="https://github.com/awtkns/confetti/issues/new"
46+
// target="_blank"
47+
// rel="noreferrer"
48+
// >
49+
// Report a bug
50+
// </a>
51+
// </DropdownItem>
52+
// </Dropdown>
53+
// );
54+
55+
// const loading = status == "loading" && <Loader />;
56+
//
57+
// const unauthenticated =
58+
// status == "unauthenticated" && router.route != "/auth" ? (
59+
// <Link href="/auth">Sign In</Link>
60+
// ) : (
61+
// <Link href="/">Home</Link>
62+
// );
63+
64+
const github = (
65+
<a
66+
href="https://github.com/reworkd/AgentGPT"
67+
className="right-0 ml-0 block block text-white hover:text-yellow-500"
68+
>
69+
<span className="sr-only">Confetti on GitHub</span>
70+
<FaGithub size="25" />
71+
</a>
72+
);
73+
74+
return (
75+
<header className="z-50 w-full p-2 relative flex flex-row items-center justify-between align-middle">
76+
<Image src="logo-white.svg" alt="yes" width={30} height={0} />
77+
{/*<AnimatePresence>*/}
78+
{/* <motion.div*/}
79+
{/* initial={{ opacity: 0 }}*/}
80+
{/* animate={{ opacity: 1 }}*/}
81+
{/* transition={{ duration: 1, type: "spring" }}*/}
82+
{/* className="ml-auto pr-4 text-lg text-white hover:text-yellow-500"*/}
83+
{/* >*/}
84+
{/* {authenticated || loading || unauthenticated}*/}
85+
{/* </motion.div>*/}
86+
{/*</AnimatePresence>*/}
87+
{github}
88+
</header>
89+
);
90+
};
91+
92+
export default Header;

‎src/layout/default.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// import Footer from "../components/Footer";
2+
// import Header from "../components/Header";
3+
import { ReactNode } from "react";
4+
import Head from "next/head";
5+
import DottedGridBackground from "../components/DottedGridBackground";
6+
import Header from "../components/Header";
7+
8+
interface LayoutProps {
9+
children: ReactNode;
10+
}
11+
12+
const DefaultLayout = (props: LayoutProps) => {
13+
return (
14+
<div
15+
className="flex min-h-screen flex-col min-h-screen bg-gradient-to-b from-[#2B2B2B] to-[#1F1F1F]"
16+
>
17+
<Head>
18+
<title>Agent-GPT</title>
19+
<meta name="description" content="Agent-GPT b Reworkd.ai"/>
20+
<link rel="icon" href="/favicon.ico"/>
21+
</Head>
22+
<DottedGridBackground>
23+
<Header />
24+
<main className="flex flex-col justify-center items-center w-screen h-screen ">
25+
{props.children}
26+
</main>
27+
</DottedGridBackground>
28+
{/*<Footer />*/}
29+
</div>
30+
);
31+
};
32+
33+
export default DefaultLayout;

‎src/pages/index.tsx

+15-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
import { type NextPage } from "next";
1+
import {type NextPage} from "next";
22
import Head from "next/head";
33
import DottedGridBackground from "../components/DottedGridBackground";
44
import Badge from "../components/Badge";
5+
import Input from "../ui/input";
6+
import {useState} from "react";
7+
import DefaultLayout from "../layout/default";
58

69
const Home: NextPage = () => {
10+
const input = useState("")
711

8-
return (
9-
<>
10-
<Head>
11-
<title>Agent-GPT</title>
12-
<meta name="description" content="Agent-GPT b Reworkd.ai" />
13-
<link rel="icon" href="/favicon.ico" />
14-
</Head>
15-
<main className="min-h-screen bg-gradient-to-b from-[#2B2B2B] to-[#1F1F1F]">
16-
<DottedGridBackground>
17-
<div id="title" className="flex gap-4 items-center">
18-
<div className="font-bold text-4xl text-[#C0C0C0]">AgentGPT</div>
19-
<Badge>Beta 🚀</Badge>
20-
</div>
21-
</DottedGridBackground>
22-
</main>
23-
</>
24-
);
12+
return (
13+
<DefaultLayout>
14+
<div id="title" className="flex gap-4 items-center">
15+
<div className="font-bold text-4xl text-[#C0C0C0]">AgentGPT</div>
16+
<Badge>Beta 🚀</Badge>
17+
18+
</div>
19+
<Input model={input}/>
20+
</DefaultLayout>
21+
);
2522
};
2623

2724
export default Home;

‎src/ui/button.tsx

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import type { ForwardedRef } from "react";
2+
import { forwardRef, useState } from "react";
3+
4+
import Loader from "./loader";
5+
6+
export interface ButtonProps {
7+
type?: "button" | "submit" | "reset";
8+
className?: string;
9+
icon?: React.ReactNode;
10+
children?: React.ReactNode;
11+
loader?: boolean;
12+
disabled?: boolean;
13+
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;
14+
}
15+
16+
const Button = forwardRef(
17+
(props: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) => {
18+
const [loading, setLoading] = useState(false);
19+
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
20+
if (props.loader == true) setLoading(true);
21+
22+
try {
23+
Promise.resolve(props.onClick?.(e)).then();
24+
} catch (e) {
25+
setLoading(false);
26+
}
27+
};
28+
29+
return (
30+
<button
31+
ref={ref}
32+
type={props.type}
33+
disabled={loading || props.disabled}
34+
onClick={onClick}
35+
className={
36+
"text-white transition hover:text-yellow-500 " + props.className
37+
}
38+
>
39+
<div className="flex items-center">
40+
{loading ? (
41+
<Loader />
42+
) : (
43+
<>
44+
{props.icon ? <div className="mr-2">{props.icon}</div> : null}
45+
{props.children}
46+
</>
47+
)}
48+
</div>
49+
</button>
50+
);
51+
}
52+
);
53+
54+
Button.displayName = "Button";
55+
export default Button;

‎src/ui/dropdown.tsx

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Menu, Transition } from "@headlessui/react";
2+
import { Fragment } from "react";
3+
4+
import type { ButtonProps } from "./button";
5+
import Button from "./button";
6+
7+
interface DropdownProps extends ButtonProps {
8+
title?: string | undefined;
9+
onClick?: () => void;
10+
}
11+
12+
export const Dropdown = (props: DropdownProps) => {
13+
return (
14+
<Menu as="div" className="right-0 ml-auto">
15+
<Menu.Button as={Button} className={props.className} icon={props.icon}>
16+
<span className="hidden md:flex">{props.title}</span>
17+
</Menu.Button>
18+
<Transition
19+
as={Fragment}
20+
enter="transition ease-out duration-100"
21+
enterFrom="transform opacity-0 scale-95"
22+
enterTo="transform opacity-100 scale-100"
23+
leave="transition ease-in duration-75"
24+
leaveFrom="transform opacity-100 scale-100"
25+
leaveTo="transform opacity-0 scale-95"
26+
>
27+
<Menu.Items className="absolute right-2 z-40 mt-2 w-56 origin-top-right divide-y rounded-lg bg-slate-900 p-1 shadow-sm focus:outline-none">
28+
<div className="py-1">{props.children}</div>
29+
</Menu.Items>
30+
</Transition>
31+
</Menu>
32+
);
33+
};
34+
35+
export const DropdownItem = (props: DropdownProps) => {
36+
return (
37+
<Menu.Item>
38+
<div
39+
className={`block cursor-pointer justify-between rounded px-3 py-2 text-sm text-white duration-200 hover:text-yellow-500
40+
${props.className}`}
41+
onClick={props.onClick}
42+
>
43+
<div className="flex items-center">
44+
{props.icon && <div className="mr-3">{props.icon}</div>}
45+
{props.children}
46+
</div>
47+
</div>
48+
</Menu.Item>
49+
);
50+
};

‎src/ui/input.tsx

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// import Loader from "@/motions/loader";
2+
import type {
3+
Dispatch,
4+
ForwardedRef,
5+
InputHTMLAttributes,
6+
KeyboardEventHandler,
7+
SetStateAction,
8+
} from "react";
9+
import { forwardRef } from "react";
10+
11+
const SHARED_STYLE = "rounded-full ";
12+
const STYLE =
13+
SHARED_STYLE +
14+
" border-gray-300 focus:border-yellow-500 focus:ring-yellow-500 ";
15+
const ERROR_STYLE =
16+
SHARED_STYLE + " border-red-500 focus:border-red-500 focus:ring-red-500 ";
17+
18+
export interface InputProps<T> extends InputHTMLAttributes<HTMLInputElement> {
19+
model: [T, Dispatch<SetStateAction<T>>];
20+
error?: [boolean, Dispatch<SetStateAction<boolean>>];
21+
enterPressed?: () => void;
22+
}
23+
24+
const Input = forwardRef(
25+
(props: InputProps<string>, ref: ForwardedRef<HTMLInputElement>) => {
26+
const { model, error, enterPressed, onKeyDown, className, ...otherProps } =
27+
props;
28+
const [isError, setIsError] = error || [false, () => undefined];
29+
30+
const keyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
31+
try {
32+
if (e.key === "Enter" && enterPressed) {
33+
e.preventDefault();
34+
enterPressed();
35+
return;
36+
}
37+
38+
if (onKeyDown) onKeyDown(e);
39+
} catch (e) {
40+
setIsError(true);
41+
}
42+
};
43+
44+
return (
45+
<input
46+
ref={ref}
47+
onKeyDown={keyDown}
48+
value={model[0]}
49+
onChange={(e) => {
50+
model[1](e.target.value);
51+
setIsError(false);
52+
}}
53+
className={(isError ? ERROR_STYLE : STYLE) + className}
54+
{...otherProps}
55+
/>
56+
);
57+
}
58+
);
59+
60+
Input.displayName = "input";
61+
export default Input;

‎src/ui/loader.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Ring } from "@uiball/loaders";
2+
3+
interface LoaderProps {
4+
className?: string;
5+
size?: number;
6+
speed?: number;
7+
lineWeight?: number;
8+
}
9+
10+
const Loader: React.FC<LoaderProps> = ({
11+
className,
12+
size = 16,
13+
speed = 2,
14+
lineWeight = 7,
15+
}) => {
16+
return (
17+
<div className={className}>
18+
<Ring size={size} speed={speed} color="white" lineWeight={lineWeight} />
19+
</div>
20+
);
21+
};
22+
23+
export default Loader;

‎src/ui/popin.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { motion } from "framer-motion";
2+
import type { PropsWithChildren } from "react";
3+
4+
interface MotionProps extends PropsWithChildren {
5+
className?: string;
6+
}
7+
8+
const PopIn = (props: MotionProps) => (
9+
<motion.div
10+
initial={{ scale: 0 }}
11+
animate={{ scale: 1 }}
12+
transition={{ duration: 0.5, type: "spring" }}
13+
{...props}
14+
>
15+
{props.children}
16+
</motion.div>
17+
);
18+
19+
PopIn.displayName = "PopIn";
20+
export default PopIn;

‎src/ui/toast.tsx

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import * as ToastPrimitive from "@radix-ui/react-toast";
2+
import cx from "classnames";
3+
import type { Dispatch, SetStateAction } from "react";
4+
import React from "react";
5+
6+
type Props = {
7+
model: [boolean, Dispatch<SetStateAction<boolean>>];
8+
onAction?: () => void;
9+
title: string;
10+
description?: string;
11+
};
12+
13+
const Toast = (props: Props) => {
14+
const [open, setOpen] = props.model;
15+
16+
return (
17+
<ToastPrimitive.Provider swipeDirection={"right"}>
18+
<ToastPrimitive.Root
19+
open={open}
20+
onOpenChange={setOpen}
21+
className={cx(
22+
"fixed inset-x-4 bottom-4 z-50 w-auto rounded-2xl shadow-lg md:right-4 md:left-auto md:w-full md:max-w-sm",
23+
"bg-slate-900",
24+
"radix-state-open:animate-toast-slide-in-bottom md:radix-state-open:animate-toast-slide-in-right",
25+
"radix-state-closed:animate-toast-hide",
26+
"radix-swipe-direction-right:radix-swipe-end:animate-toast-swipe-out-x",
27+
"radix-swipe-direction-right:translate-x-radix-toast-swipe-move-x",
28+
"radix-swipe-direction-down:radix-swipe-end:animate-toast-swipe-out-y",
29+
"radix-swipe-direction-down:translate-y-radix-toast-swipe-move-y",
30+
"radix-swipe-cancel:translate-x-0 radix-swipe-cancel:duration-200 radix-swipe-cancel:ease-[ease]",
31+
"focus:outline-none focus-visible:ring focus-visible:ring-purple-500 focus-visible:ring-opacity-75"
32+
)}
33+
>
34+
<div className="flex">
35+
<div className="flex w-0 flex-1 items-center py-4 pl-5">
36+
<div className="radix w-full">
37+
<ToastPrimitive.Title className="text-lg font-medium text-white">
38+
{props.title}
39+
</ToastPrimitive.Title>
40+
{props.description && (
41+
<ToastPrimitive.Description className="dark:text-gray-10 text-md mt-1 rounded-md bg-slate-800/50 p-1 text-white">
42+
<pre className="overflow-hidden text-ellipsis">
43+
{props.description}
44+
</pre>
45+
</ToastPrimitive.Description>
46+
)}
47+
</div>
48+
</div>
49+
<div className="mx-4 flex items-center justify-center py-4">
50+
<div className="flex flex-col ">
51+
{props.onAction && (
52+
<ToastPrimitive.Action
53+
altText="copy"
54+
className="text-md flex w-full items-center justify-center rounded-2xl border border-transparent px-3 py-2 font-medium text-yellow-500 hover:bg-white/20 "
55+
onClick={(e) => {
56+
e.preventDefault();
57+
if (props.onAction) props.onAction();
58+
setOpen(false);
59+
}}
60+
>
61+
Copy
62+
</ToastPrimitive.Action>
63+
)}
64+
<ToastPrimitive.Close className="text-md flex w-full items-center justify-center rounded-2xl border border-transparent px-3 py-2 font-medium text-white hover:bg-white/20 ">
65+
Close
66+
</ToastPrimitive.Close>
67+
</div>
68+
</div>
69+
</div>
70+
</ToastPrimitive.Root>
71+
72+
<ToastPrimitive.Viewport />
73+
</ToastPrimitive.Provider>
74+
);
75+
};
76+
77+
export default Toast;

0 commit comments

Comments
 (0)
Please sign in to comment.