Next.js Discord

Discord Forum

Errors with sign in button component

Unanswered
ahmoin posted this in #help-forum
Open in Discord
I am using the [shadcn ui responsive drawer component](https://ui.shadcn.com/docs/components/drawer) and tailwindcss which renders a Dialog component on desktop and a Drawer on mobile.

I have a continue with Google button component which works on the sign up page but not in the sign in button component which contains the drawer and dialog

Errors:
app-index.js:33 Warning: Cannot update a component (`Router`) while rendering a different component (`proxy`). To locate the bad setState() call inside `proxy`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at proxy
    at div
    at ProfileForm (webpack-internal:///(app-pages-browser)/./src/components/sign-in-button.tsx:242:11)
    at div
    at eval (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/@radix-ui+react-primitive@2.0.0_@types+react-dom@18.3.0_@types+react@18.3.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@radix-ui/react-primitive/dist/index.mjs:36:13)

Uncaught Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
    at trackUsedThenable (react-dom.development.js:9157:19)
    at useThenable (react-dom.development.js:11483:16)

The above error occurred in the <Router> component:

    at Router (


Video of how I want it to work (sign in with google button doesn't work):

2 Replies

sign-in-button.tsx:

import * as React from "react";

import { ContinueWithGoogleButton } from "@/components/continue-with-google-button";

export function SignInButton() {
  const [open, setOpen] = React.useState(false);
  const isDesktop = useMediaQuery("(min-width: 768px)");

  if (isDesktop) {
    return (
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogTrigger asChild>
          <Button variant={"outline"}>Sign In</Button>
        </DialogTrigger>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle>Sign In</DialogTitle>
          </DialogHeader>
          <div className="flex flex-row items-center justify-center">
            <ContinueWithGoogleButton />
          </div>
          <ProfileForm />
        </DialogContent>
      </Dialog>
    );
  }

  return (
    <Drawer open={open} onOpenChange={setOpen}>
      <DrawerTrigger asChild>
        <Button variant={"outline"}>Sign In</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader />
        <div className="flex flex-row items-center justify-center mb-4">
          <ContinueWithGoogleButton />
        </div>
        <ProfileForm className="px-4" />
      </DrawerContent>
    </Drawer>
  );
}

function ProfileForm({ className }: React.ComponentProps<"form">) {
  return (
    <form className={cn("grid items-start gap-4", className)}>
      <div className="grid gap-2">
        <Label htmlFor="email">Email</Label>
        <Input
          id="email"
          type="email"
          required={true}
          placeholder="ahsan@example.com"
        />
      </div>
      <div className="grid gap-2">
        <Label htmlFor="username">Password</Label>
        <Input id="password" type="password" minLength={8} required={true} />
      </div>
      <Button type="submit">Sign in</Button>
    </form>
  );
}
continue-with-google-button.tsx:
"use server";

import { signIn } from "@/lib/auth";

export async function ContinueWithGoogleButton() {
  return (
    <form
      action={async () => {
        "use server";

        await signIn("google", {
          redirectTo: "/",
        });
      }}
      className="max-w-min"
    >
      <Button size={"lg"}>
        <Icons.google className="mr-2 h-4 w-4" />
        Continue with Google
      </Button>
    </form>
  );
}


use-media-query.ts:
import * as React from "react";

export function useMediaQuery(query: string) {
  const [value, setValue] = React.useState(false);

  React.useEffect(() => {
    function onChange(event: MediaQueryListEvent) {
      setValue(event.matches);
    }

    const result = matchMedia(query);
    result.addEventListener("change", onChange);
    setValue(result.matches);

    return () => result.removeEventListener("change", onChange);
  }, [query]);

  return value;
}