@bbearai/react-native 0.1.6 → 0.1.8

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, DeviceInfo, TesterThread, TesterMessage, AppContext } from '@bbearai/core';
2
+ import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, DeviceInfo, TesterThread, TesterMessage, TesterProfileUpdate, AppContext } from '@bbearai/core';
3
3
  export { AppContext, BugBearConfig, BugBearReport, DeviceInfo, MessageSenderType, ReportType, Severity, TestAssignment, TesterInfo, TesterMessage, TesterThread, ThreadPriority, ThreadType } from '@bbearai/core';
4
4
 
5
5
  interface BugBearContextValue {
@@ -38,6 +38,13 @@ interface BugBearContextValue {
38
38
  }>;
39
39
  /** Re-check tester status (call after auth state changes) */
40
40
  refreshTesterStatus: () => Promise<void>;
41
+ /** Update tester profile */
42
+ updateTesterProfile: (updates: TesterProfileUpdate) => Promise<{
43
+ success: boolean;
44
+ error?: string;
45
+ }>;
46
+ /** Refresh tester info from server */
47
+ refreshTesterInfo: () => Promise<void>;
41
48
  }
42
49
  declare function useBugBear(): BugBearContextValue;
43
50
  interface BugBearProviderProps {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, DeviceInfo, TesterThread, TesterMessage, AppContext } from '@bbearai/core';
2
+ import { BugBearConfig, BugBearClient, TesterInfo, TestAssignment, DeviceInfo, TesterThread, TesterMessage, TesterProfileUpdate, AppContext } from '@bbearai/core';
3
3
  export { AppContext, BugBearConfig, BugBearReport, DeviceInfo, MessageSenderType, ReportType, Severity, TestAssignment, TesterInfo, TesterMessage, TesterThread, ThreadPriority, ThreadType } from '@bbearai/core';
4
4
 
5
5
  interface BugBearContextValue {
@@ -38,6 +38,13 @@ interface BugBearContextValue {
38
38
  }>;
39
39
  /** Re-check tester status (call after auth state changes) */
40
40
  refreshTesterStatus: () => Promise<void>;
41
+ /** Update tester profile */
42
+ updateTesterProfile: (updates: TesterProfileUpdate) => Promise<{
43
+ success: boolean;
44
+ error?: string;
45
+ }>;
46
+ /** Refresh tester info from server */
47
+ refreshTesterInfo: () => Promise<void>;
41
48
  }
42
49
  declare function useBugBear(): BugBearContextValue;
43
50
  interface BugBearProviderProps {
package/dist/index.js CHANGED
@@ -11566,6 +11566,9 @@ var BugBearClient = class {
11566
11566
  id: data.id,
11567
11567
  name: data.name,
11568
11568
  email: data.email,
11569
+ additionalEmails: data.additional_emails || [],
11570
+ avatarUrl: data.avatar_url || void 0,
11571
+ platforms: data.platforms || [],
11569
11572
  assignedTests: data.assigned_count || 0,
11570
11573
  completedTests: data.completed_count || 0
11571
11574
  };
@@ -11574,6 +11577,32 @@ var BugBearClient = class {
11574
11577
  return null;
11575
11578
  }
11576
11579
  }
11580
+ /**
11581
+ * Update tester profile
11582
+ * Allows testers to update their name, additional emails, avatar, and platforms
11583
+ */
11584
+ async updateTesterProfile(updates) {
11585
+ try {
11586
+ const userInfo = await this.getCurrentUserInfo();
11587
+ if (!userInfo) {
11588
+ return { success: false, error: "Not authenticated" };
11589
+ }
11590
+ const updateData = {};
11591
+ if (updates.name !== void 0) updateData.name = updates.name;
11592
+ if (updates.additionalEmails !== void 0) updateData.additional_emails = updates.additionalEmails;
11593
+ if (updates.avatarUrl !== void 0) updateData.avatar_url = updates.avatarUrl;
11594
+ if (updates.platforms !== void 0) updateData.platforms = updates.platforms;
11595
+ const { error } = await this.supabase.from("testers").update(updateData).eq("project_id", this.config.projectId).eq("email", userInfo.email);
11596
+ if (error) {
11597
+ console.error("BugBear: updateTesterProfile error", error);
11598
+ return { success: false, error: error.message };
11599
+ }
11600
+ return { success: true };
11601
+ } catch (err) {
11602
+ console.error("BugBear: updateTesterProfile error", err);
11603
+ return { success: false, error: "Failed to update profile" };
11604
+ }
11605
+ }
11577
11606
  /**
11578
11607
  * Check if current user is a tester for this project
11579
11608
  */
@@ -12120,6 +12149,9 @@ var BugBearContext = (0, import_react.createContext)({
12120
12149
  },
12121
12150
  createThread: async () => ({ success: false }),
12122
12151
  refreshTesterStatus: async () => {
12152
+ },
12153
+ updateTesterProfile: async () => ({ success: false }),
12154
+ refreshTesterInfo: async () => {
12123
12155
  }
12124
12156
  });
12125
12157
  function useBugBear() {
@@ -12181,6 +12213,20 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
12181
12213
  }
12182
12214
  return result;
12183
12215
  }, [client, refreshThreads]);
