@@ -86,7 +86,7 @@ const integrationColorIcons = {
8686
8787const IconPlaceholder = IconSettingsCog
8888
89- const PRO_ONLY_INTEGRATIONS = [ "notion" , "github" , "slack" , "discord" , "trello" ]
89+ const PRO_ONLY_INTEGRATIONS = [ "notion" , "github" , "slack" , "discord" , "trello" , "whatsapp" ]
9090
9191const proPlanFeatures = [
9292 { name : "Text Chat" , limit : "100 messages per day" } ,
@@ -174,9 +174,9 @@ const UpgradeToProModal = ({ isOpen, onClose }) => {
174174 </ button >
175175 < button
176176 onClick = { onClose }
177- className = "w-full py-2 px-5 rounded-lg hover:bg-neutral-800 text-sm font-medium text-neutral-400 "
177+ className = "w-full py-2 px-5 rounded-lg hover:bg-neutral-800 transition-colors "
178178 >
179- Not now
179+ Cancel
180180 </ button >
181181 </ footer >
182182 </ motion . div >
@@ -186,11 +186,54 @@ const UpgradeToProModal = ({ isOpen, onClose }) => {
186186 )
187187}
188188
189+ const WhatsAppDisclaimerModal = ( { isOpen, onAgree, onClose } ) => {
190+ // This modal doesn't need to know if it's open, the parent handles it.
191+ // But we keep the prop for clarity and potential internal logic.
192+ if ( ! isOpen ) return null
193+
194+ return (
195+ < ModalDialog
196+ title = {
197+ < div className = "flex items-center gap-2" >
198+ < IconBrandWhatsapp />
199+ < span > WhatsApp Disclaimer</ span >
200+ </ div >
201+ }
202+ description = "Please review the following before connecting your WhatsApp account."
203+ onCancel = { onClose }
204+ onConfirm = { onAgree }
205+ confirmButtonText = "Agree and Connect"
206+ extraContent = {
207+ < div className = "text-sm text-neutral-300 space-y-3 pt-2" >
208+ < p >
209+ By proceeding, you acknowledge that you have read and
210+ agree to the{ " " }
211+ < a
212+ href = "https://www.whatsapp.com/legal/terms-of-service"
213+ target = "_blank"
214+ rel = "noopener noreferrer"
215+ className = "text-blue-400 hover:underline"
216+ >
217+ WhatsApp Terms of Service by Meta
218+ </ a >
219+ .
220+ </ p >
221+ < p >
222+ Connecting this integration allows Sentient to act on
223+ your behalf to: read your messages, send messages, and
224+ manage your chats and contacts.
225+ </ p >
226+ </ div >
227+ }
228+ />
229+ )
230+ }
231+
189232const MANUAL_INTEGRATION_CONFIGS = { } // Manual integrations removed for Slack and Notion
190233
191234const WhatsAppQRCodeModal = ( { onClose } ) => {
192235 const [ qrCode , setQrCode ] = useState ( null )
193- const [ status , setStatus ] = useState ( "initiating" ) // initiating, scanning, working, error
236+ const [ status , setStatus ] = useState ( "initiating" ) // initiating, scanning, working,const WhatsAppQRCodeModal = ({ onClose }) => {
194237 const [ error , setError ] = useState ( "" )
195238 const intervalRef = useRef ( null )
196239
@@ -212,15 +255,15 @@ const WhatsAppQRCodeModal = ({ onClose }) => {
212255 }
213256 if ( data . status === "WORKING" ) {
214257 setStatus ( "working" )
215- stopPolling ( )
216258 toast . success ( "WhatsApp connected successfully!" )
259+ stopPolling ( )
217260 setTimeout ( onClose , 1500 )
218261 } else if ( data . status === "FAILED" ) {
219262 setError ( "Connection failed. Please close this and try again." )
220263 setStatus ( "error" )
221264 stopPolling ( )
222265 } else {
223- setStatus ( "scanning" ) // Still waiting for scan
266+ setStatus ( "scanning" )
224267 }
225268 } catch ( err ) {
226269 setError ( err . message )
@@ -241,11 +284,13 @@ const WhatsAppQRCodeModal = ({ onClose }) => {
241284 if ( ! res . ok ) {
242285 throw new Error ( data . error || "Failed to get QR code" )
243286 }
244- // WAHA returns base64 image data in the 'data' field
245287 setQrCode ( data . data )
246288 setStatus ( "scanning" )
247- // Start polling for status
248- intervalRef . current = setInterval ( pollStatus , 3000 )
289+
290+ // Start polling for status if not already started
291+ if ( ! intervalRef . current ) {
292+ intervalRef . current = setInterval ( pollStatus , 3000 )
293+ }
249294 } catch ( err ) {
250295 setError ( err . message )
251296 setStatus ( "error" )
@@ -254,9 +299,10 @@ const WhatsAppQRCodeModal = ({ onClose }) => {
254299
255300 useEffect ( ( ) => {
256301 initiateConnection ( )
257- // Cleanup on unmount
258- return ( ) => stopPolling ( )
259- } , [ initiateConnection ] )
302+ return ( ) => {
303+ stopPolling ( )
304+ }
305+ } , [ initiateConnection , stopPolling ] )
260306
261307 return (
262308 < motion . div
@@ -751,6 +797,7 @@ const IntegrationsPage = () => {
751797 const [ activeCategory , setActiveCategory ] = useState ( "Most Popular" )
752798 const [ selectedIntegration , setSelectedIntegration ] = useState ( null )
753799 const [ activeManualIntegration , setActiveManualIntegration ] = useState ( null )
800+ const [ isWhatsAppDisclaimerOpen , setIsWhatsAppDisclaimerOpen ] = useState ( false )
754801 const [ isWhatsAppQRModalOpen , setIsWhatsAppQRModalOpen ] = useState ( false )
755802 const [ sparkleTrigger , setSparkleTrigger ] = useState ( 0 )
756803 const [ privacyModalService , setPrivacyModalService ] = useState ( null )
@@ -1364,9 +1411,11 @@ const IntegrationsPage = () => {
13641411 onClick = { async ( e ) => {
13651412 e . stopPropagation ( )
13661413 if (
1367- integration . name === "whatsapp"
1414+ integration . name ===
1415+ "whatsapp"
13681416 ) {
1369- setIsWhatsAppQRModalOpen ( true )
1417+ // Show disclaimer first
1418+ setIsWhatsAppDisclaimerOpen ( true )
13701419 } else if (
13711420 integration . auth_type ===
13721421 "composio"
@@ -1407,6 +1456,24 @@ const IntegrationsPage = () => {
14071456 place = "right-start"
14081457 style = { { zIndex : 9999 } }
14091458 />
1459+ < AnimatePresence >
1460+ { isWhatsAppDisclaimerOpen && (
1461+ < div className = "isolate z-[120]" >
1462+ < WhatsAppDisclaimerModal
1463+ isOpen = { isWhatsAppDisclaimerOpen }
1464+ onClose = { ( ) => setIsWhatsAppDisclaimerOpen ( false ) }
1465+ onAgree = { ( ) => {
1466+ setIsWhatsAppDisclaimerOpen ( false )
1467+ setIsWhatsAppQRModalOpen ( true )
1468+ } }
1469+ />
1470+ </ div >
1471+ ) }
1472+ </ AnimatePresence >
1473+ < UpgradeToProModal
1474+ isOpen = { isUpgradeModalOpen }
1475+ onClose = { ( ) => setUpgradeModalOpen ( false ) }
1476+ />
14101477 < UpgradeToProModal
14111478 isOpen = { isUpgradeModalOpen }
14121479 onClose = { ( ) => setUpgradeModalOpen ( false ) }
@@ -1561,4 +1628,4 @@ const IntegrationsPage = () => {
15611628 )
15621629}
15631630
1564- export default IntegrationsPage
1631+ export default IntegrationsPage
0 commit comments