diff --git a/apps/dashboard/src/@/actions/product-feedback.ts b/apps/dashboard/src/@/actions/product-feedback.ts
new file mode 100644
index 00000000000..c12d10b5168
--- /dev/null
+++ b/apps/dashboard/src/@/actions/product-feedback.ts
@@ -0,0 +1,39 @@
+"use server";
+import "server-only";
+
+import { getAuthToken } from "@/api/auth-token";
+import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
+
+export async function submitProductFeedback(request: {
+ feedback: string;
+ source: "desktop" | "mobile";
+}): Promise<{ ok: true } | { ok: false; error: string }> {
+ const token = await getAuthToken();
+ if (!token) {
+ return { error: "You are not logged in", ok: false };
+ }
+
+ const res = await fetch(
+ new URL("/v1/account/feedback", NEXT_PUBLIC_THIRDWEB_API_HOST),
+ {
+ body: JSON.stringify(request),
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ },
+ );
+
+ if (!res.ok) {
+ return {
+ error:
+ res.status === 429
+ ? "Too many requests, please try again in a minute"
+ : "Failed to submit feedback, please try again later",
+ ok: false,
+ };
+ }
+
+ return { ok: true };
+}
diff --git a/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/SecondaryNav.tsx b/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/SecondaryNav.tsx
index c8828651399..e4ae5eacb5f 100644
--- a/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/SecondaryNav.tsx
+++ b/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/SecondaryNav.tsx
@@ -5,6 +5,7 @@ import type React from "react";
import { useState } from "react";
import { toast } from "sonner";
import type { ThirdwebClient } from "thirdweb";
+import { submitProductFeedback } from "@/actions/product-feedback";
import { reportProductFeedback } from "@/analytics/report";
import { NotificationsButton } from "@/components/notifications/notification-button";
import { NavLink } from "@/components/ui/NavLink";
@@ -39,8 +40,9 @@ export function SecondaryNav(props: {
export function SecondaryNavLinks() {
const [showFeedbackDropdown, setShowFeedbackDropdown] = useState(false);
const [modalFeedback, setModalFeedback] = useState("");
+ const [isSubmitting, setIsSubmitting] = useState(false);
- const handleModalSubmit = (e?: React.FormEvent) => {
+ const handleModalSubmit = async (e?: React.FormEvent) => {
e?.preventDefault();
// Report feedback to PostHog
@@ -49,6 +51,18 @@ export function SecondaryNavLinks() {
source: "desktop",
});
+ setIsSubmitting(true);
+ const result = await submitProductFeedback({
+ feedback: modalFeedback,
+ source: "desktop",
+ });
+ setIsSubmitting(false);
+
+ if (!result.ok) {
+ toast.error(result.error);
+ return;
+ }
+
// Show success notification
toast.success("Feedback submitted successfully!", {
description: "Thank you for your feedback. We'll review it shortly.",
@@ -135,8 +149,8 @@ export function SecondaryNavLinks() {