Skip to content

Commit 5da4e3b

Browse files
committed
fix: implement accessibility and security improvements for feedback components
1 parent 04e750c commit 5da4e3b

File tree

2 files changed

+114
-74
lines changed

2 files changed

+114
-74
lines changed

apps/dashboard/src/app/(app)/components/Header/SecondaryNav/SecondaryNav.tsx

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type React from "react";
55
import { useState } from "react";
66
import type { ThirdwebClient } from "thirdweb";
77
import { NotificationsButton } from "@/components/notifications/notification-button";
8+
import { NavLink } from "@/components/ui/NavLink";
89
import type { Account } from "@/hooks/useApi";
910
import { AccountButton } from "./account-button.client";
1011
import { ResourcesDropdownButton } from "./ResourcesDropdownButton";
@@ -37,8 +38,12 @@ export function SecondaryNavLinks() {
3738
const [showFeedbackDropdown, setShowFeedbackDropdown] = useState(false);
3839
const [modalFeedback, setModalFeedback] = useState("");
3940

40-
const handleModalSubmit = () => {
41-
console.log("Modal feedback sent:", modalFeedback);
41+
const handleModalSubmit = (e?: React.FormEvent) => {
42+
e?.preventDefault();
43+
// Avoid logging PII in production. Keep minimal diagnostics in dev.
44+
if (process.env.NODE_ENV !== "production") {
45+
console.debug("[feedback] length:", modalFeedback.trim().length);
46+
}
4247
setModalFeedback("");
4348
setShowFeedbackDropdown(false);
4449
};
@@ -71,48 +76,64 @@ export function SecondaryNavLinks() {
7176
</button>
7277

7378
{showFeedbackDropdown && (
74-
<div className="absolute top-full right-0 mt-2 bg-background border border-border rounded-2xl p-3 w-96 z-50">
75-
<h2 className="text-foreground text-base font-sans mb-2">
79+
<div
80+
id="feedback-dropdown"
81+
role="dialog"
82+
aria-labelledby="feedback-heading"
83+
className="absolute top-full right-0 mt-2 bg-background border border-border rounded-2xl p-3 w-96 z-50"
84+
>
85+
<h2
86+
id="feedback-heading"
87+
className="text-foreground text-base font-sans mb-2"
88+
>
7689
Share your feedback with us:
7790
</h2>
91+
<form onSubmit={handleModalSubmit} className="contents">
92+
<label htmlFor="feedback-text" className="sr-only">
93+
Feedback
94+
</label>
95+
<textarea
96+
id="feedback-text"
97+
value={modalFeedback}
98+
onChange={(e) => setModalFeedback(e.target.value)}
99+
maxLength={1000}
100+
aria-describedby="feedback-help"
101+
className="w-full bg-background text-foreground rounded-lg p-4 min-h-[120px] resize-none border border-border focus:border-border focus:outline-none placeholder-muted-foreground font-sans mb-4 text-sm"
102+
placeholder="Tell us what you think..."
103+
/>
78104

79-
<textarea
80-
value={modalFeedback}
81-
onChange={(e) => setModalFeedback(e.target.value)}
82-
className="w-full bg-background text-foreground rounded-lg p-4 min-h-[120px] resize-none border border-border focus:border-border focus:outline-none placeholder-muted-foreground font-sans mb-4 text-sm"
83-
placeholder="Tell us what you think..."
84-
/>
85-
86-
<div className="flex items-start justify-between gap-4">
87-
<div className="text-muted-foreground text-xs font-sans">
88-
<div>Have a technical issue?</div>
89-
<div>
90-
<Link
91-
href="/team/~/~/support"
92-
className="underline hover:text-foreground transition-colors"
105+
<div className="flex items-start justify-between gap-4">
106+
<div className="text-muted-foreground text-xs font-sans">
107+
<div>Have a technical issue?</div>
108+
<div>
109+
<NavLink
110+
href="/team/~/support"
111+
className="underline hover:text-foreground transition-colors"
112+
>
113+
Contact support
114+
</NavLink>
115+
.
116+
</div>
117+
</div>
118+
<div className="flex gap-2 flex-shrink-0">
119+
<button
120+
type="button"
121+
onClick={handleModalCancel}
122+
className="bg-transparent text-foreground px-4 py-1.5 rounded-full font-sans text-sm border border-border hover:bg-muted transition-colors"
93123
>
94-
Contact support
95-
</Link>
96-
.
124+
Cancel
125+
</button>
126+
<button
127+
type="submit"
128+
disabled={!modalFeedback.trim()}
129+
aria-disabled={!modalFeedback.trim()}
130+
className="bg-primary text-primary-foreground px-4 py-1.5 rounded-full font-sans text-sm hover:bg-primary/90 transition-colors disabled:opacity-50"
131+
>
132+
Submit
133+
</button>
97134
</div>
98135
</div>
99-
<div className="flex gap-2 flex-shrink-0">
100-
<button
101-
type="button"
102-
onClick={handleModalCancel}
103-
className="bg-transparent text-foreground px-4 py-1.5 rounded-full font-sans text-sm border border-border hover:bg-muted transition-colors"
104-
>
105-
Cancel
106-
</button>
107-
<button
108-
type="button"
109-
onClick={handleModalSubmit}
110-
className="bg-primary text-primary-foreground px-4 py-1.5 rounded-full font-sans text-sm hover:bg-primary/90 transition-colors"
111-
>
112-
Submit
113-
</button>
114-
</div>
115-
</div>
136+
</form>
116137
</div>
117138
)}
118139
</div>

apps/dashboard/src/app/(app)/components/MobileBurgerMenuButton.tsx

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useTheme } from "next-themes";
1616
import { useLayoutEffect, useState } from "react";
1717
import type { ThirdwebClient } from "thirdweb";
1818
import { Button } from "@/components/ui/button";
19+
import { NavLink } from "@/components/ui/NavLink";
1920
import { Separator } from "@/components/ui/separator";
2021
import { SkeletonContainer } from "@/components/ui/skeleton";
2122
import { useEns } from "@/hooks/contract-hooks";
@@ -48,8 +49,12 @@ export function MobileBurgerMenuButton(
4849
});
4950
// const [isCMDSearchModalOpen, setIsCMDSearchModalOpen] = useState(false);
5051

51-
const handleModalSubmit = () => {
52-
console.log("Modal feedback sent:", modalFeedback);
52+
const handleModalSubmit = (e?: React.FormEvent) => {
53+
e?.preventDefault();
54+
// Avoid logging PII in production. Keep minimal diagnostics in dev.
55+
if (process.env.NODE_ENV !== "production") {
56+
console.debug("[feedback] length:", modalFeedback.trim().length);
57+
}
5358
setModalFeedback("");
5459
setShowFeedbackSection(false);
5560
};
@@ -222,45 +227,59 @@ export function MobileBurgerMenuButton(
222227

223228
{showFeedbackSection && (
224229
<div className="pl-0 pr-4 space-y-4 mb-6">
225-
<h3 className="text-sm font-medium text-foreground">
230+
<h3
231+
id="mobile-feedback-heading"
232+
className="text-sm font-medium text-foreground mb-2"
233+
>
226234
Share your feedback with us:
227235
</h3>
236+
<form onSubmit={handleModalSubmit} className="contents">
237+
<label htmlFor="mobile-feedback-text" className="sr-only">
238+
Feedback
239+
</label>
240+
<textarea
241+
id="mobile-feedback-text"
242+
value={modalFeedback}
243+
onChange={(e) => setModalFeedback(e.target.value)}
244+
maxLength={1000}
245+
aria-describedby="mobile-feedback-help"
246+
className="w-full bg-background text-foreground rounded-lg p-3 min-h-[100px] resize-none border border-border focus:border-border focus:outline-none placeholder-muted-foreground font-sans text-sm"
247+
placeholder="Tell us what you think..."
248+
/>
228249

229-
<textarea
230-
value={modalFeedback}
231-
onChange={(e) => setModalFeedback(e.target.value)}
232-
className="w-full bg-background text-foreground rounded-lg p-3 min-h-[100px] resize-none border border-border focus:border-border focus:outline-none placeholder-muted-foreground font-sans text-sm"
233-
placeholder="Tell us what you think..."
234-
/>
235-
236-
<div className="flex flex-col gap-3">
237-
<p className="text-muted-foreground text-xs">
238-
Have a technical issue?{" "}
239-
<Link
240-
href="/team/~/~/support"
241-
className="underline hover:text-foreground transition-colors"
242-
>
243-
Contact support
244-
</Link>
245-
.
246-
</p>
247-
<div className="flex gap-3">
248-
<button
249-
type="button"
250-
onClick={handleModalCancel}
251-
className="flex-1 bg-transparent text-foreground px-3 py-2 rounded-full font-sans text-sm border border-border hover:bg-muted transition-colors"
252-
>
253-
Cancel
254-
</button>
255-
<button
256-
type="button"
257-
onClick={handleModalSubmit}
258-
className="flex-1 bg-primary text-primary-foreground px-3 py-2 rounded-full font-sans text-sm hover:bg-primary/90 transition-colors"
250+
<div className="flex flex-col gap-3">
251+
<p
252+
id="mobile-feedback-help"
253+
className="text-muted-foreground text-xs"
259254
>
260-
Submit
261-
</button>
255+
Have a technical issue?{" "}
256+
<NavLink
257+
href="/team/~/support"
258+
className="underline hover:text-foreground transition-colors"
259+
>
260+
Contact support
261+
</NavLink>
262+
.
263+
</p>
264+
<div className="flex gap-3">
265+
<button
266+
type="button"
267+
onClick={handleModalCancel}
268+
className="flex-1 bg-transparent text-foreground px-3 py-2 rounded-full font-sans text-sm border border-border hover:bg-muted transition-colors"
269+
>
270+
Cancel
271+
</button>
272+
<button
273+
type="submit"
274+
disabled={!modalFeedback.trim()}
275+
aria-disabled={!modalFeedback.trim()}
276+
className="flex-1 bg-primary text-primary-foreground px-3 py-2 rounded-full font-sans text-sm hover:bg-primary/90 transition-colors disabled:opacity-50"
277+
>
278+
Submit
279+
</button>
280+
</div>
262281
</div>
263-
</div>
282+
</form>
264283
</div>
265284
)}
266285
</div>

0 commit comments

Comments
 (0)