12216
+ const updateTesterProfile = (0, import_react.useCallback)(async (updates) => {
12217
+ if (!client) return { success: false, error: "Client not initialized" };
12218
+ const result = await client.updateTesterProfile(updates);
12219
+ if (result.success) {
12220
+ const info = await client.getTesterInfo();
12221
+ setTesterInfo(info);
12222
+ }
12223
+ return result;
12224
+ }, [client]);
12225
+ const refreshTesterInfo = (0, import_react.useCallback)(async () => {
12226
+ if (!client) return;
12227
+ const info = await client.getTesterInfo();
12228
+ setTesterInfo(info);
12229
+ }, [client]);
12184
12230
  const initializeBugBear = (0, import_react.useCallback)(async (bugBearClient) => {
12185
12231
  setIsLoading(true);
12186
12232
  try {
@@ -12247,7 +12293,9 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
12247
12293
  sendMessage,
12248
12294
  markAsRead,
12249
12295
  createThread,
12250
- refreshTesterStatus
12296
+ refreshTesterStatus,
12297
+ updateTesterProfile,
12298
+ refreshTesterInfo
12251
12299
  }
12252
12300
  },
12253
12301
  children
@@ -12290,11 +12338,14 @@ function BugBearButton({
12290
12338
  getThreadMessages,
12291
12339
  sendMessage,
12292
12340
  markAsRead,
12293
- createThread
12341
+ createThread,
12342
+ updateTesterProfile,
12343
+ refreshTesterInfo
12294
12344
  } = useBugBear();
12295
12345
  const [modalVisible, setModalVisible] = (0, import_react2.useState)(false);
12296
12346
  const [activeTab, setActiveTab] = (0, import_react2.useState)("tests");
12297
12347
  const [showSteps, setShowSteps] = (0, import_react2.useState)(false);
12348
+ const [showProfileOverlay, setShowProfileOverlay] = (0, import_react2.useState)(false);
12298
12349
  const [messageView, setMessageView] = (0, import_react2.useState)("list");
12299
12350
  const [selectedThread, setSelectedThread] = (0, import_react2.useState)(null);
12300
12351
  const [threadMessages, setThreadMessages] = (0, import_react2.useState)([]);
@@ -12304,6 +12355,13 @@ function BugBearButton({
12304
12355
  const [composeSubject, setComposeSubject] = (0, import_react2.useState)("");
12305
12356
  const [composeMessage, setComposeMessage] = (0, import_react2.useState)("");
12306
12357
  const [sendingNewMessage, setSendingNewMessage] = (0, import_react2.useState)(false);
12358
+ const [profileEditing, setProfileEditing] = (0, import_react2.useState)(false);
12359
+ const [profileName, setProfileName] = (0, import_react2.useState)("");
12360
+ const [profileAdditionalEmails, setProfileAdditionalEmails] = (0, import_react2.useState)([]);
12361
+ const [newEmailInput, setNewEmailInput] = (0, import_react2.useState)("");
12362
+ const [profilePlatforms, setProfilePlatforms] = (0, import_react2.useState)([]);
12363
+ const [savingProfile, setSavingProfile] = (0, import_react2.useState)(false);
12364
+ const [profileSaved, setProfileSaved] = (0, import_react2.useState)(false);
12307
12365
  const getInitialPosition = () => {
12308
12366
  const buttonSize = 56;
12309
12367
  const margin = 16;
@@ -12488,6 +12546,67 @@ function BugBearButton({
12488
12546
  }
12489
12547
  setSendingNewMessage(false);
12490
12548
  };
12549
+ const handleOpenProfile = () => {
12550
+ if (testerInfo) {
12551
+ setProfileName(testerInfo.name);
12552
+ setProfileAdditionalEmails(testerInfo.additionalEmails || []);
12553
+ setProfilePlatforms(testerInfo.platforms || []);
12554
+ }
12555
+ setProfileEditing(false);
12556
+ setShowProfileOverlay(true);
12557
+ };
12558
+ const handleStartEditProfile = () => {
12559
+ if (testerInfo) {
12560
+ setProfileName(testerInfo.name);
12561
+ setProfileAdditionalEmails(testerInfo.additionalEmails || []);
12562
+ setProfilePlatforms(testerInfo.platforms || []);
12563
+ }
12564
+ setProfileEditing(true);
12565
+ };
12566
+ const handleCancelEditProfile = () => {
12567
+ setProfileEditing(false);
12568
+ setNewEmailInput("");
12569
+ };
12570
+ const handleCloseProfile = () => {
12571
+ setShowProfileOverlay(false);
12572
+ setProfileEditing(false);
12573
+ setNewEmailInput("");
12574
+ };
12575
+ const handleAddEmail = () => {
12576
+ const email = newEmailInput.trim().toLowerCase();
12577
+ if (email && email.includes("@") && !profileAdditionalEmails.includes(email)) {
12578
+ setProfileAdditionalEmails([...profileAdditionalEmails, email]);
12579
+ setNewEmailInput("");
12580
+ }
12581
+ };
12582
+ const handleRemoveEmail = (email) => {
12583
+ setProfileAdditionalEmails(profileAdditionalEmails.filter((e) => e !== email));
12584
+ };
12585
+ const handleTogglePlatform = (platform) => {
12586
+ if (profilePlatforms.includes(platform)) {
12587
+ setProfilePlatforms(profilePlatforms.filter((p) => p !== platform));
12588
+ } else {
12589
+ setProfilePlatforms([...profilePlatforms, platform]);
12590
+ }
12591
+ };
12592
+ const handleSaveProfile = async () => {
12593
+ setSavingProfile(true);
12594
+ const updates = {
12595
+ name: profileName.trim(),
12596
+ additionalEmails: profileAdditionalEmails,
12597
+ platforms: profilePlatforms
12598
+ };
12599
+ const result = await updateTesterProfile(updates);
12600
+ if (result.success) {
12601
+ setProfileEditing(false);
12602
+ setProfileSaved(true);
12603
+ setTimeout(() => {
12604
+ setProfileSaved(false);
12605
+ setShowProfileOverlay(false);
12606
+ }, 1500);
12607
+ }
12608
+ setSavingProfile(false);
12609
+ };
12491
12610
  const formatRelativeTime = (dateString) => {
12492
12611
  const date = new Date(dateString);
12493
12612
  const now = /* @__PURE__ */ new Date();
@@ -12650,7 +12769,7 @@ function BugBearButton({
12650
12769
  behavior: import_react_native2.Platform.OS === "ios" ? "padding" : "height",
12651
12770
  style: styles.modalContainer
12652
12771
  },
12653
- /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.modalContent }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.header }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.headerLeft }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerEmoji }, "\u{1F43B}"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerTitle }, "BugBear"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerSubtitle }, testerInfo?.name))), /* @__PURE__ */ import_react2.default.createElement(
12772
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.modalContent }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.header }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.headerLeft }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerEmoji }, "\u{1F43B}"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerTitle }, "BugBear"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: handleOpenProfile, style: styles.headerNameButton }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerSubtitle }, testerInfo?.name), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.headerPencil }, "\u270E")))), /* @__PURE__ */ import_react2.default.createElement(
12654
12773
  import_react_native2.TouchableOpacity,
12655
12774
  {
12656
12775
  onPress: () => setModalVisible(false),
@@ -12885,7 +13004,81 @@ function BugBearButton({
12885
13004
  disabled: !description.trim() || submitting
12886
13005
  },
12887
13006
  /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.submitButtonText }, submitting ? "Submitting..." : "Submit Report")
12888
- )))), activeTab === "messages" && messageView === "thread" && selectedThread ? (
13007
+ )))), showProfileOverlay && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileOverlay }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.ScrollView, { style: styles.profileOverlayContent }, profileSaved ? /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyEmoji }, "\u2705"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyTitle }, "Profile saved!")) : profileEditing ? (
13008
+ /* Edit Profile Form */
13009
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileEditHeader }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileEditTitle }, "Edit Profile"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: handleCancelEditProfile }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.cancelText }, "Cancel"))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.label }, "Name"), /* @__PURE__ */ import_react2.default.createElement(
13010
+ import_react_native2.TextInput,
13011
+ {
13012
+ style: styles.profileInput,
13013
+ value: profileName,
13014
+ onChangeText: setProfileName,
13015
+ placeholder: "Your name",
13016
+ placeholderTextColor: "#9CA3AF"
13017
+ }
13018
+ )), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.label }, "Primary Email"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileReadOnly }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileReadOnlyText }, testerInfo?.email), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileReadOnlyHint }, "Main communication email"))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.label }, "Additional Testing Emails"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileHint }, "Add other emails you use to test on different accounts"), profileAdditionalEmails.map((email) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { key: email, style: styles.emailChip }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emailChipText }, email), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: () => handleRemoveEmail(email) }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emailChipRemove }, "\u2715")))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.addEmailRow }, /* @__PURE__ */ import_react2.default.createElement(
13019
+ import_react_native2.TextInput,
13020
+ {
13021
+ style: styles.addEmailInput,
13022
+ value: newEmailInput,
13023
+ onChangeText: setNewEmailInput,
13024
+ placeholder: "email@example.com",
13025
+ placeholderTextColor: "#9CA3AF",
13026
+ keyboardType: "email-address",
13027
+ autoCapitalize: "none"
13028
+ }
13029
+ ), /* @__PURE__ */ import_react2.default.createElement(
13030
+ import_react_native2.TouchableOpacity,
13031
+ {
13032
+ style: [styles.addEmailButton, !newEmailInput.trim() && styles.addEmailButtonDisabled],
13033
+ onPress: handleAddEmail,
13034
+ disabled: !newEmailInput.trim()
13035
+ },
13036
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.addEmailButtonText }, "Add")
13037
+ ))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.label }, "Testing Platforms"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileHint }, "Select the platforms you can test on"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.platformButtons }, [
13038
+ { key: "ios", label: "\u{1F4F1} iOS" },
13039
+ { key: "android", label: "\u{1F916} Android" },
13040
+ { key: "web", label: "\u{1F310} Web" }
13041
+ ].map(({ key, label }) => /* @__PURE__ */ import_react2.default.createElement(
13042
+ import_react_native2.TouchableOpacity,
13043
+ {
13044
+ key,
13045
+ style: [
13046
+ styles.platformButton,
13047
+ profilePlatforms.includes(key) && styles.platformButtonActive
13048
+ ],
13049
+ onPress: () => handleTogglePlatform(key)
13050
+ },
13051
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
13052
+ styles.platformButtonText,
13053
+ profilePlatforms.includes(key) && styles.platformButtonTextActive
13054
+ ] }, label)
13055
+ )))), /* @__PURE__ */ import_react2.default.createElement(
13056
+ import_react_native2.TouchableOpacity,
13057
+ {
13058
+ style: [styles.saveProfileButton, savingProfile && styles.saveProfileButtonDisabled],
13059
+ onPress: handleSaveProfile,
13060
+ disabled: savingProfile
13061
+ },
13062
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.saveProfileButtonText }, savingProfile ? "Saving..." : "Save Profile")
13063
+ ))
13064
+ ) : (
13065
+ /* Profile View */
13066
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileCard }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.avatarCircle }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.avatarText }, testerInfo?.name?.charAt(0)?.toUpperCase() || "?")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileName }, testerInfo?.name), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileEmail }, testerInfo?.email), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileStats }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileStat }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileStatValue }, testerInfo?.assignedTests || 0), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileStatLabel }, "Assigned")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileStatDivider }), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileStat }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileStatValue }, testerInfo?.completedTests || 0), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileStatLabel }, "Completed")))), (testerInfo?.additionalEmails?.length || 0) > 0 && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileInfoSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileInfoLabel }, "Additional Emails"), testerInfo?.additionalEmails?.map((email) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { key: email, style: styles.profileInfoValue }, email))), (testerInfo?.platforms?.length || 0) > 0 && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileInfoSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.profileInfoLabel }, "Testing Platforms"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.platformTags }, testerInfo?.platforms?.map((platform) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { key: platform, style: styles.platformTag }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.platformTagText }, platform === "ios" ? "\u{1F4F1} iOS" : platform === "android" ? "\u{1F916} Android" : "\u{1F310} Web"))))), /* @__PURE__ */ import_react2.default.createElement(
13067
+ import_react_native2.TouchableOpacity,
13068
+ {
13069
+ style: styles.editProfileButton,
13070
+ onPress: handleStartEditProfile
13071
+ },
13072
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.editProfileButtonText }, "Edit Profile")
13073
+ ))
13074
+ )), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.profileOverlayFooter }, /* @__PURE__ */ import_react2.default.createElement(
13075
+ import_react_native2.TouchableOpacity,
13076
+ {
13077
+ style: styles.closeProfileButton,
13078
+ onPress: handleCloseProfile
13079
+ },
13080
+ /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.closeProfileButtonText }, "\u2190 Back")
13081
+ ))), activeTab === "messages" && messageView === "thread" && selectedThread ? (
12889
13082
  /* Reply Composer */
12890
13083
  /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.replyComposer }, /* @__PURE__ */ import_react2.default.createElement(
12891
13084
  import_react_native2.TextInput,
@@ -12997,6 +13190,15 @@ var styles = import_react_native2.StyleSheet.create({
12997
13190
  color: "#DDD6FE",
12998
13191
  fontSize: 12
12999
13192
  },
13193
+ headerNameButton: {
13194
+ flexDirection: "row",
13195
+ alignItems: "center",
13196
+ gap: 4
13197
+ },
13198
+ headerPencil: {
13199
+ color: "#DDD6FE",
13200
+ fontSize: 11
13201
+ },
13000
13202
  closeButton: {
13001
13203
  padding: 8
13002
13204
  },
@@ -13882,6 +14084,275 @@ var styles = import_react_native2.StyleSheet.create({
13882
14084
  fontSize: 16,
13883
14085
  fontWeight: "600",
13884
14086
  color: "#fff"
14087
+ },
14088
+ // Profile styles
14089
+ profileCard: {
14090
+ backgroundColor: "#F9FAFB",
14091
+ borderRadius: 16,
14092
+ padding: 24,
14093
+ alignItems: "center",
14094
+ marginBottom: 16
14095
+ },
14096
+ avatarCircle: {
14097
+ width: 72,
14098
+ height: 72,
14099
+ borderRadius: 36,
14100
+ backgroundColor: "#7C3AED",
14101
+ justifyContent: "center",
14102
+ alignItems: "center",
14103
+ marginBottom: 12
14104
+ },
14105
+ avatarText: {
14106
+ fontSize: 28,
14107
+ fontWeight: "600",
14108
+ color: "#fff"
14109
+ },
14110
+ profileName: {
14111
+ fontSize: 20,
14112
+ fontWeight: "600",
14113
+ color: "#111827",
14114
+ marginBottom: 4
14115
+ },
14116
+ profileEmail: {
14117
+ fontSize: 14,
14118
+ color: "#6B7280",
14119
+ marginBottom: 16
14120
+ },
14121
+ profileStats: {
14122
+ flexDirection: "row",
14123
+ alignItems: "center"
14124
+ },
14125
+ profileStat: {
14126
+ alignItems: "center",
14127
+ paddingHorizontal: 20
14128
+ },
14129
+ profileStatValue: {
14130
+ fontSize: 24,
14131
+ fontWeight: "700",
14132
+ color: "#7C3AED"
14133
+ },
14134
+ profileStatLabel: {
14135
+ fontSize: 12,
14136
+ color: "#6B7280",
14137
+ marginTop: 2
14138
+ },
14139
+ profileStatDivider: {
14140
+ width: 1,
14141
+ height: 32,
14142
+ backgroundColor: "#E5E7EB"
14143
+ },
14144
+ profileInfoSection: {
14145
+ backgroundColor: "#F9FAFB",
14146
+ borderRadius: 12,
14147
+ padding: 16,
14148
+ marginBottom: 12
14149
+ },
14150
+ profileInfoLabel: {
14151
+ fontSize: 12,
14152
+ fontWeight: "600",
14153
+ color: "#6B7280",
14154
+ marginBottom: 8,
14155
+ textTransform: "uppercase",
14156
+ letterSpacing: 0.5
14157
+ },
14158
+ profileInfoValue: {
14159
+ fontSize: 14,
14160
+ color: "#374151",
14161
+ marginBottom: 4
14162
+ },
14163
+ platformTags: {
14164
+ flexDirection: "row",
14165
+ flexWrap: "wrap",
14166
+ gap: 8
14167
+ },
14168
+ platformTag: {
14169
+ backgroundColor: "#EDE9FE",
14170
+ paddingHorizontal: 12,
14171
+ paddingVertical: 6,
14172
+ borderRadius: 16
14173
+ },
14174
+ platformTagText: {
14175
+ fontSize: 13,
14176
+ color: "#7C3AED",
14177
+ fontWeight: "500"
14178
+ },
14179
+ editProfileButton: {
14180
+ backgroundColor: "#7C3AED",
14181
+ paddingVertical: 14,
14182
+ borderRadius: 12,
14183
+ alignItems: "center",
14184
+ marginTop: 8
14185
+ },
14186
+ editProfileButtonText: {
14187
+ fontSize: 16,
14188
+ fontWeight: "600",
14189
+ color: "#fff"
14190
+ },
14191
+ // Profile edit styles
14192
+ profileEditHeader: {
14193
+ flexDirection: "row",
14194
+ justifyContent: "space-between",
14195
+ alignItems: "center",
14196
+ marginBottom: 20
14197
+ },
14198
+ profileEditTitle: {
14199
+ fontSize: 20,
14200
+ fontWeight: "600",
14201
+ color: "#111827"
14202
+ },
14203
+ cancelText: {
14204
+ fontSize: 14,
14205
+ color: "#6B7280"
14206
+ },
14207
+ profileSection: {
14208
+ marginBottom: 20
14209
+ },
14210
+ profileInput: {
14211
+ backgroundColor: "#F9FAFB",
14212
+ borderWidth: 1,
14213
+ borderColor: "#E5E7EB",
14214
+ borderRadius: 10,
14215
+ paddingHorizontal: 14,
14216
+ paddingVertical: 12,
14217
+ fontSize: 15,
14218
+ color: "#111827"
14219
+ },
14220
+ profileReadOnly: {
14221
+ backgroundColor: "#F3F4F6",
14222
+ borderRadius: 10,
14223
+ padding: 14
14224
+ },
14225
+ profileReadOnlyText: {
14226
+ fontSize: 15,
14227
+ color: "#374151"
14228
+ },
14229
+ profileReadOnlyHint: {
14230
+ fontSize: 12,
14231
+ color: "#9CA3AF",
14232
+ marginTop: 4
14233
+ },
14234
+ profileHint: {
14235
+ fontSize: 13,
14236
+ color: "#6B7280",
14237
+ marginBottom: 12
14238
+ },
14239
+ emailChip: {
14240
+ flexDirection: "row",
14241
+ alignItems: "center",
14242
+ backgroundColor: "#EDE9FE",
14243
+ paddingHorizontal: 12,
14244
+ paddingVertical: 8,
14245
+ borderRadius: 20,
14246
+ marginBottom: 8
14247
+ },
14248
+ emailChipText: {
14249
+ flex: 1,
14250
+ fontSize: 14,
14251
+ color: "#5B21B6"
14252
+ },
14253
+ emailChipRemove: {
14254
+ fontSize: 14,
14255
+ color: "#8B5CF6",
14256
+ fontWeight: "600",
14257
+ marginLeft: 8
14258
+ },
14259
+ addEmailRow: {
14260
+ flexDirection: "row",
14261
+ gap: 8
14262
+ },
14263
+ addEmailInput: {
14264
+ flex: 1,
14265
+ backgroundColor: "#F9FAFB",
14266
+ borderWidth: 1,
14267
+ borderColor: "#E5E7EB",
14268
+ borderRadius: 10,
14269
+ paddingHorizontal: 14,
14270
+ paddingVertical: 10,
14271
+ fontSize: 14,
14272
+ color: "#111827"
14273
+ },
14274
+ addEmailButton: {
14275
+ backgroundColor: "#7C3AED",
14276
+ paddingHorizontal: 16,
14277
+ borderRadius: 10,
14278
+ justifyContent: "center"
14279
+ },
14280
+ addEmailButtonDisabled: {
14281
+ backgroundColor: "#C4B5FD"
14282
+ },
14283
+ addEmailButtonText: {
14284
+ fontSize: 14,
14285
+ fontWeight: "600",
14286
+ color: "#fff"
14287
+ },
14288
+ platformButtons: {
14289
+ flexDirection: "row",
14290
+ gap: 8
14291
+ },
14292
+ platformButton: {
14293
+ flex: 1,
14294
+ backgroundColor: "#F3F4F6",
14295
+ paddingVertical: 12,
14296
+ borderRadius: 10,
14297
+ alignItems: "center",
14298
+ borderWidth: 2,
14299
+ borderColor: "transparent"
14300
+ },
14301
+ platformButtonActive: {
14302
+ backgroundColor: "#EDE9FE",
14303
+ borderColor: "#7C3AED"
14304
+ },
14305
+ platformButtonText: {
14306
+ fontSize: 13,
14307
+ color: "#6B7280",
14308
+ fontWeight: "500"
14309
+ },
14310
+ platformButtonTextActive: {
14311
+ color: "#7C3AED"
14312
+ },
14313
+ saveProfileButton: {
14314
+ backgroundColor: "#16A34A",
14315
+ paddingVertical: 14,
14316
+ borderRadius: 12,
14317
+ alignItems: "center",
14318
+ marginTop: 8
14319
+ },
14320
+ saveProfileButtonDisabled: {
14321
+ opacity: 0.6
14322
+ },
14323
+ saveProfileButtonText: {
14324
+ fontSize: 16,
14325
+ fontWeight: "600",
14326
+ color: "#fff"
14327
+ },
14328
+ // Profile overlay styles
14329
+ profileOverlay: {
14330
+ position: "absolute",
14331
+ top: 0,
14332
+ left: 0,
14333
+ right: 0,
14334
+ bottom: 0,
14335
+ backgroundColor: "#fff",
14336
+ zIndex: 100
14337
+ },
14338
+ profileOverlayContent: {
14339
+ flex: 1,
14340
+ padding: 16
14341
+ },
14342
+ profileOverlayFooter: {
14343
+ borderTopWidth: 1,
14344
+ borderTopColor: "#E5E7EB",
14345
+ padding: 12,
14346
+ backgroundColor: "#F9FAFB"
14347
+ },
14348
+ closeProfileButton: {
14349
+ paddingVertical: 8,
14350
+ alignItems: "center"
14351
+ },
14352
+ closeProfileButtonText: {
14353
+ fontSize: 14,
14354
+ fontWeight: "500",
14355
+ color: "#7C3AED"
13885
14356
  }
13886
14357
  });
13887
14358
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -11528,6 +11528,9 @@ var BugBearClient = class {
11528
11528
  id: data.id,
11529
11529
  name: data.name,
11530
11530
  email: data.email,
11531
+ additionalEmails: data.additional_emails || [],
11532
+ avatarUrl: data.avatar_url || void 0,
11533
+ platforms: data.platforms || [],
11531
11534
  assignedTests: data.assigned_count || 0,
11532
11535
  completedTests: data.completed_count || 0
11533
11536
  };
@@ -11536,6 +11539,32 @@ var BugBearClient = class {
11536
11539
  return null;
11537
11540
  }
11538
11541
  }
