clear last tickets

This commit is contained in:
Thomas Demirdjian
2025-11-25 14:58:06 +01:00
parent 72852ad92b
commit ee9cc5dccd
31 changed files with 1009 additions and 531 deletions
+12 -5
View File
@@ -375,10 +375,17 @@ const ManageSubscription = ({ navigation }) => {
typeof coinsPerMonth === "number" && Number.isFinite(coinsPerMonth)
? Math.round(coinsPerMonth)
: null;
const grantStrategy =
typeof currentUserData?.subscriptionGrantStrategy === "string"
? currentUserData.subscriptionGrantStrategy
: null;
const isUpfrontGrant = grantStrategy === "upfront";
const nextGrantTimestamp =
currentUserData?.subscriptionNextGrantAt ||
currentUserData?.subscriptionGrantNextAt ||
null;
isUpfrontGrant
? null
: currentUserData?.subscriptionNextGrantAt ||
currentUserData?.subscriptionGrantNextAt ||
null;
const nextGrantRawDate = toDate(nextGrantTimestamp);
const now = new Date();
@@ -390,7 +397,7 @@ const ManageSubscription = ({ navigation }) => {
: null;
const fallbackInitialGrant =
isAnnual && createdAtDate
!isUpfrontGrant && isAnnual && createdAtDate
? computeFirstAnnualGrantFromCreation(createdAtDate)
: null;
const futureFallbackGrant =
@@ -409,7 +416,7 @@ const ManageSubscription = ({ navigation }) => {
}
const nextGrantLabel =
resolvedNextGrantDate && isAnnual
resolvedNextGrantDate && isAnnual && !isUpfrontGrant
? formatDate(resolvedNextGrantDate)
: null;
+82 -30
View File
@@ -19,8 +19,10 @@ import { useGlobal } from "reactn";
import { background, icons } from "../../assets";
import BorderGradient from "../../components/BorderGradient/BorderGradient";
import MoreMenu from "../../components/MoreMenu";
import MobileCoinBadge from "../../components/MobileCoinBadge";
import PressableScale from "../../components/PressableScale";
import ProfilePicture from "../../components/ProfilePicture";
import ShareBtn from "../../components/ShareBtn/ShareBtn";
import firebase, {
projectsRef,
serverTimestamp,
@@ -33,7 +35,7 @@ import useLayoutType from "../../hooks/useLayoutType";
import useNavigateToMusicDetails from "../../hooks/useNavigateToMusicDetails";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { navigate, push } from "../../navigation/NavigationService";
import { navigate, push, goBack } from "../../navigation/NavigationService";
import { useUser } from "../../providers/UserDataProvider";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
@@ -69,15 +71,15 @@ const Profile = () => {
const [webUploadMessage, setWebUploadMessage] = useState("");
const selfDisplayName = useMemo(
() => getArtistDisplayName(currentUserData, "MusicLand"),
[currentUserData]
[currentUserData],
);
const targetDisplayName = useMemo(
() => getArtistDisplayName(userData, "MusicLand"),
[userData]
[userData],
);
const profileTitle = useMemo(
() => getArtistDisplayName(isSelf ? currentUserData : userData, "Profil"),
[currentUserData, isSelf, userData]
[currentUserData, isSelf, userData],
);
const navigateToMusicDetails = useNavigateToMusicDetails();
const onPressMenu = (item) => {
@@ -96,7 +98,7 @@ const Profile = () => {
setFollowers(
Array.isArray(currentUserData?.followedBy)
? currentUserData.followedBy.length
: 0
: 0,
);
return;
}
@@ -175,7 +177,7 @@ const Profile = () => {
profilePictureURL: resultURI,
updatedAt: serverTimestamp(),
},
{ merge: true }
{ merge: true },
);
const authUser = firebase.auth().currentUser;
@@ -237,7 +239,8 @@ const Profile = () => {
setSelectedProjectId(item.id);
setMenuPosition(posTop);
setShowMenu(
(prev) => !prev || posTop?.top !== (menuPosition?.top ?? null)
(prev) =>
!prev || posTop?.top !== (menuPosition?.top ?? null),
);
}}
/>
@@ -329,26 +332,43 @@ const Profile = () => {
const displayedPlaybacks = Array.isArray(displayedPlaybacksSource)
? displayedPlaybacksSource.filter((project) => project?.playbackUrl)
: [];
const showHeader = isWeb;
const showBackButton = !params?.noBack && !isWeb;
return (
<Page
backgroundImg={isWeb ? background.profileWebBG : background.profileWebBG}
headerType="NAVIGATE"
headerType={showHeader ? "NAVIGATE" : "NONE"}
hideBackButton={params?.noBack}
contentContainerStyle={{
paddingBottom: gutters * 2,
}}
containerStyle={{
backgroundColor: isWeb ? "transparent" : "#0000004D",
paddingTop: showHeader ? undefined : 0,
}}
rightComponent={() =>
!isWeb && isSelf ? (
<PressableScale onPress={handleOpenSettings}>
<Feather name="settings" size={24} color={Palette.white} />
</PressableScale>
) : null
}
>
{!isWeb ? (
<View style={styles.mobileTopRow}>
<View style={styles.mobileTopLeft}>
{showBackButton ? (
<Pressable
onPress={goBack}
hitSlop={16}
style={styles.backButton}
>
<Image
source={icons.chevronDown}
style={styles.backIcon}
resizeMode="contain"
/>
</Pressable>
) : null}
<MobileCoinBadge />
</View>
<ShareBtn label="Partager" style={styles.mobileShareButton} />
</View>
) : null}
<View style={{ flex: 1, marginTop: responsiveHeight(2), gap: 20 }}>
<View style={{ borderRadius: 20, overflow: "hidden" }}>
<BlurView
@@ -362,21 +382,16 @@ const Profile = () => {
// Platform.OS !== "ios" ? "dimezisBlurView" : "none"
// }
>
{isWeb && isSelf && (
<PressableScale
style={{
zIndex: 2,
position: "absolute",
right: 10,
top: 10,
}}
onPress={handleOpenSettings}
>
<Feather name="settings" size={24} color={Palette.white} />
</PressableScale>
)}
<View style={{ alignItems: "center" }}>
{isSelf && (
<PressableScale
onPress={handleOpenSettings}
hitSlop={10}
style={styles.settingsButton}
>
<Feather name="settings" size={20} color={Palette.white} />
</PressableScale>
)}
<View style={styles.avatarWrapper}>
<ProfilePicture
uri={
@@ -392,7 +407,7 @@ const Profile = () => {
style={styles.editAvatarButton}
onPress={() =>
onChangeProfilePicture(
loaderMessages.profilePhotoUploadWeb
loaderMessages.profilePhotoUploadWeb,
)
}
disabled={updatingPhoto}
@@ -567,6 +582,30 @@ const Profile = () => {
export default Profile;
const styles = StyleSheet.create({
mobileTopRow: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 8,
},
mobileTopLeft: {
flexDirection: "row",
alignItems: "center",
gap: 10,
flexShrink: 1,
},
mobileShareButton: {
flexShrink: 0,
},
backButton: {
paddingVertical: 6,
paddingRight: 2,
},
backIcon: {
...Style.iconSmall,
...Style.mirrorHorizontal,
transform: [{ rotate: "90deg" }],
},
value: {
fontSize: 16,
color: Palette.white,
@@ -609,6 +648,19 @@ const styles = StyleSheet.create({
alignItems: "center",
justifyContent: "center",
},
settingsButton: {
position: "absolute",
top: -6,
right: -6,
width: 36,
height: 36,
borderRadius: 18,
backgroundColor: Palette.transparentBlack,
borderWidth: 1,
borderColor: Palette.white,
zIndex: 2,
...Style.containerCenter,
},
editAvatarButton: {
position: "absolute",
bottom: 4,
@@ -16,39 +16,32 @@ const ICON_BASE_ACCENT = "#A96BFF";
const CLUB_ADVANTAGES = [
{
title: "Revenus partagés",
description: "Gagne sur tes écoutes et ta popularité.",
iconType: "vector",
iconName: "currency-usd",
accent: "#F8C24D",
},
{
title: "Concours hit du mois",
description: "Vise le podium du mois et empoche la récompense.",
iconType: "vector",
iconName: "chart-line",
accent: "#7AE0FF",
},
{
title: "Crédits mensuels",
title: "Gagne des crédits avec ton abonnement",
description: "Des crédits premium tous les mois pour créer plus.",
iconType: "image",
icon: icons.coin,
accent: ICON_BASE_ACCENT,
},
{
title: "Gagne le double de cashprice grace à ton adésion au club",
description: "Cashprice doublé pour les membres du Club Musicland.",
iconType: "vector",
iconName: "chart-line",
accent: "#F8C24D",
},
];
const ClubAdvantagesCard = ({ style, isDev = false }) => {
const navigation = useNavigation();
const { hasActiveSubscription } = useUserData() || {};
const [useWebLayout, setUseWebLayout] = React.useState(isWeb);
const [useWebLayout, setUseWebLayout] = React.useState(isDev ? isWeb : false);
const advantages = CLUB_ADVANTAGES;
React.useEffect(() => {
if (!isDev) {
setUseWebLayout(isWeb);
setUseWebLayout(false);
}
}, [isDev, isWeb]);
}, [isDev]);
const title = hasActiveSubscription
? "Tu profites déjà du Club Musicland"