From eb2274a8e85ea781e03163da0686b37479c47541 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 14:31:00 +0800 Subject: [PATCH 01/16] feat: feed settings survey --- packages/shared/src/components/Feed.tsx | 18 ++- .../src/components/FeedItemComponent.tsx | 14 ++ .../src/components/cards/FeedSurveyCard.tsx | 122 ++++++++++++++++++ .../shared/src/components/cards/common.tsx | 1 + .../components/feeds/FeedSettingsButton.tsx | 33 +++++ packages/shared/src/graphql/alerts.ts | 16 ++- packages/shared/src/hooks/useFeed.ts | 8 +- packages/shared/src/lib/analytics.ts | 3 + packages/shared/src/lib/featureManagement.ts | 1 + 9 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 packages/shared/src/components/cards/FeedSurveyCard.tsx create mode 100644 packages/shared/src/components/feeds/FeedSettingsButton.tsx diff --git a/packages/shared/src/components/Feed.tsx b/packages/shared/src/components/Feed.tsx index a20af3c5b7..4c91560aff 100644 --- a/packages/shared/src/components/Feed.tsx +++ b/packages/shared/src/components/Feed.tsx @@ -36,7 +36,12 @@ import ShareOptionsMenu from './ShareOptionsMenu'; import { SharedFeedPage } from './utilities'; import { FeedContainer, FeedContainerProps } from './feeds/FeedContainer'; import { ActiveFeedContext } from '../contexts'; -import { useBoot, useFeedLayout, useFeedVotePost } from '../hooks'; +import { + useBoot, + useConditionalFeature, + useFeedLayout, + useFeedVotePost, +} from '../hooks'; import { AllFeedPages, OtherFeedPage, @@ -51,6 +56,7 @@ import { useFeature } from './GrowthBookProvider'; import { feature } from '../lib/featureManagement'; import { acquisitionKey } from './cards/AcquisitionFormCard'; import { MarketingCtaVariant } from './cards/MarketingCta/common'; +import { useAlertsContext } from '../contexts/AlertContext'; export interface FeedProps extends Pick< @@ -148,6 +154,15 @@ export default function Feed({ insaneMode: listMode, loadedSettings, } = useContext(SettingsContext); + const { isFetched, alerts } = useAlertsContext(); + const { value: shouldShowSurvey } = useConditionalFeature({ + feature: feature.feedSettingsFeedback, + shouldEvaluate: + user && + isFetched && + alerts.shouldShowFeedFeedback && + feedName === SharedFeedPage.MyFeed, + }); const insaneMode = !forceCardMode && listMode; const numCards = currentSettings.numCards[spaciness ?? 'eco']; const isSquadFeed = feedName === OtherFeedPage.Squad; @@ -181,6 +196,7 @@ export default function Feed({ variables, options, showPublicSquadsEligibility, + shouldShowSurvey, settings: { disableAds, adPostLength: isSquadFeed ? 2 : undefined, diff --git a/packages/shared/src/components/FeedItemComponent.tsx b/packages/shared/src/components/FeedItemComponent.tsx index f42b449c7c..04b056c22e 100644 --- a/packages/shared/src/components/FeedItemComponent.tsx +++ b/packages/shared/src/components/FeedItemComponent.tsx @@ -28,6 +28,8 @@ import { MarketingCtaCard, MarketingCtaList } from './cards'; import { MarketingCtaCardV1 } from './cards/v1/MarketingCtaCard'; import { FeedItemType } from './cards/common'; import { PublicSquadEligibilityCard } from './squads/PublicSquadEligibilityCard'; +import { FeedSurveyCard } from './cards/FeedSurveyCard'; +import { FeedSettingsButton } from './feeds/FeedSettingsButton'; const CommentPopup = dynamic( () => import(/* webpackChunkName: "commentPopup" */ './cards/CommentPopup'), @@ -281,6 +283,18 @@ export default function FeedItemComponent({ showImage={!insaneMode} /> ); + case FeedItemType.FeedSurvey: + return ( + , + }} + /> + ); case FeedItemType.UserAcquisition: return ; case FeedItemType.PublicSquadEligibility: diff --git a/packages/shared/src/components/cards/FeedSurveyCard.tsx b/packages/shared/src/components/cards/FeedSurveyCard.tsx new file mode 100644 index 0000000000..4a45819c72 --- /dev/null +++ b/packages/shared/src/components/cards/FeedSurveyCard.tsx @@ -0,0 +1,122 @@ +import React, { ReactElement, ReactNode, useEffect, useState } from 'react'; +import classNames from 'classnames'; +import { Card as CardV1 } from './v1/Card'; +import { Card } from './Card'; +import { useFeedLayout } from '../../hooks'; +import { StarIcon } from '../icons'; +import { IconSize } from '../Icon'; +import { Button, ButtonSize, ButtonVariant } from '../buttons/Button'; +import ConditionalWrapper from '../ConditionalWrapper'; +import { useAnalyticsContext } from '../../contexts/AnalyticsContext'; +import { AnalyticsEvent, TargetId, TargetType } from '../../lib/analytics'; +import { updateFeedFeedbackReminder } from '../../graphql/alerts'; + +interface FeedSurveyCardProps { + title: string; + postFeedbackMessage?: string; + max: number; + lowScore: { + value: number; + message: string; + cta: ReactNode; + }; +} + +export function FeedSurveyCard({ + max, + title, + lowScore, + postFeedbackMessage = 'Thank you for your feedback!', +}: FeedSurveyCardProps): ReactElement { + const [score, setScore] = useState(0); + const [hovered, setHovered] = useState(0); + const { shouldUseListFeedLayout } = useFeedLayout(); + const highlighted = hovered || score; + const CardComponent = shouldUseListFeedLayout ? CardV1 : Card; + const { trackEvent } = useAnalyticsContext(); + + const trackSurveyEvent = (event_name: AnalyticsEvent, extra?) => + trackEvent({ + target_type: TargetType.PromotionCard, + target_id: TargetId.FeedSurvey, + event_name, + extra, + }); + + const onStarClick = (value) => { + setScore(value); + updateFeedFeedbackReminder(); + trackSurveyEvent(AnalyticsEvent.Click, { value }); + }; + + const onHide = () => { + updateFeedFeedbackReminder(); + trackSurveyEvent(AnalyticsEvent.DismissPromotion); + }; + + useEffect(() => { + trackSurveyEvent(AnalyticsEvent.Impression); + // trackEvent is unstable and we only need to track once + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + +

{title}

+ + {Object.keys([...Array(max)]).map((key, i) => ( + ( + + )} + > + score && 'opacity-[0.8]', + )} + /> + + ))} + + {score > 0 && ( +

+ {postFeedbackMessage} + {score <= lowScore.value &&

{lowScore.message}

} + {score <= lowScore.value && lowScore.cta} +

+ )} + +
+ ); +} diff --git a/packages/shared/src/components/cards/common.tsx b/packages/shared/src/components/cards/common.tsx index 4e44426105..b2150b3eea 100644 --- a/packages/shared/src/components/cards/common.tsx +++ b/packages/shared/src/components/cards/common.tsx @@ -77,4 +77,5 @@ export enum FeedItemType { UserAcquisition = 'userAcquisition', PublicSquadEligibility = 'publicSquadEligibility', MarketingCta = 'marketingCta', + FeedSurvey = 'feedSurvey', } diff --git a/packages/shared/src/components/feeds/FeedSettingsButton.tsx b/packages/shared/src/components/feeds/FeedSettingsButton.tsx new file mode 100644 index 0000000000..b4a5094078 --- /dev/null +++ b/packages/shared/src/components/feeds/FeedSettingsButton.tsx @@ -0,0 +1,33 @@ +import React, { ReactElement } from 'react'; +import { + Button, + ButtonProps, + ButtonSize, + ButtonVariant, +} from '../buttons/Button'; +import { useAnalyticsContext } from '../../contexts/AnalyticsContext'; +import { AnalyticsEvent } from '../../lib/analytics'; +import { LazyModal } from '../modals/common/types'; +import { useLazyModal } from '../../hooks/useLazyModal'; +import { FilterIcon } from '../icons'; + +export function FeedSettingsButton(props: ButtonProps<'button'>): ReactElement { + const { trackEvent } = useAnalyticsContext(); + const { openModal } = useLazyModal(); + const onClick = () => { + trackEvent({ event_name: AnalyticsEvent.ManageTags }); + openModal({ type: LazyModal.FeedFilters, persistOnRouteChange: true }); + }; + + return ( + + ); +} diff --git a/packages/shared/src/graphql/alerts.ts b/packages/shared/src/graphql/alerts.ts index c64fa494e5..411c9c5f4d 100644 --- a/packages/shared/src/graphql/alerts.ts +++ b/packages/shared/src/graphql/alerts.ts @@ -1,4 +1,6 @@ -import { gql } from 'graphql-request'; +import request, { gql } from 'graphql-request'; +import { graphqlUrl } from '../lib/config'; +import { EmptyResponse } from './emptyResponse'; export type Alerts = { filter?: boolean; @@ -12,6 +14,7 @@ export type Alerts = { lastBanner?: string; banner?: boolean; showStreakMilestone?: boolean; + shouldShowFeedFeedback?: boolean; lastBootPopup?: Date; bootPopup?: boolean; }; @@ -48,3 +51,14 @@ export const UPDATE_LAST_BOOT_POPUP = gql` } } `; + +const UPDATE_FEED_FEEDBACK_REMINDER = ` + mutation UpdateFeedFeedbackReminder { + updateFeedFeedbackReminder { + _ + } + } +`; + +export const updateFeedFeedbackReminder = (): Promise => + request(graphqlUrl, UPDATE_FEED_FEEDBACK_REMINDER); diff --git a/packages/shared/src/hooks/useFeed.ts b/packages/shared/src/hooks/useFeed.ts index 978f99b7a7..9a68fcfe9b 100644 --- a/packages/shared/src/hooks/useFeed.ts +++ b/packages/shared/src/hooks/useFeed.ts @@ -47,6 +47,7 @@ export type FeedItem = | PostItem | AdItem | MarketingCtaItem + | FeedItemBase | FeedItemBase | FeedItemBase | FeedItemBase; @@ -94,6 +95,7 @@ export interface UseFeedOptionalParams { options?: UseInfiniteQueryOptions; settings?: UseFeedSettingParams; showPublicSquadsEligibility?: boolean; + shouldShowSurvey?: boolean; } export default function useFeed( @@ -108,6 +110,7 @@ export default function useFeed( variables, options = {}, settings, + shouldShowSurvey, showPublicSquadsEligibility, } = params; const { user, tokenRefreshed } = useContext(AuthContext); @@ -191,8 +194,8 @@ export default function useFeed( }); } else if (withFirstIndex(settings.showAcquisitionForm)) { posts.splice(adSpot, 0, { type: FeedItemType.UserAcquisition }); - } else if (withFirstIndex(settings.showAcquisitionForm)) { - posts.splice(adSpot, 0, { type: FeedItemType.UserAcquisition }); + } else if (shouldShowSurvey) { + posts.splice(adSpot, 0, { type: FeedItemType.FeedSurvey }); } else if (withFirstIndex(showPublicSquadsEligibility)) { posts.splice(adSpot, 0, { type: FeedItemType.PublicSquadEligibility, @@ -223,6 +226,7 @@ export default function useFeed( feedQuery.isFetching, settings.marketingCta, settings.showAcquisitionForm, + shouldShowSurvey, showPublicSquadsEligibility, isAdsQueryEnabled, adSpot, diff --git a/packages/shared/src/lib/analytics.ts b/packages/shared/src/lib/analytics.ts index 97026f6d75..6952c61308 100644 --- a/packages/shared/src/lib/analytics.ts +++ b/packages/shared/src/lib/analytics.ts @@ -51,6 +51,7 @@ export enum Origin { } export enum AnalyticsEvent { + DismissPromotion = 'dismiss promotion', Click = 'click', CommentPost = 'comment post', StartSubmitArticle = 'start submit article', @@ -169,6 +170,7 @@ export enum FeedItemTitle { } export enum TargetType { + PromotionCard = 'promotion_card', MyFeedModal = 'my feed modal', ArticleAnonymousCTA = 'article anonymous cta', EnableNotifications = 'enable notifications', @@ -196,6 +198,7 @@ export enum TargetType { } export enum TargetId { + FeedSurvey = 'feed survey', SearchReferralBadge = 'search referral badge', InviteBanner = 'invite banner', InviteProfileMenu = 'invite in profile menu', diff --git a/packages/shared/src/lib/featureManagement.ts b/packages/shared/src/lib/featureManagement.ts index 96a6f91f5c..fd10f15804 100644 --- a/packages/shared/src/lib/featureManagement.ts +++ b/packages/shared/src/lib/featureManagement.ts @@ -53,6 +53,7 @@ const feature = { searchGoogle: new Feature('search_google', false), onboardingFlip: new Feature('onboarding_flip', false), improvedSharedPostCard: new Feature('improved_shared_post_card', false), + feedSettingsFeedback: new Feature('feed_settings_feedback', false), }; export { feature }; From f38aa71bcd1e766f8a17f3dad3317b2e6f015e4e Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 14:42:51 +0800 Subject: [PATCH 02/16] fix: condition --- packages/shared/src/components/Feed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/components/Feed.tsx b/packages/shared/src/components/Feed.tsx index 4c91560aff..15e93b59e5 100644 --- a/packages/shared/src/components/Feed.tsx +++ b/packages/shared/src/components/Feed.tsx @@ -158,7 +158,7 @@ export default function Feed({ const { value: shouldShowSurvey } = useConditionalFeature({ feature: feature.feedSettingsFeedback, shouldEvaluate: - user && + !!user && isFetched && alerts.shouldShowFeedFeedback && feedName === SharedFeedPage.MyFeed, From 74822495ac20d65d7addadbc66b4cbc6d795e7cd Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 15:01:23 +0800 Subject: [PATCH 03/16] fix: avoid any persistence issue --- packages/shared/src/components/cards/FeedSurveyCard.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/shared/src/components/cards/FeedSurveyCard.tsx b/packages/shared/src/components/cards/FeedSurveyCard.tsx index 4a45819c72..815b0a46eb 100644 --- a/packages/shared/src/components/cards/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/FeedSurveyCard.tsx @@ -44,6 +44,10 @@ export function FeedSurveyCard({ }); const onStarClick = (value) => { + if (score > 0) { + return; + } + setScore(value); updateFeedFeedbackReminder(); trackSurveyEvent(AnalyticsEvent.Click, { value }); @@ -56,7 +60,7 @@ export function FeedSurveyCard({ useEffect(() => { trackSurveyEvent(AnalyticsEvent.Impression); - // trackEvent is unstable and we only need to track once + // trackEvent is unstable, and we only need to track once // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -114,6 +118,7 @@ export function FeedSurveyCard({ size={ButtonSize.Small} className="mb-2 mt-auto" onClick={onHide} + disabled={score > 0} > Hide From 70c324d24fa1f3a09119ef165993c11a30e2dc0a Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 18:49:09 +0800 Subject: [PATCH 04/16] refactor: ux changes when submitting --- .../src/components/cards/FeedSurveyCard.tsx | 70 +++++++++++++------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/packages/shared/src/components/cards/FeedSurveyCard.tsx b/packages/shared/src/components/cards/FeedSurveyCard.tsx index 815b0a46eb..f993b0f488 100644 --- a/packages/shared/src/components/cards/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/FeedSurveyCard.tsx @@ -30,6 +30,8 @@ export function FeedSurveyCard({ }: FeedSurveyCardProps): ReactElement { const [score, setScore] = useState(0); const [hovered, setHovered] = useState(0); + const [submitted, setSubmitted] = useState(false); + const [justClicked, setJustClicked] = useState(false); const { shouldUseListFeedLayout } = useFeedLayout(); const highlighted = hovered || score; const CardComponent = shouldUseListFeedLayout ? CardV1 : Card; @@ -43,14 +45,22 @@ export function FeedSurveyCard({ extra, }); + const onSubmit = () => { + if (submitted) { + return; + } + + setSubmitted(true); + updateFeedFeedbackReminder(); + trackSurveyEvent(AnalyticsEvent.Click, { value: score }); + }; + const onStarClick = (value) => { - if (score > 0) { + if (submitted) { return; } setScore(value); - updateFeedFeedbackReminder(); - trackSurveyEvent(AnalyticsEvent.Click, { value }); }; const onHide = () => { @@ -64,29 +74,37 @@ export function FeedSurveyCard({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const onOut = () => { + setHovered(0); + setJustClicked(false); + }; + return (

{title}

- + {Object.keys([...Array(max)]).map((key, i) => ( ( @@ -100,28 +118,38 @@ export function FeedSurveyCard({ i < highlighted ? 'text-accent-cheese-default' : 'text-text-secondary', - i < highlighted && highlighted > score && 'opacity-[0.8]', + i < highlighted && hovered && !justClicked && 'opacity-[0.8]', )} /> ))} - {score > 0 && ( -

+ {submitted && ( +

{postFeedbackMessage} {score <= lowScore.value &&

{lowScore.message}

} {score <= lowScore.value && lowScore.cta}

)} - + {score > 0 && !submitted && ( + + )} + {score === 0 && ( + + )}
); } From 852b7ed2f8a73ad0ad481cb00b51d9d301c09fcb Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 19:15:02 +0800 Subject: [PATCH 05/16] refactor: rating stars component --- .../src/components/cards/FeedSurveyCard.tsx | 58 +-------------- .../src/components/utilities/RatingStars.tsx | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+), 56 deletions(-) create mode 100644 packages/shared/src/components/utilities/RatingStars.tsx diff --git a/packages/shared/src/components/cards/FeedSurveyCard.tsx b/packages/shared/src/components/cards/FeedSurveyCard.tsx index f993b0f488..a91a497cc0 100644 --- a/packages/shared/src/components/cards/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/FeedSurveyCard.tsx @@ -1,15 +1,12 @@ import React, { ReactElement, ReactNode, useEffect, useState } from 'react'; -import classNames from 'classnames'; import { Card as CardV1 } from './v1/Card'; import { Card } from './Card'; import { useFeedLayout } from '../../hooks'; -import { StarIcon } from '../icons'; -import { IconSize } from '../Icon'; import { Button, ButtonSize, ButtonVariant } from '../buttons/Button'; -import ConditionalWrapper from '../ConditionalWrapper'; import { useAnalyticsContext } from '../../contexts/AnalyticsContext'; import { AnalyticsEvent, TargetId, TargetType } from '../../lib/analytics'; import { updateFeedFeedbackReminder } from '../../graphql/alerts'; +import { RatingStars } from '../utilities/RatingStars'; interface FeedSurveyCardProps { title: string; @@ -29,11 +26,8 @@ export function FeedSurveyCard({ postFeedbackMessage = 'Thank you for your feedback!', }: FeedSurveyCardProps): ReactElement { const [score, setScore] = useState(0); - const [hovered, setHovered] = useState(0); const [submitted, setSubmitted] = useState(false); - const [justClicked, setJustClicked] = useState(false); const { shouldUseListFeedLayout } = useFeedLayout(); - const highlighted = hovered || score; const CardComponent = shouldUseListFeedLayout ? CardV1 : Card; const { trackEvent } = useAnalyticsContext(); @@ -55,14 +49,6 @@ export function FeedSurveyCard({ trackSurveyEvent(AnalyticsEvent.Click, { value: score }); }; - const onStarClick = (value) => { - if (submitted) { - return; - } - - setScore(value); - }; - const onHide = () => { updateFeedFeedbackReminder(); trackSurveyEvent(AnalyticsEvent.DismissPromotion); @@ -74,11 +60,6 @@ export function FeedSurveyCard({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const onOut = () => { - setHovered(0); - setJustClicked(false); - }; - return (

{title}

- - {Object.keys([...Array(max)]).map((key, i) => ( - ( - - )} - > - - - ))} - + {submitted && (

{postFeedbackMessage} diff --git a/packages/shared/src/components/utilities/RatingStars.tsx b/packages/shared/src/components/utilities/RatingStars.tsx new file mode 100644 index 0000000000..b3c26fec61 --- /dev/null +++ b/packages/shared/src/components/utilities/RatingStars.tsx @@ -0,0 +1,72 @@ +import React, { ReactElement, useState } from 'react'; +import classNames from 'classnames'; +import ConditionalWrapper from '../ConditionalWrapper'; +import { StarIcon } from '../icons'; +import { IconSize } from '../Icon'; + +interface RatingStarsProps { + max: number; + isDisabled?: boolean; + onStarClick?: (value: number) => void; +} + +export function RatingStars({ + max, + isDisabled, + onStarClick, +}: RatingStarsProps): ReactElement { + const [score, setScore] = useState(0); + const [hovered, setHovered] = useState(0); + const [justClicked, setJustClicked] = useState(false); + const highlighted = hovered || score; + + const onClick = (value) => { + setScore(value); + setJustClicked(true); + + if (onStarClick) { + onStarClick(value); + } + }; + + const onOut = () => { + setHovered(0); + setJustClicked(false); + }; + + return ( + + {Object.keys([...Array(max)]).map((key, i) => ( + ( + + )} + > + + + ))} + + ); +} From 2bdca8ef1083c27a74ad4105b1523bb3bdea67c9 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 21:03:16 +0800 Subject: [PATCH 06/16] fix: list mode --- packages/shared/src/components/Feed.tsx | 6 +- .../src/components/FeedItemComponent.tsx | 2 +- .../cards/survey/FeedSurveyBanner.tsx | 50 ++++++++++++++++ .../cards/{ => survey}/FeedSurveyCard.tsx | 60 +++---------------- .../src/components/cards/survey/common.ts | 12 ++++ .../src/components/cards/survey/index.ts | 2 + .../src/components/feeds/FeedContainer.tsx | 15 +++++ .../src/components/utilities/RatingStars.tsx | 5 +- .../shared/src/hooks/feed/useFeedSurvey.ts | 50 ++++++++++++++++ 9 files changed, 147 insertions(+), 55 deletions(-) create mode 100644 packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx rename packages/shared/src/components/cards/{ => survey}/FeedSurveyCard.tsx (50%) create mode 100644 packages/shared/src/components/cards/survey/common.ts create mode 100644 packages/shared/src/components/cards/survey/index.ts create mode 100644 packages/shared/src/hooks/feed/useFeedSurvey.ts diff --git a/packages/shared/src/components/Feed.tsx b/packages/shared/src/components/Feed.tsx index 15e93b59e5..8c7de7d9a8 100644 --- a/packages/shared/src/components/Feed.tsx +++ b/packages/shared/src/components/Feed.tsx @@ -41,6 +41,8 @@ import { useConditionalFeature, useFeedLayout, useFeedVotePost, + useViewSize, + ViewSize, } from '../hooks'; import { AllFeedPages, @@ -163,6 +165,7 @@ export default function Feed({ alerts.shouldShowFeedFeedback && feedName === SharedFeedPage.MyFeed, }); + const isLaptop = useViewSize(ViewSize.Laptop); const insaneMode = !forceCardMode && listMode; const numCards = currentSettings.numCards[spaciness ?? 'eco']; const isSquadFeed = feedName === OtherFeedPage.Squad; @@ -196,7 +199,7 @@ export default function Feed({ variables, options, showPublicSquadsEligibility, - shouldShowSurvey, + shouldShowSurvey: shouldShowSurvey && isLaptop, settings: { disableAds, adPostLength: isSquadFeed ? 2 : undefined, @@ -424,6 +427,7 @@ export default function Feed({ actionButtons={actionButtons} isHorizontal={isHorizontal} feedContainerRef={feedContainerRef} + shouldShowSurvey={shouldShowSurvey && !isLaptop} > {items.map((_, index) => ( +

+
+

{title}

+ +
+ +
+ {submitted && ( +
+

+ {postFeedbackMessage} + {score <= lowScore.value ? lowScore.message : null} +

+ {score <= lowScore.value && lowScore.cta} +
+ )} + + ); +} diff --git a/packages/shared/src/components/cards/FeedSurveyCard.tsx b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx similarity index 50% rename from packages/shared/src/components/cards/FeedSurveyCard.tsx rename to packages/shared/src/components/cards/survey/FeedSurveyCard.tsx index a91a497cc0..9094555c82 100644 --- a/packages/shared/src/components/cards/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx @@ -1,64 +1,22 @@ import React, { ReactElement, ReactNode, useEffect, useState } from 'react'; -import { Card as CardV1 } from './v1/Card'; -import { Card } from './Card'; -import { useFeedLayout } from '../../hooks'; -import { Button, ButtonSize, ButtonVariant } from '../buttons/Button'; -import { useAnalyticsContext } from '../../contexts/AnalyticsContext'; -import { AnalyticsEvent, TargetId, TargetType } from '../../lib/analytics'; -import { updateFeedFeedbackReminder } from '../../graphql/alerts'; -import { RatingStars } from '../utilities/RatingStars'; - -interface FeedSurveyCardProps { - title: string; - postFeedbackMessage?: string; - max: number; - lowScore: { - value: number; - message: string; - cta: ReactNode; - }; -} +import { Card as CardV1 } from '../v1/Card'; +import { Card } from '../Card'; +import { useFeedLayout } from '../../../hooks'; +import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; +import { RatingStars } from '../../utilities/RatingStars'; +import { useFeedSurvey } from '../../../hooks/feed/useFeedSurvey'; +import { FeedSurveyProps } from './common'; export function FeedSurveyCard({ max, title, lowScore, postFeedbackMessage = 'Thank you for your feedback!', -}: FeedSurveyCardProps): ReactElement { +}: FeedSurveyProps): ReactElement { const [score, setScore] = useState(0); - const [submitted, setSubmitted] = useState(false); + const { submitted, onSubmit, onHide } = useFeedSurvey({ score }); const { shouldUseListFeedLayout } = useFeedLayout(); const CardComponent = shouldUseListFeedLayout ? CardV1 : Card; - const { trackEvent } = useAnalyticsContext(); - - const trackSurveyEvent = (event_name: AnalyticsEvent, extra?) => - trackEvent({ - target_type: TargetType.PromotionCard, - target_id: TargetId.FeedSurvey, - event_name, - extra, - }); - - const onSubmit = () => { - if (submitted) { - return; - } - - setSubmitted(true); - updateFeedFeedbackReminder(); - trackSurveyEvent(AnalyticsEvent.Click, { value: score }); - }; - - const onHide = () => { - updateFeedFeedbackReminder(); - trackSurveyEvent(AnalyticsEvent.DismissPromotion); - }; - - useEffect(() => { - trackSurveyEvent(AnalyticsEvent.Impression); - // trackEvent is unstable, and we only need to track once - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); return ( ; } @@ -145,6 +148,7 @@ export const FeedContainer = ({ shortcuts, actionButtons, isHorizontal, + shouldShowSurvey, feedContainerRef, }: FeedContainerProps): ReactElement => { const { value: isShortcutsV1 } = useConditionalFeature({ @@ -269,6 +273,17 @@ export const FeedContainer = ({ )} > + {shouldShowSurvey && ( + , + }} + /> + )}
{ + const onClick = (value: number) => { setScore(value); setJustClicked(true); @@ -44,7 +44,7 @@ export function RatingStars({ - )} - {score === 0 && ( - - )} - +
+ +

{title}

+ + {submitted && ( +

+ {postFeedbackMessage} + {score <= lowScore.value &&

{lowScore.message}

} + {score <= lowScore.value && lowScore.cta} +

+ )} + {score > 0 && !submitted && ( + + )} + {score === 0 && ( + + )} +
+
); } From 2b0c8110e47ae3ab121020f67906417b50b25d95 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Mon, 3 Jun 2024 22:16:51 +0800 Subject: [PATCH 09/16] fix: padding --- .../shared/src/components/cards/survey/FeedSurveyCard.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx index 11b8deda62..63dd8d2c93 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx @@ -1,4 +1,5 @@ import React, { ReactElement, ReactNode, useEffect, useState } from 'react'; +import classNames from 'classnames'; import { Card as CardV1 } from '../v1/Card'; import { Card } from '../Card'; import { useFeedLayout } from '../../../hooks'; @@ -28,7 +29,10 @@ export function FeedSurveyCard({ >
Date: Mon, 3 Jun 2024 22:21:16 +0800 Subject: [PATCH 10/16] fix: lint --- packages/shared/src/components/cards/survey/FeedSurveyCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx index 63dd8d2c93..b3fa0ee453 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement, ReactNode, useEffect, useState } from 'react'; +import React, { ReactElement, useState } from 'react'; import classNames from 'classnames'; import { Card as CardV1 } from '../v1/Card'; import { Card } from '../Card'; From 7c95bdfa4a8d79fd5f1f55133e449e90f63079c1 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Tue, 4 Jun 2024 19:43:26 +0800 Subject: [PATCH 11/16] refactor: feed settings button to use the same component --- .../components/feeds/FeedSettingsButton.tsx | 21 +++++++++++++------ .../src/components/filters/MyFeedHeading.tsx | 15 +++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/shared/src/components/feeds/FeedSettingsButton.tsx b/packages/shared/src/components/feeds/FeedSettingsButton.tsx index b4a5094078..435210a379 100644 --- a/packages/shared/src/components/feeds/FeedSettingsButton.tsx +++ b/packages/shared/src/components/feeds/FeedSettingsButton.tsx @@ -11,23 +11,32 @@ import { LazyModal } from '../modals/common/types'; import { useLazyModal } from '../../hooks/useLazyModal'; import { FilterIcon } from '../icons'; -export function FeedSettingsButton(props: ButtonProps<'button'>): ReactElement { +export function FeedSettingsButton({ + onClick, + children = 'Feed settings', + ...props +}: ButtonProps<'button'>): ReactElement { const { trackEvent } = useAnalyticsContext(); const { openModal } = useLazyModal(); - const onClick = () => { + const onButtonClick = (event: React.MouseEvent) => { trackEvent({ event_name: AnalyticsEvent.ManageTags }); - openModal({ type: LazyModal.FeedFilters, persistOnRouteChange: true }); + + if (onClick) { + onClick(event); + } else { + openModal({ type: LazyModal.FeedFilters, persistOnRouteChange: true }); + } }; return ( ); } diff --git a/packages/shared/src/components/filters/MyFeedHeading.tsx b/packages/shared/src/components/filters/MyFeedHeading.tsx index 7e56f1a157..3cad727fff 100644 --- a/packages/shared/src/components/filters/MyFeedHeading.tsx +++ b/packages/shared/src/components/filters/MyFeedHeading.tsx @@ -17,6 +17,7 @@ import { setShouldRefreshFeed } from '../../lib/refreshFeed'; import { SharedFeedPage } from '../utilities'; import { getFeedName } from '../../lib/feed'; import { useFeedName } from '../../hooks/feed/useFeedName'; +import { FeedSettingsButton } from '../feeds/FeedSettingsButton'; export const filterAlertMessage = 'Edit your personal feed preferences here'; @@ -36,12 +37,6 @@ function MyFeedHeading({ const isLaptop = useViewSize(ViewSize.Laptop); const feedName = getFeedName(router.pathname); const { isCustomFeed } = useFeedName({ feedName }); - - const onClick = () => { - trackEvent({ event_name: AnalyticsEvent.ManageTags }); - onOpenFeedFilters(); - }; - const onRefresh = async () => { trackEvent({ event_name: AnalyticsEvent.RefreshFeed }); setShouldRefreshFeed(true); @@ -80,18 +75,18 @@ function MyFeedHeading({ {isLaptop ? 'Refresh feed' : null} )} - + ); } From 2e0a29d62a91268545f9e816389f5fdb0d549ccf Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Tue, 4 Jun 2024 21:01:35 +0800 Subject: [PATCH 12/16] refactor: custom colors --- .../src/components/cards/survey/FeedSurveyBanner.tsx | 11 +++-------- .../src/components/cards/survey/FeedSurveyCard.tsx | 11 +++-------- packages/shared/src/styles/custom.ts | 9 +++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 packages/shared/src/styles/custom.ts diff --git a/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx b/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx index 34b23c8528..9688578eb0 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx @@ -3,6 +3,7 @@ import { RatingStars } from '../../utilities/RatingStars'; import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; import { useFeedSurvey } from '../../../hooks/feed/useFeedSurvey'; import { FeedSurveyProps } from './common'; +import { feedSurveyBg, feedSurveyBorder } from '../../../styles/custom'; export function FeedSurveyBanner({ max, @@ -16,17 +17,11 @@ export function FeedSurveyBanner({ return (
diff --git a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx index b3fa0ee453..bde30a7666 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx @@ -7,6 +7,7 @@ import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; import { RatingStars } from '../../utilities/RatingStars'; import { useFeedSurvey } from '../../../hooks/feed/useFeedSurvey'; import { FeedSurveyProps } from './common'; +import { feedSurveyBg, feedSurveyBorder } from '../../../styles/custom'; export function FeedSurveyCard({ max, @@ -22,10 +23,7 @@ export function FeedSurveyCard({ return (

{title}

diff --git a/packages/shared/src/styles/custom.ts b/packages/shared/src/styles/custom.ts new file mode 100644 index 0000000000..021230ff2e --- /dev/null +++ b/packages/shared/src/styles/custom.ts @@ -0,0 +1,9 @@ +// this file was created to contain all custom temporary colors (outside the guideline) +// and it is ideal to have this file to contain fewer colors as possible +// we should eventually convert the custom colors to be part of the guideline once it is deemed to be used frequently + +export const feedSurveyBg = + 'linear-gradient(180deg, rgba(255, 233, 35, 0.08) 0%, rgba(252, 83, 141, 0.08) 50%, rgba(113, 71, 237, 0.08) 100%)'; + +export const feedSurveyBorder = + 'linear-gradient(180deg, rgba(255, 233, 35, 1) 0%, rgba(252, 83, 141, 1) 50%, rgba(113, 71, 237, 1) 100%)'; From 92fde638834de5fca89717aadced8ac86d4cd871 Mon Sep 17 00:00:00 2001 From: Ole-Martin Bratteng <1681525+omBratteng@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:44:29 +0200 Subject: [PATCH 13/16] fix: feed settings survey border tweaks (#3183) --- packages/shared/src/components/buttons/Button.tsx | 4 ++-- .../shared/src/components/cards/survey/FeedSurveyCard.tsx | 5 ++--- packages/shared/src/styles/custom.ts | 4 ++-- packages/shared/tailwind/boxShadow.ts | 1 + 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/components/buttons/Button.tsx b/packages/shared/src/components/buttons/Button.tsx index 15262c1770..2a7eb6203d 100644 --- a/packages/shared/src/components/buttons/Button.tsx +++ b/packages/shared/src/components/buttons/Button.tsx @@ -89,8 +89,8 @@ function ButtonComponent( aria-pressed={pressed} ref={ref} className={classNames( - `btn shadow-none focus-outline inline-flex cursor-pointer select-none - flex-row items-center border no-underline transition + `btn focus-outline inline-flex cursor-pointer select-none flex-row + items-center border no-underline shadow-none transition duration-200 ease-in-out typo-callout`, variant !== ButtonVariant.Option && 'justify-center font-bold', { iconOnly }, diff --git a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx index bde30a7666..3ba5793621 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyCard.tsx @@ -22,13 +22,12 @@ export function FeedSurveyCard({ return (
-
Date: Wed, 5 Jun 2024 13:55:14 +0800 Subject: [PATCH 14/16] fix: hide survey --- packages/shared/src/components/Feed.tsx | 14 ++++++++------ packages/shared/src/contexts/AlertContext.tsx | 5 ++++- packages/shared/src/hooks/feed/useFeedSurvey.ts | 3 +++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/components/Feed.tsx b/packages/shared/src/components/Feed.tsx index 8c7de7d9a8..582933578f 100644 --- a/packages/shared/src/components/Feed.tsx +++ b/packages/shared/src/components/Feed.tsx @@ -157,14 +157,16 @@ export default function Feed({ loadedSettings, } = useContext(SettingsContext); const { isFetched, alerts } = useAlertsContext(); - const { value: shouldShowSurvey } = useConditionalFeature({ + const shouldEvaluateSurvey = + !!user && + isFetched && + alerts.shouldShowFeedFeedback && + feedName === SharedFeedPage.MyFeed; + const { value: feedSurvey } = useConditionalFeature({ feature: feature.feedSettingsFeedback, - shouldEvaluate: - !!user && - isFetched && - alerts.shouldShowFeedFeedback && - feedName === SharedFeedPage.MyFeed, + shouldEvaluate: shouldEvaluateSurvey, }); + const shouldShowSurvey = shouldEvaluateSurvey && feedSurvey; const isLaptop = useViewSize(ViewSize.Laptop); const insaneMode = !forceCardMode && listMode; const numCards = currentSettings.numCards[spaciness ?? 'eco']; diff --git a/packages/shared/src/contexts/AlertContext.tsx b/packages/shared/src/contexts/AlertContext.tsx index 0409fb9fd4..7df5b86c28 100644 --- a/packages/shared/src/contexts/AlertContext.tsx +++ b/packages/shared/src/contexts/AlertContext.tsx @@ -32,6 +32,7 @@ export interface AlertContextData { >; updateLastReferralReminder?: UseMutateAsyncFunction; updateLastBootPopup?: UseMutateAsyncFunction; + updateLocalBoot?: (alerts: Partial) => void; } export const MAX_DATE = new Date(3021, 0, 1); @@ -47,7 +48,6 @@ export interface AlertContextProviderProps { isFetched?: boolean; loadedAlerts?: boolean; updateAlerts?: (alerts: Alerts) => unknown; - updateLastReferralReminder?: () => unknown; updateLastBootPopup?: () => unknown; } @@ -124,8 +124,11 @@ export const AlertContextProvider = ({ updateAlerts: updateRemoteAlerts, updateLastReferralReminder, updateLastBootPopup, + updateLocalBoot: (params: Partial) => + updateAlerts({ ...alerts, ...params }), }), [ + updateAlerts, alerts, loadedAlerts, isFetched, diff --git a/packages/shared/src/hooks/feed/useFeedSurvey.ts b/packages/shared/src/hooks/feed/useFeedSurvey.ts index 25c6ceb08b..52a598d2fe 100644 --- a/packages/shared/src/hooks/feed/useFeedSurvey.ts +++ b/packages/shared/src/hooks/feed/useFeedSurvey.ts @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { useAnalyticsContext } from '../../contexts/AnalyticsContext'; import { AnalyticsEvent, TargetId, TargetType } from '../../lib/analytics'; import { updateFeedFeedbackReminder } from '../../graphql/alerts'; +import { useAlertsContext } from '../../contexts/AlertContext'; interface UseFeedSurvey { submitted: boolean; @@ -16,6 +17,7 @@ interface UseFeedSurveyProps { export const useFeedSurvey = ({ score }: UseFeedSurveyProps): UseFeedSurvey => { const [submitted, setSubmitted] = useState(false); const { trackEvent } = useAnalyticsContext(); + const { updateLocalBoot } = useAlertsContext(); const trackSurveyEvent = (event_name: AnalyticsEvent, extra?) => trackEvent({ @@ -38,6 +40,7 @@ export const useFeedSurvey = ({ score }: UseFeedSurveyProps): UseFeedSurvey => { const onHide = () => { updateFeedFeedbackReminder(); trackSurveyEvent(AnalyticsEvent.DismissPromotion); + updateLocalBoot({ shouldShowFeedFeedback: false }); }; useEffect(() => { From 98359bebfc225e4ea7eb7963df3ed521c7ff8f97 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 5 Jun 2024 14:15:14 +0800 Subject: [PATCH 15/16] refactor: unify target type --- .../src/components/cards/MarketingCta/MarketingCtaCard.tsx | 6 +++--- .../shared/src/components/cards/v1/MarketingCtaCard.tsx | 6 +++--- packages/shared/src/lib/analytics.ts | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/shared/src/components/cards/MarketingCta/MarketingCtaCard.tsx b/packages/shared/src/components/cards/MarketingCta/MarketingCtaCard.tsx index eca2dcf61a..4aed49fc16 100644 --- a/packages/shared/src/components/cards/MarketingCta/MarketingCtaCard.tsx +++ b/packages/shared/src/components/cards/MarketingCta/MarketingCtaCard.tsx @@ -24,7 +24,7 @@ export function MarketingCtaCard({ trackEvent({ event_name: AnalyticsEvent.Impression, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); isImpressionTracked.current = true; @@ -33,7 +33,7 @@ export function MarketingCtaCard({ const onCtaClick = useCallback(() => { trackEvent({ event_name: AnalyticsEvent.Click, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); clearMarketingCta(marketingCta.campaignId); @@ -42,7 +42,7 @@ export function MarketingCtaCard({ const onCtaDismiss = useCallback(() => { trackEvent({ event_name: AnalyticsEvent.MarketingCtaDismiss, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); clearMarketingCta(marketingCta.campaignId); diff --git a/packages/shared/src/components/cards/v1/MarketingCtaCard.tsx b/packages/shared/src/components/cards/v1/MarketingCtaCard.tsx index eaab1bb6c7..2eba4d0fdd 100644 --- a/packages/shared/src/components/cards/v1/MarketingCtaCard.tsx +++ b/packages/shared/src/components/cards/v1/MarketingCtaCard.tsx @@ -30,7 +30,7 @@ export function MarketingCtaCardV1({ trackEvent({ event_name: AnalyticsEvent.Impression, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); isImpressionTracked.current = true; @@ -39,7 +39,7 @@ export function MarketingCtaCardV1({ const onCtaClick = useCallback(() => { trackEvent({ event_name: AnalyticsEvent.Click, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); clearMarketingCta(marketingCta.campaignId); @@ -48,7 +48,7 @@ export function MarketingCtaCardV1({ const onCtaDismiss = useCallback(() => { trackEvent({ event_name: AnalyticsEvent.MarketingCtaDismiss, - target_type: TargetType.MarketingCtaCard, + target_type: TargetType.PromotionCard, target_id: marketingCta.campaignId, }); clearMarketingCta(marketingCta.campaignId); diff --git a/packages/shared/src/lib/analytics.ts b/packages/shared/src/lib/analytics.ts index 6952c61308..95a0fa77d3 100644 --- a/packages/shared/src/lib/analytics.ts +++ b/packages/shared/src/lib/analytics.ts @@ -170,7 +170,6 @@ export enum FeedItemTitle { } export enum TargetType { - PromotionCard = 'promotion_card', MyFeedModal = 'my feed modal', ArticleAnonymousCTA = 'article anonymous cta', EnableNotifications = 'enable notifications', @@ -191,7 +190,7 @@ export enum TargetType { VerifyEmail = 'verify email', ResendVerificationCode = 'resend verification code', StreaksMilestone = 'streaks milestone', - MarketingCtaCard = 'promotion_card', + PromotionCard = 'promotion_card', MarketingCtaPopover = 'promotion_popover', Comment = 'comment', ReadingReminder = 'reading reminder', From b355db90823f71af5da3c3d7155fdb076aa2cc3a Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 5 Jun 2024 14:54:24 +0800 Subject: [PATCH 16/16] fix: border on touch device --- .../cards/survey/FeedSurveyBanner.tsx | 58 +++++++++---------- packages/shared/src/styles/custom.ts | 3 + 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx b/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx index 9688578eb0..77269dfaec 100644 --- a/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx +++ b/packages/shared/src/components/cards/survey/FeedSurveyBanner.tsx @@ -3,7 +3,7 @@ import { RatingStars } from '../../utilities/RatingStars'; import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; import { useFeedSurvey } from '../../../hooks/feed/useFeedSurvey'; import { FeedSurveyProps } from './common'; -import { feedSurveyBg, feedSurveyBorder } from '../../../styles/custom'; +import { feedSurveyBg, feedSurveyTopBorder } from '../../../styles/custom'; export function FeedSurveyBanner({ max, @@ -15,38 +15,36 @@ export function FeedSurveyBanner({ const { submitted, onSubmit, onHide } = useFeedSurvey({ score }); return ( -
+
-
-
-

{title}

- + className="flex flex-col px-4 py-6 tablet:px-6" + style={{ background: feedSurveyBg }} + > +
+
+

{title}

+ +
+
- + {submitted && ( +
+

+ {postFeedbackMessage} + {score <= lowScore.value ? lowScore.message : null} +

+ {score <= lowScore.value && lowScore.cta} +
+ )}
- {submitted && ( -
-

- {postFeedbackMessage} - {score <= lowScore.value ? lowScore.message : null} -

- {score <= lowScore.value && lowScore.cta} -
- )}
); } diff --git a/packages/shared/src/styles/custom.ts b/packages/shared/src/styles/custom.ts index dc896e87b4..8cbb49b5bf 100644 --- a/packages/shared/src/styles/custom.ts +++ b/packages/shared/src/styles/custom.ts @@ -7,3 +7,6 @@ export const feedSurveyBg = export const feedSurveyBorder = 'linear-gradient(180deg, var(--theme-accent-cheese-default) 0%, var(--theme-accent-bacon-default) 50%, var(--theme-accent-onion-default) 100%)'; + +export const feedSurveyTopBorder = + 'linear-gradient(90deg, var(--theme-accent-cheese-default) 0%, var(--theme-accent-bacon-default) 50%, var(--theme-accent-onion-default) 100%)';