Working on sign in

This commit is contained in:
Khalim Conn-Kowlessar 2023-05-25 12:27:32 +01:00
parent 36dea89c8f
commit 69ae460536
6 changed files with 156 additions and 10 deletions

View file

@ -18,20 +18,20 @@ export const AuthOptions: NextAuthOptions = {
}),
],
pages: {
signIn: "/signin",
signIn: "/",
},
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
return true;
// TODO: While we don't have a database with verified users, we will only allow hestia emails to sign in
if (user.email?.endsWith("@hestia.homes")) {
return true;
}
// TODO: Handle this more elegantly
return "/beta";
},
async redirect({ url, baseUrl }) {
return baseUrl;
},
async session({ session, user, token }) {
return session;
},
async jwt({ token, user, account, profile, isNewUser }) {
return token;
async redirect({ baseUrl }) {
const redirectUrl = baseUrl + "/home";
return redirectUrl;
},
},
};

3
src/app/beta/page.tsx Normal file
View file

@ -0,0 +1,3 @@
export default function Beta() {
return <div>This application is not ready for general usage</div>;
}

View file

@ -0,0 +1,67 @@
"use client";
import { ReactNode, forwardRef } from "react";
import clsx from "clsx";
const baseStyles = {
solid:
"inline-flex justify-center rounded-lg py-2 px-3 text-sm font-semibold outline-2 outline-offset-2 transition-colors",
outline:
"inline-flex justify-center rounded-lg border py-[calc(theme(spacing.2)-1px)] px-[calc(theme(spacing.3)-1px)] text-sm outline-2 outline-offset-2 transition-colors",
};
type VariantStylesType = {
solid: {
cyan: string;
white: string;
gray: string;
};
outline: {
gray: string;
cyan: string;
white: string;
};
};
const variantStyles: VariantStylesType = {
solid: {
cyan: "relative overflow-hidden bg-cyan-500 text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-cyan-600 active:text-white/80 before:transition-colors",
white:
"bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70",
gray: "bg-gray-800 text-white hover:bg-gray-900 active:bg-gray-800 active:text-white/80",
},
outline: {
gray: "border-gray-300 text-gray-700 hover:border-gray-400 active:bg-gray-100 active:text-gray-700/80",
cyan: "relative overflow-hidden bg-cyan-500 text-white before:absolute before:inset-0 active:before:bg-transparent hover:before:bg-white/10 active:bg-cyan-600 active:text-white/80 before:transition-colors",
white:
"bg-white text-cyan-900 hover:bg-white/90 active:bg-white/90 active:text-cyan-900/70",
},
};
type ButtonInput = {
variant: "solid" | "outline";
color: "cyan" | "white" | "gray";
href: string;
} & JSX.IntrinsicElements["button"];
interface Props {
children?: ReactNode;
}
export type Ref = HTMLButtonElement;
// write me a forwardRef to use the Button component
const Button = forwardRef<Ref, ButtonInput>(
({ variant = "solid", color, className, href, ...props }, ref) => {
className = clsx(
baseStyles[variant],
variantStyles[variant][color],
className
);
return <button ref={ref} className={className} {...props} />;
}
);
Button.displayName = "Button";
export default Button;

View file

@ -0,0 +1,39 @@
"use client";
import { useSearchParams } from "next/navigation";
import { signIn } from "next-auth/react";
import Button from "./Button";
const GoogleSignInButton = () => {
const searchParams = useSearchParams();
const callbackUrl = searchParams.get("callbackUrl");
console.log("WYF");
console.log(callbackUrl);
return (
<Button
className="w-full"
onClick={() => signIn("google", { callbackUrl })}
>
<svg
aria-hidden="true"
focusable="false"
data-icon="google"
className="mr-8 w-5"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 488 512"
>
<path
fill="red"
d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"
></path>
</svg>
Continue with Google
</Button>
);
};
export default GoogleSignInButton;

View file

@ -0,0 +1,35 @@
const formClasses =
"block w-full appearance-none rounded-lg border bg-white py-[calc(theme(spacing.2)-1px)] px-[calc(theme(spacing.3)-1px)] text-gray-900 placeholder:text-gray-400 focus:border-stone-500 focus:outline-none focus:ring-cyan-500 sm:text-sm";
const Label = ({ id, children }: { id: string; children: React.ReactNode }) => {
return (
<label
htmlFor={id}
className="mb-2 block text-sm font-semibold text-gray-900"
>
{children}
</label>
);
};
type TypeFieldInput = {
id: string;
label: string;
type: string;
className?: string;
} & JSX.IntrinsicElements["input"];
export default function TextField({
id,
label,
type = "text",
className,
...props
}: TypeFieldInput) {
return (
<div className={className}>
{label && <Label id={id}>{label}</Label>}
<input id={id} type={type} {...props} className={formClasses} />
</div>
);
}

View file

@ -5,6 +5,8 @@ import { redirect } from "next/navigation";
const Home = async () => {
const session = await getServerSession(AuthOptions);
console.log("SESSION", session);
if (!session) {
redirect("/?callbackUrl=/home");
}