diff --git a/src/TODO.md b/src/TODO.md
new file mode 100644
index 00000000000..7382675c319
--- /dev/null
+++ b/src/TODO.md
@@ -0,0 +1,44 @@
+# TODO
+
+## Links
+
+- [PC-TicketNumber](https://passculture.atlassian.net/browse/PC-TicketNumber)
+- [MobTime](https://mobtime.hadrienmp.fr/mob/pass-culture)
+
+---
+
+## Tasks
+
+- [ ] CAS 0 : Utilisation de `formatToFrenchDecimal()`
+ - [ ] Modifier `formatToFrenchDecimal()` pour qu'il fasse la conversion en XPF
+
+
+- [ ] CAS 1 : Prix en dur dans le code :
+ - [ ] 1.1 : Crédits par âges
+ - [ ] Utiliser `useDepositAmountsByAge()` lorsque le crédit est marqué en dur car il utilise directement `formatToFrenchDecimal()`:
+ - [ ] `300\u00a0€`
+ - [ ] `30\u00a0€`
+ - [ ] `20\u00a0€`
+ - [ ] 1.2 : Crédit par seuil comme la part pour les offres numériques (plus tard le spectacle vivant)
+ - [ ] Utiliser `formatToFrenchDecimal(NUMERIC_AMOUNT)`
+ - [ ] Créer une constante la part du crédit pour les offres numériques. ex: const NUMERIC_AMOUNT = 10.000.
+
+
+- [ ] CAS 2 : Utilisation de `useMaxPrice()` (ex `${maxPrice}\u00a0€ ...`)
+ - [ ] Utiliser des centimes plutôt que des euros dans `useMaxPrice()` ?
+
+
+- [ ] CAS 3 : Utilisation de `getDisplayPrice()` (ex: `dès 15,60\u00a0€` (tableau de prix))
+
+
+- [ ] CAS 4 : Utilisation de `formatPriceInEuroToDisplayPrice()`
+
+
+- [ ] CAS 5 : Mention de "€" (ex: `en €`)
+ - [ ] Créer une fonction qui ne gère pas les crédits mais juste les devises
+
+---
+
+## Tasks for another US
+
+- [ ]
\ No newline at end of file
diff --git a/src/features/birthdayNotifications/pages/EighteenBirthday.tsx b/src/features/birthdayNotifications/pages/EighteenBirthday.tsx
index 6a86e8c1a5d..4e12ba9ef8f 100644
--- a/src/features/birthdayNotifications/pages/EighteenBirthday.tsx
+++ b/src/features/birthdayNotifications/pages/EighteenBirthday.tsx
@@ -12,16 +12,18 @@ import { ClockFilled } from 'ui/svg/icons/ClockFilled'
import { Spacer } from 'ui/theme'
import { CaptionNeutralInfo, Typo } from 'ui/theme/typography'
import { getHeadingAttrs } from 'ui/theme/typographyAttrs/getHeadingAttrs'
+import { formatToFrenchDecimal } from 'libs/parsers/getDisplayPrice'
+import { useDepositAmountsByAge } from 'shared/user/useDepositAmountsByAge'
const getPageWording = (userRequiresIdCheck?: boolean) => {
if (userRequiresIdCheck) {
return {
- text: 'Vérifie ton identité pour débloquer tes 300\u00a0€.',
+ text: `Vérifie ton identité pour débloquer tes ${useDepositAmountsByAge().eighteenYearsOldDeposit}.`,
buttonText: 'Vérifier mon identité',
}
}
return {
- text: 'Confirme tes informations personnelles pour débloquer tes 300\u00a0€.',
+ text: `Confirme tes informations personnelles pour débloquer tes ${useDepositAmountsByAge().eighteenYearsOldDeposit}.`,
buttonText: 'Confirmer mes informations',
}
}
@@ -39,7 +41,7 @@ export function EighteenBirthday() {
{pageWording.text}
- Ton crédit précédent a été remis à 0 €.
+ Ton crédit précédent a été remis à {formatToFrenchDecimal(0)}.
{
+ const { selectedPlace } = useLocation()
+ const isNewCaledonianLocation = selectedPlace?.info === 'Nouvelle-Calédonie'
+
+ return isNewCaledonianLocation ? MAX_PRICE * EURO_TO_XPF_RATE : MAX_PRICE
+}
diff --git a/src/features/search/helpers/useMaxPrice/useMaxPrice.ts b/src/features/search/helpers/useMaxPrice/useMaxPrice.ts
index 90c05d80ba5..9e3ce13994a 100644
--- a/src/features/search/helpers/useMaxPrice/useMaxPrice.ts
+++ b/src/features/search/helpers/useMaxPrice/useMaxPrice.ts
@@ -1,16 +1,17 @@
import { useAuthContext } from 'features/auth/context/AuthContext'
import { isUserExBeneficiary } from 'features/profile/helpers/isUserExBeneficiary'
-import { MAX_PRICE } from 'features/search/helpers/reducer.helpers'
+import { useGetMaxPrice } from 'features/search/helpers/useMaxPrice/useGetMaxPrice'
import { convertCentsToEuros } from 'libs/parsers/pricesConversion'
export const useMaxPrice = (): number => {
+ const maxPrice = useGetMaxPrice()
const { user } = useAuthContext()
const initialCredit = user?.domainsCredit?.all.initial
- if (!user || !initialCredit) return MAX_PRICE
+ if (!user || !initialCredit) return maxPrice
- if (isUserExBeneficiary(user) || initialCredit === 0) return MAX_PRICE
+ if (isUserExBeneficiary(user) || initialCredit === 0) return maxPrice
return convertCentsToEuros(initialCredit)
}
diff --git a/src/features/search/pages/modals/PriceModal/PriceModal.tsx b/src/features/search/pages/modals/PriceModal/PriceModal.tsx
index 8a3b5528068..789432c624c 100644
--- a/src/features/search/pages/modals/PriceModal/PriceModal.tsx
+++ b/src/features/search/pages/modals/PriceModal/PriceModal.tsx
@@ -11,7 +11,6 @@ import { SearchCustomModalHeader } from 'features/search/components/SearchCustom
import { SearchFixedModalBottom } from 'features/search/components/SearchFixedModalBottom'
import { useSearch } from 'features/search/context/SearchWrapper'
import { FilterBehaviour } from 'features/search/enums'
-import { MAX_PRICE } from 'features/search/helpers/reducer.helpers'
import { makeSearchPriceSchema } from 'features/search/helpers/schema/makeSearchPriceSchema/makeSearchPriceSchema'
import { SearchState } from 'features/search/types'
import { formatToFrenchDecimal } from 'libs/parsers/getDisplayPrice'
@@ -26,6 +25,8 @@ import { Separator } from 'ui/components/Separator'
import { Close } from 'ui/svg/icons/Close'
import { Error } from 'ui/svg/icons/Error'
import { getSpacing, Spacer } from 'ui/theme'
+import { useGetMaxPrice } from 'features/search/helpers/useMaxPrice/useGetMaxPrice'
+import { useCurrencyToDisplay } from 'features/search/pages/modals/PriceModal/useCurrencyToDisplay'
type PriceModalFormData = {
minPrice: string
@@ -55,6 +56,8 @@ export const PriceModal: FunctionComponent = ({
filterBehaviour,
onClose,
}) => {
+ const currency = useCurrencyToDisplay()
+ const MAX_PRICE = useGetMaxPrice()
const { searchState, dispatch } = useSearch()
const { isLoggedIn, user } = useAuthContext()
const availableCredit = useAvailableCredit()
@@ -301,7 +304,7 @@ export const PriceModal: FunctionComponent = ({
autoCapitalize="none"
isError={error && value.length > 0}
keyboardType="numeric"
- label="Prix minimum (en €)"
+ label={`Prix minimum (en\u00a0${currency})`}
value={value}
onChangeText={onChange}
onBlur={onBlur}
@@ -331,7 +334,7 @@ export const PriceModal: FunctionComponent = ({
autoCapitalize="none"
isError={error && value.length > 0}
keyboardType="numeric"
- label="Prix maximum (en €)"
+ label={`Prix maximum (en\u00a0${currency})`}
value={value}
onChangeText={(value) => {
onChange(value)
@@ -341,7 +344,7 @@ export const PriceModal: FunctionComponent = ({
textContentType="none" // disable autofill on iOS
accessibilityDescribedBy={maxPriceInputId}
testID="Entrée pour le prix maximum"
- rightLabel={`max\u00a0: ${formatInitialCredit}\u00a0€`}
+ rightLabel={`max\u00a0: ${formatInitialCredit}\u00a0${currency}`}
placeholder={`${formatInitialCredit}`}
disabled={getValues('isLimitCreditSearch') || getValues('isOnlyFreeOffersSearch')}
/>
diff --git a/src/features/search/pages/modals/PriceModal/useCurrencyToDisplay.ts b/src/features/search/pages/modals/PriceModal/useCurrencyToDisplay.ts
new file mode 100644
index 00000000000..9f69a43beab
--- /dev/null
+++ b/src/features/search/pages/modals/PriceModal/useCurrencyToDisplay.ts
@@ -0,0 +1,8 @@
+import { useLocation } from 'libs/location'
+
+export const useCurrencyToDisplay = () => {
+ const { selectedPlace } = useLocation()
+ const isNewCaledonianLocation = selectedPlace?.info === 'Nouvelle-Calédonie'
+
+ return isNewCaledonianLocation ? 'CSP' : '€'
+}
diff --git a/src/features/tutorial/components/profileTutorial/EighteenBlockDescription.tsx b/src/features/tutorial/components/profileTutorial/EighteenBlockDescription.tsx
index 44e888fd9ca..309c600fdf2 100644
--- a/src/features/tutorial/components/profileTutorial/EighteenBlockDescription.tsx
+++ b/src/features/tutorial/components/profileTutorial/EighteenBlockDescription.tsx
@@ -10,11 +10,14 @@ import { BicolorNumeric } from 'ui/svg/icons/bicolor/Numeric'
import { BicolorClock } from 'ui/svg/icons/BicolorClock'
import { BicolorLock } from 'ui/svg/icons/BicolorLock'
import { Spacer, Typo } from 'ui/theme'
+import { formatToFrenchDecimal } from 'libs/parsers/getDisplayPrice'
type Props = {
ongoingCredit?: boolean
}
+const NUMERIC_AMOUNT = 10000
+
export const EighteenBlockDescription: FunctionComponent = ({ ongoingCredit = false }) => {
const { isLoggedIn, user } = useAuthContext()
@@ -32,7 +35,7 @@ export const EighteenBlockDescription: FunctionComponent = ({ ongoingCred
}
- text="La limite de 100 € est là pour t’encourager à tester des offres culturelles variées."
+ text={`La limite de ${formatToFrenchDecimal(NUMERIC_AMOUNT)} est là pour t’encourager à tester des offres culturelles variées.`}
/>,
]
const items =
@@ -43,7 +46,7 @@ export const EighteenBlockDescription: FunctionComponent = ({ ongoingCred
- dont 100 € en offres numériques (streaming, presse en ligne, …)
+ {`dont ${formatToFrenchDecimal(NUMERIC_AMOUNT)} en offres numériques (streaming, presse en ligne, …)`}
} items={items} />
diff --git a/src/libs/parsers/getDisplayPrice.ts b/src/libs/parsers/getDisplayPrice.ts
index a64ac8b2f12..88f27a8ae37 100644
--- a/src/libs/parsers/getDisplayPrice.ts
+++ b/src/libs/parsers/getDisplayPrice.ts
@@ -1,25 +1,42 @@
-import { CENTS_IN_EURO, convertEuroToCents } from 'libs/parsers/pricesConversion'
+import { CENTS_IN_EURO, EURO_TO_XPF_RATE, convertEuroToCents } from 'libs/parsers/pricesConversion'
type FormatPriceOptions = {
fractionDigits?: number
}
/**
- * Takes a price in cents (ex: 5.5€ = 550 cents) and returns a string with the
- * price in euros in the French format, ex: "5,50 €"
- * @param {number} priceInCents
+ * Takes a price in cents (for EUR) and returns a string with the
+ * price in the appropriate format, ex: "5,50 €" or "11933 XPF"
+ * based on the value of isNewCaledonianLocation
+ * @param {number} priceInCents - price in euros (in cents)
*/
+
export const formatToFrenchDecimal = (priceInCents: number, options?: FormatPriceOptions) => {
- const euros = priceInCents / CENTS_IN_EURO
- const fractionDigits = options?.fractionDigits ?? (euros === Math.floor(euros) ? 0 : 2)
+ const isNewCaledonianLocation = true
+ // const { selectedPlace } = useLocation()
+ // const isNewCaledonianLocation = selectedPlace?.info === 'Nouvelle-Calédonie'
+
+ const priceInEuros = priceInCents / CENTS_IN_EURO
+ let price: number
+ let unit: string
+ let fractionDigits: number
+
+ if (isNewCaledonianLocation) {
+ price = priceInEuros * EURO_TO_XPF_RATE
+ unit = 'CFP'
+ fractionDigits = 0
+ } else {
+ price = priceInEuros
+ unit = '€'
+ fractionDigits = options?.fractionDigits ?? (price === Math.floor(price) ? 0 : 2)
+ }
const formatter = new Intl.NumberFormat('fr-FR', {
- style: 'currency',
- currency: 'EUR',
minimumFractionDigits: fractionDigits,
+ maximumFractionDigits: fractionDigits,
})
- return formatter.format(euros)
+ return `${formatter.format(price)}\u00A0${unit}`
}
export const formatPriceInEuroToDisplayPrice = (priceInEuro: number) =>
diff --git a/src/libs/parsers/pricesConversion.ts b/src/libs/parsers/pricesConversion.ts
index f018444fcfe..ea3b72afe8d 100644
--- a/src/libs/parsers/pricesConversion.ts
+++ b/src/libs/parsers/pricesConversion.ts
@@ -1,4 +1,5 @@
export const CENTS_IN_EURO = 100
+export const EURO_TO_XPF_RATE = 119.48
export const convertEuroToCents = (p: number): number => {
return Math.floor(Number((p * CENTS_IN_EURO).toFixed(2)))