feat(billing): refacto billing (#14243)

… prices for metered billing

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Antoine Moreaux
2025-09-19 11:25:53 +02:00
committed by GitHub
parent 163890f6c8
commit 43e0cd5d05
351 changed files with 16091 additions and 6101 deletions
@@ -1,5 +1,6 @@
import { useTheme } from '@emotion/react';
import { useNumberFormat } from '@/localization/hooks/useNumberFormat';
import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition';
import {
type FieldCurrencyMetadata,
@@ -9,7 +10,6 @@ import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/S
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { isDefined } from 'twenty-shared/utils';
import { formatToShortNumber } from '~/utils/format/formatToShortNumber';
import { formatNumber } from '~/utils/format/formatNumber';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
type CurrencyDisplayProps = {
@@ -34,6 +34,7 @@ export const CurrencyDisplay = ({
: currencyValue?.amountMicros / 1000000;
const format = fieldDefinition.metadata.settings?.format;
const { formatNumber } = useNumberFormat();
if (!shouldDisplayCurrency) {
return <EllipsisDisplay>{0}</EllipsisDisplay>;
@@ -1,4 +1,4 @@
import { formatNumber } from '~/utils/format/formatNumber';
import { useNumberFormat } from '@/localization/hooks/useNumberFormat';
import { EllipsisDisplay } from './EllipsisDisplay';
@@ -6,6 +6,9 @@ type MoneyDisplayProps = {
value: number | null;
};
export const MoneyDisplay = ({ value }: MoneyDisplayProps) => (
<EllipsisDisplay>{value ? `$${formatNumber(value)}` : ''}</EllipsisDisplay>
);
export const MoneyDisplay = ({ value }: MoneyDisplayProps) => {
const { formatNumber } = useNumberFormat();
return (
<EllipsisDisplay>{value ? `$${formatNumber(value)}` : ''}</EllipsisDisplay>
);
};
@@ -2,9 +2,8 @@ import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { useEffect, useState } from 'react';
import { useIMask } from 'react-imask';
import { useRecoilValue } from 'recoil';
import { dateTimeFormatState } from '@/localization/states/dateTimeFormatState';
import { useDateTimeFormat } from '@/localization/hooks/useDateTimeFormat';
import { DATE_BLOCKS } from '@/ui/input/components/internal/date/constants/DateBlocks';
import { DATE_TIME_BLOCKS } from '@/ui/input/components/internal/date/constants/DateTimeBlocks';
import { MAX_DATE } from '@/ui/input/components/internal/date/constants/MaxDate';
@@ -53,7 +52,7 @@ export const DateTimeInput = ({
isDateTimeInput,
}: DateTimeInputProps) => {
const [hasError, setHasError] = useState(false);
const { dateFormat } = useRecoilValue(dateTimeFormatState);
const { dateFormat } = useDateTimeFormat();
const { parseToString, parseToDate } = useDateParser({
isDateTimeInput: isDateTimeInput === true,
});
@@ -7,7 +7,7 @@ import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CalendarStartDay } from '@/localization/constants/CalendarStartDay';
import { detectCalendarStartDay } from '@/localization/utils/detectCalendarStartDay';
import { detectCalendarStartDay } from '@/localization/utils/detection/detectCalendarStartDay';
import { AbsoluteDatePickerHeader } from '@/ui/input/components/internal/date/components/AbsoluteDatePickerHeader';
import { DateTimeInput } from '@/ui/input/components/internal/date/components/DateTimeInput';
import { RelativeDatePickerHeader } from '@/ui/input/components/internal/date/components/RelativeDatePickerHeader';
@@ -1,7 +1,6 @@
import { dateTimeFormatState } from '@/localization/states/dateTimeFormatState';
import { useDateTimeFormat } from '@/localization/hooks/useDateTimeFormat';
import { UserContext } from '@/users/contexts/UserContext';
import { useCallback, useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { parseDateToString } from '../date/utils/parseDateToString';
import { parseStringToDate } from '../date/utils/parseStringToDate';
@@ -10,7 +9,7 @@ type UseDateParserProps = {
};
export const useDateParser = ({ isDateTimeInput }: UseDateParserProps) => {
const { dateFormat } = useRecoilValue(dateTimeFormatState);
const { dateFormat } = useDateTimeFormat();
const { timeZone } = useContext(UserContext);
const parseToString = useCallback(