@bbearai/react 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +1415 -829
- package/dist/index.mjs +1416 -830
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -28,7 +28,17 @@ var BugBearContext = createContext({
|
|
|
28
28
|
endSession: async () => ({ success: false }),
|
|
29
29
|
addFinding: async () => ({ success: false }),
|
|
30
30
|
refreshSession: async () => {
|
|
31
|
-
}
|
|
31
|
+
},
|
|
32
|
+
// Messaging
|
|
33
|
+
threads: [],
|
|
34
|
+
unreadCount: 0,
|
|
35
|
+
refreshThreads: async () => {
|
|
36
|
+
},
|
|
37
|
+
getThreadMessages: async () => [],
|
|
38
|
+
sendMessage: async () => false,
|
|
39
|
+
markAsRead: async () => {
|
|
40
|
+
},
|
|
41
|
+
createThread: async () => ({ success: false })
|
|
32
42
|
});
|
|
33
43
|
function useBugBear() {
|
|
34
44
|
return useContext(BugBearContext);
|
|
@@ -43,6 +53,8 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
43
53
|
const hasInitialized = useRef(false);
|
|
44
54
|
const [activeSession, setActiveSession] = useState(null);
|
|
45
55
|
const [sessionFindings, setSessionFindings] = useState([]);
|
|
56
|
+
const [threads, setThreads] = useState([]);
|
|
57
|
+
const [unreadCount, setUnreadCount] = useState(0);
|
|
46
58
|
const refreshAssignments = useCallback(async () => {
|
|
47
59
|
if (!client) return;
|
|
48
60
|
const newAssignments = await client.getAssignedTests();
|
|
@@ -87,6 +99,38 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
87
99
|
}
|
|
88
100
|
return result;
|
|
89
101
|
}, [client, activeSession]);
|
|
102
|
+
const refreshThreads = useCallback(async () => {
|
|
103
|
+
if (!client) return;
|
|
104
|
+
const newThreads = await client.getThreadsForTester();
|
|
105
|
+
setThreads(newThreads);
|
|
106
|
+
const totalUnread = newThreads.reduce((sum, t) => sum + t.unreadCount, 0);
|
|
107
|
+
setUnreadCount(totalUnread);
|
|
108
|
+
}, [client]);
|
|
109
|
+
const getThreadMessages = useCallback(async (threadId) => {
|
|
110
|
+
if (!client) return [];
|
|
111
|
+
return client.getThreadMessages(threadId);
|
|
112
|
+
}, [client]);
|
|
113
|
+
const sendMessage = useCallback(async (threadId, content) => {
|
|
114
|
+
if (!client) return false;
|
|
115
|
+
const success = await client.sendMessage(threadId, content);
|
|
116
|
+
if (success) {
|
|
117
|
+
await refreshThreads();
|
|
118
|
+
}
|
|
119
|
+
return success;
|
|
120
|
+
}, [client, refreshThreads]);
|
|
121
|
+
const markAsRead = useCallback(async (threadId) => {
|
|
122
|
+
if (!client) return;
|
|
123
|
+
await client.markThreadAsRead(threadId);
|
|
124
|
+
await refreshThreads();
|
|
125
|
+
}, [client, refreshThreads]);
|
|
126
|
+
const createThread = useCallback(async (options) => {
|
|
127
|
+
if (!client) return { success: false, error: "Client not initialized" };
|
|
128
|
+
const result = await client.createThread(options);
|
|
129
|
+
if (result.success) {
|
|
130
|
+
await refreshThreads();
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}, [client, refreshThreads]);
|
|
90
134
|
const initializeBugBear = useCallback(async (bugBearClient) => {
|
|
91
135
|
setIsLoading(true);
|
|
92
136
|
try {
|
|
@@ -99,12 +143,16 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
99
143
|
setTesterInfo(info);
|
|
100
144
|
setIsTester(!!info);
|
|
101
145
|
if (info && qaEnabled) {
|
|
102
|
-
const [newAssignments, session] = await Promise.all([
|
|
146
|
+
const [newAssignments, session, newThreads] = await Promise.all([
|
|
103
147
|
bugBearClient.getAssignedTests(),
|
|
104
|
-
bugBearClient.getActiveSession()
|
|
148
|
+
bugBearClient.getActiveSession(),
|
|
149
|
+
bugBearClient.getThreadsForTester()
|
|
105
150
|
]);
|
|
106
151
|
setAssignments(newAssignments);
|
|
107
152
|
setActiveSession(session);
|
|
153
|
+
setThreads(newThreads);
|
|
154
|
+
const totalUnread = newThreads.reduce((sum, t) => sum + t.unreadCount, 0);
|
|
155
|
+
setUnreadCount(totalUnread);
|
|
108
156
|
if (session) {
|
|
109
157
|
const findings = await bugBearClient.getSessionFindings(session.id);
|
|
110
158
|
setSessionFindings(findings);
|
|
@@ -170,7 +218,15 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
170
218
|
startSession,
|
|
171
219
|
endSession,
|
|
172
220
|
addFinding,
|
|
173
|
-
refreshSession
|
|
221
|
+
refreshSession,
|
|
222
|
+
// Messaging
|
|
223
|
+
threads,
|
|
224
|
+
unreadCount,
|
|
225
|
+
refreshThreads,
|
|
226
|
+
getThreadMessages,
|
|
227
|
+
sendMessage,
|
|
228
|
+
markAsRead,
|
|
229
|
+
createThread
|
|
174
230
|
},
|
|
175
231
|
children
|
|
176
232
|
}
|
|
@@ -178,7 +234,8 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
178
234
|
}
|
|
179
235
|
|
|
180
236
|
// src/BugBearPanel.tsx
|
|
181
|
-
import { useState as useState2, useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
|
|
237
|
+
import { useState as useState2, useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2, useMemo } from "react";
|
|
238
|
+
import { createPortal } from "react-dom";
|
|
182
239
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
183
240
|
function BugBearIcon({ size = 24, className = "" }) {
|
|
184
241
|
return /* @__PURE__ */ jsxs(
|
|
@@ -249,13 +306,77 @@ function BugBearPanel({
|
|
|
249
306
|
defaultCollapsed = false,
|
|
250
307
|
draggable = true
|
|
251
308
|
}) {
|
|
252
|
-
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate, updateTesterProfile, refreshTesterInfo, activeSession, sessionFindings, startSession, endSession, addFinding } = useBugBear();
|
|
309
|
+
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate, updateTesterProfile, refreshTesterInfo, activeSession, sessionFindings, startSession, endSession, addFinding, threads, unreadCount, refreshThreads, getThreadMessages, sendMessage, markAsRead, createThread } = useBugBear();
|
|
253
310
|
const [collapsed, setCollapsed] = useState2(defaultCollapsed);
|
|
254
311
|
const [activeTab, setActiveTab] = useState2("tests");
|
|
255
312
|
const [showSteps, setShowSteps] = useState2(false);
|
|
256
313
|
const [testView, setTestView] = useState2("detail");
|
|
257
314
|
const [selectedTestId, setSelectedTestId] = useState2(null);
|
|
315
|
+
const [messageView, setMessageView] = useState2("list");
|
|
316
|
+
const [selectedThread, setSelectedThread] = useState2(null);
|
|
317
|
+
const [threadMessages, setThreadMessages] = useState2([]);
|
|
318
|
+
const [replyText, setReplyText] = useState2("");
|
|
319
|
+
const [sendingReply, setSendingReply] = useState2(false);
|
|
320
|
+
const [loadingMessages, setLoadingMessages] = useState2(false);
|
|
321
|
+
const [composeSubject, setComposeSubject] = useState2("");
|
|
322
|
+
const [composeMessage, setComposeMessage] = useState2("");
|
|
323
|
+
const [sendingNewMessage, setSendingNewMessage] = useState2(false);
|
|
258
324
|
const displayedAssignment = selectedTestId ? assignments.find((a) => a.id === selectedTestId) || currentAssignment : currentAssignment;
|
|
325
|
+
const groupedAssignments = useMemo(() => {
|
|
326
|
+
const groups = /* @__PURE__ */ new Map();
|
|
327
|
+
for (const assignment of assignments) {
|
|
328
|
+
const groupId = assignment.testCase.group?.id || "ungrouped";
|
|
329
|
+
const group = assignment.testCase.group || null;
|
|
330
|
+
if (!groups.has(groupId)) {
|
|
331
|
+
groups.set(groupId, {
|
|
332
|
+
group,
|
|
333
|
+
assignments: [],
|
|
334
|
+
stats: { total: 0, passed: 0, failed: 0, pending: 0, skipped: 0 }
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
const folder = groups.get(groupId);
|
|
338
|
+
folder.assignments.push(assignment);
|
|
339
|
+
folder.stats.total++;
|
|
340
|
+
if (assignment.status === "passed") folder.stats.passed++;
|
|
341
|
+
else if (assignment.status === "failed") folder.stats.failed++;
|
|
342
|
+
else if (assignment.status === "skipped") folder.stats.skipped++;
|
|
343
|
+
else folder.stats.pending++;
|
|
344
|
+
}
|
|
345
|
+
const sortedGroups = Array.from(groups.values()).sort((a, b) => {
|
|
346
|
+
if (!a.group && !b.group) return 0;
|
|
347
|
+
if (!a.group) return 1;
|
|
348
|
+
if (!b.group) return -1;
|
|
349
|
+
return a.group.sortOrder - b.group.sortOrder;
|
|
350
|
+
});
|
|
351
|
+
return sortedGroups;
|
|
352
|
+
}, [assignments]);
|
|
353
|
+
const toggleFolderCollapse = useCallback2((groupId) => {
|
|
354
|
+
setCollapsedFolders((prev) => {
|
|
355
|
+
const next = new Set(prev);
|
|
356
|
+
if (next.has(groupId)) {
|
|
357
|
+
next.delete(groupId);
|
|
358
|
+
} else {
|
|
359
|
+
next.add(groupId);
|
|
360
|
+
}
|
|
361
|
+
return next;
|
|
362
|
+
});
|
|
363
|
+
}, []);
|
|
364
|
+
const getStatusBadge = (status) => {
|
|
365
|
+
switch (status) {
|
|
366
|
+
case "passed":
|
|
367
|
+
return { icon: "\u2705", label: "Passed", className: "bg-green-900/30 text-green-400" };
|
|
368
|
+
case "failed":
|
|
369
|
+
return { icon: "\u274C", label: "Failed", className: "bg-red-900/30 text-red-400" };
|
|
370
|
+
case "skipped":
|
|
371
|
+
return { icon: "\u23ED\uFE0F", label: "Skipped", className: "bg-yellow-900/30 text-yellow-400" };
|
|
372
|
+
case "in_progress":
|
|
373
|
+
return { icon: "\u{1F504}", label: "In Progress", className: "bg-blue-900/30 text-blue-400" };
|
|
374
|
+
case "blocked":
|
|
375
|
+
return { icon: "\u{1F6AB}", label: "Blocked", className: "bg-orange-900/30 text-orange-400" };
|
|
376
|
+
default:
|
|
377
|
+
return { icon: "\u23F3", label: "Pending", className: "bg-zinc-700 text-zinc-400" };
|
|
378
|
+
}
|
|
379
|
+
};
|
|
259
380
|
const [panelPosition, setPanelPosition] = useState2(null);
|
|
260
381
|
const [isDragging, setIsDragging] = useState2(false);
|
|
261
382
|
const dragStartRef = useRef2(null);
|
|
@@ -277,6 +398,10 @@ function BugBearPanel({
|
|
|
277
398
|
expectedResultUnclear: false
|
|
278
399
|
});
|
|
279
400
|
const [criteriaResults, setCriteriaResults] = useState2({});
|
|
401
|
+
const [showSkipModal, setShowSkipModal] = useState2(false);
|
|
402
|
+
const [selectedSkipReason, setSelectedSkipReason] = useState2(null);
|
|
403
|
+
const [skipNotes, setSkipNotes] = useState2("");
|
|
404
|
+
const [skipping, setSkipping] = useState2(false);
|
|
280
405
|
const [profileEditing, setProfileEditing] = useState2(false);
|
|
281
406
|
const [profileName, setProfileName] = useState2("");
|
|
282
407
|
const [profileAdditionalEmails, setProfileAdditionalEmails] = useState2([]);
|
|
@@ -285,6 +410,7 @@ function BugBearPanel({
|
|
|
285
410
|
const [savingProfile, setSavingProfile] = useState2(false);
|
|
286
411
|
const [profileSaved, setProfileSaved] = useState2(false);
|
|
287
412
|
const [showProfileOverlay, setShowProfileOverlay] = useState2(false);
|
|
413
|
+
const [collapsedFolders, setCollapsedFolders] = useState2(/* @__PURE__ */ new Set());
|
|
288
414
|
const [startingSession, setStartingSession] = useState2(false);
|
|
289
415
|
const [sessionFocusArea, setSessionFocusArea] = useState2("");
|
|
290
416
|
const [sessionPlatform, setSessionPlatform] = useState2("web");
|
|
@@ -488,6 +614,35 @@ function BugBearPanel({
|
|
|
488
614
|
expectedResultUnclear: false
|
|
489
615
|
});
|
|
490
616
|
};
|
|
617
|
+
const handleOpenSkipModal = () => {
|
|
618
|
+
setShowSkipModal(true);
|
|
619
|
+
setSelectedSkipReason(null);
|
|
620
|
+
setSkipNotes("");
|
|
621
|
+
};
|
|
622
|
+
const handleSkip = async () => {
|
|
623
|
+
if (!client || !displayedAssignment || !selectedSkipReason) return;
|
|
624
|
+
setSkipping(true);
|
|
625
|
+
const result = await client.skipAssignment(
|
|
626
|
+
displayedAssignment.id,
|
|
627
|
+
selectedSkipReason,
|
|
628
|
+
skipNotes.trim() || void 0
|
|
629
|
+
);
|
|
630
|
+
if (result.success) {
|
|
631
|
+
await refreshAssignments();
|
|
632
|
+
setShowSkipModal(false);
|
|
633
|
+
setSelectedSkipReason(null);
|
|
634
|
+
setSkipNotes("");
|
|
635
|
+
setSelectedTestId(null);
|
|
636
|
+
setTestView("detail");
|
|
637
|
+
}
|
|
638
|
+
setSkipping(false);
|
|
639
|
+
};
|
|
640
|
+
const skipReasonOptions = [
|
|
641
|
+
{ value: "blocked", label: "Blocked", description: "Environment issue or external blocker" },
|
|
642
|
+
{ value: "not_ready", label: "Not Ready", description: "Feature not yet implemented" },
|
|
643
|
+
{ value: "dependency", label: "Dependency", description: "Waiting on another test or task" },
|
|
644
|
+
{ value: "other", label: "Other", description: "Other reason (please specify)" }
|
|
645
|
+
];
|
|
491
646
|
const handleSubmitFeedback = async (skipFeedback = false) => {
|
|
492
647
|
if (!client || !displayedAssignment) return;
|
|
493
648
|
setSubmitting(true);
|
|
@@ -683,965 +838,1396 @@ function BugBearPanel({
|
|
|
683
838
|
}
|
|
684
839
|
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
685
840
|
};
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
841
|
+
const formatRelativeTime = (dateString) => {
|
|
842
|
+
const date = new Date(dateString);
|
|
843
|
+
const now = /* @__PURE__ */ new Date();
|
|
844
|
+
const diffMs = now.getTime() - date.getTime();
|
|
845
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
846
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
847
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
848
|
+
if (diffMins < 1) return "Just now";
|
|
849
|
+
if (diffMins < 60) return `${diffMins}m ago`;
|
|
850
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
851
|
+
if (diffDays === 1) return "Yesterday";
|
|
852
|
+
if (diffDays < 7) return `${diffDays}d ago`;
|
|
853
|
+
return date.toLocaleDateString();
|
|
854
|
+
};
|
|
855
|
+
const formatMessageTime = (dateString) => {
|
|
856
|
+
const date = new Date(dateString);
|
|
857
|
+
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
858
|
+
};
|
|
859
|
+
const getThreadTypeIcon = (type) => {
|
|
860
|
+
switch (type) {
|
|
861
|
+
case "announcement":
|
|
862
|
+
return "\u{1F4E2}";
|
|
863
|
+
case "direct":
|
|
864
|
+
return "\u{1F4AC}";
|
|
865
|
+
case "report":
|
|
866
|
+
return "\u{1F41B}";
|
|
867
|
+
case "general_note":
|
|
868
|
+
return "\u{1F4DD}";
|
|
869
|
+
default:
|
|
870
|
+
return "\u{1F4AC}";
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
const handleOpenThread = async (thread) => {
|
|
874
|
+
setSelectedThread(thread);
|
|
875
|
+
setMessageView("thread");
|
|
876
|
+
setLoadingMessages(true);
|
|
877
|
+
const messages = await getThreadMessages(thread.id);
|
|
878
|
+
setThreadMessages(messages);
|
|
879
|
+
setLoadingMessages(false);
|
|
880
|
+
if (thread.unreadCount > 0) {
|
|
881
|
+
await markAsRead(thread.id);
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
const handleSendReply = async () => {
|
|
885
|
+
if (!selectedThread || !replyText.trim()) return;
|
|
886
|
+
setSendingReply(true);
|
|
887
|
+
const success = await sendMessage(selectedThread.id, replyText.trim());
|
|
888
|
+
if (success) {
|
|
889
|
+
setReplyText("");
|
|
890
|
+
const messages = await getThreadMessages(selectedThread.id);
|
|
891
|
+
setThreadMessages(messages);
|
|
892
|
+
}
|
|
893
|
+
setSendingReply(false);
|
|
894
|
+
};
|
|
895
|
+
const handleBackToThreadList = () => {
|
|
896
|
+
setMessageView("list");
|
|
897
|
+
setSelectedThread(null);
|
|
898
|
+
setThreadMessages([]);
|
|
899
|
+
setReplyText("");
|
|
900
|
+
setComposeSubject("");
|
|
901
|
+
setComposeMessage("");
|
|
902
|
+
};
|
|
903
|
+
const handleStartNewMessage = () => {
|
|
904
|
+
setMessageView("compose");
|
|
905
|
+
setComposeSubject("");
|
|
906
|
+
setComposeMessage("");
|
|
907
|
+
};
|
|
908
|
+
const handleSendNewMessage = async () => {
|
|
909
|
+
if (!composeSubject.trim() || !composeMessage.trim()) return;
|
|
910
|
+
setSendingNewMessage(true);
|
|
911
|
+
const result = await createThread({
|
|
912
|
+
subject: composeSubject.trim(),
|
|
913
|
+
message: composeMessage.trim()
|
|
914
|
+
});
|
|
915
|
+
if (result.success) {
|
|
916
|
+
setComposeSubject("");
|
|
917
|
+
setComposeMessage("");
|
|
918
|
+
setMessageView("list");
|
|
919
|
+
}
|
|
920
|
+
setSendingNewMessage(false);
|
|
921
|
+
};
|
|
922
|
+
if (typeof document === "undefined") return null;
|
|
923
|
+
return createPortal(
|
|
924
|
+
/* @__PURE__ */ jsxs(
|
|
925
|
+
"div",
|
|
926
|
+
{
|
|
927
|
+
ref: panelRef,
|
|
928
|
+
className: "fixed font-sans",
|
|
929
|
+
style: {
|
|
930
|
+
zIndex: 2147483647,
|
|
931
|
+
// Max z-index to stay above all modals
|
|
932
|
+
left: panelPosition.x,
|
|
933
|
+
top: panelPosition.y,
|
|
934
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
935
|
+
cursor: isDragging ? "grabbing" : void 0,
|
|
936
|
+
userSelect: isDragging ? "none" : void 0
|
|
937
|
+
},
|
|
938
|
+
onMouseDown: handleMouseDown,
|
|
939
|
+
children: [
|
|
940
|
+
collapsed && /* @__PURE__ */ jsxs(
|
|
941
|
+
"button",
|
|
720
942
|
{
|
|
943
|
+
onClick: () => setCollapsed(false),
|
|
721
944
|
"data-drag-handle": true,
|
|
722
945
|
onDoubleClick: handleDoubleClick,
|
|
723
|
-
className: "bg-
|
|
724
|
-
style: { cursor: draggable ?
|
|
946
|
+
className: "flex items-center gap-2 px-3 py-2 bg-blue-500 text-white rounded-full shadow-lg hover:bg-blue-600 transition-colors",
|
|
947
|
+
style: { cursor: draggable ? "grab" : "pointer" },
|
|
725
948
|
children: [
|
|
726
|
-
/* @__PURE__ */
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
/* @__PURE__ */ jsxs("h3", { className: "font-semibold text-sm flex items-center gap-2", children: [
|
|
730
|
-
"BugBear",
|
|
731
|
-
draggable && /* @__PURE__ */ jsx2("span", { className: "text-purple-300 text-xs", title: "Drag to move, double-click to reset", children: "\u22EE\u22EE" })
|
|
732
|
-
] }),
|
|
733
|
-
/* @__PURE__ */ jsxs(
|
|
734
|
-
"button",
|
|
735
|
-
{
|
|
736
|
-
onClick: handleOpenProfile,
|
|
737
|
-
className: "text-purple-200 text-xs flex items-center gap-1 hover:text-white transition-colors",
|
|
738
|
-
children: [
|
|
739
|
-
testerInfo?.name,
|
|
740
|
-
/* @__PURE__ */ jsx2("span", { className: "text-[10px]", children: "\u270E" })
|
|
741
|
-
]
|
|
742
|
-
}
|
|
743
|
-
)
|
|
744
|
-
] })
|
|
745
|
-
] }),
|
|
746
|
-
/* @__PURE__ */ jsx2(
|
|
747
|
-
"button",
|
|
748
|
-
{
|
|
749
|
-
onClick: () => setCollapsed(true),
|
|
750
|
-
className: "p-1 hover:bg-purple-500 rounded",
|
|
751
|
-
children: /* @__PURE__ */ jsx2("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
752
|
-
}
|
|
753
|
-
)
|
|
949
|
+
/* @__PURE__ */ jsx2(BugBearIcon, { size: 24 }),
|
|
950
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: "BugBear" }),
|
|
951
|
+
pendingCount > 0 && /* @__PURE__ */ jsx2("span", { className: "bg-white text-blue-400 text-xs font-bold px-1.5 py-0.5 rounded-full", children: pendingCount })
|
|
754
952
|
]
|
|
755
953
|
}
|
|
756
954
|
),
|
|
757
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
758
|
-
/* @__PURE__ */ jsxs(
|
|
759
|
-
"button",
|
|
760
|
-
{
|
|
761
|
-
onClick: () => setActiveTab("tests"),
|
|
762
|
-
className: `flex-1 py-2 px-3 rounded-lg text-sm font-semibold transition-all flex items-center justify-center gap-1.5 ${activeTab === "tests" ? "bg-purple-600 text-white shadow-sm" : "bg-white text-gray-600 hover:bg-gray-100 border border-gray-200"}`,
|
|
763
|
-
children: [
|
|
764
|
-
/* @__PURE__ */ jsx2("span", { children: "\u{1F4CB}" }),
|
|
765
|
-
/* @__PURE__ */ jsx2("span", { children: "Run Tests" }),
|
|
766
|
-
pendingCount > 0 && /* @__PURE__ */ jsx2("span", { className: `ml-1 px-1.5 py-0.5 rounded-full text-xs ${activeTab === "tests" ? "bg-purple-500 text-white" : "bg-purple-100 text-purple-600"}`, children: pendingCount })
|
|
767
|
-
]
|
|
768
|
-
}
|
|
769
|
-
),
|
|
955
|
+
!collapsed && /* @__PURE__ */ jsxs("div", { className: "w-80 bg-zinc-900 rounded-xl shadow-2xl border border-zinc-800 overflow-hidden", children: [
|
|
770
956
|
/* @__PURE__ */ jsxs(
|
|
771
|
-
"
|
|
957
|
+
"div",
|
|
772
958
|
{
|
|
773
|
-
|
|
774
|
-
|
|
959
|
+
"data-drag-handle": true,
|
|
960
|
+
onDoubleClick: handleDoubleClick,
|
|
961
|
+
className: "bg-zinc-950 text-white px-4 py-3 flex items-center justify-between border-b border-zinc-800",
|
|
962
|
+
style: { cursor: draggable ? isDragging ? "grabbing" : "grab" : "default" },
|
|
775
963
|
children: [
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
] }),
|
|
783
|
-
/* @__PURE__ */ jsx2("div", { className: "flex justify-center py-1.5 border-b border-gray-200 bg-white", children: /* @__PURE__ */ jsx2(
|
|
784
|
-
"button",
|
|
785
|
-
{
|
|
786
|
-
onClick: () => setActiveTab("report"),
|
|
787
|
-
className: `px-4 py-1 text-xs font-medium transition-colors rounded-full ${activeTab === "report" ? "bg-red-50 text-red-600 border border-red-200" : "text-gray-500 hover:text-gray-700 hover:bg-gray-50"}`,
|
|
788
|
-
children: "\u{1F41B} Report Bug / Feedback"
|
|
789
|
-
}
|
|
790
|
-
) }),
|
|
791
|
-
/* @__PURE__ */ jsxs("div", { className: "p-4 max-h-96 overflow-y-auto", children: [
|
|
792
|
-
activeTab === "tests" && /* @__PURE__ */ jsx2("div", { children: assignments.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
793
|
-
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u2705" }),
|
|
794
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-600 mt-2 font-medium", children: "All caught up!" }),
|
|
795
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-400 text-sm", children: "No tests assigned" })
|
|
796
|
-
] }) : testView === "list" ? (
|
|
797
|
-
/* List View - Show all tests */
|
|
798
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
799
|
-
/* @__PURE__ */ jsx2("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-500", children: [
|
|
800
|
-
assignments.length,
|
|
801
|
-
" test",
|
|
802
|
-
assignments.length !== 1 ? "s" : "",
|
|
803
|
-
" assigned"
|
|
804
|
-
] }) }),
|
|
805
|
-
assignments.map((assignment) => /* @__PURE__ */ jsxs(
|
|
806
|
-
"button",
|
|
807
|
-
{
|
|
808
|
-
onClick: () => {
|
|
809
|
-
setSelectedTestId(assignment.id);
|
|
810
|
-
setTestView("detail");
|
|
811
|
-
setShowSteps(false);
|
|
812
|
-
},
|
|
813
|
-
className: `w-full text-left p-3 rounded-lg border transition-colors ${assignment.id === currentAssignment?.id ? "bg-purple-50 border-purple-200" : "bg-gray-50 border-gray-200 hover:bg-gray-100"}`,
|
|
814
|
-
children: [
|
|
815
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between mb-1", children: [
|
|
816
|
-
/* @__PURE__ */ jsx2("span", { className: "text-xs font-mono text-gray-500", children: assignment.testCase.testKey }),
|
|
817
|
-
/* @__PURE__ */ jsx2("span", { className: `text-xs px-1.5 py-0.5 rounded font-medium ${assignment.testCase.priority === "P0" ? "bg-red-100 text-red-700" : assignment.testCase.priority === "P1" ? "bg-orange-100 text-orange-700" : "bg-gray-100 text-gray-600"}`, children: assignment.testCase.priority })
|
|
964
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
965
|
+
/* @__PURE__ */ jsx2(BugBearIcon, { size: 28 }),
|
|
966
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
967
|
+
/* @__PURE__ */ jsxs("h3", { className: "font-semibold text-sm flex items-center gap-2", children: [
|
|
968
|
+
"BugBear",
|
|
969
|
+
draggable && /* @__PURE__ */ jsx2("span", { className: "text-zinc-500 text-xs", title: "Drag to move, double-click to reset", children: "\u22EE\u22EE" })
|
|
818
970
|
] }),
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
assignment.testCase.track?.testTemplate === "checklist" ? "items" : assignment.testCase.track?.testTemplate === "rubric" ? "criteria" : "steps"
|
|
833
|
-
] }),
|
|
834
|
-
assignment.id === currentAssignment?.id && /* @__PURE__ */ jsx2("span", { className: "text-purple-600 font-medium", children: "\u2022 Current" })
|
|
835
|
-
] })
|
|
836
|
-
]
|
|
837
|
-
},
|
|
838
|
-
assignment.id
|
|
839
|
-
))
|
|
840
|
-
] })
|
|
841
|
-
) : showFeedbackPrompt && displayedAssignment ? (
|
|
842
|
-
/* Feedback prompt after completing a test */
|
|
843
|
-
/* @__PURE__ */ jsxs("div", { className: "p-3", children: [
|
|
844
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
845
|
-
/* @__PURE__ */ jsx2("span", { className: "text-3xl", children: pendingFeedbackStatus === "passed" ? "\u2713" : "\u2717" }),
|
|
846
|
-
/* @__PURE__ */ jsx2("p", { className: `font-semibold mt-1 ${pendingFeedbackStatus === "passed" ? "text-green-600" : "text-red-600"}`, children: pendingFeedbackStatus === "passed" ? "Test Passed!" : "Test Failed" })
|
|
847
|
-
] }),
|
|
848
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-purple-50 border border-purple-100 rounded-lg p-3 mb-4", children: [
|
|
849
|
-
/* @__PURE__ */ jsx2("p", { className: "text-purple-800 text-sm font-medium mb-1", children: "Help us improve this test" }),
|
|
850
|
-
/* @__PURE__ */ jsx2("p", { className: "text-purple-600 text-xs", children: "Your feedback shapes better tests for everyone." })
|
|
851
|
-
] }),
|
|
852
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
853
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-600 mb-2", children: "How was this test?" }),
|
|
854
|
-
/* @__PURE__ */ jsx2("div", { className: "flex items-center gap-1 justify-center", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx2(
|
|
855
|
-
"button",
|
|
856
|
-
{
|
|
857
|
-
type: "button",
|
|
858
|
-
onClick: () => setFeedbackRating(star),
|
|
859
|
-
className: `text-2xl transition-colors ${star <= feedbackRating ? "text-yellow-400" : "text-gray-300"} hover:text-yellow-400`,
|
|
860
|
-
children: "\u2605"
|
|
861
|
-
},
|
|
862
|
-
star
|
|
863
|
-
)) }),
|
|
864
|
-
/* @__PURE__ */ jsx2("p", { className: "text-center text-xs text-gray-500 mt-1", children: feedbackRating === 1 ? "Needs work" : feedbackRating === 2 ? "Could be better" : feedbackRating === 3 ? "Okay" : feedbackRating === 4 ? "Good" : "Great!" })
|
|
865
|
-
] }),
|
|
866
|
-
feedbackRating < 4 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
867
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-600 mb-2", children: "What could be improved?" }),
|
|
868
|
-
/* @__PURE__ */ jsx2("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
869
|
-
{ key: "stepsUnclear", label: "Steps unclear" },
|
|
870
|
-
{ key: "expectedResultUnclear", label: "Expected result unclear" },
|
|
871
|
-
{ key: "needsMoreDetail", label: "Needs more detail" },
|
|
872
|
-
{ key: "isOutdated", label: "Seems outdated" }
|
|
873
|
-
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
874
|
-
"button",
|
|
875
|
-
{
|
|
876
|
-
type: "button",
|
|
877
|
-
onClick: () => setFeedbackFlags((prev) => ({ ...prev, [key]: !prev[key] })),
|
|
878
|
-
className: `px-2 py-1.5 rounded text-xs font-medium border transition-colors ${feedbackFlags[key] ? "bg-purple-100 border-purple-300 text-purple-700" : "bg-white border-gray-200 text-gray-600 hover:border-purple-200"}`,
|
|
879
|
-
children: label
|
|
880
|
-
},
|
|
881
|
-
key
|
|
882
|
-
)) })
|
|
883
|
-
] }),
|
|
884
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
885
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Suggestions? (optional)" }),
|
|
886
|
-
/* @__PURE__ */ jsx2(
|
|
887
|
-
"textarea",
|
|
888
|
-
{
|
|
889
|
-
value: feedbackNote,
|
|
890
|
-
onChange: (e) => setFeedbackNote(e.target.value),
|
|
891
|
-
placeholder: "How could this test be improved?",
|
|
892
|
-
className: "w-full px-3 py-2 text-sm border border-gray-200 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent",
|
|
893
|
-
rows: 2
|
|
894
|
-
}
|
|
895
|
-
)
|
|
896
|
-
] }),
|
|
897
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
898
|
-
/* @__PURE__ */ jsx2(
|
|
899
|
-
"button",
|
|
900
|
-
{
|
|
901
|
-
onClick: handleSkipFeedback,
|
|
902
|
-
disabled: submitting,
|
|
903
|
-
className: "flex-1 px-3 py-2 text-sm font-medium text-gray-600 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors disabled:opacity-50",
|
|
904
|
-
children: "Skip"
|
|
905
|
-
}
|
|
906
|
-
),
|
|
971
|
+
/* @__PURE__ */ jsxs(
|
|
972
|
+
"button",
|
|
973
|
+
{
|
|
974
|
+
onClick: handleOpenProfile,
|
|
975
|
+
className: "text-zinc-400 text-xs flex items-center gap-1 hover:text-white transition-colors",
|
|
976
|
+
children: [
|
|
977
|
+
testerInfo?.name,
|
|
978
|
+
/* @__PURE__ */ jsx2("span", { className: "text-[10px]", children: "\u270E" })
|
|
979
|
+
]
|
|
980
|
+
}
|
|
981
|
+
)
|
|
982
|
+
] })
|
|
983
|
+
] }),
|
|
907
984
|
/* @__PURE__ */ jsx2(
|
|
908
985
|
"button",
|
|
909
986
|
{
|
|
910
|
-
onClick: () =>
|
|
911
|
-
|
|
912
|
-
className: "
|
|
913
|
-
children: submitting ? "Submitting..." : "Submit Feedback"
|
|
987
|
+
onClick: () => setCollapsed(true),
|
|
988
|
+
className: "p-1 hover:bg-zinc-800 rounded",
|
|
989
|
+
children: /* @__PURE__ */ jsx2("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
914
990
|
}
|
|
915
991
|
)
|
|
916
|
-
]
|
|
917
|
-
|
|
918
|
-
)
|
|
919
|
-
|
|
920
|
-
/* @__PURE__ */ jsxs(
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
992
|
+
]
|
|
993
|
+
}
|
|
994
|
+
),
|
|
995
|
+
/* @__PURE__ */ jsxs("div", { className: "flex border-b border-zinc-800 bg-zinc-900", children: [
|
|
996
|
+
/* @__PURE__ */ jsxs(
|
|
997
|
+
"button",
|
|
998
|
+
{
|
|
999
|
+
onClick: () => setActiveTab("tests"),
|
|
1000
|
+
className: `flex-1 py-3 text-sm font-medium transition-all flex items-center justify-center gap-1.5 border-b-2 ${activeTab === "tests" ? "border-blue-500 text-blue-400" : "border-transparent text-zinc-500 hover:text-zinc-300"}`,
|
|
1001
|
+
children: [
|
|
1002
|
+
"Tests ",
|
|
1003
|
+
pendingCount > 0 && `(${pendingCount})`
|
|
1004
|
+
]
|
|
1005
|
+
}
|
|
1006
|
+
),
|
|
1007
|
+
/* @__PURE__ */ jsxs(
|
|
1008
|
+
"button",
|
|
1009
|
+
{
|
|
1010
|
+
onClick: () => setActiveTab("messages"),
|
|
1011
|
+
className: `flex-1 py-3 text-sm font-medium transition-all flex items-center justify-center gap-1.5 relative border-b-2 ${activeTab === "messages" ? "border-blue-500 text-blue-400" : "border-transparent text-zinc-500 hover:text-zinc-300"}`,
|
|
1012
|
+
children: [
|
|
1013
|
+
"Messages",
|
|
1014
|
+
unreadCount > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute top-1.5 ml-16 min-w-[18px] h-[18px] px-1 bg-blue-500 rounded-full text-[10px] text-white font-bold flex items-center justify-center", children: unreadCount })
|
|
1015
|
+
]
|
|
1016
|
+
}
|
|
1017
|
+
),
|
|
1018
|
+
/* @__PURE__ */ jsxs(
|
|
1019
|
+
"button",
|
|
1020
|
+
{
|
|
1021
|
+
onClick: () => setActiveTab("session"),
|
|
1022
|
+
className: `flex-1 py-3 text-sm font-medium transition-all flex items-center justify-center gap-1.5 relative border-b-2 ${activeTab === "session" ? "border-blue-500 text-blue-400" : "border-transparent text-zinc-500 hover:text-zinc-300"}`,
|
|
1023
|
+
children: [
|
|
1024
|
+
"Explore",
|
|
1025
|
+
activeSession && /* @__PURE__ */ jsx2("span", { className: "absolute top-2 ml-14 w-2 h-2 bg-green-500 rounded-full animate-pulse" })
|
|
1026
|
+
]
|
|
1027
|
+
}
|
|
1028
|
+
),
|
|
1029
|
+
/* @__PURE__ */ jsx2(
|
|
1030
|
+
"button",
|
|
1031
|
+
{
|
|
1032
|
+
onClick: () => setActiveTab("report"),
|
|
1033
|
+
className: `flex-1 py-3 text-sm font-medium transition-all flex items-center justify-center gap-1.5 border-b-2 ${activeTab === "report" ? "border-blue-500 text-blue-400" : "border-transparent text-zinc-500 hover:text-zinc-300"}`,
|
|
1034
|
+
children: "Report"
|
|
1035
|
+
}
|
|
1036
|
+
)
|
|
1037
|
+
] }),
|
|
1038
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 max-h-96 overflow-y-auto", children: [
|
|
1039
|
+
activeTab === "tests" && /* @__PURE__ */ jsx2("div", { children: assignments.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
1040
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u2705" }),
|
|
1041
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-400 mt-2 font-medium", children: "All caught up!" }),
|
|
1042
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-sm", children: "No tests assigned" })
|
|
1043
|
+
] }) : testView === "list" ? (
|
|
1044
|
+
/* List View - Show tests grouped by folder */
|
|
1045
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1046
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 px-1", children: [
|
|
1047
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-zinc-500", children: [
|
|
938
1048
|
assignments.length,
|
|
939
|
-
"
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1049
|
+
" test",
|
|
1050
|
+
assignments.length !== 1 ? "s" : "",
|
|
1051
|
+
" assigned"
|
|
1052
|
+
] }),
|
|
1053
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
1054
|
+
/* @__PURE__ */ jsxs("span", { className: "text-green-400", children: [
|
|
1055
|
+
"\u2705 ",
|
|
1056
|
+
assignments.filter((a) => a.status === "passed").length
|
|
1057
|
+
] }),
|
|
1058
|
+
/* @__PURE__ */ jsxs("span", { className: "text-red-400", children: [
|
|
1059
|
+
"\u274C ",
|
|
1060
|
+
assignments.filter((a) => a.status === "failed").length
|
|
1061
|
+
] }),
|
|
1062
|
+
/* @__PURE__ */ jsxs("span", { className: "text-zinc-500", children: [
|
|
1063
|
+
"\u23F3 ",
|
|
1064
|
+
assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length
|
|
1065
|
+
] })
|
|
1066
|
+
] })
|
|
1067
|
+
] }),
|
|
1068
|
+
groupedAssignments.map((folder) => {
|
|
1069
|
+
const groupId = folder.group?.id || "ungrouped";
|
|
1070
|
+
const isCollapsed = collapsedFolders.has(groupId);
|
|
1071
|
+
const completedCount = folder.stats.passed + folder.stats.failed + folder.stats.skipped;
|
|
1072
|
+
return /* @__PURE__ */ jsxs("div", { className: "border border-zinc-700 rounded-lg overflow-hidden", children: [
|
|
1073
|
+
/* @__PURE__ */ jsxs(
|
|
1074
|
+
"button",
|
|
949
1075
|
{
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
children:
|
|
1076
|
+
onClick: () => toggleFolderCollapse(groupId),
|
|
1077
|
+
className: "w-full flex items-center justify-between p-2.5 bg-zinc-800 hover:bg-zinc-700 transition-colors",
|
|
1078
|
+
children: [
|
|
1079
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1080
|
+
/* @__PURE__ */ jsx2("span", { className: "text-sm", children: isCollapsed ? "\u{1F4C1}" : "\u{1F4C2}" }),
|
|
1081
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium text-sm text-zinc-100", children: folder.group?.name || "Other Tests" }),
|
|
1082
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-zinc-500", children: [
|
|
1083
|
+
"(",
|
|
1084
|
+
completedCount,
|
|
1085
|
+
"/",
|
|
1086
|
+
folder.stats.total,
|
|
1087
|
+
")"
|
|
1088
|
+
] })
|
|
1089
|
+
] }),
|
|
1090
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx2("div", { className: "w-16 h-1.5 bg-zinc-700 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx2(
|
|
1092
|
+
"div",
|
|
1093
|
+
{
|
|
1094
|
+
className: "h-full bg-green-500 transition-all",
|
|
1095
|
+
style: { width: `${completedCount / folder.stats.total * 100}%` }
|
|
1096
|
+
}
|
|
1097
|
+
) }),
|
|
1098
|
+
/* @__PURE__ */ jsx2("span", { className: "text-zinc-500 text-xs", children: isCollapsed ? "\u25B6" : "\u25BC" })
|
|
1099
|
+
] })
|
|
1100
|
+
]
|
|
953
1101
|
}
|
|
954
1102
|
),
|
|
955
|
-
/* @__PURE__ */ jsx2("
|
|
956
|
-
|
|
1103
|
+
!isCollapsed && /* @__PURE__ */ jsx2("div", { className: "divide-y divide-zinc-800", children: folder.assignments.map((assignment) => {
|
|
1104
|
+
const statusBadge = getStatusBadge(assignment.status);
|
|
1105
|
+
return /* @__PURE__ */ jsxs(
|
|
1106
|
+
"button",
|
|
1107
|
+
{
|
|
1108
|
+
onClick: () => {
|
|
1109
|
+
setSelectedTestId(assignment.id);
|
|
1110
|
+
setTestView("detail");
|
|
1111
|
+
setShowSteps(false);
|
|
1112
|
+
},
|
|
1113
|
+
className: `w-full text-left p-3 transition-colors ${assignment.id === currentAssignment?.id ? "bg-blue-950/30" : "bg-zinc-900 hover:bg-zinc-800"}`,
|
|
1114
|
+
children: [
|
|
1115
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between mb-1", children: [
|
|
1116
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1117
|
+
/* @__PURE__ */ jsx2("span", { className: "text-xs font-mono text-zinc-500", children: assignment.testCase.testKey }),
|
|
1118
|
+
assignment.isVerification && /* @__PURE__ */ jsx2("span", { className: "text-xs px-1.5 py-0.5 rounded bg-green-900/30 text-green-400 font-medium", children: "\u{1F527} Verify" })
|
|
1119
|
+
] }),
|
|
1120
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1121
|
+
/* @__PURE__ */ jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded font-medium ${statusBadge.className}`, children: [
|
|
1122
|
+
statusBadge.icon,
|
|
1123
|
+
" ",
|
|
1124
|
+
statusBadge.label
|
|
1125
|
+
] }),
|
|
1126
|
+
/* @__PURE__ */ jsx2("span", { className: `text-xs px-1.5 py-0.5 rounded font-medium ${assignment.testCase.priority === "P0" ? "bg-red-900/30 text-red-400" : assignment.testCase.priority === "P1" ? "bg-orange-900/30 text-orange-400" : "bg-zinc-700 text-zinc-400"}`, children: assignment.testCase.priority })
|
|
1127
|
+
] })
|
|
1128
|
+
] }),
|
|
1129
|
+
/* @__PURE__ */ jsx2("h4", { className: "font-medium text-zinc-100 text-sm line-clamp-2", children: assignment.testCase.title }),
|
|
1130
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1 text-xs text-zinc-500", children: [
|
|
1131
|
+
assignment.testCase.track && /* @__PURE__ */ jsx2(
|
|
1132
|
+
"span",
|
|
1133
|
+
{
|
|
1134
|
+
className: "px-1 py-0.5 rounded text-white",
|
|
1135
|
+
style: { backgroundColor: assignment.testCase.track.color },
|
|
1136
|
+
children: templateInfo[assignment.testCase.track.testTemplate || "steps"].icon
|
|
1137
|
+
}
|
|
1138
|
+
),
|
|
1139
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1140
|
+
assignment.testCase.steps.length,
|
|
1141
|
+
" ",
|
|
1142
|
+
assignment.testCase.track?.testTemplate === "checklist" ? "items" : assignment.testCase.track?.testTemplate === "rubric" ? "criteria" : "steps"
|
|
1143
|
+
] }),
|
|
1144
|
+
assignment.id === currentAssignment?.id && /* @__PURE__ */ jsx2("span", { className: "text-blue-400 font-medium", children: "\u2022 Current" })
|
|
1145
|
+
] })
|
|
1146
|
+
]
|
|
1147
|
+
},
|
|
1148
|
+
assignment.id
|
|
1149
|
+
);
|
|
1150
|
+
}) })
|
|
1151
|
+
] }, groupId);
|
|
1152
|
+
})
|
|
1153
|
+
] })
|
|
1154
|
+
) : showFeedbackPrompt && displayedAssignment ? (
|
|
1155
|
+
/* Feedback prompt after completing a test */
|
|
1156
|
+
/* @__PURE__ */ jsxs("div", { className: "p-3", children: [
|
|
1157
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
1158
|
+
/* @__PURE__ */ jsx2("span", { className: "text-3xl", children: pendingFeedbackStatus === "passed" ? "\u2713" : "\u2717" }),
|
|
1159
|
+
/* @__PURE__ */ jsx2("p", { className: `font-semibold mt-1 ${pendingFeedbackStatus === "passed" ? "text-green-400" : "text-red-400"}`, children: pendingFeedbackStatus === "passed" ? "Test Passed!" : "Test Failed" })
|
|
957
1160
|
] }),
|
|
958
|
-
/* @__PURE__ */
|
|
959
|
-
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
/* @__PURE__ */ jsx2("
|
|
965
|
-
|
|
1161
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-blue-950/30 border border-blue-900 rounded-lg p-3 mb-4", children: [
|
|
1162
|
+
/* @__PURE__ */ jsx2("p", { className: "text-blue-300 text-sm font-medium mb-1", children: "Help us improve this test" }),
|
|
1163
|
+
/* @__PURE__ */ jsx2("p", { className: "text-blue-400 text-xs", children: "Your feedback shapes better tests for everyone." })
|
|
1164
|
+
] }),
|
|
1165
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1166
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-400 mb-2", children: "How was this test?" }),
|
|
1167
|
+
/* @__PURE__ */ jsx2("div", { className: "flex items-center gap-1 justify-center", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx2(
|
|
1168
|
+
"button",
|
|
1169
|
+
{
|
|
1170
|
+
type: "button",
|
|
1171
|
+
onClick: () => setFeedbackRating(star),
|
|
1172
|
+
className: `text-2xl transition-colors ${star <= feedbackRating ? "text-yellow-400" : "text-zinc-600"} hover:text-yellow-400`,
|
|
1173
|
+
children: "\u2605"
|
|
1174
|
+
},
|
|
1175
|
+
star
|
|
1176
|
+
)) }),
|
|
1177
|
+
/* @__PURE__ */ jsx2("p", { className: "text-center text-xs text-zinc-500 mt-1", children: feedbackRating === 1 ? "Needs work" : feedbackRating === 2 ? "Could be better" : feedbackRating === 3 ? "Okay" : feedbackRating === 4 ? "Good" : "Great!" })
|
|
1178
|
+
] }),
|
|
1179
|
+
feedbackRating < 4 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1180
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-400 mb-2", children: "What could be improved?" }),
|
|
1181
|
+
/* @__PURE__ */ jsx2("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1182
|
+
{ key: "stepsUnclear", label: "Steps unclear" },
|
|
1183
|
+
{ key: "expectedResultUnclear", label: "Expected result unclear" },
|
|
1184
|
+
{ key: "needsMoreDetail", label: "Needs more detail" },
|
|
1185
|
+
{ key: "isOutdated", label: "Seems outdated" }
|
|
1186
|
+
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
1187
|
+
"button",
|
|
1188
|
+
{
|
|
1189
|
+
type: "button",
|
|
1190
|
+
onClick: () => setFeedbackFlags((prev) => ({ ...prev, [key]: !prev[key] })),
|
|
1191
|
+
className: `px-2 py-1.5 rounded text-xs font-medium border transition-colors ${feedbackFlags[key] ? "bg-blue-900/50 border-blue-700 text-blue-300" : "bg-zinc-800 border-zinc-700 text-zinc-400 hover:border-blue-800"}`,
|
|
1192
|
+
children: label
|
|
1193
|
+
},
|
|
1194
|
+
key
|
|
1195
|
+
)) })
|
|
1196
|
+
] }),
|
|
1197
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1198
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-400 mb-1", children: "Suggestions? (optional)" }),
|
|
1199
|
+
/* @__PURE__ */ jsx2(
|
|
1200
|
+
"textarea",
|
|
1201
|
+
{
|
|
1202
|
+
value: feedbackNote,
|
|
1203
|
+
onChange: (e) => setFeedbackNote(e.target.value),
|
|
1204
|
+
placeholder: "How could this test be improved?",
|
|
1205
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-700 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent placeholder:text-zinc-500",
|
|
1206
|
+
rows: 2
|
|
1207
|
+
}
|
|
1208
|
+
)
|
|
966
1209
|
] }),
|
|
967
|
-
|
|
968
|
-
|
|
1210
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1211
|
+
/* @__PURE__ */ jsx2(
|
|
1212
|
+
"button",
|
|
1213
|
+
{
|
|
1214
|
+
onClick: handleSkipFeedback,
|
|
1215
|
+
disabled: submitting,
|
|
1216
|
+
className: "flex-1 px-3 py-2 text-sm font-medium text-zinc-400 bg-zinc-700 rounded-lg hover:bg-zinc-700 transition-colors disabled:opacity-50",
|
|
1217
|
+
children: "Skip"
|
|
1218
|
+
}
|
|
1219
|
+
),
|
|
1220
|
+
/* @__PURE__ */ jsx2(
|
|
1221
|
+
"button",
|
|
1222
|
+
{
|
|
1223
|
+
onClick: () => handleSubmitFeedback(false),
|
|
1224
|
+
disabled: submitting,
|
|
1225
|
+
className: "flex-1 px-3 py-2 text-sm font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 transition-colors disabled:opacity-50",
|
|
1226
|
+
children: submitting ? "Submitting..." : "Submit Feedback"
|
|
1227
|
+
}
|
|
1228
|
+
)
|
|
1229
|
+
] })
|
|
1230
|
+
] })
|
|
1231
|
+
) : justPassed ? (
|
|
1232
|
+
/* Success state after passing */
|
|
1233
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
1234
|
+
/* @__PURE__ */ jsx2("span", { className: "text-5xl", children: "\u2713" }),
|
|
1235
|
+
/* @__PURE__ */ jsx2("p", { className: "text-green-400 mt-3 font-semibold text-lg", children: "Passed!" }),
|
|
1236
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-sm mt-1", children: "Loading next test..." })
|
|
1237
|
+
] })
|
|
1238
|
+
) : displayedAssignment ? (
|
|
1239
|
+
/* Detail View - Show single test */
|
|
1240
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1241
|
+
/* @__PURE__ */ jsxs(
|
|
969
1242
|
"button",
|
|
970
1243
|
{
|
|
971
|
-
onClick: () =>
|
|
972
|
-
|
|
1244
|
+
onClick: () => {
|
|
1245
|
+
setTestView("list");
|
|
1246
|
+
setSelectedTestId(null);
|
|
1247
|
+
},
|
|
1248
|
+
className: "flex items-center gap-1 text-xs text-blue-400 font-medium hover:text-blue-300 mb-2",
|
|
973
1249
|
children: [
|
|
974
|
-
|
|
975
|
-
|
|
1250
|
+
"\u2190 All Tests (",
|
|
1251
|
+
assignments.length,
|
|
1252
|
+
")"
|
|
976
1253
|
]
|
|
977
1254
|
}
|
|
978
1255
|
),
|
|
979
1256
|
(() => {
|
|
980
|
-
const
|
|
981
|
-
const
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1257
|
+
const currentGroup = displayedAssignment.testCase.group;
|
|
1258
|
+
const groupAssignments = currentGroup ? assignments.filter((a) => a.testCase.group?.id === currentGroup.id) : assignments;
|
|
1259
|
+
const completed = groupAssignments.filter(
|
|
1260
|
+
(a) => a.status === "passed" || a.status === "failed" || a.status === "skipped"
|
|
1261
|
+
).length;
|
|
1262
|
+
const total = groupAssignments.length;
|
|
1263
|
+
const progressPercent = total > 0 ? completed / total * 100 : 0;
|
|
1264
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-3 p-2 bg-blue-950/30 rounded-lg", children: [
|
|
1265
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
1266
|
+
/* @__PURE__ */ jsx2("span", { className: "text-xs font-medium text-blue-300", children: currentGroup ? `\u{1F4C1} ${currentGroup.name}` : "\u{1F4CB} All Tests" }),
|
|
1267
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-blue-400", children: [
|
|
1268
|
+
completed,
|
|
1269
|
+
"/",
|
|
1270
|
+
total,
|
|
1271
|
+
" complete"
|
|
1272
|
+
] })
|
|
1273
|
+
] }),
|
|
1274
|
+
/* @__PURE__ */ jsx2("div", { className: "w-full h-2 bg-zinc-700 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx2(
|
|
986
1275
|
"div",
|
|
987
1276
|
{
|
|
988
|
-
className: "
|
|
989
|
-
style: {
|
|
990
|
-
backgroundColor: displayedAssignment.testCase.track ? `${displayedAssignment.testCase.track.color}15` : "#f3f4f6"
|
|
991
|
-
},
|
|
992
|
-
children: [
|
|
993
|
-
/* @__PURE__ */ jsx2("span", { children: info.icon }),
|
|
994
|
-
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: info.name }),
|
|
995
|
-
/* @__PURE__ */ jsxs("span", { className: "text-gray-500", children: [
|
|
996
|
-
"\u2022 ",
|
|
997
|
-
info.action
|
|
998
|
-
] })
|
|
999
|
-
]
|
|
1000
|
-
}
|
|
1001
|
-
),
|
|
1002
|
-
/* @__PURE__ */ jsxs(
|
|
1003
|
-
"button",
|
|
1004
|
-
{
|
|
1005
|
-
onClick: () => setShowSteps(!showSteps),
|
|
1006
|
-
className: "text-purple-600 text-xs font-medium hover:text-purple-700 flex items-center gap-1",
|
|
1007
|
-
children: [
|
|
1008
|
-
showSteps ? "\u25BC" : "\u25B6",
|
|
1009
|
-
" ",
|
|
1010
|
-
template === "freeform" ? "Instructions" : `${steps.length} ${template === "checklist" ? "items" : template === "rubric" ? "criteria" : "steps"}`
|
|
1011
|
-
]
|
|
1277
|
+
className: "h-full bg-blue-500 transition-all duration-300",
|
|
1278
|
+
style: { width: `${progressPercent}%` }
|
|
1012
1279
|
}
|
|
1013
|
-
),
|
|
1014
|
-
|
|
1015
|
-
/* @__PURE__ */
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1280
|
+
) }),
|
|
1281
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between mt-1 text-[10px] text-blue-400", children: [
|
|
1282
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1283
|
+
"\u2705 ",
|
|
1284
|
+
groupAssignments.filter((a) => a.status === "passed").length,
|
|
1285
|
+
" passed"
|
|
1286
|
+
] }),
|
|
1287
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1288
|
+
"\u274C ",
|
|
1289
|
+
groupAssignments.filter((a) => a.status === "failed").length,
|
|
1290
|
+
" failed"
|
|
1291
|
+
] }),
|
|
1292
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1293
|
+
"\u23ED\uFE0F ",
|
|
1294
|
+
groupAssignments.filter((a) => a.status === "skipped").length,
|
|
1295
|
+
" skipped"
|
|
1022
1296
|
] })
|
|
1023
|
-
] }
|
|
1024
|
-
|
|
1025
|
-
|
|
1297
|
+
] })
|
|
1298
|
+
] });
|
|
1299
|
+
})(),
|
|
1300
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 rounded-lg p-3 mb-3", children: [
|
|
1301
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between mb-2", children: [
|
|
1302
|
+
/* @__PURE__ */ jsx2("span", { className: "text-xs font-mono text-zinc-500", children: displayedAssignment.testCase.testKey }),
|
|
1303
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1304
|
+
displayedAssignment.testCase.track && /* @__PURE__ */ jsx2(
|
|
1305
|
+
"span",
|
|
1306
|
+
{
|
|
1307
|
+
className: "text-xs px-1.5 py-0.5 rounded text-white",
|
|
1308
|
+
style: { backgroundColor: displayedAssignment.testCase.track.color },
|
|
1309
|
+
children: templateInfo[displayedAssignment.testCase.track.testTemplate || "steps"].icon
|
|
1310
|
+
}
|
|
1311
|
+
),
|
|
1312
|
+
/* @__PURE__ */ jsx2("span", { className: `text-xs px-1.5 py-0.5 rounded font-medium ${displayedAssignment.testCase.priority === "P0" ? "bg-red-900/30 text-red-400" : displayedAssignment.testCase.priority === "P1" ? "bg-orange-900/30 text-orange-400" : "bg-zinc-700 text-zinc-400"}`, children: displayedAssignment.testCase.priority })
|
|
1313
|
+
] })
|
|
1314
|
+
] }),
|
|
1315
|
+
/* @__PURE__ */ jsx2("h4", { className: "font-medium text-zinc-100 text-sm mb-1", children: displayedAssignment.testCase.title }),
|
|
1316
|
+
displayedAssignment.status === "in_progress" && displayedAssignment.startedAt && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-2 text-xs text-green-400 bg-green-900/20 px-2 py-1 rounded", children: [
|
|
1317
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
|
|
1318
|
+
/* @__PURE__ */ jsx2("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
|
|
1319
|
+
/* @__PURE__ */ jsx2("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
|
|
1320
|
+
] }),
|
|
1321
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: "Testing" }),
|
|
1322
|
+
/* @__PURE__ */ jsx2("span", { className: "font-mono", children: formatElapsedTime(assignmentElapsedTime) })
|
|
1323
|
+
] }),
|
|
1324
|
+
displayedAssignment.testCase.description && /* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-xs mb-2", children: displayedAssignment.testCase.description }),
|
|
1325
|
+
displayedAssignment.testCase.targetRoute && onNavigate && /* @__PURE__ */ jsxs(
|
|
1326
|
+
"button",
|
|
1327
|
+
{
|
|
1328
|
+
onClick: () => onNavigate(displayedAssignment.testCase.targetRoute),
|
|
1329
|
+
className: "w-full mb-2 py-1.5 px-3 bg-blue-900/20 text-blue-300 border border-blue-800 rounded-lg text-xs font-medium hover:bg-blue-900/30 transition-colors flex items-center justify-center gap-1",
|
|
1330
|
+
children: [
|
|
1331
|
+
/* @__PURE__ */ jsx2("span", { children: "Go to test location" }),
|
|
1332
|
+
/* @__PURE__ */ jsx2("span", { children: "\u2192" })
|
|
1333
|
+
]
|
|
1334
|
+
}
|
|
1335
|
+
),
|
|
1336
|
+
(() => {
|
|
1337
|
+
const template = displayedAssignment.testCase.track?.testTemplate || "steps";
|
|
1338
|
+
const steps = displayedAssignment.testCase.steps;
|
|
1339
|
+
const info = templateInfo[template];
|
|
1340
|
+
const rubricMode = displayedAssignment.testCase.track?.rubricMode || "pass_fail";
|
|
1341
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1342
|
+
/* @__PURE__ */ jsxs(
|
|
1343
|
+
"div",
|
|
1344
|
+
{
|
|
1345
|
+
className: "flex items-center gap-2 text-xs px-2 py-1 rounded mb-2",
|
|
1346
|
+
style: {
|
|
1347
|
+
backgroundColor: displayedAssignment.testCase.track ? `${displayedAssignment.testCase.track.color}15` : "#f3f4f6"
|
|
1348
|
+
},
|
|
1349
|
+
children: [
|
|
1350
|
+
/* @__PURE__ */ jsx2("span", { children: info.icon }),
|
|
1351
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: info.name }),
|
|
1352
|
+
/* @__PURE__ */ jsxs("span", { className: "text-zinc-500", children: [
|
|
1353
|
+
"\u2022 ",
|
|
1354
|
+
info.action
|
|
1355
|
+
] })
|
|
1356
|
+
]
|
|
1357
|
+
}
|
|
1358
|
+
),
|
|
1359
|
+
/* @__PURE__ */ jsxs(
|
|
1026
1360
|
"button",
|
|
1027
1361
|
{
|
|
1028
|
-
onClick: () =>
|
|
1029
|
-
|
|
1030
|
-
if (prev[idx] === true) {
|
|
1031
|
-
delete newResults[idx];
|
|
1032
|
-
} else {
|
|
1033
|
-
newResults[idx] = true;
|
|
1034
|
-
}
|
|
1035
|
-
return newResults;
|
|
1036
|
-
}),
|
|
1037
|
-
className: `w-full flex items-center gap-2 text-xs p-2 rounded border transition-colors text-left ${criteriaResults[idx] === true ? "bg-green-50 border-green-300" : "bg-white border-gray-200 hover:bg-gray-50"}`,
|
|
1362
|
+
onClick: () => setShowSteps(!showSteps),
|
|
1363
|
+
className: "text-blue-400 text-xs font-medium hover:text-blue-300 flex items-center gap-1",
|
|
1038
1364
|
children: [
|
|
1039
|
-
|
|
1040
|
-
|
|
1365
|
+
showSteps ? "\u25BC" : "\u25B6",
|
|
1366
|
+
" ",
|
|
1367
|
+
template === "freeform" ? "Instructions" : `${steps.length} ${template === "checklist" ? "items" : template === "rubric" ? "criteria" : "steps"}`
|
|
1041
1368
|
]
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
)
|
|
1045
|
-
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
|
|
1369
|
+
}
|
|
1370
|
+
),
|
|
1371
|
+
showSteps && template === "steps" && /* @__PURE__ */ jsx2("div", { className: "mt-2 space-y-2", children: steps.map((step, idx) => /* @__PURE__ */ jsxs("div", { className: "flex gap-2 text-xs", children: [
|
|
1372
|
+
/* @__PURE__ */ jsx2("span", { className: "w-5 h-5 rounded-full bg-blue-900/50 text-blue-300 flex items-center justify-center flex-shrink-0 font-medium", children: step.stepNumber }),
|
|
1373
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1374
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-300", children: step.action }),
|
|
1375
|
+
step.expectedResult && /* @__PURE__ */ jsxs("p", { className: "text-zinc-500 mt-0.5", children: [
|
|
1376
|
+
"\u2192 ",
|
|
1377
|
+
step.expectedResult
|
|
1378
|
+
] })
|
|
1379
|
+
] })
|
|
1380
|
+
] }, idx)) }),
|
|
1381
|
+
showSteps && template === "checklist" && /* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-2", children: [
|
|
1382
|
+
steps.map((step, idx) => /* @__PURE__ */ jsxs(
|
|
1048
1383
|
"button",
|
|
1049
1384
|
{
|
|
1050
|
-
onClick: () => setCriteriaResults({
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1385
|
+
onClick: () => setCriteriaResults((prev) => {
|
|
1386
|
+
const newResults = { ...prev };
|
|
1387
|
+
if (prev[idx] === true) {
|
|
1388
|
+
delete newResults[idx];
|
|
1389
|
+
} else {
|
|
1390
|
+
newResults[idx] = true;
|
|
1391
|
+
}
|
|
1392
|
+
return newResults;
|
|
1393
|
+
}),
|
|
1394
|
+
className: `w-full flex items-center gap-2 text-xs p-2 rounded border transition-colors text-left ${criteriaResults[idx] === true ? "bg-green-900/20 border-green-700" : "bg-zinc-900 border-zinc-700 hover:bg-zinc-800"}`,
|
|
1395
|
+
children: [
|
|
1396
|
+
/* @__PURE__ */ jsx2("span", { className: `w-5 h-5 rounded border-2 flex items-center justify-center ${criteriaResults[idx] === true ? "bg-green-500 border-green-500 text-white" : "border-cyan-400 text-cyan-600"}`, children: criteriaResults[idx] === true ? "\u2713" : "" }),
|
|
1397
|
+
/* @__PURE__ */ jsx2("p", { className: `flex-1 ${criteriaResults[idx] === true ? "text-green-400" : "text-zinc-300"}`, children: step.action })
|
|
1398
|
+
]
|
|
1399
|
+
},
|
|
1400
|
+
idx
|
|
1401
|
+
)),
|
|
1402
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-2", children: [
|
|
1403
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500", children: "Tap to check off each item." }),
|
|
1404
|
+
Object.keys(criteriaResults).length > 0 && /* @__PURE__ */ jsx2(
|
|
1066
1405
|
"button",
|
|
1067
1406
|
{
|
|
1068
|
-
onClick: () => setCriteriaResults(
|
|
1069
|
-
className:
|
|
1070
|
-
children: "\
|
|
1407
|
+
onClick: () => setCriteriaResults({}),
|
|
1408
|
+
className: "text-xs text-zinc-500 hover:text-red-500 transition-colors",
|
|
1409
|
+
children: "\u21BA Reset"
|
|
1071
1410
|
}
|
|
1072
|
-
)
|
|
1073
|
-
|
|
1411
|
+
)
|
|
1412
|
+
] })
|
|
1413
|
+
] }),
|
|
1414
|
+
showSteps && template === "rubric" && /* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-2", children: [
|
|
1415
|
+
steps.map((step, idx) => /* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 p-2 rounded border border-zinc-700", children: [
|
|
1416
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs mb-1", children: [
|
|
1417
|
+
/* @__PURE__ */ jsx2("span", { className: "w-5 h-5 rounded bg-blue-900/50 text-blue-300 flex items-center justify-center font-medium", children: idx + 1 }),
|
|
1418
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-100 font-medium flex-1", children: step.action })
|
|
1419
|
+
] }),
|
|
1420
|
+
step.expectedResult && /* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500 ml-7 mb-2", children: step.expectedResult }),
|
|
1421
|
+
rubricMode === "pass_fail" && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 ml-7", children: [
|
|
1422
|
+
/* @__PURE__ */ jsx2(
|
|
1423
|
+
"button",
|
|
1424
|
+
{
|
|
1425
|
+
onClick: () => setCriteriaResults((prev) => ({ ...prev, [idx]: true })),
|
|
1426
|
+
className: `flex-1 py-1 px-2 rounded text-xs font-medium transition-colors ${criteriaResults[idx] === true ? "bg-green-500 text-white" : "bg-zinc-700 text-zinc-400 hover:bg-green-900/30"}`,
|
|
1427
|
+
children: "\u2713 Pass"
|
|
1428
|
+
}
|
|
1429
|
+
),
|
|
1430
|
+
/* @__PURE__ */ jsx2(
|
|
1431
|
+
"button",
|
|
1432
|
+
{
|
|
1433
|
+
onClick: () => setCriteriaResults((prev) => ({ ...prev, [idx]: false })),
|
|
1434
|
+
className: `flex-1 py-1 px-2 rounded text-xs font-medium transition-colors ${criteriaResults[idx] === false ? "bg-red-500 text-white" : "bg-zinc-700 text-zinc-400 hover:bg-red-900/30"}`,
|
|
1435
|
+
children: "\u2717 Fail"
|
|
1436
|
+
}
|
|
1437
|
+
)
|
|
1438
|
+
] }),
|
|
1439
|
+
rubricMode === "rating" && /* @__PURE__ */ jsx2("div", { className: "flex gap-1 ml-7", children: [1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsx2(
|
|
1440
|
+
"button",
|
|
1441
|
+
{
|
|
1442
|
+
onClick: () => setCriteriaResults((prev) => ({ ...prev, [idx]: n })),
|
|
1443
|
+
className: `w-8 h-8 rounded font-medium text-sm transition-colors ${criteriaResults[idx] === n ? "bg-blue-500 text-white" : "bg-zinc-700 text-zinc-400 hover:bg-blue-900/50"}`,
|
|
1444
|
+
children: n
|
|
1445
|
+
},
|
|
1446
|
+
n
|
|
1447
|
+
)) })
|
|
1448
|
+
] }, idx)),
|
|
1449
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-2", children: [
|
|
1450
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500", children: rubricMode === "rating" ? "Rate 1-5 for each criterion." : "Mark each criterion as Pass or Fail." }),
|
|
1451
|
+
Object.keys(criteriaResults).length > 0 && /* @__PURE__ */ jsx2(
|
|
1074
1452
|
"button",
|
|
1075
1453
|
{
|
|
1076
|
-
onClick: () => setCriteriaResults(
|
|
1077
|
-
className:
|
|
1078
|
-
children: "\
|
|
1454
|
+
onClick: () => setCriteriaResults({}),
|
|
1455
|
+
className: "text-xs text-zinc-500 hover:text-red-500 transition-colors",
|
|
1456
|
+
children: "\u21BA Reset"
|
|
1079
1457
|
}
|
|
1080
1458
|
)
|
|
1081
|
-
] })
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
},
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
] }, idx)),
|
|
1092
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-2", children: [
|
|
1093
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-400", children: rubricMode === "rating" ? "Rate 1-5 for each criterion." : "Mark each criterion as Pass or Fail." }),
|
|
1094
|
-
Object.keys(criteriaResults).length > 0 && /* @__PURE__ */ jsx2(
|
|
1095
|
-
"button",
|
|
1096
|
-
{
|
|
1097
|
-
onClick: () => setCriteriaResults({}),
|
|
1098
|
-
className: "text-xs text-gray-400 hover:text-red-500 transition-colors",
|
|
1099
|
-
children: "\u21BA Reset"
|
|
1100
|
-
}
|
|
1101
|
-
)
|
|
1459
|
+
] })
|
|
1460
|
+
] }),
|
|
1461
|
+
showSteps && template === "freeform" && /* @__PURE__ */ jsxs("div", { className: "mt-2 p-2 bg-amber-900/20 rounded border border-amber-800 text-xs", children: [
|
|
1462
|
+
/* @__PURE__ */ jsx2("p", { className: "text-amber-300 font-medium mb-1", children: "\u{1F4AD} Open Observation" }),
|
|
1463
|
+
/* @__PURE__ */ jsx2("p", { className: "text-amber-400", children: "Review the area described above and note:" }),
|
|
1464
|
+
/* @__PURE__ */ jsxs("ul", { className: "text-amber-400 mt-1 ml-4 list-disc", children: [
|
|
1465
|
+
/* @__PURE__ */ jsx2("li", { children: "What works well" }),
|
|
1466
|
+
/* @__PURE__ */ jsx2("li", { children: "Issues or concerns" }),
|
|
1467
|
+
/* @__PURE__ */ jsx2("li", { children: "Suggestions" })
|
|
1468
|
+
] })
|
|
1102
1469
|
] })
|
|
1103
|
-
] })
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1470
|
+
] });
|
|
1471
|
+
})(),
|
|
1472
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 p-2 bg-green-900/20 rounded text-xs text-green-400", children: [
|
|
1473
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: displayedAssignment.testCase.track?.testTemplate === "checklist" ? "Pass criteria:" : displayedAssignment.testCase.track?.testTemplate === "rubric" ? "Target score:" : "Expected:" }),
|
|
1474
|
+
" ",
|
|
1475
|
+
displayedAssignment.testCase.expectedResult
|
|
1476
|
+
] })
|
|
1477
|
+
] }),
|
|
1478
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1479
|
+
/* @__PURE__ */ jsx2(
|
|
1480
|
+
"button",
|
|
1481
|
+
{
|
|
1482
|
+
onClick: handleFail,
|
|
1483
|
+
disabled: submitting || skipping,
|
|
1484
|
+
className: "flex-1 py-2 px-3 bg-red-900/30 text-red-400 rounded-lg font-medium text-sm hover:bg-red-800/30 disabled:opacity-50 transition-colors",
|
|
1485
|
+
children: "\u2717 Fail"
|
|
1486
|
+
}
|
|
1487
|
+
),
|
|
1488
|
+
/* @__PURE__ */ jsx2(
|
|
1489
|
+
"button",
|
|
1490
|
+
{
|
|
1491
|
+
onClick: handleOpenSkipModal,
|
|
1492
|
+
disabled: submitting || skipping,
|
|
1493
|
+
className: "py-2 px-3 bg-yellow-900/30 text-yellow-400 rounded-lg font-medium text-sm hover:bg-yellow-800/30 disabled:opacity-50 transition-colors",
|
|
1494
|
+
children: "\u23ED\uFE0F Skip"
|
|
1495
|
+
}
|
|
1496
|
+
),
|
|
1497
|
+
/* @__PURE__ */ jsx2(
|
|
1498
|
+
"button",
|
|
1499
|
+
{
|
|
1500
|
+
onClick: handlePass,
|
|
1501
|
+
disabled: submitting || skipping,
|
|
1502
|
+
className: "flex-1 py-2 px-3 bg-green-600 text-white rounded-lg font-medium text-sm hover:bg-green-700 disabled:opacity-50 transition-colors",
|
|
1503
|
+
children: submitting ? "..." : "\u2713 Pass"
|
|
1504
|
+
}
|
|
1505
|
+
)
|
|
1506
|
+
] }),
|
|
1507
|
+
showSkipModal && /* @__PURE__ */ jsx2("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", onClick: () => setShowSkipModal(false), children: /* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 rounded-xl p-4 w-72 shadow-xl border border-zinc-700", onClick: (e) => e.stopPropagation(), children: [
|
|
1508
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100 mb-3", children: "Skip Test" }),
|
|
1509
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500 mb-3", children: "Please select a reason for skipping this test." }),
|
|
1510
|
+
/* @__PURE__ */ jsx2("div", { className: "space-y-2 mb-4", children: skipReasonOptions.map((option) => /* @__PURE__ */ jsxs(
|
|
1511
|
+
"button",
|
|
1512
|
+
{
|
|
1513
|
+
onClick: () => setSelectedSkipReason(option.value),
|
|
1514
|
+
className: `w-full text-left p-2.5 rounded-lg border transition-colors ${selectedSkipReason === option.value ? "bg-yellow-900/20 border-yellow-700 text-yellow-300" : "bg-zinc-800 border-zinc-700 text-zinc-300 hover:border-yellow-800"}`,
|
|
1515
|
+
children: [
|
|
1516
|
+
/* @__PURE__ */ jsx2("div", { className: "font-medium text-sm", children: option.label }),
|
|
1517
|
+
/* @__PURE__ */ jsx2("div", { className: "text-xs text-zinc-500", children: option.description })
|
|
1518
|
+
]
|
|
1519
|
+
},
|
|
1520
|
+
option.value
|
|
1521
|
+
)) }),
|
|
1522
|
+
selectedSkipReason === "other" && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1523
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-400 mb-1", children: "Notes (required)" }),
|
|
1524
|
+
/* @__PURE__ */ jsx2(
|
|
1525
|
+
"textarea",
|
|
1526
|
+
{
|
|
1527
|
+
value: skipNotes,
|
|
1528
|
+
onChange: (e) => setSkipNotes(e.target.value),
|
|
1529
|
+
placeholder: "Please explain why you're skipping...",
|
|
1530
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-700 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:border-transparent placeholder:text-zinc-500",
|
|
1531
|
+
rows: 2
|
|
1532
|
+
}
|
|
1533
|
+
)
|
|
1534
|
+
] }),
|
|
1535
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1536
|
+
/* @__PURE__ */ jsx2(
|
|
1537
|
+
"button",
|
|
1538
|
+
{
|
|
1539
|
+
onClick: () => setShowSkipModal(false),
|
|
1540
|
+
className: "flex-1 py-2 px-3 text-sm font-medium text-zinc-400 bg-zinc-700 rounded-lg hover:bg-zinc-700 transition-colors",
|
|
1541
|
+
children: "Cancel"
|
|
1542
|
+
}
|
|
1543
|
+
),
|
|
1544
|
+
/* @__PURE__ */ jsx2(
|
|
1545
|
+
"button",
|
|
1546
|
+
{
|
|
1547
|
+
onClick: handleSkip,
|
|
1548
|
+
disabled: !selectedSkipReason || selectedSkipReason === "other" && !skipNotes.trim() || skipping,
|
|
1549
|
+
className: "flex-1 py-2 px-3 text-sm font-medium text-white bg-yellow-500 rounded-lg hover:bg-yellow-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
1550
|
+
children: skipping ? "Skipping..." : "Skip Test"
|
|
1551
|
+
}
|
|
1552
|
+
)
|
|
1553
|
+
] })
|
|
1554
|
+
] }) })
|
|
1555
|
+
] })
|
|
1556
|
+
) : null }),
|
|
1557
|
+
activeTab === "messages" && /* @__PURE__ */ jsx2("div", { children: messageView === "compose" ? (
|
|
1558
|
+
/* Compose New Message */
|
|
1559
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1122
1560
|
/* @__PURE__ */ jsx2(
|
|
1123
1561
|
"button",
|
|
1124
1562
|
{
|
|
1125
|
-
onClick:
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
children: "\u2717 Fail"
|
|
1563
|
+
onClick: handleBackToThreadList,
|
|
1564
|
+
className: "text-sm text-zinc-400 hover:text-zinc-200 mb-3 flex items-center gap-1",
|
|
1565
|
+
children: "\u2190 Back to Messages"
|
|
1129
1566
|
}
|
|
1130
1567
|
),
|
|
1568
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
1569
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100", children: "New Message" }),
|
|
1570
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-xs mt-1", children: "Send a message to the QA team" })
|
|
1571
|
+
] }),
|
|
1572
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1573
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1574
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Subject" }),
|
|
1575
|
+
/* @__PURE__ */ jsx2(
|
|
1576
|
+
"input",
|
|
1577
|
+
{
|
|
1578
|
+
type: "text",
|
|
1579
|
+
value: composeSubject,
|
|
1580
|
+
onChange: (e) => setComposeSubject(e.target.value),
|
|
1581
|
+
placeholder: "What's this about?",
|
|
1582
|
+
maxLength: 100,
|
|
1583
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500"
|
|
1584
|
+
}
|
|
1585
|
+
)
|
|
1586
|
+
] }),
|
|
1587
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1588
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Message" }),
|
|
1589
|
+
/* @__PURE__ */ jsx2(
|
|
1590
|
+
"textarea",
|
|
1591
|
+
{
|
|
1592
|
+
value: composeMessage,
|
|
1593
|
+
onChange: (e) => setComposeMessage(e.target.value),
|
|
1594
|
+
placeholder: "Write your message...",
|
|
1595
|
+
maxLength: 2e3,
|
|
1596
|
+
rows: 6,
|
|
1597
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500 resize-none"
|
|
1598
|
+
}
|
|
1599
|
+
)
|
|
1600
|
+
] }),
|
|
1601
|
+
/* @__PURE__ */ jsx2(
|
|
1602
|
+
"button",
|
|
1603
|
+
{
|
|
1604
|
+
onClick: handleSendNewMessage,
|
|
1605
|
+
disabled: !composeSubject.trim() || !composeMessage.trim() || sendingNewMessage,
|
|
1606
|
+
className: "w-full py-2 px-4 bg-blue-500 text-white rounded-lg font-medium text-sm hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
1607
|
+
children: sendingNewMessage ? "Sending..." : "Send Message"
|
|
1608
|
+
}
|
|
1609
|
+
)
|
|
1610
|
+
] })
|
|
1611
|
+
] })
|
|
1612
|
+
) : messageView === "thread" && selectedThread ? (
|
|
1613
|
+
/* Thread Detail View */
|
|
1614
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1131
1615
|
/* @__PURE__ */ jsx2(
|
|
1132
1616
|
"button",
|
|
1133
1617
|
{
|
|
1134
|
-
onClick:
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
children: submitting ? "..." : "\u2713 Pass"
|
|
1618
|
+
onClick: handleBackToThreadList,
|
|
1619
|
+
className: "text-sm text-zinc-400 hover:text-zinc-200 mb-3 flex items-center gap-1",
|
|
1620
|
+
children: "\u2190 Back to Messages"
|
|
1138
1621
|
}
|
|
1139
|
-
)
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
activeTab === "session" && /* @__PURE__ */ jsx2("div", { children: !activeSession ? (
|
|
1144
|
-
/* Start Session View */
|
|
1145
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1146
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
1147
|
-
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u{1F50D}" }),
|
|
1148
|
-
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-gray-900 mt-2", children: "Exploratory QA Session" }),
|
|
1149
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-500 text-xs mt-1", children: "Explore freely and capture findings as you go" })
|
|
1150
|
-
] }),
|
|
1151
|
-
focusAreas.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1152
|
-
/* @__PURE__ */ jsxs("label", { className: "block text-xs font-medium text-gray-700 mb-2", children: [
|
|
1153
|
-
"\u{1F4CC} Focus Areas",
|
|
1154
|
-
/* @__PURE__ */ jsx2("span", { className: "ml-1 text-[10px] text-gray-500 font-normal", children: "from your team" })
|
|
1622
|
+
),
|
|
1623
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-4 pb-3 border-b border-zinc-700", children: [
|
|
1624
|
+
/* @__PURE__ */ jsx2("span", { className: "text-lg", children: getThreadTypeIcon(selectedThread.threadType) }),
|
|
1625
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100 text-sm leading-tight", children: selectedThread.subject || "No subject" })
|
|
1155
1626
|
] }),
|
|
1156
|
-
/* @__PURE__ */ jsx2("div", { className: "space-y-
|
|
1157
|
-
"
|
|
1627
|
+
loadingMessages ? /* @__PURE__ */ jsx2("div", { className: "text-center py-6", children: /* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-sm", children: "Loading messages..." }) }) : /* @__PURE__ */ jsx2("div", { className: "space-y-3 mb-4", children: threadMessages.map((message) => /* @__PURE__ */ jsxs(
|
|
1628
|
+
"div",
|
|
1158
1629
|
{
|
|
1159
|
-
|
|
1160
|
-
className: `w-full text-left px-3 py-2 rounded-lg text-xs transition-colors border ${sessionFocusArea === area.name ? "bg-amber-50 border-amber-300 text-amber-700" : "bg-amber-50/50 border-amber-200 text-gray-700 hover:bg-amber-50"}`,
|
|
1630
|
+
className: `p-3 rounded-lg ${message.senderType === "tester" ? "bg-blue-900/30 border border-blue-800 ml-6" : "bg-zinc-800 border border-zinc-700 mr-6"}`,
|
|
1161
1631
|
children: [
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
] }),
|
|
1166
|
-
area.description && /* @__PURE__ */ jsx2("p", { className: "text-[10px] text-gray-500 mt-0.5 line-clamp-2", children: area.description })
|
|
1632
|
+
/* @__PURE__ */ jsx2("p", { className: `text-xs font-medium mb-1 ${message.senderType === "tester" ? "text-blue-300" : "text-zinc-300"}`, children: message.senderType === "tester" ? "You" : message.senderName }),
|
|
1633
|
+
/* @__PURE__ */ jsx2("p", { className: `text-sm ${message.senderType === "tester" ? "text-blue-100" : "text-zinc-200"}`, children: message.content }),
|
|
1634
|
+
/* @__PURE__ */ jsx2("p", { className: `text-[10px] mt-1 ${message.senderType === "tester" ? "text-blue-400/60" : "text-zinc-500"}`, children: formatMessageTime(message.createdAt) })
|
|
1167
1635
|
]
|
|
1168
1636
|
},
|
|
1169
|
-
|
|
1170
|
-
)) })
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1637
|
+
message.id
|
|
1638
|
+
)) }),
|
|
1639
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-3 border-t border-zinc-700", children: [
|
|
1640
|
+
/* @__PURE__ */ jsx2(
|
|
1641
|
+
"input",
|
|
1642
|
+
{
|
|
1643
|
+
type: "text",
|
|
1644
|
+
value: replyText,
|
|
1645
|
+
onChange: (e) => setReplyText(e.target.value),
|
|
1646
|
+
placeholder: "Type a reply...",
|
|
1647
|
+
maxLength: 1e3,
|
|
1648
|
+
className: "flex-1 px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500",
|
|
1649
|
+
onKeyDown: (e) => e.key === "Enter" && !e.shiftKey && handleSendReply()
|
|
1650
|
+
}
|
|
1651
|
+
),
|
|
1652
|
+
/* @__PURE__ */ jsx2(
|
|
1653
|
+
"button",
|
|
1654
|
+
{
|
|
1655
|
+
onClick: handleSendReply,
|
|
1656
|
+
disabled: !replyText.trim() || sendingReply,
|
|
1657
|
+
className: "px-3 py-2 bg-blue-500 text-white text-sm rounded-lg hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
1658
|
+
children: sendingReply ? "..." : "Send"
|
|
1659
|
+
}
|
|
1660
|
+
)
|
|
1661
|
+
] })
|
|
1662
|
+
] })
|
|
1663
|
+
) : (
|
|
1664
|
+
/* Thread List View */
|
|
1665
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1666
|
+
/* @__PURE__ */ jsx2(
|
|
1175
1667
|
"button",
|
|
1176
1668
|
{
|
|
1177
|
-
onClick:
|
|
1178
|
-
className:
|
|
1179
|
-
children:
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1669
|
+
onClick: handleStartNewMessage,
|
|
1670
|
+
className: "w-full flex items-center justify-center gap-2 py-2 px-4 mb-3 bg-blue-500 text-white rounded-lg font-medium text-sm hover:bg-blue-600 transition-colors",
|
|
1671
|
+
children: "\u2709\uFE0F New Message"
|
|
1672
|
+
}
|
|
1673
|
+
),
|
|
1674
|
+
threads.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
1675
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u{1F4AC}" }),
|
|
1676
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-400 mt-2 font-medium", children: "No messages yet" }),
|
|
1677
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-sm", children: "Start a conversation or wait for messages from admins" })
|
|
1678
|
+
] }) : /* @__PURE__ */ jsx2("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ jsxs(
|
|
1679
|
+
"button",
|
|
1680
|
+
{
|
|
1681
|
+
onClick: () => handleOpenThread(thread),
|
|
1682
|
+
className: `w-full text-left p-3 rounded-lg border transition-colors ${thread.unreadCount > 0 ? "bg-blue-900/20 border-blue-800 hover:bg-blue-900/30" : "bg-zinc-800 border-zinc-700 hover:bg-zinc-700"}`,
|
|
1683
|
+
children: [
|
|
1684
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1", children: [
|
|
1685
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 min-w-0 flex-1", children: [
|
|
1686
|
+
thread.isPinned && /* @__PURE__ */ jsx2("span", { className: "text-xs", children: "\u{1F4CC}" }),
|
|
1687
|
+
/* @__PURE__ */ jsx2("span", { className: "text-xs", children: getThreadTypeIcon(thread.threadType) }),
|
|
1688
|
+
/* @__PURE__ */ jsx2("span", { className: `text-sm truncate ${thread.unreadCount > 0 ? "font-semibold text-zinc-100" : "text-zinc-300"}`, children: thread.subject || "No subject" })
|
|
1689
|
+
] }),
|
|
1690
|
+
(thread.priority === "high" || thread.priority === "urgent") && /* @__PURE__ */ jsx2("span", { className: `w-2 h-2 rounded-full flex-shrink-0 ml-2 ${thread.priority === "urgent" ? "bg-red-500" : "bg-orange-500"}` })
|
|
1691
|
+
] }),
|
|
1692
|
+
thread.lastMessage && /* @__PURE__ */ jsxs("p", { className: "text-xs text-zinc-500 truncate", children: [
|
|
1693
|
+
thread.lastMessage.senderName,
|
|
1694
|
+
": ",
|
|
1695
|
+
thread.lastMessage.content
|
|
1696
|
+
] }),
|
|
1697
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mt-1.5", children: [
|
|
1698
|
+
thread.unreadCount > 0 ? /* @__PURE__ */ jsxs("span", { className: "text-[10px] px-1.5 py-0.5 bg-blue-500 text-white rounded-full font-medium", children: [
|
|
1699
|
+
thread.unreadCount,
|
|
1700
|
+
" new"
|
|
1701
|
+
] }) : /* @__PURE__ */ jsx2("span", { className: "text-[10px] text-zinc-600", children: "Read" }),
|
|
1702
|
+
/* @__PURE__ */ jsx2("span", { className: "text-[10px] text-zinc-600", children: formatRelativeTime(thread.lastMessageAt) })
|
|
1703
|
+
] })
|
|
1704
|
+
]
|
|
1183
1705
|
},
|
|
1184
|
-
|
|
1706
|
+
thread.id
|
|
1185
1707
|
)) })
|
|
1186
|
-
] })
|
|
1187
|
-
|
|
1188
|
-
|
|
1708
|
+
] })
|
|
1709
|
+
) }),
|
|
1710
|
+
activeTab === "session" && /* @__PURE__ */ jsx2("div", { children: !activeSession ? (
|
|
1711
|
+
/* Start Session View */
|
|
1712
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1713
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
1714
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u{1F50D}" }),
|
|
1715
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100 mt-2", children: "Exploratory QA Session" }),
|
|
1716
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-xs mt-1", children: "Explore freely and capture findings as you go" })
|
|
1717
|
+
] }),
|
|
1718
|
+
focusAreas.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1719
|
+
/* @__PURE__ */ jsxs("label", { className: "block text-xs font-medium text-zinc-300 mb-2", children: [
|
|
1720
|
+
"\u{1F4CC} Focus Areas",
|
|
1721
|
+
/* @__PURE__ */ jsx2("span", { className: "ml-1 text-[10px] text-zinc-500 font-normal", children: "from your team" })
|
|
1722
|
+
] }),
|
|
1723
|
+
/* @__PURE__ */ jsx2("div", { className: "space-y-1.5", children: focusAreas.map((area) => /* @__PURE__ */ jsxs(
|
|
1724
|
+
"button",
|
|
1725
|
+
{
|
|
1726
|
+
onClick: () => setSessionFocusArea(area.name),
|
|
1727
|
+
className: `w-full text-left px-3 py-2 rounded-lg text-xs transition-colors border ${sessionFocusArea === area.name ? "bg-amber-900/20 border-amber-700 text-amber-400" : "bg-amber-900/20/50 border-amber-800 text-zinc-300 hover:bg-amber-900/20"}`,
|
|
1728
|
+
children: [
|
|
1729
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1730
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: area.name }),
|
|
1731
|
+
/* @__PURE__ */ jsx2("span", { className: `text-[10px] px-1.5 py-0.5 rounded ${area.priority >= 70 ? "bg-red-900/30 text-red-400" : area.priority >= 50 ? "bg-amber-900/30 text-amber-400" : "bg-zinc-700 text-zinc-500"}`, children: area.priority >= 70 ? "Urgent" : area.priority >= 50 ? "Important" : "Suggested" })
|
|
1732
|
+
] }),
|
|
1733
|
+
area.description && /* @__PURE__ */ jsx2("p", { className: "text-[10px] text-zinc-500 mt-0.5 line-clamp-2", children: area.description })
|
|
1734
|
+
]
|
|
1735
|
+
},
|
|
1736
|
+
area.id
|
|
1737
|
+
)) })
|
|
1738
|
+
] }),
|
|
1739
|
+
suggestedRoutes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1740
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-2", children: "\u{1F3AF} Suggested Routes to Explore" }),
|
|
1741
|
+
/* @__PURE__ */ jsx2("div", { className: "space-y-1.5 max-h-32 overflow-y-auto", children: suggestedRoutes.map((suggestion, idx) => /* @__PURE__ */ jsx2(
|
|
1742
|
+
"button",
|
|
1743
|
+
{
|
|
1744
|
+
onClick: () => setSessionFocusArea(suggestion.route),
|
|
1745
|
+
className: `w-full text-left px-3 py-2 rounded-lg text-xs transition-colors border ${sessionFocusArea === suggestion.route ? "bg-blue-950/30 border-blue-700 text-blue-300" : "bg-zinc-800 border-zinc-700 text-zinc-300 hover:bg-zinc-700"}`,
|
|
1746
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1747
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium truncate", children: suggestion.route }),
|
|
1748
|
+
/* @__PURE__ */ jsx2("span", { className: `text-[10px] px-1.5 py-0.5 rounded ${suggestion.priorityScore >= 40 ? "bg-red-900/30 text-red-400" : suggestion.priorityScore >= 25 ? "bg-amber-900/30 text-amber-400" : "bg-zinc-700 text-zinc-500"}`, children: suggestion.reason })
|
|
1749
|
+
] })
|
|
1750
|
+
},
|
|
1751
|
+
idx
|
|
1752
|
+
)) })
|
|
1753
|
+
] }),
|
|
1754
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1755
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Focus Area (optional)" }),
|
|
1756
|
+
/* @__PURE__ */ jsx2(
|
|
1757
|
+
"input",
|
|
1758
|
+
{
|
|
1759
|
+
type: "text",
|
|
1760
|
+
value: sessionFocusArea,
|
|
1761
|
+
onChange: (e) => setSessionFocusArea(e.target.value),
|
|
1762
|
+
placeholder: "e.g., checkout flow, settings page",
|
|
1763
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500"
|
|
1764
|
+
}
|
|
1765
|
+
)
|
|
1766
|
+
] }),
|
|
1767
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1768
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Platform" }),
|
|
1769
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: [
|
|
1770
|
+
{ key: "web", label: "\u{1F310} Web" },
|
|
1771
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
1772
|
+
{ key: "android", label: "\u{1F916} Android" }
|
|
1773
|
+
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
1774
|
+
"button",
|
|
1775
|
+
{
|
|
1776
|
+
onClick: () => setSessionPlatform(key),
|
|
1777
|
+
className: `flex-1 py-2 px-3 rounded-lg text-xs font-medium transition-colors border-2 ${sessionPlatform === key ? "bg-blue-950/30 border-blue-500 text-blue-300" : "bg-zinc-800 border-transparent text-zinc-400 hover:bg-zinc-700"}`,
|
|
1778
|
+
children: label
|
|
1779
|
+
},
|
|
1780
|
+
key
|
|
1781
|
+
)) })
|
|
1782
|
+
] }),
|
|
1189
1783
|
/* @__PURE__ */ jsx2(
|
|
1190
|
-
"
|
|
1784
|
+
"button",
|
|
1191
1785
|
{
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1786
|
+
onClick: handleStartSession,
|
|
1787
|
+
disabled: startingSession,
|
|
1788
|
+
className: "w-full py-3 px-4 bg-green-600 text-white rounded-lg font-semibold text-sm hover:bg-green-700 disabled:opacity-50 transition-colors flex items-center justify-center gap-2",
|
|
1789
|
+
children: startingSession ? "Starting..." : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1790
|
+
/* @__PURE__ */ jsx2("span", { children: "\u25B6" }),
|
|
1791
|
+
" Start Session"
|
|
1792
|
+
] })
|
|
1197
1793
|
}
|
|
1198
1794
|
)
|
|
1199
|
-
] })
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
{
|
|
1205
|
-
{
|
|
1206
|
-
|
|
1795
|
+
] })
|
|
1796
|
+
) : showEndConfirm ? (
|
|
1797
|
+
/* End Session Confirmation */
|
|
1798
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1799
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-4", children: [
|
|
1800
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u270B" }),
|
|
1801
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100 mt-2", children: "End Session?" }),
|
|
1802
|
+
/* @__PURE__ */ jsxs("p", { className: "text-zinc-500 text-xs mt-1", children: [
|
|
1803
|
+
"Duration: ",
|
|
1804
|
+
formatElapsedTime(sessionElapsedTime),
|
|
1805
|
+
" \u2022 ",
|
|
1806
|
+
sessionFindings.length,
|
|
1807
|
+
" finding",
|
|
1808
|
+
sessionFindings.length !== 1 ? "s" : ""
|
|
1809
|
+
] })
|
|
1810
|
+
] }),
|
|
1811
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1812
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Session Notes (optional)" }),
|
|
1813
|
+
/* @__PURE__ */ jsx2(
|
|
1814
|
+
"textarea",
|
|
1815
|
+
{
|
|
1816
|
+
value: sessionNotes,
|
|
1817
|
+
onChange: (e) => setSessionNotes(e.target.value),
|
|
1818
|
+
placeholder: "Any overall observations from this session...",
|
|
1819
|
+
rows: 3,
|
|
1820
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500 resize-none"
|
|
1821
|
+
}
|
|
1822
|
+
)
|
|
1823
|
+
] }),
|
|
1824
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1825
|
+
/* @__PURE__ */ jsx2(
|
|
1826
|
+
"button",
|
|
1827
|
+
{
|
|
1828
|
+
onClick: () => setShowEndConfirm(false),
|
|
1829
|
+
className: "flex-1 py-2 px-3 bg-zinc-700 text-zinc-300 rounded-lg font-medium text-sm hover:bg-zinc-700 transition-colors",
|
|
1830
|
+
children: "Cancel"
|
|
1831
|
+
}
|
|
1832
|
+
),
|
|
1833
|
+
/* @__PURE__ */ jsx2(
|
|
1834
|
+
"button",
|
|
1835
|
+
{
|
|
1836
|
+
onClick: handleEndSession,
|
|
1837
|
+
disabled: endingSession,
|
|
1838
|
+
className: "flex-1 py-2 px-3 bg-red-600 text-white rounded-lg font-medium text-sm hover:bg-red-700 disabled:opacity-50 transition-colors",
|
|
1839
|
+
children: endingSession ? "Ending..." : "End Session"
|
|
1840
|
+
}
|
|
1841
|
+
)
|
|
1842
|
+
] })
|
|
1843
|
+
] })
|
|
1844
|
+
) : showAddFinding ? (
|
|
1845
|
+
/* Add Finding Form */
|
|
1846
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1847
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
1848
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100 text-sm", children: "Add Finding" }),
|
|
1849
|
+
/* @__PURE__ */ jsx2(
|
|
1850
|
+
"button",
|
|
1851
|
+
{
|
|
1852
|
+
onClick: () => setShowAddFinding(false),
|
|
1853
|
+
className: "text-zinc-500 hover:text-zinc-400",
|
|
1854
|
+
children: "\u2715"
|
|
1855
|
+
}
|
|
1856
|
+
)
|
|
1857
|
+
] }),
|
|
1858
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-1 mb-3", children: [
|
|
1859
|
+
{ type: "bug", label: "\u{1F41B} Bug", color: "red" },
|
|
1860
|
+
{ type: "concern", label: "\u26A0\uFE0F Concern", color: "orange" },
|
|
1861
|
+
{ type: "suggestion", label: "\u{1F4A1} Idea", color: "blue" },
|
|
1862
|
+
{ type: "question", label: "\u2753 Question", color: "purple" }
|
|
1863
|
+
].map(({ type, label, color }) => /* @__PURE__ */ jsx2(
|
|
1207
1864
|
"button",
|
|
1208
1865
|
{
|
|
1209
|
-
onClick: () =>
|
|
1210
|
-
className: `flex-1 py-
|
|
1866
|
+
onClick: () => setFindingType(type),
|
|
1867
|
+
className: `flex-1 py-1.5 px-2 rounded text-xs font-medium transition-colors ${findingType === type ? color === "red" ? "bg-red-900/30 text-red-400 ring-2 ring-red-400" : color === "orange" ? "bg-orange-900/30 text-orange-400 ring-2 ring-orange-400" : color === "blue" ? "bg-blue-900/30 text-blue-300 ring-2 ring-blue-400" : "bg-blue-900/50 text-blue-300 ring-2 ring-blue-400" : "bg-zinc-700 text-zinc-400 hover:bg-zinc-700"}`,
|
|
1211
1868
|
children: label
|
|
1212
1869
|
},
|
|
1213
|
-
|
|
1214
|
-
)) })
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1870
|
+
type
|
|
1871
|
+
)) }),
|
|
1872
|
+
findingType === "bug" && /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1873
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Severity" }),
|
|
1874
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-1", children: ["critical", "high", "medium", "low", "observation"].map((sev) => /* @__PURE__ */ jsx2(
|
|
1875
|
+
"button",
|
|
1876
|
+
{
|
|
1877
|
+
onClick: () => setFindingSeverity(sev),
|
|
1878
|
+
className: `flex-1 py-1 px-1 rounded text-xs font-medium capitalize transition-colors ${findingSeverity === sev ? sev === "critical" ? "bg-red-600 text-white" : sev === "high" ? "bg-orange-500 text-white" : sev === "medium" ? "bg-yellow-500 text-black" : sev === "low" ? "bg-zinc-8000 text-white" : "bg-blue-500 text-white" : "bg-zinc-700 text-zinc-400 hover:bg-zinc-700"}`,
|
|
1879
|
+
children: sev === "observation" ? "obs" : sev
|
|
1880
|
+
},
|
|
1881
|
+
sev
|
|
1882
|
+
)) })
|
|
1883
|
+
] }),
|
|
1884
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1885
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Title *" }),
|
|
1886
|
+
/* @__PURE__ */ jsx2(
|
|
1887
|
+
"input",
|
|
1888
|
+
{
|
|
1889
|
+
type: "text",
|
|
1890
|
+
value: findingTitle,
|
|
1891
|
+
onChange: (e) => setFindingTitle(e.target.value),
|
|
1892
|
+
placeholder: "Brief description of what you found",
|
|
1893
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500"
|
|
1894
|
+
}
|
|
1895
|
+
)
|
|
1896
|
+
] }),
|
|
1897
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1898
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Details (optional)" }),
|
|
1899
|
+
/* @__PURE__ */ jsx2(
|
|
1900
|
+
"textarea",
|
|
1901
|
+
{
|
|
1902
|
+
value: findingDescription,
|
|
1903
|
+
onChange: (e) => setFindingDescription(e.target.value),
|
|
1904
|
+
placeholder: "Steps to reproduce, expected behavior, etc.",
|
|
1905
|
+
rows: 2,
|
|
1906
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500 resize-none"
|
|
1907
|
+
}
|
|
1908
|
+
)
|
|
1909
|
+
] }),
|
|
1246
1910
|
/* @__PURE__ */ jsx2(
|
|
1247
|
-
"
|
|
1911
|
+
"button",
|
|
1248
1912
|
{
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 resize-none"
|
|
1913
|
+
onClick: handleAddFinding,
|
|
1914
|
+
disabled: addingFinding || !findingTitle.trim(),
|
|
1915
|
+
className: "w-full py-2 px-4 bg-blue-500 text-white rounded-lg font-medium text-sm hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
1916
|
+
children: addingFinding ? "Adding..." : "Add Finding"
|
|
1254
1917
|
}
|
|
1255
1918
|
)
|
|
1256
|
-
] })
|
|
1257
|
-
|
|
1258
|
-
|
|
1919
|
+
] })
|
|
1920
|
+
) : (
|
|
1921
|
+
/* Active Session View */
|
|
1922
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1923
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-green-900/20 rounded-lg p-3 mb-3 border border-green-800", children: [
|
|
1924
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1925
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1926
|
+
/* @__PURE__ */ jsx2("span", { className: "w-2 h-2 bg-green-500 rounded-full animate-pulse" }),
|
|
1927
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium text-green-300 text-sm", children: "Session Active" })
|
|
1928
|
+
] }),
|
|
1929
|
+
/* @__PURE__ */ jsx2("span", { className: "font-mono text-green-400 text-lg font-semibold", children: formatElapsedTime(sessionElapsedTime) })
|
|
1930
|
+
] }),
|
|
1931
|
+
activeSession.focusArea && /* @__PURE__ */ jsxs("p", { className: "text-green-400 text-xs mt-1", children: [
|
|
1932
|
+
"Focus: ",
|
|
1933
|
+
activeSession.focusArea
|
|
1934
|
+
] })
|
|
1935
|
+
] }),
|
|
1936
|
+
/* @__PURE__ */ jsxs(
|
|
1259
1937
|
"button",
|
|
1260
1938
|
{
|
|
1261
|
-
onClick: () =>
|
|
1262
|
-
className: "
|
|
1263
|
-
children:
|
|
1939
|
+
onClick: () => setShowAddFinding(true),
|
|
1940
|
+
className: "w-full py-3 px-4 bg-blue-500 text-white rounded-lg font-semibold text-sm hover:bg-blue-600 transition-colors flex items-center justify-center gap-2 mb-3",
|
|
1941
|
+
children: [
|
|
1942
|
+
/* @__PURE__ */ jsx2("span", { children: "+" }),
|
|
1943
|
+
" Add Finding"
|
|
1944
|
+
]
|
|
1264
1945
|
}
|
|
1265
1946
|
),
|
|
1947
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1948
|
+
/* @__PURE__ */ jsx2("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-zinc-500", children: [
|
|
1949
|
+
"Findings (",
|
|
1950
|
+
sessionFindings.length,
|
|
1951
|
+
")"
|
|
1952
|
+
] }) }),
|
|
1953
|
+
sessionFindings.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-4 bg-zinc-800 rounded-lg", children: [
|
|
1954
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-xs", children: "No findings yet" }),
|
|
1955
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-500 text-xs", children: "Explore and add findings as you go" })
|
|
1956
|
+
] }) : /* @__PURE__ */ jsx2("div", { className: "space-y-2 max-h-32 overflow-y-auto", children: sessionFindings.map((finding) => /* @__PURE__ */ jsx2(
|
|
1957
|
+
"div",
|
|
1958
|
+
{
|
|
1959
|
+
className: `p-2 rounded-lg border text-xs ${finding.type === "bug" ? "bg-red-900/20 border-red-800" : finding.type === "concern" ? "bg-orange-900/20 border-orange-200" : finding.type === "suggestion" ? "bg-blue-900/20 border-blue-800" : "bg-blue-950/30 border-blue-800"}`,
|
|
1960
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
1961
|
+
/* @__PURE__ */ jsx2("span", { children: finding.type === "bug" ? "\u{1F41B}" : finding.type === "concern" ? "\u26A0\uFE0F" : finding.type === "suggestion" ? "\u{1F4A1}" : "\u2753" }),
|
|
1962
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1963
|
+
/* @__PURE__ */ jsx2("p", { className: "font-medium text-zinc-100 truncate", children: finding.title }),
|
|
1964
|
+
finding.severity && finding.type === "bug" && /* @__PURE__ */ jsx2("span", { className: `inline-block mt-0.5 px-1 py-0.5 rounded text-[10px] font-medium ${finding.severity === "critical" ? "bg-red-900/40 text-red-300" : finding.severity === "high" ? "bg-orange-900/40 text-orange-300" : finding.severity === "medium" ? "bg-yellow-900/40 text-yellow-300" : "bg-zinc-700 text-zinc-300"}`, children: finding.severity })
|
|
1965
|
+
] })
|
|
1966
|
+
] })
|
|
1967
|
+
},
|
|
1968
|
+
finding.id
|
|
1969
|
+
)) })
|
|
1970
|
+
] }),
|
|
1266
1971
|
/* @__PURE__ */ jsx2(
|
|
1267
1972
|
"button",
|
|
1268
1973
|
{
|
|
1269
|
-
onClick:
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
children: endingSession ? "Ending..." : "End Session"
|
|
1974
|
+
onClick: () => setShowEndConfirm(true),
|
|
1975
|
+
className: "w-full py-2 px-4 bg-zinc-700 text-zinc-300 rounded-lg font-medium text-sm hover:bg-zinc-700 transition-colors",
|
|
1976
|
+
children: "End Session"
|
|
1273
1977
|
}
|
|
1274
1978
|
)
|
|
1275
1979
|
] })
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
/* @__PURE__ */ jsx2(
|
|
1283
|
-
"button",
|
|
1284
|
-
{
|
|
1285
|
-
onClick: () => setShowAddFinding(false),
|
|
1286
|
-
className: "text-gray-400 hover:text-gray-600",
|
|
1287
|
-
children: "\u2715"
|
|
1288
|
-
}
|
|
1289
|
-
)
|
|
1290
|
-
] }),
|
|
1291
|
-
/* @__PURE__ */ jsx2("div", { className: "flex gap-1 mb-3", children: [
|
|
1980
|
+
) }),
|
|
1981
|
+
activeTab === "report" && /* @__PURE__ */ jsx2("div", { children: submitted ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u{1F389}" }),
|
|
1983
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-400 mt-2 font-medium", children: "Report submitted!" })
|
|
1984
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1985
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-2 mb-4", children: [
|
|
1292
1986
|
{ type: "bug", label: "\u{1F41B} Bug", color: "red" },
|
|
1293
|
-
{ type: "
|
|
1294
|
-
{ type: "suggestion", label: "\
|
|
1295
|
-
{ type: "question", label: "\u2753 Question", color: "purple" }
|
|
1987
|
+
{ type: "feedback", label: "\u{1F4A1} Feedback", color: "blue" },
|
|
1988
|
+
{ type: "suggestion", label: "\u2728 Idea", color: "purple" }
|
|
1296
1989
|
].map(({ type, label, color }) => /* @__PURE__ */ jsx2(
|
|
1297
1990
|
"button",
|
|
1298
1991
|
{
|
|
1299
|
-
onClick: () =>
|
|
1300
|
-
className: `flex-1 py-1.5 px-2 rounded text-xs font-medium transition-colors ${
|
|
1992
|
+
onClick: () => setReportType(type),
|
|
1993
|
+
className: `flex-1 py-1.5 px-2 rounded-lg text-xs font-medium transition-colors ${reportType === type ? color === "red" ? "bg-red-900/30 text-red-400 ring-2 ring-red-500" : color === "blue" ? "bg-blue-900/30 text-blue-300 ring-2 ring-blue-500" : "bg-blue-900/50 text-blue-300 ring-2 ring-blue-500" : "bg-zinc-700 text-zinc-400 hover:bg-zinc-700"}`,
|
|
1301
1994
|
children: label
|
|
1302
1995
|
},
|
|
1303
1996
|
type
|
|
1304
1997
|
)) }),
|
|
1305
|
-
|
|
1306
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-
|
|
1307
|
-
/* @__PURE__ */ jsx2("div", { className: "flex gap-1", children: ["critical", "high", "medium", "low"
|
|
1998
|
+
(reportType === "bug" || reportType === "test_fail") && /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1999
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Severity" }),
|
|
2000
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-1", children: ["critical", "high", "medium", "low"].map((sev) => /* @__PURE__ */ jsx2(
|
|
1308
2001
|
"button",
|
|
1309
2002
|
{
|
|
1310
|
-
onClick: () =>
|
|
1311
|
-
className: `flex-1 py-1 px-
|
|
1312
|
-
children: sev
|
|
2003
|
+
onClick: () => setSeverity(sev),
|
|
2004
|
+
className: `flex-1 py-1 px-2 rounded text-xs font-medium capitalize transition-colors ${severity === sev ? sev === "critical" ? "bg-red-600 text-white" : sev === "high" ? "bg-orange-500 text-white" : sev === "medium" ? "bg-yellow-500 text-black" : "bg-zinc-8000 text-white" : "bg-zinc-700 text-zinc-400 hover:bg-zinc-700"}`,
|
|
2005
|
+
children: sev
|
|
1313
2006
|
},
|
|
1314
2007
|
sev
|
|
1315
2008
|
)) })
|
|
1316
2009
|
] }),
|
|
1317
2010
|
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1318
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-
|
|
1319
|
-
/* @__PURE__ */ jsx2(
|
|
1320
|
-
"input",
|
|
1321
|
-
{
|
|
1322
|
-
type: "text",
|
|
1323
|
-
value: findingTitle,
|
|
1324
|
-
onChange: (e) => setFindingTitle(e.target.value),
|
|
1325
|
-
placeholder: "Brief description of what you found",
|
|
1326
|
-
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
|
|
1327
|
-
}
|
|
1328
|
-
)
|
|
1329
|
-
] }),
|
|
1330
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1331
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Details (optional)" }),
|
|
2011
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "What happened?" }),
|
|
1332
2012
|
/* @__PURE__ */ jsx2(
|
|
1333
2013
|
"textarea",
|
|
1334
2014
|
{
|
|
1335
|
-
value:
|
|
1336
|
-
onChange: (e) =>
|
|
1337
|
-
placeholder: "
|
|
1338
|
-
rows:
|
|
1339
|
-
className: "w-full px-3 py-2 text-sm border border-
|
|
2015
|
+
value: description,
|
|
2016
|
+
onChange: (e) => setDescription(e.target.value),
|
|
2017
|
+
placeholder: "Describe the issue...",
|
|
2018
|
+
rows: 3,
|
|
2019
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500 resize-none"
|
|
1340
2020
|
}
|
|
1341
2021
|
)
|
|
1342
2022
|
] }),
|
|
1343
2023
|
/* @__PURE__ */ jsx2(
|
|
1344
2024
|
"button",
|
|
1345
2025
|
{
|
|
1346
|
-
onClick:
|
|
1347
|
-
disabled:
|
|
1348
|
-
className: "w-full py-2 px-4 bg-
|
|
1349
|
-
children:
|
|
2026
|
+
onClick: handleSubmitReport,
|
|
2027
|
+
disabled: submitting || !description.trim(),
|
|
2028
|
+
className: "w-full py-2 px-4 bg-blue-500 text-white rounded-lg font-medium text-sm hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
2029
|
+
children: submitting ? "Submitting..." : "Submit Report"
|
|
1350
2030
|
}
|
|
1351
2031
|
)
|
|
1352
|
-
] })
|
|
1353
|
-
)
|
|
1354
|
-
|
|
1355
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1356
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-green-50 rounded-lg p-3 mb-3 border border-green-200", children: [
|
|
1357
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1358
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1359
|
-
/* @__PURE__ */ jsx2("span", { className: "w-2 h-2 bg-green-500 rounded-full animate-pulse" }),
|
|
1360
|
-
/* @__PURE__ */ jsx2("span", { className: "font-medium text-green-800 text-sm", children: "Session Active" })
|
|
1361
|
-
] }),
|
|
1362
|
-
/* @__PURE__ */ jsx2("span", { className: "font-mono text-green-700 text-lg font-semibold", children: formatElapsedTime(sessionElapsedTime) })
|
|
1363
|
-
] }),
|
|
1364
|
-
activeSession.focusArea && /* @__PURE__ */ jsxs("p", { className: "text-green-700 text-xs mt-1", children: [
|
|
1365
|
-
"Focus: ",
|
|
1366
|
-
activeSession.focusArea
|
|
1367
|
-
] })
|
|
1368
|
-
] }),
|
|
1369
|
-
/* @__PURE__ */ jsxs(
|
|
1370
|
-
"button",
|
|
1371
|
-
{
|
|
1372
|
-
onClick: () => setShowAddFinding(true),
|
|
1373
|
-
className: "w-full py-3 px-4 bg-purple-600 text-white rounded-lg font-semibold text-sm hover:bg-purple-700 transition-colors flex items-center justify-center gap-2 mb-3",
|
|
1374
|
-
children: [
|
|
1375
|
-
/* @__PURE__ */ jsx2("span", { children: "+" }),
|
|
1376
|
-
" Add Finding"
|
|
1377
|
-
]
|
|
1378
|
-
}
|
|
1379
|
-
),
|
|
1380
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1381
|
-
/* @__PURE__ */ jsx2("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-500", children: [
|
|
1382
|
-
"Findings (",
|
|
1383
|
-
sessionFindings.length,
|
|
1384
|
-
")"
|
|
1385
|
-
] }) }),
|
|
1386
|
-
sessionFindings.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-4 bg-gray-50 rounded-lg", children: [
|
|
1387
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-400 text-xs", children: "No findings yet" }),
|
|
1388
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-400 text-xs", children: "Explore and add findings as you go" })
|
|
1389
|
-
] }) : /* @__PURE__ */ jsx2("div", { className: "space-y-2 max-h-32 overflow-y-auto", children: sessionFindings.map((finding) => /* @__PURE__ */ jsx2(
|
|
1390
|
-
"div",
|
|
1391
|
-
{
|
|
1392
|
-
className: `p-2 rounded-lg border text-xs ${finding.type === "bug" ? "bg-red-50 border-red-200" : finding.type === "concern" ? "bg-orange-50 border-orange-200" : finding.type === "suggestion" ? "bg-blue-50 border-blue-200" : "bg-purple-50 border-purple-200"}`,
|
|
1393
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
1394
|
-
/* @__PURE__ */ jsx2("span", { children: finding.type === "bug" ? "\u{1F41B}" : finding.type === "concern" ? "\u26A0\uFE0F" : finding.type === "suggestion" ? "\u{1F4A1}" : "\u2753" }),
|
|
1395
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1396
|
-
/* @__PURE__ */ jsx2("p", { className: "font-medium text-gray-900 truncate", children: finding.title }),
|
|
1397
|
-
finding.severity && finding.type === "bug" && /* @__PURE__ */ jsx2("span", { className: `inline-block mt-0.5 px-1 py-0.5 rounded text-[10px] font-medium ${finding.severity === "critical" ? "bg-red-200 text-red-800" : finding.severity === "high" ? "bg-orange-200 text-orange-800" : finding.severity === "medium" ? "bg-yellow-200 text-yellow-800" : "bg-gray-200 text-gray-700"}`, children: finding.severity })
|
|
1398
|
-
] })
|
|
1399
|
-
] })
|
|
1400
|
-
},
|
|
1401
|
-
finding.id
|
|
1402
|
-
)) })
|
|
1403
|
-
] }),
|
|
2032
|
+
] }) })
|
|
2033
|
+
] }),
|
|
2034
|
+
showProfileOverlay && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-zinc-900 z-50 flex flex-col rounded-xl overflow-hidden", children: [
|
|
2035
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-zinc-950 text-white px-4 py-3 flex items-center justify-between border-b border-zinc-800", children: [
|
|
1404
2036
|
/* @__PURE__ */ jsx2(
|
|
1405
2037
|
"button",
|
|
1406
2038
|
{
|
|
1407
|
-
onClick:
|
|
1408
|
-
className: "
|
|
1409
|
-
children: "
|
|
2039
|
+
onClick: handleCloseProfile,
|
|
2040
|
+
className: "text-sm text-zinc-400 hover:text-white transition-colors",
|
|
2041
|
+
children: "\u2190 Back"
|
|
1410
2042
|
}
|
|
1411
|
-
)
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u{1F389}" }),
|
|
1416
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-600 mt-2 font-medium", children: "Report submitted!" })
|
|
1417
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1418
|
-
/* @__PURE__ */ jsx2("div", { className: "flex gap-2 mb-4", children: [
|
|
1419
|
-
{ type: "bug", label: "\u{1F41B} Bug", color: "red" },
|
|
1420
|
-
{ type: "feedback", label: "\u{1F4A1} Feedback", color: "blue" },
|
|
1421
|
-
{ type: "suggestion", label: "\u2728 Idea", color: "purple" }
|
|
1422
|
-
].map(({ type, label, color }) => /* @__PURE__ */ jsx2(
|
|
1423
|
-
"button",
|
|
1424
|
-
{
|
|
1425
|
-
onClick: () => setReportType(type),
|
|
1426
|
-
className: `flex-1 py-1.5 px-2 rounded-lg text-xs font-medium transition-colors ${reportType === type ? color === "red" ? "bg-red-100 text-red-700 ring-2 ring-red-500" : color === "blue" ? "bg-blue-100 text-blue-700 ring-2 ring-blue-500" : "bg-purple-100 text-purple-700 ring-2 ring-purple-500" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`,
|
|
1427
|
-
children: label
|
|
1428
|
-
},
|
|
1429
|
-
type
|
|
1430
|
-
)) }),
|
|
1431
|
-
(reportType === "bug" || reportType === "test_fail") && /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1432
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Severity" }),
|
|
1433
|
-
/* @__PURE__ */ jsx2("div", { className: "flex gap-1", children: ["critical", "high", "medium", "low"].map((sev) => /* @__PURE__ */ jsx2(
|
|
1434
|
-
"button",
|
|
1435
|
-
{
|
|
1436
|
-
onClick: () => setSeverity(sev),
|
|
1437
|
-
className: `flex-1 py-1 px-2 rounded text-xs font-medium capitalize transition-colors ${severity === sev ? sev === "critical" ? "bg-red-600 text-white" : sev === "high" ? "bg-orange-500 text-white" : sev === "medium" ? "bg-yellow-500 text-black" : "bg-gray-500 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`,
|
|
1438
|
-
children: sev
|
|
1439
|
-
},
|
|
1440
|
-
sev
|
|
1441
|
-
)) })
|
|
1442
|
-
] }),
|
|
1443
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
1444
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "What happened?" }),
|
|
1445
|
-
/* @__PURE__ */ jsx2(
|
|
1446
|
-
"textarea",
|
|
1447
|
-
{
|
|
1448
|
-
value: description,
|
|
1449
|
-
onChange: (e) => setDescription(e.target.value),
|
|
1450
|
-
placeholder: "Describe the issue...",
|
|
1451
|
-
rows: 3,
|
|
1452
|
-
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 resize-none"
|
|
1453
|
-
}
|
|
1454
|
-
)
|
|
2043
|
+
),
|
|
2044
|
+
/* @__PURE__ */ jsx2("span", { className: "font-semibold text-sm", children: "Profile" }),
|
|
2045
|
+
/* @__PURE__ */ jsx2("div", { className: "w-12" }),
|
|
2046
|
+
" "
|
|
1455
2047
|
] }),
|
|
1456
|
-
/* @__PURE__ */ jsx2(
|
|
1457
|
-
"
|
|
1458
|
-
{
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
)
|
|
1465
|
-
] }) })
|
|
1466
|
-
] }),
|
|
1467
|
-
showProfileOverlay && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-white z-50 flex flex-col rounded-xl overflow-hidden", children: [
|
|
1468
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-purple-600 text-white px-4 py-3 flex items-center justify-between", children: [
|
|
1469
|
-
/* @__PURE__ */ jsx2(
|
|
1470
|
-
"button",
|
|
1471
|
-
{
|
|
1472
|
-
onClick: handleCloseProfile,
|
|
1473
|
-
className: "text-sm text-purple-200 hover:text-white transition-colors",
|
|
1474
|
-
children: "\u2190 Back"
|
|
1475
|
-
}
|
|
1476
|
-
),
|
|
1477
|
-
/* @__PURE__ */ jsx2("span", { className: "font-semibold text-sm", children: "Profile" }),
|
|
1478
|
-
/* @__PURE__ */ jsx2("div", { className: "w-12" }),
|
|
1479
|
-
" "
|
|
1480
|
-
] }),
|
|
1481
|
-
/* @__PURE__ */ jsx2("div", { className: "flex-1 overflow-y-auto p-4", children: profileSaved ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
1482
|
-
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u2705" }),
|
|
1483
|
-
/* @__PURE__ */ jsx2("p", { className: "text-gray-600 mt-2 font-medium", children: "Profile saved!" })
|
|
1484
|
-
] }) : profileEditing ? (
|
|
1485
|
-
/* Edit Profile Form */
|
|
1486
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1487
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
1488
|
-
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-gray-900", children: "Edit Profile" }),
|
|
1489
|
-
/* @__PURE__ */ jsx2(
|
|
1490
|
-
"button",
|
|
1491
|
-
{
|
|
1492
|
-
onClick: handleCancelEditProfile,
|
|
1493
|
-
className: "text-sm text-gray-500 hover:text-gray-700",
|
|
1494
|
-
children: "Cancel"
|
|
1495
|
-
}
|
|
1496
|
-
)
|
|
1497
|
-
] }),
|
|
1498
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1499
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Name" }),
|
|
1500
|
-
/* @__PURE__ */ jsx2(
|
|
1501
|
-
"input",
|
|
1502
|
-
{
|
|
1503
|
-
type: "text",
|
|
1504
|
-
value: profileName,
|
|
1505
|
-
onChange: (e) => setProfileName(e.target.value),
|
|
1506
|
-
placeholder: "Your name",
|
|
1507
|
-
className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
|
|
1508
|
-
}
|
|
1509
|
-
)
|
|
1510
|
-
] }),
|
|
1511
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1512
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Primary Email" }),
|
|
1513
|
-
/* @__PURE__ */ jsxs("div", { className: "px-3 py-2 bg-gray-100 rounded-lg", children: [
|
|
1514
|
-
/* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-700", children: testerInfo?.email }),
|
|
1515
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-400 mt-0.5", children: "Main communication email" })
|
|
1516
|
-
] })
|
|
1517
|
-
] }),
|
|
1518
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1519
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Additional Testing Emails" }),
|
|
1520
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 mb-2", children: "Add other emails you use to test on different accounts" }),
|
|
1521
|
-
profileAdditionalEmails.map((email) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
1522
|
-
/* @__PURE__ */ jsx2("span", { className: "flex-1 px-3 py-1.5 bg-purple-50 text-purple-700 text-sm rounded-full", children: email }),
|
|
2048
|
+
/* @__PURE__ */ jsx2("div", { className: "flex-1 overflow-y-auto p-4", children: profileSaved ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
2049
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u2705" }),
|
|
2050
|
+
/* @__PURE__ */ jsx2("p", { className: "text-zinc-400 mt-2 font-medium", children: "Profile saved!" })
|
|
2051
|
+
] }) : profileEditing ? (
|
|
2052
|
+
/* Edit Profile Form */
|
|
2053
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2054
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2055
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100", children: "Edit Profile" }),
|
|
1523
2056
|
/* @__PURE__ */ jsx2(
|
|
1524
2057
|
"button",
|
|
1525
2058
|
{
|
|
1526
|
-
onClick:
|
|
1527
|
-
className: "text-
|
|
1528
|
-
children: "
|
|
2059
|
+
onClick: handleCancelEditProfile,
|
|
2060
|
+
className: "text-sm text-zinc-500 hover:text-zinc-300",
|
|
2061
|
+
children: "Cancel"
|
|
1529
2062
|
}
|
|
1530
2063
|
)
|
|
1531
|
-
] }
|
|
1532
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2064
|
+
] }),
|
|
2065
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
2066
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Name" }),
|
|
1533
2067
|
/* @__PURE__ */ jsx2(
|
|
1534
2068
|
"input",
|
|
1535
2069
|
{
|
|
1536
|
-
type: "
|
|
1537
|
-
value:
|
|
1538
|
-
onChange: (e) =>
|
|
1539
|
-
placeholder: "
|
|
1540
|
-
className: "
|
|
1541
|
-
onKeyDown: (e) => e.key === "Enter" && handleAddEmail()
|
|
2070
|
+
type: "text",
|
|
2071
|
+
value: profileName,
|
|
2072
|
+
onChange: (e) => setProfileName(e.target.value),
|
|
2073
|
+
placeholder: "Your name",
|
|
2074
|
+
className: "w-full px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500"
|
|
1542
2075
|
}
|
|
1543
|
-
)
|
|
1544
|
-
|
|
2076
|
+
)
|
|
2077
|
+
] }),
|
|
2078
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
2079
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Primary Email" }),
|
|
2080
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 py-2 bg-zinc-800 rounded-lg", children: [
|
|
2081
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm text-zinc-300", children: testerInfo?.email }),
|
|
2082
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500 mt-0.5", children: "Main communication email" })
|
|
2083
|
+
] })
|
|
2084
|
+
] }),
|
|
2085
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
2086
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Additional Testing Emails" }),
|
|
2087
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500 mb-2", children: "Add other emails you use to test on different accounts" }),
|
|
2088
|
+
profileAdditionalEmails.map((email) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
2089
|
+
/* @__PURE__ */ jsx2("span", { className: "flex-1 px-3 py-1.5 bg-blue-950/30 text-blue-300 text-sm rounded-full", children: email }),
|
|
2090
|
+
/* @__PURE__ */ jsx2(
|
|
2091
|
+
"button",
|
|
2092
|
+
{
|
|
2093
|
+
onClick: () => handleRemoveEmail(email),
|
|
2094
|
+
className: "text-blue-400 hover:text-red-500 text-sm",
|
|
2095
|
+
children: "\u2715"
|
|
2096
|
+
}
|
|
2097
|
+
)
|
|
2098
|
+
] }, email)),
|
|
2099
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
2100
|
+
/* @__PURE__ */ jsx2(
|
|
2101
|
+
"input",
|
|
2102
|
+
{
|
|
2103
|
+
type: "email",
|
|
2104
|
+
value: newEmailInput,
|
|
2105
|
+
onChange: (e) => setNewEmailInput(e.target.value),
|
|
2106
|
+
placeholder: "email@example.com",
|
|
2107
|
+
className: "flex-1 px-3 py-2 text-sm bg-zinc-800 text-zinc-100 border border-zinc-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 placeholder:text-zinc-500",
|
|
2108
|
+
onKeyDown: (e) => e.key === "Enter" && handleAddEmail()
|
|
2109
|
+
}
|
|
2110
|
+
),
|
|
2111
|
+
/* @__PURE__ */ jsx2(
|
|
2112
|
+
"button",
|
|
2113
|
+
{
|
|
2114
|
+
onClick: handleAddEmail,
|
|
2115
|
+
disabled: !newEmailInput.trim(),
|
|
2116
|
+
className: "px-3 py-2 bg-blue-500 text-white text-sm rounded-lg hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
2117
|
+
children: "Add"
|
|
2118
|
+
}
|
|
2119
|
+
)
|
|
2120
|
+
] })
|
|
2121
|
+
] }),
|
|
2122
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
2123
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-zinc-300 mb-1", children: "Testing Platforms" }),
|
|
2124
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500 mb-2", children: "Select the platforms you can test on" }),
|
|
2125
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: [
|
|
2126
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
2127
|
+
{ key: "android", label: "\u{1F916} Android" },
|
|
2128
|
+
{ key: "web", label: "\u{1F310} Web" }
|
|
2129
|
+
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
1545
2130
|
"button",
|
|
1546
2131
|
{
|
|
1547
|
-
onClick:
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
)
|
|
1553
|
-
] })
|
|
1554
|
-
|
|
1555
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
1556
|
-
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Testing Platforms" }),
|
|
1557
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 mb-2", children: "Select the platforms you can test on" }),
|
|
1558
|
-
/* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: [
|
|
1559
|
-
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
1560
|
-
{ key: "android", label: "\u{1F916} Android" },
|
|
1561
|
-
{ key: "web", label: "\u{1F310} Web" }
|
|
1562
|
-
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
2132
|
+
onClick: () => handleTogglePlatform(key),
|
|
2133
|
+
className: `flex-1 py-2 px-3 rounded-lg text-sm font-medium transition-colors border-2 ${profilePlatforms.includes(key) ? "bg-blue-950/30 border-blue-500 text-blue-300" : "bg-zinc-800 border-transparent text-zinc-400 hover:bg-zinc-700"}`,
|
|
2134
|
+
children: label
|
|
2135
|
+
},
|
|
2136
|
+
key
|
|
2137
|
+
)) })
|
|
2138
|
+
] }),
|
|
2139
|
+
/* @__PURE__ */ jsx2(
|
|
1563
2140
|
"button",
|
|
1564
2141
|
{
|
|
1565
|
-
onClick:
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
)
|
|
1571
|
-
] })
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
/* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-500", children: testerInfo?.email }),
|
|
1589
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-6 mt-4 pt-4 border-t border-gray-200", children: [
|
|
1590
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1591
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.assignedTests || 0 }),
|
|
1592
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500", children: "Assigned" })
|
|
1593
|
-
] }),
|
|
1594
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1595
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.completedTests || 0 }),
|
|
1596
|
-
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500", children: "Completed" })
|
|
2142
|
+
onClick: handleSaveProfile,
|
|
2143
|
+
disabled: savingProfile,
|
|
2144
|
+
className: "w-full py-2 px-4 bg-green-600 text-white rounded-lg font-medium text-sm hover:bg-green-700 disabled:opacity-50 transition-colors",
|
|
2145
|
+
children: savingProfile ? "Saving..." : "Save Profile"
|
|
2146
|
+
}
|
|
2147
|
+
)
|
|
2148
|
+
] })
|
|
2149
|
+
) : (
|
|
2150
|
+
/* Profile View */
|
|
2151
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2152
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 rounded-lg p-4 text-center mb-4", children: [
|
|
2153
|
+
/* @__PURE__ */ jsx2("div", { className: "w-16 h-16 mx-auto bg-blue-500 rounded-full flex items-center justify-center mb-3", children: /* @__PURE__ */ jsx2("span", { className: "text-2xl font-semibold text-white", children: testerInfo?.name?.charAt(0)?.toUpperCase() || "?" }) }),
|
|
2154
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-zinc-100", children: testerInfo?.name }),
|
|
2155
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm text-zinc-500", children: testerInfo?.email }),
|
|
2156
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-6 mt-4 pt-4 border-t border-zinc-700", children: [
|
|
2157
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2158
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-blue-400", children: testerInfo?.assignedTests || 0 }),
|
|
2159
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500", children: "Assigned" })
|
|
2160
|
+
] }),
|
|
2161
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2162
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-blue-400", children: testerInfo?.completedTests || 0 }),
|
|
2163
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-zinc-500", children: "Completed" })
|
|
2164
|
+
] })
|
|
1597
2165
|
] })
|
|
1598
|
-
] })
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
2166
|
+
] }),
|
|
2167
|
+
(testerInfo?.additionalEmails?.length || 0) > 0 && /* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 rounded-lg p-3 mb-3", children: [
|
|
2168
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs font-medium text-zinc-500 uppercase tracking-wide mb-2", children: "Additional Emails" }),
|
|
2169
|
+
testerInfo?.additionalEmails?.map((email) => /* @__PURE__ */ jsx2("p", { className: "text-sm text-zinc-300", children: email }, email))
|
|
2170
|
+
] }),
|
|
2171
|
+
(testerInfo?.platforms?.length || 0) > 0 && /* @__PURE__ */ jsxs("div", { className: "bg-zinc-800 rounded-lg p-3 mb-3", children: [
|
|
2172
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs font-medium text-zinc-500 uppercase tracking-wide mb-2", children: "Testing Platforms" }),
|
|
2173
|
+
/* @__PURE__ */ jsx2("div", { className: "flex flex-wrap gap-2", children: testerInfo?.platforms?.map((platform) => /* @__PURE__ */ jsx2(
|
|
2174
|
+
"span",
|
|
2175
|
+
{
|
|
2176
|
+
className: "px-2 py-1 bg-blue-900/50 text-blue-300 text-xs rounded-full font-medium",
|
|
2177
|
+
children: platform === "ios" ? "\u{1F4F1} iOS" : platform === "android" ? "\u{1F916} Android" : "\u{1F310} Web"
|
|
2178
|
+
},
|
|
2179
|
+
platform
|
|
2180
|
+
)) })
|
|
2181
|
+
] }),
|
|
2182
|
+
/* @__PURE__ */ jsx2(
|
|
2183
|
+
"button",
|
|
1608
2184
|
{
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
)
|
|
1614
|
-
] })
|
|
1615
|
-
|
|
1616
|
-
"button",
|
|
1617
|
-
{
|
|
1618
|
-
onClick: handleStartEditProfile,
|
|
1619
|
-
className: "w-full py-2 px-4 bg-purple-600 text-white rounded-lg font-medium text-sm hover:bg-purple-700 transition-colors",
|
|
1620
|
-
children: "Edit Profile"
|
|
1621
|
-
}
|
|
1622
|
-
)
|
|
1623
|
-
] })
|
|
1624
|
-
) })
|
|
1625
|
-
] }),
|
|
1626
|
-
/* @__PURE__ */ jsxs("div", { className: "px-4 py-2 bg-gray-50 border-t border-gray-200 flex items-center justify-between text-xs text-gray-400", children: [
|
|
1627
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
1628
|
-
pendingCount,
|
|
1629
|
-
" pending \xB7 ",
|
|
1630
|
-
inProgressCount,
|
|
1631
|
-
" in progress"
|
|
2185
|
+
onClick: handleStartEditProfile,
|
|
2186
|
+
className: "w-full py-2 px-4 bg-blue-500 text-white rounded-lg font-medium text-sm hover:bg-blue-600 transition-colors",
|
|
2187
|
+
children: "Edit Profile"
|
|
2188
|
+
}
|
|
2189
|
+
)
|
|
2190
|
+
] })
|
|
2191
|
+
) })
|
|
1632
2192
|
] }),
|
|
1633
|
-
/* @__PURE__ */ jsx2(
|
|
1634
|
-
"
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
2193
|
+
/* @__PURE__ */ jsx2("div", { className: "px-4 py-2 bg-zinc-950 border-t border-zinc-800 flex items-center justify-between text-xs text-zinc-500", children: activeTab === "messages" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2194
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2195
|
+
threads.length,
|
|
2196
|
+
" thread",
|
|
2197
|
+
threads.length !== 1 ? "s" : "",
|
|
2198
|
+
" \xB7 ",
|
|
2199
|
+
unreadCount,
|
|
2200
|
+
" unread"
|
|
2201
|
+
] }),
|
|
2202
|
+
/* @__PURE__ */ jsx2(
|
|
2203
|
+
"button",
|
|
2204
|
+
{
|
|
2205
|
+
onClick: refreshThreads,
|
|
2206
|
+
className: "hover:text-zinc-300",
|
|
2207
|
+
children: "\u21BB Refresh"
|
|
2208
|
+
}
|
|
2209
|
+
)
|
|
2210
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2211
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2212
|
+
pendingCount,
|
|
2213
|
+
" pending \xB7 ",
|
|
2214
|
+
inProgressCount,
|
|
2215
|
+
" in progress"
|
|
2216
|
+
] }),
|
|
2217
|
+
/* @__PURE__ */ jsx2(
|
|
2218
|
+
"button",
|
|
2219
|
+
{
|
|
2220
|
+
onClick: refreshAssignments,
|
|
2221
|
+
className: "hover:text-zinc-300",
|
|
2222
|
+
children: "\u21BB Refresh"
|
|
2223
|
+
}
|
|
2224
|
+
)
|
|
2225
|
+
] }) })
|
|
1641
2226
|
] })
|
|
1642
|
-
]
|
|
1643
|
-
|
|
1644
|
-
|
|
2227
|
+
]
|
|
2228
|
+
}
|
|
2229
|
+
),
|
|
2230
|
+
document.body
|
|
1645
2231
|
);
|
|
1646
2232
|
}
|
|
1647
2233
|
|