@greatapps/common 1.1.670 → 1.1.672
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/layouts/NavBar.mjs +5 -3
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/layouts/NotificationsPopover.mjs +5 -3
- package/dist/components/layouts/NotificationsPopover.mjs.map +1 -1
- package/dist/components/layouts/ProfilePopover.mjs +6 -4
- package/dist/components/layouts/ProfilePopover.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs +9 -7
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/modals/BuyCreditsModal.mjs +17 -18
- package/dist/components/modals/BuyCreditsModal.mjs.map +1 -1
- package/dist/components/modals/CreditsDisabledModal.mjs +6 -4
- package/dist/components/modals/CreditsDisabledModal.mjs.map +1 -1
- package/dist/components/modals/PaidPlanRequiredModal.mjs +5 -3
- package/dist/components/modals/PaidPlanRequiredModal.mjs.map +1 -1
- package/dist/components/modals/cards/AddCardModal.mjs +27 -24
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs +9 -7
- package/dist/components/modals/cards/CannotDeleteCardModal.mjs.map +1 -1
- package/dist/components/modals/cards/CardFormFields.mjs +25 -22
- package/dist/components/modals/cards/CardFormFields.mjs.map +1 -1
- package/dist/components/modals/cards/DeleteCardModal.mjs +10 -8
- package/dist/components/modals/cards/DeleteCardModal.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs +4 -2
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -1
- package/dist/components/navigation/OverdueInvoiceBanner.mjs +4 -2
- package/dist/components/navigation/OverdueInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/PendingCancellationBanner.mjs +4 -6
- package/dist/components/navigation/PendingCancellationBanner.mjs.map +1 -1
- package/dist/components/navigation/ProjectSelectorPopover.mjs +8 -6
- package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs +4 -6
- package/dist/components/navigation/UpcomingInvoiceBanner.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/BottomLinks.mjs +5 -3
- package/dist/components/navigation/subcomponents/BottomLinks.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/CreditsCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs +3 -1
- package/dist/components/navigation/subcomponents/PlanCard.mjs.map +1 -1
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs +5 -3
- package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
- package/dist/components/pages/NotFoundPage.mjs +5 -3
- package/dist/components/pages/NotFoundPage.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs +13 -10
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs +9 -5
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/CardItem.mjs +7 -5
- package/dist/components/ui/data-display/CardItem.mjs.map +1 -1
- package/dist/components/ui/data-display/PaymentInfoCard.mjs +10 -8
- package/dist/components/ui/data-display/PaymentInfoCard.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs +3 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/form/ComboboxField.mjs +11 -6
- package/dist/components/ui/form/ComboboxField.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs +5 -2
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs +5 -2
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/PhoneInput.mjs +5 -3
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
- package/dist/components/ui/form/SelectField.mjs +6 -3
- package/dist/components/ui/form/SelectField.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs +11 -18
- package/dist/components/widgets/ImageUpload/ImageCropModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +6 -15
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
- package/dist/i18n/messages/en-us.mjs +231 -0
- package/dist/i18n/messages/en-us.mjs.map +1 -1
- package/dist/i18n/messages/es-es.mjs +231 -0
- package/dist/i18n/messages/es-es.mjs.map +1 -1
- package/dist/i18n/messages/pt-br.mjs +239 -0
- package/dist/i18n/messages/pt-br.mjs.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs +2 -1
- package/dist/modules/cards/hooks/handle-delete-card.hook.mjs.map +1 -1
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs +7 -2
- package/dist/modules/plans/utils/map-api-plan-to-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/layouts/NavBar.tsx +5 -3
- package/src/components/layouts/NotificationsPopover.tsx +5 -3
- package/src/components/layouts/ProfilePopover.tsx +6 -4
- package/src/components/layouts/UsersSelectorPopover.tsx +9 -7
- package/src/components/modals/BuyCreditsModal.tsx +18 -16
- package/src/components/modals/CreditsDisabledModal.tsx +6 -6
- package/src/components/modals/PaidPlanRequiredModal.tsx +5 -3
- package/src/components/modals/cards/AddCardModal.tsx +29 -27
- package/src/components/modals/cards/CannotDeleteCardModal.tsx +9 -8
- package/src/components/modals/cards/CardFormFields.tsx +25 -22
- package/src/components/modals/cards/DeleteCardModal.tsx +10 -8
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +4 -2
- package/src/components/navigation/OverdueInvoiceBanner.tsx +4 -2
- package/src/components/navigation/PendingCancellationBanner.tsx +4 -2
- package/src/components/navigation/ProjectSelectorPopover.tsx +8 -6
- package/src/components/navigation/UpcomingInvoiceBanner.tsx +4 -2
- package/src/components/navigation/subcomponents/BottomLinks.tsx +5 -3
- package/src/components/navigation/subcomponents/CreditsCard.tsx +3 -1
- package/src/components/navigation/subcomponents/PlanCard.tsx +3 -1
- package/src/components/navigation/subcomponents/ProjectSelector.tsx +5 -3
- package/src/components/pages/NotFoundPage.tsx +5 -3
- package/src/components/pages/notifications/Notifications.tsx +13 -10
- package/src/components/ui/buttons/CopyButton.tsx +10 -5
- package/src/components/ui/data-display/CardItem.tsx +7 -5
- package/src/components/ui/data-display/PaymentInfoCard.tsx +10 -8
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +3 -1
- package/src/components/ui/form/ComboboxField.tsx +11 -6
- package/src/components/ui/form/DatePicker.tsx +5 -2
- package/src/components/ui/form/DateRangePicker.tsx +5 -2
- package/src/components/ui/form/PhoneInput.tsx +5 -3
- package/src/components/ui/form/SelectField.tsx +6 -3
- package/src/components/widgets/ImageUpload/ImageCropModal.tsx +19 -11
- package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +6 -5
- package/src/i18n/messages/en-us.ts +234 -0
- package/src/i18n/messages/es-es.ts +234 -0
- package/src/i18n/messages/pt-br.ts +248 -0
- package/src/index.ts +4 -1
- package/src/modules/cards/hooks/handle-delete-card.hook.ts +8 -3
- package/src/modules/plans/utils/map-api-plan-to-ui.ts +19 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { IconAlertTriangle, IconX } from '@tabler/icons-react';
|
|
5
5
|
import { formatShortDate } from '../../infra/utils/date';
|
|
6
|
+
import { useTranslations } from 'next-intl';
|
|
6
7
|
|
|
7
8
|
interface PendingCancellationBannerProps {
|
|
8
9
|
limitDate?: Date | null;
|
|
@@ -13,6 +14,7 @@ export function PendingCancellationBanner({
|
|
|
13
14
|
limitDate,
|
|
14
15
|
onReactivate,
|
|
15
16
|
}: PendingCancellationBannerProps) {
|
|
17
|
+
const translate = useTranslations();
|
|
16
18
|
const [visible, setVisible] = useState(true);
|
|
17
19
|
const [animated, setAnimated] = useState(false);
|
|
18
20
|
|
|
@@ -35,7 +37,7 @@ export function PendingCancellationBanner({
|
|
|
35
37
|
<div className="flex items-center gap-2 flex-1 w-full sm:w-auto">
|
|
36
38
|
<IconAlertTriangle size={16} className="text-zinc-950 shrink-0" />
|
|
37
39
|
<span className="paragraph-xsmall-semibold text-zinc-950">
|
|
38
|
-
|
|
40
|
+
{translate('common.navigation.banners.pending.message', { limitDate: formattedLimitDate ?? '' })}
|
|
39
41
|
</span>
|
|
40
42
|
</div>
|
|
41
43
|
<div className="flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start">
|
|
@@ -45,7 +47,7 @@ export function PendingCancellationBanner({
|
|
|
45
47
|
onClick={onReactivate}
|
|
46
48
|
>
|
|
47
49
|
<span className="paragraph-xsmall-semibold text-zinc-950 underline">
|
|
48
|
-
|
|
50
|
+
{translate('common.navigation.banners.pending.reactivate')}
|
|
49
51
|
</span>
|
|
50
52
|
</button>
|
|
51
53
|
<button type="button" className="cursor-pointer shrink-0" onClick={dismiss}>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Dispatch, RefObject, SetStateAction, UIEvent, useCallback } from 'react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import {
|
|
5
6
|
Button,
|
|
6
7
|
Command,
|
|
@@ -61,6 +62,7 @@ export function ProjectSelectorPopover({
|
|
|
61
62
|
onSearchChange,
|
|
62
63
|
children,
|
|
63
64
|
}: ProjectSelectorPopoverProps) {
|
|
65
|
+
const translate = useTranslations();
|
|
64
66
|
const handleListScroll = useCallback((event: UIEvent<HTMLDivElement>) => {
|
|
65
67
|
if (!hasNextPage || isFetchingNextPage || !onLoadMore) return;
|
|
66
68
|
|
|
@@ -96,10 +98,10 @@ export function ProjectSelectorPopover({
|
|
|
96
98
|
>
|
|
97
99
|
<div className="flex flex-col p-3 gap-2">
|
|
98
100
|
<div className="flex items-center justify-between">
|
|
99
|
-
<span className="paragraph-small-semibold">
|
|
101
|
+
<span className="paragraph-small-semibold">{translate('common.navigation.projectSelector.title')}</span>
|
|
100
102
|
</div>
|
|
101
103
|
<Command className="gap-2" defaultValue=" " shouldFilter={!onSearchChange} value=" " onValueChange={() => {}}>
|
|
102
|
-
<CommandInput placeholder=
|
|
104
|
+
<CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={onSearchChange} />
|
|
103
105
|
<CommandList
|
|
104
106
|
className="custom-scrollbar paragraph-small-medium text-gray-600 max-h-[227px]"
|
|
105
107
|
onScroll={handleListScroll}
|
|
@@ -115,14 +117,14 @@ export function ProjectSelectorPopover({
|
|
|
115
117
|
<div className="flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4">
|
|
116
118
|
<IconFolderOpen size={28} className="text-gray-300" />
|
|
117
119
|
<span className="paragraph-small-medium text-center text-gray-500">
|
|
118
|
-
|
|
120
|
+
{translate('common.navigation.projectSelector.emptyLine1')}
|
|
119
121
|
<br />
|
|
120
|
-
|
|
122
|
+
{translate('common.navigation.projectSelector.emptyLine2')}
|
|
121
123
|
</span>
|
|
122
124
|
</div>
|
|
123
125
|
) : (
|
|
124
126
|
<>
|
|
125
|
-
<CommandEmpty>
|
|
127
|
+
<CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>
|
|
126
128
|
{projects.map((project) => {
|
|
127
129
|
const isSelected = selectedProject?.id === project.id;
|
|
128
130
|
return (
|
|
@@ -167,7 +169,7 @@ export function ProjectSelectorPopover({
|
|
|
167
169
|
className="h-10! paragraph-small-medium text-gray-600 hover:text-gray-950 hover:bg-zinc-50 w-full justify-center"
|
|
168
170
|
onClick={onManageProjects}
|
|
169
171
|
>
|
|
170
|
-
|
|
172
|
+
{translate('common.navigation.projectSelector.manageProjects')}
|
|
171
173
|
</Button>
|
|
172
174
|
</>
|
|
173
175
|
)}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { IconAlertTriangle, IconX } from '@tabler/icons-react';
|
|
5
5
|
import { formatShortDate } from '../../infra/utils/date';
|
|
6
|
+
import { useTranslations } from 'next-intl';
|
|
6
7
|
|
|
7
8
|
interface UpcomingInvoiceBannerProps {
|
|
8
9
|
dueDate?: Date | null;
|
|
@@ -10,6 +11,7 @@ interface UpcomingInvoiceBannerProps {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function UpcomingInvoiceBanner({ dueDate, onDetails }: UpcomingInvoiceBannerProps) {
|
|
14
|
+
const translate = useTranslations();
|
|
13
15
|
const [visible, setVisible] = useState(true);
|
|
14
16
|
const [animated, setAnimated] = useState(false);
|
|
15
17
|
|
|
@@ -32,7 +34,7 @@ export function UpcomingInvoiceBanner({ dueDate, onDetails }: UpcomingInvoiceBan
|
|
|
32
34
|
<div className="flex items-center gap-2 flex-1 w-full sm:w-auto">
|
|
33
35
|
<IconAlertTriangle size={16} className="text-zinc-950 shrink-0" />
|
|
34
36
|
<span className="paragraph-xsmall-semibold text-zinc-950">
|
|
35
|
-
|
|
37
|
+
{translate('common.navigation.banners.upcoming.message', { dueDate: formattedDueDate ?? '' })}
|
|
36
38
|
</span>
|
|
37
39
|
</div>
|
|
38
40
|
<div className="flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start">
|
|
@@ -41,7 +43,7 @@ export function UpcomingInvoiceBanner({ dueDate, onDetails }: UpcomingInvoiceBan
|
|
|
41
43
|
className="flex items-center justify-center p-1.5 cursor-pointer"
|
|
42
44
|
onClick={onDetails}
|
|
43
45
|
>
|
|
44
|
-
<span className="paragraph-xsmall-semibold text-zinc-950 underline">
|
|
46
|
+
<span className="paragraph-xsmall-semibold text-zinc-950 underline">{translate('common.navigation.banners.upcoming.details')}</span>
|
|
45
47
|
</button>
|
|
46
48
|
<button type="button" className="cursor-pointer shrink-0" onClick={dismiss}>
|
|
47
49
|
<IconX size={18} className="text-zinc-700" />
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { IconHelp, IconBulb, IconStar, type TablerIcon } from '@tabler/icons-react';
|
|
4
4
|
import { useIsDefaultWhitelabel, useWhitelabel } from '../../../providers/whitelabel.provider';
|
|
5
|
+
import { useTranslations } from 'next-intl';
|
|
5
6
|
|
|
6
7
|
interface BottomLink {
|
|
7
8
|
label: string;
|
|
@@ -17,6 +18,7 @@ function openFrillWidget() {
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function BottomLinks() {
|
|
21
|
+
const translate = useTranslations();
|
|
20
22
|
const { whitelabel } = useWhitelabel();
|
|
21
23
|
const isMainWhitelabel = useIsDefaultWhitelabel();
|
|
22
24
|
|
|
@@ -26,7 +28,7 @@ export function BottomLinks() {
|
|
|
26
28
|
...(isMainWhitelabel
|
|
27
29
|
? [
|
|
28
30
|
{
|
|
29
|
-
label: '
|
|
31
|
+
label: translate('common.navigation.bottomLinks.news'),
|
|
30
32
|
icon: IconStar,
|
|
31
33
|
className: 'novidades',
|
|
32
34
|
onClick: openFrillWidget,
|
|
@@ -34,14 +36,14 @@ export function BottomLinks() {
|
|
|
34
36
|
]
|
|
35
37
|
: []),
|
|
36
38
|
{
|
|
37
|
-
label: '
|
|
39
|
+
label: translate('common.navigation.bottomLinks.helpCenter'),
|
|
38
40
|
icon: IconHelp,
|
|
39
41
|
href: helpUrl,
|
|
40
42
|
},
|
|
41
43
|
...(isMainWhitelabel
|
|
42
44
|
? [
|
|
43
45
|
{
|
|
44
|
-
label: '
|
|
46
|
+
label: translate('common.navigation.bottomLinks.sendSuggestions'),
|
|
45
47
|
icon: IconBulb,
|
|
46
48
|
href: 'https://ideias.greatpages.com.br/b/y0geg1ve/feature-ideas',
|
|
47
49
|
},
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useAppNavigationContext } from '../AppNavigationContext';
|
|
4
4
|
import { Progress } from '../../../index';
|
|
5
|
+
import { useTranslations } from 'next-intl';
|
|
5
6
|
import { useBuyCreditsModal } from '../../../store/useBuyCreditsModal';
|
|
6
7
|
import { useCreditsDisabledModal } from '../../../store/useCreditsDisabledModal';
|
|
7
8
|
import { useAuth } from '../../../providers/auth.provider';
|
|
@@ -13,6 +14,7 @@ export interface CreditsCardProps {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export function CreditsCard({ used, total, onClick }: CreditsCardProps) {
|
|
17
|
+
const translate = useTranslations();
|
|
16
18
|
const { breakpoint } = useAppNavigationContext();
|
|
17
19
|
const { openModal } = useBuyCreditsModal();
|
|
18
20
|
const { openModal: openDisabledModal } = useCreditsDisabledModal();
|
|
@@ -35,7 +37,7 @@ export function CreditsCard({ used, total, onClick }: CreditsCardProps) {
|
|
|
35
37
|
onClick={handleClick}
|
|
36
38
|
>
|
|
37
39
|
<div className="flex items-center justify-between">
|
|
38
|
-
<span className="paragraph-xsmall-semibold text-white">
|
|
40
|
+
<span className="paragraph-xsmall-semibold text-white">{translate('common.navigation.creditsCard.label')}</span>
|
|
39
41
|
<span className="paragraph-xsmall-medium text-white/50">{used} / {total}</span>
|
|
40
42
|
</div>
|
|
41
43
|
<Progress className="bg-white/10 h-[6px]" indicatorColor="bg-white" value={Math.round((used / total) * 100)} />
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Button, Progress } from '../../../index';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
|
|
5
6
|
export interface PlanCardProps {
|
|
6
7
|
planName: string;
|
|
@@ -10,6 +11,7 @@ export interface PlanCardProps {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function PlanCard({ planName, trialLabel, progressValue, onKnowPlans }: PlanCardProps) {
|
|
14
|
+
const translate = useTranslations();
|
|
13
15
|
return (
|
|
14
16
|
<div className="flex flex-col rounded-md p-4 gap-4 bg-gray-50">
|
|
15
17
|
<div className="flex flex-col gap-1">
|
|
@@ -22,7 +24,7 @@ export function PlanCard({ planName, trialLabel, progressValue, onKnowPlans }: P
|
|
|
22
24
|
className="paragraph-small-semibold text-gray-950"
|
|
23
25
|
onClick={onKnowPlans}
|
|
24
26
|
>
|
|
25
|
-
|
|
27
|
+
{translate('common.navigation.planCard.knowPlans')}
|
|
26
28
|
</Button>
|
|
27
29
|
</div>
|
|
28
30
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useRef, useEffect, useMemo, RefObject } from 'react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { useMobileNavbarSheet } from '../../../store/useMobileNavbarSheet';
|
|
5
6
|
import { useAppNavigationContext } from '../AppNavigationContext';
|
|
6
7
|
import { ProjectSelectorPopover } from '../ProjectSelectorPopover';
|
|
@@ -30,6 +31,7 @@ export function ProjectSelector({
|
|
|
30
31
|
onSelectProject,
|
|
31
32
|
onManageProjects,
|
|
32
33
|
}: ProjectSelectorProps) {
|
|
34
|
+
const translate = useTranslations();
|
|
33
35
|
const isMainWhitelabel = useIsDefaultWhitelabel();
|
|
34
36
|
const { breakpoint } = useAppNavigationContext();
|
|
35
37
|
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
|
@@ -124,10 +126,10 @@ export function ProjectSelector({
|
|
|
124
126
|
{activeSection === 'projects' && (
|
|
125
127
|
<div className="flex flex-col p-3 gap-2 border border-gray-200 rounded-lg animate-in fade-in duration-400">
|
|
126
128
|
<div className="flex items-center justify-between">
|
|
127
|
-
<span className="paragraph-small-semibold">
|
|
129
|
+
<span className="paragraph-small-semibold">{translate('common.navigation.projectSelector.title')}</span>
|
|
128
130
|
</div>
|
|
129
131
|
<Command className="gap-2" shouldFilter={false}>
|
|
130
|
-
<CommandInput placeholder=
|
|
132
|
+
<CommandInput placeholder={translate('common.navigation.projectSelector.searchPlaceholder')} value={search} onValueChange={setSearch} />
|
|
131
133
|
<CommandList
|
|
132
134
|
className="custom-scrollbar paragraph-small-medium text-gray-600 h-[227px]"
|
|
133
135
|
onScroll={(event) => {
|
|
@@ -141,7 +143,7 @@ export function ProjectSelector({
|
|
|
141
143
|
}
|
|
142
144
|
}}
|
|
143
145
|
>
|
|
144
|
-
<CommandEmpty>
|
|
146
|
+
<CommandEmpty>{translate('common.navigation.projectSelector.noResults')}</CommandEmpty>
|
|
145
147
|
{showListSkeleton ? (
|
|
146
148
|
<>
|
|
147
149
|
<ProjectItemSkeleton />
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import Image from "next/image";
|
|
4
4
|
import { useEffect } from "react";
|
|
5
|
+
import { useTranslations } from "next-intl";
|
|
5
6
|
import { useRouter } from "next/navigation";
|
|
6
7
|
import { useWhitelabel, useIsDefaultWhitelabel } from "../../providers/whitelabel.provider";
|
|
7
8
|
import { Button } from "../ui/buttons/Button";
|
|
@@ -18,6 +19,7 @@ function GreatAppsLogo() {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export function NotFoundPage() {
|
|
22
|
+
const translate = useTranslations();
|
|
21
23
|
const router = useRouter();
|
|
22
24
|
|
|
23
25
|
useEffect(() => {
|
|
@@ -47,11 +49,11 @@ export function NotFoundPage() {
|
|
|
47
49
|
</div>
|
|
48
50
|
|
|
49
51
|
<h1 className="max-w-[554px] px-6 font-[family-name:var(--font-outfit)] text-[32px] leading-[36px] font-semibold text-zinc-950 sm:px-0 sm:text-[56px] sm:leading-[56px]">
|
|
50
|
-
|
|
52
|
+
{translate('common.notFound.title')}
|
|
51
53
|
</h1>
|
|
52
54
|
|
|
53
55
|
<p className="max-w-[496px] px-6 paragraph-medium-medium text-zinc-950 sm:px-0">
|
|
54
|
-
|
|
56
|
+
{translate('common.notFound.description')}
|
|
55
57
|
</p>
|
|
56
58
|
|
|
57
59
|
<Button
|
|
@@ -65,7 +67,7 @@ export function NotFoundPage() {
|
|
|
65
67
|
}
|
|
66
68
|
}}
|
|
67
69
|
>
|
|
68
|
-
|
|
70
|
+
{translate('common.notFound.backToHome')}
|
|
69
71
|
</Button>
|
|
70
72
|
</div>
|
|
71
73
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { IconBell, IconCheck, IconLoader2 } from '@tabler/icons-react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { Button } from "../../ui/buttons/Button";
|
|
5
6
|
import {
|
|
6
7
|
Tabs,
|
|
@@ -34,6 +35,7 @@ function NotificationsList({
|
|
|
34
35
|
hasNextPage: boolean;
|
|
35
36
|
fetchNextPage: () => void;
|
|
36
37
|
}) {
|
|
38
|
+
const translate = useTranslations();
|
|
37
39
|
const notifications = pages?.pages.flatMap((p) => p.data) ?? [];
|
|
38
40
|
|
|
39
41
|
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
|
@@ -50,7 +52,7 @@ function NotificationsList({
|
|
|
50
52
|
return (
|
|
51
53
|
<div className="rounded-lg border border-zinc-200 bg-white">
|
|
52
54
|
<div className="flex flex-col items-center justify-center py-16 gap-2">
|
|
53
|
-
<span className="paragraph-medium-regular text-zinc-500">
|
|
55
|
+
<span className="paragraph-medium-regular text-zinc-500">{translate('common.notifications.page.empty')}</span>
|
|
54
56
|
</div>
|
|
55
57
|
</div>
|
|
56
58
|
);
|
|
@@ -80,7 +82,7 @@ function NotificationsList({
|
|
|
80
82
|
actions={
|
|
81
83
|
detailsUrl ? (
|
|
82
84
|
<Button asChild variant="secondary" className="h-8! px-3! paragraph-small-semibold">
|
|
83
|
-
<Link href={detailsUrl}>
|
|
85
|
+
<Link href={detailsUrl}>{translate('common.notifications.page.details')}</Link>
|
|
84
86
|
</Button>
|
|
85
87
|
) : undefined
|
|
86
88
|
}
|
|
@@ -97,6 +99,7 @@ function NotificationsList({
|
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
export function NotificationPageContent() {
|
|
102
|
+
const translate = useTranslations();
|
|
100
103
|
const unreadNotifications = useInfiniteMessages({
|
|
101
104
|
readed: false,
|
|
102
105
|
type: "notification",
|
|
@@ -116,12 +119,12 @@ export function NotificationPageContent() {
|
|
|
116
119
|
markAllAsRead(undefined, {
|
|
117
120
|
onSuccess: () => {
|
|
118
121
|
toast.custom((t) => (
|
|
119
|
-
<Toast variant="success" message=
|
|
122
|
+
<Toast variant="success" message={translate('common.notifications.page.markAllSuccess')} toastId={t} />
|
|
120
123
|
));
|
|
121
124
|
},
|
|
122
125
|
onError: () => {
|
|
123
126
|
toast.custom((t) => (
|
|
124
|
-
<Toast variant="error" message=
|
|
127
|
+
<Toast variant="error" message={translate('common.notifications.page.markAllError')} toastId={t} />
|
|
125
128
|
));
|
|
126
129
|
},
|
|
127
130
|
});
|
|
@@ -132,10 +135,10 @@ export function NotificationPageContent() {
|
|
|
132
135
|
<div className="flex items-center justify-between gap-4">
|
|
133
136
|
<div className="flex flex-col gap-2">
|
|
134
137
|
<h1 className="title-large-semibold text-gray-950">
|
|
135
|
-
|
|
138
|
+
{translate('common.notifications.page.title')}
|
|
136
139
|
</h1>
|
|
137
140
|
<p className="paragraph-small-regular text-gray-600 hidden lg:block">
|
|
138
|
-
|
|
141
|
+
{translate('common.notifications.page.subtitle')}
|
|
139
142
|
</p>
|
|
140
143
|
</div>
|
|
141
144
|
<Button
|
|
@@ -145,8 +148,8 @@ export function NotificationPageContent() {
|
|
|
145
148
|
disabled={isMarkingAll || totalUnread === 0}
|
|
146
149
|
>
|
|
147
150
|
{isMarkingAll ? <IconLoader2 size={20} className="animate-spin" /> : <IconCheck size={20} />}
|
|
148
|
-
<span className="lg:block hidden">
|
|
149
|
-
<span className="lg:hidden">
|
|
151
|
+
<span className="lg:block hidden">{translate('common.notifications.page.markAllReadDesktop')}</span>
|
|
152
|
+
<span className="lg:hidden">{translate('common.notifications.page.markAllReadMobile')}</span>
|
|
150
153
|
</Button>
|
|
151
154
|
</div>
|
|
152
155
|
<Tabs
|
|
@@ -155,11 +158,11 @@ export function NotificationPageContent() {
|
|
|
155
158
|
>
|
|
156
159
|
<TabsList className="h-auto pb-0 bg-transparent">
|
|
157
160
|
<TabsTrigger className="gap-2" value="all">
|
|
158
|
-
|
|
161
|
+
{translate('common.notifications.page.tabAll')}{" "}
|
|
159
162
|
<span className="text-gray-500">({totalAll})</span>
|
|
160
163
|
</TabsTrigger>
|
|
161
164
|
<TabsTrigger className="gap-2" value="unreads" disabled={totalUnread === 0}>
|
|
162
|
-
|
|
165
|
+
{translate('common.notifications.page.tabUnread')}{" "}
|
|
163
166
|
<span className="text-gray-500">({totalUnread})</span>
|
|
164
167
|
</TabsTrigger>
|
|
165
168
|
</TabsList>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
3
4
|
import { IconCheck, IconCopy } from '@tabler/icons-react';
|
|
4
5
|
import { toast } from "sonner";
|
|
5
6
|
import { Toast } from "../feedback/Toast";
|
|
@@ -19,18 +20,22 @@ export function CopyButton({
|
|
|
19
20
|
textToCopy,
|
|
20
21
|
size = 14,
|
|
21
22
|
className,
|
|
22
|
-
tooltipText
|
|
23
|
-
successMessage
|
|
23
|
+
tooltipText,
|
|
24
|
+
successMessage,
|
|
24
25
|
}: CopyButtonProps) {
|
|
26
|
+
const translate = useTranslations();
|
|
27
|
+
const resolvedTooltipText = tooltipText ?? translate('common.forms.copyButton.tooltipDefault');
|
|
28
|
+
const resolvedSuccessMessage = successMessage ?? translate('common.forms.copyButton.successDefault');
|
|
29
|
+
|
|
25
30
|
const { isCopied, copy } = useCopyToClipboard({
|
|
26
31
|
onSuccess: () => {
|
|
27
32
|
toast.custom((t) => (
|
|
28
|
-
<Toast variant="success" message={
|
|
33
|
+
<Toast variant="success" message={resolvedSuccessMessage} toastId={t} />
|
|
29
34
|
));
|
|
30
35
|
},
|
|
31
36
|
onError: () => {
|
|
32
37
|
toast.custom((t) => (
|
|
33
|
-
<Toast variant="error" message=
|
|
38
|
+
<Toast variant="error" message={translate('common.forms.copyButton.errorMessage')} toastId={t} />
|
|
34
39
|
));
|
|
35
40
|
},
|
|
36
41
|
});
|
|
@@ -48,7 +53,7 @@ export function CopyButton({
|
|
|
48
53
|
{isCopied ? <IconCheck size={size} /> : <IconCopy size={size} />}
|
|
49
54
|
</span>
|
|
50
55
|
</TooltipTrigger>
|
|
51
|
-
<TooltipContent>{isCopied ?
|
|
56
|
+
<TooltipContent>{isCopied ? translate('common.actions.copied') : resolvedTooltipText}</TooltipContent>
|
|
52
57
|
</Tooltip>
|
|
53
58
|
);
|
|
54
59
|
}
|
|
@@ -10,6 +10,7 @@ import { CardBrandIcon } from './CardBrandIcons';
|
|
|
10
10
|
import { useSetDefaultCard } from '../../../modules/cards/hooks/set-default-card.hook';
|
|
11
11
|
import { useHandleDeleteCard } from '../../../modules/cards/hooks/handle-delete-card.hook';
|
|
12
12
|
import type { Card } from '../../../modules/cards/types';
|
|
13
|
+
import { useTranslations } from 'next-intl';
|
|
13
14
|
|
|
14
15
|
type CardItemProps = {
|
|
15
16
|
card: Card;
|
|
@@ -32,6 +33,7 @@ export function CardItem({
|
|
|
32
33
|
onAfterDelete,
|
|
33
34
|
onAfterSetDefault,
|
|
34
35
|
}: CardItemProps) {
|
|
36
|
+
const translate = useTranslations();
|
|
35
37
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
36
38
|
|
|
37
39
|
const setDefaultCardMutation = useSetDefaultCard();
|
|
@@ -44,7 +46,7 @@ export function CardItem({
|
|
|
44
46
|
toast.custom((t) => (
|
|
45
47
|
<Toast
|
|
46
48
|
variant="success"
|
|
47
|
-
message=
|
|
49
|
+
message={translate('common.cards.item.setDefaultSuccess')}
|
|
48
50
|
toastId={t}
|
|
49
51
|
/>
|
|
50
52
|
));
|
|
@@ -54,7 +56,7 @@ export function CardItem({
|
|
|
54
56
|
toast.custom((t) => (
|
|
55
57
|
<Toast
|
|
56
58
|
variant="error"
|
|
57
|
-
message=
|
|
59
|
+
message={translate('common.cards.item.setDefaultError')}
|
|
58
60
|
toastId={t}
|
|
59
61
|
/>
|
|
60
62
|
));
|
|
@@ -86,7 +88,7 @@ export function CardItem({
|
|
|
86
88
|
</div>
|
|
87
89
|
{card.is_default && (
|
|
88
90
|
<span className="paragraph-xsmall-semibold text-zinc-600 bg-zinc-100 px-2 py-0.5 rounded-lg whitespace-nowrap">
|
|
89
|
-
|
|
91
|
+
{translate('common.cards.item.defaultBadge')}
|
|
90
92
|
</span>
|
|
91
93
|
)}
|
|
92
94
|
<CardBrandIcon brand={card.brand} />
|
|
@@ -108,7 +110,7 @@ export function CardItem({
|
|
|
108
110
|
{menuHasSetDefault && (
|
|
109
111
|
<NavBarItem
|
|
110
112
|
icon={<IconStar size={18} className="text-zinc-400" />}
|
|
111
|
-
label=
|
|
113
|
+
label={translate('common.cards.item.makeDefault')}
|
|
112
114
|
onClick={() => {
|
|
113
115
|
setPopoverOpen(false);
|
|
114
116
|
handleSetDefault();
|
|
@@ -118,7 +120,7 @@ export function CardItem({
|
|
|
118
120
|
{menuHasDelete && (
|
|
119
121
|
<NavBarItem
|
|
120
122
|
icon={<IconTrash size={18} className="text-zinc-400" />}
|
|
121
|
-
label=
|
|
123
|
+
label={translate('common.actions.delete')}
|
|
122
124
|
onClick={() => {
|
|
123
125
|
setPopoverOpen(false);
|
|
124
126
|
handleDeleteCard(card);
|
|
@@ -9,6 +9,7 @@ import { useCards } from '../../../modules/cards/hooks/cards.hook';
|
|
|
9
9
|
import { useModalManager } from '../../../store/useModalManager';
|
|
10
10
|
import { useIsDefaultWhitelabel } from '../../../providers/whitelabel.provider';
|
|
11
11
|
import type { Card } from '../../../modules/cards/types';
|
|
12
|
+
import { useTranslations } from 'next-intl';
|
|
12
13
|
|
|
13
14
|
type PaymentInfoCardProps = {
|
|
14
15
|
email?: string;
|
|
@@ -29,6 +30,7 @@ export function PaymentInfoCard({
|
|
|
29
30
|
hideDelete,
|
|
30
31
|
hideSetDefault,
|
|
31
32
|
}: PaymentInfoCardProps) {
|
|
33
|
+
const translate = useTranslations();
|
|
32
34
|
const isMobile = useIsMobile();
|
|
33
35
|
const { openModal } = useModalManager();
|
|
34
36
|
const isDefaultWl = useIsDefaultWhitelabel();
|
|
@@ -83,19 +85,19 @@ export function PaymentInfoCard({
|
|
|
83
85
|
<div className="border border-zinc-200 rounded-lg overflow-hidden">
|
|
84
86
|
{email && (
|
|
85
87
|
<div className="flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3">
|
|
86
|
-
<span className="paragraph-small-medium text-zinc-500 w-[100px]">
|
|
88
|
+
<span className="paragraph-small-medium text-zinc-500 w-[100px]">{translate('common.cards.paymentInfo.email')}</span>
|
|
87
89
|
<span className="paragraph-small-medium text-zinc-950 flex-1">{email}</span>
|
|
88
90
|
</div>
|
|
89
91
|
)}
|
|
90
92
|
<div className="flex items-center h-[60px] px-4 gap-3">
|
|
91
|
-
<span className="paragraph-small-medium text-zinc-500 w-[100px]">
|
|
93
|
+
<span className="paragraph-small-medium text-zinc-500 w-[100px]">{translate('common.cards.paymentInfo.payment')}</span>
|
|
92
94
|
<button
|
|
93
95
|
type="button"
|
|
94
96
|
onClick={handleOpenAddCardModal}
|
|
95
97
|
className="flex items-center h-8 px-2 paragraph-small-semibold text-zinc-950 border border-zinc-200 rounded-md hover:border-zinc-400 transition-colors cursor-pointer w-fit"
|
|
96
98
|
>
|
|
97
99
|
<IconPlus className="size-[18px]" />
|
|
98
|
-
<span className="px-1.5">
|
|
100
|
+
<span className="px-1.5">{translate('common.cards.paymentInfo.addCard')}</span>
|
|
99
101
|
</button>
|
|
100
102
|
</div>
|
|
101
103
|
</div>
|
|
@@ -107,7 +109,7 @@ export function PaymentInfoCard({
|
|
|
107
109
|
<div className="border border-zinc-200 rounded-lg overflow-hidden">
|
|
108
110
|
{email && (
|
|
109
111
|
<div className="flex items-center h-[60px] px-4 border-b border-zinc-200 gap-3">
|
|
110
|
-
<span className="paragraph-small-medium text-zinc-500 w-[100px]">
|
|
112
|
+
<span className="paragraph-small-medium text-zinc-500 w-[100px]">{translate('common.cards.paymentInfo.email')}</span>
|
|
111
113
|
<span className="paragraph-small-medium text-zinc-950 flex-1">{email}</span>
|
|
112
114
|
</div>
|
|
113
115
|
)}
|
|
@@ -118,7 +120,7 @@ export function PaymentInfoCard({
|
|
|
118
120
|
>
|
|
119
121
|
{!isExpanded ? (
|
|
120
122
|
<>
|
|
121
|
-
<span className="paragraph-small-medium text-zinc-500 w-[100px]">
|
|
123
|
+
<span className="paragraph-small-medium text-zinc-500 w-[100px]">{translate('common.cards.paymentInfo.payment')}</span>
|
|
122
124
|
<div className="flex flex-col gap-0.5 flex-1 min-w-0">
|
|
123
125
|
<span className="paragraph-small-semibold text-zinc-950 truncate">
|
|
124
126
|
{selectedCard?.name}
|
|
@@ -135,7 +137,7 @@ export function PaymentInfoCard({
|
|
|
135
137
|
) : (
|
|
136
138
|
<>
|
|
137
139
|
<span className="paragraph-small-semibold text-zinc-950 flex-1">
|
|
138
|
-
|
|
140
|
+
{translate('common.cards.paymentInfo.selectPaymentMethod')}
|
|
139
141
|
</span>
|
|
140
142
|
<div className="size-8 flex items-center justify-center rounded-lg">
|
|
141
143
|
<IconChevronDown className="size-[18px] text-zinc-500 rotate-180" />
|
|
@@ -170,7 +172,7 @@ export function PaymentInfoCard({
|
|
|
170
172
|
: 'text-zinc-600 border border-zinc-200 hover:bg-zinc-50'
|
|
171
173
|
}`}
|
|
172
174
|
>
|
|
173
|
-
|
|
175
|
+
{translate('common.cards.paymentInfo.manageCards')}
|
|
174
176
|
</button>
|
|
175
177
|
)}
|
|
176
178
|
</div>
|
|
@@ -183,7 +185,7 @@ export function PaymentInfoCard({
|
|
|
183
185
|
>
|
|
184
186
|
<IconPlus className="size-[18px]" />
|
|
185
187
|
<span className="px-1.5">
|
|
186
|
-
{isExpanded ? '
|
|
188
|
+
{isExpanded ? translate('common.cards.paymentInfo.addCard') : translate('common.cards.paymentInfo.newPaymentMethod')}
|
|
187
189
|
</span>
|
|
188
190
|
</button>
|
|
189
191
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
3
4
|
import {
|
|
4
5
|
calculateRadius,
|
|
5
6
|
calculateCircumference,
|
|
@@ -21,6 +22,7 @@ export default function DefaultCircularProgress({
|
|
|
21
22
|
size = 62,
|
|
22
23
|
strokeWidth = 3,
|
|
23
24
|
}: CircularProgressProps) {
|
|
25
|
+
const translate = useTranslations();
|
|
24
26
|
const isDefaultWl = useIsDefaultWhitelabel();
|
|
25
27
|
const radius = calculateRadius(size, strokeWidth);
|
|
26
28
|
const circumference = calculateCircumference(radius);
|
|
@@ -35,7 +37,7 @@ export default function DefaultCircularProgress({
|
|
|
35
37
|
aria-valuenow={current}
|
|
36
38
|
aria-valuemin={0}
|
|
37
39
|
aria-valuemax={total}
|
|
38
|
-
aria-label=
|
|
40
|
+
aria-label={translate('common.forms.circularProgress.ariaLabel')}
|
|
39
41
|
>
|
|
40
42
|
<svg width={size} height={size} className="absolute">
|
|
41
43
|
<circle
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useMemo } from 'react';
|
|
4
|
+
import { useTranslations } from 'next-intl';
|
|
4
5
|
import { IconCheck, IconChevronDown, IconSearch } from '@tabler/icons-react';
|
|
5
6
|
import { Popover, PopoverContent, PopoverTrigger } from '../overlay/Popover';
|
|
6
7
|
import { cn } from '../../../infra/utils/clsx';
|
|
@@ -28,9 +29,9 @@ interface ComboboxFieldProps {
|
|
|
28
29
|
export function ComboboxField({
|
|
29
30
|
options,
|
|
30
31
|
label,
|
|
31
|
-
placeholder
|
|
32
|
-
searchPlaceholder
|
|
33
|
-
emptyMessage
|
|
32
|
+
placeholder,
|
|
33
|
+
searchPlaceholder,
|
|
34
|
+
emptyMessage,
|
|
34
35
|
value,
|
|
35
36
|
onChange,
|
|
36
37
|
disabled = false,
|
|
@@ -38,6 +39,10 @@ export function ComboboxField({
|
|
|
38
39
|
className,
|
|
39
40
|
containerClassName,
|
|
40
41
|
}: ComboboxFieldProps) {
|
|
42
|
+
const translate = useTranslations();
|
|
43
|
+
const resolvedPlaceholder = placeholder ?? translate('common.forms.combobox.placeholder');
|
|
44
|
+
const resolvedSearchPlaceholder = searchPlaceholder ?? translate('common.forms.combobox.searchPlaceholder');
|
|
45
|
+
const resolvedEmptyMessage = emptyMessage ?? translate('common.forms.combobox.emptyMessage');
|
|
41
46
|
const [open, setOpen] = useState(false);
|
|
42
47
|
const [search, setSearch] = useState('');
|
|
43
48
|
|
|
@@ -90,7 +95,7 @@ export function ComboboxField({
|
|
|
90
95
|
<span className={cn('truncate text-left', !selectedOption && 'text-gray-400')}>
|
|
91
96
|
{selectedOption
|
|
92
97
|
? (selectedOption.displayValue ?? selectedOption.label)
|
|
93
|
-
:
|
|
98
|
+
: resolvedPlaceholder}
|
|
94
99
|
</span>
|
|
95
100
|
{icon ?? (
|
|
96
101
|
<IconChevronDown
|
|
@@ -114,7 +119,7 @@ export function ComboboxField({
|
|
|
114
119
|
<IconSearch className="size-4 shrink-0 opacity-50 text-gray-500" />
|
|
115
120
|
<input
|
|
116
121
|
autoFocus
|
|
117
|
-
placeholder={
|
|
122
|
+
placeholder={resolvedSearchPlaceholder}
|
|
118
123
|
value={search}
|
|
119
124
|
onChange={(e) => setSearch(e.target.value)}
|
|
120
125
|
className="flex h-full w-full bg-transparent text-sm outline-none placeholder:text-gray-400 paragraph-small-medium text-gray-950"
|
|
@@ -123,7 +128,7 @@ export function ComboboxField({
|
|
|
123
128
|
|
|
124
129
|
<div className="overflow-y-auto max-h-[280px] p-1">
|
|
125
130
|
{filteredOptions.length === 0 ? (
|
|
126
|
-
<p className="py-6 text-center paragraph-small-medium text-gray-500">{
|
|
131
|
+
<p className="py-6 text-center paragraph-small-medium text-gray-500">{resolvedEmptyMessage}</p>
|
|
127
132
|
) : (
|
|
128
133
|
filteredOptions.map((option) => {
|
|
129
134
|
const isSelected = value === option.value;
|