Skip to content

Commit b1bf434

Browse files
committed
feat: integrate SIWA API for support ticket feedback
1 parent f3cb6f5 commit b1bf434

File tree

2 files changed

+19
-45
lines changed

2 files changed

+19
-45
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/_components/SupportCaseDetails.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Button } from "@/components/ui/button";
1818
import { DynamicHeight } from "@/components/ui/DynamicHeight";
1919
import { Spinner } from "@/components/ui/Spinner/Spinner";
2020
import { AutoResizeTextarea } from "@/components/ui/textarea";
21+
import { useLocalStorage } from "@/hooks/useLocalStorage";
2122
import { cn } from "@/lib/utils";
2223
import { ThirdwebMiniLogo } from "../../../../../../components/ThirdwebMiniLogo";
2324
import { submitSupportFeedback } from "../apis/feedback";
@@ -33,10 +34,6 @@ interface SupportCaseDetailsProps {
3334
team: Team;
3435
}
3536

36-
// Helper function to generate localStorage key for feedback submission
37-
const getFeedbackSubmittedKey = (ticketId: string) =>
38-
`feedback_submitted_${ticketId}`;
39-
4037
export function SupportCaseDetails({ ticket, team }: SupportCaseDetailsProps) {
4138
const [replyMessage, setReplyMessage] = useState("");
4239
const [isSubmittingReply, setIsSubmittingReply] = useState(false);
@@ -47,14 +44,11 @@ export function SupportCaseDetails({ ticket, team }: SupportCaseDetailsProps) {
4744
const [feedback, setFeedback] = useState("");
4845

4946
// Check if feedback has already been submitted for this ticket
50-
const [feedbackSubmitted, setFeedbackSubmitted] = useState(() => {
51-
if (typeof window !== "undefined") {
52-
return (
53-
localStorage.getItem(getFeedbackSubmittedKey(ticket.id)) === "true"
54-
);
55-
}
56-
return false;
57-
});
47+
const [feedbackSubmitted, setFeedbackSubmitted] = useLocalStorage(
48+
`feedback_submitted_${ticket.id}`,
49+
false,
50+
false,
51+
);
5852

5953
const handleStarClick = (starIndex: number) => {
6054
setRating(starIndex + 1);
@@ -78,8 +72,7 @@ export function SupportCaseDetails({ ticket, team }: SupportCaseDetailsProps) {
7872
throw new Error(result.error);
7973
}
8074

81-
// Mark feedback as submitted in localStorage
82-
localStorage.setItem(getFeedbackSubmittedKey(ticket.id), "true");
75+
// Mark feedback as submitted
8376
setFeedbackSubmitted(true);
8477

8578
toast.success("Thank you for your feedback!");
@@ -89,7 +82,7 @@ export function SupportCaseDetails({ ticket, team }: SupportCaseDetailsProps) {
8982
console.error("Failed to submit feedback:", error);
9083
toast.error("Failed to submit feedback. Please try again.");
9184
}
92-
}, [rating, feedback, ticket.id, team.id]);
85+
}, [rating, feedback, ticket.id, team.id, setFeedbackSubmitted]);
9386

9487
const handleSendReply = async () => {
9588
if (!team.unthreadCustomerId) {

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/apis/feedback.ts

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
"use server";
2+
13
import { z } from "zod";
2-
import { getVercelEnv } from "@/utils/vercel";
34

45
type SupportFeedbackInput = {
56
ticketId: string;
@@ -18,34 +19,28 @@ const SupportFeedbackSchema = z.object({
1819
export async function submitSupportFeedback(
1920
data: SupportFeedbackInput,
2021
): Promise<{ success: true } | { error: string }> {
21-
"use server";
22-
2322
const parsed = SupportFeedbackSchema.safeParse(data);
2423
if (!parsed.success) {
2524
return { error: parsed.error.issues.map((i) => i.message).join(", ") };
2625
}
2726
const input = parsed.data;
2827

2928
try {
30-
const apiKey = process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID;
31-
if (!apiKey) {
32-
return { error: "NEXT_PUBLIC_DASHBOARD_CLIENT_ID not configured" };
29+
const serviceKey = process.env.SERVICE_AUTH_KEY_SIWA;
30+
if (!serviceKey) {
31+
return { error: "SERVICE_AUTH_KEY_SIWA not configured" };
3332
}
3433

35-
// Use the main API host, not SIWA
36-
const apiHost = process.env.NEXT_PUBLIC_THIRDWEB_API_HOST;
37-
if (!apiHost) {
38-
return { error: "NEXT_PUBLIC_THIRDWEB_API_HOST not configured" };
34+
const apiUrl = process.env.NEXT_PUBLIC_SIWA_URL;
35+
if (!apiUrl) {
36+
return { error: "NEXT_PUBLIC_SIWA_URL not configured" };
3937
}
4038

41-
const vercelEnv = getVercelEnv();
42-
const isPreview = vercelEnv === "preview" || vercelEnv === "development";
43-
44-
const response = await fetch(`${apiHost}/v1/csat/saveCSATFeedback`, {
39+
const response = await fetch(`${apiUrl}/v1/csat/saveCSATFeedback`, {
4540
method: "POST",
4641
headers: {
4742
"Content-Type": "application/json",
48-
"x-service-api-key": apiKey,
43+
"x-service-api-key": serviceKey,
4944
},
5045
body: JSON.stringify({
5146
rating: input.rating,
@@ -55,22 +50,8 @@ export async function submitSupportFeedback(
5550
});
5651

5752
if (!response.ok) {
58-
if (response.status === 404 && isPreview) {
59-
// Only in preview/dev, simulate success if the endpoint isn't deployed yet
60-
console.debug(
61-
"CSAT endpoint not available; treating as success in preview/dev",
62-
{
63-
rating: input.rating,
64-
ticket_id: input.ticketId,
65-
vercel_env: vercelEnv,
66-
},
67-
);
68-
await new Promise((resolve) => setTimeout(resolve, 300));
69-
return { success: true };
70-
}
71-
7253
const errorText = await response.text();
73-
console.error("CSAT endpoint error:", {
54+
console.error("CSAT feedback submission failed:", {
7455
status: response.status,
7556
statusText: response.statusText,
7657
error: errorText,

0 commit comments

Comments
 (0)