Victor Mesquita

Uai Blocks Sign-in Card

Component

About

A compound sign-in form with providers, credentials, recovery, and async feedback.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Uai Blocks Sign-in Card to your project and fits it to your theme.

Code

How Uai Blocks Sign-in Card is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";
import {ThemeProvider as LibraryDemoThemeProvider} from "next-themes";
"use client";

import { Building2, Code2 } from "lucide-react";
import { type FormEvent, useEffect, useRef, useState } from "react";
import {
  SignInCard,
  SignInCardBody,
  SignInCardDescription,
  SignInCardDivider,
  SignInCardError,
  SignInCardField,
  SignInCardFieldMessage,
  SignInCardFields,
  SignInCardFooter,
  SignInCardHeader,
  SignInCardInput,
  SignInCardLabel,
  SignInCardOptions,
  SignInCardProvider,
  SignInCardProviders,
  type SignInCardStatus,
  SignInCardSubmit,
  SignInCardTitle,
  type SignInCardVariant,
} from "@/components/ui/uai-sign-in-card";

export function SignInCardPreview({ variant = "card" }: { variant?: SignInCardVariant }) {
  const [status, setStatus] = useState<SignInCardStatus>("idle");
  const timerRef = useRef<number | null>(null);

  useEffect(
    () => () => {
      if (timerRef.current) window.clearTimeout(timerRef.current);
    },
    [],
  );

  function finishAuthentication(success: boolean) {
    if (timerRef.current) window.clearTimeout(timerRef.current);
    setStatus("submitting");
    timerRef.current = window.setTimeout(() => {
      setStatus(success ? "idle" : "error");
    }, 800);
  }

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const password = new FormData(event.currentTarget).get("password");
    finishAuthentication(password === "preview");
  }

  return (
    <div
      className={
        variant === "split"
          ? "w-full max-w-[680px]"
          : variant === "compact"
            ? "w-full max-w-[320px]"
            : "w-full max-w-[380px]"
      }
    >
      <SignInCard variant={variant} status={status} onSubmit={handleSubmit}>
        <SignInCardHeader>
          <SignInCardTitle>Welcome back</SignInCardTitle>
          <SignInCardDescription>Sign in to continue to your workspace.</SignInCardDescription>
        </SignInCardHeader>
        <SignInCardBody>
          <SignInCardProviders>
            <SignInCardProvider onClick={() => finishAuthentication(true)}>
              <Building2 strokeWidth={1.8} aria-hidden="true" />
              Continue with SSO
            </SignInCardProvider>
            <SignInCardProvider onClick={() => finishAuthentication(true)}>
              <Code2 strokeWidth={1.8} aria-hidden="true" />
              Continue with GitHub
            </SignInCardProvider>
          </SignInCardProviders>
          <SignInCardDivider />
          <SignInCardFields>
            <SignInCardField>
              <SignInCardLabel>Email</SignInCardLabel>
              <SignInCardInput
                name="email"
                type="email"
                autoComplete="email"
                defaultValue="hello@acme.co"
                required
              />
            </SignInCardField>
            <SignInCardField invalid={status === "error"}>
              <SignInCardLabel>Password</SignInCardLabel>
              <SignInCardInput
                name="password"
                revealable
                autoComplete="current-password"
                defaultValue="preview"
                required
              />
              {status === "error" ? (
                <SignInCardFieldMessage>
                  That password did not match. Enter “preview” and try again.
                </SignInCardFieldMessage>
              ) : null}
            </SignInCardField>
            <SignInCardOptions>
              <label>
                <input type="checkbox" name="remember" defaultChecked /> Remember me
              </label>
              <a href="#recovery">Forgot password?</a>
            </SignInCardOptions>
            <SignInCardError>
              We could not sign you in. Check your details and try again.
            </SignInCardError>
            <SignInCardSubmit>{status === "error" ? "Try again" : "Sign in"}</SignInCardSubmit>
          </SignInCardFields>
        </SignInCardBody>
        <SignInCardFooter>
          New here? <a href="#sign-up">Create an account</a>
        </SignInCardFooter>
      </SignInCard>
    </div>
  );
}

function SourceSpecimen(){return <SignInCardPreview/>}
export default function LibraryRegistryPreview(){return <LibraryDemoThemeProvider defaultTheme="dark" enableSystem={false}><div data-component-demo data-demo-theme="dark" data-theme="dark" className="dark" style={{background:"var(--background)",color:"var(--foreground)"}}><div className="relative w-full min-w-0 max-w-5xl min-h-[400px] flex items-center justify-center"><SourceSpecimen/></div></div></LibraryDemoThemeProvider>}

Dependencies

More by Victor Mesquita

View all
  • Data Table Toolbar

    Data Table Toolbar

    2
  • Uai Blocks Resource Manager

    Uai Blocks Resource Manager

  • Uai Blocks Response Status

    Uai Blocks Response Status

  • Uai Blocks Data Explorer

    Uai Blocks Data Explorer

  • Uai Blocks Order Status

    Uai Blocks Order Status

  • Uai Blocks CEP Field

    Uai Blocks CEP Field

  • Uai Blocks Community Feed

    Uai Blocks Community Feed

  • Dashboard Shell

    Dashboard Shell