Skip to content

Commit

Permalink
feat: add signin app contexte (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
Clement-Muth authored Jul 11, 2023
1 parent 3a8b6a9 commit ec5867c
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 48 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
GOOGLE_CLIENT_ID=692432207293-9pj9dlm4n6fu81s5r5bj3a14qmevc79h.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=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
NEXTAUTH_SECRET=my_ultra_secure_nextauth_secret
NEXTAUTH_URL=http://localhost:3000
5 changes: 4 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
compress: true
compress: true,
images: {
domains: ["lh3.googleusercontent.com", "vercel.com"]
}
}

const withPWA = require("@imbios/next-pwa")({
Expand Down
7 changes: 6 additions & 1 deletion rome.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"nursery": {
"useGroupedTypeImport": "error",
"noConsoleLog": "warn",
"recommended": true
},
"suspicious": {
"noImportAssign": "error",
"recommended": true
},
"correctness": {
Expand Down
15 changes: 15 additions & 0 deletions src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import NextAuth, { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions: NextAuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
],
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
12 changes: 7 additions & 5 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import "./globals.css";
import type { Metadata } from "next";
import { Metadata } from "next";
import { Inter } from "next/font/google";
import { Suspense } from "react";
import Header from "~/components/Header/Header";
import AuthenticationFirewall from "~/applications/Authentication/Ui/AuthenticationFirewall";
import ApplicationKernel from "~/core/ApplicationKernel";

const inter = Inter({ subsets: ["latin"] });
Expand All @@ -17,7 +16,8 @@ export const metadata: Metadata = {
creator: "@Clement-Muth"
},
metadataBase: new URL("https://price-comparator.vercel.app"),
themeColor: "#FFF"
themeColor: "#FFF",
manifest: "/manifest.json"
};

export default function RootLayout({
Expand All @@ -28,7 +28,9 @@ export default function RootLayout({
return (
<html lang="en">
<body className={inter.className}>
<ApplicationKernel>{children}</ApplicationKernel>
<AuthenticationFirewall>
<ApplicationKernel>{children}</ApplicationKernel>
</AuthenticationFirewall>
</body>
</html>
);
Expand Down
4 changes: 3 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getServerSession } from "next-auth";
import { Balancer } from "react-wrap-balancer";
import { authOptions } from "~/app/api/auth/[...nextauth]/route";

const HomePage = () => {
const HomePage = async () => {
return (
<>
<Balancer
Expand Down
13 changes: 13 additions & 0 deletions src/applications/Authentication/Ui/AuthenticationFirewall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use client";

import { SessionProvider } from "next-auth/react";

export interface AuthenticationFirewallProps {
children: React.ReactNode;
}

const AuthenticationFirewall = ({ children }: AuthenticationFirewallProps) => {
return <SessionProvider>{children}</SessionProvider>;
};

export default AuthenticationFirewall;
9 changes: 0 additions & 9 deletions src/applications/Authentication/Ui/SigninButton.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client";

import useSignInModal from "~/applications/Authentication/Ui/useSigninModal";

const SigninButtonBase = () => {
const { SignInModal, setShowSignInModal } = useSignInModal();

return (
<>
<button
type="button"
onClick={() => setShowSignInModal(true)}
className="rounded-full text-white bg-black px-5 py-2"
>
Sign in
</button>
<SignInModal />
</>
);
};

export default SigninButtonBase;
23 changes: 23 additions & 0 deletions src/applications/Authentication/Ui/SigninButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { getServerSession } from "next-auth";
import Image from "next/image";
import { authOptions } from "~/app/api/auth/[...nextauth]/route";
import SigninButtonBase from "~/applications/Authentication/Ui/SigninButton/SigninButtonBase";

const SigninButton = async () => {
const session = await getServerSession(authOptions);

return session?.user ? (
<Image
src={session.user.image ?? ""}
alt=""
width={30}
height={30}
className="rounded-full"
style={{ width: "auto", height: "auto" }}
/>
) : (
<SigninButtonBase />
);
};

export default SigninButton;
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use client";

import { signIn } from "next-auth/react";
import Image from "next/image";
import { useCallback, useMemo, useState } from "react";
import { Dispatch, SetStateAction } from "react";
import Link from "next/link";
import { Dispatch, SetStateAction, useState } from "react";
import Google from "~/components/Icons/Google/Google";
import LoadingDots from "~/components/Loader/LoadingDot";
import Modal from "~/components/Modal/Modal";
import { pcomparatorHomepageRoute } from "~/core/routes";

const SignInModal = ({
showSignInModal,
Expand All @@ -15,16 +17,20 @@ const SignInModal = ({
const [signInClicked, setSignInClicked] = useState(false);

return (
<Modal showModal={true} setShowModal={setShowSignInModal}>
<Modal showModal={showSignInModal} setShowModal={setShowSignInModal}>
<div className="w-full overflow-hidden shadow-xl md:max-w-md md:rounded-2xl md:border md:border-gray-200">
<div className="flex flex-col items-center justify-center space-y-3 border-b border-gray-200 bg-white px-4 py-6 pt-8 text-center md:px-16">
<a href="https://precedent.dev">
<Image src="/logo.png" alt="Logo" className="h-10 w-10 rounded-full" width={20} height={20} />
</a>
<Link href={pcomparatorHomepageRoute()}>
<Image
src="/static/logo.png"
alt="Logo"
className="h-10 w-10 rounded-full"
width={20}
height={20}
/>
</Link>
<h3 className="font-display text-2xl font-bold">Sign In</h3>
<p className="text-sm text-gray-500">
This is strictly for demo purposes - only your email and profile picture will be stored.
</p>
<p className="text-sm text-gray-500">Sign in to enjoy all features of PComparator</p>
</div>

<div className="flex flex-col space-y-4 bg-gray-50 px-4 py-8 md:px-16">
Expand All @@ -38,33 +44,22 @@ const SignInModal = ({
} flex h-10 w-full items-center justify-center space-x-3 rounded-md border text-sm shadow-sm transition-all duration-75 focus:outline-none`}
onClick={() => {
setSignInClicked(true);
// signIn("google");
signIn("google");
}}
>
{/* {signInClicked ? (
{signInClicked ? (
<LoadingDots color="#808080" />
) : (
<>
<Google className="h-5 w-5" />
<p>Sign In with Google</p>
</>
)} */}
)}
</button>
</div>
</div>
</Modal>
);
};

export function useSignInModal() {
const [showSignInModal, setShowSignInModal] = useState(false);

const SignInModalCallback = useCallback(() => {
return <SignInModal showSignInModal={showSignInModal} setShowSignInModal={setShowSignInModal} />;
}, [showSignInModal, setShowSignInModal]);

return useMemo(
() => ({ setShowSignInModal, SignInModal: SignInModalCallback }),
[setShowSignInModal, SignInModalCallback]
);
}
export default SignInModal;
16 changes: 16 additions & 0 deletions src/applications/Authentication/Ui/useSigninModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { useCallback, useMemo, useState } from "react";
import SignInModal from "~/applications/Authentication/Ui/SigninModal";

const useSignInModal = () => {
const [showSignInModal, setShowSignInModal] = useState(false);

const SignInModalCallback = useCallback(() => {
return <SignInModal showSignInModal={showSignInModal} setShowSignInModal={setShowSignInModal} />;
}, [showSignInModal]);

return useMemo(() => ({ setShowSignInModal, SignInModal: SignInModalCallback }), [SignInModalCallback]);
};

export default useSignInModal;
2 changes: 1 addition & 1 deletion src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface HeaderProps {

const Header = ({ children }: HeaderProps) => {
return (
<header className="fixed top-0 w-full flex justify-between px-4 py-3">
<header className="fixed top-0 w-full flex justify-between px-4 py-3 z-[33]">
<div className="flex items-center gap-x-2">
<Image
src="/static/logo.png"
Expand Down
33 changes: 33 additions & 0 deletions src/components/Icons/Google/Google.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export default function Google({ className }: { className: string }) {
return (
<svg viewBox="0 0 186.69 190.5" className={className}>
<title>Google</title>
<g transform="translate(1184.583 765.171)">
<path
clip-path="none"
mask="none"
d="M-1089.333-687.239v36.888h51.262c-2.251 11.863-9.006 21.908-19.137 28.662l30.913 23.986c18.011-16.625 28.402-41.044 28.402-70.052 0-6.754-.606-13.249-1.732-19.483z"
fill="#4285f4"
/>
<path
clip-path="none"
mask="none"
d="M-1142.714-651.791l-6.972 5.337-24.679 19.223h0c15.673 31.086 47.796 52.561 85.03 52.561 25.717 0 47.278-8.486 63.038-23.033l-30.913-23.986c-8.486 5.715-19.31 9.179-32.125 9.179-24.765 0-45.806-16.712-53.34-39.226z"
fill="#34a853"
/>
<path
clip-path="none"
mask="none"
d="M-1174.365-712.61c-6.494 12.815-10.217 27.276-10.217 42.689s3.723 29.874 10.217 42.689c0 .086 31.693-24.592 31.693-24.592-1.905-5.715-3.031-11.776-3.031-18.098s1.126-12.383 3.031-18.098z"
fill="#fbbc05"
/>
<path
d="M-1089.333-727.244c14.028 0 26.497 4.849 36.455 14.201l27.276-27.276c-16.539-15.413-38.013-24.852-63.731-24.852-37.234 0-69.359 21.388-85.032 52.561l31.692 24.592c7.533-22.514 28.575-39.226 53.34-39.226z"
fill="#ea4335"
clip-path="none"
mask="none"
/>
</g>
</svg>
);
}
9 changes: 6 additions & 3 deletions src/components/Leaflet/Leaflet.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { AnimatePresence, motion, useAnimation } from "framer-motion";
"use client";

import { AnimatePresence, PanInfo, motion, useAnimation } from "framer-motion";
import { Dispatch, ReactNode, SetStateAction, useEffect, useRef } from "react";

interface LeafletProps {
Expand All @@ -10,14 +12,15 @@ const Leaflet = ({ setShow, children }: LeafletProps) => {
const leafletRef = useRef<HTMLDivElement>(null);
const controls = useAnimation();
const transitionProps = { type: "spring", stiffness: 500, damping: 30 };

useEffect(() => {
controls.start({
y: 20,
transition: transitionProps
});
}, []);
}, [controls]);

async function handleDragEnd(_: any, info: any) {
async function handleDragEnd(_: unknown, info: PanInfo) {
const offset = info.offset.y;
const velocity = info.velocity.y;
const height = leafletRef.current?.getBoundingClientRect().height || 0;
Expand Down
40 changes: 40 additions & 0 deletions src/components/Loader/LoadingDot.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.loading {
display: inline-flex;
align-items: center;
}

.loading .spacer {
margin-right: 2px;
}

.loading span {
animation-name: blink;
animation-duration: 1.4s;
animation-iteration-count: infinite;
animation-fill-mode: both;
width: 5px;
height: 5px;
border-radius: 50%;
display: inline-block;
margin: 0 1px;
}

.loading span:nth-of-type(2) {
animation-delay: 0.2s;
}

.loading span:nth-of-type(3) {
animation-delay: 0.4s;
}

@keyframes blink {
0% {
opacity: 0.2;
}
20% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}
13 changes: 13 additions & 0 deletions src/components/Loader/LoadingDot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styles from "~/components/Loader/LoadingDot.module.css";

const LoadingDots = ({ color = "#000" }: { color?: string }) => {
return (
<span className={styles.loading}>
<span style={{ backgroundColor: color }} />
<span style={{ backgroundColor: color }} />
<span style={{ backgroundColor: color }} />
</span>
);
};

export default LoadingDots;
1 change: 1 addition & 0 deletions src/core/ApplicationKernel.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SessionProvider } from "next-auth/react";
import { ReactNode, Suspense } from "react";
import SigninButton from "~/applications/Authentication/Ui/SigninButton";
import Header from "~/components/Header/Header";
Expand Down
5 changes: 5 additions & 0 deletions src/core/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type Route = string;

export const pcomparatorHomepageRoute = (): Route => {
return "/";
};
Loading

0 comments on commit ec5867c

Please sign in to comment.