@bbearai/react 0.1.5 → 0.1.7
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 +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +260 -3
- package/dist/index.mjs +260 -3
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode, Component, ErrorInfo } from 'react';
|
|
3
3
|
import * as _bbearai_core from '@bbearai/core';
|
|
4
|
-
import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, AppContext, captureError } from '@bbearai/core';
|
|
4
|
+
import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, TesterProfileUpdate, AppContext, captureError } from '@bbearai/core';
|
|
5
5
|
export { AppContext, BugBearConfig, BugBearReport, ConsoleLogEntry, DeviceInfo, EnhancedBugContext, NetworkRequest, QATrack, ReportType, Severity, TestAssignment, TestTemplate, TesterInfo, captureError, contextCapture } from '@bbearai/core';
|
|
6
6
|
|
|
7
7
|
interface BugBearContextValue {
|
|
@@ -18,6 +18,13 @@ interface BugBearContextValue {
|
|
|
18
18
|
onNavigate?: (route: string) => void;
|
|
19
19
|
/** Re-check tester status (call after auth state changes) */
|
|
20
20
|
refreshTesterStatus: () => Promise<void>;
|
|
21
|
+
/** Update tester profile */
|
|
22
|
+
updateTesterProfile: (updates: TesterProfileUpdate) => Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
error?: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** Refresh tester info from server */
|
|
27
|
+
refreshTesterInfo: () => Promise<void>;
|
|
21
28
|
}
|
|
22
29
|
declare function useBugBear(): BugBearContextValue;
|
|
23
30
|
interface BugBearProviderProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode, Component, ErrorInfo } from 'react';
|
|
3
3
|
import * as _bbearai_core from '@bbearai/core';
|
|
4
|
-
import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, AppContext, captureError } from '@bbearai/core';
|
|
4
|
+
import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, TesterProfileUpdate, AppContext, captureError } from '@bbearai/core';
|
|
5
5
|
export { AppContext, BugBearConfig, BugBearReport, ConsoleLogEntry, DeviceInfo, EnhancedBugContext, NetworkRequest, QATrack, ReportType, Severity, TestAssignment, TestTemplate, TesterInfo, captureError, contextCapture } from '@bbearai/core';
|
|
6
6
|
|
|
7
7
|
interface BugBearContextValue {
|
|
@@ -18,6 +18,13 @@ interface BugBearContextValue {
|
|
|
18
18
|
onNavigate?: (route: string) => void;
|
|
19
19
|
/** Re-check tester status (call after auth state changes) */
|
|
20
20
|
refreshTesterStatus: () => Promise<void>;
|
|
21
|
+
/** Update tester profile */
|
|
22
|
+
updateTesterProfile: (updates: TesterProfileUpdate) => Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
error?: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** Refresh tester info from server */
|
|
27
|
+
refreshTesterInfo: () => Promise<void>;
|
|
21
28
|
}
|
|
22
29
|
declare function useBugBear(): BugBearContextValue;
|
|
23
30
|
interface BugBearProviderProps {
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,9 @@ var BugBearContext = (0, import_react.createContext)({
|
|
|
47
47
|
isLoading: true,
|
|
48
48
|
onNavigate: void 0,
|
|
49
49
|
refreshTesterStatus: async () => {
|
|
50
|
+
},
|
|
51
|
+
updateTesterProfile: async () => ({ success: false }),
|
|
52
|
+
refreshTesterInfo: async () => {
|
|
50
53
|
}
|
|
51
54
|
});
|
|
52
55
|
function useBugBear() {
|
|
@@ -91,6 +94,20 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
91
94
|
setClient(freshClient);
|
|
92
95
|
await initializeBugBear(freshClient);
|
|
93
96
|
}, [config, initializeBugBear]);
|
|
97
|
+
const updateTesterProfile = (0, import_react.useCallback)(async (updates) => {
|
|
98
|
+
if (!client) return { success: false, error: "Client not initialized" };
|
|
99
|
+
const result = await client.updateTesterProfile(updates);
|
|
100
|
+
if (result.success) {
|
|
101
|
+
const info = await client.getTesterInfo();
|
|
102
|
+
setTesterInfo(info);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}, [client]);
|
|
106
|
+
const refreshTesterInfo = (0, import_react.useCallback)(async () => {
|
|
107
|
+
if (!client) return;
|
|
108
|
+
const info = await client.getTesterInfo();
|
|
109
|
+
setTesterInfo(info);
|
|
110
|
+
}, [client]);
|
|
94
111
|
(0, import_react.useEffect)(() => {
|
|
95
112
|
if (enabled && !hasInitialized.current) {
|
|
96
113
|
hasInitialized.current = true;
|
|
@@ -117,7 +134,9 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
117
134
|
refreshAssignments,
|
|
118
135
|
isLoading,
|
|
119
136
|
onNavigate: config.onNavigate,
|
|
120
|
-
refreshTesterStatus
|
|
137
|
+
refreshTesterStatus,
|
|
138
|
+
updateTesterProfile,
|
|
139
|
+
refreshTesterInfo
|
|
121
140
|
},
|
|
122
141
|
children
|
|
123
142
|
}
|
|
@@ -196,7 +215,7 @@ function BugBearPanel({
|
|
|
196
215
|
defaultCollapsed = false,
|
|
197
216
|
draggable = true
|
|
198
217
|
}) {
|
|
199
|
-
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate } = useBugBear();
|
|
218
|
+
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate, updateTesterProfile, refreshTesterInfo } = useBugBear();
|
|
200
219
|
const [collapsed, setCollapsed] = (0, import_react2.useState)(defaultCollapsed);
|
|
201
220
|
const [activeTab, setActiveTab] = (0, import_react2.useState)("tests");
|
|
202
221
|
const [showSteps, setShowSteps] = (0, import_react2.useState)(false);
|
|
@@ -214,6 +233,14 @@ function BugBearPanel({
|
|
|
214
233
|
const [submitted, setSubmitted] = (0, import_react2.useState)(false);
|
|
215
234
|
const [justPassed, setJustPassed] = (0, import_react2.useState)(false);
|
|
216
235
|
const [criteriaResults, setCriteriaResults] = (0, import_react2.useState)({});
|
|
236
|
+
const [profileEditing, setProfileEditing] = (0, import_react2.useState)(false);
|
|
237
|
+
const [profileName, setProfileName] = (0, import_react2.useState)("");
|
|
238
|
+
const [profileAdditionalEmails, setProfileAdditionalEmails] = (0, import_react2.useState)([]);
|
|
239
|
+
const [newEmailInput, setNewEmailInput] = (0, import_react2.useState)("");
|
|
240
|
+
const [profilePlatforms, setProfilePlatforms] = (0, import_react2.useState)([]);
|
|
241
|
+
const [savingProfile, setSavingProfile] = (0, import_react2.useState)(false);
|
|
242
|
+
const [profileSaved, setProfileSaved] = (0, import_react2.useState)(false);
|
|
243
|
+
const [showProfileOverlay, setShowProfileOverlay] = (0, import_react2.useState)(false);
|
|
217
244
|
(0, import_react2.useEffect)(() => {
|
|
218
245
|
if (typeof window === "undefined") return;
|
|
219
246
|
try {
|
|
@@ -350,6 +377,67 @@ function BugBearPanel({
|
|
|
350
377
|
};
|
|
351
378
|
const pendingCount = assignments.filter((a) => a.status === "pending").length;
|
|
352
379
|
const inProgressCount = assignments.filter((a) => a.status === "in_progress").length;
|
|
380
|
+
const handleOpenProfile = () => {
|
|
381
|
+
if (testerInfo) {
|
|
382
|
+
setProfileName(testerInfo.name);
|
|
383
|
+
setProfileAdditionalEmails(testerInfo.additionalEmails || []);
|
|
384
|
+
setProfilePlatforms(testerInfo.platforms || []);
|
|
385
|
+
}
|
|
386
|
+
setProfileEditing(false);
|
|
387
|
+
setShowProfileOverlay(true);
|
|
388
|
+
};
|
|
389
|
+
const handleStartEditProfile = () => {
|
|
390
|
+
if (testerInfo) {
|
|
391
|
+
setProfileName(testerInfo.name);
|
|
392
|
+
setProfileAdditionalEmails(testerInfo.additionalEmails || []);
|
|
393
|
+
setProfilePlatforms(testerInfo.platforms || []);
|
|
394
|
+
}
|
|
395
|
+
setProfileEditing(true);
|
|
396
|
+
};
|
|
397
|
+
const handleCancelEditProfile = () => {
|
|
398
|
+
setProfileEditing(false);
|
|
399
|
+
setNewEmailInput("");
|
|
400
|
+
};
|
|
401
|
+
const handleCloseProfile = () => {
|
|
402
|
+
setShowProfileOverlay(false);
|
|
403
|
+
setProfileEditing(false);
|
|
404
|
+
setNewEmailInput("");
|
|
405
|
+
};
|
|
406
|
+
const handleAddEmail = () => {
|
|
407
|
+
const email = newEmailInput.trim().toLowerCase();
|
|
408
|
+
if (email && email.includes("@") && !profileAdditionalEmails.includes(email)) {
|
|
409
|
+
setProfileAdditionalEmails([...profileAdditionalEmails, email]);
|
|
410
|
+
setNewEmailInput("");
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
const handleRemoveEmail = (email) => {
|
|
414
|
+
setProfileAdditionalEmails(profileAdditionalEmails.filter((e) => e !== email));
|
|
415
|
+
};
|
|
416
|
+
const handleTogglePlatform = (platform) => {
|
|
417
|
+
if (profilePlatforms.includes(platform)) {
|
|
418
|
+
setProfilePlatforms(profilePlatforms.filter((p) => p !== platform));
|
|
419
|
+
} else {
|
|
420
|
+
setProfilePlatforms([...profilePlatforms, platform]);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
const handleSaveProfile = async () => {
|
|
424
|
+
setSavingProfile(true);
|
|
425
|
+
const updates = {
|
|
426
|
+
name: profileName.trim(),
|
|
427
|
+
additionalEmails: profileAdditionalEmails,
|
|
428
|
+
platforms: profilePlatforms
|
|
429
|
+
};
|
|
430
|
+
const result = await updateTesterProfile(updates);
|
|
431
|
+
if (result.success) {
|
|
432
|
+
setProfileEditing(false);
|
|
433
|
+
setProfileSaved(true);
|
|
434
|
+
setTimeout(() => {
|
|
435
|
+
setProfileSaved(false);
|
|
436
|
+
setShowProfileOverlay(false);
|
|
437
|
+
}, 1500);
|
|
438
|
+
}
|
|
439
|
+
setSavingProfile(false);
|
|
440
|
+
};
|
|
353
441
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
354
442
|
"div",
|
|
355
443
|
{
|
|
@@ -397,7 +485,17 @@ function BugBearPanel({
|
|
|
397
485
|
"BugBear",
|
|
398
486
|
draggable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-purple-300 text-xs", title: "Drag to move, double-click to reset", children: "\u22EE\u22EE" })
|
|
399
487
|
] }),
|
|
400
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
488
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
489
|
+
"button",
|
|
490
|
+
{
|
|
491
|
+
onClick: handleOpenProfile,
|
|
492
|
+
className: "text-purple-200 text-xs flex items-center gap-1 hover:text-white transition-colors",
|
|
493
|
+
children: [
|
|
494
|
+
testerInfo?.name,
|
|
495
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px]", children: "\u270E" })
|
|
496
|
+
]
|
|
497
|
+
}
|
|
498
|
+
)
|
|
401
499
|
] })
|
|
402
500
|
] }),
|
|
403
501
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -752,6 +850,165 @@ function BugBearPanel({
|
|
|
752
850
|
)
|
|
753
851
|
] }) })
|
|
754
852
|
] }),
|
|
853
|
+
showProfileOverlay && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "absolute inset-0 bg-white z-50 flex flex-col rounded-xl overflow-hidden", children: [
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bg-purple-600 text-white px-4 py-3 flex items-center justify-between", children: [
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
856
|
+
"button",
|
|
857
|
+
{
|
|
858
|
+
onClick: handleCloseProfile,
|
|
859
|
+
className: "text-sm text-purple-200 hover:text-white transition-colors",
|
|
860
|
+
children: "\u2190 Back"
|
|
861
|
+
}
|
|
862
|
+
),
|
|
863
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-semibold text-sm", children: "Profile" }),
|
|
864
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-12" }),
|
|
865
|
+
" "
|
|
866
|
+
] }),
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 overflow-y-auto p-4", children: profileSaved ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center py-8", children: [
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-4xl", children: "\u2705" }),
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-gray-600 mt-2 font-medium", children: "Profile saved!" })
|
|
870
|
+
] }) : profileEditing ? (
|
|
871
|
+
/* Edit Profile Form */
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
873
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
874
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "font-semibold text-gray-900", children: "Edit Profile" }),
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
876
|
+
"button",
|
|
877
|
+
{
|
|
878
|
+
onClick: handleCancelEditProfile,
|
|
879
|
+
className: "text-sm text-gray-500 hover:text-gray-700",
|
|
880
|
+
children: "Cancel"
|
|
881
|
+
}
|
|
882
|
+
)
|
|
883
|
+
] }),
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-4", children: [
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Name" }),
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
887
|
+
"input",
|
|
888
|
+
{
|
|
889
|
+
type: "text",
|
|
890
|
+
value: profileName,
|
|
891
|
+
onChange: (e) => setProfileName(e.target.value),
|
|
892
|
+
placeholder: "Your name",
|
|
893
|
+
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"
|
|
894
|
+
}
|
|
895
|
+
)
|
|
896
|
+
] }),
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-4", children: [
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Primary Email" }),
|
|
899
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-3 py-2 bg-gray-100 rounded-lg", children: [
|
|
900
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-gray-700", children: testerInfo?.email }),
|
|
901
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-gray-400 mt-0.5", children: "Main communication email" })
|
|
902
|
+
] })
|
|
903
|
+
] }),
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-4", children: [
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Additional Testing Emails" }),
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-gray-500 mb-2", children: "Add other emails you use to test on different accounts" }),
|
|
907
|
+
profileAdditionalEmails.map((email) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "flex-1 px-3 py-1.5 bg-purple-50 text-purple-700 text-sm rounded-full", children: email }),
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
910
|
+
"button",
|
|
911
|
+
{
|
|
912
|
+
onClick: () => handleRemoveEmail(email),
|
|
913
|
+
className: "text-purple-400 hover:text-red-500 text-sm",
|
|
914
|
+
children: "\u2715"
|
|
915
|
+
}
|
|
916
|
+
)
|
|
917
|
+
] }, email)),
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex gap-2", children: [
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
920
|
+
"input",
|
|
921
|
+
{
|
|
922
|
+
type: "email",
|
|
923
|
+
value: newEmailInput,
|
|
924
|
+
onChange: (e) => setNewEmailInput(e.target.value),
|
|
925
|
+
placeholder: "email@example.com",
|
|
926
|
+
className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500",
|
|
927
|
+
onKeyDown: (e) => e.key === "Enter" && handleAddEmail()
|
|
928
|
+
}
|
|
929
|
+
),
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
931
|
+
"button",
|
|
932
|
+
{
|
|
933
|
+
onClick: handleAddEmail,
|
|
934
|
+
disabled: !newEmailInput.trim(),
|
|
935
|
+
className: "px-3 py-2 bg-purple-600 text-white text-sm rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
936
|
+
children: "Add"
|
|
937
|
+
}
|
|
938
|
+
)
|
|
939
|
+
] })
|
|
940
|
+
] }),
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-4", children: [
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Testing Platforms" }),
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-gray-500 mb-2", children: "Select the platforms you can test on" }),
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex gap-2", children: [
|
|
945
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
946
|
+
{ key: "android", label: "\u{1F916} Android" },
|
|
947
|
+
{ key: "web", label: "\u{1F310} Web" }
|
|
948
|
+
].map(({ key, label }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
949
|
+
"button",
|
|
950
|
+
{
|
|
951
|
+
onClick: () => handleTogglePlatform(key),
|
|
952
|
+
className: `flex-1 py-2 px-3 rounded-lg text-sm font-medium transition-colors border-2 ${profilePlatforms.includes(key) ? "bg-purple-50 border-purple-500 text-purple-700" : "bg-gray-50 border-transparent text-gray-600 hover:bg-gray-100"}`,
|
|
953
|
+
children: label
|
|
954
|
+
},
|
|
955
|
+
key
|
|
956
|
+
)) })
|
|
957
|
+
] }),
|
|
958
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
959
|
+
"button",
|
|
960
|
+
{
|
|
961
|
+
onClick: handleSaveProfile,
|
|
962
|
+
disabled: savingProfile,
|
|
963
|
+
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",
|
|
964
|
+
children: savingProfile ? "Saving..." : "Save Profile"
|
|
965
|
+
}
|
|
966
|
+
)
|
|
967
|
+
] })
|
|
968
|
+
) : (
|
|
969
|
+
/* Profile View */
|
|
970
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bg-gray-50 rounded-lg p-4 text-center mb-4", children: [
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-16 h-16 mx-auto bg-purple-600 rounded-full flex items-center justify-center mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-2xl font-semibold text-white", children: testerInfo?.name?.charAt(0)?.toUpperCase() || "?" }) }),
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "font-semibold text-gray-900", children: testerInfo?.name }),
|
|
974
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-gray-500", children: testerInfo?.email }),
|
|
975
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-center gap-6 mt-4 pt-4 border-t border-gray-200", children: [
|
|
976
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center", children: [
|
|
977
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.assignedTests || 0 }),
|
|
978
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-gray-500", children: "Assigned" })
|
|
979
|
+
] }),
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "text-center", children: [
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.completedTests || 0 }),
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-gray-500", children: "Completed" })
|
|
983
|
+
] })
|
|
984
|
+
] })
|
|
985
|
+
] }),
|
|
986
|
+
(testerInfo?.additionalEmails?.length || 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bg-gray-50 rounded-lg p-3 mb-3", children: [
|
|
987
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-2", children: "Additional Emails" }),
|
|
988
|
+
testerInfo?.additionalEmails?.map((email) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-gray-700", children: email }, email))
|
|
989
|
+
] }),
|
|
990
|
+
(testerInfo?.platforms?.length || 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bg-gray-50 rounded-lg p-3 mb-3", children: [
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-2", children: "Testing Platforms" }),
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex flex-wrap gap-2", children: testerInfo?.platforms?.map((platform) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
993
|
+
"span",
|
|
994
|
+
{
|
|
995
|
+
className: "px-2 py-1 bg-purple-100 text-purple-700 text-xs rounded-full font-medium",
|
|
996
|
+
children: platform === "ios" ? "\u{1F4F1} iOS" : platform === "android" ? "\u{1F916} Android" : "\u{1F310} Web"
|
|
997
|
+
},
|
|
998
|
+
platform
|
|
999
|
+
)) })
|
|
1000
|
+
] }),
|
|
1001
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1002
|
+
"button",
|
|
1003
|
+
{
|
|
1004
|
+
onClick: handleStartEditProfile,
|
|
1005
|
+
className: "w-full py-2 px-4 bg-purple-600 text-white rounded-lg font-medium text-sm hover:bg-purple-700 transition-colors",
|
|
1006
|
+
children: "Edit Profile"
|
|
1007
|
+
}
|
|
1008
|
+
)
|
|
1009
|
+
] })
|
|
1010
|
+
) })
|
|
1011
|
+
] }),
|
|
755
1012
|
/* @__PURE__ */ (0, import_jsx_runtime2.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: [
|
|
756
1013
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
|
|
757
1014
|
pendingCount,
|
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,9 @@ var BugBearContext = createContext({
|
|
|
17
17
|
isLoading: true,
|
|
18
18
|
onNavigate: void 0,
|
|
19
19
|
refreshTesterStatus: async () => {
|
|
20
|
+
},
|
|
21
|
+
updateTesterProfile: async () => ({ success: false }),
|
|
22
|
+
refreshTesterInfo: async () => {
|
|
20
23
|
}
|
|
21
24
|
});
|
|
22
25
|
function useBugBear() {
|
|
@@ -61,6 +64,20 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
61
64
|
setClient(freshClient);
|
|
62
65
|
await initializeBugBear(freshClient);
|
|
63
66
|
}, [config, initializeBugBear]);
|
|
67
|
+
const updateTesterProfile = useCallback(async (updates) => {
|
|
68
|
+
if (!client) return { success: false, error: "Client not initialized" };
|
|
69
|
+
const result = await client.updateTesterProfile(updates);
|
|
70
|
+
if (result.success) {
|
|
71
|
+
const info = await client.getTesterInfo();
|
|
72
|
+
setTesterInfo(info);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}, [client]);
|
|
76
|
+
const refreshTesterInfo = useCallback(async () => {
|
|
77
|
+
if (!client) return;
|
|
78
|
+
const info = await client.getTesterInfo();
|
|
79
|
+
setTesterInfo(info);
|
|
80
|
+
}, [client]);
|
|
64
81
|
useEffect(() => {
|
|
65
82
|
if (enabled && !hasInitialized.current) {
|
|
66
83
|
hasInitialized.current = true;
|
|
@@ -87,7 +104,9 @@ function BugBearProvider({ config, children, enabled = true }) {
|
|
|
87
104
|
refreshAssignments,
|
|
88
105
|
isLoading,
|
|
89
106
|
onNavigate: config.onNavigate,
|
|
90
|
-
refreshTesterStatus
|
|
107
|
+
refreshTesterStatus,
|
|
108
|
+
updateTesterProfile,
|
|
109
|
+
refreshTesterInfo
|
|
91
110
|
},
|
|
92
111
|
children
|
|
93
112
|
}
|
|
@@ -166,7 +185,7 @@ function BugBearPanel({
|
|
|
166
185
|
defaultCollapsed = false,
|
|
167
186
|
draggable = true
|
|
168
187
|
}) {
|
|
169
|
-
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate } = useBugBear();
|
|
188
|
+
const { client, shouldShowWidget, testerInfo, assignments, currentAssignment, refreshAssignments, isLoading, onNavigate, updateTesterProfile, refreshTesterInfo } = useBugBear();
|
|
170
189
|
const [collapsed, setCollapsed] = useState2(defaultCollapsed);
|
|
171
190
|
const [activeTab, setActiveTab] = useState2("tests");
|
|
172
191
|
const [showSteps, setShowSteps] = useState2(false);
|
|
@@ -184,6 +203,14 @@ function BugBearPanel({
|
|
|
184
203
|
const [submitted, setSubmitted] = useState2(false);
|
|
185
204
|
const [justPassed, setJustPassed] = useState2(false);
|
|
186
205
|
const [criteriaResults, setCriteriaResults] = useState2({});
|
|
206
|
+
const [profileEditing, setProfileEditing] = useState2(false);
|
|
207
|
+
const [profileName, setProfileName] = useState2("");
|
|
208
|
+
const [profileAdditionalEmails, setProfileAdditionalEmails] = useState2([]);
|
|
209
|
+
const [newEmailInput, setNewEmailInput] = useState2("");
|
|
210
|
+
const [profilePlatforms, setProfilePlatforms] = useState2([]);
|
|
211
|
+
const [savingProfile, setSavingProfile] = useState2(false);
|
|
212
|
+
const [profileSaved, setProfileSaved] = useState2(false);
|
|
213
|
+
const [showProfileOverlay, setShowProfileOverlay] = useState2(false);
|
|
187
214
|
useEffect2(() => {
|
|
188
215
|
if (typeof window === "undefined") return;
|
|
189
216
|
try {
|
|
@@ -320,6 +347,67 @@ function BugBearPanel({
|
|
|
320
347
|
};
|
|
321
348
|
const pendingCount = assignments.filter((a) => a.status === "pending").length;
|
|
322
349
|
const inProgressCount = assignments.filter((a) => a.status === "in_progress").length;
|
|
350
|
+
const handleOpenProfile = () => {
|
|
351
|
+
if (testerInfo) {
|
|
352
|
+
setProfileName(testerInfo.name);
|
|
353
|
+
setProfileAdditionalEmails(testerInfo.additionalEmails || []);
|
|
354
|
+
setProfilePlatforms(testerInfo.platforms || []);
|
|
355
|
+
}
|
|
356
|
+
setProfileEditing(false);
|
|
357
|
+
setShowProfileOverlay(true);
|
|
358
|
+
};
|
|
359
|
+
const handleStartEditProfile = () => {
|
|
360
|
+
if (testerInfo) {
|
|
361
|
+
setProfileName(testerInfo.name);
|
|
362
|
+
setProfileAdditionalEmails(testerInfo.additionalEmails || []);
|
|
363
|
+
setProfilePlatforms(testerInfo.platforms || []);
|
|
364
|
+
}
|
|
365
|
+
setProfileEditing(true);
|
|
366
|
+
};
|
|
367
|
+
const handleCancelEditProfile = () => {
|
|
368
|
+
setProfileEditing(false);
|
|
369
|
+
setNewEmailInput("");
|
|
370
|
+
};
|
|
371
|
+
const handleCloseProfile = () => {
|
|
372
|
+
setShowProfileOverlay(false);
|
|
373
|
+
setProfileEditing(false);
|
|
374
|
+
setNewEmailInput("");
|
|
375
|
+
};
|
|
376
|
+
const handleAddEmail = () => {
|
|
377
|
+
const email = newEmailInput.trim().toLowerCase();
|
|
378
|
+
if (email && email.includes("@") && !profileAdditionalEmails.includes(email)) {
|
|
379
|
+
setProfileAdditionalEmails([...profileAdditionalEmails, email]);
|
|
380
|
+
setNewEmailInput("");
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
const handleRemoveEmail = (email) => {
|
|
384
|
+
setProfileAdditionalEmails(profileAdditionalEmails.filter((e) => e !== email));
|
|
385
|
+
};
|
|
386
|
+
const handleTogglePlatform = (platform) => {
|
|
387
|
+
if (profilePlatforms.includes(platform)) {
|
|
388
|
+
setProfilePlatforms(profilePlatforms.filter((p) => p !== platform));
|
|
389
|
+
} else {
|
|
390
|
+
setProfilePlatforms([...profilePlatforms, platform]);
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
const handleSaveProfile = async () => {
|
|
394
|
+
setSavingProfile(true);
|
|
395
|
+
const updates = {
|
|
396
|
+
name: profileName.trim(),
|
|
397
|
+
additionalEmails: profileAdditionalEmails,
|
|
398
|
+
platforms: profilePlatforms
|
|
399
|
+
};
|
|
400
|
+
const result = await updateTesterProfile(updates);
|
|
401
|
+
if (result.success) {
|
|
402
|
+
setProfileEditing(false);
|
|
403
|
+
setProfileSaved(true);
|
|
404
|
+
setTimeout(() => {
|
|
405
|
+
setProfileSaved(false);
|
|
406
|
+
setShowProfileOverlay(false);
|
|
407
|
+
}, 1500);
|
|
408
|
+
}
|
|
409
|
+
setSavingProfile(false);
|
|
410
|
+
};
|
|
323
411
|
return /* @__PURE__ */ jsxs(
|
|
324
412
|
"div",
|
|
325
413
|
{
|
|
@@ -367,7 +455,17 @@ function BugBearPanel({
|
|
|
367
455
|
"BugBear",
|
|
368
456
|
draggable && /* @__PURE__ */ jsx2("span", { className: "text-purple-300 text-xs", title: "Drag to move, double-click to reset", children: "\u22EE\u22EE" })
|
|
369
457
|
] }),
|
|
370
|
-
/* @__PURE__ */
|
|
458
|
+
/* @__PURE__ */ jsxs(
|
|
459
|
+
"button",
|
|
460
|
+
{
|
|
461
|
+
onClick: handleOpenProfile,
|
|
462
|
+
className: "text-purple-200 text-xs flex items-center gap-1 hover:text-white transition-colors",
|
|
463
|
+
children: [
|
|
464
|
+
testerInfo?.name,
|
|
465
|
+
/* @__PURE__ */ jsx2("span", { className: "text-[10px]", children: "\u270E" })
|
|
466
|
+
]
|
|
467
|
+
}
|
|
468
|
+
)
|
|
371
469
|
] })
|
|
372
470
|
] }),
|
|
373
471
|
/* @__PURE__ */ jsx2(
|
|
@@ -722,6 +820,165 @@ function BugBearPanel({
|
|
|
722
820
|
)
|
|
723
821
|
] }) })
|
|
724
822
|
] }),
|
|
823
|
+
showProfileOverlay && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-white z-50 flex flex-col rounded-xl overflow-hidden", children: [
|
|
824
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-purple-600 text-white px-4 py-3 flex items-center justify-between", children: [
|
|
825
|
+
/* @__PURE__ */ jsx2(
|
|
826
|
+
"button",
|
|
827
|
+
{
|
|
828
|
+
onClick: handleCloseProfile,
|
|
829
|
+
className: "text-sm text-purple-200 hover:text-white transition-colors",
|
|
830
|
+
children: "\u2190 Back"
|
|
831
|
+
}
|
|
832
|
+
),
|
|
833
|
+
/* @__PURE__ */ jsx2("span", { className: "font-semibold text-sm", children: "Profile" }),
|
|
834
|
+
/* @__PURE__ */ jsx2("div", { className: "w-12" }),
|
|
835
|
+
" "
|
|
836
|
+
] }),
|
|
837
|
+
/* @__PURE__ */ jsx2("div", { className: "flex-1 overflow-y-auto p-4", children: profileSaved ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
|
|
838
|
+
/* @__PURE__ */ jsx2("span", { className: "text-4xl", children: "\u2705" }),
|
|
839
|
+
/* @__PURE__ */ jsx2("p", { className: "text-gray-600 mt-2 font-medium", children: "Profile saved!" })
|
|
840
|
+
] }) : profileEditing ? (
|
|
841
|
+
/* Edit Profile Form */
|
|
842
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
843
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
844
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-gray-900", children: "Edit Profile" }),
|
|
845
|
+
/* @__PURE__ */ jsx2(
|
|
846
|
+
"button",
|
|
847
|
+
{
|
|
848
|
+
onClick: handleCancelEditProfile,
|
|
849
|
+
className: "text-sm text-gray-500 hover:text-gray-700",
|
|
850
|
+
children: "Cancel"
|
|
851
|
+
}
|
|
852
|
+
)
|
|
853
|
+
] }),
|
|
854
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
855
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Name" }),
|
|
856
|
+
/* @__PURE__ */ jsx2(
|
|
857
|
+
"input",
|
|
858
|
+
{
|
|
859
|
+
type: "text",
|
|
860
|
+
value: profileName,
|
|
861
|
+
onChange: (e) => setProfileName(e.target.value),
|
|
862
|
+
placeholder: "Your name",
|
|
863
|
+
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"
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
] }),
|
|
867
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
868
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Primary Email" }),
|
|
869
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 py-2 bg-gray-100 rounded-lg", children: [
|
|
870
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-700", children: testerInfo?.email }),
|
|
871
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-400 mt-0.5", children: "Main communication email" })
|
|
872
|
+
] })
|
|
873
|
+
] }),
|
|
874
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
875
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Additional Testing Emails" }),
|
|
876
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 mb-2", children: "Add other emails you use to test on different accounts" }),
|
|
877
|
+
profileAdditionalEmails.map((email) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
878
|
+
/* @__PURE__ */ jsx2("span", { className: "flex-1 px-3 py-1.5 bg-purple-50 text-purple-700 text-sm rounded-full", children: email }),
|
|
879
|
+
/* @__PURE__ */ jsx2(
|
|
880
|
+
"button",
|
|
881
|
+
{
|
|
882
|
+
onClick: () => handleRemoveEmail(email),
|
|
883
|
+
className: "text-purple-400 hover:text-red-500 text-sm",
|
|
884
|
+
children: "\u2715"
|
|
885
|
+
}
|
|
886
|
+
)
|
|
887
|
+
] }, email)),
|
|
888
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
889
|
+
/* @__PURE__ */ jsx2(
|
|
890
|
+
"input",
|
|
891
|
+
{
|
|
892
|
+
type: "email",
|
|
893
|
+
value: newEmailInput,
|
|
894
|
+
onChange: (e) => setNewEmailInput(e.target.value),
|
|
895
|
+
placeholder: "email@example.com",
|
|
896
|
+
className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500",
|
|
897
|
+
onKeyDown: (e) => e.key === "Enter" && handleAddEmail()
|
|
898
|
+
}
|
|
899
|
+
),
|
|
900
|
+
/* @__PURE__ */ jsx2(
|
|
901
|
+
"button",
|
|
902
|
+
{
|
|
903
|
+
onClick: handleAddEmail,
|
|
904
|
+
disabled: !newEmailInput.trim(),
|
|
905
|
+
className: "px-3 py-2 bg-purple-600 text-white text-sm rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
906
|
+
children: "Add"
|
|
907
|
+
}
|
|
908
|
+
)
|
|
909
|
+
] })
|
|
910
|
+
] }),
|
|
911
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
912
|
+
/* @__PURE__ */ jsx2("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Testing Platforms" }),
|
|
913
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 mb-2", children: "Select the platforms you can test on" }),
|
|
914
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: [
|
|
915
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
916
|
+
{ key: "android", label: "\u{1F916} Android" },
|
|
917
|
+
{ key: "web", label: "\u{1F310} Web" }
|
|
918
|
+
].map(({ key, label }) => /* @__PURE__ */ jsx2(
|
|
919
|
+
"button",
|
|
920
|
+
{
|
|
921
|
+
onClick: () => handleTogglePlatform(key),
|
|
922
|
+
className: `flex-1 py-2 px-3 rounded-lg text-sm font-medium transition-colors border-2 ${profilePlatforms.includes(key) ? "bg-purple-50 border-purple-500 text-purple-700" : "bg-gray-50 border-transparent text-gray-600 hover:bg-gray-100"}`,
|
|
923
|
+
children: label
|
|
924
|
+
},
|
|
925
|
+
key
|
|
926
|
+
)) })
|
|
927
|
+
] }),
|
|
928
|
+
/* @__PURE__ */ jsx2(
|
|
929
|
+
"button",
|
|
930
|
+
{
|
|
931
|
+
onClick: handleSaveProfile,
|
|
932
|
+
disabled: savingProfile,
|
|
933
|
+
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",
|
|
934
|
+
children: savingProfile ? "Saving..." : "Save Profile"
|
|
935
|
+
}
|
|
936
|
+
)
|
|
937
|
+
] })
|
|
938
|
+
) : (
|
|
939
|
+
/* Profile View */
|
|
940
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
941
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-gray-50 rounded-lg p-4 text-center mb-4", children: [
|
|
942
|
+
/* @__PURE__ */ jsx2("div", { className: "w-16 h-16 mx-auto bg-purple-600 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() || "?" }) }),
|
|
943
|
+
/* @__PURE__ */ jsx2("h3", { className: "font-semibold text-gray-900", children: testerInfo?.name }),
|
|
944
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-500", children: testerInfo?.email }),
|
|
945
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-6 mt-4 pt-4 border-t border-gray-200", children: [
|
|
946
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
947
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.assignedTests || 0 }),
|
|
948
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500", children: "Assigned" })
|
|
949
|
+
] }),
|
|
950
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
951
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-purple-600", children: testerInfo?.completedTests || 0 }),
|
|
952
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500", children: "Completed" })
|
|
953
|
+
] })
|
|
954
|
+
] })
|
|
955
|
+
] }),
|
|
956
|
+
(testerInfo?.additionalEmails?.length || 0) > 0 && /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 rounded-lg p-3 mb-3", children: [
|
|
957
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-2", children: "Additional Emails" }),
|
|
958
|
+
testerInfo?.additionalEmails?.map((email) => /* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-700", children: email }, email))
|
|
959
|
+
] }),
|
|
960
|
+
(testerInfo?.platforms?.length || 0) > 0 && /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 rounded-lg p-3 mb-3", children: [
|
|
961
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-2", children: "Testing Platforms" }),
|
|
962
|
+
/* @__PURE__ */ jsx2("div", { className: "flex flex-wrap gap-2", children: testerInfo?.platforms?.map((platform) => /* @__PURE__ */ jsx2(
|
|
963
|
+
"span",
|
|
964
|
+
{
|
|
965
|
+
className: "px-2 py-1 bg-purple-100 text-purple-700 text-xs rounded-full font-medium",
|
|
966
|
+
children: platform === "ios" ? "\u{1F4F1} iOS" : platform === "android" ? "\u{1F916} Android" : "\u{1F310} Web"
|
|
967
|
+
},
|
|
968
|
+
platform
|
|
969
|
+
)) })
|
|
970
|
+
] }),
|
|
971
|
+
/* @__PURE__ */ jsx2(
|
|
972
|
+
"button",
|
|
973
|
+
{
|
|
974
|
+
onClick: handleStartEditProfile,
|
|
975
|
+
className: "w-full py-2 px-4 bg-purple-600 text-white rounded-lg font-medium text-sm hover:bg-purple-700 transition-colors",
|
|
976
|
+
children: "Edit Profile"
|
|
977
|
+
}
|
|
978
|
+
)
|
|
979
|
+
] })
|
|
980
|
+
) })
|
|
981
|
+
] }),
|
|
725
982
|
/* @__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: [
|
|
726
983
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
727
984
|
pendingCount,
|