-
Notifications
You must be signed in to change notification settings - Fork 129
feat(condo): [DOMA-13311, DOMA-13308] - hide paid content and pc specific layout behind feature flags #7684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2caa55b
36e7cbe
9eef122
9f93db4
6ec7eb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -11,11 +11,15 @@ import Link from 'next/link' | |||
| import { useRouter } from 'next/router' | ||||
| import { CSSProperties, useCallback, useEffect, useMemo, useState } from 'react' | ||||
|
|
||||
| import { useFeatureFlags } from '@open-condo/featureflags/FeatureFlagsContext' | ||||
| import { useAuth } from '@open-condo/next/auth' | ||||
| import { useIntl } from '@open-condo/next/intl' | ||||
| import { Banner, Carousel, Typography } from '@open-condo/ui' | ||||
| import { colors } from '@open-condo/ui/colors' | ||||
|
|
||||
| import { UI_HIDE_USER_LINKS } from '@condo/domains/common/constants/featureflags' | ||||
|
|
||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
two spaces are enough |
||||
|
|
||||
|
|
||||
| interface HintI18n { | ||||
| title: string | ||||
|
|
@@ -43,6 +47,8 @@ const HINTS_WRAPPER_STYLE: CSSProperties = { marginBottom: 40 } | |||
| const HINTS_ROW_GUTTERS: RowProps['gutter'] = [0, 8] | ||||
|
|
||||
| export const useGlobalHints = () => { | ||||
| const { useFlag } = useFeatureFlags() | ||||
| const isUserLinksHidden = useFlag(UI_HIDE_USER_LINKS) | ||||
| const intl = useIntl() | ||||
| const CanDisableHintsMessage = intl.formatMessage({ id: 'global.globalHints.canDisableHints' }) | ||||
| const InProfileMessage = intl.formatMessage({ id: 'global.globalHints.canDisableHints.inProfile' }) | ||||
|
|
@@ -134,14 +140,16 @@ export const useGlobalHints = () => { | |||
| <Typography.Text type='secondary' size='small'> | ||||
| {CanDisableHintsMessage} | ||||
| </Typography.Text> | ||||
| <Link href='/user'> | ||||
| <Typography.Link size='small'>{InProfileMessage}</Typography.Link> | ||||
| </Link> | ||||
| {!isUserLinksHidden && ( | ||||
| <Link href='/user'> | ||||
| <Typography.Link size='small'>{InProfileMessage}</Typography.Link> | ||||
| </Link> | ||||
| )} | ||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||
| </Typography.Text> | ||||
| </Col> | ||||
| </Row> | ||||
| </div> | ||||
| ), [CanDisableHintsMessage, InProfileMessage, MoreMessage, handleBannerClick, hints]) | ||||
| ), [CanDisableHintsMessage, InProfileMessage, isUserLinksHidden, MoreMessage, handleBannerClick, hints]) | ||||
|
|
||||
| return { | ||||
| GlobalHints: renderHints, | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,13 +4,15 @@ import Head from 'next/head' | |||||
| import { useRouter } from 'next/router' | ||||||
| import React, { useMemo, useCallback } from 'react' | ||||||
|
|
||||||
| import { useFeatureFlags } from '@open-condo/featureflags/FeatureFlagsContext' | ||||||
| import { useAuth } from '@open-condo/next/auth' | ||||||
| import { useIntl } from '@open-condo/next/intl' | ||||||
| import { useOrganization } from '@open-condo/next/organization' | ||||||
| import { Typography, Button, Tooltip } from '@open-condo/ui' | ||||||
|
|
||||||
| import { PageHeader, PageWrapper } from '@condo/domains/common/components/containers/BaseLayout' | ||||||
| import { Loader } from '@condo/domains/common/components/Loader' | ||||||
| import { UI_HIDE_PAID_FEATURES } from '@condo/domains/common/constants/featureflags' | ||||||
| import { SETTINGS_TAB_SUBSCRIPTION } from '@condo/domains/common/constants/settingsTabs' | ||||||
|
|
||||||
| import { SubscriptionBlockedContent } from './SubscriptionBlockedContent' | ||||||
|
|
@@ -72,6 +74,8 @@ const getPageTitle = (pathname: string, intl: any): string => { | |||||
| export const SubscriptionAccessGuard: React.FC<SubscriptionAccessGuardProps> = ({ children, skipGuard = false }) => { | ||||||
| const router = useRouter() | ||||||
| const intl = useIntl() | ||||||
| const { useFlag } = useFeatureFlags() | ||||||
| const hidePaidFeatures = useFlag(UI_HIDE_PAID_FEATURES) | ||||||
| const GuardTitle = intl.formatMessage({ id: 'subscription.accessGuard.title' }) | ||||||
| const GuardDescription = intl.formatMessage({ id: 'subscription.accessGuard.description' }) | ||||||
| const GoToPlansMessage = intl.formatMessage({ id: 'subscription.accessGuard.goToPlans' }) | ||||||
|
|
@@ -80,6 +84,8 @@ export const SubscriptionAccessGuard: React.FC<SubscriptionAccessGuardProps> = ( | |||||
| const FeaturePayButton = intl.formatMessage({ id: 'subscription.accessGuard.feature.payButton' }) | ||||||
| const AwaitingPaymentMessage = intl.formatMessage({ id: 'subscription.planCard.requestPending' }) | ||||||
| const AwaitingPaymentTooltipMessage = intl.formatMessage({ id: 'subscription.planCard.requestPending.tooltip' }) | ||||||
| const UnavailableTitle = intl.formatMessage({ id: 'subscription.accessGuard.unavailable.title' }, { defaultMessage: 'Access denied' }) | ||||||
| const UnavailableDescription = intl.formatMessage({ id: 'subscription.accessGuard.unavailable.description' }, { defaultMessage: 'You do not have access to this service' }) | ||||||
| const { isFeatureAvailable, isB2BAppEnabled, hasSubscription, loading, hasSubscriptionsFeature } = useOrganizationSubscription() | ||||||
| const { organization, isLoading: orgIsLoading } = useOrganization() | ||||||
| const { isLoading: authIsLoading } = useAuth() | ||||||
|
|
@@ -200,6 +206,24 @@ export const SubscriptionAccessGuard: React.FC<SubscriptionAccessGuardProps> = ( | |||||
| : null | ||||||
|
|
||||||
| if (isBlocked) { | ||||||
| if (hidePaidFeatures && !hasSubscription) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Logic flaw in feature-flag condition creates non-functional buttons. The condition In that screen:
Both buttons would be visible but non-functional, breaking the UX. 🔒 Proposed fixRemove the - if (hidePaidFeatures && !hasSubscription) {
+ if (hidePaidFeatures) {
return (📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| return ( | ||||||
| <> | ||||||
| <Head> | ||||||
| <title>{pageTitle}</title> | ||||||
| </Head> | ||||||
| <PageWrapper> | ||||||
| <PageHeader title={<Typography.Title>{pageTitle}</Typography.Title>} /> | ||||||
| <SubscriptionBlockedContent | ||||||
| title={UnavailableTitle} | ||||||
| description={UnavailableDescription} | ||||||
| primaryButton={null} | ||||||
| /> | ||||||
| </PageWrapper> | ||||||
| </> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| let primaryButton: React.ReactNode | ||||||
| if (!hasFeaturePlan) { | ||||||
| primaryButton = <Button id='subscription-access-guard-go-to-plans-button' type='primary' onClick={handleGoToPlans}>{GoToPlansMessage}</Button> | ||||||
|
|
@@ -229,8 +253,8 @@ export const SubscriptionAccessGuard: React.FC<SubscriptionAccessGuardProps> = ( | |||||
|
|
||||||
| return ( | ||||||
| <> | ||||||
| {PaymentModal} | ||||||
| <SubscriptionTrialEndedModal /> | ||||||
| {!hidePaidFeatures && PaymentModal} | ||||||
| {!hidePaidFeatures && <SubscriptionTrialEndedModal />} | ||||||
| <Head> | ||||||
| <title>{pageTitle}</title> | ||||||
| </Head> | ||||||
|
|
@@ -251,8 +275,8 @@ export const SubscriptionAccessGuard: React.FC<SubscriptionAccessGuardProps> = ( | |||||
|
|
||||||
| return ( | ||||||
| <> | ||||||
| <SubscriptionWelcomeModal /> | ||||||
| <SubscriptionTrialEndedModal /> | ||||||
| {!hidePaidFeatures && <SubscriptionWelcomeModal />} | ||||||
| {!hidePaidFeatures && <SubscriptionTrialEndedModal />} | ||||||
| {children} | ||||||
| </> | ||||||
| ) | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
UI_HIDE_LAYOUT_SIDE_MENUis enabled on desktop, theSideNavis not rendered, but this class still applies eitherstyles.subLayoutExpandedorstyles.subLayoutCollapsed; inBaseLayout.module.cssthose add a left margin equal to the side-menu width/collapsed width. As a result, embedded pages with the side menu hidden still render shifted to the right with a blank gutter, so the layout is not actually full-width.Useful? React with 👍 / 👎.