Spaces:
Sleeping
Sleeping
Update web/src/components/RightPanel.tsx
Browse files
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';
|
|
@@ -20,7 +21,7 @@ import {
|
|
| 20 |
|
| 21 |
interface RightPanelProps {
|
| 22 |
user: User | null;
|
| 23 |
-
onLogin: (name: string,
|
| 24 |
onLogout: () => void;
|
| 25 |
isLoggedIn: boolean;
|
| 26 |
onClose?: () => void;
|
|
@@ -30,7 +31,7 @@ interface RightPanelProps {
|
|
| 30 |
resultType: 'export' | 'quiz' | 'summary' | null;
|
| 31 |
setResultType: (type: 'export' | 'quiz' | 'summary' | null) => void;
|
| 32 |
|
| 33 |
-
// ✅
|
| 34 |
onExport: () => void;
|
| 35 |
onQuiz: () => void;
|
| 36 |
onSummary: () => void;
|
|
@@ -41,7 +42,6 @@ export function RightPanel({
|
|
| 41 |
onLogin,
|
| 42 |
onLogout,
|
| 43 |
isLoggedIn,
|
| 44 |
-
onClose,
|
| 45 |
exportResult,
|
| 46 |
setExportResult,
|
| 47 |
resultType,
|
|
@@ -52,21 +52,21 @@ export function RightPanel({
|
|
| 52 |
}: RightPanelProps) {
|
| 53 |
const [showLoginForm, setShowLoginForm] = useState(false);
|
| 54 |
const [name, setName] = useState('');
|
| 55 |
-
const [
|
| 56 |
|
| 57 |
const [feedbackDialogOpen, setFeedbackDialogOpen] = useState(false);
|
| 58 |
const [feedbackText, setFeedbackText] = useState('');
|
| 59 |
const [feedbackCategory, setFeedbackCategory] = useState<'general' | 'bug' | 'feature'>('general');
|
| 60 |
|
| 61 |
const handleLoginClick = () => {
|
| 62 |
-
if (!name.trim() || !
|
| 63 |
toast.error('Please fill in all fields');
|
| 64 |
return;
|
| 65 |
}
|
| 66 |
-
onLogin(name.trim(),
|
| 67 |
setShowLoginForm(false);
|
| 68 |
setName('');
|
| 69 |
-
|
| 70 |
};
|
| 71 |
|
| 72 |
const handleLogoutClick = () => {
|
|
@@ -87,7 +87,7 @@ export function RightPanel({
|
|
| 87 |
|
| 88 |
return (
|
| 89 |
<div className="flex-1 overflow-auto p-4 space-y-4">
|
| 90 |
-
{/*
|
| 91 |
<Card className="p-4">
|
| 92 |
{!isLoggedIn ? (
|
| 93 |
<div className="space-y-4">
|
|
@@ -115,11 +115,11 @@ export function RightPanel({
|
|
| 115 |
/>
|
| 116 |
</div>
|
| 117 |
<div className="space-y-2">
|
| 118 |
-
<Label htmlFor="
|
| 119 |
<Input
|
| 120 |
-
id="
|
| 121 |
-
value={
|
| 122 |
-
onChange={(e) =>
|
| 123 |
placeholder="Enter your email or ID"
|
| 124 |
/>
|
| 125 |
</div>
|
|
@@ -155,55 +155,49 @@ export function RightPanel({
|
|
| 155 |
)}
|
| 156 |
</Card>
|
| 157 |
|
| 158 |
-
{/* ✅
|
| 159 |
-
<Card className="p-4 space-y-
|
| 160 |
-
<
|
|
|
|
|
|
|
| 161 |
|
|
|
|
| 162 |
<div className="grid grid-cols-3 gap-2">
|
| 163 |
<Button
|
| 164 |
variant="outline"
|
| 165 |
-
className="
|
| 166 |
onClick={onExport}
|
| 167 |
disabled={!isLoggedIn}
|
| 168 |
-
title="Export
|
| 169 |
>
|
| 170 |
<Download className="h-4 w-4" />
|
| 171 |
-
<span className="hidden xl:inline">Export</span>
|
| 172 |
</Button>
|
| 173 |
|
| 174 |
<Button
|
| 175 |
variant="outline"
|
| 176 |
-
className="
|
| 177 |
onClick={onQuiz}
|
| 178 |
disabled={!isLoggedIn}
|
| 179 |
-
title="
|
| 180 |
>
|
| 181 |
<ClipboardList className="h-4 w-4" />
|
| 182 |
-
<span className="hidden xl:inline">Quiz</span>
|
| 183 |
</Button>
|
| 184 |
|
| 185 |
<Button
|
| 186 |
variant="outline"
|
| 187 |
-
className="
|
| 188 |
onClick={onSummary}
|
| 189 |
disabled={!isLoggedIn}
|
| 190 |
-
title="
|
| 191 |
>
|
| 192 |
<Sparkles className="h-4 w-4" />
|
| 193 |
-
<span className="hidden xl:inline">Summary</span>
|
| 194 |
</Button>
|
| 195 |
</div>
|
| 196 |
-
|
| 197 |
-
{!isLoggedIn && (
|
| 198 |
-
<p className="text-xs text-muted-foreground mt-1">
|
| 199 |
-
Log in to enable export / quiz / summary.
|
| 200 |
-
</p>
|
| 201 |
-
)}
|
| 202 |
</Card>
|
| 203 |
|
| 204 |
<Separator />
|
| 205 |
|
| 206 |
-
{/*
|
| 207 |
<div className="space-y-3">
|
| 208 |
<h3>
|
| 209 |
{resultType === 'export' && 'Exported Conversation'}
|
|
@@ -240,7 +234,7 @@ export function RightPanel({
|
|
| 240 |
|
| 241 |
<Separator />
|
| 242 |
|
| 243 |
-
{/*
|
| 244 |
<div className="space-y-3">
|
| 245 |
<h3>Feedback</h3>
|
| 246 |
<Button
|
|
@@ -257,9 +251,7 @@ export function RightPanel({
|
|
| 257 |
<DialogContent className="sm:max-w-[425px]">
|
| 258 |
<DialogHeader>
|
| 259 |
<DialogTitle>Provide Feedback</DialogTitle>
|
| 260 |
-
<DialogDescription>
|
| 261 |
-
Help us improve Clare by sharing your thoughts and suggestions.
|
| 262 |
-
</DialogDescription>
|
| 263 |
</DialogHeader>
|
| 264 |
|
| 265 |
<div className="space-y-3">
|
|
|
|
| 1 |
+
// web/src/components/RightPanel.tsx
|
| 2 |
import React, { useState } from 'react';
|
| 3 |
import { Button } from './ui/button';
|
| 4 |
import { Input } from './ui/input';
|
|
|
|
| 21 |
|
| 22 |
interface RightPanelProps {
|
| 23 |
user: User | null;
|
| 24 |
+
onLogin: (name: string, emailOrId: string) => void;
|
| 25 |
onLogout: () => void;
|
| 26 |
isLoggedIn: boolean;
|
| 27 |
onClose?: () => void;
|
|
|
|
| 31 |
resultType: 'export' | 'quiz' | 'summary' | null;
|
| 32 |
setResultType: (type: 'export' | 'quiz' | 'summary' | null) => void;
|
| 33 |
|
| 34 |
+
// ✅ Actions buttons callbacks (来自 App.tsx)
|
| 35 |
onExport: () => void;
|
| 36 |
onQuiz: () => void;
|
| 37 |
onSummary: () => void;
|
|
|
|
| 42 |
onLogin,
|
| 43 |
onLogout,
|
| 44 |
isLoggedIn,
|
|
|
|
| 45 |
exportResult,
|
| 46 |
setExportResult,
|
| 47 |
resultType,
|
|
|
|
| 52 |
}: RightPanelProps) {
|
| 53 |
const [showLoginForm, setShowLoginForm] = useState(false);
|
| 54 |
const [name, setName] = useState('');
|
| 55 |
+
const [emailOrId, setEmailOrId] = useState('');
|
| 56 |
|
| 57 |
const [feedbackDialogOpen, setFeedbackDialogOpen] = useState(false);
|
| 58 |
const [feedbackText, setFeedbackText] = useState('');
|
| 59 |
const [feedbackCategory, setFeedbackCategory] = useState<'general' | 'bug' | 'feature'>('general');
|
| 60 |
|
| 61 |
const handleLoginClick = () => {
|
| 62 |
+
if (!name.trim() || !emailOrId.trim()) {
|
| 63 |
toast.error('Please fill in all fields');
|
| 64 |
return;
|
| 65 |
}
|
| 66 |
+
onLogin(name.trim(), emailOrId.trim());
|
| 67 |
setShowLoginForm(false);
|
| 68 |
setName('');
|
| 69 |
+
setEmailOrId('');
|
| 70 |
};
|
| 71 |
|
| 72 |
const handleLogoutClick = () => {
|
|
|
|
| 87 |
|
| 88 |
return (
|
| 89 |
<div className="flex-1 overflow-auto p-4 space-y-4">
|
| 90 |
+
{/* Account */}
|
| 91 |
<Card className="p-4">
|
| 92 |
{!isLoggedIn ? (
|
| 93 |
<div className="space-y-4">
|
|
|
|
| 115 |
/>
|
| 116 |
</div>
|
| 117 |
<div className="space-y-2">
|
| 118 |
+
<Label htmlFor="emailOrId">Email / Student ID</Label>
|
| 119 |
<Input
|
| 120 |
+
id="emailOrId"
|
| 121 |
+
value={emailOrId}
|
| 122 |
+
onChange={(e) => setEmailOrId(e.target.value)}
|
| 123 |
placeholder="Enter your email or ID"
|
| 124 |
/>
|
| 125 |
</div>
|
|
|
|
| 155 |
)}
|
| 156 |
</Card>
|
| 157 |
|
| 158 |
+
{/* ✅ Actions:三按钮并排(同宽) */}
|
| 159 |
+
<Card className="p-4 space-y-3">
|
| 160 |
+
<div className="flex items-center justify-between">
|
| 161 |
+
<h3>Actions</h3>
|
| 162 |
+
</div>
|
| 163 |
|
| 164 |
+
{/* 关键:grid-cols-3 + 每个 Button w-full */}
|
| 165 |
<div className="grid grid-cols-3 gap-2">
|
| 166 |
<Button
|
| 167 |
variant="outline"
|
| 168 |
+
className="w-full h-10 px-0"
|
| 169 |
onClick={onExport}
|
| 170 |
disabled={!isLoggedIn}
|
| 171 |
+
title="Export"
|
| 172 |
>
|
| 173 |
<Download className="h-4 w-4" />
|
|
|
|
| 174 |
</Button>
|
| 175 |
|
| 176 |
<Button
|
| 177 |
variant="outline"
|
| 178 |
+
className="w-full h-10 px-0"
|
| 179 |
onClick={onQuiz}
|
| 180 |
disabled={!isLoggedIn}
|
| 181 |
+
title="Quiz"
|
| 182 |
>
|
| 183 |
<ClipboardList className="h-4 w-4" />
|
|
|
|
| 184 |
</Button>
|
| 185 |
|
| 186 |
<Button
|
| 187 |
variant="outline"
|
| 188 |
+
className="w-full h-10 px-0"
|
| 189 |
onClick={onSummary}
|
| 190 |
disabled={!isLoggedIn}
|
| 191 |
+
title="Summary"
|
| 192 |
>
|
| 193 |
<Sparkles className="h-4 w-4" />
|
|
|
|
| 194 |
</Button>
|
| 195 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 196 |
</Card>
|
| 197 |
|
| 198 |
<Separator />
|
| 199 |
|
| 200 |
+
{/* Results */}
|
| 201 |
<div className="space-y-3">
|
| 202 |
<h3>
|
| 203 |
{resultType === 'export' && 'Exported Conversation'}
|
|
|
|
| 234 |
|
| 235 |
<Separator />
|
| 236 |
|
| 237 |
+
{/* Feedback */}
|
| 238 |
<div className="space-y-3">
|
| 239 |
<h3>Feedback</h3>
|
| 240 |
<Button
|
|
|
|
| 251 |
<DialogContent className="sm:max-w-[425px]">
|
| 252 |
<DialogHeader>
|
| 253 |
<DialogTitle>Provide Feedback</DialogTitle>
|
| 254 |
+
<DialogDescription>Help us improve Clare by sharing your thoughts and suggestions.</DialogDescription>
|
|
|
|
|
|
|
| 255 |
</DialogHeader>
|
| 256 |
|
| 257 |
<div className="space-y-3">
|