feat: subscription packs
This commit is contained in:
@@ -76,6 +76,9 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
|
||||
typeof plan?.coinsPerMonth === 'number' && Number.isFinite(plan.coinsPerMonth)
|
||||
? Math.round(plan.coinsPerMonth)
|
||||
: null
|
||||
const details = planKey ? PLAN_DETAILS[planKey] : null
|
||||
const isPopular = details?.popular
|
||||
|
||||
const planBadgeKey = planKey
|
||||
const planBadgeSource = planBadgeKey && subBadges[planBadgeKey] ? subBadges[planBadgeKey] : null
|
||||
const handleSelect = React.useCallback(() => {
|
||||
@@ -92,6 +95,7 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
|
||||
selected && styles.cardWrapperSelected,
|
||||
pressed && styles.cardWrapperPressed,
|
||||
plan?.active === false && styles.cardWrapperInactive,
|
||||
isPopular && styles.cardWrapperPopular,
|
||||
]}
|
||||
accessibilityRole="button"
|
||||
accessibilityState={{ selected, disabled: plan?.active === false }}
|
||||
@@ -105,6 +109,7 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
|
||||
<View style={styles.cardHeader}>
|
||||
<View style={styles.titleRow}>
|
||||
<Text style={styles.planName}>{planName}</Text>
|
||||
@@ -127,7 +132,10 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
|
||||
{intervalLabel ? <Text style={styles.period}>{intervalLabel}</Text> : null}
|
||||
</View>
|
||||
) : null}
|
||||
{coinsPerMonth !== null ? (
|
||||
|
||||
{details?.creditsLabel ? (
|
||||
<Text style={styles.coinsPromoText}>{details.creditsLabel}</Text>
|
||||
) : coinsPerMonth !== null ? (
|
||||
<View style={styles.coinsPerMonthRow}>
|
||||
<CreditAmount
|
||||
value={coinsPerMonth}
|
||||
@@ -143,9 +151,33 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
|
||||
) : null}
|
||||
|
||||
<View style={styles.cardBenefits}>
|
||||
<Text style={styles.cardBenefitsItem}>• Eligible au concours mensuel chanson/Vidéo</Text>
|
||||
<Text style={styles.cardBenefitsItem}>• Crédits gratuits tous les mois</Text>
|
||||
<Text style={styles.benefitsTitle}>Privilège Membre :</Text>
|
||||
{details?.privileges?.map((item, index) => (
|
||||
<View key={index} style={styles.benefitBlock}>
|
||||
<Text style={[styles.benefitText, item.bold && styles.benefitTextBold]}>
|
||||
{item.bold ? `• ${item.text}` : item.text}
|
||||
</Text>
|
||||
{item.subItems ? (
|
||||
<View style={styles.benefitSubList}>
|
||||
<Text style={styles.benefitSubText}>{item.subItems.join(' - ')}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
)) || (
|
||||
<>
|
||||
<Text style={styles.cardBenefitsItem}>
|
||||
• Eligible au concours mensuel chanson/Vidéo
|
||||
</Text>
|
||||
<Text style={styles.cardBenefitsItem}>• Crédits gratuits tous les mois</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{isPopular ? (
|
||||
<View style={styles.popularBadge}>
|
||||
<Text style={styles.popularBadgeText}>Le plus populaire !</Text>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
</BlurView>
|
||||
{isAnnual ? (
|
||||
@@ -208,6 +240,36 @@ const PLAN_DISPLAY_NAME_BY_KEY = {
|
||||
premium: 'Play Backer Gold',
|
||||
}
|
||||
|
||||
const PLAN_DETAILS = {
|
||||
starter: {
|
||||
creditsLabel: '50 Crédits / Mois',
|
||||
popular: false,
|
||||
privileges: [
|
||||
{ text: 'Eligible au concours mensuel chanson/Vidéo', bold: true },
|
||||
{ text: 'Catégorie Chanson :', subItems: ['Top 1: 500 €', 'Top 2: 250 €', 'Top 3: 125 €'] },
|
||||
{ text: 'Catégorie Vidéo :', subItems: ['Top 1: 1000 €', 'Top 2: 500 €', 'Top 3: 250 €'] },
|
||||
],
|
||||
},
|
||||
pro: {
|
||||
creditsLabel: '100 crédits + 50 offerts / Mois',
|
||||
popular: true,
|
||||
privileges: [
|
||||
{ text: 'Eligible au concours mensuel chanson/Vidéo', bold: true },
|
||||
{ text: 'Catégorie Chanson :', subItems: ['Top 1: 500 €', 'Top 2: 250 €', 'Top 3: 125 €'] },
|
||||
{ text: 'Catégorie Vidéo :', subItems: ['Top 1: 1000 €', 'Top 2: 500 €', 'Top 3: 250 €'] },
|
||||
],
|
||||
},
|
||||
premium: {
|
||||
creditsLabel: '150 Crédits + 100 offerts / Mois',
|
||||
popular: false,
|
||||
privileges: [
|
||||
{ text: 'Eligible au concours mensuel chanson/Vidéo', bold: true },
|
||||
{ text: 'Catégorie Chanson :', subItems: ['Top 1: 500 €', 'Top 2: 250 €', 'Top 3: 125 €'] },
|
||||
{ text: 'Catégorie Vidéo :', subItems: ['Top 1: 1000 €', 'Top 2: 500 €', 'Top 3: 250 €'] },
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const getPlanKeyForBadge = (plan) => {
|
||||
if (!plan || typeof plan !== 'object') {
|
||||
return null
|
||||
@@ -621,7 +683,7 @@ export default function Subscriptions() {
|
||||
<Page
|
||||
headerType="NAVIGATE"
|
||||
title="Abonnements"
|
||||
scrollEnabled={false}
|
||||
scrollEnabled={isWeb}
|
||||
width={isWeb ? 960 : undefined}
|
||||
containerStyle={styles.page}
|
||||
contentContainerStyle={[styles.pageContent, isMobile && styles.pageContentMobile]}
|
||||
@@ -821,14 +883,47 @@ const styles = StyleSheet.create({
|
||||
marginTop: 12,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: 'rgba(255, 255, 255, 0.1)',
|
||||
paddingTop: 8,
|
||||
gap: 4,
|
||||
paddingTop: 12,
|
||||
gap: 6,
|
||||
},
|
||||
cardBenefitsItem: {
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
fontSize: 12,
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
},
|
||||
benefitsTitle: {
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
fontSize: 13,
|
||||
color: Palette.white,
|
||||
marginBottom: 2,
|
||||
},
|
||||
benefitBlock: {
|
||||
marginBottom: 4,
|
||||
},
|
||||
benefitText: {
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
fontSize: 13,
|
||||
color: 'rgba(255, 255, 255, 0.85)',
|
||||
},
|
||||
benefitTextBold: {
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
color: Palette.white,
|
||||
},
|
||||
benefitSubList: {
|
||||
marginTop: 2,
|
||||
paddingLeft: 0,
|
||||
},
|
||||
benefitSubText: {
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
fontSize: 12,
|
||||
color: 'rgba(255, 255, 255, 0.65)',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
coinsPromoText: {
|
||||
fontFamily: FONT_FAMILY.InterBold,
|
||||
fontSize: 15,
|
||||
color: Palette.primary,
|
||||
},
|
||||
balanceContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
@@ -1032,6 +1127,10 @@ const styles = StyleSheet.create({
|
||||
shadowRadius: 20,
|
||||
elevation: 8,
|
||||
},
|
||||
cardWrapperPopular: {
|
||||
borderColor: Palette.primary, // Highlight border for popular
|
||||
backgroundColor: 'rgba(112, 35, 247, 0.1)', // Slight tint
|
||||
},
|
||||
cardWrapperPressed: {
|
||||
transform: [{ scale: 0.98 }],
|
||||
},
|
||||
@@ -1123,6 +1222,20 @@ const styles = StyleSheet.create({
|
||||
color: Palette.primary,
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
popularBadge: {
|
||||
alignSelf: 'center',
|
||||
marginTop: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 999,
|
||||
backgroundColor: Palette.primary,
|
||||
},
|
||||
popularBadgeText: {
|
||||
fontFamily: FONT_FAMILY.InterBold,
|
||||
fontSize: 11,
|
||||
color: Palette.white,
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
inlineLoader: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user