← back to Ken

src/app/page.js

86 lines

'use client';
import { useState, useEffect } from 'react';

export default function LoginPage() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('/api/health').then(r => r.json()).then(d => {
      if (d.authenticated) window.location.href = '/dashboard';
      else setLoading(false);
    }).catch(() => setLoading(false));
  }, []);

  async function handleLogin(e) {
    e.preventDefault();
    setError('');
    const res = await fetch('/api/health', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password })
    });
    const data = await res.json();
    if (data.token) {
      document.cookie = `bertha_token=${data.token}; path=/; max-age=${7*86400}`;
      window.location.href = '/dashboard';
    } else {
      setError(data.error || 'Login failed');
    }
  }

  if (loading) return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="animate-spin w-8 h-8 border-2 border-blue-500 border-t-transparent rounded-full" />
    </div>
  );

  return (
    <div className="min-h-screen flex items-center justify-center p-4">
      <div className="w-full max-w-md">
        <div className="text-center mb-8">
          <div className="inline-flex items-center justify-center w-20 h-20 rounded-2xl mb-4" style={{ background: 'linear-gradient(135deg, #3b82f6, #8b5cf6)' }}>
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/>
              <circle cx="12" cy="12" r="3"/>
            </svg>
          </div>
          <h1 className="text-3xl font-extrabold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">BERTHA</h1>
          <p className="text-gray-400 mt-2 text-sm">Weather Forecast Micro-Betting System</p>
          <p className="text-gray-500 text-xs mt-1">Polymarket Edge Detection + Risk Management</p>
        </div>

        <form onSubmit={handleLogin} className="card space-y-4">
          {error && <div className="text-red-400 text-sm bg-red-500/10 rounded-lg p-3">{error}</div>}
          <div>
            <label className="block text-xs font-medium text-gray-400 mb-1.5">Username</label>
            <input type="text" value={username} onChange={e => setUsername(e.target.value)} required
              className="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-3 py-2.5 text-sm focus:outline-none focus:border-blue-500 transition" placeholder="admin" />
          </div>
          <div>
            <label className="block text-xs font-medium text-gray-400 mb-1.5">Password</label>
            <input type="password" value={password} onChange={e => setPassword(e.target.value)} required
              className="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-3 py-2.5 text-sm focus:outline-none focus:border-blue-500 transition" placeholder="Enter password" />
          </div>
          <button type="submit" className="btn btn-primary w-full py-2.5">Sign In</button>
        </form>

        <div className="mt-6 grid grid-cols-3 gap-2 text-center">
          {[
            { label: 'Bankroll', value: '$50', color: 'text-green-400' },
            { label: 'Mode', value: 'Paper', color: 'text-yellow-400' },
            { label: 'Status', value: 'Active', color: 'text-blue-400' }
          ].map(s => (
            <div key={s.label} className="card !p-3">
              <div className={`text-lg font-bold ${s.color}`}>{s.value}</div>
              <div className="text-[10px] text-gray-500 uppercase">{s.label}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}