Skip to content

Commit

Permalink
A4A > Feedback: Handle save feedback (#97106)
Browse files Browse the repository at this point in the history
* A4A: automated feedbacks UI

* show feedback after some actions are performed

* logic changes

* show notification only if feedback is not shown

* logic update

* initial API integration

* wire up to existing endpoint

* show success notice when feedback is successfully sent

* lint fix

* update success notice copy based on demo video in p2

---------

Co-authored-by: Andrii <lysenkoa.work@gmail.com>
Co-authored-by: Travis Walter <travis@automattic.com>
  • Loading branch information
3 people authored Dec 11, 2024
1 parent fc13b5f commit ae2ce55
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useMutation, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import wpcom from 'calypso/lib/wp';
import type { MutationSaveFeedbackVariables } from '../types';

const SURVEY_ID_PREFIX = 'a4a-feedback-';

interface APIFeedback {
success: boolean;
err: string | null;
}

function mutationSaveFeedback( { params }: MutationSaveFeedbackVariables ): Promise< APIFeedback > {
// Add a prefix to params.survey_id
const prefixedParams = {
...params,
survey_id: `${ SURVEY_ID_PREFIX }${ params.survey_id }`,
};

return wpcom.req.post( {
apiNamespace: 'wpcom/v2',
path: `/marketing/survey`,
body: { ...prefixedParams },
} );
}

export default function useSaveFeedbackMutation< TContext = unknown >(
options?: UseMutationOptions< APIFeedback, Error, MutationSaveFeedbackVariables, TContext >
): UseMutationResult< APIFeedback, Error, MutationSaveFeedbackVariables, TContext > {
return useMutation< APIFeedback, Error, MutationSaveFeedbackVariables, TContext >( {
...options,
mutationFn: ( args ) => mutationSaveFeedback( { ...args } ),
} );
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import page from '@automattic/calypso-router';
import { removeQueryArgs } from '@wordpress/url';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useMemo, useState } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import useUrlQueryParam from 'calypso/a8c-for-agencies/hooks/use-url-query-param';
import { useDispatch, useSelector } from 'calypso/state';
import { getActiveAgencyId } from 'calypso/state/a8c-for-agencies/agency/selectors';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import { successNotice } from 'calypso/state/notices/actions';
import { savePreference } from 'calypso/state/preferences/actions';
import { getPreference } from '../../../../state/preferences/selectors';
import { getA4AfeedbackProps } from '../lib/get-a4a-feedback-props';
import useSaveFeedbackMutation from './use-save-feedback-mutation';
import type { Props as A4AFeedbackProps } from '../index';
import type { FeedbackQueryData, FeedbackType, FeedbackProps } from '../types';
import type {
FeedbackQueryData,
FeedbackType,
FeedbackProps,
FeedbackSurveyResponsesPayload,
} from '../types';

const FEEDBACK_URL_HASH_FRAGMENT = '#feedback';
const FEEDBACK_PREFERENCE = 'a4a-feedback';
Expand Down Expand Up @@ -42,6 +50,8 @@ const useShowFeedback = ( type: FeedbackType ) => {

const [ feedbackInteracted, setFeedbackInteracted ] = useState( false );

const { mutate: saveFeedback, isPending, data: apiResponseData } = useSaveFeedbackMutation();

// Let's use hash #feedback if we want to show the feedback
const feedbackFormHash = window.location.hash === FEEDBACK_URL_HASH_FRAGMENT;

Expand All @@ -64,18 +74,39 @@ const useShowFeedback = ( type: FeedbackType ) => {
[ type, translate, args ]
);

const agencyId = useSelector( getActiveAgencyId );

// Do the action when submitting feedback
const onSubmitFeedback = useCallback(
( data: FeedbackQueryData ) => {
dispatch( recordTracksEvent( 'calypso_a4a_feedback_submit', { type } ) );
if ( data ) {
// TODO: Send feedback data to the backend
if ( ! data || ! agencyId ) {
return;
}
const { experience, comments } = data;
const params: FeedbackSurveyResponsesPayload = {
site_id: agencyId,
survey_id: type,
survey_responses: {
rating: experience,
comment: comments,
},
};

dispatch(
recordTracksEvent( 'calypso_a4a_feedback_submit', {
agency_id: agencyId,
survey_id: params.survey_id,
rating: params.survey_responses.rating,
} )
);
saveFeedback( { params } );

setFeedbackInteracted( true );
const updatedPreference = getUpdatedPreference( feedbackTimestamp, type, 'lastSubmittedAt' );
dispatch( savePreference( FEEDBACK_PREFERENCE, updatedPreference ) );
},
[ dispatch, feedbackTimestamp, type ]

[ agencyId, dispatch, feedbackTimestamp, saveFeedback, type ]
);

// Do action when skipping feedback
Expand All @@ -96,16 +127,44 @@ const useShowFeedback = ( type: FeedbackType ) => {
[ feedbackProps, onSubmitFeedback, onSkipFeedback ]
);

if ( feedbackFormHash && ! showFeedback ) {
// If the feedback form hash is present but we don't want to show the feedback form, redirect to the default URL
// If feedback was interacted, redirect to the URL passed in the feedbackProps
redirectToDefaultUrl( feedbackInteracted ? feedbackProps.redirectUrl : undefined );
}
useEffect( () => {
if ( apiResponseData?.success ) {
// Show success notice
dispatch(
successNotice(
translate(
'Thanks! Our team will use your feedback to help prioritize improvements to Automattic for Agencies.'
),
{
displayOnNextPage: true,
id: 'submit-product-feedback-success',
duration: 2000,
}
)
);
}

if ( feedbackFormHash && ! showFeedback && ! isPending ) {
// If the feedback form hash is present but we don't want to show the feedback form, redirect to the default URL
// If feedback was interacted, redirect to the URL passed in the feedbackProps
redirectToDefaultUrl( feedbackInteracted ? feedbackProps.redirectUrl : undefined );
}
}, [
apiResponseData,
dispatch,
feedbackFormHash,
feedbackInteracted,
feedbackProps,
isPending,
showFeedback,
translate,
] );

return {
isFeedbackShown: ! showFeedback,
showFeedback: feedbackFormHash && showFeedback,
feedbackProps: updatedFeedbackProps,
isSubmitting: isPending,
};
};

Expand Down
14 changes: 14 additions & 0 deletions client/a8c-for-agencies/components/a4a-feedback/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,17 @@ export type FeedbackProps = {
ctaText: string;
redirectUrl?: string;
};

interface FeedbackSurveyResponses {
rating: string;
comment: string;
}
export interface FeedbackSurveyResponsesPayload {
site_id: number;
survey_id: FeedbackType;
survey_responses: FeedbackSurveyResponses;
}

export interface MutationSaveFeedbackVariables {
params: FeedbackSurveyResponsesPayload;
}

0 comments on commit ae2ce55

Please sign in to comment.