From 10f5a7e1fe6a1ba51d9d72179365d343c393c130 Mon Sep 17 00:00:00 2001 From: Angela Ocando Date: Wed, 25 Feb 2026 16:36:28 -0500 Subject: [PATCH 01/10] fix: connect with us button updates + removing uf references --- docusaurus.config.ts | 6 ++-- src/components/NewsletterForm/index.tsx | 9 +++-- src/pages/index.tsx | 45 +++---------------------- src/theme/Footer.tsx | 30 ++++++++--------- src/theme/Navbar/Content/index.tsx | 2 +- 5 files changed, 28 insertions(+), 64 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index c7edfcf9e..253b9bff1 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -88,13 +88,13 @@ const config: Config = { }, { label: "Give Feedback", - to: 'https://share.hsforms.com/14XvN41xQTyC8KPamgaM8Jwsdca9', + to: 'https://share.hsforms.com/1gMemq5uWQS-UaaorwU-qGAs8pgg', target: '_blank', rel: 'noreferrer', }, { - label: "Uniswap Foundation", - to: 'https://www.uniswapfoundation.org/', + label: "Uniswap Labs", + to: 'https://app.uniswap.org/', target: '_blank', rel: 'noreferrer', }, diff --git a/src/components/NewsletterForm/index.tsx b/src/components/NewsletterForm/index.tsx index 32bdd5660..3fb23525f 100644 --- a/src/components/NewsletterForm/index.tsx +++ b/src/components/NewsletterForm/index.tsx @@ -21,16 +21,15 @@ const NewsletterForm: React.FC = ({
- - + + Sign up
-
- + ) } -export default NewsletterForm +export default NewsletterForm \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6d650f739..51437d9b5 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -124,9 +124,9 @@ const connectBlock = { url: 'https://discord.com/invite/uniswap', name: 'Dev Chat', }, - socialTitle: 'Insights and news from the UF team', + socialTitle: 'News and insights from Uniswap Labs', socialButton: { - url: 'https://www.uniswapfoundation.org/blog', + url: 'https://blog.uniswap.org/', name: 'Blog', }, newsletterTitle: 'Sign up for research and updates from the Uniswap Foundation', @@ -276,41 +276,6 @@ const Home = () => { - -
-
-
-
-

Uniswap Foundation

-

- In pursuit of a more open and fair financial system, the Uniswap Foundation supports the growth, - decentralization, and sustainability of the Uniswap community. -

-
-
- -
- - - -
- - Learn more - - -
-
-
- -
-
-
) @@ -327,13 +292,13 @@ const IconButton: FC<{ return (
{color === 'orange-vibrant' && } {color === 'brown-vibrant' && }
diff --git a/src/theme/Footer.tsx b/src/theme/Footer.tsx index 11bf8dcb0..57d8520d1 100644 --- a/src/theme/Footer.tsx +++ b/src/theme/Footer.tsx @@ -15,7 +15,7 @@ const footerData = { }, { label: 'Feedback', - href: 'https://forms.gle/13XtjmkwdXQ2jMn26', + href: 'https://share.hsforms.com/1gMemq5uWQS-UaaorwU-qGAs8pgg', }, { label: 'Bug Bounty', @@ -31,19 +31,19 @@ const footerData = { title: 'GitHub', links: [ { - label: 'uniswap-v4-core', + label: 'v4-core', href: 'https://github.com/Uniswap/v4-core', }, { - label: 'uniswap-v4-sdk', + label: 'v4-sdk', href: 'https://github.com/Uniswap/sdks/tree/main/sdks/v4-sdk', }, { - label: 'uniswap-v4-periphery', + label: 'v4-periphery', href: 'https://github.com/Uniswap/v4-periphery', }, { - label: 'Deployment addresses', + label: 'Deployments', href: '/contracts/v4/deployments', }, ], @@ -61,7 +61,7 @@ const footerData = { }, { label: 'Token Lists', - href: 'https://tokenlists.org/', + href: 'https://tokenlists.org/token-list?url=https://ipfs.io/ipns/tokens.uniswap.org', }, { label: 'Brand Assets', @@ -73,21 +73,21 @@ const footerData = { title: 'Community', links: [ { - label: 'Blog', - href: 'https://uniswapfoundation.org/blog/', + label: 'X', + href: 'https://twitter.com/Uniswap', }, { - label: 'Governance', - href: 'https://gov.uniswap.org/', + label: 'Blog', + href: 'https://docs.uniswap.org/blog/', }, { - label: 'Uniswap Labs Twitter', - href: 'https://twitter.com/Uniswap', + label: 'Help Center', + href: 'https://support.uniswap.org/hc/en-us', }, { - label: 'Uniswap Foundation Twitter', - href: 'https://x.com/UniswapFND', - }, + label: 'Governance', + href: 'https://gov.uniswap.org/', + } ], }, ], diff --git a/src/theme/Navbar/Content/index.tsx b/src/theme/Navbar/Content/index.tsx index 20836bf3a..e61a79cc9 100644 --- a/src/theme/Navbar/Content/index.tsx +++ b/src/theme/Navbar/Content/index.tsx @@ -86,7 +86,7 @@ export default function NavbarContent(): ReactNode { From 2af616cac7b619404ff6458ec2d8b4c4b2978a63 Mon Sep 17 00:00:00 2001 From: Angela Ocando Date: Wed, 25 Feb 2026 17:23:36 -0500 Subject: [PATCH 02/10] fix: newsletter + ui component back --- src/components/NewsletterForm/index.tsx | 2 +- src/pages/index.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/NewsletterForm/index.tsx b/src/components/NewsletterForm/index.tsx index 3fb23525f..4439de27a 100644 --- a/src/components/NewsletterForm/index.tsx +++ b/src/components/NewsletterForm/index.tsx @@ -21,7 +21,7 @@ const NewsletterForm: React.FC = ({
- + Sign up diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 51437d9b5..2cb29bf86 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -129,7 +129,7 @@ const connectBlock = { url: 'https://blog.uniswap.org/', name: 'Blog', }, - newsletterTitle: 'Sign up for research and updates from the Uniswap Foundation', + newsletterTitle: 'Sign up for developer updates', } const Home = () => { @@ -318,7 +318,7 @@ const ArticleLinkCard: FC<{ return (
From 4edfaadd6d6f02ae285ae9cb965a5a765a695559 Mon Sep 17 00:00:00 2001 From: Angela O <254776627+ocandocrypto-uniswap@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:22:32 -0500 Subject: [PATCH 03/10] Temp feedback form component --- api/feedback.ts | 64 ++++++++ src/components/FeedbackForm.tsx | 256 +++++++++++++++++++++++++++++ src/pages/feedback.tsx | 14 ++ src/theme/Footer.tsx | 2 +- src/theme/Navbar/Content/index.tsx | 5 +- static/img/feedback-banner.webp | Bin 0 -> 142970 bytes 6 files changed, 337 insertions(+), 4 deletions(-) create mode 100644 api/feedback.ts create mode 100644 src/components/FeedbackForm.tsx create mode 100644 src/pages/feedback.tsx create mode 100644 static/img/feedback-banner.webp diff --git a/api/feedback.ts b/api/feedback.ts new file mode 100644 index 000000000..e6332ca12 --- /dev/null +++ b/api/feedback.ts @@ -0,0 +1,64 @@ +const HUBSPOT_PORTAL_ID = '47435488' +const HUBSPOT_FORM_ID = '80c7a6ab-9b96-412f-9469-aa2bc14faa18' +const HUBSPOT_SUBMIT_URL = `https://api.hsforms.com/submissions/v3/integration/submit/${HUBSPOT_PORTAL_ID}/${HUBSPOT_FORM_ID}` + +function isValidEmail(value: string): boolean { + return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) +} + +export default async function handler(req: any, res: any) { + if (req.method !== 'POST') { + return res.status(405).json({ success: false, error: 'Method not allowed' }) + } + + try { + const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body || {} + const { email, feedbackType, issue, followUp, challenges, docsUsefulness, pageUrl, website } = body + + if (website) return res.status(200).json({ success: true }) // honeypot + if (!email || !isValidEmail(email)) return res.status(400).json({ success: false, error: 'Invalid email' }) + if (!feedbackType || !issue) return res.status(400).json({ success: false, error: 'Missing required fields' }) + + const fields = [ + { name: 'email', value: String(email) }, + { name: 'type_of_feedback', value: String(feedbackType) }, + { name: 'whats_the_issue_idea_or_question', value: String(issue) }, + { name: 'can_we_follow_up_with_you_about_your_feedback', value: followUp ? 'Yes' : 'No' }, + ...(challenges?.trim() + ? [{ name: 'what_has_been_the_most_challenging_part_of_building_on_or_integrating_with_uniswap', value: challenges.trim() }] + : []), + ...(docsUsefulness?.trim() + ? [{ name: 'have_you_found_uniswap_docs_to_be_useful', value: docsUsefulness.trim() }] + : []), + ] + + const payload = { + fields, + legalConsentOptions: { + consent: { + consentToProcess: true, + text: 'By submitting, I agree to Uniswap Labs Terms of Service and Privacy Policy.', + }, + }, + context: { + pageUri: pageUrl || '', + pageName: 'Feedback | Uniswap Docs', + }, + } + + const hsRes = await fetch(HUBSPOT_SUBMIT_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }) + + if (!hsRes.ok) { + const hsText = await hsRes.text() + return res.status(502).json({ success: false, error: 'HubSpot submission failed', details: hsText }) + } + + return res.status(200).json({ success: true }) + } catch { + return res.status(500).json({ success: false, error: 'Internal server error' }) + } +} \ No newline at end of file diff --git a/src/components/FeedbackForm.tsx b/src/components/FeedbackForm.tsx new file mode 100644 index 000000000..88b131cc7 --- /dev/null +++ b/src/components/FeedbackForm.tsx @@ -0,0 +1,256 @@ +import React, { useState } from 'react' + +const FEEDBACK_TYPES = ['Bug', 'Feature request', 'Question', 'Other'] as const + +export default function FeedbackForm() { + const [email, setEmail] = useState('') + const [feedbackType, setFeedbackType] = useState<(typeof FEEDBACK_TYPES)[number] | ''>('') + const [followUp, setFollowUp] = useState(null) + const [issue, setIssue] = useState('') + const [challenges, setChallenges] = useState('') + const [docsUsefulness, setDocsUsefulness] = useState('') + const [loading, setLoading] = useState(false) + const [status, setStatus] = useState<'idle' | 'success' | 'error'>('idle') + const [errorMsg, setErrorMsg] = useState('') + const [acceptedTerms, setAcceptedTerms] = useState(false) + + async function onSubmit(e: React.FormEvent) { + e.preventDefault() + setLoading(true) + setStatus('idle') + setErrorMsg('') + + try { + const res = await fetch('/api/feedback', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email, + feedbackType, + issue, + followUp, + challenges, + docsUsefulness, + pageUrl: typeof window !== 'undefined' ? window.location.href : '', + website: '', + }), + }) + + const data = await res.json().catch(() => ({})) + if (!res.ok || !data.success) { + setStatus('error') + setErrorMsg(data?.details || data?.error || 'Failed to submit feedback.') + return + } + + setStatus('success') + setEmail('') + setFeedbackType('Bug') + setIssue('') + setFollowUp(true) + setChallenges('') + setDocsUsefulness('') + } catch { + setStatus('error') + setErrorMsg('Network error. Please try again.') + } finally { + setLoading(false) + } + } + + if (status === 'success') { + return ( +
+
+ Developers banner +
+ +

+ Thanks for submitting your feedback +

+

+ We appreciate it. Your input helps us improve Uniswap Docs. +

+ + +
+ ) + } + + return ( +
+ +
+ Developers banner +
+ + +
+ + setEmail(e.target.value)} + className="mt-2 w-full rounded-large bg-light-surface-1 dark:bg-dark-surface-1 border border-light-surface-3 dark:border-dark-surface-3 p-3 text-light-neutral-1 dark:text-dark-neutral-1" + /> +
+ +
+ +
+ {FEEDBACK_TYPES.map((type) => ( + + ))} +
+
+ +
+ +