-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
integrating process features with plan permissions
- Trying to get rid of the plans mock, but it still needs some work (complicated when most features are missing from the plan rn) - Commented all the non implemented features in the process create form
- Loading branch information
1 parent
00d43e8
commit 41e3239
Showing
14 changed files
with
244 additions
and
379 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { dotobject } from '@vocdoni/sdk' | ||
import { useTranslation } from 'react-i18next' | ||
import type { Plan } from './Plans' | ||
|
||
export type FeaturesKeys = | ||
| 'anonymous' | ||
| 'secretUntilTheEnd' | ||
| 'overwrite' | ||
| 'personalization' | ||
| 'emailReminder' | ||
| 'smsNotification' | ||
| 'whiteLabel' | ||
| 'liveStreaming' | ||
|
||
// Translation keys for the subscription features | ||
export const PlanFeaturesTranslationKeys = { | ||
'organization.memberships': 'features.memberships', | ||
'organization.subOrgs': 'features.sub_orgs', | ||
'votingTypes.weighted': 'features.weighted', | ||
'votingTypes.approval': 'features.approval', | ||
'votingTypes.ranked': 'features.ranked', | ||
'features.personalization': 'features.personalization', | ||
'features.emailReminder': 'features.email_reminder', | ||
'features.smsNotification': 'features.sms_notification', | ||
} | ||
|
||
/** | ||
* Checks if a given feature exists and meets the required condition in a plan. | ||
* | ||
* @param plan - The plan object to check. | ||
* @param featurePath - Dot notation path to the feature (e.g., 'organization.memberships'). | ||
* @param expectedValue - Expected value or comparison object. | ||
* - If a number, checks for >= comparison. | ||
* - If an object, supports { operator, value } (e.g., { operator: '>=', value: 10 }). | ||
* @returns boolean - `true` if the feature meets the condition, `false` otherwise. | ||
*/ | ||
export const isFeatureAvailable = ( | ||
plan: Plan, | ||
featurePath: string, | ||
expectedValue?: number | { operator: '===' | '>' | '>=' | '<' | '<='; value: number } | ||
): boolean => { | ||
const featureValue = dotobject(plan, featurePath) // Get the feature value using dot notation | ||
|
||
if (typeof featureValue === 'undefined') { | ||
return false // If the feature doesn't exist, return false | ||
} | ||
|
||
// If no expected value is provided, return true if the feature exists | ||
if (typeof expectedValue === 'undefined') { | ||
return true | ||
} | ||
|
||
// Handle exact match or comparison | ||
if (typeof expectedValue === 'number') { | ||
return featureValue >= expectedValue // Default to "greater than or equal to" for numbers | ||
} | ||
|
||
if (typeof expectedValue === 'object' && expectedValue.operator && expectedValue.value !== undefined) { | ||
const { operator, value } = expectedValue | ||
|
||
switch (operator) { | ||
case '===': | ||
return featureValue === value | ||
case '>': | ||
return featureValue > value | ||
case '>=': | ||
return featureValue >= value | ||
case '<': | ||
return featureValue < value | ||
case '<=': | ||
return featureValue <= value | ||
default: | ||
throw new Error(`Unsupported operator: ${operator}`) | ||
} | ||
} | ||
|
||
throw new Error('Invalid expectedValue type') | ||
} | ||
|
||
// yeah, it's sad but we need to include all the translations in a way the extractor does not remove them... | ||
// note this component does not need (and should never) to be included in the app | ||
const UnusedComponentButRequiredToNotLoseTranslations = () => { | ||
const { t } = useTranslation() | ||
t('features.memberships', { defaultValue: 'Up to {{ count }} memberships' }) | ||
t('features.sub_orgs', { defaultValue: 'Up to {{ count }} sub-organizations' }) | ||
t('features.approval', { defaultValue: 'Approval voting' }) | ||
t('features.ranked', { defaultValue: 'Ranked voting' }) | ||
t('features.weighted', { defaultValue: 'Weighted voting' }) | ||
t('features.personalization', { defaultValue: 'Personalization' }) | ||
t('features.email_reminder', { defaultValue: 'Email reminder' }) | ||
t('features.sms_notification', { defaultValue: 'SMS notification' }) | ||
|
||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 0 additions & 82 deletions
82
src/components/ProcessCreate/Questions/useSaasVotingType.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
import { Box, Flex, Link, Text } from '@chakra-ui/react' | ||
import { Button } from '@vocdoni/chakra-components' | ||
import { Box, Flex, Link } from '@chakra-ui/react' | ||
import { useTranslation } from 'react-i18next' | ||
import { Link as ReactRouterLink } from 'react-router-dom' | ||
import { useAccountPlan } from '~components/Account/useAccountPlan' | ||
import { useSubscription } from '~components/Auth/Subscription' | ||
import { VocdoniLogo } from '~components/Layout/Logo' | ||
import { PlanId } from '~constants' | ||
|
||
const SaasFooter = () => { | ||
const { t } = useTranslation() | ||
const { data } = useAccountPlan() | ||
const isCustom = data?.plan === 'custom' | ||
const isFree = data?.plan === 'free' | ||
const { subscription } = useSubscription() | ||
const isCustom = subscription?.plan.id === PlanId.Custom | ||
const isFree = subscription?.plan.id === PlanId.Free | ||
|
||
return ( | ||
<Box bgColor={'process_create.bg_light'} _dark={{ bgColor: 'process_create.bg_dark' }}> | ||
|
@@ -35,17 +35,7 @@ const SaasFooter = () => { | |
<Link as={ReactRouterLink} to=''> | ||
{t('privacy_policy', { defaultValue: 'Privacy Policy' })} | ||
</Link> | ||
<Link as={ReactRouterLink} to=''> | ||
[email protected] | ||
</Link> | ||
</Flex> | ||
<Flex flexDirection={{ base: 'column', lg: 'row' }} alignItems='center' gap={6} order={{ base: 1, lg: 2 }}> | ||
{isFree && ( | ||
<Text fontWeight='bold' fontSize='xl' mb={0}> | ||
$0.00 | ||
</Text> | ||
)} | ||
{!isCustom && <Button>UPGRADE TO PREMIUM</Button>} | ||
<Link href='mailto:[email protected]'>[email protected]</Link> | ||
</Flex> | ||
</Flex> | ||
</Box> | ||
|
Oops, something went wrong.