11542
+ /**
11543
+ * Update tester profile
11544
+ * Allows testers to update their name, additional emails, avatar, and platforms
11545
+ */
11546
+ async updateTesterProfile(updates) {
11547
+ try {
11548
+ const userInfo = await this.getCurrentUserInfo();
11549
+ if (!userInfo) {
11550
+ return { success: false, error: "Not authenticated" };
11551
+ }
11552
+ const updateData = {};
11553
+ if (updates.name !== void 0) updateData.name = updates.name;
11554
+ if (updates.additionalEmails !== void 0) updateData.additional_emails = updates.additionalEmails;
11555
+ if (updates.avatarUrl !== void 0) updateData.avatar_url = updates.avatarUrl;
11556
+ if (updates.platforms !== void 0) updateData.platforms = updates.platforms;
11557
+ const { error } = await this.supabase.from("testers").update(updateData).eq("project_id", this.config.projectId).eq("email", userInfo.email);
11558
+ if (error) {
11559
+ console.error("BugBear: updateTesterProfile error", error);
11560
+ return { success: false, error: error.message };
11561
+ }
11562
+ return { success: true };
11563
+ } catch (err) {
11564
+ console.error("BugBear: updateTesterProfile error", err);
11565
+ return { success: false, error: "Failed to update profile" };
11566
+ }
11567
+ }
11539
11568
  /**
11540
11569
  * Check if current user is a tester for this project
11541
11570
  */
