diff --git a/pages/api/support-create-ticket.ts b/pages/api/support-create-ticket.ts index 7c959d1507..801a4dc251 100644 --- a/pages/api/support-create-ticket.ts +++ b/pages/api/support-create-ticket.ts @@ -1,3 +1,4 @@ +import { ethers } from 'ethers'; import type { NextApiRequest, NextApiResponse } from 'next'; import { CREATE_THREAD_MUTATION, UPSERT_CUSTOMER_MUTATION } from './plain-mutations'; @@ -57,7 +58,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } try { - const { email, text } = req.body; + const { email, text, walletAddress } = req.body; if (!email || !text) { return res.status(400).json({ message: 'Email and text are required.' }); @@ -70,6 +71,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) if (!text?.trim()) { return res.status(400).json({ error: 'Missing inquiry' }); } + let sanitizedWalletAddress: string | undefined = undefined; + if (walletAddress && typeof walletAddress === 'string') { + const candidate = walletAddress.trim(); + if (ethers.utils.isAddress(candidate)) { + sanitizedWalletAddress = ethers.utils.getAddress(candidate); + } else { + console.warn('Invalid walletAddress format provided'); + } + } const upsertCustomerVariables = { input: { @@ -109,6 +119,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) customerIdentifier: { emailAddress: email, }, + components: [ { componentText: { @@ -155,6 +166,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }, }, ], + threadFields: [ + { + key: 'wallet_address', + type: 'STRING', + stringValue: sanitizedWalletAddress ?? '', + }, + ], }, }; const result = await makeGraphQLRequest(CREATE_THREAD_MUTATION, createThreadVariables); diff --git a/src/layouts/SupportModal.tsx b/src/layouts/SupportModal.tsx index 93333dd2cd..47158c8748 100644 --- a/src/layouts/SupportModal.tsx +++ b/src/layouts/SupportModal.tsx @@ -1,16 +1,33 @@ import { XIcon } from '@heroicons/react/outline'; import { Trans } from '@lingui/macro'; -import { Box, Button, CircularProgress, SvgIcon, TextField, Typography } from '@mui/material'; +import { + Box, + Button, + Checkbox, + CircularProgress, + FormControlLabel, + SvgIcon, + TextField, + Typography, +} from '@mui/material'; import { FormEvent, useEffect, useState } from 'react'; import { BasicModal } from 'src/components/primitives/BasicModal'; import { Link } from 'src/components/primitives/Link'; import { BaseSuccessView } from 'src/components/transactions/FlowCommons/BaseSuccess'; import { useRootStore } from 'src/store/root'; +import { SUPPORT } from 'src/utils/events'; import { useShallow } from 'zustand/shallow'; export const SupportModal = () => { - const [feedbackDialogOpen, setFeedbackOpen] = useRootStore( - useShallow((state) => [state.feedbackDialogOpen, state.setFeedbackOpen]) + const [feedbackDialogOpen, setFeedbackOpen, isTrackingEnabled] = useRootStore( + useShallow((state) => [ + state.feedbackDialogOpen, + state.setFeedbackOpen, + state.isTrackingEnabled, + ]) + ); + const [account, trackEvent] = useRootStore( + useShallow((store) => [store.account, store.trackEvent]) ); const [value, setValue] = useState(''); @@ -20,7 +37,8 @@ export const SupportModal = () => { const [email, setEmail] = useState(''); const [emailError, setEmailError] = useState(''); const [dirtyEmailField, setDirtyEmailField] = useState(false); - + const [isShareWalletApproved, setIsShareWalletApproved] = useState(false); + const hasOptedIn = isTrackingEnabled; const onBlur = () => { if (!dirtyEmailField) setDirtyEmailField(true); }; @@ -56,10 +74,10 @@ export const SupportModal = () => { setIsLoading(true); const url = '/api/support-create-ticket'; - const payload = { text: value, email: email, + walletAddress: (hasOptedIn || isShareWalletApproved) && account ? account : undefined, }; try { @@ -75,15 +93,22 @@ export const SupportModal = () => { setIsLoading(false); setValue(''); setEmail(''); + setIsShareWalletApproved(false); return; } setSuccess(true); + trackEvent(SUPPORT.TICKET_CREATED, { + type: 'Form', + hasWalletConnected: !!account, + }); } catch (error) { setError(true); + setIsShareWalletApproved(false); } finally { setIsLoading(false); setValue(''); setEmail(''); + setIsShareWalletApproved(false); } }; @@ -92,6 +117,7 @@ export const SupportModal = () => { setEmailError(''); setEmail(''); setValue(''); + setIsShareWalletApproved(false); setDirtyEmailField(false); setSuccess(false); setError(false); @@ -208,7 +234,7 @@ export const SupportModal = () => { sx={{ mb: 2, '& .MuiInputBase-input': { - padding: '6px 12px', + padding: '6px 8px', }, }} /> @@ -234,6 +260,34 @@ export const SupportModal = () => { }, }} /> + + {account && ( + + {!hasOptedIn ? ( + setIsShareWalletApproved(e.target.checked)} + color="primary" + size="small" + /> + } + label={ + + + + Share my wallet address to help the support team resolve my issue + + + + } + /> + ) : ( + '' + )} + + )}