skip to Main Content

This is my login modal:

"use client";

import Link from "next/link";

import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import {
  Card,
  CardContent,
  CardFooter,
  CardHeader,
} from "@/components/ui/card";
import { Icons } from "@/components/icons";
import { siteConfig } from "@/config/site";
import { Button, buttonVariants } from "@/components/ui/button";
import { ModeToggle } from "../mode-toggle";
import { cn } from "@/lib/utils";
import { RegisterModal } from "@/components/auth/register-modal";
import { LoginForm } from "@/components/auth/login-form";

interface LoginModalProps {
  children: React.ReactNode;
  asChild?: boolean;
}

export function LoginModal({ children, asChild }: LoginModalProps) {
  return (
    <Dialog>
      <DialogTrigger asChild={asChild}>{children}</DialogTrigger>
      <DialogContent className="p-0 w-auto bg-transparent border-none">
        <Card className="w-[400px] shadow-md">
          <CardHeader>
            <div className="w-full flex flex-col gap-y-4 items-start justify-start">
              <Link href="/">
                <div className="mr-6 flex items-center space-x-2">
                  <Icons.logo className="h-6 w-6" />
                  <span className="hidden font-bold sm:inline-block">
                    {siteConfig.name}
                  </span>
                </div>
              </Link>
              <div className="gap-y-0.5">
                <p className="text-3xl font-bold">Login</p>
                <p className="text-muted-foreground text-sm">
                  to access exclusive content on XXXXXXX
                </p>
              </div>
            </div>
          </CardHeader>
          <CardContent>
            <LoginForm />
          </CardContent>
          <CardFooter>
            <div className="flex items-center w-full gap-x-2">
              <Button
                size="lg"
                className="w-full"
                variant="outline"
                onClick={() => {}}
              >
                <Icons.google className="h-5 w-5" />
              </Button>
              <Button
                size="lg"
                className="w-full"
                variant="outline"
                onClick={() => {}}
              >
                <Icons.discord className="h-5 w-5" />
              </Button>
            </div>
          </CardFooter>
          <CardFooter>
            <div
              className={cn(
                buttonVariants({
                  variant: "link",
                  size: "sm",
                }),
                "text-secondary-foreground font-normal w-full items-start justify-start"
              )}
            >
              <RegisterModal>
                Don&apos;t have an account?
              </RegisterModal>
            </div>
            <div className="flex flex-1 items-center space-x-2 justify-end">
              <nav className="flex items-center">
                <Link
                  href={siteConfig.links.discord}
                  target="_blank"
                  rel="noreferrer"
                >
                  <div
                    className={cn(
                      buttonVariants({
                        variant: "ghost",
                      }),
                      "w-9 px-0"
                    )}
                  >
                    <Icons.discord className="h-4 w-4" />
                    <span className="sr-only">Discord</span>
                  </div>
                </Link>
                <Link
                  href={siteConfig.links.twitter}
                  target="_blank"
                  rel="noreferrer"
                >
                  <div
                    className={cn(
                      buttonVariants({
                        variant: "ghost",
                      }),
                      "w-9 px-0"
                    )}
                  >
                    <Icons.twitter className="h-3 w-3 fill-current" />
                    <span className="sr-only">Twitter</span>
                  </div>
                </Link>
                <ModeToggle />
              </nav>
            </div>
          </CardFooter>
        </Card>
      </DialogContent>
    </Dialog>
  );
}

I want to open this login modal when someones presses avatar on my home page! Also in login modal there is Already have an account?, I want to open register modal and close login modal when someone clicks on this!

I tried using useState but it isn’t working! Maybe I am using useStates incorrectly!

2

Answers


  1. You can control whether it will be open or closed from the parent component.

    const ParentComp = () => {
        const [open, setOpen] = useState(false);
        return (
          <div>
            <Button onClick={() => setOpen(true)}>Open popover</Button>
            <LoginModal open={open} setOpen={setOpen} />
          </div>
        );
      };
    
    export function LoginModal({ open, setOpen}) {
      return (
        <Dialog open={open} onClose={() => setOpen(false)}
          ....
        </Dialog>
      );
    }
    
    Login or Signup to reply.
  2. You don’t need to close the login modal and open the registration modal to show the registration form. You can show both forms (login and registration) in one modal and show the appropriate form based on the user’s choice:

    type AuhModeType = "login" | "register";
    
    interface FormPropsType {
      handleShowForm: (mode: AuhModeType) => void;
    }
    
    export function AuthModal() {
      const [mode, setMode] = useState<AuhModeType>("login");
      const handleShowForm = (formMode: AuhModeType) => {
        setMode(formMode);
      };
      return (
        <Dialog>
          <DialogTrigger>Avatar</DialogTrigger>
          <DialogContent>
            {mode === "login" ? (
              <LoginFormMode handleShowForm={handleShowForm} />
            ) : (
              <RegisterFormMode handleShowForm={handleShowForm} />
            )}
          </DialogContent>
        </Dialog>
      );
    }
    function LoginFormMode({ handleShowForm }: FormPropsType) {
      return (
        <Card className="w-[400px] shadow-md">
          <CardContent>
            <LoginForm />
          </CardContent>
          <CardFooter>
            <Button
              size="lg"
              className="w-full"
              variant="outline"
              onClick={() => handleShowForm("register")}
            >
              Don&apos;t have an account?
            </Button>
          </CardFooter>
        </Card>
      );
    }
    function RegisterFormMode({ handleShowForm }: FormPropsType) {
      return (
        <Card className="w-[400px] shadow-md">
          <CardContent>
            <RegisterForm />
          </CardContent>
          <CardFooter>
            <Button
              size="lg"
              className="w-full"
              variant="outline"
              onClick={() => handleShowForm("login")}
            >
              have an account?
            </Button>
          </CardFooter>
        </Card>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search