@@ -12082,6 +12111,9 @@ var BugBearContext = createContext({
12082
12111
  },
12083
12112
  createThread: async () => ({ success: false }),
12084
12113
  refreshTesterStatus: async () => {
12114
+ },
12115
+ updateTesterProfile: async () => ({ success: false }),
12116
+ refreshTesterInfo: async () => {
12085
12117
  }
12086
12118
  });
12087
12119
  function useBugBear() {
@@ -12143,6 +12175,20 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
12143
12175
  }
12144
12176
  return result;
12145
12177
  }, [client, refreshThreads]);
12178
+ const updateTesterProfile = useCallback(async (updates) => {
12179
+ if (!client) return { success: false, error: "Client not initialized" };
12180
+ const result = await client.updateTesterProfile(updates);
12181
+ if (result.success) {
12182
+ const info = await client.getTesterInfo();
12183
+ setTesterInfo(info);
12184
+ }
12185
+ return result;
12186
+ }, [client]);
12187
+ const refreshTesterInfo = useCallback(async () => {
12188
+ if (!client) return;
12189
+ const info = await client.getTesterInfo();
12190
+ setTesterInfo(info);
12191
+ }, [client]);
12146
12192
  const initializeBugBear = useCallback(async (bugBearClient) => {
12147
12193
  setIsLoading(true);
12148
12194
  try {
@@ -12209,7 +12255,9 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
12209
12255
  sendMessage,
12210
12256
  markAsRead,
12211
12257
  createThread,
12212
- refreshTesterStatus
12258
+ refreshTesterStatus,
12259
+ updateTesterProfile,
12260
+ refreshTesterInfo
12213
12261
  }
12214
12262
  },
12215
12263
  children
@@ -12265,11 +12313,14 @@ function BugBearButton({
12265
12313
  getThreadMessages,
12266
12314
  sendMessage,
12267
12315
  markAsRead,
12268
- createThread
12316
+ createThread,
12317
+ updateTesterProfile,
12318
+ refreshTesterInfo
12269
12319
  } = useBugBear();
12270
12320
  const [modalVisible, setModalVisible] = useState2(false);
12271
12321
  const [activeTab, setActiveTab] = useState2("tests");
12272
12322
  const [showSteps, setShowSteps] = useState2(false);
12323
+ const [showProfileOverlay, setShowProfileOverlay] = useState2(false);
12273
12324
  const [messageView, setMessageView] = useState2("list");
12274
12325
  const [selectedThread, setSelectedThread] = useState2(null);
12275
12326
  const [threadMessages, setThreadMessages] = useState2([]);
@@ -12279,6 +12330,13 @@ function BugBearButton({
12279
12330
  const [composeSubject, setComposeSubject] = useState2("");
12280
12331
  const [composeMessage, setComposeMessage] = useState2("");
12281
12332
  const [sendingNewMessage, setSendingNewMessage] = useState2(false);
12333
+ const [profileEditing, setProfileEditing] = useState2(false);
12334
+ const [profileName, setProfileName] = useState2("");
12335
+ const [profileAdditionalEmails, setProfileAdditionalEmails] = useState2([]);
12336
+ const [newEmailInput, setNewEmailInput] = useState2("");
12337
+ const [profilePlatforms, setProfilePlatforms] = useState2([]);
12338
+ const [savingProfile, setSavingProfile] = useState2(false);
12339
+ const [profileSaved, setProfileSaved] = useState2(false);
12282
12340
  const getInitialPosition = () => {
12283
12341
  const buttonSize = 56;
12284
12342
  const margin = 16;
@@ -12463,6 +12521,67 @@ function BugBearButton({
12463
12521
  }
12464
12522
  setSendingNewMessage(false);
12465
12523
  };
12524
+ const handleOpenProfile = () => {
12525
+ if (testerInfo) {
12526
+ setProfileName(testerInfo.name);
12527
+ setProfileAdditionalEmails(testerInfo.additionalEmails || []);
12528
+ setProfilePlatforms(testerInfo.platforms || []);
12529
+ }
12530
+ setProfileEditing(false);
12531
+ setShowProfileOverlay(true);
12532
+ };
12533
+ const handleStartEditProfile = () => {
12534
+ if (testerInfo) {
12535
+ setProfileName(testerInfo.name);
12536
+ setProfileAdditionalEmails(testerInfo.additionalEmails || []);
12537
+ setProfilePlatforms(testerInfo.platforms || []);
12538
+ }
12539
+ setProfileEditing(true);
12540
+ };
12541
+ const handleCancelEditProfile = () => {
12542
+ setProfileEditing(false);
12543
+ setNewEmailInput("");
12544
+ };
12545
+ const handleCloseProfile = () => {
12546
+ setShowProfileOverlay(false);
12547
+ setProfileEditing(false);
12548
+ setNewEmailInput("");
12549
+ };
12550
+ const handleAddEmail = () => {
12551
+ const email = newEmailInput.trim().toLowerCase();
12552
+ if (email && email.includes("@") && !profileAdditionalEmails.includes(email)) {
12553
+ setProfileAdditionalEmails([...profileAdditionalEmails, email]);
12554
+ setNewEmailInput("");
12555
+ }
12556
+ };
12557
+ const handleRemoveEmail = (email) => {
12558
+ setProfileAdditionalEmails(profileAdditionalEmails.filter((e) => e !== email));
12559
+ };
12560
+ const handleTogglePlatform = (platform) => {
12561
+ if (profilePlatforms.includes(platform)) {
12562
+ setProfilePlatforms(profilePlatforms.filter((p) => p !== platform));
12563
+ } else {
12564
+ setProfilePlatforms([...profilePlatforms, platform]);
12565
+ }
12566
+ };
12567
+ const handleSaveProfile = async () => {
12568
+ setSavingProfile(true);
12569
+ const updates = {
12570
+ name: profileName.trim(),
12571
+ additionalEmails: profileAdditionalEmails,
12572
+ platforms: profilePlatforms
12573
+ };
12574
+ const result = await updateTesterProfile(updates);
12575
+ if (result.success) {
12576
+ setProfileEditing(false);
12577
+ setProfileSaved(true);
12578
+ setTimeout(() => {
12579
+ setProfileSaved(false);
12580
+ setShowProfileOverlay(false);
12581
+ }, 1500);
12582
+ }
12583
+ setSavingProfile(false);
12584
+ };
12466
12585
  const formatRelativeTime = (dateString) => {
12467
12586
  const date = new Date(dateString);
12468
12587
  const now = /* @__PURE__ */ new Date();
@@ -12625,7 +12744,7 @@ function BugBearButton({
12625
12744
  behavior: Platform2.OS === "ios" ? "padding" : "height",
12626
12745
  style: styles.modalContainer
12627
12746
  },
12628
- /* @__PURE__ */ React2.createElement(View, { style: styles.modalContent }, /* @__PURE__ */ React2.createElement(View, { style: styles.header }, /* @__PURE__ */ React2.createElement(View, { style: styles.headerLeft }, /* @__PURE__ */ React2.createElement(Text, { style: styles.headerEmoji }, "\u{1F43B}"), /* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.headerTitle }, "BugBear"), /* @__PURE__ */ React2.createElement(Text, { style: styles.headerSubtitle }, testerInfo?.name))), /* @__PURE__ */ React2.createElement(
12747
+ /* @__PURE__ */ React2.createElement(View, { style: styles.modalContent }, /* @__PURE__ */ React2.createElement(View, { style: styles.header }, /* @__PURE__ */ React2.createElement(View, { style: styles.headerLeft }, /* @__PURE__ */ React2.createElement(Text, { style: styles.headerEmoji }, "\u{1F43B}"), /* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(Text, { style: styles.headerTitle }, "BugBear"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: handleOpenProfile, style: styles.headerNameButton }, /* @__PURE__ */ React2.createElement(Text, { style: styles.headerSubtitle }, testerInfo?.name), /* @__PURE__ */ React2.createElement(Text, { style: styles.headerPencil }, "\u270E")))), /* @__PURE__ */ React2.createElement(
12629
12748
  TouchableOpacity,
12630
12749
  {
12631
12750
  onPress: () => setModalVisible(false),
@@ -12860,7 +12979,81 @@ function BugBearButton({
12860
12979
  disabled: !description.trim() || submitting
12861
12980
  },
12862
12981
  /* @__PURE__ */ React2.createElement(Text, { style: styles.submitButtonText }, submitting ? "Submitting..." : "Submit Report")
12863
- )))), activeTab === "messages" && messageView === "thread" && selectedThread ? (
12982
+ )))), showProfileOverlay && /* @__PURE__ */ React2.createElement(View, { style: styles.profileOverlay }, /* @__PURE__ */ React2.createElement(ScrollView, { style: styles.profileOverlayContent }, profileSaved ? /* @__PURE__ */ React2.createElement(View, { style: styles.emptyState }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyEmoji }, "\u2705"), /* @__PURE__ */ React2.createElement(Text, { style: styles.emptyTitle }, "Profile saved!")) : profileEditing ? (
12983
+ /* Edit Profile Form */
12984
+ /* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: styles.profileEditHeader }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileEditTitle }, "Edit Profile"), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: handleCancelEditProfile }, /* @__PURE__ */ React2.createElement(Text, { style: styles.cancelText }, "Cancel"))), /* @__PURE__ */ React2.createElement(View, { style: styles.profileSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.label }, "Name"), /* @__PURE__ */ React2.createElement(
12985
+ TextInput,
12986
+ {
12987
+ style: styles.profileInput,
12988
+ value: profileName,
12989
+ onChangeText: setProfileName,
12990
+ placeholder: "Your name",
12991
+ placeholderTextColor: "#9CA3AF"
12992
+ }
12993
+ )), /* @__PURE__ */ React2.createElement(View, { style: styles.profileSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.label }, "Primary Email"), /* @__PURE__ */ React2.createElement(View, { style: styles.profileReadOnly }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileReadOnlyText }, testerInfo?.email), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileReadOnlyHint }, "Main communication email"))), /* @__PURE__ */ React2.createElement(View, { style: styles.profileSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.label }, "Additional Testing Emails"), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileHint }, "Add other emails you use to test on different accounts"), profileAdditionalEmails.map((email) => /* @__PURE__ */ React2.createElement(View, { key: email, style: styles.emailChip }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emailChipText }, email), /* @__PURE__ */ React2.createElement(TouchableOpacity, { onPress: () => handleRemoveEmail(email) }, /* @__PURE__ */ React2.createElement(Text, { style: styles.emailChipRemove }, "\u2715")))), /* @__PURE__ */ React2.createElement(View, { style: styles.addEmailRow }, /* @__PURE__ */ React2.createElement(
12994
+ TextInput,
12995
+ {
12996
+ style: styles.addEmailInput,
12997
+ value: newEmailInput,
12998
+ onChangeText: setNewEmailInput,
12999
+ placeholder: "email@example.com",
13000
+ placeholderTextColor: "#9CA3AF",
13001
+ keyboardType: "email-address",
13002
+ autoCapitalize: "none"
13003
+ }
13004
+ ), /* @__PURE__ */ React2.createElement(
13005
+ TouchableOpacity,
13006
+ {
13007
+ style: [styles.addEmailButton, !newEmailInput.trim() && styles.addEmailButtonDisabled],
13008
+ onPress: handleAddEmail,
13009
+ disabled: !newEmailInput.trim()
13010
+ },
13011
+ /* @__PURE__ */ React2.createElement(Text, { style: styles.addEmailButtonText }, "Add")
13012
+ ))), /* @__PURE__ */ React2.createElement(View, { style: styles.profileSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.label }, "Testing Platforms"), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileHint }, "Select the platforms you can test on"), /* @__PURE__ */ React2.createElement(View, { style: styles.platformButtons }, [
13013
+ { key: "ios", label: "\u{1F4F1} iOS" },
13014
+ { key: "android", label: "\u{1F916} Android" },
13015
+ { key: "web", label: "\u{1F310} Web" }
13016
+ ].map(({ key, label }) => /* @__PURE__ */ React2.createElement(
13017
+ TouchableOpacity,
13018
+ {
13019
+ key,
13020
+ style: [
13021
+ styles.platformButton,
13022
+ profilePlatforms.includes(key) && styles.platformButtonActive
13023
+ ],
13024
+ onPress: () => handleTogglePlatform(key)
13025
+ },
13026
+ /* @__PURE__ */ React2.createElement(Text, { style: [
13027
+ styles.platformButtonText,
13028
+ profilePlatforms.includes(key) && styles.platformButtonTextActive
13029
+ ] }, label)
13030
+ )))), /* @__PURE__ */ React2.createElement(
13031
+ TouchableOpacity,
13032
+ {
13033
+ style: [styles.saveProfileButton, savingProfile && styles.saveProfileButtonDisabled],
13034
+ onPress: handleSaveProfile,
13035
+ disabled: savingProfile
13036
+ },
13037
+ /* @__PURE__ */ React2.createElement(Text, { style: styles.saveProfileButtonText }, savingProfile ? "Saving..." : "Save Profile")
13038
+ ))
13039
+ ) : (
13040
+ /* Profile View */
13041
+ /* @__PURE__ */ React2.createElement(View, null, /* @__PURE__ */ React2.createElement(View, { style: styles.profileCard }, /* @__PURE__ */ React2.createElement(View, { style: styles.avatarCircle }, /* @__PURE__ */ React2.createElement(Text, { style: styles.avatarText }, testerInfo?.name?.charAt(0)?.toUpperCase() || "?")), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileName }, testerInfo?.name), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileEmail }, testerInfo?.email), /* @__PURE__ */ React2.createElement(View, { style: styles.profileStats }, /* @__PURE__ */ React2.createElement(View, { style: styles.profileStat }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileStatValue }, testerInfo?.assignedTests || 0), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileStatLabel }, "Assigned")), /* @__PURE__ */ React2.createElement(View, { style: styles.profileStatDivider }), /* @__PURE__ */ React2.createElement(View, { style: styles.profileStat }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileStatValue }, testerInfo?.completedTests || 0), /* @__PURE__ */ React2.createElement(Text, { style: styles.profileStatLabel }, "Completed")))), (testerInfo?.additionalEmails?.length || 0) > 0 && /* @__PURE__ */ React2.createElement(View, { style: styles.profileInfoSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileInfoLabel }, "Additional Emails"), testerInfo?.additionalEmails?.map((email) => /* @__PURE__ */ React2.createElement(Text, { key: email, style: styles.profileInfoValue }, email))), (testerInfo?.platforms?.length || 0) > 0 && /* @__PURE__ */ React2.createElement(View, { style: styles.profileInfoSection }, /* @__PURE__ */ React2.createElement(Text, { style: styles.profileInfoLabel }, "Testing Platforms"), /* @__PURE__ */ React2.createElement(View, { style: styles.platformTags }, testerInfo?.platforms?.map((platform) => /* @__PURE__ */ React2.createElement(View, { key: platform, style: styles.platformTag }, /* @__PURE__ */ React2.createElement(Text, { style: styles.platformTagText }, platform === "ios" ? "\u{1F4F1} iOS" : platform === "android" ? "\u{1F916} Android" : "\u{1F310} Web"))))), /* @__PURE__ */ React2.createElement(
13042
+ TouchableOpacity,
13043
+ {
13044
+ style: styles.editProfileButton,
13045
+ onPress: handleStartEditProfile
13046
+ },
13047
+ /* @__PURE__ */ React2.createElement(Text, { style: styles.editProfileButtonText }, "Edit Profile")
13048
+ ))
13049
+ )), /* @__PURE__ */ React2.createElement(View, { style: styles.profileOverlayFooter }, /* @__PURE__ */ React2.createElement(
13050
+ TouchableOpacity,
13051
+ {
13052
+ style: styles.closeProfileButton,
13053
+ onPress: handleCloseProfile
13054
+ },
13055
+ /* @__PURE__ */ React2.createElement(Text, { style: styles.closeProfileButtonText }, "\u2190 Back")
13056
+ ))), activeTab === "messages" && messageView === "thread" && selectedThread ? (
12864
13057
  /* Reply Composer */
12865
13058
  /* @__PURE__ */ React2.createElement(View, { style: styles.replyComposer }, /* @__PURE__ */ React2.createElement(
12866
13059
  TextInput,
@@ -12972,6 +13165,15 @@ var styles = StyleSheet.create({
12972
13165
  color: "#DDD6FE",
12973
13166
  fontSize: 12
12974
13167
  },
13168
+ headerNameButton: {
13169
+ flexDirection: "row",
13170
+ alignItems: "center",
13171
+ gap: 4
13172
+ },
13173
+ headerPencil: {
13174
+ color: "#DDD6FE",
13175
+ fontSize: 11
13176
+ },
12975
13177
  closeButton: {
12976
13178
  padding: 8
12977
13179
  },
@@ -13857,6 +14059,275 @@ var styles = StyleSheet.create({
13857
14059
  fontSize: 16,
13858
14060
  fontWeight: "600",
13859
14061
  color: "#fff"
14062
+ },
14063
+ // Profile styles
14064
+ profileCard: {
14065
+ backgroundColor: "#F9FAFB",
14066
+ borderRadius: 16,
14067
+ padding: 24,
14068
+ alignItems: "center",
14069
+ marginBottom: 16
14070
+ },
14071
+ avatarCircle: {
14072
+ width: 72,
14073
+ height: 72,
14074
+ borderRadius: 36,
14075
+ backgroundColor: "#7C3AED",
14076
+ justifyContent: "center",
14077
+ alignItems: "center",
14078
+ marginBottom: 12
14079
+ },
14080
+ avatarText: {
14081
+ fontSize: 28,
14082
+ fontWeight: "600",
14083
+ color: "#fff"
14084
+ },
14085
+ profileName: {
14086
+ fontSize: 20,
14087
+ fontWeight: "600",
14088
+ color: "#111827",
14089
+ marginBottom: 4
14090
+ },
14091
+ profileEmail: {
14092
+ fontSize: 14,
14093
+ color: "#6B7280",
14094
+ marginBottom: 16
14095
+ },
14096
+ profileStats: {
14097
+ flexDirection: "row",
14098
+ alignItems: "center"
14099
+ },
14100
+ profileStat: {
14101
+ alignItems: "center",
14102
+ paddingHorizontal: 20
14103
+ },
14104
+ profileStatValue: {
14105
+ fontSize: 24,
14106
+ fontWeight: "700",
14107
+ color: "#7C3AED"
14108
+ },
14109
+ profileStatLabel: {
14110
+ fontSize: 12,
14111
+ color: "#6B7280",
14112
+ marginTop: 2
14113
+ },
14114
+ profileStatDivider: {
14115
+ width: 1,
14116
+ height: 32,
14117
+ backgroundColor: "#E5E7EB"
14118
+ },
14119
+ profileInfoSection: {
14120
+ backgroundColor: "#F9FAFB",
14121
+ borderRadius: 12,
14122
+ padding: 16,
14123
+ marginBottom: 12
14124
+ },
14125
+ profileInfoLabel: {
14126
+ fontSize: 12,
14127
+ fontWeight: "600",
14128
+ color: "#6B7280",
14129
+ marginBottom: 8,
14130
+ textTransform: "uppercase",
14131
+ letterSpacing: 0.5
14132
+ },
14133
+ profileInfoValue: {
14134
+ fontSize: 14,
14135
+ color: "#374151",
14136
+ marginBottom: 4
14137
+ },
14138
+ platformTags: {
14139
+ flexDirection: "row",
14140
+ flexWrap: "wrap",
14141
+ gap: 8
14142
+ },
14143
+ platformTag: {
14144
+ backgroundColor: "#EDE9FE",
14145
+ paddingHorizontal: 12,
14146
+ paddingVertical: 6,
14147
+ borderRadius: 16
14148
+ },
14149
+ platformTagText: {
14150
+ fontSize: 13,
14151
+ color: "#7C3AED",
14152
+ fontWeight: "500"
14153
+ },
14154
+ editProfileButton: {
14155
+ backgroundColor: "#7C3AED",
14156
+ paddingVertical: 14,
14157
+ borderRadius: 12,
14158
+ alignItems: "center",
14159
+ marginTop: 8
14160
+ },
14161
+ editProfileButtonText: {
14162
+ fontSize: 16,
14163
+ fontWeight: "600",
14164
+ color: "#fff"
14165
+ },
14166
+ // Profile edit styles
14167
+ profileEditHeader: {
14168
+ flexDirection: "row",
14169
+ justifyContent: "space-between",
14170
+ alignItems: "center",
14171
+ marginBottom: 20
14172
+ },
14173
+ profileEditTitle: {
14174
+ fontSize: 20,
14175
+ fontWeight: "600",
14176
+ color: "#111827"
14177
+ },
14178
+ cancelText: {
14179
+ fontSize: 14,
14180
+ color: "#6B7280"
14181
+ },
14182
+ profileSection: {
14183
+ marginBottom: 20
14184
+ },
14185
+ profileInput: {
14186
+ backgroundColor: "#F9FAFB",
14187
+ borderWidth: 1,
14188
+ borderColor: "#E5E7EB",
14189
+ borderRadius: 10,
14190
+ paddingHorizontal: 14,
14191
+ paddingVertical: 12,
14192
+ fontSize: 15,
14193
+ color: "#111827"
14194
+ },
14195
+ profileReadOnly: {
14196
+ backgroundColor: "#F3F4F6",
14197
+ borderRadius: 10,
14198
+ padding: 14
14199
+ },
14200
+ profileReadOnlyText: {
14201
+ fontSize: 15,
14202
+ color: "#374151"
14203
+ },
14204
+ profileReadOnlyHint: {
14205
+ fontSize: 12,
14206
+ color: "#9CA3AF",
14207
+ marginTop: 4
14208
+ },
14209
+ profileHint: {
14210
+ fontSize: 13,
14211
+ color: "#6B7280",
14212
+ marginBottom: 12
14213
+ },
14214
+ emailChip: {
14215
+ flexDirection: "row",
14216
+ alignItems: "center",
14217
+ backgroundColor: "#EDE9FE",
14218
+ paddingHorizontal: 12,
14219
+ paddingVertical: 8,
14220
+ borderRadius: 20,
14221
+ marginBottom: 8
14222
+ },
14223
+ emailChipText: {
14224
+ flex: 1,
14225
+ fontSize: 14,
14226
+ color: "#5B21B6"
14227
+ },
14228
+ emailChipRemove: {
14229
+ fontSize: 14,
14230
+ color: "#8B5CF6",
14231
+ fontWeight: "600",
14232
+ marginLeft: 8
14233
+ },
14234
+ addEmailRow: {
14235
+ flexDirection: "row",
14236
+ gap: 8
14237
+ },
14238
+ addEmailInput: {
14239
+ flex: 1,
14240
+ backgroundColor: "#F9FAFB",
14241
+ borderWidth: 1,
14242
+ borderColor: "#E5E7EB",
14243
+ borderRadius: 10,
14244
+ paddingHorizontal: 14,
14245
+ paddingVertical: 10,
14246
+ fontSize: 14,
14247
+ color: "#111827"
14248
+ },
14249
+ addEmailButton: {
14250
+ backgroundColor: "#7C3AED",
14251
+ paddingHorizontal: 16,
14252
+ borderRadius: 10,
14253
+ justifyContent: "center"
14254
+ },
14255
+ addEmailButtonDisabled: {
14256
+ backgroundColor: "#C4B5FD"
14257
+ },
14258
+ addEmailButtonText: {
14259
+ fontSize: 14,
14260
+ fontWeight: "600",
14261
+ color: "#fff"
14262
+ },
14263
+ platformButtons: {
14264
+ flexDirection: "row",
14265
+ gap: 8
14266
+ },
14267
+ platformButton: {
14268
+ flex: 1,
14269
+ backgroundColor: "#F3F4F6",
14270
+ paddingVertical: 12,
14271
+ borderRadius: 10,
14272
+ alignItems: "center",
14273
+ borderWidth: 2,
14274
+ borderColor: "transparent"
14275
+ },
14276
+ platformButtonActive: {
14277
+ backgroundColor: "#EDE9FE",
14278
+ borderColor: "#7C3AED"
14279
+ },
14280
+ platformButtonText: {
14281
+ fontSize: 13,
14282
+ color: "#6B7280",
14283
+ fontWeight: "500"
14284
+ },
14285
+ platformButtonTextActive: {
14286
+ color: "#7C3AED"
14287
+ },
14288
+ saveProfileButton: {
14289
+ backgroundColor: "#16A34A",
14290
+ paddingVertical: 14,
14291
+ borderRadius: 12,
14292
+ alignItems: "center",
14293
+ marginTop: 8
14294
+ },
14295
+ saveProfileButtonDisabled: {
14296
+ opacity: 0.6
14297
+ },
14298
+ saveProfileButtonText: {
14299
+ fontSize: 16,
14300
+ fontWeight: "600",
14301
+ color: "#fff"
14302
+ },
14303
+ // Profile overlay styles
14304
+ profileOverlay: {
14305
+ position: "absolute",
14306
+ top: 0,
14307
+ left: 0,
14308
+ right: 0,
14309
+ bottom: 0,
14310
+ backgroundColor: "#fff",
14311
+ zIndex: 100
14312
+ },
14313
+ profileOverlayContent: {
14314
+ flex: 1,
14315
+ padding: 16
14316
+ },
14317
+ profileOverlayFooter: {
14318
+ borderTopWidth: 1,
14319
+ borderTopColor: "#E5E7EB",
14320
+ padding: 12,
14321
+ backgroundColor: "#F9FAFB"
14322
+ },
14323
+ closeProfileButton: {
14324
+ paddingVertical: 8,
14325
+ alignItems: "center"
14326
+ },
14327
+ closeProfileButtonText: {
14328
+ fontSize: 14,
14329
+ fontWeight: "500",
14330
+ color: "#7C3AED"
13860
14331
  }
13861
14332
  });
13862
14333
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/react-native",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "BugBear React Native components for mobile apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",