@sendoracloud/sdk-react-native 1.2.0 → 1.3.0

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.
@@ -45,6 +45,8 @@ function ContactWidget({
45
45
  theme = "auto",
46
46
  prefillName,
47
47
  prefillEmail,
48
+ prefillUserId,
49
+ lockEmail,
48
50
  onClose
49
51
  }) {
50
52
  const didFire = React.useRef(false);
@@ -55,6 +57,8 @@ function ContactWidget({
55
57
  const params = new URLSearchParams({ widgetId, theme });
56
58
  if (prefillName) params.set("prefillName", prefillName);
57
59
  if (prefillEmail) params.set("prefillEmail", prefillEmail);
60
+ if (prefillUserId) params.set("prefillUserId", prefillUserId);
61
+ if (lockEmail && prefillEmail) params.set("lockEmail", "1");
58
62
  const uri = `${workerHost}/embed/contact?${params.toString()}`;
59
63
  const handleClose = (result) => {
60
64
  if (didFire.current) return;
@@ -103,20 +107,30 @@ function useContactWidget(widgetId, defaults) {
103
107
  const [lastResult, setLastResult] = React.useState(null);
104
108
  const open = React.useCallback(() => setVisible(true), []);
105
109
  const close = React.useCallback(() => setVisible(false), []);
110
+ const sdkUser = defaults?.user ?? null;
111
+ const resolvedName = defaults?.prefillName ?? sdkUser?.name ?? void 0;
112
+ const resolvedEmail = defaults?.prefillEmail ?? sdkUser?.email ?? void 0;
113
+ const resolvedUserId = defaults?.prefillUserId ?? sdkUser?.id ?? void 0;
114
+ const resolvedLockEmail = defaults?.lockEmail ?? (sdkUser != null && sdkUser.email != null && sdkUser.emailVerified && !sdkUser.isAnonymous);
106
115
  const View2 = React.useCallback(
107
116
  () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
108
117
  ContactWidget,
109
118
  {
110
- ...defaults,
119
+ workerHost: defaults?.workerHost,
120
+ theme: defaults?.theme,
111
121
  widgetId,
112
122
  visible,
123
+ prefillName: resolvedName,
124
+ prefillEmail: resolvedEmail,
125
+ prefillUserId: resolvedUserId,
126
+ lockEmail: resolvedLockEmail,
113
127
  onClose: (r) => {
114
128
  setLastResult(r);
115
129
  setVisible(false);
116
130
  }
117
131
  }
118
132
  ),
119
- [defaults, widgetId, visible]
133
+ [defaults, widgetId, visible, resolvedName, resolvedEmail, resolvedUserId, resolvedLockEmail]
120
134
  );
121
135
  return { open, close, View: View2, lastResult };
122
136
  }
@@ -44,6 +44,20 @@ interface ContactWidgetProps {
44
44
  prefillName?: string;
45
45
  /** Pre-fill email field for signed-in users. */
46
46
  prefillEmail?: string;
47
+ /**
48
+ * Wave 68 — stitch the ticket to the same profile as analytics
49
+ * events. Pass the signed-in user's id (anon or identified). Hint
50
+ * only, not an auth boundary — backend stores it without verifying
51
+ * because the WebView is in customer-app code.
52
+ */
53
+ prefillUserId?: string;
54
+ /**
55
+ * When true (and `prefillEmail` is set) the email field is hidden +
56
+ * read-only. Use for identified users so the agent inbox can trust
57
+ * the email field came from the customer's verified account, not
58
+ * free text.
59
+ */
60
+ lockEmail?: boolean;
47
61
  /**
48
62
  * Fired when the user closes the sheet — either after a successful
49
63
  * submit (`submitted = true`) or via the close button
@@ -51,7 +65,7 @@ interface ContactWidgetProps {
51
65
  */
52
66
  onClose: (result: ContactWidgetResult) => void;
53
67
  }
54
- declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillName, prefillEmail, onClose, }: ContactWidgetProps): React.ReactElement | null;
68
+ declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillName, prefillEmail, prefillUserId, lockEmail, onClose, }: ContactWidgetProps): React.ReactElement | null;
55
69
  /**
56
70
  * Helper hook so the host doesn't have to wire visibility state by
57
71
  * hand.
@@ -59,8 +73,27 @@ declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillNa
59
73
  * const contact = useContactWidget("widget-uuid");
60
74
  * <Button onPress={contact.open} title="Contact us" />
61
75
  * <contact.View />
76
+ *
77
+ * Auto-resolves identity from the SDK when the host passes the
78
+ * current `AuthUser` via the `user` default. Identified users get the
79
+ * locked-email mode + userId attached automatically. Anonymous SDK
80
+ * rows get the userId attached without locking. No user = standard
81
+ * form.
82
+ *
83
+ * import SendoraCloud from "@sendoracloud/sdk-react-native";
84
+ * const user = SendoraCloud.auth.getCurrentUser();
85
+ * const contact = useContactWidget("widget-uuid", { user });
62
86
  */
