← Components/Authentication

LoginForm

loginform-1779379671410.tsx
'use client'
import { useState } from 'react'

export default function LoginForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [showPw, setShowPw] = useState(false)
  const [remember, setRemember] = useState(false)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')
  const [success, setSuccess] = useState(false)

  async function submit(e: React.FormEvent) {
    e.preventDefault()
    if (!email || !password) { setError('Please fill in all fields.'); return }
    if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(email)) { setError('Invalid email address.'); return }
    setLoading(true); setError('')
    await new Promise(r => setTimeout(r, 1500))
    if (password === 'wrong') { setError('Invalid email or password.'); setLoading(false); return }
    setSuccess(true); setLoading(false)
  }

  if (success) return (
    <div style={{ padding: 40, background: '#0A0A0A', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: 400 }}>
      <div style={{ textAlign: 'center' }}>
        <div style={{ fontSize: 52, marginBottom: 12 }}>✅</div>
        <div style={{ color: '#F5F5F0', fontSize: 20, fontWeight: 700, marginBottom: 6 }}>Welcome back!</div>
        <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13 }}>Redirecting to dashboard...</div>
        <button onClick={() => setSuccess(false)} style={{ marginTop: 16, color: '#C9A84C', background: 'none', border: 'none', cursor: 'pointer', fontSize: 13 }}>Back to login</button>
      </div>
    </div>
  )

  return (
    <div style={{ padding: 40, background: '#0A0A0A', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: 400 }}>
      <div style={{ width: 360 }}>
        <div style={{ textAlign: 'center', marginBottom: 32 }}>
          <div style={{ width: 48, height: 48, borderRadius: 14, background: 'linear-gradient(135deg, #C9A84C, #6366f1)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px', fontSize: 22 }}>⬡</div>
          <div style={{ color: '#F5F5F0', fontSize: 22, fontWeight: 800 }}>Welcome back</div>
          <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 14, marginTop: 4 }}>Sign in to your Empire UI account</div>
        </div>

        {/* OAuth */}
        <div style={{ display: 'flex', gap: 8, marginBottom: 24 }}>
          {[{ icon: '🔵', label: 'GitHub' }, { icon: '🔴', label: 'Google' }].map(p => (
            <button key={p.label} style={{ flex: 1, background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.1)', color: '#F5F5F0', borderRadius: 10, padding: '10px', cursor: 'pointer', fontSize: 13, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
              <span>{p.icon}</span>{p.label}
            </button>
          ))}
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 24 }}>
          <div style={{ flex: 1, height: 1, background: 'rgba(255,255,255,0.08)' }} />
          <span style={{ color: 'rgba(255,255,255,0.25)', fontSize: 12 }}>or continue with email</span>
          <div style={{ flex: 1, height: 1, background: 'rgba(255,255,255,0.08)' }} />
        </div>

        <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {error && <div style={{ background: 'rgba(239,68,68,0.1)', border: '1px solid rgba(239,68,68,0.25)', color: '#ef4444', borderRadius: 8, padding: '10px 14px', fontSize: 13 }}>{error}</div>}

          <input type="email" placeholder="Email address" value={email} onChange={e => { setEmail(e.target.value); setError('') }}
            style={{ background: 'rgba(255,255,255,0.04)', border: '1.5px solid rgba(255,255,255,0.1)', borderRadius: 10, color: '#F5F5F0', fontSize: 14, padding: '12px 14px', outline: 'none' }} />

          <div style={{ position: 'relative' }}>
            <input type={showPw ? 'text' : 'password'} placeholder="Password" value={password} onChange={e => { setPassword(e.target.value); setError('') }}
              style={{ width: '100%', boxSizing: 'border-box', background: 'rgba(255,255,255,0.04)', border: '1.5px solid rgba(255,255,255,0.1)', borderRadius: 10, color: '#F5F5F0', fontSize: 14, padding: '12px 44px 12px 14px', outline: 'none' }} />
            <button type="button" onClick={() => setShowPw(s => !s)} style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', fontSize: 16, color: 'rgba(255,255,255,0.3)' }}>
              {showPw ? '🙈' : '👁'}
            </button>
          </div>

          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}>
              <div onClick={() => setRemember(r => !r)} style={{ width: 18, height: 18, borderRadius: 4, border: '1.5px solid', borderColor: remember ? '#C9A84C' : 'rgba(255,255,255,0.2)', background: remember ? '#C9A84C' : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', transition: 'all 0.2s' }}>
                {remember && <span style={{ color: '#0A0A0A', fontSize: 12, fontWeight: 900 }}>✓</span>}
              </div>
              <span style={{ color: 'rgba(255,255,255,0.5)', fontSize: 13 }}>Remember me</span>
            </label>
            <button type="button" style={{ background: 'none', border: 'none', color: '#C9A84C', cursor: 'pointer', fontSize: 13 }}>Forgot password?</button>
          </div>

          <button type="submit" disabled={loading} style={{ background: loading ? 'rgba(255,255,255,0.08)' : '#C9A84C', color: loading ? 'rgba(255,255,255,0.3)' : '#0A0A0A', border: 'none', borderRadius: 10, padding: '13px', cursor: loading ? 'default' : 'pointer', fontWeight: 800, fontSize: 14, transition: 'all 0.2s', marginTop: 4 }}>
            {loading ? 'Signing in...' : 'Sign in'}
          </button>
        </form>

        <div style={{ textAlign: 'center', marginTop: 20, color: 'rgba(255,255,255,0.4)', fontSize: 13 }}>
          No account? <span style={{ color: '#C9A84C', cursor: 'pointer' }}>Sign up free</span>
        </div>
        <div style={{ textAlign: 'center', marginTop: 6, color: 'rgba(255,255,255,0.2)', fontSize: 11 }}>Hint: any email + password works (use "wrong" to test error)</div>
      </div>
    </div>
  )
}

Component info

CategoryAuthentication
Frameworkreact
TierFREE
Views0
Copies0

About

Dark login form with social OAuth buttons, remember me toggle, password show/hide, and error states

More from Authentication

'use client';

import React, { useState } from 'react';

interface LoginFormProps {
  onSubmit: (email: string, password: string) => void;
}

const LoginForm: React.FC<LoginFormProps> = ({ onSubmit }) => {
  const [email, setEmail] = useState('');
  
LoginForm
Authentication
'use client';

import { useState } from 'react';

interface SignupFormProps {
  // No props for this component
}

const SignupForm: React.FC<SignupFormProps> = () => {
  const [step, setStep] = useState(1);
  const [email, setEmail] = useState('');
 
SignupForm
Authentication
'use client';

import React, { useState } from 'react';

interface ForgotPasswordProps {
  // No props needed for this component
}

const ForgotPassword: React.FC<ForgotPasswordProps> = () => {
  const [email, setEmail] = useState('');
  const [isSub
ForgotPassword
Authentication
'use client'
import { useState } from 'react'

type State = 'idle' | 'sending' | 'sent' | 'error'

export default function MagicLinkAuth() {
  const [email, setEmail] = useState('')
  const [state, setState] = useState<State>('idle')

  async functio
MagicLinkAuth
Authentication