onairos 2.2.0 → 2.2.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.
@@ -1,16 +1,16 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
 
3
- // Platform connectors with correct icons
4
- const platformConnectors = [
5
- { name: 'YouTube', icon: '📺', color: 'bg-red-500', connector: 'youtube' },
6
- { name: 'LinkedIn', icon: '💼', color: 'bg-blue-700', connector: 'linkedin' },
7
- { name: 'Reddit', icon: '🔥', color: 'bg-orange-500', connector: 'reddit' },
8
- { name: 'Pinterest', icon: '📌', color: 'bg-red-600', connector: 'pinterest' },
9
- { name: 'Instagram', icon: '📷', color: 'bg-pink-500', connector: 'instagram' },
10
- { name: 'GitHub', icon: '⚡', color: 'bg-gray-800', connector: 'github' },
11
- { name: 'Facebook', icon: '👥', color: 'bg-blue-600', connector: 'facebook' },
12
- { name: 'Gmail', icon: '✉️', color: 'bg-red-400', connector: 'gmail' }
13
- ];
3
+ // Remove the platform connectors - these should be handled in onboarding
4
+ // const platformConnectors = [
5
+ // { name: 'YouTube', icon: '📺', color: 'bg-red-500', connector: 'youtube' },
6
+ // { name: 'LinkedIn', icon: '💼', color: 'bg-blue-700', connector: 'linkedin' },
7
+ // { name: 'Reddit', icon: '🔥', color: 'bg-orange-500', connector: 'reddit' },
8
+ // { name: 'Pinterest', icon: '📌', color: 'bg-red-600', connector: 'pinterest' },
9
+ // { name: 'Instagram', icon: '📷', color: 'bg-pink-500', connector: 'instagram' },
10
+ // { name: 'GitHub', icon: '⚡', color: 'bg-gray-800', connector: 'github' },
11
+ // { name: 'Facebook', icon: '👥', color: 'bg-blue-600', connector: 'facebook' },
12
+ // { name: 'Gmail', icon: '✉️', color: 'bg-red-400', connector: 'gmail' }
13
+ // ];
14
14
 
15
15
  const dataTypes = [
16
16
  {
@@ -37,7 +37,7 @@ const dataTypes = [
37
37
  description: 'User preferences, interests, settings and personal choices',
38
38
  icon: '⚙️',
39
39
  required: false,
40
- tooltip: 'Your likes, interests, content preferences, and behavioral patterns. Helps create a more personalized experience.',
40
+ tooltip: 'Your stated preferences and interests from connected platforms. Helps customize your experience.',
41
41
  privacyLink: 'https://onairos.uk/privacy#preferences-data'
42
42
  }
43
43
  ];
@@ -86,23 +86,24 @@ export default function DataRequest({
86
86
  preferences: false
87
87
  });
88
88
 
89
- const [connectorStates, setConnectorStates] = useState({});
89
+ // Remove connector states - not needed for data request
90
+ // const [connectorStates, setConnectorStates] = useState({});
90
91
  const [isSubmitting, setIsSubmitting] = useState(false);
91
92
  const [isLoadingApi, setIsLoadingApi] = useState(false);
92
93
  const [apiResponse, setApiResponse] = useState(null);
93
94
  const [apiError, setApiError] = useState(null);
94
95
 
95
- // Initialize connector states based on connected accounts
96
- useEffect(() => {
97
- const initialStates = {};
98
- platformConnectors.forEach(platform => {
99
- initialStates[platform.name] = {
100
- connected: connectedAccounts[platform.name] || false,
101
- selected: false
102
- };
103
- });
104
- setConnectorStates(initialStates);
105
- }, [connectedAccounts]);
96
+ // Remove connector initialization - not needed
97
+ // useEffect(() => {
98
+ // const initialStates = {};
99
+ // platformConnectors.forEach(platform => {
100
+ // initialStates[platform.name] = {
101
+ // connected: connectedAccounts[platform.name] || false,
102
+ // selected: false
103
+ // };
104
+ // });
105
+ // setConnectorStates(initialStates);
106
+ // }, [connectedAccounts]);
106
107
 
107
108
  const handleDataToggle = (dataId) => {
108
109
  // Don't allow toggling required items
@@ -115,15 +116,7 @@ export default function DataRequest({
115
116
  }));
116
117
  };
117
118
 
