From 4370ce990a2e6d8e67f533dbd4c58ca33f006d47 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 21:02:13 +0800 Subject: [PATCH 1/7] fix: gift modal UI --- .../src/components/ConditionalWrapper.tsx | 11 ++ .../src/components/plus/GiftPlusModal.tsx | 134 ++++++++++++------ .../shared/src/components/plus/PlusTitle.tsx | 2 +- 3 files changed, 103 insertions(+), 44 deletions(-) diff --git a/packages/shared/src/components/ConditionalWrapper.tsx b/packages/shared/src/components/ConditionalWrapper.tsx index 839460162b..a309b6a6fe 100644 --- a/packages/shared/src/components/ConditionalWrapper.tsx +++ b/packages/shared/src/components/ConditionalWrapper.tsx @@ -13,3 +13,14 @@ const ConditionalWrapper = ({ condition ? wrapper(children) : (children as ReactElement); export default ConditionalWrapper; + +export const ConditionalRender = ({ + condition, + children, +}: Pick): ReactNode => { + if (!condition) { + return null; + } + + return children; +}; diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index fafaf60f1a..a963aee3bd 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -1,6 +1,7 @@ import type { ReactElement } from 'react'; import React, { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; +import classNames from 'classnames'; import type { ModalProps } from '../modals/common/Modal'; import { Modal } from '../modals/common/Modal'; import { @@ -29,12 +30,23 @@ import { ArrowKey, KeyboardCommand } from '../../lib/element'; import { GiftingSelectedUser } from './GiftingSelectedUser'; import Link from '../utilities/Link'; import { useViewSize, ViewSize } from '../../hooks'; +import { Image } from '../image/Image'; +import { fallbackImages } from '../../lib/config'; +import { sizeClasses } from '../ProfilePicture'; +import { ConditionalRender } from '../ConditionalWrapper'; +import { Separator } from '../cards/common/common'; +import { IconSize } from '../Icon'; +import { ReputationUserBadge } from '../ReputationUserBadge'; +import classed from '../../lib/classed'; +import JoinedDate from '../profile/JoinedDate'; interface GiftPlusModalProps extends ModalProps { preselected?: UserShortProfile; onSelected?: (user: UserShortProfile) => void; } +const UserText = classed('span', 'flex flex-row items-center justify-center'); + export function GiftPlusModalComponent({ preselected, onSelected, @@ -117,7 +129,7 @@ export function GiftPlusModalComponent({ overlayRef={setOverlay} isDrawerOnMobile > - +
- + Gift daily.dev Plus 🎁 - {selected ? ( - setSelected(null)} +
+ - ) : ( -
- setQuery('')} - visible={isVisible} - showArrow={false} - interactive - content={ - user.isPlus} - disabledTooltip="This user already has daily.dev Plus" + {preselected && ( + <> + + + {preselected.name} + + + + + + @{preselected.username} + + + + + + )} +
+ + {selected ? ( + setSelected(null)} + /> + ) : ( +
+ setQuery('')} + visible={isVisible} + showArrow={false} + interactive + content={ + user.isPlus} + disabledTooltip="This user already has daily.dev Plus" + /> + } + container={{ + className: 'shadow', + paddingClassName: 'p-0', + roundedClassName: 'rounded-16', + bgClassName: 'bg-accent-pepper-subtlest', + }} + > + } + inputId="search_user" + fieldType="tertiary" + autoComplete="off" + label="Select a recipient by name or handle" + onKeyDown={onKeyDown} + onChange={(e) => onSearch(e.currentTarget.value.trim())} + onFocus={(e) => setQuery(e.currentTarget.value.trim())} /> - } - container={{ - className: 'shadow', - paddingClassName: 'p-0', - roundedClassName: 'rounded-16', - bgClassName: 'bg-accent-pepper-subtlest', - }} - > - } - inputId="search_user" - fieldType="tertiary" - autoComplete="off" - label="Select a recipient by name or handle" - onKeyDown={onKeyDown} - onChange={(e) => onSearch(e.currentTarget.value.trim())} - onFocus={(e) => setQuery(e.currentTarget.value.trim())} - /> - -
- )} + +
+ )} +
One-year plan diff --git a/packages/shared/src/components/plus/PlusTitle.tsx b/packages/shared/src/components/plus/PlusTitle.tsx index 586129ba71..78ff9d8f8e 100644 --- a/packages/shared/src/components/plus/PlusTitle.tsx +++ b/packages/shared/src/components/plus/PlusTitle.tsx @@ -24,7 +24,7 @@ export function PlusTitle( {...typography} className={classnames('flex flex-row items-center gap-0.5', className)} > - Plus + Plus ); } From 1eb138af4e76e4901b46dbb7777c8b0cb97e160f Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 22:16:12 +0800 Subject: [PATCH 2/7] fix: app crash --- .../shared/src/components/comments/CommentActionButtons.tsx | 3 +-- packages/shared/src/components/squads/SquadMemberMenu.tsx | 5 ++--- packages/webapp/pages/account/invite.tsx | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/components/comments/CommentActionButtons.tsx b/packages/shared/src/components/comments/CommentActionButtons.tsx index a674c5ad58..3b01563066 100644 --- a/packages/shared/src/components/comments/CommentActionButtons.tsx +++ b/packages/shared/src/components/comments/CommentActionButtons.tsx @@ -52,7 +52,6 @@ import { ContentPreferenceType } from '../../graphql/contentPreference'; import { isFollowingContent } from '../../hooks/contentPreference/types'; import { useIsSpecialUser } from '../../hooks/auth/useIsSpecialUser'; import { GiftIcon } from '../icons/gift'; -import { usePaymentContext } from '../../contexts/PaymentContext'; export interface CommentActionProps { onComment: (comment: Comment, parentId: string | null) => void; @@ -89,7 +88,7 @@ export default function CommentActionButtons({ const { onMenuClick, isOpen, onHide } = useContextMenu({ id }); const { openModal } = useLazyModal(); const { displayToast } = useToastNotification(); - const { isPlusAvailable } = usePaymentContext(); + const { isValidRegion: isPlusAvailable } = useAuthContext(); const { logSubscriptionEvent } = usePlusSubscription(); const [voteState, setVoteState] = useState(() => { return { diff --git a/packages/shared/src/components/squads/SquadMemberMenu.tsx b/packages/shared/src/components/squads/SquadMemberMenu.tsx index 24e3f1879f..eb2f08a9bb 100644 --- a/packages/shared/src/components/squads/SquadMemberMenu.tsx +++ b/packages/shared/src/components/squads/SquadMemberMenu.tsx @@ -1,6 +1,6 @@ import type { ReactElement } from 'react'; import React, { useContext, useMemo } from 'react'; -import AuthContext from '../../contexts/AuthContext'; +import AuthContext, { useAuthContext } from '../../contexts/AuthContext'; import { reportSquadMember } from '../../lib/constants'; import { IconSize } from '../Icon'; import type { SourceMember, Squad } from '../../graphql/sources'; @@ -19,7 +19,6 @@ import { LazyModal } from '../modals/common/types'; import { GiftIcon } from '../icons/gift'; import { useLazyModal } from '../../hooks/useLazyModal'; import { LogEvent, TargetId } from '../../lib/log'; -import { usePaymentContext } from '../../contexts/PaymentContext'; interface SquadMemberMenuProps extends Pick { squad: Squad; @@ -129,7 +128,7 @@ export default function SquadMemberMenu({ const { user } = useContext(AuthContext); const { showPrompt } = usePrompt(); const { displayToast } = useToastNotification(); - const { isPlusAvailable } = usePaymentContext(); + const { isValidRegion: isPlusAvailable } = useAuthContext(); const { logSubscriptionEvent } = usePlusSubscription(); const onUpdateMember = async ( role: SourceMemberRole, diff --git a/packages/webapp/pages/account/invite.tsx b/packages/webapp/pages/account/invite.tsx index 0a16bbc0b3..10ca9e2823 100644 --- a/packages/webapp/pages/account/invite.tsx +++ b/packages/webapp/pages/account/invite.tsx @@ -47,7 +47,6 @@ import { import { GiftIcon } from '@dailydotdev/shared/src/components/icons/gift'; import { useLazyModal } from '@dailydotdev/shared/src/hooks/useLazyModal'; import { LazyModal } from '@dailydotdev/shared/src/components/modals/common/types'; -import { usePaymentContext } from '@dailydotdev/shared/src/contexts/PaymentContext'; import { useLogContext } from '@dailydotdev/shared/src/contexts/LogContext'; import AccountContentSection from '../../components/layouts/AccountLayout/AccountContentSection'; import { AccountPageContainer } from '../../components/layouts/AccountLayout/AccountPageContainer'; @@ -66,7 +65,7 @@ const AccountInvitePage = (): ReactElement => { const { url, referredUsersCount } = useReferralCampaign({ campaignKey: ReferralCampaignKey.Generic, }); - const { isPlusAvailable } = usePaymentContext(); + const { isValidRegion: isPlusAvailable } = useAuthContext(); const { logSubscriptionEvent } = usePlusSubscription(); const { logEvent } = useLogContext(); const inviteLink = url || link.referral.defaultUrl; From 1da1ee94559d8fc71b8413dca3ebfeffef6f54a3 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 22:21:23 +0800 Subject: [PATCH 3/7] fix: spacing --- packages/shared/src/components/plus/GiftPlusModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index a963aee3bd..b37716ac13 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -220,7 +220,7 @@ export function GiftPlusModalComponent({
)} -
+
One-year plan From 317f89cd246e2ff52239cabb592160acffc5a31f Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 22:23:45 +0800 Subject: [PATCH 4/7] fix: minor --- .../shared/src/components/plus/GiftPlusModal.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index b37716ac13..6d107704de 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -224,11 +224,13 @@ export function GiftPlusModalComponent({ One-year plan - + {giftOneYear?.extraLabel && ( + + )} {giftOneYear?.price} {giftOneYear?.currencyCode} From fe57b27caab4802028fce411295329e2668b9f89 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 22:28:29 +0800 Subject: [PATCH 5/7] fix: error --- packages/shared/src/components/plus/GiftPlusModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index 6d107704de..c264f185ee 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -246,7 +246,7 @@ export function GiftPlusModalComponent({ tag="a" disabled={!selected} variant={ButtonVariant.Primary} - onClick={() => onSelected(selected)} + onClick={() => onSelected?.(selected)} > Gift & Pay {giftOneYear?.price} From 73709a827034044a49c1b1c3958d5bfaf9f2ad2d Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Thu, 6 Feb 2025 22:35:30 +0800 Subject: [PATCH 6/7] fix: urls --- packages/shared/src/components/plus/GiftPlusModal.tsx | 3 ++- packages/shared/src/components/plus/GiftReceivedPlusModal.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index c264f185ee..3cf150dc95 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -39,6 +39,7 @@ import { IconSize } from '../Icon'; import { ReputationUserBadge } from '../ReputationUserBadge'; import classed from '../../lib/classed'; import JoinedDate from '../profile/JoinedDate'; +import { webappUrl } from '../../lib/constants'; interface GiftPlusModalProps extends ModalProps { preselected?: UserShortProfile; @@ -241,7 +242,7 @@ export function GiftPlusModalComponent({ payment is processed, they’ll be notified of your gift. This is a one-time purchase, not a recurring subscription. - +
From 3971a34dad6b170a170e6c128cc54ddb4a78cea1 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Fri, 7 Feb 2025 17:49:31 +0800 Subject: [PATCH 7/7] fix: keyboard nav without data --- packages/shared/src/components/plus/GiftPlusModal.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/shared/src/components/plus/GiftPlusModal.tsx b/packages/shared/src/components/plus/GiftPlusModal.tsx index 3cf150dc95..c90cfa9a8e 100644 --- a/packages/shared/src/components/plus/GiftPlusModal.tsx +++ b/packages/shared/src/components/plus/GiftPlusModal.tsx @@ -67,6 +67,8 @@ export function GiftPlusModalComponent({ query, }); + setIndex(0); + return result.recommendedMentions; }, enabled: !!query?.length, @@ -78,6 +80,10 @@ export function GiftPlusModalComponent({ return; } + if (!users?.length) { + return; + } + e.preventDefault(); if (e.key === ArrowKey.Down) {