Some design
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#1185FE" d="M6.335 4.212c2.293 1.76 4.76 5.327 5.665 7.241.906-1.914 3.372-5.482 5.665-7.241C19.319 2.942 22 1.96 22 5.086c0 .624-.35 5.244-.556 5.994-.713 2.608-3.315 3.273-5.629 2.87 4.045.704 5.074 3.035 2.852 5.366-4.22 4.426-6.066-1.111-6.54-2.53-.086-.26-.126-.382-.127-.278 0-.104-.041.018-.128.278-.473 1.419-2.318 6.956-6.539 2.53-2.222-2.331-1.193-4.662 2.852-5.366-2.314.403-4.916-.262-5.63-2.87C2.35 10.33 2 5.71 2 5.086c0-3.126 2.68-2.144 4.335-.874Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 557 B |
+6
-2
@@ -108,8 +108,7 @@ export const gradients = {
|
|||||||
nordic: {
|
nordic: {
|
||||||
values: [
|
values: [
|
||||||
[0, '#083367'],
|
[0, '#083367'],
|
||||||
[0.4, '#1A4972'],
|
[0.4, '#386D84'],
|
||||||
[0.6, '#386D84'],
|
|
||||||
[1, '#9EE8C1'],
|
[1, '#9EE8C1'],
|
||||||
],
|
],
|
||||||
hover_value: '#3A7085',
|
hover_value: '#3A7085',
|
||||||
@@ -124,3 +123,8 @@ export const gradients = {
|
|||||||
hover_value: '#755B62',
|
hover_value: '#755B62',
|
||||||
},
|
},
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
export const blueskyPlus = {
|
||||||
|
dark: '#083367',
|
||||||
|
light: '#9EE8C1',
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ export function Logotype(props: Props) {
|
|||||||
const {fill, size: _size, style, gradient, ...rest} = useCommonSVGProps(props)
|
const {fill, size: _size, style, gradient, ...rest} = useCommonSVGProps(props)
|
||||||
// @ts-ignore it's fiiiiine
|
// @ts-ignore it's fiiiiine
|
||||||
const size = parseInt(rest.width || 100)
|
const size = parseInt(rest.width || 100)
|
||||||
const ratio = 78 / 330
|
const ratio = 88 / 330
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Svg
|
<Svg
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 330 78"
|
viewBox="0 -10 330 88"
|
||||||
accessibilityLabel={_(msg`Bluesky Plus`)}
|
accessibilityLabel={_(msg`Bluesky Plus`)}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import {createSinglePathSVG} from './TEMPLATE'
|
||||||
|
|
||||||
|
export const Mark = createSinglePathSVG({
|
||||||
|
path: 'M6.335 4.212c2.293 1.76 4.76 5.327 5.665 7.241.906-1.914 3.372-5.482 5.665-7.241C19.319 2.942 22 1.96 22 5.086c0 .624-.35 5.244-.556 5.994-.713 2.608-3.315 3.273-5.629 2.87 4.045.704 5.074 3.035 2.852 5.366-4.22 4.426-6.066-1.111-6.54-2.53-.086-.26-.126-.382-.127-.278 0-.104-.041.018-.128.278-.473 1.419-2.318 6.956-6.539 2.53-2.222-2.331-1.193-4.662 2.852-5.366-2.314.403-4.916-.262-5.63-2.87C2.35 10.33 2 5.71 2 5.086c0-3.126 2.68-2.144 4.335-.874Z',
|
||||||
|
})
|
||||||
@@ -39,6 +39,7 @@ import {CodeBrackets_Stroke2_Corner2_Rounded as CodeBracketsIcon} from '#/compon
|
|||||||
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
||||||
import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe'
|
import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe'
|
||||||
import {Lock_Stroke2_Corner2_Rounded as LockIcon} from '#/components/icons/Lock'
|
import {Lock_Stroke2_Corner2_Rounded as LockIcon} from '#/components/icons/Lock'
|
||||||
|
import {Mark} from '#/components/icons/Logo'
|
||||||
import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller'
|
import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller'
|
||||||
import {
|
import {
|
||||||
Person_Stroke2_Corner2_Rounded as PersonIcon,
|
Person_Stroke2_Corner2_Rounded as PersonIcon,
|
||||||
@@ -142,6 +143,18 @@ export function SettingsScreen({}: Props) {
|
|||||||
<AddAccountRow />
|
<AddAccountRow />
|
||||||
)}
|
)}
|
||||||
<SettingsList.Divider />
|
<SettingsList.Divider />
|
||||||
|
<SettingsList.LinkItem
|
||||||
|
to="/subscriptions"
|
||||||
|
label={_(msg`Subscriptions`)}>
|
||||||
|
<SettingsList.ItemIcon
|
||||||
|
icon={Mark}
|
||||||
|
iconProps={{gradient: 'nordic'}}
|
||||||
|
/>
|
||||||
|
<SettingsList.ItemText>
|
||||||
|
<Trans>Subscriptions</Trans>
|
||||||
|
</SettingsList.ItemText>
|
||||||
|
</SettingsList.LinkItem>
|
||||||
|
<SettingsList.Divider />
|
||||||
<SettingsList.LinkItem to="/settings/account" label={_(msg`Account`)}>
|
<SettingsList.LinkItem to="/settings/account" label={_(msg`Account`)}>
|
||||||
<SettingsList.ItemIcon icon={PersonIcon} />
|
<SettingsList.ItemIcon icon={PersonIcon} />
|
||||||
<SettingsList.ItemText>
|
<SettingsList.ItemText>
|
||||||
@@ -162,12 +175,6 @@ export function SettingsScreen({}: Props) {
|
|||||||
<Trans>Moderation</Trans>
|
<Trans>Moderation</Trans>
|
||||||
</SettingsList.ItemText>
|
</SettingsList.ItemText>
|
||||||
</SettingsList.LinkItem>
|
</SettingsList.LinkItem>
|
||||||
<SettingsList.LinkItem to="/subscriptions" label={_(msg`Subscriptions`)}>
|
|
||||||
<SettingsList.ItemIcon icon={HandIcon} />
|
|
||||||
<SettingsList.ItemText>
|
|
||||||
<Trans>Subscriptions</Trans>
|
|
||||||
</SettingsList.ItemText>
|
|
||||||
</SettingsList.LinkItem>
|
|
||||||
<SettingsList.LinkItem
|
<SettingsList.LinkItem
|
||||||
to="/settings/content-and-media"
|
to="/settings/content-and-media"
|
||||||
label={_(msg`Content and media`)}>
|
label={_(msg`Content and media`)}>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {HITSLOP_10} from '#/lib/constants'
|
|||||||
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
|
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
|
||||||
import * as Button from '#/components/Button'
|
import * as Button from '#/components/Button'
|
||||||
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron'
|
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron'
|
||||||
|
import {Props as IconProps} from '#/components/icons/common'
|
||||||
import {Link, LinkProps} from '#/components/Link'
|
import {Link, LinkProps} from '#/components/Link'
|
||||||
import {createPortalGroup} from '#/components/Portal'
|
import {createPortalGroup} from '#/components/Portal'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
@@ -177,8 +178,10 @@ export function ItemIcon({
|
|||||||
icon: Comp,
|
icon: Comp,
|
||||||
size = 'xl',
|
size = 'xl',
|
||||||
color: colorProp,
|
color: colorProp,
|
||||||
|
iconProps,
|
||||||
}: Omit<React.ComponentProps<typeof Button.ButtonIcon>, 'position'> & {
|
}: Omit<React.ComponentProps<typeof Button.ButtonIcon>, 'position'> & {
|
||||||
color?: string
|
color?: string
|
||||||
|
iconProps?: Pick<IconProps, 'gradient'>
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {destructive, withinGroup} = useContext(ItemContext)
|
const {destructive, withinGroup} = useContext(ItemContext)
|
||||||
@@ -201,7 +204,7 @@ export function ItemIcon({
|
|||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<View style={[a.z_20, {width: iconSize, height: iconSize}]}>
|
<View style={[a.z_20, {width: iconSize, height: iconSize}]}>
|
||||||
<Comp width={iconSize} style={[{color}]} />
|
<Comp width={iconSize} style={[{color}]} {...iconProps} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
|
|
||||||
import {CommonNavigatorParams} from '#/lib/routes/types'
|
import {CommonNavigatorParams} from '#/lib/routes/types'
|
||||||
|
import {isAndroid, isIOS, isWeb} from '#/platform/detection'
|
||||||
import {PurchasesState, usePurchases} from '#/state/purchases'
|
import {PurchasesState, usePurchases} from '#/state/purchases'
|
||||||
import {useManageSubscription} from '#/state/purchases/hooks/useManageSubscription'
|
import {useManageSubscription} from '#/state/purchases/hooks/useManageSubscription'
|
||||||
import {SubscriptionGroupId} from '#/state/purchases/types'
|
import {
|
||||||
|
PlatformId,
|
||||||
|
SubscriptionGroupId,
|
||||||
|
SubscriptionOfferingId,
|
||||||
|
} from '#/state/purchases/types'
|
||||||
import {APISubscription} from '#/state/purchases/types'
|
import {APISubscription} from '#/state/purchases/types'
|
||||||
import {CenteredView} from '#/view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
import {atoms as a, tokens, useTheme} from '#/alf'
|
||||||
@@ -14,15 +20,18 @@ import {Admonition} from '#/components/Admonition'
|
|||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {useDialogControl} from '#/components/Dialog'
|
import {useDialogControl} from '#/components/Dialog'
|
||||||
import {BlueskyPlus} from '#/components/dialogs/BlueskyPlus'
|
import {BlueskyPlus} from '#/components/dialogs/BlueskyPlus'
|
||||||
|
import {Divider} from '#/components/Divider'
|
||||||
import {GradientFill} from '#/components/GradientFill'
|
import {GradientFill} from '#/components/GradientFill'
|
||||||
|
import {AndroidLogo} from '#/components/icons/AndroidLogo'
|
||||||
|
import {AppleLogo} from '#/components/icons/AppleLogo'
|
||||||
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Rotate} from '#/components/icons/ArrowRotateCounterClockwise'
|
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Rotate} from '#/components/icons/ArrowRotateCounterClockwise'
|
||||||
import {Full as BlueskyPlusLogo} from '#/components/icons/BlueskyPlus'
|
import {Full as BlueskyPlusLogo, Logotype} from '#/components/icons/BlueskyPlus'
|
||||||
import {CheckThick_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
import {CheckThick_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
||||||
import {Clock_Stroke2_Corner0_Rounded as Clock} from '#/components/icons/Clock'
|
import {Clock_Stroke2_Corner0_Rounded as Clock} from '#/components/icons/Clock'
|
||||||
|
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||||
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||||
import {SettingsGear2_Stroke2_Corner0_Rounded as Gear} from '#/components/icons/SettingsGear2'
|
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
import {createStaticClick, InlineLinkText, Link} from '#/components/Link'
|
import {createStaticClick, Link} from '#/components/Link'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
@@ -40,7 +49,7 @@ export function Subscriptions(_props: ScreenProps) {
|
|||||||
<Layout.Header title={_(msg`Subscriptions`)} />
|
<Layout.Header title={_(msg`Subscriptions`)} />
|
||||||
|
|
||||||
<Layout.Content>
|
<Layout.Content>
|
||||||
<CenteredView sideBorders={true} style={[a.util_screen_outer]}>
|
<CenteredView style={[a.util_screen_outer]}>
|
||||||
<View style={[a.px_xl, a.py_xl]}>
|
<View style={[a.px_xl, a.py_xl]}>
|
||||||
{purchases.status === 'loading' ? (
|
{purchases.status === 'loading' ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
@@ -113,13 +122,9 @@ function Core({
|
|||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.pt_sm]}>
|
<View style={[]}>
|
||||||
<BlueskyPlusLogo width={130} gradient="nordic" />
|
|
||||||
|
|
||||||
{isSubscribedToCore ? (
|
{isSubscribedToCore ? (
|
||||||
<View style={[a.pt_md]}>
|
<CoreSubscriptions subscriptions={state.subscriptions} />
|
||||||
<CoreSubscriptions subscriptions={state.subscriptions} />
|
|
||||||
</View>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!isSubscribedToCore && (
|
{!isSubscribedToCore && (
|
||||||
@@ -136,6 +141,8 @@ function Core({
|
|||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
<BlueskyPlusLogo width={130} gradient="nordic" />
|
||||||
|
|
||||||
<Text style={[a.text_3xl, a.font_heavy, a.pt_md, a.pb_xs]}>
|
<Text style={[a.text_3xl, a.font_heavy, a.pt_md, a.pb_xs]}>
|
||||||
<Trans>Building a better internet needs your support.</Trans>
|
<Trans>Building a better internet needs your support.</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
@@ -221,6 +228,7 @@ function Core({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/*
|
||||||
<View style={[a.pt_md]}>
|
<View style={[a.pt_md]}>
|
||||||
<Text style={[a.mb_md, a.text_xs]}>
|
<Text style={[a.mb_md, a.text_xs]}>
|
||||||
<InlineLinkText
|
<InlineLinkText
|
||||||
@@ -245,6 +253,7 @@ function Core({
|
|||||||
</InlineLinkText>
|
</InlineLinkText>
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
*/}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -254,51 +263,134 @@ function CoreSubscriptions(props: {subscriptions: APISubscription[]}) {
|
|||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
const {mutateAsync: manageSubscription} = useManageSubscription()
|
const {mutateAsync: manageSubscription} = useManageSubscription()
|
||||||
|
|
||||||
|
const copy = React.useMemo(() => {
|
||||||
|
return {
|
||||||
|
[SubscriptionOfferingId.CoreMonthly]: {
|
||||||
|
title: _(msg`Monthly`),
|
||||||
|
},
|
||||||
|
[SubscriptionOfferingId.CoreAnnual]: {
|
||||||
|
title: _(msg`Annual`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}, [_])
|
||||||
|
|
||||||
return props.subscriptions.map(sub => {
|
return props.subscriptions.map(sub => {
|
||||||
const endDate = i18n.date(new Date(sub.periodEndsAt), {dateStyle: 'medium'})
|
const endDate = i18n.date(new Date(sub.periodEndsAt), {dateStyle: 'medium'})
|
||||||
const StatusIcon = sub.renews ? Rotate : Clock
|
const StatusIcon = sub.renews ? Rotate : Clock
|
||||||
|
const c = copy[sub.offering]
|
||||||
|
const canManage =
|
||||||
|
(isWeb && sub.platform === PlatformId.Web) ||
|
||||||
|
(isIOS && sub.platform === PlatformId.Ios) ||
|
||||||
|
(isAndroid && sub.platform === PlatformId.Android)
|
||||||
|
const PlatformIcon = {
|
||||||
|
[PlatformId.Ios]: AppleLogo,
|
||||||
|
[PlatformId.Android]: AndroidLogo,
|
||||||
|
[PlatformId.Web]: Globe,
|
||||||
|
}[sub.platform]
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
key={sub.purchasedAt}
|
key={sub.purchasedAt}
|
||||||
style={[
|
style={[
|
||||||
a.p_lg,
|
a.p_md,
|
||||||
a.py_md,
|
a.px_lg,
|
||||||
a.rounded_md,
|
a.rounded_md,
|
||||||
a.border,
|
a.border,
|
||||||
a.gap_xs,
|
a.gap_xs,
|
||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
]}>
|
]}>
|
||||||
<GradientFill
|
<View
|
||||||
gradient={tokens.gradients.nordic}
|
style={[
|
||||||
style={{opacity: 0.1}}
|
a.flex_row,
|
||||||
/>
|
a.justify_between,
|
||||||
|
a.align_center,
|
||||||
|
{paddingBottom: 6},
|
||||||
|
]}>
|
||||||
|
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
|
||||||
|
<Logotype width={75} fill={t.atoms.text.color} />
|
||||||
|
|
||||||
<View style={[a.flex_row, a.justify_between, a.align_center]}>
|
<Text
|
||||||
<View>
|
style={[
|
||||||
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
a.text_sm,
|
||||||
<Text
|
a.rounded_full,
|
||||||
style={[a.text_md, a.font_bold, t.atoms.text_contrast_medium]}>
|
a.font_bold,
|
||||||
Active
|
{
|
||||||
</Text>
|
paddingVertical: 3,
|
||||||
</View>
|
paddingHorizontal: 5,
|
||||||
|
backgroundColor: tokens.blueskyPlus.dark,
|
||||||
|
color: tokens.blueskyPlus.light,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{c.title}
|
||||||
|
</Text>
|
||||||
|
|
||||||
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
<Text
|
||||||
<StatusIcon size="sm" fill={t.atoms.text_contrast_low.color} />
|
style={[
|
||||||
<Text style={[a.text_sm]}>{endDate}</Text>
|
a.text_sm,
|
||||||
</View>
|
a.rounded_full,
|
||||||
|
a.font_bold,
|
||||||
|
{
|
||||||
|
paddingVertical: 3,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
borderWidth: sub.renews ? 0 : a.border.borderWidth,
|
||||||
|
borderColor: t.palette.negative_500,
|
||||||
|
backgroundColor: sub.renews
|
||||||
|
? tokens.blueskyPlus.light
|
||||||
|
: t.atoms.bg.backgroundColor,
|
||||||
|
color: sub.renews
|
||||||
|
? tokens.blueskyPlus.dark
|
||||||
|
: t.atoms.text.color,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{sub.renews ? <Trans>Active</Trans> : <Trans>Cancelled</Trans>}
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<Link
|
|
||||||
label={_('Manage subscription')}
|
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||||
size="small"
|
<StatusIcon size="sm" fill={t.atoms.text_contrast_low.color} />
|
||||||
variant="ghost"
|
<Text style={[a.text_sm, a.font_bold]}>{endDate}</Text>
|
||||||
shape="round"
|
</View>
|
||||||
{...createStaticClick(() => {
|
</View>
|
||||||
manageSubscription()
|
|
||||||
})}
|
<Divider />
|
||||||
style={[a.justify_center]}>
|
|
||||||
<ButtonIcon icon={Gear} size="lg" />
|
<View
|
||||||
</Link>
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.justify_between,
|
||||||
|
a.align_center,
|
||||||
|
{paddingTop: 6},
|
||||||
|
]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.justify_between,
|
||||||
|
a.align_center,
|
||||||
|
a.gap_xs,
|
||||||
|
{left: -1},
|
||||||
|
]}>
|
||||||
|
<PlatformIcon size="md" fill={t.atoms.text_contrast_low.color} />
|
||||||
|
<Text
|
||||||
|
style={[a.text_sm, a.font_bold, t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>Managed via web</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{canManage && (
|
||||||
|
<Link
|
||||||
|
label={_('Manage subscription')}
|
||||||
|
size="tiny"
|
||||||
|
variant="solid"
|
||||||
|
color="secondary_inverted"
|
||||||
|
{...createStaticClick(() => {
|
||||||
|
manageSubscription()
|
||||||
|
})}
|
||||||
|
style={[a.justify_center]}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Manage</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export type SubscriptionOffering =
|
|||||||
export type APISubscription = {
|
export type APISubscription = {
|
||||||
group: SubscriptionGroupId
|
group: SubscriptionGroupId
|
||||||
platform: PlatformId
|
platform: PlatformId
|
||||||
|
offering: SubscriptionOfferingId
|
||||||
renews: boolean
|
renews: boolean
|
||||||
periodDtartsAt: string
|
periodDtartsAt: string
|
||||||
periodEndsAt: string
|
periodEndsAt: string
|
||||||
|
|||||||
Reference in New Issue
Block a user