@thisispamela/react 1.0.0 → 1.0.1

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 CHANGED
@@ -1,11 +1,11 @@
1
- # @pamela/react
1
+ # @thisispamela/react
2
2
 
3
3
  React component library for easy integration of Pamela Voice API into your React applications.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @pamela/react @pamela/sdk
8
+ npm install @thisispamela/react @thisispamela/sdk
9
9
  ```
10
10
 
11
11
  ## Quick Start
@@ -13,7 +13,7 @@ npm install @pamela/react @pamela/sdk
13
13
  ### 1. Wrap your app with PamelaProvider
14
14
 
15
15
  ```tsx
16
- import { PamelaProvider } from '@pamela/react';
16
+ import { PamelaProvider } from '@thisispamela/react';
17
17
 
18
18
  function App() {
19
19
  return (
@@ -32,7 +32,7 @@ function App() {
32
32
  ### 2. Use the components
33
33
 
34
34
  ```tsx
35
- import { CallButton, CallStatus } from '@pamela/react';
35
+ import { CallButton, CallStatus } from '@thisispamela/react';
36
36
 
37
37
  function MyComponent() {
38
38
  const [callId, setCallId] = useState<string | null>(null);
@@ -168,7 +168,7 @@ Displays a list of previous calls (requires API endpoint).
168
168
  Access the Pamela client directly for custom integrations.
169
169
 
170
170
  ```tsx
171
- import { usePamela } from '@pamela/react';
171
+ import { usePamela } from '@thisispamela/react';
172
172
 
173
173
  function MyComponent() {
174
174
  const { client } = usePamela();
@@ -220,7 +220,7 @@ Or use the `className` prop on any component to add your own classes.
220
220
 
221
221
  ```tsx
222
222
  import React, { useState } from 'react';
223
- import { PamelaProvider, CallButton, CallStatus, TranscriptViewer } from '@pamela/react';
223
+ import { PamelaProvider, CallButton, CallStatus, TranscriptViewer } from '@thisispamela/react';
224
224
 
225
225
  function App() {
226
226
  return (
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
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;
3
+ export declare function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, tools, webhooks, onCallStart, onCallComplete, onError, disabled, className, children, }: CallButtonProps): React.JSX.Element;
4
4
  //# sourceMappingURL=CallButton.d.ts.map
@@ -1 +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"}
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,KAAK,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,OAAO,EACP,QAAgB,EAChB,SAAc,EACd,QAAQ,GACT,EAAE,eAAe,qBA6DjB"}
@@ -1 +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"}
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,qBAgHlB"}
@@ -1 +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"}
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;AA4H1C,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,YAAmB,EACnB,cAAc,EACd,cAAqB,EACrB,SAAc,GACf,EAAE,eAAe,qBA2IjB"}
@@ -1 +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"}
1
+ {"version":3,"file":"PamelaProvider.d.ts","sourceRoot":"","sources":["../src/PamelaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA6B,SAAS,EAAW,MAAM,OAAO,CAAC;AAC7E,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,qBAevE;AAED,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
@@ -1 +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"}
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,qBAmHrF"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { CallStatus as CallStatus$1, PamelaClient } from '@thisispamela/sdk';
2
+ import { CreateCallRequest, CallStatus as CallStatus$1, PamelaClient } from '@thisispamela/sdk';
3
3
 
4
4
  interface PamelaConfig {
5
5
  apiKey: string;
@@ -13,6 +13,8 @@ interface CallButtonProps {
13
13
  instructions?: string;
14
14
  end_user_id?: string;
15
15
  metadata?: Record<string, any>;
16
+ tools?: CreateCallRequest["tools"];
17
+ webhooks?: CreateCallRequest["webhooks"];
16
18
  onCallStart?: (callId: string) => void;
17
19
  onCallComplete?: (call: CallStatus$1) => void;
18
20
  onError?: (error: Error) => void;
@@ -51,7 +53,7 @@ interface PamelaProviderProps {
51
53
  declare function PamelaProvider({ config, children }: PamelaProviderProps): React.JSX.Element;
52
54
  declare function usePamela(): PamelaContextValue;
53
55
 
54
- declare function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, onCallStart, onCallComplete, onError, disabled, className, children, }: CallButtonProps): React.JSX.Element;
56
+ declare function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, tools, webhooks, onCallStart, onCallComplete, onError, disabled, className, children, }: CallButtonProps): React.JSX.Element;
55
57
 
56
58
  declare function CallStatus({ callId, pollInterval, onStatusChange, showTranscript, className, }: CallStatusProps): React.JSX.Element;
57
59
 
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useState, useEffect } from 'react';
1
+ import React, { createContext, useMemo, useContext, useState, useEffect } from 'react';
2
2
  import { PamelaClient } from '@thisispamela/sdk';
3
3
 
4
4
  function styleInject(css, ref) {
@@ -28,15 +28,15 @@ function styleInject(css, ref) {
28
28
  }
29
29
  }
30
30
 
31
- var css_248z = "/**\n * Pamela B2B React Component Library - Default Styles\n * \n * These styles match the Pamela B2C design system:\n * - Colors: Orange (#FA931C), Beige (#e7ab84), Blue (#4b4bea)\n * - Fonts: Poppins, Inter\n * - Dark mode support\n */\n\n/* Pulse animation for status indicators */\n@keyframes pamela-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n/* Call Button - matches your gradient style */\n.pamela-call-button {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n background: linear-gradient(to right, #FA931C, #fd8b74);\n color: white;\n border: none;\n border-radius: 0.5rem;\n font-weight: 600;\n transition: opacity 0.2s;\n box-shadow: 0 2px 4px rgba(250, 147, 28, 0.2);\n}\n\n.pamela-call-button:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.pamela-call-button:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n background: linear-gradient(to right, #ccc, #aaa);\n}\n\n/* Call Status - matches your card style */\n.pamela-call-status {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Transcript Viewer - matches your message bubble style */\n.pamela-transcript-viewer {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .pamela-call-status {\n color: #ffffff;\n }\n \n .pamela-transcript-viewer {\n color: #ffffff;\n }\n}\n\n";
31
+ var css_248z = "/**\n * Pamela Enterprise React Component Library - Default Styles\n *\n * These styles align with the Pamela app design schema.\n * If the host app already defines these CSS variables, its values will win.\n */\n\n:root {\n --accent: #F27A1A;\n --accent-2: #F06C4F;\n --accent-3: #F3A84C;\n --accent-gradient: linear-gradient(90deg, var(--accent), var(--accent-2));\n --bg-gradient: linear-gradient(135deg, #F5F0E8 0%, #F3EEE8 45%, #EFE8DF 100%);\n --bg-glow: radial-gradient(1200px circle at 10% 20%, rgba(250, 147, 28, 0.1), transparent 58%),\n radial-gradient(900px circle at 80% 10%, rgba(253, 139, 116, 0.1), transparent 62%),\n radial-gradient(800px circle at 70% 80%, rgba(251, 193, 107, 0.08), transparent 60%);\n --surface: rgba(255, 255, 255, 0.5);\n --surface-strong: rgba(255, 255, 255, 0.78);\n --surface-border: rgba(231, 171, 132, 0.24);\n --surface-border-strong: rgba(255, 255, 255, 0.75);\n --surface-highlight: rgba(255, 255, 255, 0.68);\n --surface-liquid: linear-gradient(135deg, rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.38));\n --surface-liquid-strong: linear-gradient(140deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.5));\n --liquid-shadow: 0 18px 42px rgba(28, 25, 17, 0.14);\n --liquid-glow: 0 0 32px rgba(250, 147, 28, 0.2);\n --shadow-soft: 0 12px 26px rgba(28, 25, 17, 0.1);\n --shadow-hover: 0 24px 44px rgba(28, 25, 17, 0.18);\n --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.7);\n --cta-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.7), rgba(250, 147, 28, 0.32));\n --cta-border: 1px solid rgba(250, 147, 28, 0.4);\n --cta-glow: 0 0 18px rgba(250, 147, 28, 0.28);\n --cta-glow-hover: 0 0 22px rgba(250, 147, 28, 0.36);\n --danger-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.6), rgba(239, 68, 68, 0.3));\n --danger-border: 1px solid rgba(239, 68, 68, 0.45);\n --danger-glow: 0 0 16px rgba(239, 68, 68, 0.3);\n --danger-glow-hover: 0 0 20px rgba(239, 68, 68, 0.4);\n --radius-sm: 0.5rem;\n --radius-md: 0.75rem;\n --radius-lg: 1rem;\n --radius-xl: 1.5rem;\n --text-primary: #1C1917;\n --text-secondary: rgba(28, 25, 17, 0.78);\n --text-muted: rgba(28, 25, 17, 0.55);\n --status-success: #10b981;\n --status-warning: #eab308;\n --status-muted: #d1d5db;\n --status-error: #ef4444;\n --bubble-user: #FA931C;\n --bubble-pamela: #ffffff;\n --bubble-recipient: #4b4bea;\n --bubble-border: rgba(231, 171, 132, 0.3);\n}\n\n.dark {\n --bg-gradient: linear-gradient(135deg, #171513 0%, #14110f 45%, #0f0d0b 100%);\n --bg-glow: radial-gradient(1100px circle at 20% 10%, rgba(250, 147, 28, 0.18), transparent 60%),\n radial-gradient(900px circle at 80% 20%, rgba(253, 139, 116, 0.16), transparent 60%),\n radial-gradient(700px circle at 60% 80%, rgba(251, 193, 107, 0.12), transparent 55%);\n --surface: rgba(255, 255, 255, 0.08);\n --surface-strong: rgba(255, 255, 255, 0.16);\n --surface-border: rgba(255, 255, 255, 0.18);\n --surface-border-strong: rgba(255, 255, 255, 0.36);\n --surface-highlight: rgba(255, 255, 255, 0.2);\n --surface-liquid: linear-gradient(150deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.05));\n --surface-liquid-strong: linear-gradient(150deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.08));\n --liquid-shadow: 0 22px 48px rgba(0, 0, 0, 0.55);\n --liquid-glow: 0 0 30px rgba(250, 147, 28, 0.24);\n --shadow-soft: 0 16px 32px rgba(0, 0, 0, 0.5);\n --shadow-hover: 0 26px 44px rgba(0, 0, 0, 0.7);\n --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.12);\n --cta-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.22), rgba(250, 147, 28, 0.34));\n --cta-border: 1px solid rgba(250, 147, 28, 0.5);\n --cta-glow: 0 0 16px rgba(250, 147, 28, 0.26);\n --cta-glow-hover: 0 0 20px rgba(250, 147, 28, 0.32);\n --danger-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.18), rgba(239, 68, 68, 0.32));\n --danger-border: 1px solid rgba(248, 113, 113, 0.55);\n --danger-glow: 0 0 18px rgba(239, 68, 68, 0.32);\n --danger-glow-hover: 0 0 22px rgba(239, 68, 68, 0.4);\n --text-primary: rgba(255, 255, 255, 0.95);\n --text-secondary: rgba(255, 255, 255, 0.72);\n --text-muted: rgba(255, 255, 255, 0.5);\n --bubble-pamela: rgba(255, 255, 255, 0.12);\n --bubble-border: rgba(255, 255, 255, 0.2);\n}\n\n/* Pulse animation for status indicators */\n@keyframes pamela-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n/* Call Button - matches your gradient style */\n.pamela-call-button {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n background: var(--accent-gradient);\n color: var(--text-primary);\n border: var(--cta-border);\n border-radius: var(--radius-md);\n font-weight: 600;\n transition: opacity 0.2s;\n box-shadow: var(--shadow-soft), var(--cta-glow);\n padding: 10px 20px;\n font-size: 16px;\n cursor: pointer;\n}\n\n.pamela-call-button:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.pamela-call-button:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n background: linear-gradient(to right, #cfcfcf, #b6b6b6);\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-shadow: none;\n}\n\n/* Call Status - matches your card style */\n.pamela-call-status {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Transcript Viewer - matches your message bubble style */\n.pamela-transcript-viewer {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n.pamela-card {\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-soft), var(--liquid-glow);\n}\n\n.pamela-panel {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-xl);\n box-shadow: var(--liquid-shadow), var(--liquid-glow);\n}\n\n.pamela-chip {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: 999px;\n padding: 0.25rem 0.6rem;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--text-secondary);\n box-shadow: var(--shadow-inset);\n}\n\n.pamela-transcript-container {\n background: var(--surface);\n border-radius: var(--radius-md);\n padding: 16px;\n}\n\n.pamela-transcript-bubble {\n border-radius: var(--radius-md);\n padding: 12px 16px;\n}\n\n.pamela-transcript-bubble--pamela {\n background: var(--bubble-pamela);\n border: 1px solid var(--bubble-border);\n color: var(--text-primary);\n}\n\n.pamela-transcript-bubble--user {\n background: var(--bubble-user);\n color: #ffffff;\n}\n\n.pamela-transcript-bubble--recipient {\n background: var(--bubble-recipient);\n color: #ffffff;\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .pamela-call-status {\n color: #ffffff;\n }\n \n .pamela-transcript-viewer {\n color: #ffffff;\n }\n}\n\n";
32
32
  styleInject(css_248z);
33
33
 
34
34
  const PamelaContext = createContext(null);
35
35
  function PamelaProvider({ config, children }) {
36
- const client = new PamelaClient({
36
+ const client = useMemo(() => new PamelaClient({
37
37
  apiKey: config.apiKey,
38
38
  baseUrl: config.baseUrl,
39
- });
39
+ }), [config.apiKey, config.baseUrl]);
40
40
  return (React.createElement(PamelaContext.Provider, { value: { client } }, children));
41
41
  }
42
42
  function usePamela() {
@@ -47,7 +47,7 @@ function usePamela() {
47
47
  return context;
48
48
  }
49
49
 
50
- function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, onCallStart, onCallComplete, onError, disabled = false, className = '', children, }) {
50
+ function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, tools, webhooks, onCallStart, onCallComplete, onError, disabled = false, className = '', children, }) {
51
51
  const { client } = usePamela();
52
52
  const [loading, setLoading] = useState(false);
53
53
  const [callId, setCallId] = useState(null);
@@ -64,6 +64,8 @@ function CallButton({ to, task, country, locale, instructions, end_user_id, meta
64
64
  instructions,
65
65
  end_user_id,
66
66
  metadata,
67
+ tools,
68
+ webhooks,
67
69
  });
68
70
  setCallId(call.id);
69
71
  onCallStart?.(call.id);
@@ -94,22 +96,7 @@ function CallButton({ to, task, country, locale, instructions, end_user_id, meta
94
96
  onError?.(error);
95
97
  }
96
98
  };
97
- return (React.createElement("button", { onClick: handleClick, disabled: loading || disabled, className: `pamela-call-button ${className}`, style: {
98
- padding: '10px 20px',
99
- background: loading
100
- ? 'linear-gradient(to right, #ccc, #aaa)'
101
- : 'linear-gradient(to right, #FA931C, #fd8b74)',
102
- color: 'white',
103
- border: 'none',
104
- borderRadius: '0.5rem',
105
- cursor: loading || disabled ? 'not-allowed' : 'pointer',
106
- fontSize: '16px',
107
- fontWeight: '600',
108
- fontFamily: 'Poppins, Inter, -apple-system, BlinkMacSystemFont, sans-serif',
109
- transition: 'opacity 0.2s',
110
- opacity: loading || disabled ? 0.7 : 1,
111
- boxShadow: loading || disabled ? 'none' : '0 2px 4px rgba(250, 147, 28, 0.2)',
112
- } }, loading ? 'Calling...' : children || 'Call Now'));
99
+ return (React.createElement("button", { onClick: handleClick, disabled: loading || disabled, className: `pamela-call-button ${className}` }, loading ? 'Calling...' : children || 'Call Now'));
113
100
  }
114
101
 
115
102
  function TranscriptViewer({ transcript, className = '' }) {
@@ -117,25 +104,28 @@ function TranscriptViewer({ transcript, className = '' }) {
117
104
  if (speaker === 'pamela' || speaker === 'agent') {
118
105
  // Pamela messages: white background with beige border
119
106
  return {
120
- backgroundColor: '#ffffff',
121
- border: '1px solid rgba(231, 171, 132, 0.3)',
122
- color: '#1f2937',
107
+ backgroundColor: 'var(--bubble-pamela, #ffffff)',
108
+ border: '1px solid var(--bubble-border, rgba(231, 171, 132, 0.3))',
109
+ color: 'var(--text-primary, #1f2937)',
110
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--pamela',
123
111
  };
124
112
  }
125
113
  else if (speaker === 'user' || speaker === 'caller') {
126
114
  // User messages: orange background
127
115
  return {
128
- backgroundColor: '#FA931C',
116
+ backgroundColor: 'var(--bubble-user, #FA931C)',
129
117
  border: 'none',
130
118
  color: '#ffffff',
119
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--user',
131
120
  };
132
121
  }
133
122
  else {
134
123
  // Call recipient: blue background
135
124
  return {
136
- backgroundColor: '#4b4bea',
125
+ backgroundColor: 'var(--bubble-recipient, #4b4bea)',
137
126
  border: 'none',
138
127
  color: '#ffffff',
128
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--recipient',
139
129
  };
140
130
  }
141
131
  };
@@ -146,21 +136,21 @@ function TranscriptViewer({ transcript, className = '' }) {
146
136
  marginBottom: '16px',
147
137
  fontSize: '18px',
148
138
  fontWeight: '600',
149
- color: '#1f2937',
139
+ color: 'var(--text-primary, #1f2937)',
150
140
  } }, "Transcript"),
151
- React.createElement("div", { style: {
141
+ React.createElement("div", { className: "pamela-transcript-container", style: {
152
142
  maxHeight: '400px',
153
143
  overflowY: 'auto',
154
- borderRadius: '0.5rem',
144
+ borderRadius: 'var(--radius-sm, 0.5rem)',
155
145
  padding: '16px',
156
- backgroundColor: '#F7F4ED',
146
+ background: 'var(--surface, #F7F4ED)',
157
147
  } }, transcript.map((entry, index) => {
158
148
  const style = getMessageStyle(entry.speaker);
159
- return (React.createElement("div", { key: index, style: {
149
+ const { className: bubbleClassName, ...bubbleStyle } = style;
150
+ return (React.createElement("div", { key: index, className: bubbleClassName, style: {
160
151
  marginBottom: '12px',
161
- padding: '12px 16px',
162
- ...style,
163
- borderRadius: '0.75rem',
152
+ ...bubbleStyle,
153
+ borderRadius: 'var(--radius-md, 0.75rem)',
164
154
  maxWidth: '75%',
165
155
  marginLeft: entry.speaker === 'pamela' || entry.speaker === 'agent' ? '0' : 'auto',
166
156
  marginRight: entry.speaker === 'pamela' || entry.speaker === 'agent' ? 'auto' : '0',
@@ -168,7 +158,7 @@ function TranscriptViewer({ transcript, className = '' }) {
168
158
  React.createElement("div", { style: {
169
159
  fontSize: '12px',
170
160
  fontWeight: '600',
171
- color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.9)' : '#6b7280',
161
+ color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.9)' : 'var(--text-muted, #6b7280)',
172
162
  marginBottom: '6px',
173
163
  textTransform: 'capitalize',
174
164
  } }, entry.speaker === 'pamela' || entry.speaker === 'agent'
@@ -185,7 +175,7 @@ function TranscriptViewer({ transcript, className = '' }) {
185
175
  } }, entry.text),
186
176
  entry.timestamp && (React.createElement("div", { style: {
187
177
  fontSize: '11px',
188
- color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.7)' : '#9ca3af',
178
+ color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.7)' : 'var(--text-muted, #9ca3af)',
189
179
  marginTop: '6px',
190
180
  } }, new Date(entry.timestamp).toLocaleTimeString()))));
191
181
  }))));
@@ -195,45 +185,63 @@ function TranscriptViewer({ transcript, className = '' }) {
195
185
  function StatusIndicator({ status }) {
196
186
  const getStatusConfig = () => {
197
187
  switch (status) {
188
+ case 'queued':
189
+ case 'initiating':
190
+ return {
191
+ dots: [
192
+ { color: 'var(--status-warning, #eab308)', pulse: true },
193
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
194
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
195
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
196
+ ],
197
+ text: 'Queued...',
198
+ textColor: 'var(--status-warning, #eab308)',
199
+ };
198
200
  case 'ringing':
199
201
  return {
200
202
  dots: [
201
- { color: '#10b981', pulse: true }, // green-500 (first dot)
202
- { color: '#eab308', pulse: true }, // yellow-500 (second dot)
203
- { color: '#d1d5db', pulse: false }, // gray-300 (third dot)
204
- { color: '#d1d5db', pulse: false }, // gray-300 (fourth dot)
203
+ { color: 'var(--status-success, #10b981)', pulse: true },
204
+ { color: 'var(--status-warning, #eab308)', pulse: true },
205
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
206
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
205
207
  ],
206
208
  text: 'Ringing...',
207
- textColor: '#eab308', // yellow-600
209
+ textColor: 'var(--status-warning, #eab308)',
208
210
  };
209
211
  case 'in_progress':
210
212
  case 'in-progress':
211
213
  return {
212
214
  dots: [
213
- { color: '#10b981', pulse: false }, // green-500
214
- { color: '#10b981', pulse: false },
215
- { color: '#10b981', pulse: true }, // third dot pulses
216
- { color: '#d1d5db', pulse: false }, // gray-300
215
+ { color: 'var(--status-success, #10b981)', pulse: false },
216
+ { color: 'var(--status-success, #10b981)', pulse: false },
217
+ { color: 'var(--status-success, #10b981)', pulse: true },
218
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
217
219
  ],
218
220
  text: 'In progress',
219
- textColor: '#10b981', // green-600
221
+ textColor: 'var(--status-success, #10b981)',
220
222
  };
221
223
  case 'completed':
222
224
  return {
223
225
  dots: [
224
- { color: '#10b981', pulse: false },
225
- { color: '#10b981', pulse: false },
226
- { color: '#10b981', pulse: false },
227
- { color: '#10b981', pulse: false, icon: true },
226
+ { color: 'var(--status-success, #10b981)', pulse: false },
227
+ { color: 'var(--status-success, #10b981)', pulse: false },
228
+ { color: 'var(--status-success, #10b981)', pulse: false },
229
+ { color: 'var(--status-success, #10b981)', pulse: false, icon: true },
228
230
  ],
229
231
  text: 'Completed',
230
- textColor: '#10b981',
232
+ textColor: 'var(--status-success, #10b981)',
231
233
  };
232
234
  case 'failed':
233
235
  return {
234
236
  dots: [],
235
237
  text: 'Failed',
236
- textColor: '#ef4444', // red-500
238
+ textColor: 'var(--status-error, #ef4444)',
239
+ };
240
+ case 'cancelled':
241
+ return {
242
+ dots: [],
243
+ text: 'Cancelled',
244
+ textColor: 'var(--status-error, #ef4444)',
237
245
  };
238
246
  default:
239
247
  return {
@@ -251,7 +259,7 @@ function StatusIndicator({ status }) {
251
259
  height: '8px',
252
260
  borderRadius: '50%',
253
261
  backgroundColor: dot.color,
254
- animation: dot.pulse ? 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' : 'none',
262
+ animation: dot.pulse ? 'pamela-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' : 'none',
255
263
  } }))))))),
256
264
  React.createElement("span", { style: {
257
265
  fontSize: '12px',
@@ -286,17 +294,17 @@ function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscrip
286
294
  }, [callId, pollInterval, client, onStatusChange]);
287
295
  if (loading) {
288
296
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
289
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call status...")));
297
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call status...")));
290
298
  }
291
299
  if (error) {
292
300
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
293
- React.createElement("div", { style: { color: '#ef4444', fontFamily: 'Poppins, Inter, sans-serif' } },
301
+ React.createElement("div", { style: { color: 'var(--status-error, #ef4444)', fontFamily: 'Poppins, Inter, sans-serif' } },
294
302
  "Error: ",
295
303
  error.message)));
296
304
  }
297
305
  if (!status) {
298
306
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
299
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Call not found")));
307
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Call not found")));
300
308
  }
301
309
  return (React.createElement("div", { className: `pamela-call-status ${className}`, style: {
302
310
  fontFamily: 'Poppins, Inter, -apple-system, BlinkMacSystemFont, sans-serif',
@@ -304,34 +312,34 @@ function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscrip
304
312
  React.createElement("div", { style: {
305
313
  marginBottom: '16px',
306
314
  padding: '16px',
307
- backgroundColor: '#ffffff',
308
- borderRadius: '0.75rem',
309
- border: '1px solid rgba(231, 171, 132, 0.3)',
310
- boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1)',
315
+ background: 'var(--surface-liquid-strong, #ffffff)',
316
+ borderRadius: 'var(--radius-md, 0.75rem)',
317
+ border: '1px solid var(--surface-border-strong, rgba(231, 171, 132, 0.3))',
318
+ boxShadow: 'var(--shadow-soft, 0 1px 3px rgba(0, 0, 0, 0.1))',
311
319
  } },
312
320
  React.createElement("div", { style: { marginBottom: '12px' } },
313
321
  React.createElement(StatusIndicator, { status: status.status })),
314
- React.createElement("div", { style: { fontSize: '14px', color: '#1f2937', lineHeight: '1.6' } },
322
+ React.createElement("div", { style: { fontSize: '14px', color: 'var(--text-primary, #1f2937)', lineHeight: '1.6' } },
315
323
  React.createElement("div", { style: { marginBottom: '8px' } },
316
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "To:"),
324
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "To:"),
317
325
  ' ',
318
- React.createElement("span", { style: { color: '#1f2937' } }, status.to)),
326
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } }, status.to)),
319
327
  React.createElement("div", { style: { marginBottom: '8px' } },
320
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "From:"),
328
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "From:"),
321
329
  ' ',
322
- React.createElement("span", { style: { color: '#1f2937' } }, status.from_)),
330
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } }, status.from_)),
323
331
  status.duration_seconds && (React.createElement("div", { style: { marginBottom: '8px' } },
324
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "Duration:"),
332
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "Duration:"),
325
333
  ' ',
326
- React.createElement("span", { style: { color: '#1f2937' } },
334
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } },
327
335
  status.duration_seconds,
328
336
  "s")))),
329
337
  status.summary && (React.createElement("div", { style: {
330
338
  marginTop: '16px',
331
339
  padding: '16px',
332
- background: 'linear-gradient(to right, rgba(250, 147, 28, 0.1), rgba(253, 139, 116, 0.1))',
333
- border: '1px solid rgba(250, 147, 28, 0.3)',
334
- borderRadius: '0.75rem',
340
+ background: 'var(--cta-bg, linear-gradient(to right, rgba(250, 147, 28, 0.1), rgba(253, 139, 116, 0.1)))',
341
+ border: 'var(--cta-border, 1px solid rgba(250, 147, 28, 0.3))',
342
+ borderRadius: 'var(--radius-md, 0.75rem)',
335
343
  } },
336
344
  React.createElement("div", { style: {
337
345
  display: 'flex',
@@ -339,21 +347,11 @@ function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscrip
339
347
  gap: '8px',
340
348
  marginBottom: '8px',
341
349
  } },
342
- React.createElement("svg", { style: { width: '20px', height: '20px', color: '#FA931C' }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
350
+ React.createElement("svg", { style: { width: '20px', height: '20px', color: 'var(--accent, #FA931C)' }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
343
351
  React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" })),
344
- React.createElement("h4", { style: { fontWeight: '600', color: '#1f2937', fontSize: '14px' } }, "Call Summary")),
345
- React.createElement("p", { style: { fontSize: '14px', color: '#1f2937', lineHeight: '1.6' } }, status.summary)))),
346
- showTranscript && status.transcript && status.transcript.length > 0 && (React.createElement(TranscriptViewer, { transcript: status.transcript })),
347
- React.createElement("style", null, `
348
- @keyframes pulse {
349
- 0%, 100% {
350
- opacity: 1;
351
- }
352
- 50% {
353
- opacity: 0.5;
354
- }
355
- }
356
- `)));
352
+ React.createElement("h4", { style: { fontWeight: '600', color: 'var(--text-primary, #1f2937)', fontSize: '14px' } }, "Call Summary")),
353
+ React.createElement("p", { style: { fontSize: '14px', color: 'var(--text-primary, #1f2937)', lineHeight: '1.6' } }, status.summary)))),
354
+ showTranscript && status.transcript && status.transcript.length > 0 && (React.createElement(TranscriptViewer, { transcript: status.transcript }))));
357
355
  }
358
356
 
359
357
  function CallHistory({ limit = 10, onCallSelect, className = '', }) {
@@ -361,19 +359,37 @@ function CallHistory({ limit = 10, onCallSelect, className = '', }) {
361
359
  const [calls, setCalls] = useState([]);
362
360
  const [loading, setLoading] = useState(true);
363
361
  const [error, setError] = useState(null);
364
- // Note: This requires a list endpoint in the API
365
- // For now, this is a placeholder that shows the structure
366
362
  useEffect(() => {
367
- // TODO: Implement when /api/b2b/v1/calls list endpoint is available
368
- setLoading(false);
369
- }, [client]);
363
+ let isMounted = true;
364
+ const fetchCalls = async () => {
365
+ try {
366
+ const response = await client.listCalls({ limit });
367
+ if (!isMounted) {
368
+ return;
369
+ }
370
+ setCalls(response.items || []);
371
+ setLoading(false);
372
+ }
373
+ catch (err) {
374
+ if (!isMounted) {
375
+ return;
376
+ }
377
+ setError(err);
378
+ setLoading(false);
379
+ }
380
+ };
381
+ fetchCalls();
382
+ return () => {
383
+ isMounted = false;
384
+ };
385
+ }, [client, limit]);
370
386
  if (loading) {
371
387
  return (React.createElement("div", { className: `pamela-call-history ${className}` },
372
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call history...")));
388
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call history...")));
373
389
  }
374
390
  if (error) {
375
391
  return (React.createElement("div", { className: `pamela-call-history ${className}` },
376
- React.createElement("div", { style: { color: '#ef4444', fontFamily: 'Poppins, Inter, sans-serif' } },
392
+ React.createElement("div", { style: { color: 'var(--status-error, #ef4444)', fontFamily: 'Poppins, Inter, sans-serif' } },
377
393
  "Error: ",
378
394
  error.message)));
379
395
  }
@@ -384,30 +400,30 @@ function CallHistory({ limit = 10, onCallSelect, className = '', }) {
384
400
  marginBottom: '16px',
385
401
  fontSize: '18px',
386
402
  fontWeight: '600',
387
- color: '#1f2937',
403
+ color: 'var(--text-primary, #1f2937)',
388
404
  } }, "Call History"),
389
- calls.length === 0 ? (React.createElement("div", { style: { color: '#6b7280', fontSize: '14px' } }, "No calls yet")) : (React.createElement("div", null, calls.map((call) => (React.createElement("div", { key: call.id, onClick: () => onCallSelect?.(call.id), style: {
405
+ calls.length === 0 ? (React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontSize: '14px' } }, "No calls yet")) : (React.createElement("div", null, calls.map((call) => (React.createElement("div", { key: call.id, onClick: () => onCallSelect?.(call.id), style: {
390
406
  padding: '12px',
391
407
  marginBottom: '8px',
392
- border: '1px solid rgba(231, 171, 132, 0.3)',
393
- borderRadius: '0.5rem',
408
+ border: '1px solid var(--surface-border-strong, rgba(231, 171, 132, 0.3))',
409
+ borderRadius: 'var(--radius-sm, 0.5rem)',
394
410
  cursor: onCallSelect ? 'pointer' : 'default',
395
- backgroundColor: '#ffffff',
411
+ background: 'var(--surface-liquid-strong, #ffffff)',
396
412
  transition: 'background-color 0.2s',
397
413
  ...(onCallSelect && {
398
414
  ':hover': {
399
- backgroundColor: '#F7F4ED',
415
+ backgroundColor: 'var(--surface, #F7F4ED)',
400
416
  },
401
417
  }),
402
418
  }, onMouseEnter: (e) => {
403
419
  if (onCallSelect) {
404
- e.currentTarget.style.backgroundColor = '#F7F4ED';
420
+ e.currentTarget.style.backgroundColor = 'var(--surface, #F7F4ED)';
405
421
  }
406
422
  }, onMouseLeave: (e) => {
407
- e.currentTarget.style.backgroundColor = '#ffffff';
423
+ e.currentTarget.style.backgroundColor = 'var(--surface-liquid-strong, #ffffff)';
408
424
  } },
409
- React.createElement("div", { style: { fontWeight: '600', color: '#1f2937', marginBottom: '4px' } }, call.to),
410
- React.createElement("div", { style: { fontSize: '14px', color: '#6b7280' } },
425
+ React.createElement("div", { style: { fontWeight: '600', color: 'var(--text-primary, #1f2937)', marginBottom: '4px' } }, call.to),
426
+ React.createElement("div", { style: { fontSize: '14px', color: 'var(--text-secondary, #6b7280)' } },
411
427
  call.status,
412
428
  " \u2022 ",
413
429
  new Date(call.created_at).toLocaleString()))))))));