SarahXia0405 commited on
Commit
74c282e
·
verified ·
1 Parent(s): 8c6e3e1

Update web/src/components/RightPanel.tsx

Browse files
Files changed (1) hide show
  1. web/src/components/RightPanel.tsx +75 -88
web/src/components/RightPanel.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState } from 'react';
2
  import { Button } from './ui/button';
3
  import { Input } from './ui/input';
@@ -9,19 +10,11 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
9
  import { LogIn, LogOut, FileText, MessageSquare } from 'lucide-react';
10
  import type { User } from '../App';
11
  import { toast } from 'sonner';
12
- import {
13
- Dialog,
14
- DialogContent,
15
- DialogDescription,
16
- DialogHeader,
17
- DialogTitle,
18
- DialogTrigger,
19
- DialogFooter,
20
- } from './ui/dialog';
21
 
22
  interface RightPanelProps {
23
  user: User | null;
24
- onLogin: (payload: { name: string; email: string }) => Promise<void> | void;
25
  onLogout: () => void;
26
  isLoggedIn: boolean;
27
  onClose?: () => void;
@@ -30,6 +23,10 @@ interface RightPanelProps {
30
  setExportResult: (result: string) => void;
31
  resultType: 'export' | 'quiz' | 'summary' | null;
32
  setResultType: (type: 'export' | 'quiz' | 'summary' | null) => void;
 
 
 
 
33
  }
34
 
35
  export function RightPanel({
@@ -38,9 +35,10 @@ export function RightPanel({
38
  onLogout,
39
  isLoggedIn,
40
  exportResult,
41
- setExportResult,
42
  resultType,
43
- setResultType,
 
 
44
  }: RightPanelProps) {
45
  const [showLoginForm, setShowLoginForm] = useState(false);
46
  const [name, setName] = useState('');
@@ -50,28 +48,22 @@ export function RightPanel({
50
  const [feedbackText, setFeedbackText] = useState('');
51
  const [feedbackCategory, setFeedbackCategory] = useState<'general' | 'bug' | 'feature'>('general');
52
 
53
- const handleLoginClick = async () => {
54
  if (!name.trim() || !email.trim()) {
55
  toast.error('Please fill in all fields');
56
  return;
57
  }
58
- await onLogin({ name: name.trim(), email: email.trim() });
59
  setShowLoginForm(false);
60
  setName('');
61
  setEmail('');
62
  };
63
 
64
- const handleLogout = () => {
65
- onLogout();
66
- setShowLoginForm(false);
67
- };
68
-
69
  const handleFeedbackSubmit = () => {
70
  if (!feedbackText.trim()) {
71
  toast.error('Please provide feedback text');
72
  return;
73
  }
74
- // MVP: keep console log; next step we can POST to /api/feedback
75
  console.log('Feedback submitted:', feedbackText, feedbackCategory);
76
  setFeedbackDialogOpen(false);
77
  setFeedbackText('');
@@ -80,16 +72,10 @@ export function RightPanel({
80
 
81
  return (
82
  <div className="flex-1 overflow-auto p-4 space-y-4">
83
- {/* Login Section */}
84
  <Card className="p-4">
85
  {!isLoggedIn ? (
86
  <div className="space-y-4">
87
  <div className="flex flex-col items-center py-4">
88
- <img
89
- src="https://images.unsplash.com/photo-1588912914049-d2664f76a947?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxzdHVkZW50JTIwc3R1ZHlpbmclMjBpbGx1c3RyYXRpb258ZW58MXx8fHwxNzY2MDY2NjcyfDA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral"
90
- alt="Student studying"
91
- className="w-20 h-20 rounded-full object-cover mb-4"
92
- />
93
  <h3 className="mb-2">Welcome to Clare!</h3>
94
  <p className="text-sm text-muted-foreground text-center mb-4">
95
  Log in to start your personalized learning journey
@@ -105,24 +91,20 @@ export function RightPanel({
105
  <div className="space-y-3">
106
  <div className="space-y-2">
107
  <Label htmlFor="name">Name</Label>
108
- <Input
109
- id="name"
110
- value={name}
111
- onChange={(e) => setName(e.target.value)}
112
- placeholder="Enter your name"
113
- />
114
  </div>
115
  <div className="space-y-2">
116
  <Label htmlFor="email">Email / Student ID</Label>
117
  <Input
118
  id="email"
 
119
  value={email}
120
  onChange={(e) => setEmail(e.target.value)}
121
  placeholder="Enter your email or ID"
122
  />
123
  </div>
124
  <div className="flex gap-2">
125
- <Button onClick={handleLoginClick} className="flex-1">
126
  Enter
127
  </Button>
128
  <Button variant="outline" onClick={() => setShowLoginForm(false)}>
@@ -136,14 +118,27 @@ export function RightPanel({
136
  <div className="space-y-4">
137
  <div className="flex items-center gap-3">
138
  <div className="w-12 h-12 rounded-full bg-gradient-to-br from-purple-500 to-blue-500 flex items-center justify-center text-white">
139
- {user?.name?.charAt(0)?.toUpperCase() ?? 'U'}
140
  </div>
141
  <div className="flex-1 min-w-0">
142
  <h4 className="truncate">{user?.name}</h4>
143
  <p className="text-sm text-muted-foreground truncate">{user?.email}</p>
144
  </div>
145
  </div>
146
- <Button variant="destructive" onClick={handleLogout} className="w-full gap-2">
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  <LogOut className="h-4 w-4" />
148
  Log Out
149
  </Button>
@@ -153,7 +148,6 @@ export function RightPanel({
153
 
154
  <Separator />
155
 
156
- {/* Results Section */}
157
  <div className="space-y-3">
158
  <h3>
159
  {resultType === 'export' && 'Exported Conversation'}
@@ -161,7 +155,6 @@ export function RightPanel({
161
  {resultType === 'summary' && 'Summarization'}
162
  {!resultType && 'Results'}
163
  </h3>
164
-
165
  <Card className="p-4 min-h-[200px] bg-muted/30">
166
  {exportResult ? (
167
  <div className="space-y-3">
@@ -182,7 +175,7 @@ export function RightPanel({
182
  </div>
183
  ) : (
184
  <div className="flex items-center justify-center h-full text-sm text-muted-foreground text-left">
185
- Results (export / summary / quiz) will appear here after using the actions
186
  </div>
187
  )}
188
  </Card>
@@ -190,62 +183,56 @@ export function RightPanel({
190
 
191
  <Separator />
192
 
193
- {/* Feedback Section */}
194
  <div className="space-y-3">
195
  <h3>Feedback</h3>
196
- <Dialog open={feedbackDialogOpen} onOpenChange={setFeedbackDialogOpen}>
197
- <DialogTrigger asChild>
198
- <Button variant="outline" className="w-full justify-start gap-2">
199
- <MessageSquare className="h-4 w-4" />
200
- Provide Feedback
201
- </Button>
202
- </DialogTrigger>
203
-
204
- <DialogContent className="sm:max-w-[425px]">
205
- <DialogHeader>
206
- <DialogTitle>Provide Feedback</DialogTitle>
207
- <DialogDescription>Help us improve Clare by sharing your thoughts and suggestions.</DialogDescription>
208
- </DialogHeader>
209
 
210
- <div className="space-y-3">
211
- <div className="space-y-2">
212
- <Label htmlFor="feedbackCategory">Category</Label>
213
- <Select
214
- value={feedbackCategory}
215
- onValueChange={(value) => setFeedbackCategory(value as 'general' | 'bug' | 'feature')}
216
- >
217
- <SelectTrigger>
218
- <SelectValue placeholder="Select a category" />
219
- </SelectTrigger>
220
- <SelectContent>
221
- <SelectItem value="general">General Feedback</SelectItem>
222
- <SelectItem value="bug">Bug Report</SelectItem>
223
- <SelectItem value="feature">Feature Request</SelectItem>
224
- </SelectContent>
225
- </Select>
226
- </div>
 
 
 
 
227
 
228
- <div className="space-y-2">
229
- <Label htmlFor="feedbackText">Feedback</Label>
230
- <Textarea
231
- id="feedbackText"
232
- value={feedbackText}
233
- onChange={(e) => setFeedbackText(e.target.value)}
234
- placeholder="Enter your feedback here..."
235
- className="min-h-[100px]"
236
- />
237
- </div>
238
  </div>
 
239
 
240
- <DialogFooter>
241
- <Button variant="outline" onClick={() => setFeedbackDialogOpen(false)}>
242
- Cancel
243
- </Button>
244
- <Button onClick={handleFeedbackSubmit}>Submit</Button>
245
- </DialogFooter>
246
- </DialogContent>
247
- </Dialog>
248
- </div>
249
  </div>
250
  );
251
  }
 
1
+ // web/src/components/RightPanel.tsx
2
  import React, { useState } from 'react';
3
  import { Button } from './ui/button';
4
  import { Input } from './ui/input';
 
10
  import { LogIn, LogOut, FileText, MessageSquare } from 'lucide-react';
11
  import type { User } from '../App';
12
  import { toast } from 'sonner';
13
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from './ui/dialog';
 
 
 
 
 
 
 
 
14
 
15
  interface RightPanelProps {
16
  user: User | null;
17
+ onLogin: (user: User) => void;
18
  onLogout: () => void;
19
  isLoggedIn: boolean;
20
  onClose?: () => void;
 
23
  setExportResult: (result: string) => void;
24
  resultType: 'export' | 'quiz' | 'summary' | null;
25
  setResultType: (type: 'export' | 'quiz' | 'summary' | null) => void;
26
+
27
+ onExport: () => void;
28
+ onQuiz: () => void;
29
+ onSummary: () => void;
30
  }
31
 
32
  export function RightPanel({
 
35
  onLogout,
36
  isLoggedIn,
37
  exportResult,
 
38
  resultType,
39
+ onExport,
40
+ onQuiz,
41
+ onSummary,
42
  }: RightPanelProps) {
43
  const [showLoginForm, setShowLoginForm] = useState(false);
44
  const [name, setName] = useState('');
 
48
  const [feedbackText, setFeedbackText] = useState('');
49
  const [feedbackCategory, setFeedbackCategory] = useState<'general' | 'bug' | 'feature'>('general');
50
 
51
+ const handleLogin = () => {
52
  if (!name.trim() || !email.trim()) {
53
  toast.error('Please fill in all fields');
54
  return;
55
  }
56
+ onLogin({ name: name.trim(), email: email.trim() });
57
  setShowLoginForm(false);
58
  setName('');
59
  setEmail('');
60
  };
61
 
 
 
 
 
 
62
  const handleFeedbackSubmit = () => {
63
  if (!feedbackText.trim()) {
64
  toast.error('Please provide feedback text');
65
  return;
66
  }
 
67
  console.log('Feedback submitted:', feedbackText, feedbackCategory);
68
  setFeedbackDialogOpen(false);
69
  setFeedbackText('');
 
72
 
73
  return (
74
  <div className="flex-1 overflow-auto p-4 space-y-4">
 
75
  <Card className="p-4">
76
  {!isLoggedIn ? (
77
  <div className="space-y-4">
78
  <div className="flex flex-col items-center py-4">
 
 
 
 
 
79
  <h3 className="mb-2">Welcome to Clare!</h3>
80
  <p className="text-sm text-muted-foreground text-center mb-4">
81
  Log in to start your personalized learning journey
 
91
  <div className="space-y-3">
92
  <div className="space-y-2">
93
  <Label htmlFor="name">Name</Label>
94
+ <Input id="name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter your name" />
 
 
 
 
 
95
  </div>
96
  <div className="space-y-2">
97
  <Label htmlFor="email">Email / Student ID</Label>
98
  <Input
99
  id="email"
100
+ type="email"
101
  value={email}
102
  onChange={(e) => setEmail(e.target.value)}
103
  placeholder="Enter your email or ID"
104
  />
105
  </div>
106
  <div className="flex gap-2">
107
+ <Button onClick={handleLogin} className="flex-1">
108
  Enter
109
  </Button>
110
  <Button variant="outline" onClick={() => setShowLoginForm(false)}>
 
118
  <div className="space-y-4">
119
  <div className="flex items-center gap-3">
120
  <div className="w-12 h-12 rounded-full bg-gradient-to-br from-purple-500 to-blue-500 flex items-center justify-center text-white">
121
+ {user?.name?.charAt(0).toUpperCase()}
122
  </div>
123
  <div className="flex-1 min-w-0">
124
  <h4 className="truncate">{user?.name}</h4>
125
  <p className="text-sm text-muted-foreground truncate">{user?.email}</p>
126
  </div>
127
  </div>
128
+
129
+ <div className="grid grid-cols-3 gap-2">
130
+ <Button variant="outline" onClick={onExport} className="text-xs" disabled={!isLoggedIn}>
131
+ Export
132
+ </Button>
133
+ <Button variant="outline" onClick={onSummary} className="text-xs" disabled={!isLoggedIn}>
134
+ Summary
135
+ </Button>
136
+ <Button variant="outline" onClick={onQuiz} className="text-xs" disabled={!isLoggedIn}>
137
+ Quiz
138
+ </Button>
139
+ </div>
140
+
141
+ <Button variant="destructive" onClick={onLogout} className="w-full gap-2">
142
  <LogOut className="h-4 w-4" />
143
  Log Out
144
  </Button>
 
148
 
149
  <Separator />
150
 
 
151
  <div className="space-y-3">
152
  <h3>
153
  {resultType === 'export' && 'Exported Conversation'}
 
155
  {resultType === 'summary' && 'Summarization'}
156
  {!resultType && 'Results'}
157
  </h3>
 
158
  <Card className="p-4 min-h-[200px] bg-muted/30">
159
  {exportResult ? (
160
  <div className="space-y-3">
 
175
  </div>
176
  ) : (
177
  <div className="flex items-center justify-center h-full text-sm text-muted-foreground text-left">
178
+ Results (export / summary / quiz) will appear here after using the buttons above
179
  </div>
180
  )}
181
  </Card>
 
183
 
184
  <Separator />
185
 
 
186
  <div className="space-y-3">
187
  <h3>Feedback</h3>
188
+ <Button variant="outline" className="w-full justify-start gap-2" onClick={() => setFeedbackDialogOpen(true)}>
189
+ <MessageSquare className="h-4 w-4" />
190
+ Provide Feedback
191
+ </Button>
192
+ </div>
 
 
 
 
 
 
 
 
193
 
194
+ <Dialog open={feedbackDialogOpen} onOpenChange={setFeedbackDialogOpen}>
195
+ <DialogContent className="sm:max-w-[425px]">
196
+ <DialogHeader>
197
+ <DialogTitle>Provide Feedback</DialogTitle>
198
+ <DialogDescription>Help us improve Clare by sharing your thoughts and suggestions.</DialogDescription>
199
+ </DialogHeader>
200
+
201
+ <div className="space-y-3">
202
+ <div className="space-y-2">
203
+ <Label htmlFor="feedbackCategory">Category</Label>
204
+ <Select value={feedbackCategory} onValueChange={(value) => setFeedbackCategory(value as any)}>
205
+ <SelectTrigger>
206
+ <SelectValue placeholder="Select a category" />
207
+ </SelectTrigger>
208
+ <SelectContent>
209
+ <SelectItem value="general">General Feedback</SelectItem>
210
+ <SelectItem value="bug">Bug Report</SelectItem>
211
+ <SelectItem value="feature">Feature Request</SelectItem>
212
+ </SelectContent>
213
+ </Select>
214
+ </div>
215
 
216
+ <div className="space-y-2">
217
+ <Label htmlFor="feedbackText">Feedback</Label>
218
+ <Textarea
219
+ id="feedbackText"
220
+ value={feedbackText}
221
+ onChange={(e) => setFeedbackText(e.target.value)}
222
+ placeholder="Enter your feedback here..."
223
+ className="min-h-[100px]"
224
+ />
 
225
  </div>
226
+ </div>
227
 
228
+ <DialogFooter>
229
+ <Button variant="outline" onClick={() => setFeedbackDialogOpen(false)}>
230
+ Cancel
231
+ </Button>
232
+ <Button onClick={handleFeedbackSubmit}>Submit</Button>
233
+ </DialogFooter>
234
+ </DialogContent>
235
+ </Dialog>
 
236
  </div>
237
  );
238
  }