@bbearai/react-native 0.1.8 → 0.1.9

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.
Files changed (3) hide show
  1. package/dist/index.js +843 -191
  2. package/dist/index.mjs +843 -191
  3. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -11449,7 +11449,16 @@ var BugBearClient = class {
11449
11449
  */
11450
11450
  async submitReport(report) {
11451
11451
  try {
11452
+ const validationError = this.validateReport(report);
11453
+ if (validationError) {
11454
+ return { success: false, error: validationError };
11455
+ }
11452
11456
  const userInfo = await this.getCurrentUserInfo();
11457
+ const rateLimitId = userInfo?.email || this.config.projectId;
11458
+ const rateLimit = await this.checkRateLimit(rateLimitId, "report_submit");
11459
+ if (!rateLimit.allowed) {
11460
+ return { success: false, error: rateLimit.error };
11461
+ }
11453
11462
  if (!userInfo) {
11454
11463
  console.error("BugBear: No user info available, cannot submit report");
11455
11464
  return { success: false, error: "User not authenticated" };
@@ -11500,6 +11509,7 @@ var BugBearClient = class {
11500
11509
  const { data, error } = await this.supabase.from("test_assignments").select(`
11501
11510
  id,
11502
11511
  status,
11512
+ started_at,
11503
11513
  test_case:test_cases(
11504
11514
  id,
11505
11515
  title,
@@ -11527,6 +11537,7 @@ var BugBearClient = class {
11527
11537
  return (data || []).map((item) => ({
11528
11538
  id: item.id,
11529
11539
  status: item.status,
11540
+ startedAt: item.started_at,
11530
11541
  testCase: {
11531
11542
  id: item.test_case.id,
11532
11543
  title: item.test_case.title,
@@ -11552,47 +11563,430 @@ var BugBearClient = class {
11552
11563
  return [];
11553
11564
  }
11554
11565
  }
11566
+ /**
11567
+ * Get assignment by ID with time tracking fields
11568
+ */
11569
+ async getAssignment(assignmentId) {
11570
+ try {
11571
+ const { data, error } = await this.supabase.from("test_assignments").select(`
11572
+ id,
11573
+ status,
11574
+ started_at,
11575
+ completed_at,
11576
+ duration_seconds,
11577
+ test_case:test_cases(
11578
+ id,
11579
+ title,
11580
+ test_key,
11581
+ description,
11582
+ steps,
11583
+ expected_result,
11584
+ priority,
11585
+ target_route,
11586
+ track:qa_tracks(
11587
+ id,
11588
+ name,
11589
+ icon,
11590
+ color,
11591
+ test_template,
11592
+ rubric_mode,
11593
+ description
11594
+ )
11595
+ )
11596
+ `).eq("id", assignmentId).single();
11597
+ if (error || !data) return null;
11598
+ const testCase = data.test_case;
11599
+ if (!testCase) {
11600
+ console.error("BugBear: Assignment returned without test_case");
11601
+ return null;
11602
+ }
11603
+ const track = testCase.track;
11604
+ return {
11605
+ id: data.id,
11606
+ status: data.status,
11607
+ startedAt: data.started_at,
11608
+ durationSeconds: data.duration_seconds,
11609
+ testCase: {
11610
+ id: testCase.id,
11611
+ title: testCase.title,
11612
+ testKey: testCase.test_key,
11613
+ description: testCase.description,
11614
+ steps: testCase.steps,
11615
+ expectedResult: testCase.expected_result,
11616
+ priority: testCase.priority,
11617
+ targetRoute: testCase.target_route,
11618
+ track: track ? {
11619
+ id: track.id,
11620
+ name: track.name,
11621
+ icon: track.icon,
11622
+ color: track.color,
11623
+ testTemplate: track.test_template,
11624
+ rubricMode: track.rubric_mode || "pass_fail",
11625
+ description: track.description
11626
+ } : void 0
11627
+ }
11628
+ };
11629
+ } catch (err) {
11630
+ console.error("BugBear: Error fetching assignment", err);
11631
+ return null;
11632
+ }
11633
+ }
11634
+ /**
11635
+ * Update assignment status with automatic time tracking
11636
+ * - Sets started_at when status changes to 'in_progress'
11637
+ * - Calculates duration_seconds when status changes to 'passed'/'failed'/'blocked'
11638
+ * - Optionally include feedback when completing a test
11639
+ */
11640
+ async updateAssignmentStatus(assignmentId, status, options) {
11641
+ try {
11642
+ const { data: currentAssignment, error: fetchError } = await this.supabase.from("test_assignments").select("status, started_at").eq("id", assignmentId).single();
11643
+ if (fetchError || !currentAssignment) {
11644
+ return { success: false, error: "Assignment not found" };
11645
+ }
11646
+ const updateData = { status };
11647
+ let durationSeconds;
11648
+ if (status === "in_progress" && currentAssignment.status !== "in_progress") {
11649
+ updateData.started_at = (/* @__PURE__ */ new Date()).toISOString();
11650
+ }
11651
+ if (["passed", "failed", "blocked"].includes(status)) {
11652
+ updateData.completed_at = (/* @__PURE__ */ new Date()).toISOString();
11653
+ if (currentAssignment.started_at) {
11654
+ const startedAt = new Date(currentAssignment.started_at);
11655
+ const completedAt = /* @__PURE__ */ new Date();
11656
+ durationSeconds = Math.round((completedAt.getTime() - startedAt.getTime()) / 1e3);
11657
+ updateData.duration_seconds = durationSeconds;
11658
+ }
11659
+ }
11660
+ if (options?.notes) {
11661
+ updateData.notes = options.notes;
11662
+ }
11663
+ if (options?.testResult) {
11664
+ updateData.test_result = options.testResult;
11665
+ }
11666
+ const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
11667
+ if (error) {
11668
+ console.error("BugBear: Failed to update assignment status", error);
11669
+ return { success: false, error: error.message };
11670
+ }
11671
+ if (options?.feedback && ["passed", "failed", "blocked"].includes(status)) {
11672
+ const { data: assignmentData, error: fetchError2 } = await this.supabase.from("test_assignments").select("test_case_id").eq("id", assignmentId).single();
11673
+ if (fetchError2) {
11674
+ console.error("BugBear: Failed to fetch assignment for feedback", fetchError2);
11675
+ } else if (assignmentData?.test_case_id) {
11676
+ const feedbackResult = await this.submitTestFeedback({
11677
+ testCaseId: assignmentData.test_case_id,
11678
+ assignmentId,
11679
+ feedback: options.feedback,
11680
+ timeToCompleteSeconds: durationSeconds
11681
+ });
11682
+ if (!feedbackResult.success) {
11683
+ console.error("BugBear: Failed to submit feedback", feedbackResult.error);
11684
+ }
11685
+ }
11686
+ }
11687
+ return { success: true, durationSeconds };
11688
+ } catch (err) {
11689
+ const message = err instanceof Error ? err.message : "Unknown error";
11690
+ console.error("BugBear: Error updating assignment status", err);
11691
+ return { success: false, error: message };
11692
+ }
11693
+ }
11694
+ /**
11695
+ * Submit feedback on a test case to help improve test quality
11696
+ * This empowers testers to shape better tests over time
11697
+ */
11698
+ async submitTestFeedback(options) {
11699
+ try {
11700
+ const testerInfo = await this.getTesterInfo();
11701
+ if (!testerInfo) {
11702
+ return { success: false, error: "Not authenticated as tester" };
11703
+ }
11704
+ const { testCaseId, assignmentId, feedback, timeToCompleteSeconds } = options;
11705
+ if (feedback.rating < 1 || feedback.rating > 5) {
11706
+ return { success: false, error: "Rating must be between 1 and 5" };
11707
+ }
11708
+ const { error: feedbackError } = await this.supabase.from("test_feedback").insert({
11709
+ project_id: this.config.projectId,
11710
+ test_case_id: testCaseId,
11711
+ assignment_id: assignmentId || null,
11712
+ tester_id: testerInfo.id,
11713
+ rating: feedback.rating,
11714
+ clarity_rating: feedback.clarityRating || null,
11715
+ steps_rating: feedback.stepsRating || null,
11716
+ relevance_rating: feedback.relevanceRating || null,
11717
+ feedback_note: feedback.feedbackNote?.trim() || null,
11718
+ suggested_improvement: feedback.suggestedImprovement?.trim() || null,
11719
+ is_outdated: feedback.isOutdated || false,
11720
+ needs_more_detail: feedback.needsMoreDetail || false,
11721
+ steps_unclear: feedback.stepsUnclear || false,
11722
+ expected_result_unclear: feedback.expectedResultUnclear || false,
11723
+ platform: this.getDeviceInfo().platform,
11724
+ time_to_complete_seconds: timeToCompleteSeconds || null
11725
+ });
11726
+ if (feedbackError) {
11727
+ console.error("BugBear: Failed to submit feedback", feedbackError);
11728
+ return { success: false, error: feedbackError.message };
11729
+ }
11730
+ if (assignmentId) {
11731
+ const { error: assignmentError } = await this.supabase.from("test_assignments").update({
11732
+ feedback_rating: feedback.rating,
11733
+ feedback_note: feedback.feedbackNote?.trim() || null,
11734
+ feedback_submitted_at: (/* @__PURE__ */ new Date()).toISOString()
11735
+ }).eq("id", assignmentId);
11736
+ if (assignmentError) {
11737
+ console.error("BugBear: Failed to update assignment feedback fields", assignmentError);
11738
+ }
11739
+ }
11740
+ return { success: true };
11741
+ } catch (err) {
11742
+ const message = err instanceof Error ? err.message : "Unknown error";
11743
+ console.error("BugBear: Error submitting feedback", err);
11744
+ return { success: false, error: message };
11745
+ }
11746
+ }
11747
+ /**
11748
+ * Get the currently active (in_progress) assignment for the tester
11749
+ */
11750
+ async getActiveAssignment() {
11751
+ try {
11752
+ const testerInfo = await this.getTesterInfo();
11753
+ if (!testerInfo) return null;
11754
+ const { data, error } = await this.supabase.from("test_assignments").select(`
11755
+ id,
11756
+ status,
11757
+ started_at,
11758
+ test_case:test_cases(
11759
+ id,
11760
+ title,
11761
+ test_key,
11762
+ description,
11763
+ steps,
11764
+ expected_result,
11765
+ priority,
11766
+ target_route,
11767
+ track:qa_tracks(
11768
+ id,
11769
+ name,
11770
+ icon,
11771
+ color,
11772
+ test_template,
11773
+ rubric_mode,
11774
+ description
11775
+ )
11776
+ )
11777
+ `).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).eq("status", "in_progress").order("started_at", { ascending: false }).limit(1).maybeSingle();
11778
+ if (error || !data) return null;
11779
+ const testCase = data.test_case;
11780
+ if (!testCase) {
11781
+ console.error("BugBear: Active assignment returned without test_case");
11782
+ return null;
11783
+ }
11784
+ const track = testCase.track;
11785
+ return {
11786
+ id: data.id,
11787
+ status: data.status,
11788
+ startedAt: data.started_at,
11789
+ testCase: {
11790
+ id: testCase.id,
11791
+ title: testCase.title,
11792
+ testKey: testCase.test_key,
11793
+ description: testCase.description,
11794
+ steps: testCase.steps,
11795
+ expectedResult: testCase.expected_result,
11796
+ priority: testCase.priority,
11797
+ targetRoute: testCase.target_route,
11798
+ track: track ? {
11799
+ id: track.id,
11800
+ name: track.name,
11801
+ icon: track.icon,
11802
+ color: track.color,
11803
+ testTemplate: track.test_template,
11804
+ rubricMode: track.rubric_mode || "pass_fail",
11805
+ description: track.description
11806
+ } : void 0
11807
+ }
11808
+ };
11809
+ } catch (err) {
11810
+ console.error("BugBear: Error fetching active assignment", err);
11811
+ return null;
11812
+ }
11813
+ }
11555
11814
  /**
11556
11815
  * Get current tester info
11557
11816
  * Looks up tester by email from the host app's authenticated user
11817
+ * Checks both primary email AND additional_emails array
11818
+ * Uses parameterized RPC function to prevent SQL injection
11558
11819
  */
11559
11820
  async getTesterInfo() {
11560
11821
  try {
11561
11822
  const userInfo = await this.getCurrentUserInfo();
11562
- if (!userInfo) return null;
11563
- const { data, error } = await this.supabase.from("testers").select("*").eq("project_id", this.config.projectId).eq("email", userInfo.email).eq("status", "active").single();
11823
+ if (!userInfo?.email) return null;
11824
+ if (!this.isValidEmail(userInfo.email)) {
11825
+ console.warn("BugBear: Invalid email format");
11826
+ return null;
11827
+ }
11828
+ const { data, error } = await this.supabase.rpc("lookup_tester_by_email", {
11829
+ p_project_id: this.config.projectId,
11830
+ p_email: userInfo.email
11831
+ }).maybeSingle();
11564
11832
  if (error || !data) return null;
11833
+ const tester = data;
11565
11834
  return {
11566
- id: data.id,
11567
- name: data.name,
11568
- email: data.email,
11569
- additionalEmails: data.additional_emails || [],
11570
- avatarUrl: data.avatar_url || void 0,
11571
- platforms: data.platforms || [],
11572
- assignedTests: data.assigned_count || 0,
11573
- completedTests: data.completed_count || 0
11835
+ id: tester.id,
11836
+ name: tester.name,
11837
+ email: tester.email,
11838
+ additionalEmails: tester.additional_emails || [],
11839
+ avatarUrl: tester.avatar_url || void 0,
11840
+ platforms: tester.platforms || [],
11841
+ assignedTests: tester.assigned_count || 0,
11842
+ completedTests: tester.completed_count || 0
11574
11843
  };
11575
11844
  } catch (err) {
11576
11845
  console.error("BugBear: getTesterInfo error", err);
11577
11846
  return null;
11578
11847
  }
11579
11848
  }
11849
+ /**
11850
+ * Basic email format validation (defense in depth)
11851
+ */
11852
+ isValidEmail(email) {
11853
+ if (!email || email.length > 254) return false;
11854
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
11855
+ return emailRegex.test(email);
11856
+ }
11857
+ /**
11858
+ * Validate report input before submission
11859
+ * Returns error message if invalid, null if valid
11860
+ */
11861
+ validateReport(report) {
11862
+ const validTypes = ["bug", "feedback", "suggestion", "test_pass", "test_fail"];
11863
+ if (report.type && !validTypes.includes(report.type)) {
11864
+ return `Invalid report type: ${report.type}. Must be one of: ${validTypes.join(", ")}`;
11865
+ }
11866
+ const validSeverities = ["critical", "high", "medium", "low"];
11867
+ if (report.severity && !validSeverities.includes(report.severity)) {
11868
+ return `Invalid severity: ${report.severity}. Must be one of: ${validSeverities.join(", ")}`;
11869
+ }
11870
+ if (report.title && report.title.length > 500) {
11871
+ return "Title must be 500 characters or less";
11872
+ }
11873
+ if (report.description && report.description.length > 1e4) {
11874
+ return "Description must be 10,000 characters or less";
11875
+ }
11876
+ if (report.screenshots && Array.isArray(report.screenshots)) {
11877
+ if (report.screenshots.length > 10) {
11878
+ return "Maximum 10 screenshots allowed";
11879
+ }
11880
+ for (const url of report.screenshots) {
11881
+ if (typeof url !== "string" || url.length > 2e3) {
11882
+ return "Invalid screenshot URL";
11883
+ }
11884
+ }
11885
+ }
11886
+ return null;
11887
+ }
11888
+ /**
11889
+ * Validate profile update input
11890
+ * Returns error message if invalid, null if valid
11891
+ */
11892
+ validateProfileUpdate(updates) {
11893
+ if (updates.name !== void 0) {
11894
+ if (typeof updates.name !== "string" || updates.name.length > 100) {
11895
+ return "Name must be 100 characters or less";
11896
+ }
11897
+ }
11898
+ if (updates.additionalEmails !== void 0) {
11899
+ if (!Array.isArray(updates.additionalEmails)) {
11900
+ return "Additional emails must be an array";
11901
+ }
11902
+ if (updates.additionalEmails.length > 5) {
11903
+ return "Maximum 5 additional emails allowed";
11904
+ }
11905
+ for (const email of updates.additionalEmails) {
11906
+ if (!this.isValidEmail(email)) {
11907
+ return `Invalid email format: ${email}`;
11908
+ }
11909
+ }
11910
+ }
11911
+ if (updates.avatarUrl !== void 0 && updates.avatarUrl !== null) {
11912
+ if (typeof updates.avatarUrl !== "string" || updates.avatarUrl.length > 2e3) {
11913
+ return "Invalid avatar URL";
11914
+ }
11915
+ }
11916
+ if (updates.platforms !== void 0) {
11917
+ if (!Array.isArray(updates.platforms)) {
11918
+ return "Platforms must be an array";
11919
+ }
11920
+ const validPlatforms = ["ios", "android", "web", "desktop", "other"];
11921
+ for (const platform of updates.platforms) {
11922
+ if (!validPlatforms.includes(platform)) {
11923
+ return `Invalid platform: ${platform}. Must be one of: ${validPlatforms.join(", ")}`;
11924
+ }
11925
+ }
11926
+ }
11927
+ return null;
11928
+ }
11929
+ /**
11930
+ * Check rate limit for an action
11931
+ * Returns { allowed: boolean, error?: string, remaining?: number }
11932
+ */
11933
+ async checkRateLimit(identifier, action) {
11934
+ try {
11935
+ const { data, error } = await this.supabase.rpc("check_rate_limit", {
11936
+ p_identifier: identifier,
11937
+ p_action: action,
11938
+ p_project_id: this.config.projectId
11939
+ });
11940
+ if (error) {
11941
+ console.warn("BugBear: Rate limit check failed, allowing request", error.message);
11942
+ return { allowed: true };
11943
+ }
11944
+ if (!data.allowed) {
11945
+ return {
11946
+ allowed: false,
11947
+ error: `Rate limit exceeded. Try again in ${Math.ceil((new Date(data.reset_at).getTime() - Date.now()) / 1e3)} seconds.`,
11948
+ remaining: 0,
11949
+ resetAt: data.reset_at
11950
+ };
11951
+ }
11952
+ return {
11953
+ allowed: true,
11954
+ remaining: data.remaining,
11955
+ resetAt: data.reset_at
11956
+ };
11957
+ } catch (err) {
11958
+ console.warn("BugBear: Rate limit check error", err);
11959
+ return { allowed: true };
11960
+ }
11961
+ }
11580
11962
  /**
11581
11963
  * Update tester profile
11582
11964
  * Allows testers to update their name, additional emails, avatar, and platforms
11583
11965
  */
11584
11966
  async updateTesterProfile(updates) {
11585
11967
  try {
11968
+ const validationError = this.validateProfileUpdate(updates);
11969
+ if (validationError) {
11970
+ return { success: false, error: validationError };
11971
+ }
11586
11972
  const userInfo = await this.getCurrentUserInfo();
11587
11973
  if (!userInfo) {
11588
11974
  return { success: false, error: "Not authenticated" };
11589
11975
  }
11976
+ const rateLimit = await this.checkRateLimit(userInfo.email, "profile_update");
11977
+ if (!rateLimit.allowed) {
11978
+ return { success: false, error: rateLimit.error };
11979
+ }
11980
+ const testerInfo = await this.getTesterInfo();
11981
+ if (!testerInfo) {
11982
+ return { success: false, error: "Not a registered tester" };
11983
+ }
11590
11984
  const updateData = {};
11591
11985
  if (updates.name !== void 0) updateData.name = updates.name;
11592
11986
  if (updates.additionalEmails !== void 0) updateData.additional_emails = updates.additionalEmails;
11593
11987
  if (updates.avatarUrl !== void 0) updateData.avatar_url = updates.avatarUrl;
11594
11988
  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);
11989
+ const { error } = await this.supabase.from("testers").update(updateData).eq("id", testerInfo.id);
11596
11990
  if (error) {
11597
11991
  console.error("BugBear: updateTesterProfile error", error);
11598
11992
  return { success: false, error: error.message };
@@ -11868,6 +12262,11 @@ var BugBearClient = class {
11868
12262
  console.error("BugBear: No tester info, cannot send message");
11869
12263
  return false;
11870
12264
  }
12265
+ const rateLimit = await this.checkRateLimit(testerInfo.email, "message_send");
12266
+ if (!rateLimit.allowed) {
12267
+ console.error("BugBear: Rate limit exceeded for messages");
12268
+ return false;
12269
+ }
11871
12270
  const { error } = await this.supabase.from("discussion_messages").insert({
11872
12271
  thread_id: threadId,
11873
12272
  sender_type: "tester",
@@ -11962,6 +12361,248 @@ var BugBearClient = class {
11962
12361
  return { success: false, error: message };
11963
12362
  }
11964
12363
  }
12364
+ // ============================================
12365
+ // QA Sessions (Sprint 1)
12366
+ // ============================================
12367
+ /**
12368
+ * Start a new QA session for exploratory testing
12369
+ */
12370
+ async startSession(options = {}) {
12371
+ try {
12372
+ const testerInfo = await this.getTesterInfo();
12373
+ if (!testerInfo) {
12374
+ return { success: false, error: "Not authenticated as a tester" };
12375
+ }
12376
+ const activeSession = await this.getActiveSession();
12377
+ if (activeSession) {
12378
+ return { success: false, error: "You already have an active session. End it before starting a new one." };
12379
+ }
12380
+ const { data, error } = await this.supabase.rpc("start_qa_session", {
12381
+ p_project_id: this.config.projectId,
12382
+ p_tester_id: testerInfo.id,
12383
+ p_focus_area: options.focusArea || null,
12384
+ p_track: options.track || null,
12385
+ p_platform: options.platform || null
12386
+ });
12387
+ if (error) {
12388
+ console.error("BugBear: Failed to start session", error);
12389
+ return { success: false, error: error.message };
12390
+ }
12391
+ const session = await this.getSession(data);
12392
+ if (!session) {
12393
+ return { success: false, error: "Session created but could not be fetched" };
12394
+ }
12395
+ return { success: true, session };
12396
+ } catch (err) {
12397
+ const message = err instanceof Error ? err.message : "Unknown error";
12398
+ console.error("BugBear: Error starting session", err);
12399
+ return { success: false, error: message };
12400
+ }
12401
+ }
12402
+ /**
12403
+ * End the current QA session
12404
+ */
12405
+ async endSession(sessionId, options = {}) {
12406
+ try {
12407
+ const { data, error } = await this.supabase.rpc("end_qa_session", {
12408
+ p_session_id: sessionId,
12409
+ p_notes: options.notes || null,
12410
+ p_routes_covered: options.routesCovered || null
12411
+ });
12412
+ if (error) {
12413
+ console.error("BugBear: Failed to end session", error);
12414
+ return { success: false, error: error.message };
12415
+ }
12416
+ const session = this.transformSession(data);
12417
+ return { success: true, session };
12418
+ } catch (err) {
12419
+ const message = err instanceof Error ? err.message : "Unknown error";
12420
+ console.error("BugBear: Error ending session", err);
12421
+ return { success: false, error: message };
12422
+ }
12423
+ }
12424
+ /**
12425
+ * Get the current active session for the tester
12426
+ */
12427
+ async getActiveSession() {
12428
+ try {
12429
+ const testerInfo = await this.getTesterInfo();
12430
+ if (!testerInfo) return null;
12431
+ const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).eq("status", "active").order("started_at", { ascending: false }).limit(1).maybeSingle();
12432
+ if (error || !data) return null;
12433
+ return this.transformSession(data);
12434
+ } catch (err) {
12435
+ console.error("BugBear: Error fetching active session", err);
12436
+ return null;
12437
+ }
12438
+ }
12439
+ /**
12440
+ * Get a session by ID
12441
+ */
12442
+ async getSession(sessionId) {
12443
+ try {
12444
+ const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("id", sessionId).single();
12445
+ if (error || !data) return null;
12446
+ return this.transformSession(data);
12447
+ } catch (err) {
12448
+ console.error("BugBear: Error fetching session", err);
12449
+ return null;
12450
+ }
12451
+ }
12452
+ /**
12453
+ * Get session history for the tester
12454
+ */
12455
+ async getSessionHistory(limit = 10) {
12456
+ try {
12457
+ const testerInfo = await this.getTesterInfo();
12458
+ if (!testerInfo) return [];
12459
+ const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).order("started_at", { ascending: false }).limit(limit);
12460
+ if (error) {
12461
+ console.error("BugBear: Failed to fetch session history", error);
12462
+ return [];
12463
+ }
12464
+ return (data || []).map((s) => this.transformSession(s));
12465
+ } catch (err) {
12466
+ console.error("BugBear: Error fetching session history", err);
12467
+ return [];
12468
+ }
12469
+ }
12470
+ /**
12471
+ * Add a finding during a session
12472
+ */
12473
+ async addFinding(sessionId, options) {
12474
+ try {
12475
+ const { data, error } = await this.supabase.rpc("add_session_finding", {
12476
+ p_session_id: sessionId,
12477
+ p_type: options.type,
12478
+ p_title: options.title,
12479
+ p_description: options.description || null,
12480
+ p_severity: options.severity || "observation",
12481
+ p_route: options.route || null,
12482
+ p_screenshot_url: options.screenshotUrl || null,
12483
+ p_console_logs: options.consoleLogs || null,
12484
+ p_network_snapshot: options.networkSnapshot || null,
12485
+ p_device_info: options.deviceInfo || null,
12486
+ p_app_context: options.appContext || null
12487
+ });
12488
+ if (error) {
12489
+ console.error("BugBear: Failed to add finding", error);
12490
+ return { success: false, error: error.message };
12491
+ }
12492
+ const finding = this.transformFinding(data);
12493
+ return { success: true, finding };
12494
+ } catch (err) {
12495
+ const message = err instanceof Error ? err.message : "Unknown error";
12496
+ console.error("BugBear: Error adding finding", err);
12497
+ return { success: false, error: message };
12498
+ }
12499
+ }
12500
+ /**
12501
+ * Get findings for a session
12502
+ */
12503
+ async getSessionFindings(sessionId) {
12504
+ try {
12505
+ const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true });
12506
+ if (error) {
12507
+ console.error("BugBear: Failed to fetch findings", error);
12508
+ return [];
12509
+ }
12510
+ return (data || []).map((f) => this.transformFinding(f));
12511
+ } catch (err) {
12512
+ console.error("BugBear: Error fetching findings", err);
12513
+ return [];
12514
+ }
12515
+ }
12516
+ /**
12517
+ * Convert a finding to a bug report
12518
+ */
12519
+ async convertFindingToBug(findingId) {
12520
+ try {
12521
+ const { data, error } = await this.supabase.rpc("convert_finding_to_bug", {
12522
+ p_finding_id: findingId
12523
+ });
12524
+ if (error) {
12525
+ console.error("BugBear: Failed to convert finding", error);
12526
+ return { success: false, error: error.message };
12527
+ }
12528
+ return { success: true, bugId: data };
12529
+ } catch (err) {
12530
+ const message = err instanceof Error ? err.message : "Unknown error";
12531
+ console.error("BugBear: Error converting finding", err);
12532
+ return { success: false, error: message };
12533
+ }
12534
+ }
12535
+ /**
12536
+ * Dismiss a finding
12537
+ */
12538
+ async dismissFinding(findingId, reason) {
12539
+ try {
12540
+ const { error } = await this.supabase.from("qa_findings").update({
12541
+ dismissed: true,
12542
+ dismissed_reason: reason || null,
12543
+ dismissed_at: (/* @__PURE__ */ new Date()).toISOString()
12544
+ }).eq("id", findingId);
12545
+ if (error) {
12546
+ console.error("BugBear: Failed to dismiss finding", error);
12547
+ return { success: false, error: error.message };
12548
+ }
12549
+ return { success: true };
12550
+ } catch (err) {
12551
+ const message = err instanceof Error ? err.message : "Unknown error";
12552
+ console.error("BugBear: Error dismissing finding", err);
12553
+ return { success: false, error: message };
12554
+ }
12555
+ }
12556
+ /**
12557
+ * Transform database session to QASession type
12558
+ */
12559
+ transformSession(data) {
12560
+ return {
12561
+ id: data.id,
12562
+ projectId: data.project_id,
12563
+ testerId: data.tester_id,
12564
+ focusArea: data.focus_area,
12565
+ track: data.track,
12566
+ platform: data.platform,
12567
+ startedAt: data.started_at,
12568
+ endedAt: data.ended_at,
12569
+ notes: data.notes,
12570
+ routesCovered: data.routes_covered || [],
12571
+ status: data.status,
12572
+ durationMinutes: data.duration_minutes,
12573
+ findingsCount: data.findings_count || 0,
12574
+ bugsFiled: data.bugs_filed || 0,
12575
+ createdAt: data.created_at,
12576
+ updatedAt: data.updated_at
12577
+ };
12578
+ }
12579
+ /**
12580
+ * Transform database finding to QAFinding type
12581
+ */
12582
+ transformFinding(data) {
12583
+ return {
12584
+ id: data.id,
12585
+ sessionId: data.session_id,
12586
+ projectId: data.project_id,
12587
+ type: data.type,
12588
+ severity: data.severity,
12589
+ title: data.title,
12590
+ description: data.description,
12591
+ route: data.route,
12592
+ screenshotUrl: data.screenshot_url,
12593
+ consoleLogs: data.console_logs,
12594
+ networkSnapshot: data.network_snapshot,
12595
+ deviceInfo: data.device_info,
12596
+ appContext: data.app_context,
12597
+ convertedToBugId: data.converted_to_bug_id,
12598
+ convertedToTestId: data.converted_to_test_id,
12599
+ dismissed: data.dismissed || false,
12600
+ dismissedReason: data.dismissed_reason,
12601
+ dismissedAt: data.dismissed_at,
12602
+ createdAt: data.created_at,
12603
+ updatedAt: data.updated_at
12604
+ };
12605
+ }
11965
12606
  };
11966
12607
  function createBugBear(config) {
11967
12608
  return new BugBearClient(config);
@@ -12660,7 +13301,7 @@ function BugBearButton({
12660
13301
  const steps = displayedAssignment.testCase.steps;
12661
13302
  const info = templateInfo[template];
12662
13303
  const rubricMode = displayedAssignment.testCase.track?.rubricMode || "pass_fail";
12663
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: [styles.templateBadge, { backgroundColor: displayedAssignment.testCase.track?.color ? `${displayedAssignment.testCase.track.color}20` : "#F3F4F6" }] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateIcon }, info.icon), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateName }, info.name), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateAction }, "\u2022 ", info.action)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: () => setShowSteps(!showSteps), style: styles.stepsToggle }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepsToggleText }, showSteps ? "\u25BC" : "\u25B6", " ", template === "freeform" ? "Instructions" : `${steps.length} ${template === "checklist" ? "items" : template === "rubric" ? "criteria" : "steps"}`)), showSteps && template === "steps" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepsList }, steps.map((step, idx) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { key: idx, style: styles.step }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepNumber }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepNumberText }, step.stepNumber)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepContent }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepAction }, step.action), step.expectedResult && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepExpected }, "\u2192 ", step.expectedResult))))), showSteps && template === "checklist" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepsList }, steps.map((step, idx) => /* @__PURE__ */ import_react2.default.createElement(
13304
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: [styles.templateBadge, { backgroundColor: displayedAssignment.testCase.track?.color ? `${displayedAssignment.testCase.track.color}20` : "#3f3f46" }] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateIcon }, info.icon), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateName }, info.name), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.templateAction }, "\u2022 ", info.action)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: () => setShowSteps(!showSteps), style: styles.stepsToggle }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepsToggleText }, showSteps ? "\u25BC" : "\u25B6", " ", template === "freeform" ? "Instructions" : `${steps.length} ${template === "checklist" ? "items" : template === "rubric" ? "criteria" : "steps"}`)), showSteps && template === "steps" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepsList }, steps.map((step, idx) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { key: idx, style: styles.step }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepNumber }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepNumberText }, step.stepNumber)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepContent }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepAction }, step.action), step.expectedResult && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.stepExpected }, "\u2192 ", step.expectedResult))))), showSteps && template === "checklist" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.stepsList }, steps.map((step, idx) => /* @__PURE__ */ import_react2.default.createElement(
12664
13305
  import_react_native2.TouchableOpacity,
12665
13306
  {
12666
13307
  key: idx,
@@ -12866,7 +13507,7 @@ function BugBearButton({
12866
13507
  value: composeSubject,
12867
13508
  onChangeText: setComposeSubject,
12868
13509
  placeholder: "What's this about?",
12869
- placeholderTextColor: "#9CA3AF",
13510
+ placeholderTextColor: "#71717a",
12870
13511
  maxLength: 100
12871
13512
  }
12872
13513
  ), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [styles.label, { marginTop: 16 }] }, "Message"), /* @__PURE__ */ import_react2.default.createElement(
@@ -12876,7 +13517,7 @@ function BugBearButton({
12876
13517
  value: composeMessage,
12877
13518
  onChangeText: setComposeMessage,
12878
13519
  placeholder: "Write your message...",
12879
- placeholderTextColor: "#9CA3AF",
13520
+ placeholderTextColor: "#71717a",
12880
13521
  multiline: true,
12881
13522
  numberOfLines: 6,
12882
13523
  textAlignVertical: "top",
@@ -12988,7 +13629,7 @@ function BugBearButton({
12988
13629
  value: description,
12989
13630
  onChangeText: setDescription,
12990
13631
  placeholder: "Describe the issue...",
12991
- placeholderTextColor: "#9CA3AF",
13632
+ placeholderTextColor: "#71717a",
12992
13633
  multiline: true,
12993
13634
  numberOfLines: 4,
12994
13635
  textAlignVertical: "top"
@@ -13013,7 +13654,7 @@ function BugBearButton({
13013
13654
  value: profileName,
13014
13655
  onChangeText: setProfileName,
13015
13656
  placeholder: "Your name",
13016
- placeholderTextColor: "#9CA3AF"
13657
+ placeholderTextColor: "#71717a"
13017
13658
  }
13018
13659
  )), /* @__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
13660
  import_react_native2.TextInput,
@@ -13022,7 +13663,7 @@ function BugBearButton({
13022
13663
  value: newEmailInput,
13023
13664
  onChangeText: setNewEmailInput,
13024
13665
  placeholder: "email@example.com",
13025
- placeholderTextColor: "#9CA3AF",
13666
+ placeholderTextColor: "#71717a",
13026
13667
  keyboardType: "email-address",
13027
13668
  autoCapitalize: "none"
13028
13669
  }
@@ -13087,7 +13728,7 @@ function BugBearButton({
13087
13728
  value: replyText,
13088
13729
  onChangeText: setReplyText,
13089
13730
  placeholder: "Type a reply...",
13090
- placeholderTextColor: "#9CA3AF",
13731
+ placeholderTextColor: "#71717a",
13091
13732
  multiline: true,
13092
13733
  maxLength: 1e3
13093
13734
  }
@@ -13116,13 +13757,13 @@ var styles = import_react_native2.StyleSheet.create({
13116
13757
  width: 56,
13117
13758
  height: 56,
13118
13759
  borderRadius: 28,
13119
- backgroundColor: "#7C3AED",
13760
+ backgroundColor: "#3B82F6",
13120
13761
  justifyContent: "center",
13121
13762
  alignItems: "center",
13122
- shadowColor: "#000",
13763
+ shadowColor: "#3B82F6",
13123
13764
  shadowOffset: { width: 0, height: 4 },
13124
- shadowOpacity: 0.3,
13125
- shadowRadius: 8,
13765
+ shadowOpacity: 0.4,
13766
+ shadowRadius: 12,
13126
13767
  elevation: 8,
13127
13768
  zIndex: 999999
13128
13769
  },
@@ -13155,10 +13796,10 @@ var styles = import_react_native2.StyleSheet.create({
13155
13796
  modalContainer: {
13156
13797
  flex: 1,
13157
13798
  justifyContent: "flex-end",
13158
- backgroundColor: "rgba(0, 0, 0, 0.5)"
13799
+ backgroundColor: "rgba(0, 0, 0, 0.6)"
13159
13800
  },
13160
13801
  modalContent: {
13161
- backgroundColor: "#fff",
13802
+ backgroundColor: "#18181b",
13162
13803
  borderTopLeftRadius: 20,
13163
13804
  borderTopRightRadius: 20,
13164
13805
  maxHeight: "85%"
@@ -13167,11 +13808,13 @@ var styles = import_react_native2.StyleSheet.create({
13167
13808
  flexDirection: "row",
13168
13809
  alignItems: "center",
13169
13810
  justifyContent: "space-between",
13170
- backgroundColor: "#7C3AED",
13811
+ backgroundColor: "#09090b",
13171
13812
  paddingHorizontal: 16,
13172
13813
  paddingVertical: 12,
13173
13814
  borderTopLeftRadius: 20,
13174
- borderTopRightRadius: 20
13815
+ borderTopRightRadius: 20,
13816
+ borderBottomWidth: 1,
13817
+ borderBottomColor: "#27272a"
13175
13818
  },
13176
13819
  headerLeft: {
13177
13820
  flexDirection: "row",
@@ -13182,12 +13825,12 @@ var styles = import_react_native2.StyleSheet.create({
13182
13825
  marginRight: 10
13183
13826
  },
13184
13827
  headerTitle: {
13185
- color: "#fff",
13828
+ color: "#fafafa",
13186
13829
  fontSize: 16,
13187
13830
  fontWeight: "600"
13188
13831
  },
13189
13832
  headerSubtitle: {
13190
- color: "#DDD6FE",
13833
+ color: "#71717a",
13191
13834
  fontSize: 12
13192
13835
  },
13193
13836
  headerNameButton: {
@@ -13196,20 +13839,21 @@ var styles = import_react_native2.StyleSheet.create({
13196
13839
  gap: 4
13197
13840
  },
13198
13841
  headerPencil: {
13199
- color: "#DDD6FE",
13842
+ color: "#71717a",
13200
13843
  fontSize: 11
13201
13844
  },
13202
13845
  closeButton: {
13203
13846
  padding: 8
13204
13847
  },
13205
13848
  closeButtonText: {
13206
- color: "#fff",
13849
+ color: "#a1a1aa",
13207
13850
  fontSize: 18
13208
13851
  },
13209
13852
  tabs: {
13210
13853
  flexDirection: "row",
13211
13854
  borderBottomWidth: 1,
13212
- borderBottomColor: "#E5E7EB"
13855
+ borderBottomColor: "#27272a",
13856
+ backgroundColor: "#18181b"
13213
13857
  },
13214
13858
  tab: {
13215
13859
  flex: 1,
@@ -13218,15 +13862,15 @@ var styles = import_react_native2.StyleSheet.create({
13218
13862
  },
13219
13863
  activeTab: {
13220
13864
  borderBottomWidth: 2,
13221
- borderBottomColor: "#7C3AED"
13865
+ borderBottomColor: "#3B82F6"
13222
13866
  },
13223
13867
  tabText: {
13224
13868
  fontSize: 14,
13225
13869
  fontWeight: "500",
13226
- color: "#6B7280"
13870
+ color: "#71717a"
13227
13871
  },
13228
13872
  activeTabText: {
13229
- color: "#7C3AED"
13873
+ color: "#3B82F6"
13230
13874
  },
13231
13875
  content: {
13232
13876
  padding: 16,
@@ -13239,16 +13883,16 @@ var styles = import_react_native2.StyleSheet.create({
13239
13883
  paddingHorizontal: 16,
13240
13884
  paddingVertical: 12,
13241
13885
  borderTopWidth: 1,
13242
- borderTopColor: "#E5E7EB",
13243
- backgroundColor: "#F9FAFB"
13886
+ borderTopColor: "#27272a",
13887
+ backgroundColor: "#09090b"
13244
13888
  },
13245
13889
  footerText: {
13246
13890
  fontSize: 12,
13247
- color: "#9CA3AF"
13891
+ color: "#52525b"
13248
13892
  },
13249
13893
  refreshText: {
13250
13894
  fontSize: 12,
13251
- color: "#6B7280"
13895
+ color: "#71717a"
13252
13896
  },
13253
13897
  emptyState: {
13254
13898
  alignItems: "center",
@@ -13260,7 +13904,7 @@ var styles = import_react_native2.StyleSheet.create({
13260
13904
  emptyTitle: {
13261
13905
  fontSize: 18,
13262
13906
  fontWeight: "600",
13263
- color: "#374151",
13907
+ color: "#e4e4e7",
13264
13908
  marginTop: 12
13265
13909
  },
13266
13910
  passedEmoji: {
@@ -13275,26 +13919,26 @@ var styles = import_react_native2.StyleSheet.create({
13275
13919
  },
13276
13920
  emptySubtitle: {
13277
13921
  fontSize: 14,
13278
- color: "#9CA3AF",
13922
+ color: "#71717a",
13279
13923
  marginTop: 4
13280
13924
  },
13281
13925
  // List view styles
13282
13926
  listHeader: {
13283
13927
  fontSize: 12,
13284
- color: "#6B7280",
13928
+ color: "#71717a",
13285
13929
  marginBottom: 12
13286
13930
  },
13287
13931
  listItem: {
13288
- backgroundColor: "#F9FAFB",
13932
+ backgroundColor: "#27272a",
13289
13933
  borderRadius: 12,
13290
13934
  padding: 12,
13291
13935
  marginBottom: 8,
13292
13936
  borderWidth: 1,
13293
- borderColor: "#E5E7EB"
13937
+ borderColor: "#3f3f46"
13294
13938
  },
13295
13939
  listItemCurrent: {
13296
- backgroundColor: "#EDE9FE",
13297
- borderColor: "#C4B5FD"
13940
+ backgroundColor: "#1e3a5f",
13941
+ borderColor: "#3B82F6"
13298
13942
  },
13299
13943
  listItemHeader: {
13300
13944
  flexDirection: "row",
@@ -13305,7 +13949,7 @@ var styles = import_react_native2.StyleSheet.create({
13305
13949
  listItemKey: {
13306
13950
  fontSize: 12,
13307
13951
  fontFamily: import_react_native2.Platform.OS === "ios" ? "Menlo" : "monospace",
13308
- color: "#6B7280"
13952
+ color: "#71717a"
13309
13953
  },
13310
13954
  listItemBadges: {
13311
13955
  flexDirection: "row",
@@ -13314,7 +13958,7 @@ var styles = import_react_native2.StyleSheet.create({
13314
13958
  listItemTitle: {
13315
13959
  fontSize: 14,
13316
13960
  fontWeight: "600",
13317
- color: "#111827",
13961
+ color: "#fafafa",
13318
13962
  marginBottom: 4
13319
13963
  },
13320
13964
  listItemMeta: {
@@ -13323,11 +13967,11 @@ var styles = import_react_native2.StyleSheet.create({
13323
13967
  },
13324
13968
  listItemMetaText: {
13325
13969
  fontSize: 12,
13326
- color: "#9CA3AF"
13970
+ color: "#71717a"
13327
13971
  },
13328
13972
  currentBadge: {
13329
13973
  fontSize: 12,
13330
- color: "#7C3AED",
13974
+ color: "#3B82F6",
13331
13975
  fontWeight: "600",
13332
13976
  marginLeft: 8
13333
13977
  },
@@ -13337,15 +13981,17 @@ var styles = import_react_native2.StyleSheet.create({
13337
13981
  },
13338
13982
  backButtonText: {
13339
13983
  fontSize: 14,
13340
- color: "#7C3AED",
13984
+ color: "#3B82F6",
13341
13985
  fontWeight: "500"
13342
13986
  },
13343
13987
  // Test card styles
13344
13988
  testCard: {
13345
- backgroundColor: "#F9FAFB",
13989
+ backgroundColor: "#27272a",
13346
13990
  borderRadius: 12,
13347
13991
  padding: 16,
13348
- marginBottom: 16
13992
+ marginBottom: 16,
13993
+ borderWidth: 1,
13994
+ borderColor: "#3f3f46"
13349
13995
  },
13350
13996
  testHeader: {
13351
13997
  flexDirection: "row",
@@ -13360,7 +14006,7 @@ var styles = import_react_native2.StyleSheet.create({
13360
14006
  testKey: {
13361
14007
  fontSize: 12,
13362
14008
  fontFamily: import_react_native2.Platform.OS === "ios" ? "Menlo" : "monospace",
13363
- color: "#6B7280"
14009
+ color: "#71717a"
13364
14010
  },
13365
14011
  trackBadge: {
13366
14012
  paddingHorizontal: 6,
@@ -13372,38 +14018,38 @@ var styles = import_react_native2.StyleSheet.create({
13372
14018
  color: "#fff"
13373
14019
  },
13374
14020
  priorityBadge: {
13375
- backgroundColor: "#E5E7EB",
14021
+ backgroundColor: "#3f3f46",
13376
14022
  paddingHorizontal: 8,
13377
14023
  paddingVertical: 2,
13378
14024
  borderRadius: 4
13379
14025
  },
13380
14026
  priorityP0: {
13381
- backgroundColor: "#FEE2E2"
14027
+ backgroundColor: "#7f1d1d"
13382
14028
  },
13383
14029
  priorityP1: {
13384
- backgroundColor: "#FED7AA"
14030
+ backgroundColor: "#78350f"
13385
14031
  },
13386
14032
  priorityText: {
13387
14033
  fontSize: 12,
13388
14034
  fontWeight: "600",
13389
- color: "#374151"
14035
+ color: "#e4e4e7"
13390
14036
  },
13391
14037
  testTitle: {
13392
14038
  fontSize: 16,
13393
14039
  fontWeight: "600",
13394
- color: "#111827",
14040
+ color: "#fafafa",
13395
14041
  marginBottom: 4
13396
14042
  },
13397
14043
  testDescription: {
13398
14044
  fontSize: 14,
13399
- color: "#6B7280",
14045
+ color: "#a1a1aa",
13400
14046
  marginBottom: 8
13401
14047
  },
13402
14048
  // Navigate button
13403
14049
  navigateButton: {
13404
- backgroundColor: "#EFF6FF",
14050
+ backgroundColor: "#1e3a5f",
13405
14051
  borderWidth: 1,
13406
- borderColor: "#BFDBFE",
14052
+ borderColor: "#3B82F6",
13407
14053
  borderRadius: 8,
13408
14054
  paddingVertical: 10,
13409
14055
  paddingHorizontal: 16,
@@ -13413,7 +14059,7 @@ var styles = import_react_native2.StyleSheet.create({
13413
14059
  navigateButtonText: {
13414
14060
  fontSize: 14,
13415
14061
  fontWeight: "500",
13416
- color: "#1D4ED8"
14062
+ color: "#60a5fa"
13417
14063
  },
13418
14064
  // Template badge
13419
14065
  templateBadge: {
@@ -13431,12 +14077,12 @@ var styles = import_react_native2.StyleSheet.create({
13431
14077
  templateName: {
13432
14078
  fontSize: 12,
13433
14079
  fontWeight: "600",
13434
- color: "#374151",
14080
+ color: "#e4e4e7",
13435
14081
  marginRight: 4
13436
14082
  },
13437
14083
  templateAction: {
13438
14084
  fontSize: 12,
13439
- color: "#6B7280"
14085
+ color: "#71717a"
13440
14086
  },
13441
14087
  // Steps toggle
13442
14088
  stepsToggle: {
@@ -13444,7 +14090,7 @@ var styles = import_react_native2.StyleSheet.create({
13444
14090
  },
13445
14091
  stepsToggleText: {
13446
14092
  fontSize: 14,
13447
- color: "#7C3AED",
14093
+ color: "#3B82F6",
13448
14094
  fontWeight: "500"
13449
14095
  },
13450
14096
  stepsList: {
@@ -13458,7 +14104,7 @@ var styles = import_react_native2.StyleSheet.create({
13458
14104
  width: 24,
13459
14105
  height: 24,
13460
14106
  borderRadius: 12,
13461
- backgroundColor: "#EDE9FE",
14107
+ backgroundColor: "#1e3a5f",
13462
14108
  justifyContent: "center",
13463
14109
  alignItems: "center",
13464
14110
  marginRight: 12
@@ -13466,41 +14112,41 @@ var styles = import_react_native2.StyleSheet.create({
13466
14112
  stepNumberText: {
13467
14113
  fontSize: 12,
13468
14114
  fontWeight: "600",
13469
- color: "#7C3AED"
14115
+ color: "#3B82F6"
13470
14116
  },
13471
14117
  stepContent: {
13472
14118
  flex: 1
13473
14119
  },
13474
14120
  stepAction: {
13475
14121
  fontSize: 14,
13476
- color: "#374151"
14122
+ color: "#e4e4e7"
13477
14123
  },
13478
14124
  stepExpected: {
13479
14125
  fontSize: 12,
13480
- color: "#9CA3AF",
14126
+ color: "#71717a",
13481
14127
  marginTop: 2
13482
14128
  },
13483
14129
  // Checklist styles
13484
14130
  checklistItem: {
13485
14131
  flexDirection: "row",
13486
14132
  alignItems: "center",
13487
- backgroundColor: "#fff",
14133
+ backgroundColor: "#27272a",
13488
14134
  borderWidth: 1,
13489
- borderColor: "#E5E7EB",
14135
+ borderColor: "#3f3f46",
13490
14136
  borderRadius: 8,
13491
14137
  padding: 12,
13492
14138
  marginBottom: 8
13493
14139
  },
13494
14140
  checklistItemChecked: {
13495
- backgroundColor: "#ECFDF5",
13496
- borderColor: "#86EFAC"
14141
+ backgroundColor: "#14532d",
14142
+ borderColor: "#22C55E"
13497
14143
  },
13498
14144
  checkbox: {
13499
14145
  width: 24,
13500
14146
  height: 24,
13501
14147
  borderRadius: 4,
13502
14148
  borderWidth: 2,
13503
- borderColor: "#22D3EE",
14149
+ borderColor: "#3B82F6",
13504
14150
  marginRight: 12,
13505
14151
  justifyContent: "center",
13506
14152
  alignItems: "center"
@@ -13517,16 +14163,16 @@ var styles = import_react_native2.StyleSheet.create({
13517
14163
  checklistText: {
13518
14164
  flex: 1,
13519
14165
  fontSize: 14,
13520
- color: "#374151"
14166
+ color: "#e4e4e7"
13521
14167
  },
13522
14168
  checklistTextChecked: {
13523
- color: "#15803D"
14169
+ color: "#4ade80"
13524
14170
  },
13525
14171
  // Rubric styles
13526
14172
  rubricItem: {
13527
- backgroundColor: "#fff",
14173
+ backgroundColor: "#27272a",
13528
14174
  borderWidth: 1,
13529
- borderColor: "#E5E7EB",
14175
+ borderColor: "#3f3f46",
13530
14176
  borderRadius: 8,
13531
14177
  padding: 12,
13532
14178
  marginBottom: 8
@@ -13540,7 +14186,7 @@ var styles = import_react_native2.StyleSheet.create({
13540
14186
  width: 24,
13541
14187
  height: 24,
13542
14188
  borderRadius: 4,
13543
- backgroundColor: "#EDE9FE",
14189
+ backgroundColor: "#1e3a5f",
13544
14190
  justifyContent: "center",
13545
14191
  alignItems: "center",
13546
14192
  marginRight: 8
@@ -13548,17 +14194,17 @@ var styles = import_react_native2.StyleSheet.create({
13548
14194
  rubricNumberText: {
13549
14195
  fontSize: 12,
13550
14196
  fontWeight: "600",
13551
- color: "#7C3AED"
14197
+ color: "#3B82F6"
13552
14198
  },
13553
14199
  rubricTitle: {
13554
14200
  flex: 1,
13555
14201
  fontSize: 14,
13556
14202
  fontWeight: "500",
13557
- color: "#111827"
14203
+ color: "#fafafa"
13558
14204
  },
13559
14205
  rubricExpected: {
13560
14206
  fontSize: 12,
13561
- color: "#6B7280",
14207
+ color: "#71717a",
13562
14208
  marginLeft: 32,
13563
14209
  marginBottom: 8
13564
14210
  },
@@ -13572,7 +14218,7 @@ var styles = import_react_native2.StyleSheet.create({
13572
14218
  paddingVertical: 8,
13573
14219
  paddingHorizontal: 12,
13574
14220
  borderRadius: 6,
13575
- backgroundColor: "#F3F4F6",
14221
+ backgroundColor: "#3f3f46",
13576
14222
  alignItems: "center"
13577
14223
  },
13578
14224
  passButtonActive: {
@@ -13584,7 +14230,7 @@ var styles = import_react_native2.StyleSheet.create({
13584
14230
  passFailButtonText: {
13585
14231
  fontSize: 12,
13586
14232
  fontWeight: "600",
13587
- color: "#6B7280"
14233
+ color: "#a1a1aa"
13588
14234
  },
13589
14235
  passButtonTextActive: {
13590
14236
  color: "#fff"
@@ -13601,17 +14247,17 @@ var styles = import_react_native2.StyleSheet.create({
13601
14247
  width: 36,
13602
14248
  height: 36,
13603
14249
  borderRadius: 6,
13604
- backgroundColor: "#F3F4F6",
14250
+ backgroundColor: "#3f3f46",
13605
14251
  justifyContent: "center",
13606
14252
  alignItems: "center"
13607
14253
  },
13608
14254
  ratingButtonActive: {
13609
- backgroundColor: "#7C3AED"
14255
+ backgroundColor: "#3B82F6"
13610
14256
  },
13611
14257
  ratingButtonText: {
13612
14258
  fontSize: 14,
13613
14259
  fontWeight: "600",
13614
- color: "#6B7280"
14260
+ color: "#a1a1aa"
13615
14261
  },
13616
14262
  ratingButtonTextActive: {
13617
14263
  color: "#fff"
@@ -13625,17 +14271,17 @@ var styles = import_react_native2.StyleSheet.create({
13625
14271
  },
13626
14272
  helperText: {
13627
14273
  fontSize: 12,
13628
- color: "#9CA3AF"
14274
+ color: "#71717a"
13629
14275
  },
13630
14276
  resetText: {
13631
14277
  fontSize: 12,
13632
- color: "#9CA3AF"
14278
+ color: "#71717a"
13633
14279
  },
13634
14280
  // Freeform styles
13635
14281
  freeformBox: {
13636
- backgroundColor: "#FFFBEB",
14282
+ backgroundColor: "#422006",
13637
14283
  borderWidth: 1,
13638
- borderColor: "#FDE68A",
14284
+ borderColor: "#a16207",
13639
14285
  borderRadius: 8,
13640
14286
  padding: 12,
13641
14287
  marginTop: 8
@@ -13643,22 +14289,22 @@ var styles = import_react_native2.StyleSheet.create({
13643
14289
  freeformTitle: {
13644
14290
  fontSize: 14,
13645
14291
  fontWeight: "600",
13646
- color: "#92400E",
14292
+ color: "#fbbf24",
13647
14293
  marginBottom: 4
13648
14294
  },
13649
14295
  freeformText: {
13650
14296
  fontSize: 12,
13651
- color: "#A16207",
14297
+ color: "#fcd34d",
13652
14298
  marginBottom: 4
13653
14299
  },
13654
14300
  freeformBullet: {
13655
14301
  fontSize: 12,
13656
- color: "#A16207",
14302
+ color: "#fcd34d",
13657
14303
  marginLeft: 8
13658
14304
  },
13659
14305
  // Expected result
13660
14306
  expectedResult: {
13661
- backgroundColor: "#ECFDF5",
14307
+ backgroundColor: "#14532d",
13662
14308
  padding: 12,
13663
14309
  borderRadius: 8,
13664
14310
  marginTop: 12
@@ -13666,12 +14312,12 @@ var styles = import_react_native2.StyleSheet.create({
13666
14312
  expectedLabel: {
13667
14313
  fontSize: 12,
13668
14314
  fontWeight: "600",
13669
- color: "#065F46",
14315
+ color: "#4ade80",
13670
14316
  marginBottom: 4
13671
14317
  },
13672
14318
  expectedText: {
13673
14319
  fontSize: 14,
13674
- color: "#047857"
14320
+ color: "#86efac"
13675
14321
  },
13676
14322
  // Action buttons
13677
14323
  actionButtons: {
@@ -13680,7 +14326,7 @@ var styles = import_react_native2.StyleSheet.create({
13680
14326
  },
13681
14327
  failButton: {
13682
14328
  flex: 1,
13683
- backgroundColor: "#FEE2E2",
14329
+ backgroundColor: "#7f1d1d",
13684
14330
  paddingVertical: 14,
13685
14331
  borderRadius: 12,
13686
14332
  alignItems: "center"
@@ -13688,7 +14334,7 @@ var styles = import_react_native2.StyleSheet.create({
13688
14334
  failButtonText: {
13689
14335
  fontSize: 16,
13690
14336
  fontWeight: "600",
13691
- color: "#DC2626"
14337
+ color: "#fca5a5"
13692
14338
  },
13693
14339
  passButton: {
13694
14340
  flex: 1,
@@ -13710,22 +14356,22 @@ var styles = import_react_native2.StyleSheet.create({
13710
14356
  },
13711
14357
  reportTypeButton: {
13712
14358
  flex: 1,
13713
- backgroundColor: "#F3F4F6",
14359
+ backgroundColor: "#3f3f46",
13714
14360
  paddingVertical: 10,
13715
14361
  borderRadius: 8,
13716
14362
  alignItems: "center"
13717
14363
  },
13718
14364
  reportTypeActive: {
13719
- backgroundColor: "#EDE9FE",
14365
+ backgroundColor: "#1e3a5f",
13720
14366
  borderWidth: 2,
13721
- borderColor: "#7C3AED"
14367
+ borderColor: "#3B82F6"
13722
14368
  },
13723
14369
  reportTypeText: {
13724
14370
  fontSize: 14,
13725
- color: "#6B7280"
14371
+ color: "#a1a1aa"
13726
14372
  },
13727
14373
  reportTypeTextActive: {
13728
- color: "#7C3AED",
14374
+ color: "#3B82F6",
13729
14375
  fontWeight: "600"
13730
14376
  },
13731
14377
  severitySection: {
@@ -13734,7 +14380,7 @@ var styles = import_react_native2.StyleSheet.create({
13734
14380
  label: {
13735
14381
  fontSize: 14,
13736
14382
  fontWeight: "500",
13737
- color: "#374151",
14383
+ color: "#e4e4e7",
13738
14384
  marginBottom: 8
13739
14385
  },
13740
14386
  severityButtons: {
@@ -13743,7 +14389,7 @@ var styles = import_react_native2.StyleSheet.create({
13743
14389
  },
13744
14390
  severityButton: {
13745
14391
  flex: 1,
13746
- backgroundColor: "#F3F4F6",
14392
+ backgroundColor: "#3f3f46",
13747
14393
  paddingVertical: 8,
13748
14394
  borderRadius: 6,
13749
14395
  alignItems: "center"
@@ -13762,7 +14408,7 @@ var styles = import_react_native2.StyleSheet.create({
13762
14408
  },
13763
14409
  severityText: {
13764
14410
  fontSize: 12,
13765
- color: "#6B7280",
14411
+ color: "#a1a1aa",
13766
14412
  textTransform: "capitalize"
13767
14413
  },
13768
14414
  severityTextActive: {
@@ -13773,17 +14419,17 @@ var styles = import_react_native2.StyleSheet.create({
13773
14419
  marginBottom: 16
13774
14420
  },
13775
14421
  textInput: {
13776
- backgroundColor: "#F9FAFB",
14422
+ backgroundColor: "#27272a",
13777
14423
  borderWidth: 1,
13778
- borderColor: "#E5E7EB",
14424
+ borderColor: "#3f3f46",
13779
14425
  borderRadius: 12,
13780
14426
  padding: 12,
13781
14427
  fontSize: 14,
13782
14428
  minHeight: 100,
13783
- color: "#111827"
14429
+ color: "#fafafa"
13784
14430
  },
13785
14431
  submitButton: {
13786
- backgroundColor: "#7C3AED",
14432
+ backgroundColor: "#3B82F6",
13787
14433
  paddingVertical: 14,
13788
14434
  borderRadius: 12,
13789
14435
  alignItems: "center"
@@ -13822,16 +14468,16 @@ var styles = import_react_native2.StyleSheet.create({
13822
14468
  },
13823
14469
  // Thread list styles
13824
14470
  threadItem: {
13825
- backgroundColor: "#F9FAFB",
14471
+ backgroundColor: "#27272a",
13826
14472
  borderRadius: 12,
13827
14473
  padding: 12,
13828
14474
  marginBottom: 8,
13829
14475
  borderWidth: 1,
13830
- borderColor: "#E5E7EB"
14476
+ borderColor: "#3f3f46"
13831
14477
  },
13832
14478
  threadItemUnread: {
13833
- backgroundColor: "#EFF6FF",
13834
- borderColor: "#BFDBFE"
14479
+ backgroundColor: "#1e3a5f",
14480
+ borderColor: "#3B82F6"
13835
14481
  },
13836
14482
  threadHeader: {
13837
14483
  flexDirection: "row",
@@ -13855,12 +14501,12 @@ var styles = import_react_native2.StyleSheet.create({
13855
14501
  threadSubject: {
13856
14502
  fontSize: 14,
13857
14503
  fontWeight: "500",
13858
- color: "#374151",
14504
+ color: "#e4e4e7",
13859
14505
  flex: 1
13860
14506
  },
13861
14507
  threadSubjectUnread: {
13862
14508
  fontWeight: "600",
13863
- color: "#111827"
14509
+ color: "#fafafa"
13864
14510
  },
13865
14511
  priorityDot: {
13866
14512
  width: 8,
@@ -13870,7 +14516,7 @@ var styles = import_react_native2.StyleSheet.create({
13870
14516
  },
13871
14517
  threadPreview: {
13872
14518
  fontSize: 13,
13873
- color: "#6B7280",
14519
+ color: "#a1a1aa",
13874
14520
  marginBottom: 4
13875
14521
  },
13876
14522
  threadMeta: {
@@ -13880,7 +14526,7 @@ var styles = import_react_native2.StyleSheet.create({
13880
14526
  },
13881
14527
  threadMetaText: {
13882
14528
  fontSize: 12,
13883
- color: "#9CA3AF"
14529
+ color: "#71717a"
13884
14530
  },
13885
14531
  unreadBadge: {
13886
14532
  backgroundColor: "#3B82F6",
@@ -13895,7 +14541,7 @@ var styles = import_react_native2.StyleSheet.create({
13895
14541
  },
13896
14542
  threadTime: {
13897
14543
  fontSize: 12,
13898
- color: "#9CA3AF"
14544
+ color: "#71717a"
13899
14545
  },
13900
14546
  // Thread detail styles
13901
14547
  threadDetailContainer: {
@@ -13904,7 +14550,7 @@ var styles = import_react_native2.StyleSheet.create({
13904
14550
  threadDetailHeader: {
13905
14551
  flexDirection: "row",
13906
14552
  alignItems: "center",
13907
- backgroundColor: "#F3F4F6",
14553
+ backgroundColor: "#27272a",
13908
14554
  padding: 12,
13909
14555
  borderRadius: 8,
13910
14556
  marginBottom: 12
@@ -13917,7 +14563,7 @@ var styles = import_react_native2.StyleSheet.create({
13917
14563
  flex: 1,
13918
14564
  fontSize: 15,
13919
14565
  fontWeight: "600",
13920
- color: "#111827"
14566
+ color: "#fafafa"
13921
14567
  },
13922
14568
  loadingMessages: {
13923
14569
  padding: 20,
@@ -13925,7 +14571,7 @@ var styles = import_react_native2.StyleSheet.create({
13925
14571
  },
13926
14572
  loadingText: {
13927
14573
  fontSize: 14,
13928
- color: "#6B7280"
14574
+ color: "#71717a"
13929
14575
  },
13930
14576
  messagesContainer: {
13931
14577
  paddingBottom: 8
@@ -13938,26 +14584,26 @@ var styles = import_react_native2.StyleSheet.create({
13938
14584
  },
13939
14585
  messageBubbleAdmin: {
13940
14586
  alignSelf: "flex-start",
13941
- backgroundColor: "#F3F4F6",
14587
+ backgroundColor: "#27272a",
13942
14588
  borderBottomLeftRadius: 4
13943
14589
  },
13944
14590
  messageBubbleTester: {
13945
14591
  alignSelf: "flex-end",
13946
- backgroundColor: "#7C3AED",
14592
+ backgroundColor: "#3B82F6",
13947
14593
  borderBottomRightRadius: 4
13948
14594
  },
13949
14595
  messageSender: {
13950
14596
  fontSize: 12,
13951
14597
  fontWeight: "600",
13952
- color: "#6B7280",
14598
+ color: "#71717a",
13953
14599
  marginBottom: 2
13954
14600
  },
13955
14601
  messageSenderTester: {
13956
- color: "#DDD6FE"
14602
+ color: "#93c5fd"
13957
14603
  },
13958
14604
  messageContent: {
13959
14605
  fontSize: 14,
13960
- color: "#111827",
14606
+ color: "#fafafa",
13961
14607
  lineHeight: 20
13962
14608
  },
13963
14609
  messageContentTester: {
@@ -13965,12 +14611,12 @@ var styles = import_react_native2.StyleSheet.create({
13965
14611
  },
13966
14612
  messageTime: {
13967
14613
  fontSize: 11,
13968
- color: "#9CA3AF",
14614
+ color: "#71717a",
13969
14615
  marginTop: 4,
13970
14616
  textAlign: "right"
13971
14617
  },
13972
14618
  messageTimeTester: {
13973
- color: "#C4B5FD"
14619
+ color: "#93c5fd"
13974
14620
  },
13975
14621
  // Reply composer styles
13976
14622
  replyComposer: {
@@ -13978,24 +14624,24 @@ var styles = import_react_native2.StyleSheet.create({
13978
14624
  alignItems: "flex-end",
13979
14625
  padding: 12,
13980
14626
  borderTopWidth: 1,
13981
- borderTopColor: "#E5E7EB",
13982
- backgroundColor: "#fff"
14627
+ borderTopColor: "#27272a",
14628
+ backgroundColor: "#18181b"
13983
14629
  },
13984
14630
  replyInput: {
13985
14631
  flex: 1,
13986
- backgroundColor: "#F9FAFB",
14632
+ backgroundColor: "#27272a",
13987
14633
  borderWidth: 1,
13988
- borderColor: "#E5E7EB",
14634
+ borderColor: "#3f3f46",
13989
14635
  borderRadius: 20,
13990
14636
  paddingHorizontal: 16,
13991
14637
  paddingVertical: 10,
13992
14638
  fontSize: 14,
13993
- color: "#111827",
14639
+ color: "#fafafa",
13994
14640
  maxHeight: 100,
13995
14641
  marginRight: 8
13996
14642
  },
13997
14643
  sendButton: {
13998
- backgroundColor: "#7C3AED",
14644
+ backgroundColor: "#3B82F6",
13999
14645
  paddingHorizontal: 16,
14000
14646
  paddingVertical: 10,
14001
14647
  borderRadius: 20,
@@ -14003,7 +14649,7 @@ var styles = import_react_native2.StyleSheet.create({
14003
14649
  alignItems: "center"
14004
14650
  },
14005
14651
  sendButtonDisabled: {
14006
- backgroundColor: "#C4B5FD"
14652
+ backgroundColor: "#1e40af"
14007
14653
  },
14008
14654
  sendButtonText: {
14009
14655
  fontSize: 14,
@@ -14015,7 +14661,7 @@ var styles = import_react_native2.StyleSheet.create({
14015
14661
  flexDirection: "row",
14016
14662
  alignItems: "center",
14017
14663
  justifyContent: "center",
14018
- backgroundColor: "#7C3AED",
14664
+ backgroundColor: "#3B82F6",
14019
14665
  paddingVertical: 12,
14020
14666
  paddingHorizontal: 20,
14021
14667
  borderRadius: 12,
@@ -14037,48 +14683,50 @@ var styles = import_react_native2.StyleSheet.create({
14037
14683
  composeTitle: {
14038
14684
  fontSize: 20,
14039
14685
  fontWeight: "600",
14040
- color: "#111827",
14686
+ color: "#fafafa",
14041
14687
  marginBottom: 4
14042
14688
  },
14043
14689
  composeSubtitle: {
14044
14690
  fontSize: 14,
14045
- color: "#6B7280"
14691
+ color: "#71717a"
14046
14692
  },
14047
14693
  composeForm: {
14048
- backgroundColor: "#F9FAFB",
14694
+ backgroundColor: "#27272a",
14049
14695
  borderRadius: 12,
14050
- padding: 16
14696
+ padding: 16,
14697
+ borderWidth: 1,
14698
+ borderColor: "#3f3f46"
14051
14699
  },
14052
14700
  composeSubjectInput: {
14053
- backgroundColor: "#fff",
14701
+ backgroundColor: "#18181b",
14054
14702
  borderWidth: 1,
14055
- borderColor: "#E5E7EB",
14703
+ borderColor: "#3f3f46",
14056
14704
  borderRadius: 8,
14057
14705
  paddingHorizontal: 12,
14058
14706
  paddingVertical: 10,
14059
14707
  fontSize: 15,
14060
- color: "#111827"
14708
+ color: "#fafafa"
14061
14709
  },
14062
14710
  composeMessageInput: {
14063
- backgroundColor: "#fff",
14711
+ backgroundColor: "#18181b",
14064
14712
  borderWidth: 1,
14065
- borderColor: "#E5E7EB",
14713
+ borderColor: "#3f3f46",
14066
14714
  borderRadius: 8,
14067
14715
  paddingHorizontal: 12,
14068
14716
  paddingVertical: 10,
14069
14717
  fontSize: 15,
14070
- color: "#111827",
14718
+ color: "#fafafa",
14071
14719
  minHeight: 120
14072
14720
  },
14073
14721
  composeSendButton: {
14074
- backgroundColor: "#7C3AED",
14722
+ backgroundColor: "#3B82F6",
14075
14723
  paddingVertical: 14,
14076
14724
  borderRadius: 12,
14077
14725
  alignItems: "center",
14078
14726
  marginTop: 20
14079
14727
  },
14080
14728
  composeSendButtonDisabled: {
14081
- backgroundColor: "#C4B5FD"
14729
+ backgroundColor: "#1e40af"
14082
14730
  },
14083
14731
  composeSendButtonText: {
14084
14732
  fontSize: 16,
@@ -14087,17 +14735,19 @@ var styles = import_react_native2.StyleSheet.create({
14087
14735
  },
14088
14736
  // Profile styles
14089
14737
  profileCard: {
14090
- backgroundColor: "#F9FAFB",
14738
+ backgroundColor: "#27272a",
14091
14739
  borderRadius: 16,
14092
14740
  padding: 24,
14093
14741
  alignItems: "center",
14094
- marginBottom: 16
14742
+ marginBottom: 16,
14743
+ borderWidth: 1,
14744
+ borderColor: "#3f3f46"
14095
14745
  },
14096
14746
  avatarCircle: {
14097
14747
  width: 72,
14098
14748
  height: 72,
14099
14749
  borderRadius: 36,
14100
- backgroundColor: "#7C3AED",
14750
+ backgroundColor: "#3B82F6",
14101
14751
  justifyContent: "center",
14102
14752
  alignItems: "center",
14103
14753
  marginBottom: 12
@@ -14110,12 +14760,12 @@ var styles = import_react_native2.StyleSheet.create({
14110
14760
  profileName: {
14111
14761
  fontSize: 20,
14112
14762
  fontWeight: "600",
14113
- color: "#111827",
14763
+ color: "#fafafa",
14114
14764
  marginBottom: 4
14115
14765
  },
14116
14766
  profileEmail: {
14117
14767
  fontSize: 14,
14118
- color: "#6B7280",
14768
+ color: "#71717a",
14119
14769
  marginBottom: 16
14120
14770
  },
14121
14771
  profileStats: {
@@ -14129,35 +14779,37 @@ var styles = import_react_native2.StyleSheet.create({
14129
14779
  profileStatValue: {
14130
14780
  fontSize: 24,
14131
14781
  fontWeight: "700",
14132
- color: "#7C3AED"
14782
+ color: "#3B82F6"
14133
14783
  },
14134
14784
  profileStatLabel: {
14135
14785
  fontSize: 12,
14136
- color: "#6B7280",
14786
+ color: "#71717a",
14137
14787
  marginTop: 2
14138
14788
  },
14139
14789
  profileStatDivider: {
14140
14790
  width: 1,
14141
14791
  height: 32,
14142
- backgroundColor: "#E5E7EB"
14792
+ backgroundColor: "#3f3f46"
14143
14793
  },
14144
14794
  profileInfoSection: {
14145
- backgroundColor: "#F9FAFB",
14795
+ backgroundColor: "#27272a",
14146
14796
  borderRadius: 12,
14147
14797
  padding: 16,
14148
- marginBottom: 12
14798
+ marginBottom: 12,
14799
+ borderWidth: 1,
14800
+ borderColor: "#3f3f46"
14149
14801
  },
14150
14802
  profileInfoLabel: {
14151
14803
  fontSize: 12,
14152
14804
  fontWeight: "600",
14153
- color: "#6B7280",
14805
+ color: "#71717a",
14154
14806
  marginBottom: 8,
14155
14807
  textTransform: "uppercase",
14156
14808
  letterSpacing: 0.5
14157
14809
  },
14158
14810
  profileInfoValue: {
14159
14811
  fontSize: 14,
14160
- color: "#374151",
14812
+ color: "#e4e4e7",
14161
14813
  marginBottom: 4
14162
14814
  },
14163
14815
  platformTags: {
@@ -14166,18 +14818,18 @@ var styles = import_react_native2.StyleSheet.create({
14166
14818
  gap: 8
14167
14819
  },
14168
14820
  platformTag: {
14169
- backgroundColor: "#EDE9FE",
14821
+ backgroundColor: "#1e3a5f",
14170
14822
  paddingHorizontal: 12,
14171
14823
  paddingVertical: 6,
14172
14824
  borderRadius: 16
14173
14825
  },
14174
14826
  platformTagText: {
14175
14827
  fontSize: 13,
14176
- color: "#7C3AED",
14828
+ color: "#60a5fa",
14177
14829
  fontWeight: "500"
14178
14830
  },
14179
14831
  editProfileButton: {
14180
- backgroundColor: "#7C3AED",
14832
+ backgroundColor: "#3B82F6",
14181
14833
  paddingVertical: 14,
14182
14834
  borderRadius: 12,
14183
14835
  alignItems: "center",
@@ -14198,48 +14850,48 @@ var styles = import_react_native2.StyleSheet.create({
14198
14850
  profileEditTitle: {
14199
14851
  fontSize: 20,
14200
14852
  fontWeight: "600",
14201
- color: "#111827"
14853
+ color: "#fafafa"
14202
14854
  },
14203
14855
  cancelText: {
14204
14856
  fontSize: 14,
14205
- color: "#6B7280"
14857
+ color: "#71717a"
14206
14858
  },
14207
14859
  profileSection: {
14208
14860
  marginBottom: 20
14209
14861
  },
14210
14862
  profileInput: {
14211
- backgroundColor: "#F9FAFB",
14863
+ backgroundColor: "#27272a",
14212
14864
  borderWidth: 1,
14213
- borderColor: "#E5E7EB",
14865
+ borderColor: "#3f3f46",
14214
14866
  borderRadius: 10,
14215
14867
  paddingHorizontal: 14,
14216
14868
  paddingVertical: 12,
14217
14869
  fontSize: 15,
14218
- color: "#111827"
14870
+ color: "#fafafa"
14219
14871
  },
14220
14872
  profileReadOnly: {
14221
- backgroundColor: "#F3F4F6",
14873
+ backgroundColor: "#27272a",
14222
14874
  borderRadius: 10,
14223
14875
  padding: 14
14224
14876
  },
14225
14877
  profileReadOnlyText: {
14226
14878
  fontSize: 15,
14227
- color: "#374151"
14879
+ color: "#a1a1aa"
14228
14880
  },
14229
14881
  profileReadOnlyHint: {
14230
14882
  fontSize: 12,
14231
- color: "#9CA3AF",
14883
+ color: "#52525b",
14232
14884
  marginTop: 4
14233
14885
  },
14234
14886
  profileHint: {
14235
14887
  fontSize: 13,
14236
- color: "#6B7280",
14888
+ color: "#71717a",
14237
14889
  marginBottom: 12
14238
14890
  },
14239
14891
  emailChip: {
14240
14892
  flexDirection: "row",
14241
14893
  alignItems: "center",
14242
- backgroundColor: "#EDE9FE",
14894
+ backgroundColor: "#1e3a5f",
14243
14895
  paddingHorizontal: 12,
14244
14896
  paddingVertical: 8,
14245
14897
  borderRadius: 20,
@@ -14248,11 +14900,11 @@ var styles = import_react_native2.StyleSheet.create({
14248
14900
  emailChipText: {
14249
14901
  flex: 1,
14250
14902
  fontSize: 14,
14251
- color: "#5B21B6"
14903
+ color: "#60a5fa"
14252
14904
  },
14253
14905
  emailChipRemove: {
14254
14906
  fontSize: 14,
14255
- color: "#8B5CF6",
14907
+ color: "#93c5fd",
14256
14908
  fontWeight: "600",
14257
14909
  marginLeft: 8
14258
14910
  },
@@ -14262,23 +14914,23 @@ var styles = import_react_native2.StyleSheet.create({
14262
14914
  },
14263
14915
  addEmailInput: {
14264
14916
  flex: 1,
14265
- backgroundColor: "#F9FAFB",
14917
+ backgroundColor: "#27272a",
14266
14918
  borderWidth: 1,
14267
- borderColor: "#E5E7EB",
14919
+ borderColor: "#3f3f46",
14268
14920
  borderRadius: 10,
14269
14921
  paddingHorizontal: 14,
14270
14922
  paddingVertical: 10,
14271
14923
  fontSize: 14,
14272
- color: "#111827"
14924
+ color: "#fafafa"
14273
14925
  },
14274
14926
  addEmailButton: {
14275
- backgroundColor: "#7C3AED",
14927
+ backgroundColor: "#3B82F6",
14276
14928
  paddingHorizontal: 16,
14277
14929
  borderRadius: 10,
14278
14930
  justifyContent: "center"
14279
14931
  },
14280
14932
  addEmailButtonDisabled: {
14281
- backgroundColor: "#C4B5FD"
14933
+ backgroundColor: "#1e40af"
14282
14934
  },
14283
14935
  addEmailButtonText: {
14284
14936
  fontSize: 14,
@@ -14291,7 +14943,7 @@ var styles = import_react_native2.StyleSheet.create({
14291
14943
  },
14292
14944
  platformButton: {
14293
14945
  flex: 1,
14294
- backgroundColor: "#F3F4F6",
14946
+ backgroundColor: "#3f3f46",
14295
14947
  paddingVertical: 12,
14296
14948
  borderRadius: 10,
14297
14949
  alignItems: "center",
@@ -14299,16 +14951,16 @@ var styles = import_react_native2.StyleSheet.create({
14299
14951
  borderColor: "transparent"
14300
14952
  },
14301
14953
  platformButtonActive: {
14302
- backgroundColor: "#EDE9FE",
14303
- borderColor: "#7C3AED"
14954
+ backgroundColor: "#1e3a5f",
14955
+ borderColor: "#3B82F6"
14304
14956
  },
14305
14957
  platformButtonText: {
14306
14958
  fontSize: 13,
14307
- color: "#6B7280",
14959
+ color: "#a1a1aa",
14308
14960
  fontWeight: "500"
14309
14961
  },
14310
14962
  platformButtonTextActive: {
14311
- color: "#7C3AED"
14963
+ color: "#3B82F6"
14312
14964
  },
14313
14965
  saveProfileButton: {
14314
14966
  backgroundColor: "#16A34A",
@@ -14332,7 +14984,7 @@ var styles = import_react_native2.StyleSheet.create({
14332
14984
  left: 0,
14333
14985
  right: 0,
14334
14986
  bottom: 0,
14335
- backgroundColor: "#fff",
14987
+ backgroundColor: "#18181b",
14336
14988
  zIndex: 100
14337
14989
  },
14338
14990
  profileOverlayContent: {
@@ -14341,9 +14993,9 @@ var styles = import_react_native2.StyleSheet.create({
14341
14993
  },
14342
14994
  profileOverlayFooter: {
14343
14995
  borderTopWidth: 1,
14344
- borderTopColor: "#E5E7EB",
14996
+ borderTopColor: "#27272a",
14345
14997
  padding: 12,
14346
- backgroundColor: "#F9FAFB"
14998
+ backgroundColor: "#09090b"
14347
14999
  },
14348
15000
  closeProfileButton: {
14349
15001
  paddingVertical: 8,
@@ -14352,7 +15004,7 @@ var styles = import_react_native2.StyleSheet.create({
14352
15004
  closeProfileButtonText: {
14353
15005
  fontSize: 14,
14354
15006
  fontWeight: "500",
14355
- color: "#7C3AED"
15007
+ color: "#3B82F6"
14356
15008
  }
14357
15009
  });
14358
15010
  // Annotate the CommonJS export names for ESM import in node: