From e61eb0f417b36577513f9fb27d23f87d5bed577b Mon Sep 17 00:00:00 2001
From: Alejandro <95312462+AGMASO@users.noreply.github.com>
Date: Mon, 27 Oct 2025 12:18:52 +0100
Subject: [PATCH 1/3] feat: send rich info to support and track submit event
---
pages/api/support-create-ticket.ts | 20 +++++++++-
src/layouts/SupportModal.tsx | 60 +++++++++++++++++++++++++++++-
src/locales/el/messages.js | 2 +-
src/locales/en/messages.js | 2 +-
src/locales/en/messages.po | 4 ++
src/locales/es/messages.js | 2 +-
src/locales/fr/messages.js | 2 +-
src/utils/events.ts | 3 ++
8 files changed, 88 insertions(+), 7 deletions(-)
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..13fb2321db 100644
--- a/src/layouts/SupportModal.tsx
+++ b/src/layouts/SupportModal.tsx
@@ -1,17 +1,31 @@
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 { CONSENT_KEY } from 'src/store/analyticsSlice';
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 [account, trackEvent] = useRootStore(
+ useShallow((store) => [store.account, store.trackEvent])
+ );
const [value, setValue] = useState('');
const [isLoading, setIsLoading] = useState(false);
@@ -20,6 +34,8 @@ export const SupportModal = () => {
const [email, setEmail] = useState('');
const [emailError, setEmailError] = useState('');
const [dirtyEmailField, setDirtyEmailField] = useState(false);
+ const [hasOptedIn, setHasOptedIn] = useState(false);
+ const [isShareWalletApproved, setIsShareWalletApproved] = useState(false);
const onBlur = () => {
if (!dirtyEmailField) setDirtyEmailField(true);
@@ -27,6 +43,10 @@ export const SupportModal = () => {
useEffect(() => {
if (feedbackDialogOpen) {
+ const optInStatus =
+ typeof window !== 'undefined' ? localStorage.getItem(CONSENT_KEY) === 'true' : false;
+
+ setHasOptedIn(optInStatus);
setSuccess(false);
setError(false);
setEmailError('');
@@ -56,10 +76,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 +95,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 +119,7 @@ export const SupportModal = () => {
setEmailError('');
setEmail('');
setValue('');
+ setIsShareWalletApproved(false);
setDirtyEmailField(false);
setSuccess(false);
setError(false);
@@ -234,6 +262,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
+
+
+
+ }
+ />
+ ) : (
+ ''
+ )}
+
+ )}