Skip to content

Commit 1756aa6

Browse files
0xFirekeeperclaude
andauthored
dashboard: send product feedback to the team (#9032)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 0149b64 commit 1756aa6

3 files changed

Lines changed: 75 additions & 6 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"use server";
2+
import "server-only";
3+
4+
import { getAuthToken } from "@/api/auth-token";
5+
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
6+
7+
export async function submitProductFeedback(request: {
8+
feedback: string;
9+
source: "desktop" | "mobile";
10+
}): Promise<{ ok: true } | { ok: false; error: string }> {
11+
const token = await getAuthToken();
12+
if (!token) {
13+
return { error: "You are not logged in", ok: false };
14+
}
15+
16+
const res = await fetch(
17+
new URL("/v1/account/feedback", NEXT_PUBLIC_THIRDWEB_API_HOST),
18+
{
19+
body: JSON.stringify(request),
20+
headers: {
21+
Authorization: `Bearer ${token}`,
22+
"Content-Type": "application/json",
23+
},
24+
method: "POST",
25+
},
26+
);
27+
28+
if (!res.ok) {
29+
return {
30+
error:
31+
res.status === 429
32+
? "Too many requests, please try again in a minute"
33+
: "Failed to submit feedback, please try again later",
34+
ok: false,
35+
};
36+
}
37+
38+
return { ok: true };
39+
}

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

Lines changed: 17 additions & 3 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 { toast } from "sonner";
77
import type { ThirdwebClient } from "thirdweb";
8+
import { submitProductFeedback } from "@/actions/product-feedback";
89
import { reportProductFeedback } from "@/analytics/report";
910
import { NotificationsButton } from "@/components/notifications/notification-button";
1011
import { NavLink } from "@/components/ui/NavLink";
@@ -39,8 +40,9 @@ export function SecondaryNav(props: {
3940
export function SecondaryNavLinks() {
4041
const [showFeedbackDropdown, setShowFeedbackDropdown] = useState(false);
4142
const [modalFeedback, setModalFeedback] = useState("");
43+
const [isSubmitting, setIsSubmitting] = useState(false);
4244

43-
const handleModalSubmit = (e?: React.FormEvent) => {
45+
const handleModalSubmit = async (e?: React.FormEvent) => {
4446
e?.preventDefault();
4547

4648
// Report feedback to PostHog
@@ -49,6 +51,18 @@ export function SecondaryNavLinks() {
4951
source: "desktop",
5052
});
5153

54+
setIsSubmitting(true);
55+
const result = await submitProductFeedback({
56+
feedback: modalFeedback,
57+
source: "desktop",
58+
});
59+
setIsSubmitting(false);
60+
61+
if (!result.ok) {
62+
toast.error(result.error);
63+
return;
64+
}
65+
5266
// Show success notification
5367
toast.success("Feedback submitted successfully!", {
5468
description: "Thank you for your feedback. We'll review it shortly.",
@@ -135,8 +149,8 @@ export function SecondaryNavLinks() {
135149
</button>
136150
<button
137151
type="submit"
138-
disabled={!modalFeedback.trim()}
139-
aria-disabled={!modalFeedback.trim()}
152+
disabled={!modalFeedback.trim() || isSubmitting}
153+
aria-disabled={!modalFeedback.trim() || isSubmitting}
140154
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"
141155
>
142156
Submit

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

Lines changed: 19 additions & 3 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 { toast } from "sonner";
1818
import type { ThirdwebClient } from "thirdweb";
19+
import { submitProductFeedback } from "@/actions/product-feedback";
1920
import { reportProductFeedback } from "@/analytics/report";
2021
import { Button } from "@/components/ui/button";
2122
import { NavLink } from "@/components/ui/NavLink";
@@ -43,6 +44,7 @@ export function MobileBurgerMenuButton(
4344
const [isMenuOpen, setIsMenuOpen] = useState(false);
4445
const [showFeedbackSection, setShowFeedbackSection] = useState(false);
4546
const [modalFeedback, setModalFeedback] = useState("");
47+
const [isSubmitting, setIsSubmitting] = useState(false);
4648
const { setTheme, theme } = useTheme();
4749
const ensQuery = useEns({
4850
addressOrEnsName:
@@ -51,7 +53,7 @@ export function MobileBurgerMenuButton(
5153
});
5254
// const [isCMDSearchModalOpen, setIsCMDSearchModalOpen] = useState(false);
5355

54-
const handleModalSubmit = (e?: React.FormEvent) => {
56+
const handleModalSubmit = async (e?: React.FormEvent) => {
5557
e?.preventDefault();
5658

5759
// Report feedback to PostHog
@@ -60,6 +62,18 @@ export function MobileBurgerMenuButton(
6062
source: "mobile",
6163
});
6264

65+
setIsSubmitting(true);
66+
const result = await submitProductFeedback({
67+
feedback: modalFeedback,
68+
source: "mobile",
69+
});
70+
setIsSubmitting(false);
71+
72+
if (!result.ok) {
73+
toast.error(result.error);
74+
return;
75+
}
76+
6377
// Show success notification
6478
toast.success("Feedback submitted successfully!", {
6579
description: "Thank you for your feedback. We'll review it shortly.",
@@ -281,8 +295,10 @@ export function MobileBurgerMenuButton(
281295
</button>
282296
<button
283297
type="submit"
284-
disabled={!modalFeedback.trim()}
285-
aria-disabled={!modalFeedback.trim()}
298+
disabled={!modalFeedback.trim() || isSubmitting}
299+
aria-disabled={
300+
!modalFeedback.trim() || isSubmitting
301+
}
286302
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"
287303
>
288304
Submit

0 commit comments

Comments
 (0)