"use client"; import styles from "./loginPrompt.module.css"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { ArrowLeft, ArrowsClockwise, GoogleLogo, LineVertical, PaperPlaneTilt, PencilSimple, Spinner, CaretLeft, CaretRight, } from "@phosphor-icons/react"; import Link from "next/link"; import { useEffect, useState } from "react"; import useSWR from "swr"; import { GoogleSignIn } from "./GoogleSignIn"; import { Drawer, DrawerContent } from "@/components/ui/drawer"; export interface LoginPromptProps { loginRedirectMessage: string; onOpenChange: (open: boolean) => void; isMobileWidth?: boolean; } const fetcher = (url: string) => fetch(url).then((res) => res.json()); interface Provider { client_id: string; redirect_uri: string; } interface CredentialsData { [provider: string]: Provider; } export default function LoginPrompt(props: LoginPromptProps) { const { data, error, isLoading } = useSWR("/auth/oauth/metadata", fetcher); const [useEmailSignIn, setUseEmailSignIn] = useState(false); const [email, setEmail] = useState(""); const [checkEmail, setCheckEmail] = useState(false); const [recheckEmail, setRecheckEmail] = useState(false); const [currentTip, setCurrentTip] = useState(0); const [autoRotate, setAutoRotate] = useState(true); // Add these handler functions in your component const nextSlide = () => { setCurrentTip((prev) => (prev + 1) % tips.length); setAutoRotate(false); }; const prevSlide = () => { setCurrentTip((prev) => (prev - 1 + tips.length) % tips.length); setAutoRotate(false); }; useEffect(() => { const google = (window as any).google; console.log(data, isLoading, error); if (!google) return; // Initialize Google Sign In after script loads google.accounts.id.initialize({ client_id: data?.google?.client_id, callback: handleGoogleSignIn, auto_select: false, login_uri: data?.google?.redirect_uri, }); // Render the button google.accounts.id.renderButton(document.getElementById("g_id_signin")!, { theme: "outline", size: "large", width: "100%", }); }, [data]); const handleGoogleSignIn = () => { if (!data?.google?.client_id || !data?.google?.redirect_uri) return; // Create full redirect URL using current origin const fullRedirectUri = `${window.location.origin}${data.google.redirect_uri}`; const params = new URLSearchParams({ client_id: data.google.client_id, redirect_uri: fullRedirectUri, response_type: "code", scope: "email profile openid", state: window.location.pathname, access_type: "offline", prompt: "consent select_account", include_granted_scopes: "true", }); window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?${params}`; }; const handleGoogleScriptLoad = () => { const google = (window as any).google; console.log(data, isLoading, error); if (!data?.google?.client_id || !data?.google?.redirect_uri) return; // Initialize Google Sign In after script loads google.accounts.id.initialize({ client_id: data?.google?.client_id, callback: handleGoogleSignIn, auto_select: false, login_uri: data?.google?.redirect_uri, }); // Render the button google.accounts.id.renderButton(document.getElementById("g_id_signin")!, { theme: "outline", size: "large", width: "100%", }); }; const tips = [ { src: "/documents_tip.png", alt: "Documents tip" }, { src: "/personalize_tip.png", alt: "Personalize tip" }, { src: "/automate_tip.png", alt: "Automate tip" }, ]; useEffect(() => { if (!autoRotate) return; const timer = setInterval(() => { setCurrentTip((prev) => (prev + 1) % tips.length); }, 3000); // Rotate every 3 seconds return () => clearInterval(timer); }, [autoRotate]); function handleMagicLinkSignIn() { fetch("/auth/magic", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email: email }), }) .then((res) => { if (res.ok) { setCheckEmail(true); if (checkEmail) { setRecheckEmail(true); } return res.json(); } else { throw new Error("Failed to send magic link"); } }) .then((data) => { console.log(data); }) .catch((err) => { console.error(err); }); } if (props.isMobileWidth) { return (
{useEmailSignIn && ( )} {!useEmailSignIn && ( )}
); } return (
{useEmailSignIn && ( )} {!useEmailSignIn && ( )}
); } function EmailSignInContext({ email, setEmail, checkEmail, setCheckEmail, setUseEmailSignIn, recheckEmail, handleMagicLinkSignIn, }: { email: string; setEmail: (email: string) => void; checkEmail: boolean; setCheckEmail: (checkEmail: boolean) => void; setUseEmailSignIn: (useEmailSignIn: boolean) => void; recheckEmail: boolean; setRecheckEmail: (recheckEmail: boolean) => void; handleMagicLinkSignIn: () => void; }) { return (
Sign in with Email
{checkEmail ? recheckEmail ? "A new link has been sent. Click on the link in your email to sign-in" : "Click on the link in your email to sign-in" : "You will receive a sign-in link on the email address you provide below"}
setEmail(e.target.value)} /> {checkEmail && (
)}
); } function MainSignInContext({ tips, currentTip, nextSlide, prevSlide, handleGoogleScriptLoad, handleGoogleSignIn, isLoading, data, setUseEmailSignIn, isMobileWidth, }: { tips: { src: string; alt: string }[]; currentTip: number; nextSlide: () => void; prevSlide: () => void; handleGoogleScriptLoad: () => void; handleGoogleSignIn: () => void; isLoading: boolean; data: CredentialsData | undefined; setUseEmailSignIn: (useEmailSignIn: boolean) => void; isMobileWidth: boolean; }) { return (
{!isMobileWidth && (
{tips.map((tip, index) => ( {tip.alt} ))}
)}
Sign In for free to start using Khoj: Your AI-powered second brain
{/*
*/} )} Continue with Google
By logging in, you agree to our{" "} Terms of Service.
); }