diff --git a/src/screens/HitParade/components/SongCard.js b/src/screens/HitParade/components/SongCard.js
index 797a6e7..0e2ffdd 100644
--- a/src/screens/HitParade/components/SongCard.js
+++ b/src/screens/HitParade/components/SongCard.js
@@ -49,9 +49,9 @@ const SongCard = ({
...Style.containerRow,
}}
tint="dark"
- // experimentalBlurMethod={
- // Platform.OS !== "ios" ? "dimezisBlurView" : "none"
- // }
+ // experimentalBlurMethod={
+ // Platform.OS !== "ios" ? "dimezisBlurView" : "none"
+ // }
>
{
if (typeof amount !== 'number') {
@@ -139,6 +141,11 @@ function SubscriptionCard({ plan, selected, onSelect, isAnnual }) {
) : null}
) : null}
+
+
+ • Eligible au concours mensuel chanson/Vidéo
+ • Crédits gratuits tous les mois
+
{isAnnual ? (
@@ -278,7 +285,15 @@ export default function Subscriptions() {
const initialSubscriptionPack = initialPack && initialPack !== 'packs' ? initialPack : null
- const { subscriptions, isCatalogLoading, catalogError, createSubscriptionCheckout } = useStripe()
+ const {
+ subscriptions,
+ coinPacks,
+ isCatalogLoading,
+ catalogError,
+ createSubscriptionCheckout,
+ createCoinPackCheckout,
+ } = useStripe()
+ const { currentUserData } = useUserData()
const [selectedPeriodKey, setSelectedPeriodKey] = React.useState('annual')
const [selectedPriceId, setSelectedPriceId] = React.useState(null)
const [processingPriceId, setProcessingPriceId] = React.useState(null)
@@ -315,6 +330,7 @@ export default function Subscriptions() {
)
if (!periodEntries.length) {
+ // Don't reset selectedPeriodKey here so it behaves more stably
setSelectedPriceId(null)
return
}
@@ -323,10 +339,11 @@ export default function Subscriptions() {
let matchedPriceId = null
let matchedPeriodKey = selectedPeriodKey
- let nextPeriodKey =
- periodEntries.find(([periodKey]) => periodKey === selectedPeriodKey)?.[0] ||
- periodEntries[0]?.[0] ||
- 'annual'
+ let nextPeriodKey = selectedPeriodKey
+ // Only force switch if current selected period is empty and another is not
+ if ((normalizedPlansByPeriod[selectedPeriodKey]?.length || 0) === 0) {
+ nextPeriodKey = periodEntries[0]?.[0] || 'annual'
+ }
if (shouldApplyPack) {
const desired = initialSubscriptionPack.trim().toLowerCase()
@@ -447,17 +464,35 @@ export default function Subscriptions() {
[selectedPeriodKey]
)
+ const handleBuyCredits = React.useCallback(
+ async (pack) => {
+ const targetId = pack?.productId
+ if (!targetId) return
+ setProcessingPriceId(targetId)
+ setErrorMessage(null)
+ try {
+ await createCoinPackCheckout(targetId)
+ } catch (error) {
+ console.error('[Subscriptions] coin checkout error', error)
+ setErrorMessage(
+ error?.message ||
+ 'Une erreur est survenue lors de la création de la session Stripe pour les crédits.'
+ )
+ } finally {
+ setProcessingPriceId(null)
+ }
+ },
+ [createCoinPackCheckout]
+ )
+
const renderHeaderSection = React.useCallback(() => {
return (
<>
Rejoignez le club MusicLand
-
- Privilège Membre :
-
- - Eligible au concours mensuel chanson/Vidéo
- - Crédits gratuits tous les mois
-
+
+ Votre solde actuel :
+
{combinedErrorMessage ? {combinedErrorMessage} : null}
@@ -639,6 +674,45 @@ export default function Subscriptions() {
))}
+ {coinPacks && coinPacks.length > 0 ? (
+
+ Recharger vos crédits
+
+ {coinPacks.map((pack) => {
+ // Attempt to find amount in commonly used Stripe fields
+ const rawAmount = pack.unitAmount ?? pack.amount ?? pack.price ?? 0
+ const price = formatCurrency(rawAmount, pack.currency)
+ // Assuming pack structure: { id, name, unitAmount/amount, currency, metadata: { coins: 100 } }
+ const coins = Number(pack.metadata?.coins || 0)
+ return (
+
+
+ {pack.name}
+
+
+ handleBuyCredits(pack)}
+ disabled={Boolean(processingPriceId)}
+ style={styles.creditButton}
+ textStyle={styles.creditButtonText}
+ gradientStyle={{ paddingVertical: 8, paddingHorizontal: 16 }}
+ />
+
+ )
+ })}
+
+
+ ) : null}
+
{isLoadingPlans && currentPlanCount > 0 ? (
@@ -742,11 +816,79 @@ const styles = StyleSheet.create({
benefitsList: {
gap: 2,
},
- benefitsItem: {
+
+ cardBenefits: {
+ marginTop: 12,
+ borderTopWidth: 1,
+ borderTopColor: 'rgba(255, 255, 255, 0.1)',
+ paddingTop: 8,
+ gap: 4,
+ },
+ cardBenefitsItem: {
fontFamily: FONT_FAMILY.InterMedium,
- fontSize: 13,
- color: 'rgba(255, 255, 255, 0.85)',
+ fontSize: 12,
+ color: 'rgba(255, 255, 255, 0.7)',
+ },
+ balanceContainer: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
+ paddingHorizontal: 16,
+ paddingVertical: 8,
+ borderRadius: 20,
+ gap: 10,
+ marginTop: 8,
+ },
+ balanceLabel: {
+ fontFamily: FONT_FAMILY.InterMedium,
+ fontSize: 14,
+ color: Palette.white,
+ },
+ creditsSection: {
+ width: '100%',
+ marginTop: 40,
+ gap: 16,
+ alignItems: 'center',
+ },
+ sectionTitle: {
+ fontFamily: FONT_FAMILY.InterBold,
+ fontSize: 20,
+ color: Palette.white,
+ },
+ creditsGrid: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ gap: 16,
+ justifyContent: 'center',
+ },
+ creditCard: {
+ backgroundColor: 'rgba(255, 255, 255, 0.05)',
+ borderRadius: 16,
+ padding: 16,
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ width: isWeb ? 200 : '45%',
+ gap: 12,
+ borderWidth: 1,
+ borderColor: 'rgba(255, 255, 255, 0.1)',
+ },
+ creditName: {
+ fontFamily: FONT_FAMILY.InterSemiBold,
+ fontSize: 14,
+ color: Palette.white,
textAlign: 'center',
+ marginBottom: 4,
+ },
+ creditAmountText: {
+ fontSize: 20,
+ },
+ creditButton: {
+ width: '100%',
+ height: 36,
+ minHeight: 36,
+ },
+ creditButtonText: {
+ fontSize: 13,
},
webBackContainer: {
alignSelf: 'flex-start',