118
- const handleConnectorToggle = (platformName) => {
119
- setConnectorStates(prev => ({
120
- ...prev,
121
- [platformName]: {
122
- ...prev[platformName],
123
- selected: !prev[platformName]?.selected
124
- }
125
- }));
126
- };
119
+ // handleConnectorToggle removed - connectors are handled in onboarding
127
120
 
128
121
  const handleRowClick = (dataId) => {
129
122
  const dataType = dataTypes.find(dt => dt.id === dataId);
@@ -155,9 +148,9 @@ export default function DataRequest({
155
148
  .map(([key]) => key);
156
149
 
157
150
  // Get selected connectors
158
- const selectedConnectors = Object.entries(connectorStates)
159
- .filter(([platform, state]) => state.selected && state.connected)
160
- .map(([platform]) => platform);
151
+ // const selectedConnectors = Object.entries(connectorStates)
152
+ // .filter(([platform, state]) => state.selected && state.connected)
153
+ // .map(([platform]) => platform);
161
154
 
162
155
  const mapDataTypesToConfirmations = (approvedData) => {
163
156
  const confirmations = [];
@@ -189,7 +182,7 @@ export default function DataRequest({
189
182
  userHash,
190
183
  appName,
191
184
  approvedData,
192
- selectedConnectors,
185
+ // selectedConnectors, // Removed as connectors are handled in onboarding
193
186
  apiUrl: apiEndpoint,
194
187
  testMode,
195
188
  timestamp: new Date().toISOString()
@@ -201,7 +194,7 @@ export default function DataRequest({
201
194
 
202
195
  const requestBody = testMode ? {
203
196
  approvedData,
204
- selectedConnectors,
197
+ // selectedConnectors, // Removed as connectors are handled in onboarding
205
198
  userEmail,
206
199
  appName,
207
200
  testMode,
@@ -211,7 +204,7 @@ export default function DataRequest({
211
204
  storage: "local",
212
205
  appId: appName,
213
206
  confirmations: confirmations,
214
- connectors: selectedConnectors,
207
+ // connectors: selectedConnectors, // Removed as connectors are handled in onboarding
215
208
  EncryptedUserPin: "pending_pin_integration",
216
209
  account: userEmail,
217
210
  proofMode: false,
@@ -297,8 +290,8 @@ export default function DataRequest({
297
290
  };
298
291
 
299
292
  const selectedCount = Object.values(selectedData).filter(Boolean).length;
300
- const selectedConnectorCount = Object.values(connectorStates).filter(state => state.selected).length;
301
- const connectedCount = Object.values(connectorStates).filter(state => state.connected).length;
293
+ // const selectedConnectorCount = Object.values(connectorStates).filter(state => state.selected).length; // Removed as connectors are handled in onboarding
294
+ // const connectedCount = Object.values(connectorStates).filter(state => state.connected).length; // Removed as connectors are handled in onboarding
302
295
 
303
296
  return (
304
297
  <div className="w-full max-w-md mx-auto bg-white rounded-lg shadow-xl overflow-hidden" style={{ maxHeight: '90vh', height: 'auto' }}>
@@ -378,65 +371,10 @@ export default function DataRequest({
378
371
  </div>
379
372
  </div>
380
373
 
381
- {/* Platform Connectors */}
382
- <div className="mb-6">
383
- <h3 className="text-md font-semibold text-gray-900 mb-3">Data Connectors</h3>
384
- <p className="text-xs text-gray-600 mb-3">Select connected platforms to include their data</p>
385
-
386
- <div className="grid grid-cols-2 gap-2">
387
- {platformConnectors.map((platform) => {
388
- const connectorState = connectorStates[platform.name];
389
- const isConnected = connectorState?.connected || false;
390
- const isSelected = connectorState?.selected || false;
391
-
392
- return (
393
- <div
394
- key={platform.name}
395
- className={`p-2 border rounded-lg transition-all duration-200 cursor-pointer ${
396
- !isConnected ? 'opacity-50 cursor-not-allowed border-gray-200 bg-gray-50' :
397
- isSelected ? 'border-green-400 bg-green-50' :
398
- 'border-gray-200 bg-white hover:border-gray-300'
399
- }`}
400
- onClick={() => isConnected && handleConnectorToggle(platform.name)}
401
- >
402
- <div className={`w-6 h-6 rounded ${platform.color} flex items-center justify-center text-white text-sm mb-2 mx-auto relative`}>
403
- {platform.icon}
404
-
405
- {/* Connection Status Indicator */}
406
- {isConnected && isSelected && (
407
- <div className="absolute -top-1 -right-1 w-3 h-3 bg-green-500 rounded-full flex items-center justify-center">
408
- <svg className="w-2 h-2 text-white" fill="currentColor" viewBox="0 0 20 20">
409
- <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
410
- </svg>
411
- </div>
412
- )}
413
- </div>
414
-
415
- <div className="text-center">
416
- <h4 className="font-medium text-gray-900 text-xs">{platform.name}</h4>
417
- <p className={`text-xs ${
418
- isConnected ? (isSelected ? 'text-green-600' : 'text-blue-600') : 'text-gray-400'
419
- }`}>
420
- {!isConnected ? 'Not connected' :
421
- isSelected ? 'Selected' : 'Tap to select'}
422
- </p>
423
- </div>
424
- </div>
425
- );
426
- })}
427
- </div>
428
-
429
- {connectedCount === 0 && (
430
- <p className="text-xs text-yellow-600 mt-2 text-center">
431
- ⚠️ No platforms connected. Connect platforms in onboarding to select data sources.
432
- </p>
433
- )}
434
- </div>
435
-
436
374
  {/* Selection Summary */}
437
375
  <div className="mb-3 sm:mb-4 p-2 sm:p-3 bg-green-50 border border-green-200 rounded-lg">
438
376
  <p className="text-green-800 text-xs sm:text-sm">
439
- ✅ {selectedCount} data type{selectedCount > 1 ? 's' : ''} and {selectedConnectorCount} connector{selectedConnectorCount > 1 ? 's' : ''} selected
377
+ ✅ {selectedCount} data type{selectedCount > 1 ? 's' : ''} selected
440
378
  </p>
441
379
  </div>
442
380
 
@@ -8,46 +8,106 @@ function Box({
8
8
  setSelected,
9
9
  number,
10
10
  type,
11
- title}) {
11
+ title
12
+ }) {
12
13
  const [isChecked, setIsChecked] = useState(false);
13
14
 
14
15
  const handleCheckboxChange = (newState) => {
15
16
  setIsChecked(newState);
16
- console.log("This data request is active :", active)
17
- console.log("With new Checked state now being: ", newState)
17
+ console.log("This data request is active:", active);
18
+ console.log("With new Checked state now being:", newState);
19
+
18
20
  // Update the counter
19
21
  if (newState) {
20
22
  changeGranted(1);
21
23
  } else {
22
24
  changeGranted(-1);
23
25
  }
24
- // onSelectionChange(type);
26
+
27
+ // Call parent callback if provided
28
+ if (onSelectionChange) {
29
+ onSelectionChange(newState);
30
+ }
25
31
  };
26
32
 
27
- return (
28
- <div className="group">
29
- <div
30
-
31
- >
32
- <input
33
- // disabled={!active}
34
- type="checkbox"
35
- checked={isChecked}
36
- onChange={(e) => {
37
- // setIsChecked(e.target.checked);
38
-
39
- handleCheckboxChange(e.target.checked);
40
- }}
41
- />
33
+ return (
34
+ <div className="group">
35
+ <div className="relative">
36
+ {/* Custom styled checkbox with clear visual feedback */}
37
+ <label className="flex items-center cursor-pointer">
38
+ <div className="relative">
39
+ <input
40
+ type="checkbox"
41
+ checked={isChecked}
42
+ disabled={!active}
43
+ onChange={(e) => handleCheckboxChange(e.target.checked)}
44
+ className="sr-only" // Hide default checkbox
45
+ />
46
+
47
+ {/* Custom checkbox appearance */}
48
+ <div className={`
49
+ w-6 h-6 border-2 rounded-md flex items-center justify-center transition-all duration-200
50
+ ${!active
51
+ ? 'border-gray-300 bg-gray-100 cursor-not-allowed opacity-50'
52
+ : isChecked
53
+ ? 'border-green-500 bg-green-500 shadow-md transform scale-105'
54
+ : 'border-gray-400 bg-white hover:border-green-400 hover:bg-green-50'
55
+ }
56
+ `}>
57
+ {/* Checkmark icon */}
58
+ {isChecked && (
59
+ <svg
60
+ className="w-4 h-4 text-white animate-pulse"
61
+ fill="currentColor"
62
+ viewBox="0 0 20 20"
63
+ >
64
+ <path
65
+ fillRule="evenodd"
66
+ d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
67
+ clipRule="evenodd"
68
+ />
69
+ </svg>
70
+ )}
71
+ </div>
72
+ </div>
73
+
74
+ {/* Selection status text */}
75
+ <span className={`ml-3 text-sm font-medium transition-colors duration-200 ${
76
+ !active
77
+ ? 'text-gray-400'
78
+ : isChecked
79
+ ? 'text-green-600 font-semibold'
80
+ : 'text-gray-700'
81
+ }`}>
82
+ {!active
83
+ ? 'Not available'
84
+ : isChecked
85
+ ? '✓ Selected'
86
+ : 'Click to select'
87
+ }
88
+ </span>
89
+ </label>
90
+
91
+ {/* Selection indicator badge */}
92
+ {isChecked && active && (
93
+ <div className="absolute -top-2 -right-2 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center animate-bounce">
94
+ <svg className="w-2 h-2 text-white" fill="currentColor" viewBox="0 0 20 20">
95
+ <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
96
+ </svg>
97
+ </div>
98
+ )}
99
+ </div>
42
100
  </div>
43
- </div>
44
- );
101
+ );
45
102
  }
46
103
 
47
104
  Box.propTypes = {
48
105
  active: PropTypes.bool.isRequired,
49
- onSelectionChange: PropTypes.func.isRequired,
50
- disabled: PropTypes.bool,
106
+ onSelectionChange: PropTypes.func,
107
+ changeGranted: PropTypes.func.isRequired,
108
+ setSelected: PropTypes.func,
109
+ number: PropTypes.number,
110
+ type: PropTypes.string,
51
111
  title: PropTypes.string.isRequired
52
112
  };
53
113
 
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  export default function IndividualConnection({
@@ -13,35 +13,165 @@ export default function IndividualConnection({
13
13
  onCheckboxChange,
14
14
  }) {
15
15
  return (
16
- <div className="bg-white rounded-lg p-4 shadow border border-gray-200">
17
- <div className="flex items-center justify-between">
18
- <div className="flex items-center space-x-4">
19
- <div className="group">
16
+ <div className={`relative p-4 sm:p-6 rounded-lg overflow-hidden mb-4 transition-all duration-300 border-2 ${
17
+ !active
18
+ ? 'bg-gray-50 border-gray-200 opacity-60'
19
+ : isChecked
20
+ ? 'bg-green-50 border-green-400 shadow-lg transform scale-[1.02] ring-2 ring-green-200'
21
+ : 'bg-white border-gray-300 hover:border-blue-300 hover:shadow-md'
22
+ }`}>
23
+
24
+ {/* Selection Status Indicator */}
25
+ {isChecked && active && (
26
+ <div className="absolute top-2 right-2 w-8 h-8 bg-green-500 rounded-full flex items-center justify-center animate-pulse shadow-lg">
27
+ <svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 20 20">
28
+ <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
29
+ </svg>
30
+ </div>
31
+ )}
32
+
33
+ <div className="relative">
34
+ {/* Header with title and status */}
35
+ <div className="flex items-center justify-between mb-4">
36
+ <div className="flex items-center space-x-4">
37
+ {/* Data type icon */}
38
+ <div className={`w-12 h-12 rounded-full flex items-center justify-center text-2xl transition-all duration-300 ${
39
+ !active
40
+ ? 'bg-gray-200 text-gray-400'
41
+ : isChecked
42
+ ? 'bg-green-500 text-white shadow-lg'
43
+ : 'bg-blue-500 text-white'
44
+ }`}>
45
+ {title === "Avatar" ? "👤" :
46
+ title === "Traits" ? "🧠" :
47
+ title === "Personality" ? "🎭" : "📊"}
48
+ </div>
49
+
20
50
  <div>
51
+ <h3 className={`text-xl font-bold ${
52
+ !active ? 'text-gray-400' : isChecked ? 'text-green-700' : 'text-gray-800'
53
+ }`}>
54
+ {title === "Avatar" ? 'Avatar' :
55
+ title === "Traits" ? 'Personality Traits' :
56
+ title === "Personality" ? 'Personality Model' :
57
+ title}
58
+ </h3>
59
+
60
+ {/* Status badge */}
61
+ <div className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold ${
62
+ !active
63
+ ? 'bg-red-100 text-red-700'
64
+ : isChecked
65
+ ? 'bg-green-100 text-green-700'
66
+ : 'bg-blue-100 text-blue-700'
67
+ }`}>
68
+ {!active ? '❌ Not Available' : isChecked ? '✅ SELECTED' : '⏳ Available'}
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ {/* Enhanced Checkbox */}
75
+ <div className="flex items-center justify-center mb-4">
76
+ <label className="flex items-center cursor-pointer">
77
+ <div className="relative">
21
78
  <input
22
- disabled={!active}
23
79
  type="checkbox"
24
80
  checked={isChecked}
81
+ disabled={!active}
25
82
  onChange={(e) => onCheckboxChange(e.target.checked)}
83
+ className="sr-only" // Hide default checkbox
26
84
  />
85
+
86
+ {/* Custom checkbox appearance */}
87
+ <div className={`
88
+ w-8 h-8 border-3 rounded-lg flex items-center justify-center transition-all duration-200
89
+ ${!active
90
+ ? 'border-gray-300 bg-gray-100 cursor-not-allowed opacity-50'
91
+ : isChecked
92
+ ? 'border-green-500 bg-green-500 shadow-xl transform scale-110'
93
+ : 'border-gray-400 bg-white hover:border-green-400 hover:bg-green-50 hover:scale-105'
94
+ }
95
+ `}>
96
+ {/* Checkmark icon */}
97
+ {isChecked && (
98
+ <svg
99
+ className="w-6 h-6 text-white animate-bounce"
100
+ fill="currentColor"
101
+ viewBox="0 0 20 20"
102
+ >
103
+ <path
104
+ fillRule="evenodd"
105
+ d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
106
+ clipRule="evenodd"
107
+ />
108
+ </svg>
109
+ )}
110
+ </div>
27
111
  </div>
28
- </div>
112
+
113
+ {/* Selection status text */}
114
+ <span className={`ml-4 text-lg font-bold transition-colors duration-200 ${
115
+ !active
116
+ ? 'text-gray-400'
117
+ : isChecked
118
+ ? 'text-green-600'
119
+ : 'text-gray-700'
120
+ }`}>
121
+ {!active
122
+ ? 'Not available'
123
+ : isChecked
124
+ ? '✓ SELECTED FOR SHARING'
125
+ : 'Click to select'
126
+ }
127
+ </span>
128
+ </label>
29
129
  </div>
30
130
 
31
- <div className="flex items-center">
32
- {/* Optional icons or additional UI elements */}
131
+ {/* Status message for disabled items */}
132
+ <div className="flex items-center justify-center mb-4">
133
+ {!active && (
134
+ <div className="flex items-center space-x-2 text-sm text-red-700 bg-red-100 px-4 py-3 rounded-lg border-2 border-red-300">
135
+ <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
136
+ <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
137
+ </svg>
138
+ <span className="font-bold">
139
+ {`No ${title} data available to share`}
140
+ </span>
141
+ </div>
142
+ )}
143
+
144
+ {isChecked && active && (
145
+ <div className="flex items-center space-x-2 text-sm text-green-700 bg-green-100 px-4 py-3 rounded-lg border-2 border-green-300 animate-pulse">
146
+ <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
147
+ <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
148
+ </svg>
149
+ <span className="font-bold">
150
+ THIS DATA WILL BE SHARED
151
+ </span>
152
+ </div>
153
+ )}
33
154
  </div>
34
155
 
156
+ {/* Description and rewards with enhanced styling */}
35
157
  {descriptions && title !== "Avatar" && (
36
- <p className="text-sm font-medium text-gray-900 dark:text-gray-300">
37
- Intent: {descriptions}
38
- </p>
158
+ <div className="mb-3 p-3 bg-blue-50 rounded-lg border border-blue-200">
159
+ <p className={`text-sm font-semibold ${
160
+ !active ? 'text-gray-400' : 'text-blue-800'
161
+ }`}>
162
+ <span className="text-blue-600">🎯 Intent:</span> {descriptions}
163
+ </p>
164
+ </div>
39
165
  )}
40
166
 
41
167
  {rewards && (
42
- <p className="text-sm font-medium text-gray-900 dark:text-gray-300">
43
- Rewards: {rewards}
44
- </p>
168
+ <div className="mb-3 p-3 bg-yellow-50 rounded-lg border border-yellow-200">
169
+ <p className={`text-sm font-semibold ${
170
+ !active ? 'text-gray-400' : 'text-yellow-800'
171
+ }`}>
172
+ <span className="text-yellow-600">🎁 Rewards:</span> {rewards}
173
+ </p>
174
+ </div>
45
175
  )}
46
176
  </div>
47
177
  </div>