SarahXia0405 commited on
Commit
2519d03
·
verified ·
1 Parent(s): a57f137

Update web/src/components/sidebar/LeftSidebar.tsx

Browse files
web/src/components/sidebar/LeftSidebar.tsx CHANGED
@@ -8,6 +8,16 @@ import { Badge } from "../ui/badge";
8
  import { SavedChatSection } from "./SavedChatSection";
9
 
10
  import { Pencil, Check, X, MailPlus, Users } from "lucide-react";
 
 
 
 
 
 
 
 
 
 
11
 
12
  import type {
13
  SavedChat,
@@ -61,8 +71,6 @@ type Props = {
61
  selectedCourse: string;
62
  availableCourses: CourseDirectoryItem[];
63
 
64
- onInviteGroupMembers?: () => void;
65
-
66
  onRenameGroupName?: (workspaceId: string, newName: string) => Promise<void> | void;
67
  onRenameGroupNo?: (workspaceId: string, newNo: number) => Promise<void> | void;
68
  };
@@ -117,7 +125,6 @@ export function LeftSidebar(props: Props) {
117
  workspaces,
118
  selectedCourse,
119
  availableCourses,
120
- onInviteGroupMembers,
121
  onRenameGroupName,
122
  onRenameGroupNo,
123
  } = props;
@@ -188,16 +195,34 @@ export function LeftSidebar(props: Props) {
188
  [currentWorkspaceId]
189
  );
190
 
191
- // state: group name
192
  const [groupName, setGroupName] = useState<string>(wsGroupName);
193
  const [editingGroupName, setEditingGroupName] = useState(false);
194
  const [draftGroupName, setDraftGroupName] = useState<string>(wsGroupName);
195
 
196
- // state: group no
197
  const [groupNo, setGroupNo] = useState<number>(toIntOrFallback(wsGroupNo, 1));
198
  const [editingGroupNo, setEditingGroupNo] = useState(false);
199
  const [draftGroupNo, setDraftGroupNo] = useState<string>(String(toIntOrFallback(wsGroupNo, 1)));
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  useEffect(() => {
202
  const storedName =
203
  typeof window !== "undefined" ? window.localStorage.getItem(groupNameStorageKey) : null;
@@ -208,9 +233,10 @@ export function LeftSidebar(props: Props) {
208
 
209
  const storedNo =
210
  typeof window !== "undefined" ? window.localStorage.getItem(groupNoStorageKey) : null;
211
- const no = storedNo && storedNo.trim()
212
- ? toIntOrFallback(storedNo, toIntOrFallback(wsGroupNo, 1))
213
- : toIntOrFallback(wsGroupNo, 1);
 
214
  setGroupNo(no);
215
  setDraftGroupNo(String(no));
216
  setEditingGroupNo(false);
@@ -292,7 +318,6 @@ export function LeftSidebar(props: Props) {
292
  <div className="text-[30px] leading-tight font-semibold">{courseName}</div>
293
 
294
  {!isTeamSpace ? (
295
- // My Space unchanged
296
  <div className="space-y-3">
297
  <div className="text-[30px] leading-tight font-semibold">
298
  Group {String(groupNo)}
@@ -336,10 +361,9 @@ export function LeftSidebar(props: Props) {
336
  </div>
337
  </div>
338
  ) : (
339
- // Team/Group Space (your requested structure)
340
  <div className="rounded-2xl border bg-white overflow-hidden">
341
  <div className="px-4 pt-4 pb-3 space-y-3">
342
- {/* Line 1: group name in BLACK + pencil (editable) */}
343
  {!editingGroupName ? (
344
  <div className="flex items-center gap-2">
345
  <div className="text-[18px] font-semibold text-foreground truncate">
@@ -375,7 +399,7 @@ export function LeftSidebar(props: Props) {
375
  </div>
376
  )}
377
 
378
- {/* Line 2: "Group {no} (count)" where {no} is editable via pencil */}
379
  <div className="flex items-center justify-between gap-3">
380
  <div className="flex items-center gap-2">
381
  <Users className="w-4 h-4 text-muted-foreground" />
@@ -424,7 +448,7 @@ export function LeftSidebar(props: Props) {
424
  type="button"
425
  variant="secondary"
426
  className="h-9 px-3 text-[13px]"
427
- onClick={onInviteGroupMembers}
428
  >
429
  <MailPlus className="w-4 h-4 mr-2" />
430
  Invite
@@ -546,6 +570,31 @@ export function LeftSidebar(props: Props) {
546
  </div>
547
  </div>
548
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  </div>
550
  );
551
  }
 
8
  import { SavedChatSection } from "./SavedChatSection";
9
 
10
  import { Pencil, Check, X, MailPlus, Users } from "lucide-react";
11
+ import { toast } from "sonner";
12
+
13
+ import {
14
+ Dialog,
15
+ DialogContent,
16
+ DialogDescription,
17
+ DialogFooter,
18
+ DialogHeader,
19
+ DialogTitle,
20
+ } from "../ui/dialog";
21
 
22
  import type {
23
  SavedChat,
 
71
  selectedCourse: string;
72
  availableCourses: CourseDirectoryItem[];
73
 
 
 
74
  onRenameGroupName?: (workspaceId: string, newName: string) => Promise<void> | void;
75
  onRenameGroupNo?: (workspaceId: string, newNo: number) => Promise<void> | void;
76
  };
 
125
  workspaces,
126
  selectedCourse,
127
  availableCourses,
 
128
  onRenameGroupName,
129
  onRenameGroupNo,
130
  } = props;
 
195
  [currentWorkspaceId]
196
  );
197
 
198
+ // group name
199
  const [groupName, setGroupName] = useState<string>(wsGroupName);
200
  const [editingGroupName, setEditingGroupName] = useState(false);
201
  const [draftGroupName, setDraftGroupName] = useState<string>(wsGroupName);
202
 
203
+ // group no
204
  const [groupNo, setGroupNo] = useState<number>(toIntOrFallback(wsGroupNo, 1));
205
  const [editingGroupNo, setEditingGroupNo] = useState(false);
206
  const [draftGroupNo, setDraftGroupNo] = useState<string>(String(toIntOrFallback(wsGroupNo, 1)));
207
 
208
+ // Invite dialog state (restored)
209
+ const [inviteOpen, setInviteOpen] = useState(false);
210
+ const [inviteEmail, setInviteEmail] = useState("");
211
+
212
+ const handleInviteClick = () => {
213
+ setInviteOpen(true);
214
+ };
215
+
216
+ const handleSendInvite = () => {
217
+ if (!inviteEmail.trim()) {
218
+ toast.error("Please enter an email to invite");
219
+ return;
220
+ }
221
+ toast.success(`Invitation sent to ${inviteEmail}`);
222
+ setInviteEmail("");
223
+ setInviteOpen(false);
224
+ };
225
+
226
  useEffect(() => {
227
  const storedName =
228
  typeof window !== "undefined" ? window.localStorage.getItem(groupNameStorageKey) : null;
 
233
 
234
  const storedNo =
235
  typeof window !== "undefined" ? window.localStorage.getItem(groupNoStorageKey) : null;
236
+ const no =
237
+ storedNo && storedNo.trim()
238
+ ? toIntOrFallback(storedNo, toIntOrFallback(wsGroupNo, 1))
239
+ : toIntOrFallback(wsGroupNo, 1);
240
  setGroupNo(no);
241
  setDraftGroupNo(String(no));
242
  setEditingGroupNo(false);
 
318
  <div className="text-[30px] leading-tight font-semibold">{courseName}</div>
319
 
320
  {!isTeamSpace ? (
 
321
  <div className="space-y-3">
322
  <div className="text-[30px] leading-tight font-semibold">
323
  Group {String(groupNo)}
 
361
  </div>
362
  </div>
363
  ) : (
 
364
  <div className="rounded-2xl border bg-white overflow-hidden">
365
  <div className="px-4 pt-4 pb-3 space-y-3">
366
+ {/* Line 1: group name (black) + pencil */}
367
  {!editingGroupName ? (
368
  <div className="flex items-center gap-2">
369
  <div className="text-[18px] font-semibold text-foreground truncate">
 
399
  </div>
400
  )}
401
 
402
+ {/* Line 2: Group {no}(✏️) ({count}) + Invite */}
403
  <div className="flex items-center justify-between gap-3">
404
  <div className="flex items-center gap-2">
405
  <Users className="w-4 h-4 text-muted-foreground" />
 
448
  type="button"
449
  variant="secondary"
450
  className="h-9 px-3 text-[13px]"
451
+ onClick={handleInviteClick}
452
  >
453
  <MailPlus className="w-4 h-4 mr-2" />
454
  Invite
 
570
  </div>
571
  </div>
572
  </div>
573
+
574
+ {/* Invite Dialog (restored) */}
575
+ <Dialog open={inviteOpen} onOpenChange={setInviteOpen}>
576
+ <DialogContent className="w-[600px] max-w-[600px] sm:max-w-[600px]" style={{ maxWidth: 600 }}>
577
+ <DialogHeader>
578
+ <DialogTitle>Invite member</DialogTitle>
579
+ <DialogDescription>Send a quick email invite with the team details.</DialogDescription>
580
+ </DialogHeader>
581
+ <div className="space-y-3">
582
+ <Input
583
+ type="email"
584
+ placeholder="name@example.com"
585
+ value={inviteEmail}
586
+ onChange={(e) => setInviteEmail(e.target.value)}
587
+ />
588
+ <p className="text-xs text-muted-foreground">
589
+ An invitation email with a join link will be sent to this address.
590
+ </p>
591
+ </div>
592
+ <DialogFooter>
593
+ <Button variant="outline" onClick={() => setInviteOpen(false)}>Cancel</Button>
594
+ <Button onClick={handleSendInvite}>Send invite</Button>
595
+ </DialogFooter>
596
+ </DialogContent>
597
+ </Dialog>
598
  </div>
599
  );
600
  }