From 003a61dc38ea72b1c590bc2d157c0b0fa73d6737 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Wed, 15 Jan 2025 15:05:27 +0900 Subject: [PATCH] [DevOverlay] Gather Feedback per Error --- .../error-feedback/error-feedback.tsx | 67 ++++++++++--------- .../internal/container/Errors.stories.tsx | 16 +++-- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/Errors/error-overlay-footer/error-feedback/error-feedback.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/Errors/error-overlay-footer/error-feedback/error-feedback.tsx index b8df0dd1a3b5..0c6631b7391b 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/Errors/error-overlay-footer/error-feedback/error-feedback.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/Errors/error-overlay-footer/error-feedback/error-feedback.tsx @@ -7,13 +7,18 @@ interface ErrorFeedbackProps { errorCode: string } export function ErrorFeedback({ errorCode }: ErrorFeedbackProps) { - const [voted, setVoted] = useState(null) - const hasVoted = voted !== null + const [votedMap, setVotedMap] = useState>({}) + const voted = votedMap[errorCode] + const hasVoted = voted !== undefined const handleFeedback = useCallback( async (wasHelpful: boolean) => { // Optimistically set feedback state without loading/error states to keep implementation simple - setVoted(wasHelpful) + setVotedMap((prev) => ({ + ...prev, + [errorCode]: wasHelpful, + })) + try { const response = await fetch( `${process.env.__NEXT_ROUTER_BASEPATH || ''}/__nextjs_error_feedback?${new URLSearchParams( @@ -36,35 +41,33 @@ export function ErrorFeedback({ errorCode }: ErrorFeedbackProps) { ) return ( - <> -
- {hasVoted ? ( -

- Thanks for your feedback! -

- ) : ( - <> -

Was this helpful?

- - - - )} -
- +
+ {hasVoted ? ( +

+ Thanks for your feedback! +

+ ) : ( + <> +

Was this helpful?

+ + + + )} +
) } diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx index a8f100982594..04490fa81511 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.stories.tsx @@ -22,7 +22,9 @@ export const Default: Story = { id: 1, event: { type: ACTION_UNHANDLED_ERROR, - reason: new Error('First error message'), + reason: Object.assign(new Error('First error message'), { + __NEXT_ERROR_CODE: 'E001', + }), componentStackFrames: [ { file: 'app/page.tsx', @@ -47,7 +49,9 @@ export const Default: Story = { id: 2, event: { type: ACTION_UNHANDLED_ERROR, - reason: new Error('Second error message'), + reason: Object.assign(new Error('Second error message'), { + __NEXT_ERROR_CODE: 'E002', + }), frames: [], }, }, @@ -55,7 +59,9 @@ export const Default: Story = { id: 3, event: { type: ACTION_UNHANDLED_ERROR, - reason: new Error('Third error message'), + reason: Object.assign(new Error('Third error message'), { + __NEXT_ERROR_CODE: 'E003', + }), frames: [], }, }, @@ -63,7 +69,9 @@ export const Default: Story = { id: 4, event: { type: ACTION_UNHANDLED_ERROR, - reason: new Error('Fourth error message'), + reason: Object.assign(new Error('Fourth error message'), { + __NEXT_ERROR_CODE: 'E004', + }), frames: [], }, },