@thisispamela/react 1.0.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.
package/README.md ADDED
@@ -0,0 +1,293 @@
1
+ # @pamela/react
2
+
3
+ React component library for easy integration of Pamela Voice API into your React applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @pamela/react @pamela/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Wrap your app with PamelaProvider
14
+
15
+ ```tsx
16
+ import { PamelaProvider } from '@pamela/react';
17
+
18
+ function App() {
19
+ return (
20
+ <PamelaProvider
21
+ config={{
22
+ apiKey: 'pk_live_your_api_key_here',
23
+ baseUrl: 'https://api.thisispamela.com', // Optional
24
+ }}
25
+ >
26
+ <YourApp />
27
+ </PamelaProvider>
28
+ );
29
+ }
30
+ ```
31
+
32
+ ### 2. Use the components
33
+
34
+ ```tsx
35
+ import { CallButton, CallStatus } from '@pamela/react';
36
+
37
+ function MyComponent() {
38
+ const [callId, setCallId] = useState<string | null>(null);
39
+
40
+ return (
41
+ <div>
42
+ <CallButton
43
+ to="+1234567890"
44
+ task="Schedule a meeting for next week"
45
+ onCallStart={(id) => setCallId(id)}
46
+ onCallComplete={(call) => console.log('Call completed:', call)}
47
+ >
48
+ Make Call
49
+ </CallButton>
50
+
51
+ {callId && (
52
+ <CallStatus
53
+ callId={callId}
54
+ showTranscript={true}
55
+ />
56
+ )}
57
+ </div>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ## Components
63
+
64
+ ### CallButton
65
+
66
+ A button component that initiates a call when clicked.
67
+
68
+ ```tsx
69
+ <CallButton
70
+ to="+1234567890"
71
+ task="Schedule a meeting"
72
+ country="US"
73
+ locale="en-US"
74
+ instructions="Be professional and concise"
75
+ metadata={{ customer_id: "12345" }}
76
+ onCallStart={(callId) => console.log('Call started:', callId)}
77
+ onCallComplete={(call) => console.log('Call completed:', call)}
78
+ onError={(error) => console.error('Error:', error)}
79
+ disabled={false}
80
+ className="my-custom-class"
81
+ >
82
+ Make Call
83
+ </CallButton>
84
+ ```
85
+
86
+ **Props:**
87
+ - `to` (required): Phone number in E.164 format
88
+ - `task` (required): Task description for the call
89
+ - `country`: ISO country code (optional)
90
+ - `locale`: Locale string (optional, e.g., "en-US")
91
+ - `instructions`: Additional instructions (optional)
92
+ - `metadata`: Custom metadata object (optional)
93
+ - `onCallStart`: Callback when call starts (optional)
94
+ - `onCallComplete`: Callback when call completes (optional)
95
+ - `onError`: Error callback (optional)
96
+ - `disabled`: Disable button (optional)
97
+ - `className`: Custom CSS class (optional)
98
+ - `children`: Button content (optional, defaults to "Make Call")
99
+
100
+ ### CallStatus
101
+
102
+ Displays the current status of a call with optional transcript.
103
+
104
+ ```tsx
105
+ <CallStatus
106
+ callId="call_123"
107
+ pollInterval={5000}
108
+ onStatusChange={(status) => console.log('Status:', status)}
109
+ showTranscript={true}
110
+ className="my-custom-class"
111
+ />
112
+ ```
113
+
114
+ **Props:**
115
+ - `callId` (required): Call ID to monitor
116
+ - `pollInterval`: Polling interval in milliseconds (default: 5000)
117
+ - `onStatusChange`: Callback when status changes (optional)
118
+ - `showTranscript`: Show transcript (default: true)
119
+ - `className`: Custom CSS class (optional)
120
+
121
+ ### TranscriptViewer
122
+
123
+ Displays a call transcript in a readable format.
124
+
125
+ ```tsx
126
+ <TranscriptViewer
127
+ transcript={[
128
+ {
129
+ speaker: "pamela",
130
+ text: "Hello, this is Pamela...",
131
+ timestamp: "2024-01-01T00:00:02Z"
132
+ },
133
+ {
134
+ speaker: "user",
135
+ text: "Hi Pamela!",
136
+ timestamp: "2024-01-01T00:00:05Z"
137
+ }
138
+ ]}
139
+ className="my-custom-class"
140
+ />
141
+ ```
142
+
143
+ **Props:**
144
+ - `transcript` (required): Array of transcript entries
145
+ - `className`: Custom CSS class (optional)
146
+
147
+ ### CallHistory
148
+
149
+ Displays a list of previous calls (requires API endpoint).
150
+
151
+ ```tsx
152
+ <CallHistory
153
+ limit={10}
154
+ onCallSelect={(callId) => console.log('Selected:', callId)}
155
+ className="my-custom-class"
156
+ />
157
+ ```
158
+
159
+ **Props:**
160
+ - `limit`: Maximum number of calls to display (default: 10)
161
+ - `onCallSelect`: Callback when a call is selected (optional)
162
+ - `className`: Custom CSS class (optional)
163
+
164
+ ## Hooks
165
+
166
+ ### usePamela
167
+
168
+ Access the Pamela client directly for custom integrations.
169
+
170
+ ```tsx
171
+ import { usePamela } from '@pamela/react';
172
+
173
+ function MyComponent() {
174
+ const { client } = usePamela();
175
+
176
+ const handleCustomCall = async () => {
177
+ const call = await client.createCall({
178
+ to: '+1234567890',
179
+ task: 'Custom task',
180
+ });
181
+ console.log('Call created:', call);
182
+ };
183
+
184
+ return <button onClick={handleCustomCall}>Custom Call</button>;
185
+ }
186
+ ```
187
+
188
+ ## Styling
189
+
190
+ Components use **Pamela's design system** by default, matching the B2C UI:
191
+
192
+ - **Colors**: Orange gradient buttons (#FA931C → #fd8b74), beige borders (#e7ab84)
193
+ - **3-Color Call Status**: Yellow (ringing), Green (in progress), Green with checkmark (completed)
194
+ - **Message Bubbles**: Orange (user), White with beige border (Pamela), Blue (call recipient)
195
+ - **Fonts**: Poppins, Inter
196
+ - **Dark Mode**: Automatic support
197
+
198
+ You can override styles with CSS classes:
199
+
200
+ ```css
201
+ .pamela-call-button {
202
+ /* Override button styles */
203
+ background: linear-gradient(to right, #your-color, #your-color);
204
+ }
205
+
206
+ .pamela-call-status {
207
+ /* Override status container */
208
+ }
209
+
210
+ .pamela-transcript-viewer {
211
+ /* Override transcript container */
212
+ }
213
+ ```
214
+
215
+ Or use the `className` prop on any component to add your own classes.
216
+
217
+ ## Examples
218
+
219
+ ### Complete Integration Example
220
+
221
+ ```tsx
222
+ import React, { useState } from 'react';
223
+ import { PamelaProvider, CallButton, CallStatus, TranscriptViewer } from '@pamela/react';
224
+
225
+ function App() {
226
+ return (
227
+ <PamelaProvider
228
+ config={{
229
+ apiKey: process.env.REACT_APP_PAMELA_API_KEY!,
230
+ }}
231
+ >
232
+ <CallExample />
233
+ </PamelaProvider>
234
+ );
235
+ }
236
+
237
+ function CallExample() {
238
+ const [callId, setCallId] = useState<string | null>(null);
239
+ const [callData, setCallData] = useState<any>(null);
240
+
241
+ return (
242
+ <div>
243
+ <h1>Make a Call</h1>
244
+
245
+ <CallButton
246
+ to="+1234567890"
247
+ task="Schedule a meeting for next week"
248
+ onCallStart={(id) => {
249
+ setCallId(id);
250
+ console.log('Call started:', id);
251
+ }}
252
+ onCallComplete={(call) => {
253
+ setCallData(call);
254
+ console.log('Call completed:', call);
255
+ }}
256
+ onError={(error) => {
257
+ console.error('Call error:', error);
258
+ }}
259
+ >
260
+ Call Now
261
+ </CallButton>
262
+
263
+ {callId && (
264
+ <div style={{ marginTop: '24px' }}>
265
+ <CallStatus
266
+ callId={callId}
267
+ onStatusChange={(status) => {
268
+ if (status.status === 'completed') {
269
+ setCallData(status);
270
+ }
271
+ }}
272
+ />
273
+ </div>
274
+ )}
275
+
276
+ {callData && callData.transcript && (
277
+ <div style={{ marginTop: '24px' }}>
278
+ <TranscriptViewer transcript={callData.transcript} />
279
+ </div>
280
+ )}
281
+ </div>
282
+ );
283
+ }
284
+ ```
285
+
286
+ ## TypeScript Support
287
+
288
+ Full TypeScript support is included. All components and hooks are fully typed.
289
+
290
+ ## License
291
+
292
+ MIT
293
+
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { CallButtonProps } from './types';
3
+ export declare function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, onCallStart, onCallComplete, onError, disabled, className, children, }: CallButtonProps): React.JSX.Element;
4
+ //# sourceMappingURL=CallButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallButton.d.ts","sourceRoot":"","sources":["../src/CallButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,UAAU,CAAC,EACzB,EAAE,EACF,IAAI,EACJ,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc,EACd,OAAO,EACP,QAAgB,EAChB,SAAc,EACd,QAAQ,GACT,EAAE,eAAe,qBA2EjB"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { CallHistoryProps } from './types';
3
+ export declare function CallHistory({ limit, onCallSelect, className, }: CallHistoryProps): React.JSX.Element;
4
+ //# sourceMappingURL=CallHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallHistory.d.ts","sourceRoot":"","sources":["../src/CallHistory.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,wBAAgB,WAAW,CAAC,EAC1B,KAAU,EACV,YAAY,EACZ,SAAc,GACf,EAAE,gBAAgB,qBA6FlB"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { CallStatusProps } from './types';
3
+ export declare function CallStatus({ callId, pollInterval, onStatusChange, showTranscript, className, }: CallStatusProps): React.JSX.Element;
4
+ //# sourceMappingURL=CallStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallStatus.d.ts","sourceRoot":"","sources":["../src/CallStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA0G1C,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,YAAmB,EACnB,cAAc,EACd,cAAqB,EACrB,SAAc,GACf,EAAE,eAAe,qBAqJjB"}
@@ -0,0 +1,14 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { PamelaClient } from '@thisispamela/sdk';
3
+ import { PamelaConfig } from './types';
4
+ interface PamelaContextValue {
5
+ client: PamelaClient;
6
+ }
7
+ export interface PamelaProviderProps {
8
+ config: PamelaConfig;
9
+ children: ReactNode;
10
+ }
11
+ export declare function PamelaProvider({ config, children }: PamelaProviderProps): React.JSX.Element;
12
+ export declare function usePamela(): PamelaContextValue;
13
+ export {};
14
+ //# sourceMappingURL=PamelaProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PamelaProvider.d.ts","sourceRoot":"","sources":["../src/PamelaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAU,kBAAkB;IAC1B,MAAM,EAAE,YAAY,CAAC;CACtB;AAID,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,mBAAmB,qBAWvE;AAED,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { TranscriptViewerProps } from './types';
3
+ export declare function TranscriptViewer({ transcript, className }: TranscriptViewerProps): React.JSX.Element;
4
+ //# sourceMappingURL=TranscriptViewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranscriptViewer.d.ts","sourceRoot":"","sources":["../src/TranscriptViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,SAAc,EAAE,EAAE,qBAAqB,qBA8GrF"}
@@ -0,0 +1,62 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { CallStatus as CallStatus$1, PamelaClient } from '@thisispamela/sdk';
3
+
4
+ interface PamelaConfig {
5
+ apiKey: string;
6
+ baseUrl?: string;
7
+ }
8
+ interface CallButtonProps {
9
+ to: string;
10
+ task: string;
11
+ country?: string;
12
+ locale?: string;
13
+ instructions?: string;
14
+ end_user_id?: string;
15
+ metadata?: Record<string, any>;
16
+ onCallStart?: (callId: string) => void;
17
+ onCallComplete?: (call: CallStatus$1) => void;
18
+ onError?: (error: Error) => void;
19
+ disabled?: boolean;
20
+ className?: string;
21
+ children?: ReactNode;
22
+ }
23
+ interface CallStatusProps {
24
+ callId: string;
25
+ pollInterval?: number;
26
+ onStatusChange?: (status: CallStatus$1) => void;
27
+ showTranscript?: boolean;
28
+ className?: string;
29
+ }
30
+ interface TranscriptViewerProps {
31
+ transcript: Array<{
32
+ speaker: string;
33
+ text: string;
34
+ timestamp: string;
35
+ }>;
36
+ className?: string;
37
+ }
38
+ interface CallHistoryProps {
39
+ limit?: number;
40
+ onCallSelect?: (callId: string) => void;
41
+ className?: string;
42
+ }
43
+
44
+ interface PamelaContextValue {
45
+ client: PamelaClient;
46
+ }
47
+ interface PamelaProviderProps {
48
+ config: PamelaConfig;
49
+ children: ReactNode;
50
+ }
51
+ declare function PamelaProvider({ config, children }: PamelaProviderProps): React.JSX.Element;
52
+ declare function usePamela(): PamelaContextValue;
53
+
54
+ declare function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, onCallStart, onCallComplete, onError, disabled, className, children, }: CallButtonProps): React.JSX.Element;
55
+
56
+ declare function CallStatus({ callId, pollInterval, onStatusChange, showTranscript, className, }: CallStatusProps): React.JSX.Element;
57
+
58
+ declare function TranscriptViewer({ transcript, className }: TranscriptViewerProps): React.JSX.Element;
59
+
60
+ declare function CallHistory({ limit, onCallSelect, className, }: CallHistoryProps): React.JSX.Element;
61
+
62
+ export { CallButton, CallButtonProps, CallHistory, CallHistoryProps, CallStatus, CallStatusProps, PamelaConfig, PamelaProvider, TranscriptViewer, TranscriptViewerProps, usePamela };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,cAAc,CAAC;AAEtB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}