63
- declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidgetProps, "visible" | "widgetId" | "onClose">): {
87
+ declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidgetProps, "visible" | "widgetId" | "onClose"> & {
88
+ /** Pass `SendoraCloud.auth.getCurrentUser()` here to auto-stitch identity. */
89
+ user?: {
90
+ id: string;
91
+ email: string | null;
92
+ emailVerified: boolean;
93
+ name: string | null;
94
+ isAnonymous: boolean;
95
+ } | null;
96
+ }): {
64
97
  open: () => void;
65
98
  close: () => void;
66
99
  View: () => React.ReactElement | null;
@@ -44,6 +44,20 @@ interface ContactWidgetProps {
44
44
  prefillName?: string;
45
45
  /** Pre-fill email field for signed-in users. */
46
46
  prefillEmail?: string;
47
+ /**
48
+ * Wave 68 — stitch the ticket to the same profile as analytics
49
+ * events. Pass the signed-in user's id (anon or identified). Hint
50
+ * only, not an auth boundary — backend stores it without verifying
51
+ * because the WebView is in customer-app code.
52
+ */
53
+ prefillUserId?: string;
54
+ /**
55
+ * When true (and `prefillEmail` is set) the email field is hidden +
56
+ * read-only. Use for identified users so the agent inbox can trust
57
+ * the email field came from the customer's verified account, not
58
+ * free text.
59
+ */
60
+ lockEmail?: boolean;
47
61
  /**
48
62
  * Fired when the user closes the sheet — either after a successful
49
63
  * submit (`submitted = true`) or via the close button
@@ -51,7 +65,7 @@ interface ContactWidgetProps {
51
65
  */
52
66
  onClose: (result: ContactWidgetResult) => void;
53
67
  }
54
- declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillName, prefillEmail, onClose, }: ContactWidgetProps): React.ReactElement | null;
68
+ declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillName, prefillEmail, prefillUserId, lockEmail, onClose, }: ContactWidgetProps): React.ReactElement | null;
55
69
  /**
56
70
  * Helper hook so the host doesn't have to wire visibility state by
57
71
  * hand.
@@ -59,8 +73,27 @@ declare function ContactWidget({ visible, widgetId, workerHost, theme, prefillNa
59
73
  * const contact = useContactWidget("widget-uuid");
60
74
  * <Button onPress={contact.open} title="Contact us" />
61
75
  * <contact.View />
76
+ *
77
+ * Auto-resolves identity from the SDK when the host passes the
78
+ * current `AuthUser` via the `user` default. Identified users get the
79
+ * locked-email mode + userId attached automatically. Anonymous SDK
80
+ * rows get the userId attached without locking. No user = standard
81
+ * form.
82
+ *
83
+ * import SendoraCloud from "@sendoracloud/sdk-react-native";
84
+ * const user = SendoraCloud.auth.getCurrentUser();
85
+ * const contact = useContactWidget("widget-uuid", { user });
62
86
  */
63
- declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidgetProps, "visible" | "widgetId" | "onClose">): {
87
+ declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidgetProps, "visible" | "widgetId" | "onClose"> & {
88
+ /** Pass `SendoraCloud.auth.getCurrentUser()` here to auto-stitch identity. */
89
+ user?: {
90
+ id: string;
91
+ email: string | null;
92
+ emailVerified: boolean;
93
+ name: string | null;
94
+ isAnonymous: boolean;
95
+ } | null;
96
+ }): {
64
97
  open: () => void;
65
98
  close: () => void;
66
99
  View: () => React.ReactElement | null;
@@ -10,6 +10,8 @@ function ContactWidget({
10
10
  theme = "auto",
11
11
  prefillName,
12
12
  prefillEmail,
13
+ prefillUserId,
14
+ lockEmail,
13
15
  onClose
14
16
  }) {
15
17
  const didFire = React.useRef(false);
@@ -20,6 +22,8 @@ function ContactWidget({
20
22
  const params = new URLSearchParams({ widgetId, theme });
21
23
  if (prefillName) params.set("prefillName", prefillName);
22
24
  if (prefillEmail) params.set("prefillEmail", prefillEmail);
25
+ if (prefillUserId) params.set("prefillUserId", prefillUserId);
26
+ if (lockEmail && prefillEmail) params.set("lockEmail", "1");
23
27
  const uri = `${workerHost}/embed/contact?${params.toString()}`;
24
28
  const handleClose = (result) => {
25
29
  if (didFire.current) return;
@@ -68,20 +72,30 @@ function useContactWidget(widgetId, defaults) {
68
72
  const [lastResult, setLastResult] = React.useState(null);
69
73
  const open = React.useCallback(() => setVisible(true), []);
70
74
  const close = React.useCallback(() => setVisible(false), []);
75
+ const sdkUser = defaults?.user ?? null;
76
+ const resolvedName = defaults?.prefillName ?? sdkUser?.name ?? void 0;
77
+ const resolvedEmail = defaults?.prefillEmail ?? sdkUser?.email ?? void 0;
78
+ const resolvedUserId = defaults?.prefillUserId ?? sdkUser?.id ?? void 0;
79
+ const resolvedLockEmail = defaults?.lockEmail ?? (sdkUser != null && sdkUser.email != null && sdkUser.emailVerified && !sdkUser.isAnonymous);
71
80
  const View2 = React.useCallback(
72
81
  () => /* @__PURE__ */ jsx(
73
82
  ContactWidget,
74
83
  {
75
- ...defaults,
84
+ workerHost: defaults?.workerHost,
85
+ theme: defaults?.theme,
76
86
  widgetId,
77
87
  visible,
88
+ prefillName: resolvedName,
89
+ prefillEmail: resolvedEmail,
90
+ prefillUserId: resolvedUserId,
91
+ lockEmail: resolvedLockEmail,
78
92
  onClose: (r) => {
79
93
  setLastResult(r);
80
94
  setVisible(false);
81
95
  }
82
96
  }
83
97
  ),
84
- [defaults, widgetId, visible]
98
+ [defaults, widgetId, visible, resolvedName, resolvedEmail, resolvedUserId, resolvedLockEmail]
85
99
  );
86
100
  return { open, close, View: View2, lastResult };
87
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendoracloud/sdk-react-native",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",