File size: 4,116 Bytes
c3c70f8
 
 
 
 
 
 
 
 
0ef5c60
 
 
 
 
 
 
c3c70f8
 
0ef5c60
c3c70f8
 
 
 
0ef5c60
c3c70f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ef5c60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c3c70f8
0ef5c60
 
 
 
 
 
 
 
 
 
 
 
c3c70f8
0ef5c60
 
c3c70f8
0ef5c60
 
 
 
 
 
 
 
 
c3c70f8
0ef5c60
 
c3c70f8
 
 
 
 
 
 
0ef5c60
c3c70f8
 
0ef5c60
 
 
 
c3c70f8
 
 
 
 
 
0ef5c60
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// web/src/components/LoginScreen.tsx
import React, { useState } from "react";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Label } from "./ui/label";
import { Card } from "./ui/card";
import clareAvatar from "../assets/dfe44dab3ad8cd93953eac4a3e68bd1a5f999653.png";
import type { User } from "../App";
import { apiLogin } from "../lib/api";

interface LoginScreenProps {
  onLogin: (user: User) => void;
}

export function LoginScreen({ onLogin }: LoginScreenProps) {
  const [showForm, setShowForm] = useState(false);
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");

  const [submitting, setSubmitting] = useState(false);
  const [err, setErr] = useState<string | null>(null);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setErr(null);

    const n = name.trim();
    const u = email.trim();
    if (!n || !u) return;

    setSubmitting(true);
    try {
      // backend expects: { name, user_id }
      const resp = await apiLogin({ name: n, user_id: u });

      // api.ts returns { ok: true/false ... }
      if ((resp as any)?.ok !== true) {
        const msg = (resp as any)?.error || "Login failed";
        setErr(msg);
        return;
      }

      onLogin({ name: n, email: u });
    } catch (e: any) {
      setErr(e?.message || "Login failed");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="min-h-screen bg-background flex items-center justify-center p-4">
      <Card className="w-full max-w-md p-8">
        <div className="flex flex-col items-center space-y-6">
          <div className="w-24 h-24 rounded-full overflow-hidden bg-white flex items-center justify-center">
            <img src={clareAvatar} alt="Clare AI" className="w-full h-full object-cover" />
          </div>

          <div className="text-center space-y-2">
            <h1 className="text-2xl">Welcome to Clare</h1>
            <p className="text-sm text-muted-foreground">
              Your AI teaching assistant for personalized learning
            </p>
          </div>

          {!showForm ? (
            <Button onClick={() => setShowForm(true)} className="w-full" size="lg">
              Sign In
            </Button>
          ) : (
            <form onSubmit={handleSubmit} className="w-full space-y-4">
              <div className="space-y-2">
                <Label htmlFor="login-name">Name</Label>
                <Input
                  id="login-name"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  placeholder="Enter your name"
                  required
                  disabled={submitting}
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="login-email">Email / Student ID</Label>
                <Input
                  id="login-email"
                  type="email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  placeholder="Enter your email or ID"
                  required
                  disabled={submitting}
                />
              </div>

              {err && (
                <div className="text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md p-2">
                  {err}
                </div>
              )}

              <div className="flex gap-2">
                <Button type="submit" className="flex-1" disabled={submitting}>
                  {submitting ? "Signing in..." : "Enter"}
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => {
                    if (submitting) return;
                    setShowForm(false);
                    setErr(null);
                  }}
                  disabled={submitting}
                >
                  Cancel
                </Button>
              </div>
            </form>
          )}
        </div>
      </Card>
    </div>
  );
}