@bbearai/react-native 0.1.9 → 0.2.1
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 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +1485 -51
- package/dist/index.mjs +1486 -52
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -11472,6 +11472,9 @@ var BugBearClient = class {
|
|
|
11472
11472
|
id,
|
|
11473
11473
|
status,
|
|
11474
11474
|
started_at,
|
|
11475
|
+
skip_reason,
|
|
11476
|
+
is_verification,
|
|
11477
|
+
original_report_id,
|
|
11475
11478
|
test_case:test_cases(
|
|
11476
11479
|
id,
|
|
11477
11480
|
title,
|
|
@@ -11489,6 +11492,12 @@ var BugBearClient = class {
|
|
|
11489
11492
|
test_template,
|
|
11490
11493
|
rubric_mode,
|
|
11491
11494
|
description
|
|
11495
|
+
),
|
|
11496
|
+
group:test_groups(
|
|
11497
|
+
id,
|
|
11498
|
+
name,
|
|
11499
|
+
description,
|
|
11500
|
+
sort_order
|
|
11492
11501
|
)
|
|
11493
11502
|
)
|
|
11494
11503
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true });
|
|
@@ -11500,6 +11509,9 @@ var BugBearClient = class {
|
|
|
11500
11509
|
id: item.id,
|
|
11501
11510
|
status: item.status,
|
|
11502
11511
|
startedAt: item.started_at,
|
|
11512
|
+
skipReason: item.skip_reason,
|
|
11513
|
+
isVerification: item.is_verification || false,
|
|
11514
|
+
originalReportId: item.original_report_id,
|
|
11503
11515
|
testCase: {
|
|
11504
11516
|
id: item.test_case.id,
|
|
11505
11517
|
title: item.test_case.title,
|
|
@@ -11517,6 +11529,12 @@ var BugBearClient = class {
|
|
|
11517
11529
|
testTemplate: item.test_case.track.test_template,
|
|
11518
11530
|
rubricMode: item.test_case.track.rubric_mode || "pass_fail",
|
|
11519
11531
|
description: item.test_case.track.description
|
|
11532
|
+
} : void 0,
|
|
11533
|
+
group: item.test_case.group ? {
|
|
11534
|
+
id: item.test_case.group.id,
|
|
11535
|
+
name: item.test_case.group.name,
|
|
11536
|
+
description: item.test_case.group.description,
|
|
11537
|
+
sortOrder: item.test_case.group.sort_order
|
|
11520
11538
|
} : void 0
|
|
11521
11539
|
}
|
|
11522
11540
|
}));
|
|
@@ -11653,6 +11671,32 @@ var BugBearClient = class {
|
|
|
11653
11671
|
return { success: false, error: message };
|
|
11654
11672
|
}
|
|
11655
11673
|
}
|
|
11674
|
+
/**
|
|
11675
|
+
* Skip a test assignment with a required reason
|
|
11676
|
+
* Marks the assignment as 'skipped' and records why it was skipped
|
|
11677
|
+
*/
|
|
11678
|
+
async skipAssignment(assignmentId, reason, notes) {
|
|
11679
|
+
try {
|
|
11680
|
+
const updateData = {
|
|
11681
|
+
status: "skipped",
|
|
11682
|
+
skip_reason: reason,
|
|
11683
|
+
completed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
11684
|
+
};
|
|
11685
|
+
if (notes) {
|
|
11686
|
+
updateData.notes = notes;
|
|
11687
|
+
}
|
|
11688
|
+
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
11689
|
+
if (error) {
|
|
11690
|
+
console.error("BugBear: Failed to skip assignment", error);
|
|
11691
|
+
return { success: false, error: error.message };
|
|
11692
|
+
}
|
|
11693
|
+
return { success: true };
|
|
11694
|
+
} catch (err) {
|
|
11695
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
11696
|
+
console.error("BugBear: Error skipping assignment", err);
|
|
11697
|
+
return { success: false, error: message };
|
|
11698
|
+
}
|
|
11699
|
+
}
|
|
11656
11700
|
/**
|
|
11657
11701
|
* Submit feedback on a test case to help improve test quality
|
|
11658
11702
|
* This empowers testers to shape better tests over time
|
|
@@ -12751,6 +12795,14 @@ var BugBearContext = createContext({
|
|
|
12751
12795
|
markAsRead: async () => {
|
|
12752
12796
|
},
|
|
12753
12797
|
createThread: async () => ({ success: false }),
|
|
12798
|
+
// QA Sessions
|
|
12799
|
+
activeSession: null,
|
|
12800
|
+
sessionFindings: [],
|
|
12801
|
+
startSession: async () => ({ success: false }),
|
|
12802
|
+
endSession: async () => ({ success: false }),
|
|
12803
|
+
addFinding: async () => ({ success: false }),
|
|
12804
|
+
refreshSession: async () => {
|
|
12805
|
+
},
|
|
12754
12806
|
refreshTesterStatus: async () => {
|
|
12755
12807
|
},
|
|
12756
12808
|
updateTesterProfile: async () => ({ success: false }),
|
|
@@ -12769,6 +12821,8 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12769
12821
|
const [isLoading, setIsLoading] = useState(true);
|
|
12770
12822
|
const [threads, setThreads] = useState([]);
|
|
12771
12823
|
const [unreadCount, setUnreadCount] = useState(0);
|
|
12824
|
+
const [activeSession, setActiveSession] = useState(null);
|
|
12825
|
+
const [sessionFindings, setSessionFindings] = useState([]);
|
|
12772
12826
|
const hasInitialized = useRef(false);
|
|
12773
12827
|
const getDeviceInfo = useCallback(() => {
|
|
12774
12828
|
const { width, height } = Dimensions.get("window");
|
|
@@ -12816,6 +12870,45 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12816
12870
|
}
|
|
12817
12871
|
return result;
|
|
12818
12872
|
}, [client, refreshThreads]);
|
|
12873
|
+
const refreshSession = useCallback(async () => {
|
|
12874
|
+
if (!client) return;
|
|
12875
|
+
const session = await client.getActiveSession();
|
|
12876
|
+
setActiveSession(session);
|
|
12877
|
+
if (session) {
|
|
12878
|
+
const findings = await client.getSessionFindings(session.id);
|
|
12879
|
+
setSessionFindings(findings);
|
|
12880
|
+
} else {
|
|
12881
|
+
setSessionFindings([]);
|
|
12882
|
+
}
|
|
12883
|
+
}, [client]);
|
|
12884
|
+
const startSession = useCallback(async (options = {}) => {
|
|
12885
|
+
if (!client) return { success: false, error: "Client not initialized" };
|
|
12886
|
+
const result = await client.startSession(options);
|
|
12887
|
+
if (result.success && result.session) {
|
|
12888
|
+
setActiveSession(result.session);
|
|
12889
|
+
setSessionFindings([]);
|
|
12890
|
+
}
|
|
12891
|
+
return { success: result.success, error: result.error };
|
|
12892
|
+
}, [client]);
|
|
12893
|
+
const endSession = useCallback(async (notes) => {
|
|
12894
|
+
if (!client || !activeSession) return { success: false, error: "No active session" };
|
|
12895
|
+
const routesCovered = client.getNavigationHistory();
|
|
12896
|
+
const result = await client.endSession(activeSession.id, { notes, routesCovered });
|
|
12897
|
+
if (result.success) {
|
|
12898
|
+
setActiveSession(null);
|
|
12899
|
+
setSessionFindings([]);
|
|
12900
|
+
}
|
|
12901
|
+
return { success: result.success, error: result.error };
|
|
12902
|
+
}, [client, activeSession]);
|
|
12903
|
+
const addFinding = useCallback(async (options) => {
|
|
12904
|
+
if (!client || !activeSession) return { success: false, error: "No active session" };
|
|
12905
|
+
const result = await client.addFinding(activeSession.id, options);
|
|
12906
|
+
if (result.success && result.finding) {
|
|
12907
|
+
setSessionFindings((prev) => [...prev, result.finding]);
|
|
12908
|
+
setActiveSession((prev) => prev ? { ...prev, findingsCount: prev.findingsCount + 1 } : null);
|
|
12909
|
+
}
|
|
12910
|
+
return result;
|
|
12911
|
+
}, [client, activeSession]);
|
|
12819
12912
|
const updateTesterProfile = useCallback(async (updates) => {
|
|
12820
12913
|
if (!client) return { success: false, error: "Client not initialized" };
|
|
12821
12914
|
const result = await client.updateTesterProfile(updates);
|
|
@@ -12842,14 +12935,20 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12842
12935
|
setTesterInfo(info);
|
|
12843
12936
|
setIsTester(!!info);
|
|
12844
12937
|
if (info && qaEnabled) {
|
|
12845
|
-
const [newAssignments, newThreads] = await Promise.all([
|
|
12938
|
+
const [newAssignments, newThreads, session] = await Promise.all([
|
|
12846
12939
|
bugBearClient.getAssignedTests(),
|
|
12847
|
-
bugBearClient.getThreadsForTester()
|
|
12940
|
+
bugBearClient.getThreadsForTester(),
|
|
12941
|
+
bugBearClient.getActiveSession()
|
|
12848
12942
|
]);
|
|
12849
12943
|
setAssignments(newAssignments);
|
|
12850
12944
|
setThreads(newThreads);
|
|
12851
12945
|
const totalUnread = newThreads.reduce((sum, t) => sum + t.unreadCount, 0);
|
|
12852
12946
|
setUnreadCount(totalUnread);
|
|
12947
|
+
setActiveSession(session);
|
|
12948
|
+
if (session) {
|
|
12949
|
+
const findings = await bugBearClient.getSessionFindings(session.id);
|
|
12950
|
+
setSessionFindings(findings);
|
|
12951
|
+
}
|
|
12853
12952
|
}
|
|
12854
12953
|
} catch (err) {
|
|
12855
12954
|
console.error("BugBear: Init error", err);
|
|
@@ -12872,6 +12971,8 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12872
12971
|
}, [enabled, config, initializeBugBear]);
|
|
12873
12972
|
const currentAssignment = assignments.find(
|
|
12874
12973
|
(a) => a.status === "in_progress"
|
|
12974
|
+
) || assignments.find(
|
|
12975
|
+
(a) => a.status === "pending"
|
|
12875
12976
|
) || assignments[0] || null;
|
|
12876
12977
|
const shouldShowWidget = isQAEnabled && isTester;
|
|
12877
12978
|
return /* @__PURE__ */ React.createElement(
|
|
@@ -12896,6 +12997,13 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12896
12997
|
sendMessage,
|
|
12897
12998
|
markAsRead,
|
|
12898
12999
|
createThread,
|
|
13000
|
+
// QA Sessions
|
|
13001
|
+
activeSession,
|
|
13002
|
+
sessionFindings,
|
|
13003
|
+
startSession,
|
|
13004
|
+
endSession,
|
|
13005
|
+
addFinding,
|
|
13006
|
+
refreshSession,
|
|
12899
13007
|
refreshTesterStatus,
|
|
12900
13008
|
updateTesterProfile,
|
|
12901
13009
|
refreshTesterInfo
|
|
@@ -12906,7 +13014,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12906
13014
|
}
|
|
12907
13015
|
|
|
12908
13016
|
// src/BugBearButton.tsx
|
|
12909
|
-
import React2, { useState as useState2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
13017
|
+
import React2, { useState as useState2, useEffect as useEffect2, useRef as useRef2, useMemo, useCallback as useCallback2 } from "react";
|
|
12910
13018
|
import {
|
|
12911
13019
|
View,
|
|
12912
13020
|
Text,
|
|
@@ -12956,7 +13064,13 @@ function BugBearButton({
|
|
|
12956
13064
|
markAsRead,
|
|
12957
13065
|
createThread,
|
|
12958
13066
|
updateTesterProfile,
|
|
12959
|
-
refreshTesterInfo
|
|
13067
|
+
refreshTesterInfo,
|
|
13068
|
+
activeSession,
|
|
13069
|
+
sessionFindings,
|
|
13070
|
+
startSession,
|
|
13071
|
+
endSession,
|
|
13072
|
+
addFinding,
|
|
13073
|
+
refreshSession
|
|
12960
13074
|
} = useBugBear();
|
|
12961
13075
|
const [modalVisible, setModalVisible] = useState2(false);
|
|
12962
13076
|
const [activeTab, setActiveTab] = useState2("tests");
|
|
@@ -13044,39 +13158,250 @@ function BugBearButton({
|
|
|
13044
13158
|
const [submitting, setSubmitting] = useState2(false);
|
|
13045
13159
|
const [submitted, setSubmitted] = useState2(false);
|
|
13046
13160
|
const [justPassed, setJustPassed] = useState2(false);
|
|
13161
|
+
const [showFeedbackPrompt, setShowFeedbackPrompt] = useState2(false);
|
|
13162
|
+
const [pendingFeedbackStatus, setPendingFeedbackStatus] = useState2(null);
|
|
13163
|
+
const [feedbackRating, setFeedbackRating] = useState2(5);
|
|
13164
|
+
const [feedbackNote, setFeedbackNote] = useState2("");
|
|
13165
|
+
const [feedbackFlags, setFeedbackFlags] = useState2({
|
|
13166
|
+
isOutdated: false,
|
|
13167
|
+
needsMoreDetail: false,
|
|
13168
|
+
stepsUnclear: false,
|
|
13169
|
+
expectedResultUnclear: false
|
|
13170
|
+
});
|
|
13047
13171
|
const [criteriaResults, setCriteriaResults] = useState2({});
|
|
13172
|
+
const [showSkipModal, setShowSkipModal] = useState2(false);
|
|
13173
|
+
const [selectedSkipReason, setSelectedSkipReason] = useState2(null);
|
|
13174
|
+
const [skipNotes, setSkipNotes] = useState2("");
|
|
13175
|
+
const [skipping, setSkipping] = useState2(false);
|
|
13176
|
+
const [collapsedFolders, setCollapsedFolders] = useState2(/* @__PURE__ */ new Set());
|
|
13177
|
+
const [startingSession, setStartingSession] = useState2(false);
|
|
13178
|
+
const [sessionFocusArea, setSessionFocusArea] = useState2("");
|
|
13179
|
+
const [sessionPlatform, setSessionPlatform] = useState2(Platform2.OS === "ios" ? "ios" : "android");
|
|
13180
|
+
const [showAddFinding, setShowAddFinding] = useState2(false);
|
|
13181
|
+
const [findingType, setFindingType] = useState2("bug");
|
|
13182
|
+
const [findingTitle, setFindingTitle] = useState2("");
|
|
13183
|
+
const [findingDescription, setFindingDescription] = useState2("");
|
|
13184
|
+
const [findingSeverity, setFindingSeverity] = useState2("medium");
|
|
13185
|
+
const [addingFinding, setAddingFinding] = useState2(false);
|
|
13186
|
+
const [endingSession, setEndingSession] = useState2(false);
|
|
13187
|
+
const [sessionNotes, setSessionNotes] = useState2("");
|
|
13188
|
+
const [showEndConfirm, setShowEndConfirm] = useState2(false);
|
|
13189
|
+
const [sessionElapsedTime, setSessionElapsedTime] = useState2(0);
|
|
13190
|
+
const [assignmentElapsedTime, setAssignmentElapsedTime] = useState2(0);
|
|
13191
|
+
useEffect2(() => {
|
|
13192
|
+
const activeAssignment = displayedAssignment?.status === "in_progress" ? displayedAssignment : null;
|
|
13193
|
+
if (!activeAssignment?.startedAt) {
|
|
13194
|
+
setAssignmentElapsedTime(0);
|
|
13195
|
+
return;
|
|
13196
|
+
}
|
|
13197
|
+
const startTime = new Date(activeAssignment.startedAt).getTime();
|
|
13198
|
+
setAssignmentElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13199
|
+
const interval = setInterval(() => {
|
|
13200
|
+
setAssignmentElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13201
|
+
}, 1e3);
|
|
13202
|
+
return () => clearInterval(interval);
|
|
13203
|
+
}, [displayedAssignment?.id, displayedAssignment?.status, displayedAssignment?.startedAt]);
|
|
13204
|
+
useEffect2(() => {
|
|
13205
|
+
if (!activeSession) {
|
|
13206
|
+
setSessionElapsedTime(0);
|
|
13207
|
+
return;
|
|
13208
|
+
}
|
|
13209
|
+
const startTime = new Date(activeSession.startedAt).getTime();
|
|
13210
|
+
setSessionElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13211
|
+
const interval = setInterval(() => {
|
|
13212
|
+
setSessionElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13213
|
+
}, 1e3);
|
|
13214
|
+
return () => clearInterval(interval);
|
|
13215
|
+
}, [activeSession]);
|
|
13216
|
+
const formatElapsedTime = (seconds) => {
|
|
13217
|
+
const h = Math.floor(seconds / 3600);
|
|
13218
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
13219
|
+
const s = seconds % 60;
|
|
13220
|
+
if (h > 0) return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
|
|
13221
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
13222
|
+
};
|
|
13048
13223
|
useEffect2(() => {
|
|
13049
13224
|
setCriteriaResults({});
|
|
13050
13225
|
setShowSteps(false);
|
|
13051
13226
|
}, [displayedAssignment?.id]);
|
|
13227
|
+
const groupedAssignments = useMemo(() => {
|
|
13228
|
+
const groups = /* @__PURE__ */ new Map();
|
|
13229
|
+
for (const assignment of assignments) {
|
|
13230
|
+
const groupId = assignment.testCase.group?.id || "ungrouped";
|
|
13231
|
+
const group = assignment.testCase.group || null;
|
|
13232
|
+
if (!groups.has(groupId)) {
|
|
13233
|
+
groups.set(groupId, {
|
|
13234
|
+
group,
|
|
13235
|
+
assignments: [],
|
|
13236
|
+
stats: { total: 0, passed: 0, failed: 0, pending: 0, skipped: 0 }
|
|
13237
|
+
});
|
|
13238
|
+
}
|
|
13239
|
+
const folder = groups.get(groupId);
|
|
13240
|
+
folder.assignments.push(assignment);
|
|
13241
|
+
folder.stats.total++;
|
|
13242
|
+
if (assignment.status === "passed") folder.stats.passed++;
|
|
13243
|
+
else if (assignment.status === "failed") folder.stats.failed++;
|
|
13244
|
+
else if (assignment.status === "skipped") folder.stats.skipped++;
|
|
13245
|
+
else folder.stats.pending++;
|
|
13246
|
+
}
|
|
13247
|
+
const priorityOrder = { P0: 0, P1: 1, P2: 2, P3: 3 };
|
|
13248
|
+
const statusOrder = { in_progress: 0, pending: 1, failed: 2, skipped: 3, passed: 4 };
|
|
13249
|
+
for (const folder of groups.values()) {
|
|
13250
|
+
folder.assignments.sort((a, b) => {
|
|
13251
|
+
const statusDiff = (statusOrder[a.status] ?? 5) - (statusOrder[b.status] ?? 5);
|
|
13252
|
+
if (statusDiff !== 0) return statusDiff;
|
|
13253
|
+
return (priorityOrder[a.testCase.priority] ?? 4) - (priorityOrder[b.testCase.priority] ?? 4);
|
|
13254
|
+
});
|
|
13255
|
+
}
|
|
13256
|
+
const sortedGroups = Array.from(groups.values()).sort((a, b) => {
|
|
13257
|
+
if (!a.group && !b.group) return 0;
|
|
13258
|
+
if (!a.group) return 1;
|
|
13259
|
+
if (!b.group) return -1;
|
|
13260
|
+
return a.group.sortOrder - b.group.sortOrder;
|
|
13261
|
+
});
|
|
13262
|
+
return sortedGroups;
|
|
13263
|
+
}, [assignments]);
|
|
13264
|
+
const toggleFolderCollapse = useCallback2((groupId) => {
|
|
13265
|
+
setCollapsedFolders((prev) => {
|
|
13266
|
+
const next = new Set(prev);
|
|
13267
|
+
if (next.has(groupId)) {
|
|
13268
|
+
next.delete(groupId);
|
|
13269
|
+
} else {
|
|
13270
|
+
next.add(groupId);
|
|
13271
|
+
}
|
|
13272
|
+
return next;
|
|
13273
|
+
});
|
|
13274
|
+
}, []);
|
|
13275
|
+
const getStatusBadge = (status) => {
|
|
13276
|
+
switch (status) {
|
|
13277
|
+
case "passed":
|
|
13278
|
+
return { icon: "\u2705", label: "Passed", color: "#22c55e" };
|
|
13279
|
+
case "failed":
|
|
13280
|
+
return { icon: "\u274C", label: "Failed", color: "#ef4444" };
|
|
13281
|
+
case "skipped":
|
|
13282
|
+
return { icon: "\u23ED\uFE0F", label: "Skipped", color: "#eab308" };
|
|
13283
|
+
case "in_progress":
|
|
13284
|
+
return { icon: "\u{1F504}", label: "In Progress", color: "#3b82f6" };
|
|
13285
|
+
case "blocked":
|
|
13286
|
+
return { icon: "\u{1F6AB}", label: "Blocked", color: "#f97316" };
|
|
13287
|
+
case "pending":
|
|
13288
|
+
default:
|
|
13289
|
+
return { icon: "\u23F3", label: "Pending", color: "#71717a" };
|
|
13290
|
+
}
|
|
13291
|
+
};
|
|
13052
13292
|
if (isLoading || !shouldShowWidget) {
|
|
13053
13293
|
return null;
|
|
13054
13294
|
}
|
|
13055
13295
|
const pendingCount = assignments.filter((a) => a.status === "pending").length;
|
|
13056
13296
|
const inProgressCount = assignments.filter((a) => a.status === "in_progress").length;
|
|
13297
|
+
const passedCount = assignments.filter((a) => a.status === "passed").length;
|
|
13298
|
+
const failedCount = assignments.filter((a) => a.status === "failed").length;
|
|
13299
|
+
const [testFilter, setTestFilter] = useState2("all");
|
|
13300
|
+
const handleNextTest = () => {
|
|
13301
|
+
const nextTest = assignments.find(
|
|
13302
|
+
(a) => a.id !== displayedAssignment?.id && (a.status === "pending" || a.status === "in_progress")
|
|
13303
|
+
);
|
|
13304
|
+
if (nextTest) {
|
|
13305
|
+
setSelectedTestId(nextTest.id);
|
|
13306
|
+
setTestView("detail");
|
|
13307
|
+
setShowSteps(false);
|
|
13308
|
+
}
|
|
13309
|
+
};
|
|
13057
13310
|
const handlePass = async () => {
|
|
13311
|
+
if (!displayedAssignment) return;
|
|
13312
|
+
setPendingFeedbackStatus("passed");
|
|
13313
|
+
setShowFeedbackPrompt(true);
|
|
13314
|
+
setFeedbackRating(5);
|
|
13315
|
+
setFeedbackNote("");
|
|
13316
|
+
setFeedbackFlags({ isOutdated: false, needsMoreDetail: false, stepsUnclear: false, expectedResultUnclear: false });
|
|
13317
|
+
};
|
|
13318
|
+
const handleFail = () => {
|
|
13319
|
+
if (!displayedAssignment) return;
|
|
13320
|
+
setPendingFeedbackStatus("failed");
|
|
13321
|
+
setShowFeedbackPrompt(true);
|
|
13322
|
+
setFeedbackRating(3);
|
|
13323
|
+
setFeedbackNote("");
|
|
13324
|
+
setFeedbackFlags({ isOutdated: false, needsMoreDetail: false, stepsUnclear: false, expectedResultUnclear: false });
|
|
13325
|
+
};
|
|
13326
|
+
const handleSubmitFeedback = async (skipFeedback = false) => {
|
|
13058
13327
|
if (!client || !displayedAssignment) return;
|
|
13059
13328
|
setSubmitting(true);
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
}
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
-
|
|
13072
|
-
|
|
13329
|
+
const feedback = skipFeedback ? void 0 : {
|
|
13330
|
+
rating: feedbackRating,
|
|
13331
|
+
feedbackNote: feedbackNote.trim() || void 0,
|
|
13332
|
+
isOutdated: feedbackFlags.isOutdated,
|
|
13333
|
+
needsMoreDetail: feedbackFlags.needsMoreDetail,
|
|
13334
|
+
stepsUnclear: feedbackFlags.stepsUnclear,
|
|
13335
|
+
expectedResultUnclear: feedbackFlags.expectedResultUnclear
|
|
13336
|
+
};
|
|
13337
|
+
if (pendingFeedbackStatus === "passed") {
|
|
13338
|
+
await client.submitReport({
|
|
13339
|
+
type: "test_pass",
|
|
13340
|
+
description: `Test passed: ${displayedAssignment.testCase.title}`,
|
|
13341
|
+
assignmentId: displayedAssignment.id,
|
|
13342
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13343
|
+
appContext: getAppContext?.() || { currentRoute: "unknown" },
|
|
13344
|
+
deviceInfo: getDeviceInfo()
|
|
13345
|
+
});
|
|
13346
|
+
if (feedback) {
|
|
13347
|
+
await client.submitTestFeedback({
|
|
13348
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13349
|
+
assignmentId: displayedAssignment.id,
|
|
13350
|
+
feedback,
|
|
13351
|
+
timeToCompleteSeconds: assignmentElapsedTime || void 0
|
|
13352
|
+
});
|
|
13353
|
+
}
|
|
13354
|
+
await refreshAssignments();
|
|
13355
|
+
setSubmitting(false);
|
|
13356
|
+
setShowFeedbackPrompt(false);
|
|
13357
|
+
setPendingFeedbackStatus(null);
|
|
13358
|
+
setJustPassed(true);
|
|
13359
|
+
setTimeout(() => {
|
|
13360
|
+
setJustPassed(false);
|
|
13361
|
+
setSelectedTestId(null);
|
|
13362
|
+
setTestView("detail");
|
|
13363
|
+
}, 1200);
|
|
13364
|
+
} else if (pendingFeedbackStatus === "failed") {
|
|
13365
|
+
if (feedback) {
|
|
13366
|
+
await client.submitTestFeedback({
|
|
13367
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13368
|
+
assignmentId: displayedAssignment.id,
|
|
13369
|
+
feedback,
|
|
13370
|
+
timeToCompleteSeconds: assignmentElapsedTime || void 0
|
|
13371
|
+
});
|
|
13372
|
+
}
|
|
13373
|
+
setSubmitting(false);
|
|
13374
|
+
setShowFeedbackPrompt(false);
|
|
13375
|
+
setPendingFeedbackStatus(null);
|
|
13376
|
+
setActiveTab("report");
|
|
13377
|
+
setReportType("bug");
|
|
13378
|
+
}
|
|
13379
|
+
};
|
|
13380
|
+
const handleSkipFeedback = () => {
|
|
13381
|
+
handleSubmitFeedback(true);
|
|
13382
|
+
};
|
|
13383
|
+
const handleOpenSkipModal = () => {
|
|
13384
|
+
setShowSkipModal(true);
|
|
13385
|
+
setSelectedSkipReason(null);
|
|
13386
|
+
setSkipNotes("");
|
|
13387
|
+
};
|
|
13388
|
+
const handleSkip = async () => {
|
|
13389
|
+
if (!client || !displayedAssignment || !selectedSkipReason) return;
|
|
13390
|
+
setSkipping(true);
|
|
13391
|
+
const result = await client.skipAssignment(
|
|
13392
|
+
displayedAssignment.id,
|
|
13393
|
+
selectedSkipReason,
|
|
13394
|
+
skipNotes || void 0
|
|
13395
|
+
);
|
|
13396
|
+
if (result.success) {
|
|
13397
|
+
await refreshAssignments();
|
|
13398
|
+
setShowSkipModal(false);
|
|
13399
|
+
setSelectedSkipReason(null);
|
|
13400
|
+
setSkipNotes("");
|
|
13073
13401
|
setSelectedTestId(null);
|
|
13074
13402
|
setTestView("detail");
|
|
13075
|
-
}
|
|
13076
|
-
|
|
13077
|
-
const handleFail = () => {
|
|
13078
|
-
setActiveTab("report");
|
|
13079
|
-
setReportType("test_fail");
|
|
13403
|
+
}
|
|
13404
|
+
setSkipping(false);
|
|
13080
13405
|
};
|
|
13081
13406
|
const handleSubmitReport = async () => {
|
|
13082
13407
|
if (!client || !description.trim()) return;
|
|
@@ -13124,14 +13449,19 @@ function BugBearButton({
|
|
|
13124
13449
|
await markAsRead(thread.id);
|
|
13125
13450
|
}
|
|
13126
13451
|
};
|
|
13452
|
+
const [messageSendError, setMessageSendError] = useState2(false);
|
|
13127
13453
|
const handleSendReply = async () => {
|
|
13128
13454
|
if (!selectedThread || !replyText.trim()) return;
|
|
13129
13455
|
setSendingReply(true);
|
|
13456
|
+
setMessageSendError(false);
|
|
13130
13457
|
const success = await sendMessage(selectedThread.id, replyText.trim());
|
|
13131
13458
|
if (success) {
|
|
13132
13459
|
setReplyText("");
|
|
13133
13460
|
const messages = await getThreadMessages(selectedThread.id);
|
|
13134
13461
|
setThreadMessages(messages);
|
|
13462
|
+
} else {
|
|
13463
|
+
setMessageSendError(true);
|
|
13464
|
+
setTimeout(() => setMessageSendError(false), 3e3);
|
|
13135
13465
|
}
|
|
13136
13466
|
setSendingReply(false);
|
|
13137
13467
|
};
|
|
@@ -13223,6 +13553,44 @@ function BugBearButton({
|
|
|
13223
13553
|
}
|
|
13224
13554
|
setSavingProfile(false);
|
|
13225
13555
|
};
|
|
13556
|
+
const handleStartSession = async () => {
|
|
13557
|
+
setStartingSession(true);
|
|
13558
|
+
const result = await startSession({
|
|
13559
|
+
focusArea: sessionFocusArea.trim() || void 0,
|
|
13560
|
+
platform: sessionPlatform
|
|
13561
|
+
});
|
|
13562
|
+
if (result.success) {
|
|
13563
|
+
setSessionFocusArea("");
|
|
13564
|
+
}
|
|
13565
|
+
setStartingSession(false);
|
|
13566
|
+
};
|
|
13567
|
+
const handleEndSession = async () => {
|
|
13568
|
+
setEndingSession(true);
|
|
13569
|
+
const result = await endSession(sessionNotes.trim() || void 0);
|
|
13570
|
+
if (result.success) {
|
|
13571
|
+
setSessionNotes("");
|
|
13572
|
+
setShowEndConfirm(false);
|
|
13573
|
+
}
|
|
13574
|
+
setEndingSession(false);
|
|
13575
|
+
};
|
|
13576
|
+
const handleAddFinding = async () => {
|
|
13577
|
+
if (!findingTitle.trim()) return;
|
|
13578
|
+
setAddingFinding(true);
|
|
13579
|
+
const result = await addFinding({
|
|
13580
|
+
type: findingType,
|
|
13581
|
+
title: findingTitle.trim(),
|
|
13582
|
+
description: findingDescription.trim() || void 0,
|
|
13583
|
+
severity: findingType === "bug" ? findingSeverity : void 0
|
|
13584
|
+
});
|
|
13585
|
+
if (result.success) {
|
|
13586
|
+
setFindingTitle("");
|
|
13587
|
+
setFindingDescription("");
|
|
13588
|
+
setFindingType("bug");
|
|
13589
|
+
setFindingSeverity("medium");
|
|
13590
|
+
setShowAddFinding(false);
|
|
13591
|
+
}
|
|
13592
|
+
setAddingFinding(false);
|
|
13593
|
+
};
|
|
13226
13594
|
const formatRelativeTime = (dateString) => {
|
|
13227
13595
|
const date = new Date(dateString);
|
|
13228
13596
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -13398,7 +13766,7 @@ function BugBearButton({
|
|
|
13398
13766
|
style: [styles.tab, activeTab === "tests" && styles.activeTab],
|
|
13399
13767
|
onPress: () => setActiveTab("tests")
|
|
13400
13768
|
},
|
|
13401
|
-
/* @__PURE__ */ React2.createElement(Text, { style: [styles.tabText, activeTab === "tests" && styles.activeTabText] }, "Tests ",
|
|
13769
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [styles.tabText, activeTab === "tests" && styles.activeTabText] }, "Tests ", assignments.length > 0 && `(${passedCount + failedCount}/${assignments.length})`)
|
|
13402
13770
|
), /* @__PURE__ */ React2.createElement(
|
|
13403
13771
|
TouchableOpacity,
|
|
13404
13772
|
{
|
|
@@ -13406,6 +13774,13 @@ function BugBearButton({
|
|
|
13406
13774
|
onPress: () => setActiveTab("messages")
|
|
13407
13775
|
},
|
|
13408
13776
|
/* @__PURE__ */ React2.createElement(View, { style: styles.tabWithBadge }, /* @__PURE__ */ React2.createElement(Text, { style: [styles.tabText, activeTab === "messages" && styles.activeTabText] }, "Messages"), unreadCount > 0 && /* @__PURE__ */ React2.createElement(View, { style: styles.tabBadge }, /* @__PURE__ */ React2.createElement(Text, { style: styles.tabBadgeText }, unreadCount)))
|
|
13777
|
+
), /* @__PURE__ */ React2.createElement(
|
|
13778
|
+
TouchableOpacity,
|
|
13779
|
+
{
|
|
13780
|
+
style: [styles.tab, activeTab === "explore" && styles.activeTab],
|
|
13781
|
+
onPress: () => setActiveTab("explore")
|
|
13782
|
+
},
|
|
13783
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.tabWithBadge }, /* @__PURE__ */ React2.createElement(Text, { style: [styles.tabText, activeTab === "explore" && styles.activeTabText] }, "Explore"), activeSession && /* @__PURE__ */ React2.createElement(View, { style: styles.sessionDot }))
|
|
13409
13784
|
), /* @__PURE__ */ React2.createElement(
|
|
13410
13785
|
TouchableOpacity,
|
|
13411
13786
|
{
|
|
@@ -13414,32 +13789,126 @@ function BugBearButton({
|
|
|
13414
13789
|
},
|
|
13415
13790
|
/* @__PURE__ */ React2.createElement(Text, { style: [styles.tabText, activeTab === "report" && styles.activeTabText] }, "Report")
|
|
13416
13791
|
)), /* @__PURE__ */ React2.createElement(ScrollView, { style: styles.content }, activeTab === "tests" && /* @__PURE__ */ React2.createElement(View, null, assignments.length === 0 ? /* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyEmoji }, "\u2705"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyTitle }, "All caught up!"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptySubtitle }, "No tests assigned")) : testView === "list" ? (
|
|
13417
|
-
/* List View - Show
|
|
13418
|
-
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.listHeader }, assignments.length, " test", assignments.length !== 1 ? "s" : "", "
|
|
13792
|
+
/* List View - Show tests grouped by folder */
|
|
13793
|
+
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.listHeader }, assignments.length, " test", assignments.length !== 1 ? "s" : "", " \xB7 ", passedCount, " passed \xB7 ", failedCount, " failed"), /* @__PURE__ */ React2.createElement(View, { style: styles.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ React2.createElement(
|
|
13419
13794
|
TouchableOpacity,
|
|
13420
13795
|
{
|
|
13421
|
-
key:
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13796
|
+
key: f,
|
|
13797
|
+
style: [styles.filterChip, testFilter === f && styles.filterChipActive],
|
|
13798
|
+
onPress: () => setTestFilter(f)
|
|
13799
|
+
},
|
|
13800
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [styles.filterChipText, testFilter === f && styles.filterChipTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${pendingCount + inProgressCount})` : `Done (${passedCount + failedCount})`)
|
|
13801
|
+
))), groupedAssignments.map((folder) => {
|
|
13802
|
+
const groupId = folder.group?.id || "ungrouped";
|
|
13803
|
+
const isCollapsed = collapsedFolders.has(groupId);
|
|
13804
|
+
const completedCount = folder.stats.passed + folder.stats.failed + folder.stats.skipped;
|
|
13805
|
+
return /* @__PURE__ */ React2.createElement(View, { key: groupId, style: styles.folderContainer }, /* @__PURE__ */ React2.createElement(
|
|
13806
|
+
TouchableOpacity,
|
|
13807
|
+
{
|
|
13808
|
+
onPress: () => toggleFolderCollapse(groupId),
|
|
13809
|
+
style: styles.folderHeader
|
|
13426
13810
|
},
|
|
13811
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.folderHeaderLeft }, /* @__PURE__ */ React2.createElement(Text, { style: styles.folderIcon }, isCollapsed ? "\u{1F4C1}" : "\u{1F4C2}"), /* @__PURE__ */ React2.createElement(Text, { style: styles.folderName }, folder.group?.name || "Ungrouped Tests")),
|
|
13812
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.folderStats }, /* @__PURE__ */ React2.createElement(Text, { style: styles.folderProgress }, completedCount, "/", folder.stats.total), /* @__PURE__ */ React2.createElement(Text, { style: styles.folderChevron }, isCollapsed ? "\u25B6" : "\u25BC"))
|
|
13813
|
+
), !isCollapsed && /* @__PURE__ */ React2.createElement(View, { style: styles.folderProgressBar }, /* @__PURE__ */ React2.createElement(
|
|
13814
|
+
View,
|
|
13815
|
+
{
|
|
13816
|
+
style: [
|
|
13817
|
+
styles.folderProgressFill,
|
|
13818
|
+
{ width: `${completedCount / folder.stats.total * 100}%` }
|
|
13819
|
+
]
|
|
13820
|
+
}
|
|
13821
|
+
)), !isCollapsed && folder.assignments.filter((a) => {
|
|
13822
|
+
if (testFilter === "pending") return a.status === "pending" || a.status === "in_progress";
|
|
13823
|
+
if (testFilter === "completed") return a.status === "passed" || a.status === "failed" || a.status === "skipped";
|
|
13824
|
+
return true;
|
|
13825
|
+
}).map((assignment) => {
|
|
13826
|
+
const statusBadge = getStatusBadge(assignment.status);
|
|
13827
|
+
return /* @__PURE__ */ React2.createElement(
|
|
13828
|
+
TouchableOpacity,
|
|
13829
|
+
{
|
|
13830
|
+
key: assignment.id,
|
|
13831
|
+
onPress: () => {
|
|
13832
|
+
setSelectedTestId(assignment.id);
|
|
13833
|
+
setTestView("detail");
|
|
13834
|
+
setShowSteps(false);
|
|
13835
|
+
},
|
|
13836
|
+
style: [
|
|
13837
|
+
styles.listItem,
|
|
13838
|
+
styles.listItemInFolder,
|
|
13839
|
+
assignment.id === currentAssignment?.id && styles.listItemCurrent
|
|
13840
|
+
]
|
|
13841
|
+
},
|
|
13842
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.listItemHeader }, /* @__PURE__ */ React2.createElement(View, { style: styles.listItemKeyWithStatus }, /* @__PURE__ */ React2.createElement(Text, { style: styles.listItemKey }, assignment.testCase.testKey), /* @__PURE__ */ React2.createElement(View, { style: [styles.statusBadge, { backgroundColor: statusBadge.color + "20" }] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.statusBadgeIcon }, statusBadge.icon), /* @__PURE__ */ React2.createElement(Text, { style: [styles.statusBadgeText, { color: statusBadge.color }] }, statusBadge.label))), /* @__PURE__ */ React2.createElement(View, { style: styles.listItemBadges }, assignment.testCase.track && /* @__PURE__ */ React2.createElement(View, { style: [styles.trackBadge, { backgroundColor: assignment.testCase.track.color }] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.trackBadgeText }, templateInfo[assignment.testCase.track.testTemplate || "steps"].icon)), /* @__PURE__ */ React2.createElement(View, { style: [
|
|
13843
|
+
styles.priorityBadge,
|
|
13844
|
+
assignment.testCase.priority === "P0" && styles.priorityP0,
|
|
13845
|
+
assignment.testCase.priority === "P1" && styles.priorityP1
|
|
13846
|
+
] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.priorityText }, assignment.testCase.priority)))),
|
|
13847
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.listItemTitle, numberOfLines: 2 }, assignment.testCase.title),
|
|
13848
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.listItemMeta }, /* @__PURE__ */ React2.createElement(Text, { style: styles.listItemMetaText }, assignment.testCase.steps.length, " ", assignment.testCase.track?.testTemplate === "checklist" ? "items" : assignment.testCase.track?.testTemplate === "rubric" ? "criteria" : "steps"), assignment.id === currentAssignment?.id && /* @__PURE__ */ React2.createElement(Text, { style: styles.currentBadge }, "\u2022 Current"))
|
|
13849
|
+
);
|
|
13850
|
+
}));
|
|
13851
|
+
}))
|
|
13852
|
+
) : justPassed ? (
|
|
13853
|
+
/* Success state after passing */
|
|
13854
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.passedEmoji }, "\u2713"), /* @__PURE__ */ React2.createElement(Text, { style: styles.passedTitle }, "Passed!"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptySubtitle }, "Loading next test..."))
|
|
13855
|
+
) : showFeedbackPrompt && displayedAssignment ? (
|
|
13856
|
+
/* Feedback prompt after completing a test */
|
|
13857
|
+
/* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.container }, /* @__PURE__ */ React2.createElement(View, { style: { alignItems: "center", marginBottom: 16 } }, /* @__PURE__ */ React2.createElement(Text, { style: { fontSize: 28 } }, pendingFeedbackStatus === "passed" ? "\u2713" : "\u2717"), /* @__PURE__ */ React2.createElement(Text, { style: [feedbackStyles.statusText, pendingFeedbackStatus === "passed" ? { color: "#4ade80" } : { color: "#f87171" }] }, pendingFeedbackStatus === "passed" ? "Test Passed!" : "Test Failed")), /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.infoBox }, /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.infoTitle }, "Help us improve this test"), /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.infoSubtitle }, "Your feedback shapes better tests for everyone.")), /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.ratingSection }, /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.ratingLabel }, "How was this test?"), /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.starsRow }, [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ React2.createElement(
|
|
13858
|
+
TouchableOpacity,
|
|
13859
|
+
{
|
|
13860
|
+
key: star,
|
|
13861
|
+
onPress: () => setFeedbackRating(star)
|
|
13862
|
+
},
|
|
13863
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [feedbackStyles.star, star <= feedbackRating ? feedbackStyles.starActive : feedbackStyles.starInactive] }, "\u2605")
|
|
13864
|
+
))), /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.ratingDesc }, feedbackRating === 1 ? "Needs work" : feedbackRating === 2 ? "Could be better" : feedbackRating === 3 ? "Okay" : feedbackRating === 4 ? "Good" : "Great!")), feedbackRating < 4 && /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.flagsSection }, /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.ratingLabel }, "What could be improved?"), /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.flagsGrid }, [
|
|
13865
|
+
{ key: "stepsUnclear", label: "Steps unclear" },
|
|
13866
|
+
{ key: "expectedResultUnclear", label: "Expected result unclear" },
|
|
13867
|
+
{ key: "needsMoreDetail", label: "Needs more detail" },
|
|
13868
|
+
{ key: "isOutdated", label: "Seems outdated" }
|
|
13869
|
+
].map(({ key, label }) => /* @__PURE__ */ React2.createElement(
|
|
13870
|
+
TouchableOpacity,
|
|
13871
|
+
{
|
|
13872
|
+
key,
|
|
13873
|
+
onPress: () => setFeedbackFlags((prev) => ({ ...prev, [key]: !prev[key] })),
|
|
13427
13874
|
style: [
|
|
13428
|
-
|
|
13429
|
-
|
|
13875
|
+
feedbackStyles.flagButton,
|
|
13876
|
+
feedbackFlags[key] && feedbackStyles.flagButtonActive
|
|
13430
13877
|
]
|
|
13431
13878
|
},
|
|
13432
|
-
/* @__PURE__ */ React2.createElement(
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13879
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [
|
|
13880
|
+
feedbackStyles.flagButtonText,
|
|
13881
|
+
feedbackFlags[key] && feedbackStyles.flagButtonTextActive
|
|
13882
|
+
] }, label)
|
|
13883
|
+
)))), /* @__PURE__ */ React2.createElement(View, { style: { marginBottom: 12 } }, /* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.ratingLabel }, "Suggestions? (optional)"), /* @__PURE__ */ React2.createElement(
|
|
13884
|
+
TextInput,
|
|
13885
|
+
{
|
|
13886
|
+
style: feedbackStyles.noteInput,
|
|
13887
|
+
value: feedbackNote,
|
|
13888
|
+
onChangeText: setFeedbackNote,
|
|
13889
|
+
placeholder: "How could this test be improved?",
|
|
13890
|
+
placeholderTextColor: "#71717a",
|
|
13891
|
+
multiline: true,
|
|
13892
|
+
numberOfLines: 2,
|
|
13893
|
+
textAlignVertical: "top"
|
|
13894
|
+
}
|
|
13895
|
+
)), /* @__PURE__ */ React2.createElement(View, { style: feedbackStyles.buttonRow }, /* @__PURE__ */ React2.createElement(
|
|
13896
|
+
TouchableOpacity,
|
|
13897
|
+
{
|
|
13898
|
+
onPress: handleSkipFeedback,
|
|
13899
|
+
disabled: submitting,
|
|
13900
|
+
style: [feedbackStyles.skipButton, submitting && { opacity: 0.5 }]
|
|
13901
|
+
},
|
|
13902
|
+
/* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.skipButtonText }, "Skip")
|
|
13903
|
+
), /* @__PURE__ */ React2.createElement(
|
|
13904
|
+
TouchableOpacity,
|
|
13905
|
+
{
|
|
13906
|
+
onPress: () => handleSubmitFeedback(false),
|
|
13907
|
+
disabled: submitting,
|
|
13908
|
+
style: [feedbackStyles.submitButton, submitting && { opacity: 0.5 }]
|
|
13909
|
+
},
|
|
13910
|
+
/* @__PURE__ */ React2.createElement(Text, { style: feedbackStyles.submitButtonText }, submitting ? "Submitting..." : "Submit Feedback")
|
|
13439
13911
|
)))
|
|
13440
|
-
) : justPassed ? (
|
|
13441
|
-
/* Success state after passing */
|
|
13442
|
-
/* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.passedEmoji }, "\u2713"), /* @__PURE__ */ React2.createElement(Text, { style: styles.passedTitle }, "Passed!"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptySubtitle }, "Loading next test..."))
|
|
13443
13912
|
) : displayedAssignment ? (
|
|
13444
13913
|
/* Detail View - Show single test */
|
|
13445
13914
|
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(
|
|
@@ -13452,27 +13921,58 @@ function BugBearButton({
|
|
|
13452
13921
|
style: styles.backButton
|
|
13453
13922
|
},
|
|
13454
13923
|
/* @__PURE__ */ React2.createElement(Text, { style: styles.backButtonText }, "\u2190 All Tests (", assignments.length, ")")
|
|
13455
|
-
), /* @__PURE__ */ React2.createElement(View, { style: styles.testCard }, /* @__PURE__ */ React2.createElement(View, { style: styles.testHeader }, /* @__PURE__ */ React2.createElement(Text, { style: styles.testKey }, displayedAssignment.testCase.testKey), /* @__PURE__ */ React2.createElement(View, { style: styles.testHeaderBadges },
|
|
13924
|
+
), /* @__PURE__ */ React2.createElement(View, { style: styles.testCard }, /* @__PURE__ */ React2.createElement(View, { style: styles.testHeader }, /* @__PURE__ */ React2.createElement(Text, { style: styles.testKey }, displayedAssignment.testCase.testKey), /* @__PURE__ */ React2.createElement(View, { style: styles.testHeaderBadges }, (() => {
|
|
13925
|
+
const badge = getStatusBadge(displayedAssignment.status);
|
|
13926
|
+
return /* @__PURE__ */ React2.createElement(View, { style: [styles.statusBadge, { backgroundColor: badge.color + "20" }] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.statusBadgeIcon }, badge.icon), /* @__PURE__ */ React2.createElement(Text, { style: [styles.statusBadgeText, { color: badge.color }] }, badge.label));
|
|
13927
|
+
})(), displayedAssignment.testCase.track && /* @__PURE__ */ React2.createElement(View, { style: [styles.trackBadge, { backgroundColor: displayedAssignment.testCase.track.color }] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.trackBadgeText }, templateInfo[displayedAssignment.testCase.track.testTemplate || "steps"].icon)), /* @__PURE__ */ React2.createElement(View, { style: [
|
|
13456
13928
|
styles.priorityBadge,
|
|
13457
13929
|
displayedAssignment.testCase.priority === "P0" && styles.priorityP0,
|
|
13458
13930
|
displayedAssignment.testCase.priority === "P1" && styles.priorityP1
|
|
13459
|
-
] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.priorityText }, displayedAssignment.testCase.priority)))), /* @__PURE__ */ React2.createElement(Text, { style: styles.testTitle }, displayedAssignment.testCase.title), displayedAssignment.testCase.description && /* @__PURE__ */ React2.createElement(Text, { style: styles.testDescription }, displayedAssignment.testCase.description), displayedAssignment.testCase.targetRoute && onNavigate && /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: handleNavigate, style: styles.navigateButton }, /* @__PURE__ */ React2.createElement(Text, { style: styles.navigateButtonText }, "Go to test location \u2192")), renderTestContent(), /* @__PURE__ */ React2.createElement(View, { style: styles.expectedResult }, /* @__PURE__ */ React2.createElement(Text, { style: styles.expectedLabel }, displayedAssignment.testCase.track?.testTemplate === "checklist" ? "Pass criteria:" : displayedAssignment.testCase.track?.testTemplate === "rubric" ? "Target score:" : "Expected:"), /* @__PURE__ */ React2.createElement(Text, { style: styles.expectedText }, displayedAssignment.testCase.expectedResult))),
|
|
13931
|
+
] }, /* @__PURE__ */ React2.createElement(Text, { style: styles.priorityText }, displayedAssignment.testCase.priority)))), /* @__PURE__ */ React2.createElement(Text, { style: styles.testTitle }, displayedAssignment.testCase.title), displayedAssignment.status === "in_progress" && displayedAssignment.startedAt && /* @__PURE__ */ React2.createElement(View, { style: timerStyles.container }, /* @__PURE__ */ React2.createElement(View, { style: timerStyles.dot }), /* @__PURE__ */ React2.createElement(Text, { style: timerStyles.label }, "Testing"), /* @__PURE__ */ React2.createElement(Text, { style: timerStyles.time }, formatElapsedTime(assignmentElapsedTime))), displayedAssignment.testCase.description && /* @__PURE__ */ React2.createElement(Text, { style: styles.testDescription }, displayedAssignment.testCase.description), displayedAssignment.testCase.targetRoute && onNavigate && /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: handleNavigate, style: styles.navigateButton }, /* @__PURE__ */ React2.createElement(Text, { style: styles.navigateButtonText }, "Go to test location \u2192")), renderTestContent(), /* @__PURE__ */ React2.createElement(View, { style: styles.expectedResult }, /* @__PURE__ */ React2.createElement(Text, { style: styles.expectedLabel }, displayedAssignment.testCase.track?.testTemplate === "checklist" ? "Pass criteria:" : displayedAssignment.testCase.track?.testTemplate === "rubric" ? "Target score:" : "Expected:"), /* @__PURE__ */ React2.createElement(Text, { style: styles.expectedText }, displayedAssignment.testCase.expectedResult))), displayedAssignment.testCase.group && (() => {
|
|
13932
|
+
const folder = groupedAssignments.find((f) => f.group?.id === displayedAssignment.testCase.group?.id);
|
|
13933
|
+
if (!folder) return null;
|
|
13934
|
+
const completedCount = folder.stats.passed + folder.stats.failed + folder.stats.skipped;
|
|
13935
|
+
return /* @__PURE__ */ React2.createElement(View, { style: styles.detailProgressContainer }, /* @__PURE__ */ React2.createElement(Text, { style: styles.detailProgressText }, folder.group?.name, ": ", completedCount, "/", folder.stats.total, " complete"), /* @__PURE__ */ React2.createElement(View, { style: styles.detailProgressBar }, /* @__PURE__ */ React2.createElement(
|
|
13936
|
+
View,
|
|
13937
|
+
{
|
|
13938
|
+
style: [
|
|
13939
|
+
styles.detailProgressFill,
|
|
13940
|
+
{ width: `${completedCount / folder.stats.total * 100}%` }
|
|
13941
|
+
]
|
|
13942
|
+
}
|
|
13943
|
+
)));
|
|
13944
|
+
})(), /* @__PURE__ */ React2.createElement(View, { style: styles.actionButtons }, /* @__PURE__ */ React2.createElement(
|
|
13460
13945
|
TouchableOpacity,
|
|
13461
13946
|
{
|
|
13462
13947
|
style: styles.failButton,
|
|
13463
13948
|
onPress: handleFail,
|
|
13464
|
-
disabled: submitting
|
|
13949
|
+
disabled: submitting || skipping
|
|
13465
13950
|
},
|
|
13466
13951
|
/* @__PURE__ */ React2.createElement(Text, { style: styles.failButtonText }, "\u2717 Fail")
|
|
13952
|
+
), /* @__PURE__ */ React2.createElement(
|
|
13953
|
+
TouchableOpacity,
|
|
13954
|
+
{
|
|
13955
|
+
style: styles.skipButton,
|
|
13956
|
+
onPress: handleOpenSkipModal,
|
|
13957
|
+
disabled: submitting || skipping
|
|
13958
|
+
},
|
|
13959
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.skipButtonText }, skipping ? "..." : "\u2192 Skip")
|
|
13467
13960
|
), /* @__PURE__ */ React2.createElement(
|
|
13468
13961
|
TouchableOpacity,
|
|
13469
13962
|
{
|
|
13470
13963
|
style: styles.passButton,
|
|
13471
13964
|
onPress: handlePass,
|
|
13472
|
-
disabled: submitting
|
|
13965
|
+
disabled: submitting || skipping
|
|
13473
13966
|
},
|
|
13474
13967
|
/* @__PURE__ */ React2.createElement(Text, { style: styles.passButtonText }, submitting ? "..." : "\u2713 Pass")
|
|
13475
|
-
))
|
|
13968
|
+
)), pendingCount > 1 || pendingCount === 1 && displayedAssignment.status !== "pending" ? /* @__PURE__ */ React2.createElement(
|
|
13969
|
+
TouchableOpacity,
|
|
13970
|
+
{
|
|
13971
|
+
style: styles.nextTestButton,
|
|
13972
|
+
onPress: handleNextTest
|
|
13973
|
+
},
|
|
13974
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.nextTestButtonText }, "Next Test \u25B6")
|
|
13975
|
+
) : null)
|
|
13476
13976
|
) : null), activeTab === "messages" && /* @__PURE__ */ React2.createElement(View, null, messageView === "compose" ? (
|
|
13477
13977
|
/* Compose New Message View */
|
|
13478
13978
|
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: handleBackToThreadList, style: styles.backButton }, /* @__PURE__ */ React2.createElement(Text, { style: styles.backButtonText }, "\u2190 Back to Messages")), /* @__PURE__ */ React2.createElement(View, { style: styles.composeHeader }, /* @__PURE__ */ React2.createElement(Text, { style: styles.composeTitle }, "New Message"), /* @__PURE__ */ React2.createElement(Text, { style: styles.composeSubtitle }, "Send a message to the QA team")), /* @__PURE__ */ React2.createElement(View, { style: styles.composeForm }, /* @__PURE__ */ React2.createElement(Text, { style: styles.label }, "Subject"), /* @__PURE__ */ React2.createElement(
|
|
@@ -13557,6 +14057,166 @@ function BugBearButton({
|
|
|
13557
14057
|
message.senderType === "tester" && styles.messageTimeTester
|
|
13558
14058
|
] }, formatMessageTime(message.createdAt))
|
|
13559
14059
|
))))
|
|
14060
|
+
)), activeTab === "explore" && /* @__PURE__ */ React2.createElement(View, null, !activeSession ? (
|
|
14061
|
+
/* Start Session View */
|
|
14062
|
+
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyEmoji }, "\u{1F50D}"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyTitle }, "Exploratory QA Session"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptySubtitle }, "Explore freely and capture findings as you go")), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Focus Area (optional)"), /* @__PURE__ */ React2.createElement(
|
|
14063
|
+
TextInput,
|
|
14064
|
+
{
|
|
14065
|
+
style: exploreStyles.input,
|
|
14066
|
+
value: sessionFocusArea,
|
|
14067
|
+
onChangeText: setSessionFocusArea,
|
|
14068
|
+
placeholder: "e.g., checkout flow, settings page",
|
|
14069
|
+
placeholderTextColor: "#71717a"
|
|
14070
|
+
}
|
|
14071
|
+
)), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Platform"), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.platformRow }, [
|
|
14072
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
14073
|
+
{ key: "android", label: "\u{1F916} Android" },
|
|
14074
|
+
{ key: "web", label: "\u{1F310} Web" }
|
|
14075
|
+
].map(({ key, label }) => /* @__PURE__ */ React2.createElement(
|
|
14076
|
+
TouchableOpacity,
|
|
14077
|
+
{
|
|
14078
|
+
key,
|
|
14079
|
+
onPress: () => setSessionPlatform(key),
|
|
14080
|
+
style: [
|
|
14081
|
+
exploreStyles.platformButton,
|
|
14082
|
+
sessionPlatform === key && exploreStyles.platformButtonActive
|
|
14083
|
+
]
|
|
14084
|
+
},
|
|
14085
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [
|
|
14086
|
+
exploreStyles.platformButtonText,
|
|
14087
|
+
sessionPlatform === key && exploreStyles.platformButtonTextActive
|
|
14088
|
+
] }, label)
|
|
14089
|
+
)))), /* @__PURE__ */ React2.createElement(
|
|
14090
|
+
TouchableOpacity,
|
|
14091
|
+
{
|
|
14092
|
+
onPress: handleStartSession,
|
|
14093
|
+
disabled: startingSession,
|
|
14094
|
+
style: [exploreStyles.startButton, startingSession && { opacity: 0.5 }]
|
|
14095
|
+
},
|
|
14096
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.startButtonText }, startingSession ? "Starting..." : "\u25B6 Start Session")
|
|
14097
|
+
))
|
|
14098
|
+
) : showEndConfirm ? (
|
|
14099
|
+
/* End Session Confirmation */
|
|
14100
|
+
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyEmoji }, "\u270B"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyTitle }, "End Session?"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptySubtitle }, "Duration: ", formatElapsedTime(sessionElapsedTime), " \xB7 ", sessionFindings.length, " finding", sessionFindings.length !== 1 ? "s" : "")), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Session Notes (optional)"), /* @__PURE__ */ React2.createElement(
|
|
14101
|
+
TextInput,
|
|
14102
|
+
{
|
|
14103
|
+
style: [exploreStyles.input, { height: 80, textAlignVertical: "top" }],
|
|
14104
|
+
value: sessionNotes,
|
|
14105
|
+
onChangeText: setSessionNotes,
|
|
14106
|
+
placeholder: "Any overall observations from this session...",
|
|
14107
|
+
placeholderTextColor: "#71717a",
|
|
14108
|
+
multiline: true
|
|
14109
|
+
}
|
|
14110
|
+
)), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.buttonRow }, /* @__PURE__ */ React2.createElement(
|
|
14111
|
+
TouchableOpacity,
|
|
14112
|
+
{
|
|
14113
|
+
onPress: () => setShowEndConfirm(false),
|
|
14114
|
+
style: exploreStyles.cancelButton
|
|
14115
|
+
},
|
|
14116
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.cancelButtonText }, "Cancel")
|
|
14117
|
+
), /* @__PURE__ */ React2.createElement(
|
|
14118
|
+
TouchableOpacity,
|
|
14119
|
+
{
|
|
14120
|
+
onPress: handleEndSession,
|
|
14121
|
+
disabled: endingSession,
|
|
14122
|
+
style: [exploreStyles.endButton, endingSession && { opacity: 0.5 }]
|
|
14123
|
+
},
|
|
14124
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.endButtonText }, endingSession ? "Ending..." : "End Session")
|
|
14125
|
+
)))
|
|
14126
|
+
) : showAddFinding ? (
|
|
14127
|
+
/* Add Finding Form */
|
|
14128
|
+
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.findingHeader }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingHeaderTitle }, "Add Finding"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: () => setShowAddFinding(false) }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingHeaderClose }, "\u2715"))), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.findingTypeRow }, [
|
|
14129
|
+
{ type: "bug", label: "\u{1F41B} Bug" },
|
|
14130
|
+
{ type: "concern", label: "\u26A0\uFE0F Concern" },
|
|
14131
|
+
{ type: "suggestion", label: "\u{1F4A1} Idea" },
|
|
14132
|
+
{ type: "question", label: "\u2753 Q" }
|
|
14133
|
+
].map(({ type, label }) => /* @__PURE__ */ React2.createElement(
|
|
14134
|
+
TouchableOpacity,
|
|
14135
|
+
{
|
|
14136
|
+
key: type,
|
|
14137
|
+
onPress: () => setFindingType(type),
|
|
14138
|
+
style: [
|
|
14139
|
+
exploreStyles.findingTypeButton,
|
|
14140
|
+
findingType === type && exploreStyles.findingTypeButtonActive
|
|
14141
|
+
]
|
|
14142
|
+
},
|
|
14143
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [
|
|
14144
|
+
exploreStyles.findingTypeButtonText,
|
|
14145
|
+
findingType === type && exploreStyles.findingTypeButtonTextActive
|
|
14146
|
+
] }, label)
|
|
14147
|
+
))), findingType === "bug" && /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Severity"), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.severityRow }, ["critical", "high", "medium", "low"].map((sev) => /* @__PURE__ */ React2.createElement(
|
|
14148
|
+
TouchableOpacity,
|
|
14149
|
+
{
|
|
14150
|
+
key: sev,
|
|
14151
|
+
onPress: () => setFindingSeverity(sev),
|
|
14152
|
+
style: [
|
|
14153
|
+
exploreStyles.severityButton,
|
|
14154
|
+
findingSeverity === sev && (sev === "critical" ? exploreStyles.severityCritical : sev === "high" ? exploreStyles.severityHigh : sev === "medium" ? exploreStyles.severityMedium : exploreStyles.severityLow)
|
|
14155
|
+
]
|
|
14156
|
+
},
|
|
14157
|
+
/* @__PURE__ */ React2.createElement(Text, { style: [
|
|
14158
|
+
exploreStyles.severityButtonText,
|
|
14159
|
+
findingSeverity === sev && exploreStyles.severityButtonTextActive
|
|
14160
|
+
] }, sev)
|
|
14161
|
+
)))), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Title *"), /* @__PURE__ */ React2.createElement(
|
|
14162
|
+
TextInput,
|
|
14163
|
+
{
|
|
14164
|
+
style: exploreStyles.input,
|
|
14165
|
+
value: findingTitle,
|
|
14166
|
+
onChangeText: setFindingTitle,
|
|
14167
|
+
placeholder: "Brief description of what you found",
|
|
14168
|
+
placeholderTextColor: "#71717a"
|
|
14169
|
+
}
|
|
14170
|
+
)), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.formGroup }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.label }, "Details (optional)"), /* @__PURE__ */ React2.createElement(
|
|
14171
|
+
TextInput,
|
|
14172
|
+
{
|
|
14173
|
+
style: [exploreStyles.input, { height: 60, textAlignVertical: "top" }],
|
|
14174
|
+
value: findingDescription,
|
|
14175
|
+
onChangeText: setFindingDescription,
|
|
14176
|
+
placeholder: "Steps to reproduce, expected behavior, etc.",
|
|
14177
|
+
placeholderTextColor: "#71717a",
|
|
14178
|
+
multiline: true
|
|
14179
|
+
}
|
|
14180
|
+
)), /* @__PURE__ */ React2.createElement(
|
|
14181
|
+
TouchableOpacity,
|
|
14182
|
+
{
|
|
14183
|
+
onPress: handleAddFinding,
|
|
14184
|
+
disabled: addingFinding || !findingTitle.trim(),
|
|
14185
|
+
style: [exploreStyles.addFindingButton, (addingFinding || !findingTitle.trim()) && { opacity: 0.5 }]
|
|
14186
|
+
},
|
|
14187
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.addFindingButtonText }, addingFinding ? "Adding..." : "Add Finding")
|
|
14188
|
+
))
|
|
14189
|
+
) : (
|
|
14190
|
+
/* Active Session View */
|
|
14191
|
+
/* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.sessionBanner }, /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.sessionBannerRow }, /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.sessionBannerLeft }, /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.sessionDotLarge }), /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.sessionBannerLabel }, "Session Active")), /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.sessionTimer }, formatElapsedTime(sessionElapsedTime))), activeSession.focusArea && /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.sessionFocus }, "Focus: ", activeSession.focusArea)), /* @__PURE__ */ React2.createElement(
|
|
14192
|
+
TouchableOpacity,
|
|
14193
|
+
{
|
|
14194
|
+
onPress: () => setShowAddFinding(true),
|
|
14195
|
+
style: exploreStyles.addButton
|
|
14196
|
+
},
|
|
14197
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.addButtonText }, "+ Add Finding")
|
|
14198
|
+
), /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.findingsSection }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingsLabel }, "Findings (", sessionFindings.length, ")"), sessionFindings.length === 0 ? /* @__PURE__ */ React2.createElement(View, { style: exploreStyles.findingsEmpty }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingsEmptyText }, "No findings yet"), /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingsEmptyText }, "Explore and add findings as you go")) : /* @__PURE__ */ React2.createElement(View, null, sessionFindings.map((finding) => /* @__PURE__ */ React2.createElement(
|
|
14199
|
+
View,
|
|
14200
|
+
{
|
|
14201
|
+
key: finding.id,
|
|
14202
|
+
style: [
|
|
14203
|
+
exploreStyles.findingCard,
|
|
14204
|
+
finding.type === "bug" ? exploreStyles.findingCardBug : finding.type === "concern" ? exploreStyles.findingCardConcern : finding.type === "suggestion" ? exploreStyles.findingCardSuggestion : exploreStyles.findingCardQuestion
|
|
14205
|
+
]
|
|
14206
|
+
},
|
|
14207
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingCardIcon }, finding.type === "bug" ? "\u{1F41B}" : finding.type === "concern" ? "\u26A0\uFE0F" : finding.type === "suggestion" ? "\u{1F4A1}" : "\u2753"),
|
|
14208
|
+
/* @__PURE__ */ React2.createElement(View, { style: { flex: 1 } }, /* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.findingCardTitle, numberOfLines: 1 }, finding.title), finding.severity && finding.type === "bug" && /* @__PURE__ */ React2.createElement(Text, { style: [
|
|
14209
|
+
exploreStyles.findingCardSeverity,
|
|
14210
|
+
finding.severity === "critical" ? { color: "#f87171" } : finding.severity === "high" ? { color: "#fb923c" } : finding.severity === "medium" ? { color: "#facc15" } : { color: "#a1a1aa" }
|
|
14211
|
+
] }, finding.severity))
|
|
14212
|
+
)))), /* @__PURE__ */ React2.createElement(
|
|
14213
|
+
TouchableOpacity,
|
|
14214
|
+
{
|
|
14215
|
+
onPress: () => setShowEndConfirm(true),
|
|
14216
|
+
style: exploreStyles.endSessionButton
|
|
14217
|
+
},
|
|
14218
|
+
/* @__PURE__ */ React2.createElement(Text, { style: exploreStyles.endSessionButtonText }, "End Session")
|
|
14219
|
+
))
|
|
13560
14220
|
)), activeTab === "report" && /* @__PURE__ */ React2.createElement(View, null, submitted ? /* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyEmoji }, "\u{1F389}"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyTitle }, "Report submitted!")) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(View, { style: styles.reportTypes }, [
|
|
13561
14221
|
{ type: "bug", label: "\u{1F41B} Bug" },
|
|
13562
14222
|
{ type: "feedback", label: "\u{1F4A1} Feedback" },
|
|
@@ -13696,7 +14356,7 @@ function BugBearButton({
|
|
|
13696
14356
|
/* @__PURE__ */ React2.createElement(Text, { style: styles.closeProfileButtonText }, "\u2190 Back")
|
|
13697
14357
|
))), activeTab === "messages" && messageView === "thread" && selectedThread ? (
|
|
13698
14358
|
/* Reply Composer */
|
|
13699
|
-
/* @__PURE__ */ React2.createElement(View, { style: styles.replyComposer }, /* @__PURE__ */ React2.createElement(
|
|
14359
|
+
/* @__PURE__ */ React2.createElement(View, null, messageSendError && /* @__PURE__ */ React2.createElement(View, { style: styles.messageSendError }, /* @__PURE__ */ React2.createElement(Text, { style: styles.messageSendErrorText }, "Failed to send. Tap Send to retry.")), /* @__PURE__ */ React2.createElement(View, { style: styles.replyComposer }, /* @__PURE__ */ React2.createElement(
|
|
13700
14360
|
TextInput,
|
|
13701
14361
|
{
|
|
13702
14362
|
style: styles.replyInput,
|
|
@@ -13718,12 +14378,67 @@ function BugBearButton({
|
|
|
13718
14378
|
disabled: !replyText.trim() || sendingReply
|
|
13719
14379
|
},
|
|
13720
14380
|
/* @__PURE__ */ React2.createElement(Text, { style: styles.sendButtonText }, sendingReply ? "..." : "Send")
|
|
13721
|
-
))
|
|
14381
|
+
)))
|
|
13722
14382
|
) : (
|
|
13723
14383
|
/* Standard Footer */
|
|
13724
|
-
/* @__PURE__ */ React2.createElement(View, { style: styles.footer }, activeTab === "messages" ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: refreshThreads }, /* @__PURE__ */ React2.createElement(Text, { style: styles.refreshText }, "\u21BB Refresh"))) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.footerText },
|
|
14384
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.footer }, activeTab === "messages" ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: refreshThreads }, /* @__PURE__ */ React2.createElement(Text, { style: styles.refreshText }, "\u21BB Refresh"))) : activeTab === "explore" ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.footerText }, activeSession ? `${sessionFindings.length} findings` : "No active session"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: refreshSession }, /* @__PURE__ */ React2.createElement(Text, { style: styles.refreshText }, "\u21BB Refresh"))) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.footerText }, passedCount + failedCount, "/", assignments.length, " done \xB7 ", pendingCount, " pending"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: refreshAssignments }, /* @__PURE__ */ React2.createElement(Text, { style: styles.refreshText }, "\u21BB Refresh"))))
|
|
13725
14385
|
))
|
|
13726
14386
|
)
|
|
14387
|
+
), /* @__PURE__ */ React2.createElement(
|
|
14388
|
+
Modal,
|
|
14389
|
+
{
|
|
14390
|
+
visible: showSkipModal,
|
|
14391
|
+
transparent: true,
|
|
14392
|
+
animationType: "fade",
|
|
14393
|
+
onRequestClose: () => setShowSkipModal(false)
|
|
14394
|
+
},
|
|
14395
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.skipModalOverlay }, /* @__PURE__ */ React2.createElement(View, { style: styles.skipModalContent }, /* @__PURE__ */ React2.createElement(Text, { style: styles.skipModalTitle }, "Skip Test"), /* @__PURE__ */ React2.createElement(Text, { style: styles.skipModalSubtitle }, "Why are you skipping this test?"), /* @__PURE__ */ React2.createElement(View, { style: styles.skipReasonOptions }, [
|
|
14396
|
+
{ value: "blocked", label: "\u{1F6AB} Blocked", desc: "Something is preventing testing" },
|
|
14397
|
+
{ value: "not_ready", label: "\u{1F6A7} Not Ready", desc: "Feature not yet implemented" },
|
|
14398
|
+
{ value: "dependency", label: "\u{1F517} Dependency", desc: "Waiting on another test/feature" },
|
|
14399
|
+
{ value: "other", label: "\u{1F4DD} Other", desc: "Different reason" }
|
|
14400
|
+
].map((option) => /* @__PURE__ */ React2.createElement(
|
|
14401
|
+
TouchableOpacity,
|
|
14402
|
+
{
|
|
14403
|
+
key: option.value,
|
|
14404
|
+
style: [
|
|
14405
|
+
styles.skipReasonOption,
|
|
14406
|
+
selectedSkipReason === option.value && styles.skipReasonOptionSelected
|
|
14407
|
+
],
|
|
14408
|
+
onPress: () => setSelectedSkipReason(option.value)
|
|
14409
|
+
},
|
|
14410
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.skipReasonLabel }, option.label),
|
|
14411
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.skipReasonDesc }, option.desc)
|
|
14412
|
+
))), /* @__PURE__ */ React2.createElement(
|
|
14413
|
+
TextInput,
|
|
14414
|
+
{
|
|
14415
|
+
style: styles.skipNotesInput,
|
|
14416
|
+
value: skipNotes,
|
|
14417
|
+
onChangeText: setSkipNotes,
|
|
14418
|
+
placeholder: "Add notes (optional)...",
|
|
14419
|
+
placeholderTextColor: "#71717a",
|
|
14420
|
+
multiline: true,
|
|
14421
|
+
numberOfLines: 2
|
|
14422
|
+
}
|
|
14423
|
+
), /* @__PURE__ */ React2.createElement(View, { style: styles.skipModalActions }, /* @__PURE__ */ React2.createElement(
|
|
14424
|
+
TouchableOpacity,
|
|
14425
|
+
{
|
|
14426
|
+
style: styles.skipModalCancel,
|
|
14427
|
+
onPress: () => setShowSkipModal(false)
|
|
14428
|
+
},
|
|
14429
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.skipModalCancelText }, "Cancel")
|
|
14430
|
+
), /* @__PURE__ */ React2.createElement(
|
|
14431
|
+
TouchableOpacity,
|
|
14432
|
+
{
|
|
14433
|
+
style: [
|
|
14434
|
+
styles.skipModalConfirm,
|
|
14435
|
+
!selectedSkipReason && styles.skipModalConfirmDisabled
|
|
14436
|
+
],
|
|
14437
|
+
onPress: handleSkip,
|
|
14438
|
+
disabled: !selectedSkipReason || skipping
|
|
14439
|
+
},
|
|
14440
|
+
/* @__PURE__ */ React2.createElement(Text, { style: styles.skipModalConfirmText }, skipping ? "Skipping..." : "Skip Test")
|
|
14441
|
+
))))
|
|
13727
14442
|
));
|
|
13728
14443
|
}
|
|
13729
14444
|
var styles = StyleSheet.create({
|
|
@@ -13856,7 +14571,8 @@ var styles = StyleSheet.create({
|
|
|
13856
14571
|
justifyContent: "space-between",
|
|
13857
14572
|
alignItems: "center",
|
|
13858
14573
|
paddingHorizontal: 16,
|
|
13859
|
-
|
|
14574
|
+
paddingTop: 12,
|
|
14575
|
+
paddingBottom: Platform2.OS === "ios" ? 34 : 12,
|
|
13860
14576
|
borderTopWidth: 1,
|
|
13861
14577
|
borderTopColor: "#27272a",
|
|
13862
14578
|
backgroundColor: "#09090b"
|
|
@@ -14426,6 +15142,13 @@ var styles = StyleSheet.create({
|
|
|
14426
15142
|
flexDirection: "row",
|
|
14427
15143
|
alignItems: "center"
|
|
14428
15144
|
},
|
|
15145
|
+
sessionDot: {
|
|
15146
|
+
width: 8,
|
|
15147
|
+
height: 8,
|
|
15148
|
+
borderRadius: 4,
|
|
15149
|
+
backgroundColor: "#22c55e",
|
|
15150
|
+
marginLeft: 4
|
|
15151
|
+
},
|
|
14429
15152
|
tabBadge: {
|
|
14430
15153
|
backgroundColor: "#EF4444",
|
|
14431
15154
|
borderRadius: 8,
|
|
@@ -14597,7 +15320,9 @@ var styles = StyleSheet.create({
|
|
|
14597
15320
|
replyComposer: {
|
|
14598
15321
|
flexDirection: "row",
|
|
14599
15322
|
alignItems: "flex-end",
|
|
14600
|
-
|
|
15323
|
+
paddingHorizontal: 12,
|
|
15324
|
+
paddingTop: 12,
|
|
15325
|
+
paddingBottom: Platform2.OS === "ios" ? 34 : 12,
|
|
14601
15326
|
borderTopWidth: 1,
|
|
14602
15327
|
borderTopColor: "#27272a",
|
|
14603
15328
|
backgroundColor: "#18181b"
|
|
@@ -14980,6 +15705,715 @@ var styles = StyleSheet.create({
|
|
|
14980
15705
|
fontSize: 14,
|
|
14981
15706
|
fontWeight: "500",
|
|
14982
15707
|
color: "#3B82F6"
|
|
15708
|
+
},
|
|
15709
|
+
// Folder grouping styles
|
|
15710
|
+
folderContainer: {
|
|
15711
|
+
marginBottom: 12
|
|
15712
|
+
},
|
|
15713
|
+
folderHeader: {
|
|
15714
|
+
flexDirection: "row",
|
|
15715
|
+
justifyContent: "space-between",
|
|
15716
|
+
alignItems: "center",
|
|
15717
|
+
backgroundColor: "#27272a",
|
|
15718
|
+
padding: 12,
|
|
15719
|
+
borderRadius: 8,
|
|
15720
|
+
marginBottom: 4
|
|
15721
|
+
},
|
|
15722
|
+
folderHeaderLeft: {
|
|
15723
|
+
flexDirection: "row",
|
|
15724
|
+
alignItems: "center",
|
|
15725
|
+
flex: 1
|
|
15726
|
+
},
|
|
15727
|
+
folderIcon: {
|
|
15728
|
+
fontSize: 16,
|
|
15729
|
+
marginRight: 8
|
|
15730
|
+
},
|
|
15731
|
+
folderName: {
|
|
15732
|
+
fontSize: 14,
|
|
15733
|
+
fontWeight: "600",
|
|
15734
|
+
color: "#fafafa"
|
|
15735
|
+
},
|
|
15736
|
+
folderStats: {
|
|
15737
|
+
flexDirection: "row",
|
|
15738
|
+
alignItems: "center"
|
|
15739
|
+
},
|
|
15740
|
+
folderProgress: {
|
|
15741
|
+
fontSize: 12,
|
|
15742
|
+
color: "#71717a",
|
|
15743
|
+
marginRight: 8
|
|
15744
|
+
},
|
|
15745
|
+
folderChevron: {
|
|
15746
|
+
fontSize: 10,
|
|
15747
|
+
color: "#71717a"
|
|
15748
|
+
},
|
|
15749
|
+
folderProgressBar: {
|
|
15750
|
+
height: 3,
|
|
15751
|
+
backgroundColor: "#3f3f46",
|
|
15752
|
+
borderRadius: 2,
|
|
15753
|
+
marginBottom: 8,
|
|
15754
|
+
marginHorizontal: 4
|
|
15755
|
+
},
|
|
15756
|
+
folderProgressFill: {
|
|
15757
|
+
height: "100%",
|
|
15758
|
+
backgroundColor: "#22c55e",
|
|
15759
|
+
borderRadius: 2
|
|
15760
|
+
},
|
|
15761
|
+
listItemInFolder: {
|
|
15762
|
+
marginLeft: 12,
|
|
15763
|
+
borderLeftWidth: 2,
|
|
15764
|
+
borderLeftColor: "#3f3f46",
|
|
15765
|
+
paddingLeft: 12
|
|
15766
|
+
},
|
|
15767
|
+
listItemKeyWithStatus: {
|
|
15768
|
+
flexDirection: "row",
|
|
15769
|
+
alignItems: "center",
|
|
15770
|
+
flex: 1
|
|
15771
|
+
},
|
|
15772
|
+
statusBadge: {
|
|
15773
|
+
flexDirection: "row",
|
|
15774
|
+
alignItems: "center",
|
|
15775
|
+
paddingHorizontal: 6,
|
|
15776
|
+
paddingVertical: 2,
|
|
15777
|
+
borderRadius: 4,
|
|
15778
|
+
marginLeft: 8
|
|
15779
|
+
},
|
|
15780
|
+
statusBadgeIcon: {
|
|
15781
|
+
fontSize: 10,
|
|
15782
|
+
marginRight: 4
|
|
15783
|
+
},
|
|
15784
|
+
statusBadgeText: {
|
|
15785
|
+
fontSize: 10,
|
|
15786
|
+
fontWeight: "600"
|
|
15787
|
+
},
|
|
15788
|
+
// Skip button styles
|
|
15789
|
+
skipButton: {
|
|
15790
|
+
flex: 1,
|
|
15791
|
+
backgroundColor: "#eab308",
|
|
15792
|
+
paddingVertical: 14,
|
|
15793
|
+
borderRadius: 12,
|
|
15794
|
+
alignItems: "center",
|
|
15795
|
+
marginHorizontal: 4
|
|
15796
|
+
},
|
|
15797
|
+
skipButtonText: {
|
|
15798
|
+
fontSize: 15,
|
|
15799
|
+
fontWeight: "600",
|
|
15800
|
+
color: "#18181b"
|
|
15801
|
+
},
|
|
15802
|
+
// Skip modal styles
|
|
15803
|
+
skipModalOverlay: {
|
|
15804
|
+
flex: 1,
|
|
15805
|
+
backgroundColor: "rgba(0, 0, 0, 0.7)",
|
|
15806
|
+
justifyContent: "center",
|
|
15807
|
+
alignItems: "center",
|
|
15808
|
+
padding: 20
|
|
15809
|
+
},
|
|
15810
|
+
skipModalContent: {
|
|
15811
|
+
backgroundColor: "#18181b",
|
|
15812
|
+
borderRadius: 16,
|
|
15813
|
+
padding: 20,
|
|
15814
|
+
width: "100%",
|
|
15815
|
+
maxWidth: 340,
|
|
15816
|
+
borderWidth: 1,
|
|
15817
|
+
borderColor: "#3f3f46"
|
|
15818
|
+
},
|
|
15819
|
+
skipModalTitle: {
|
|
15820
|
+
fontSize: 18,
|
|
15821
|
+
fontWeight: "600",
|
|
15822
|
+
color: "#fafafa",
|
|
15823
|
+
marginBottom: 4
|
|
15824
|
+
},
|
|
15825
|
+
skipModalSubtitle: {
|
|
15826
|
+
fontSize: 14,
|
|
15827
|
+
color: "#71717a",
|
|
15828
|
+
marginBottom: 16
|
|
15829
|
+
},
|
|
15830
|
+
skipReasonOptions: {
|
|
15831
|
+
marginBottom: 16
|
|
15832
|
+
},
|
|
15833
|
+
skipReasonOption: {
|
|
15834
|
+
backgroundColor: "#27272a",
|
|
15835
|
+
padding: 12,
|
|
15836
|
+
borderRadius: 8,
|
|
15837
|
+
marginBottom: 8,
|
|
15838
|
+
borderWidth: 2,
|
|
15839
|
+
borderColor: "transparent"
|
|
15840
|
+
},
|
|
15841
|
+
skipReasonOptionSelected: {
|
|
15842
|
+
borderColor: "#eab308",
|
|
15843
|
+
backgroundColor: "#422006"
|
|
15844
|
+
},
|
|
15845
|
+
skipReasonLabel: {
|
|
15846
|
+
fontSize: 14,
|
|
15847
|
+
fontWeight: "600",
|
|
15848
|
+
color: "#fafafa",
|
|
15849
|
+
marginBottom: 2
|
|
15850
|
+
},
|
|
15851
|
+
skipReasonDesc: {
|
|
15852
|
+
fontSize: 12,
|
|
15853
|
+
color: "#71717a"
|
|
15854
|
+
},
|
|
15855
|
+
skipNotesInput: {
|
|
15856
|
+
backgroundColor: "#27272a",
|
|
15857
|
+
borderWidth: 1,
|
|
15858
|
+
borderColor: "#3f3f46",
|
|
15859
|
+
borderRadius: 8,
|
|
15860
|
+
padding: 12,
|
|
15861
|
+
fontSize: 14,
|
|
15862
|
+
color: "#fafafa",
|
|
15863
|
+
minHeight: 60,
|
|
15864
|
+
textAlignVertical: "top",
|
|
15865
|
+
marginBottom: 16
|
|
15866
|
+
},
|
|
15867
|
+
skipModalActions: {
|
|
15868
|
+
flexDirection: "row",
|
|
15869
|
+
gap: 8
|
|
15870
|
+
},
|
|
15871
|
+
skipModalCancel: {
|
|
15872
|
+
flex: 1,
|
|
15873
|
+
backgroundColor: "#3f3f46",
|
|
15874
|
+
paddingVertical: 12,
|
|
15875
|
+
borderRadius: 8,
|
|
15876
|
+
alignItems: "center"
|
|
15877
|
+
},
|
|
15878
|
+
skipModalCancelText: {
|
|
15879
|
+
fontSize: 14,
|
|
15880
|
+
fontWeight: "600",
|
|
15881
|
+
color: "#e4e4e7"
|
|
15882
|
+
},
|
|
15883
|
+
skipModalConfirm: {
|
|
15884
|
+
flex: 1,
|
|
15885
|
+
backgroundColor: "#eab308",
|
|
15886
|
+
paddingVertical: 12,
|
|
15887
|
+
borderRadius: 8,
|
|
15888
|
+
alignItems: "center"
|
|
15889
|
+
},
|
|
15890
|
+
skipModalConfirmDisabled: {
|
|
15891
|
+
backgroundColor: "#713f12"
|
|
15892
|
+
},
|
|
15893
|
+
skipModalConfirmText: {
|
|
15894
|
+
fontSize: 14,
|
|
15895
|
+
fontWeight: "600",
|
|
15896
|
+
color: "#18181b"
|
|
15897
|
+
},
|
|
15898
|
+
// Detail progress bar styles
|
|
15899
|
+
detailProgressContainer: {
|
|
15900
|
+
backgroundColor: "#27272a",
|
|
15901
|
+
padding: 12,
|
|
15902
|
+
borderRadius: 8,
|
|
15903
|
+
marginTop: 16,
|
|
15904
|
+
marginBottom: 8
|
|
15905
|
+
},
|
|
15906
|
+
detailProgressText: {
|
|
15907
|
+
fontSize: 12,
|
|
15908
|
+
color: "#a1a1aa",
|
|
15909
|
+
marginBottom: 8
|
|
15910
|
+
},
|
|
15911
|
+
detailProgressBar: {
|
|
15912
|
+
height: 4,
|
|
15913
|
+
backgroundColor: "#3f3f46",
|
|
15914
|
+
borderRadius: 2
|
|
15915
|
+
},
|
|
15916
|
+
detailProgressFill: {
|
|
15917
|
+
height: "100%",
|
|
15918
|
+
backgroundColor: "#22c55e",
|
|
15919
|
+
borderRadius: 2
|
|
15920
|
+
},
|
|
15921
|
+
nextTestButton: {
|
|
15922
|
+
backgroundColor: "#27272a",
|
|
15923
|
+
paddingVertical: 10,
|
|
15924
|
+
borderRadius: 10,
|
|
15925
|
+
alignItems: "center",
|
|
15926
|
+
marginTop: 8,
|
|
15927
|
+
borderWidth: 1,
|
|
15928
|
+
borderColor: "#3f3f46"
|
|
15929
|
+
},
|
|
15930
|
+
nextTestButtonText: {
|
|
15931
|
+
fontSize: 14,
|
|
15932
|
+
fontWeight: "500",
|
|
15933
|
+
color: "#a1a1aa"
|
|
15934
|
+
},
|
|
15935
|
+
filterBar: {
|
|
15936
|
+
flexDirection: "row",
|
|
15937
|
+
gap: 6,
|
|
15938
|
+
marginBottom: 10
|
|
15939
|
+
},
|
|
15940
|
+
filterChip: {
|
|
15941
|
+
paddingHorizontal: 10,
|
|
15942
|
+
paddingVertical: 5,
|
|
15943
|
+
borderRadius: 12,
|
|
15944
|
+
backgroundColor: "#27272a",
|
|
15945
|
+
borderWidth: 1,
|
|
15946
|
+
borderColor: "#3f3f46"
|
|
15947
|
+
},
|
|
15948
|
+
filterChipActive: {
|
|
15949
|
+
backgroundColor: "#1e3a5f",
|
|
15950
|
+
borderColor: "#3B82F6"
|
|
15951
|
+
},
|
|
15952
|
+
filterChipText: {
|
|
15953
|
+
fontSize: 12,
|
|
15954
|
+
color: "#71717a"
|
|
15955
|
+
},
|
|
15956
|
+
filterChipTextActive: {
|
|
15957
|
+
color: "#93c5fd"
|
|
15958
|
+
},
|
|
15959
|
+
messageSendError: {
|
|
15960
|
+
backgroundColor: "#7f1d1d",
|
|
15961
|
+
paddingHorizontal: 12,
|
|
15962
|
+
paddingVertical: 6,
|
|
15963
|
+
borderTopWidth: 1,
|
|
15964
|
+
borderTopColor: "#991b1b"
|
|
15965
|
+
},
|
|
15966
|
+
messageSendErrorText: {
|
|
15967
|
+
fontSize: 12,
|
|
15968
|
+
color: "#fca5a5",
|
|
15969
|
+
textAlign: "center"
|
|
15970
|
+
}
|
|
15971
|
+
});
|
|
15972
|
+
var exploreStyles = StyleSheet.create({
|
|
15973
|
+
formGroup: {
|
|
15974
|
+
marginBottom: 12
|
|
15975
|
+
},
|
|
15976
|
+
label: {
|
|
15977
|
+
fontSize: 12,
|
|
15978
|
+
fontWeight: "500",
|
|
15979
|
+
color: "#d4d4d8",
|
|
15980
|
+
marginBottom: 6
|
|
15981
|
+
},
|
|
15982
|
+
input: {
|
|
15983
|
+
backgroundColor: "#27272a",
|
|
15984
|
+
borderRadius: 8,
|
|
15985
|
+
paddingHorizontal: 12,
|
|
15986
|
+
paddingVertical: 10,
|
|
15987
|
+
fontSize: 14,
|
|
15988
|
+
color: "#fafafa",
|
|
15989
|
+
borderWidth: 1,
|
|
15990
|
+
borderColor: "#3f3f46"
|
|
15991
|
+
},
|
|
15992
|
+
platformRow: {
|
|
15993
|
+
flexDirection: "row",
|
|
15994
|
+
gap: 8
|
|
15995
|
+
},
|
|
15996
|
+
platformButton: {
|
|
15997
|
+
flex: 1,
|
|
15998
|
+
paddingVertical: 10,
|
|
15999
|
+
paddingHorizontal: 8,
|
|
16000
|
+
borderRadius: 8,
|
|
16001
|
+
backgroundColor: "#27272a",
|
|
16002
|
+
borderWidth: 2,
|
|
16003
|
+
borderColor: "transparent",
|
|
16004
|
+
alignItems: "center"
|
|
16005
|
+
},
|
|
16006
|
+
platformButtonActive: {
|
|
16007
|
+
backgroundColor: "#172554",
|
|
16008
|
+
borderColor: "#3B82F6"
|
|
16009
|
+
},
|
|
16010
|
+
platformButtonText: {
|
|
16011
|
+
fontSize: 12,
|
|
16012
|
+
fontWeight: "500",
|
|
16013
|
+
color: "#a1a1aa"
|
|
16014
|
+
},
|
|
16015
|
+
platformButtonTextActive: {
|
|
16016
|
+
color: "#93c5fd"
|
|
16017
|
+
},
|
|
16018
|
+
startButton: {
|
|
16019
|
+
backgroundColor: "#16a34a",
|
|
16020
|
+
borderRadius: 8,
|
|
16021
|
+
paddingVertical: 14,
|
|
16022
|
+
alignItems: "center",
|
|
16023
|
+
marginTop: 4
|
|
16024
|
+
},
|
|
16025
|
+
startButtonText: {
|
|
16026
|
+
color: "#fff",
|
|
16027
|
+
fontSize: 14,
|
|
16028
|
+
fontWeight: "600"
|
|
16029
|
+
},
|
|
16030
|
+
buttonRow: {
|
|
16031
|
+
flexDirection: "row",
|
|
16032
|
+
gap: 8
|
|
16033
|
+
},
|
|
16034
|
+
cancelButton: {
|
|
16035
|
+
flex: 1,
|
|
16036
|
+
backgroundColor: "#3f3f46",
|
|
16037
|
+
borderRadius: 8,
|
|
16038
|
+
paddingVertical: 10,
|
|
16039
|
+
alignItems: "center"
|
|
16040
|
+
},
|
|
16041
|
+
cancelButtonText: {
|
|
16042
|
+
color: "#d4d4d8",
|
|
16043
|
+
fontSize: 14,
|
|
16044
|
+
fontWeight: "500"
|
|
16045
|
+
},
|
|
16046
|
+
endButton: {
|
|
16047
|
+
flex: 1,
|
|
16048
|
+
backgroundColor: "#dc2626",
|
|
16049
|
+
borderRadius: 8,
|
|
16050
|
+
paddingVertical: 10,
|
|
16051
|
+
alignItems: "center"
|
|
16052
|
+
},
|
|
16053
|
+
endButtonText: {
|
|
16054
|
+
color: "#fff",
|
|
16055
|
+
fontSize: 14,
|
|
16056
|
+
fontWeight: "500"
|
|
16057
|
+
},
|
|
16058
|
+
findingHeader: {
|
|
16059
|
+
flexDirection: "row",
|
|
16060
|
+
justifyContent: "space-between",
|
|
16061
|
+
alignItems: "center",
|
|
16062
|
+
marginBottom: 12
|
|
16063
|
+
},
|
|
16064
|
+
findingHeaderTitle: {
|
|
16065
|
+
fontSize: 14,
|
|
16066
|
+
fontWeight: "600",
|
|
16067
|
+
color: "#fafafa"
|
|
16068
|
+
},
|
|
16069
|
+
findingHeaderClose: {
|
|
16070
|
+
fontSize: 16,
|
|
16071
|
+
color: "#71717a"
|
|
16072
|
+
},
|
|
16073
|
+
findingTypeRow: {
|
|
16074
|
+
flexDirection: "row",
|
|
16075
|
+
gap: 4,
|
|
16076
|
+
marginBottom: 12
|
|
16077
|
+
},
|
|
16078
|
+
findingTypeButton: {
|
|
16079
|
+
flex: 1,
|
|
16080
|
+
paddingVertical: 8,
|
|
16081
|
+
paddingHorizontal: 4,
|
|
16082
|
+
borderRadius: 6,
|
|
16083
|
+
backgroundColor: "#3f3f46",
|
|
16084
|
+
alignItems: "center"
|
|
16085
|
+
},
|
|
16086
|
+
findingTypeButtonActive: {
|
|
16087
|
+
backgroundColor: "#1e3a5f",
|
|
16088
|
+
borderWidth: 2,
|
|
16089
|
+
borderColor: "#3B82F6"
|
|
16090
|
+
},
|
|
16091
|
+
findingTypeButtonText: {
|
|
16092
|
+
fontSize: 11,
|
|
16093
|
+
fontWeight: "500",
|
|
16094
|
+
color: "#a1a1aa"
|
|
16095
|
+
},
|
|
16096
|
+
findingTypeButtonTextActive: {
|
|
16097
|
+
color: "#93c5fd"
|
|
16098
|
+
},
|
|
16099
|
+
severityRow: {
|
|
16100
|
+
flexDirection: "row",
|
|
16101
|
+
gap: 4
|
|
16102
|
+
},
|
|
16103
|
+
severityButton: {
|
|
16104
|
+
flex: 1,
|
|
16105
|
+
paddingVertical: 6,
|
|
16106
|
+
borderRadius: 6,
|
|
16107
|
+
backgroundColor: "#3f3f46",
|
|
16108
|
+
alignItems: "center"
|
|
16109
|
+
},
|
|
16110
|
+
severityCritical: {
|
|
16111
|
+
backgroundColor: "#dc2626"
|
|
16112
|
+
},
|
|
16113
|
+
severityHigh: {
|
|
16114
|
+
backgroundColor: "#f97316"
|
|
16115
|
+
},
|
|
16116
|
+
severityMedium: {
|
|
16117
|
+
backgroundColor: "#eab308"
|
|
16118
|
+
},
|
|
16119
|
+
severityLow: {
|
|
16120
|
+
backgroundColor: "#3f3f46",
|
|
16121
|
+
borderWidth: 1,
|
|
16122
|
+
borderColor: "#71717a"
|
|
16123
|
+
},
|
|
16124
|
+
severityButtonText: {
|
|
16125
|
+
fontSize: 11,
|
|
16126
|
+
fontWeight: "500",
|
|
16127
|
+
color: "#a1a1aa",
|
|
16128
|
+
textTransform: "capitalize"
|
|
16129
|
+
},
|
|
16130
|
+
severityButtonTextActive: {
|
|
16131
|
+
color: "#fff"
|
|
16132
|
+
},
|
|
16133
|
+
addFindingButton: {
|
|
16134
|
+
backgroundColor: "#3B82F6",
|
|
16135
|
+
borderRadius: 8,
|
|
16136
|
+
paddingVertical: 10,
|
|
16137
|
+
alignItems: "center"
|
|
16138
|
+
},
|
|
16139
|
+
addFindingButtonText: {
|
|
16140
|
+
color: "#fff",
|
|
16141
|
+
fontSize: 14,
|
|
16142
|
+
fontWeight: "500"
|
|
16143
|
+
},
|
|
16144
|
+
sessionBanner: {
|
|
16145
|
+
backgroundColor: "rgba(22, 163, 74, 0.15)",
|
|
16146
|
+
borderRadius: 12,
|
|
16147
|
+
padding: 12,
|
|
16148
|
+
marginBottom: 12,
|
|
16149
|
+
borderWidth: 1,
|
|
16150
|
+
borderColor: "#166534"
|
|
16151
|
+
},
|
|
16152
|
+
sessionBannerRow: {
|
|
16153
|
+
flexDirection: "row",
|
|
16154
|
+
justifyContent: "space-between",
|
|
16155
|
+
alignItems: "center"
|
|
16156
|
+
},
|
|
16157
|
+
sessionBannerLeft: {
|
|
16158
|
+
flexDirection: "row",
|
|
16159
|
+
alignItems: "center",
|
|
16160
|
+
gap: 8
|
|
16161
|
+
},
|
|
16162
|
+
sessionDotLarge: {
|
|
16163
|
+
width: 8,
|
|
16164
|
+
height: 8,
|
|
16165
|
+
borderRadius: 4,
|
|
16166
|
+
backgroundColor: "#22c55e"
|
|
16167
|
+
},
|
|
16168
|
+
sessionBannerLabel: {
|
|
16169
|
+
fontSize: 14,
|
|
16170
|
+
fontWeight: "500",
|
|
16171
|
+
color: "#86efac"
|
|
16172
|
+
},
|
|
16173
|
+
sessionTimer: {
|
|
16174
|
+
fontSize: 20,
|
|
16175
|
+
fontWeight: "600",
|
|
16176
|
+
color: "#4ade80",
|
|
16177
|
+
fontVariant: ["tabular-nums"]
|
|
16178
|
+
},
|
|
16179
|
+
sessionFocus: {
|
|
16180
|
+
fontSize: 12,
|
|
16181
|
+
color: "#4ade80",
|
|
16182
|
+
marginTop: 4
|
|
16183
|
+
},
|
|
16184
|
+
addButton: {
|
|
16185
|
+
backgroundColor: "#3B82F6",
|
|
16186
|
+
borderRadius: 8,
|
|
16187
|
+
paddingVertical: 14,
|
|
16188
|
+
alignItems: "center",
|
|
16189
|
+
marginBottom: 12
|
|
16190
|
+
},
|
|
16191
|
+
addButtonText: {
|
|
16192
|
+
color: "#fff",
|
|
16193
|
+
fontSize: 14,
|
|
16194
|
+
fontWeight: "600"
|
|
16195
|
+
},
|
|
16196
|
+
findingsSection: {
|
|
16197
|
+
marginBottom: 12
|
|
16198
|
+
},
|
|
16199
|
+
findingsLabel: {
|
|
16200
|
+
fontSize: 12,
|
|
16201
|
+
fontWeight: "500",
|
|
16202
|
+
color: "#71717a",
|
|
16203
|
+
marginBottom: 8
|
|
16204
|
+
},
|
|
16205
|
+
findingsEmpty: {
|
|
16206
|
+
backgroundColor: "#27272a",
|
|
16207
|
+
borderRadius: 8,
|
|
16208
|
+
paddingVertical: 16,
|
|
16209
|
+
alignItems: "center"
|
|
16210
|
+
},
|
|
16211
|
+
findingsEmptyText: {
|
|
16212
|
+
fontSize: 12,
|
|
16213
|
+
color: "#71717a"
|
|
16214
|
+
},
|
|
16215
|
+
findingCard: {
|
|
16216
|
+
flexDirection: "row",
|
|
16217
|
+
alignItems: "flex-start",
|
|
16218
|
+
padding: 8,
|
|
16219
|
+
borderRadius: 8,
|
|
16220
|
+
marginBottom: 6,
|
|
16221
|
+
borderWidth: 1,
|
|
16222
|
+
gap: 8
|
|
16223
|
+
},
|
|
16224
|
+
findingCardBug: {
|
|
16225
|
+
backgroundColor: "rgba(220, 38, 38, 0.1)",
|
|
16226
|
+
borderColor: "#991b1b"
|
|
16227
|
+
},
|
|
16228
|
+
findingCardConcern: {
|
|
16229
|
+
backgroundColor: "rgba(249, 115, 22, 0.1)",
|
|
16230
|
+
borderColor: "#9a3412"
|
|
16231
|
+
},
|
|
16232
|
+
findingCardSuggestion: {
|
|
16233
|
+
backgroundColor: "rgba(59, 130, 246, 0.1)",
|
|
16234
|
+
borderColor: "#1e40af"
|
|
16235
|
+
},
|
|
16236
|
+
findingCardQuestion: {
|
|
16237
|
+
backgroundColor: "rgba(139, 92, 246, 0.1)",
|
|
16238
|
+
borderColor: "#5b21b6"
|
|
16239
|
+
},
|
|
16240
|
+
findingCardIcon: {
|
|
16241
|
+
fontSize: 14
|
|
16242
|
+
},
|
|
16243
|
+
findingCardTitle: {
|
|
16244
|
+
fontSize: 12,
|
|
16245
|
+
fontWeight: "500",
|
|
16246
|
+
color: "#fafafa"
|
|
16247
|
+
},
|
|
16248
|
+
findingCardSeverity: {
|
|
16249
|
+
fontSize: 10,
|
|
16250
|
+
fontWeight: "500",
|
|
16251
|
+
marginTop: 2,
|
|
16252
|
+
textTransform: "capitalize"
|
|
16253
|
+
},
|
|
16254
|
+
endSessionButton: {
|
|
16255
|
+
backgroundColor: "#3f3f46",
|
|
16256
|
+
borderRadius: 8,
|
|
16257
|
+
paddingVertical: 10,
|
|
16258
|
+
alignItems: "center"
|
|
16259
|
+
},
|
|
16260
|
+
endSessionButtonText: {
|
|
16261
|
+
color: "#d4d4d8",
|
|
16262
|
+
fontSize: 14,
|
|
16263
|
+
fontWeight: "500"
|
|
16264
|
+
}
|
|
16265
|
+
});
|
|
16266
|
+
var feedbackStyles = StyleSheet.create({
|
|
16267
|
+
container: {
|
|
16268
|
+
padding: 4
|
|
16269
|
+
},
|
|
16270
|
+
statusText: {
|
|
16271
|
+
fontSize: 16,
|
|
16272
|
+
fontWeight: "600",
|
|
16273
|
+
marginTop: 4
|
|
16274
|
+
},
|
|
16275
|
+
infoBox: {
|
|
16276
|
+
backgroundColor: "rgba(59, 130, 246, 0.1)",
|
|
16277
|
+
borderRadius: 8,
|
|
16278
|
+
padding: 12,
|
|
16279
|
+
marginBottom: 16,
|
|
16280
|
+
borderWidth: 1,
|
|
16281
|
+
borderColor: "#1e3a5f"
|
|
16282
|
+
},
|
|
16283
|
+
infoTitle: {
|
|
16284
|
+
fontSize: 14,
|
|
16285
|
+
fontWeight: "500",
|
|
16286
|
+
color: "#93c5fd",
|
|
16287
|
+
marginBottom: 4
|
|
16288
|
+
},
|
|
16289
|
+
infoSubtitle: {
|
|
16290
|
+
fontSize: 12,
|
|
16291
|
+
color: "#60a5fa"
|
|
16292
|
+
},
|
|
16293
|
+
ratingSection: {
|
|
16294
|
+
alignItems: "center",
|
|
16295
|
+
marginBottom: 16
|
|
16296
|
+
},
|
|
16297
|
+
ratingLabel: {
|
|
16298
|
+
fontSize: 12,
|
|
16299
|
+
fontWeight: "500",
|
|
16300
|
+
color: "#a1a1aa",
|
|
16301
|
+
marginBottom: 8
|
|
16302
|
+
},
|
|
16303
|
+
starsRow: {
|
|
16304
|
+
flexDirection: "row",
|
|
16305
|
+
gap: 4
|
|
16306
|
+
},
|
|
16307
|
+
star: {
|
|
16308
|
+
fontSize: 28
|
|
16309
|
+
},
|
|
16310
|
+
starActive: {
|
|
16311
|
+
color: "#facc15"
|
|
16312
|
+
},
|
|
16313
|
+
starInactive: {
|
|
16314
|
+
color: "#3f3f46"
|
|
16315
|
+
},
|
|
16316
|
+
ratingDesc: {
|
|
16317
|
+
fontSize: 12,
|
|
16318
|
+
color: "#71717a",
|
|
16319
|
+
marginTop: 4
|
|
16320
|
+
},
|
|
16321
|
+
flagsSection: {
|
|
16322
|
+
marginBottom: 12
|
|
16323
|
+
},
|
|
16324
|
+
flagsGrid: {
|
|
16325
|
+
flexDirection: "row",
|
|
16326
|
+
flexWrap: "wrap",
|
|
16327
|
+
gap: 8
|
|
16328
|
+
},
|
|
16329
|
+
flagButton: {
|
|
16330
|
+
paddingHorizontal: 10,
|
|
16331
|
+
paddingVertical: 6,
|
|
16332
|
+
borderRadius: 6,
|
|
16333
|
+
backgroundColor: "#27272a",
|
|
16334
|
+
borderWidth: 1,
|
|
16335
|
+
borderColor: "#3f3f46"
|
|
16336
|
+
},
|
|
16337
|
+
flagButtonActive: {
|
|
16338
|
+
backgroundColor: "#1e3a5f",
|
|
16339
|
+
borderColor: "#3B82F6"
|
|
16340
|
+
},
|
|
16341
|
+
flagButtonText: {
|
|
16342
|
+
fontSize: 12,
|
|
16343
|
+
fontWeight: "500",
|
|
16344
|
+
color: "#a1a1aa"
|
|
16345
|
+
},
|
|
16346
|
+
flagButtonTextActive: {
|
|
16347
|
+
color: "#93c5fd"
|
|
16348
|
+
},
|
|
16349
|
+
noteInput: {
|
|
16350
|
+
backgroundColor: "#27272a",
|
|
16351
|
+
borderRadius: 8,
|
|
16352
|
+
paddingHorizontal: 12,
|
|
16353
|
+
paddingVertical: 10,
|
|
16354
|
+
fontSize: 14,
|
|
16355
|
+
color: "#fafafa",
|
|
16356
|
+
borderWidth: 1,
|
|
16357
|
+
borderColor: "#3f3f46",
|
|
16358
|
+
minHeight: 60
|
|
16359
|
+
},
|
|
16360
|
+
buttonRow: {
|
|
16361
|
+
flexDirection: "row",
|
|
16362
|
+
gap: 8
|
|
16363
|
+
},
|
|
16364
|
+
skipButton: {
|
|
16365
|
+
flex: 1,
|
|
16366
|
+
paddingVertical: 10,
|
|
16367
|
+
backgroundColor: "#3f3f46",
|
|
16368
|
+
borderRadius: 8,
|
|
16369
|
+
alignItems: "center"
|
|
16370
|
+
},
|
|
16371
|
+
skipButtonText: {
|
|
16372
|
+
color: "#a1a1aa",
|
|
16373
|
+
fontSize: 14,
|
|
16374
|
+
fontWeight: "500"
|
|
16375
|
+
},
|
|
16376
|
+
submitButton: {
|
|
16377
|
+
flex: 1,
|
|
16378
|
+
paddingVertical: 10,
|
|
16379
|
+
backgroundColor: "#3B82F6",
|
|
16380
|
+
borderRadius: 8,
|
|
16381
|
+
alignItems: "center"
|
|
16382
|
+
},
|
|
16383
|
+
submitButtonText: {
|
|
16384
|
+
color: "#fff",
|
|
16385
|
+
fontSize: 14,
|
|
16386
|
+
fontWeight: "500"
|
|
16387
|
+
}
|
|
16388
|
+
});
|
|
16389
|
+
var timerStyles = StyleSheet.create({
|
|
16390
|
+
container: {
|
|
16391
|
+
flexDirection: "row",
|
|
16392
|
+
alignItems: "center",
|
|
16393
|
+
gap: 6,
|
|
16394
|
+
backgroundColor: "rgba(22, 163, 74, 0.15)",
|
|
16395
|
+
paddingHorizontal: 8,
|
|
16396
|
+
paddingVertical: 4,
|
|
16397
|
+
borderRadius: 6,
|
|
16398
|
+
marginBottom: 8,
|
|
16399
|
+
alignSelf: "flex-start"
|
|
16400
|
+
},
|
|
16401
|
+
dot: {
|
|
16402
|
+
width: 6,
|
|
16403
|
+
height: 6,
|
|
16404
|
+
borderRadius: 3,
|
|
16405
|
+
backgroundColor: "#22c55e"
|
|
16406
|
+
},
|
|
16407
|
+
label: {
|
|
16408
|
+
fontSize: 12,
|
|
16409
|
+
fontWeight: "500",
|
|
16410
|
+
color: "#4ade80"
|
|
16411
|
+
},
|
|
16412
|
+
time: {
|
|
16413
|
+
fontSize: 12,
|
|
16414
|
+
fontWeight: "600",
|
|
16415
|
+
color: "#4ade80",
|
|
16416
|
+
fontVariant: ["tabular-nums"]
|
|
14983
16417
|
}
|
|
14984
16418
|
});
|
|
14985
16419
|
export {
|