clear last tickets
This commit is contained in:
@@ -45,6 +45,7 @@ const formatCurrency = (amount, currency = "eur") => {
|
||||
|
||||
const FALLBACK_BASE_PRICE_PER_COIN = 12; // ~0,12€ par jeton (valeur indicatif pour l'affichage)
|
||||
const FALLBACK_DISCOUNT_STEPS = [0, 12, 18, 26, 32];
|
||||
const STATIC_DISCOUNTS = [0, 30, 50];
|
||||
|
||||
const computeCoinPackPricing = (packs = []) => {
|
||||
if (!Array.isArray(packs) || !packs.length) {
|
||||
@@ -61,9 +62,7 @@ const computeCoinPackPricing = (packs = []) => {
|
||||
return {
|
||||
...pack,
|
||||
hasValidPrice,
|
||||
pricePerCoin: hasValidPrice
|
||||
? pack.unitAmount / pack.coinAmount
|
||||
: null,
|
||||
pricePerCoin: hasValidPrice ? pack.unitAmount / pack.coinAmount : null,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -146,8 +145,7 @@ const computeCoinPackPricing = (packs = []) => {
|
||||
discountPercent,
|
||||
isBasePack,
|
||||
isBestValue:
|
||||
(bestDiscountPack &&
|
||||
bestDiscountPack.productId === pack.productId) ||
|
||||
(bestDiscountPack && bestDiscountPack.productId === pack.productId) ||
|
||||
(!bestDiscountPack && fallbackBestId === pack.productId),
|
||||
};
|
||||
|
||||
@@ -155,7 +153,13 @@ const computeCoinPackPricing = (packs = []) => {
|
||||
}, {});
|
||||
};
|
||||
|
||||
function CoinPackCard({ pack, selected, pricingDetail, onSelect }) {
|
||||
function CoinPackCard({
|
||||
pack,
|
||||
selected,
|
||||
pricingDetail,
|
||||
onSelect,
|
||||
staticDiscountPercent,
|
||||
}) {
|
||||
const handleSelect = React.useCallback(() => {
|
||||
if (typeof onSelect !== "function" || !pack?.productId) {
|
||||
return;
|
||||
@@ -166,11 +170,20 @@ function CoinPackCard({ pack, selected, pricingDetail, onSelect }) {
|
||||
const formattedPrice = formatCurrency(pack?.unitAmount, pack?.currency);
|
||||
const perCoinPrice = pricingDetail?.formattedPricePerCoin;
|
||||
const discountPercent = pricingDetail?.discountPercent;
|
||||
const discountLabel = pricingDetail?.isBasePack
|
||||
? "Pack de base (référence)"
|
||||
: typeof discountPercent === "number"
|
||||
? `-${discountPercent}% vs pack de base`
|
||||
: null;
|
||||
const hasStaticDiscount = typeof staticDiscountPercent === "number";
|
||||
const effectiveDiscountPercent = hasStaticDiscount
|
||||
? staticDiscountPercent
|
||||
: discountPercent;
|
||||
const isBaseReference = !hasStaticDiscount && pricingDetail?.isBasePack;
|
||||
const discountLabel = hasStaticDiscount
|
||||
? staticDiscountPercent > 0
|
||||
? `-${staticDiscountPercent}%`
|
||||
: null
|
||||
: isBaseReference
|
||||
? "Pack de base (référence)"
|
||||
: typeof discountPercent === "number"
|
||||
? `-${discountPercent}% vs pack de base`
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@@ -184,6 +197,11 @@ function CoinPackCard({ pack, selected, pricingDetail, onSelect }) {
|
||||
accessibilityState={{ selected }}
|
||||
>
|
||||
<BlurView intensity={20} tint="dark" style={styles.cardBlur}>
|
||||
{/*{pricingDetail?.isBestValue ? (*/}
|
||||
{/* <View style={styles.tagBestValue}>*/}
|
||||
{/* <Text style={styles.tagBestValueText}>Meilleure offre</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/*) : null}*/}
|
||||
<View style={styles.cardHeader}>
|
||||
<CreditAmount
|
||||
value={pack?.coinAmount}
|
||||
@@ -191,55 +209,39 @@ function CoinPackCard({ pack, selected, pricingDetail, onSelect }) {
|
||||
textStyle={styles.coinAmount}
|
||||
iconSize={26}
|
||||
/>
|
||||
{pack?.name ? <Text style={styles.packName}>{pack.name}</Text> : null}
|
||||
{pricingDetail?.isBestValue ? (
|
||||
<View style={styles.tagBestValue}>
|
||||
<Text style={styles.tagBestValueText}>Meilleure offre</Text>
|
||||
{discountLabel ? (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
top: -5,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.discountBadge,
|
||||
isBaseReference && styles.discountBadgeBase,
|
||||
]}
|
||||
>
|
||||
<Text style={[styles.discountText]}>{discountLabel}</Text>
|
||||
</View>
|
||||
</View>
|
||||
) : null}
|
||||
{pack?.name ? <Text style={styles.packName}>{pack.name}</Text> : null}
|
||||
</View>
|
||||
<View style={styles.perksList}>
|
||||
<Text style={styles.perkItem}>
|
||||
- Diffusion sur mes plates formes de streaming
|
||||
</Text>
|
||||
<Text style={styles.perkItem}>
|
||||
*Eligible au Hit parade Chanson/Video
|
||||
</Text>
|
||||
</View>
|
||||
{pack?.description ? (
|
||||
<Text style={styles.packDescription}>{pack.description}</Text>
|
||||
) : null}
|
||||
<View style={styles.priceBlock}>
|
||||
{formattedPrice ? (
|
||||
<Text style={styles.packPrice}>{formattedPrice}</Text>
|
||||
) : null}
|
||||
<Text style={styles.pricePerCoin} numberOfLines={1}>
|
||||
{perCoinPrice
|
||||
? `≈ ${perCoinPrice} / jeton`
|
||||
: "Valeurs indicatives / jeton"}
|
||||
</Text>
|
||||
</View>
|
||||
{discountLabel ? (
|
||||
<View style={styles.discountRow}>
|
||||
<View
|
||||
style={[
|
||||
styles.discountBadge,
|
||||
pricingDetail?.isBestValue && styles.discountBadgeBest,
|
||||
pricingDetail?.isBasePack && styles.discountBadgeBase,
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.discountText,
|
||||
pricingDetail?.isBestValue && styles.discountTextBest,
|
||||
]}
|
||||
>
|
||||
{discountLabel}
|
||||
</Text>
|
||||
</View>
|
||||
{!pricingDetail?.isBasePack && typeof discountPercent === "number" ? (
|
||||
<Text style={styles.discountHelper}>
|
||||
Économie estimée vs pack de base
|
||||
</Text>
|
||||
) : (
|
||||
<Text style={styles.discountHelperMuted}>
|
||||
Référence prix/jeton
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
) : null}
|
||||
</BlurView>
|
||||
</Pressable>
|
||||
);
|
||||
@@ -359,13 +361,14 @@ const CoinPackModal = ({ visible, onClose }) => {
|
||||
]}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
{coinPacks.map((pack) => (
|
||||
{coinPacks.map((pack, index) => (
|
||||
<CoinPackCard
|
||||
key={pack.productId}
|
||||
pack={pack}
|
||||
selected={selectedPackId === pack.productId}
|
||||
pricingDetail={packPricingById[pack.productId]}
|
||||
onSelect={setSelectedPackId}
|
||||
staticDiscountPercent={STATIC_DISCOUNTS[index]}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
@@ -564,6 +567,16 @@ const styles = StyleSheet.create({
|
||||
color: "rgba(255, 255, 255, 0.72)",
|
||||
textAlign: "center",
|
||||
},
|
||||
perksList: {
|
||||
gap: 6,
|
||||
alignItems: "center",
|
||||
},
|
||||
perkItem: {
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
fontSize: 13,
|
||||
color: "rgba(255, 255, 255, 0.72)",
|
||||
textAlign: "center",
|
||||
},
|
||||
priceBlock: {
|
||||
gap: 2,
|
||||
alignItems: "center",
|
||||
@@ -580,10 +593,6 @@ const styles = StyleSheet.create({
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
textAlign: "center",
|
||||
},
|
||||
discountRow: {
|
||||
alignItems: "center",
|
||||
gap: 6,
|
||||
},
|
||||
discountBadge: {
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
@@ -626,6 +635,9 @@ const styles = StyleSheet.create({
|
||||
paddingVertical: 4,
|
||||
borderRadius: 10,
|
||||
backgroundColor: Palette.transparentGreen,
|
||||
alignSelf: "center",
|
||||
position: "absolute",
|
||||
top: 10,
|
||||
},
|
||||
tagBestValueText: {
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
|
||||
Reference in New Issue
Block a user