diff --git a/apps/mobile/app/(app)/(tabs)/_layout.tsx b/apps/mobile/app/(app)/(tabs)/_layout.tsx index 937b7fa0..f66989a9 100644 --- a/apps/mobile/app/(app)/(tabs)/_layout.tsx +++ b/apps/mobile/app/(app)/(tabs)/_layout.tsx @@ -1,4 +1,5 @@ import { Button } from '@/components/ui/button' +import { Text } from '@/components/ui/text' import { useColorScheme } from '@/hooks/useColorScheme' import { theme } from '@/lib/theme' import { t } from '@lingui/macro' @@ -51,11 +52,13 @@ export default function TabLayout() { tabBarIcon: ({ color }) => , headerRight: () => ( - ), + headerTitleAlign: 'left', }} /> {/* + ) } diff --git a/apps/mobile/app/(app)/budget/new-budget.tsx b/apps/mobile/app/(app)/budget/new-budget.tsx new file mode 100644 index 00000000..3e29b40d --- /dev/null +++ b/apps/mobile/app/(app)/budget/new-budget.tsx @@ -0,0 +1,27 @@ +import { BudgetForm } from '@/components/budget/budget-form' +import { useCreateBudget } from '@/stores/budget/hooks' +import type { BudgetFormValues } from '@6pm/validation' +import { createId } from '@paralleldrive/cuid2' +import { PortalHost, useModalPortalRoot } from '@rn-primitives/portal' +import { useRouter } from 'expo-router' +import { View } from 'react-native' + +export default function CreateBudgetScreen() { + const router = useRouter() + const { mutateAsync } = useCreateBudget() + const { sideOffset, ...rootProps } = useModalPortalRoot() + + const handleCreate = async (data: BudgetFormValues) => { + mutateAsync({ data, id: createId() }).catch(() => { + // ignore + }) + router.back() + } + + return ( + + + + + ) +} diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 918c1445..5cce1c09 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -27,6 +27,7 @@ import { DefaultTheme, ThemeProvider, } from '@react-navigation/native' +import { PortalHost } from '@rn-primitives/portal' import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' import { focusManager, onlineManager } from '@tanstack/react-query' import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' @@ -126,6 +127,7 @@ export default function RootLayout() { /> + diff --git a/apps/mobile/components/budget/budget-form.tsx b/apps/mobile/components/budget/budget-form.tsx new file mode 100644 index 00000000..dc43963b --- /dev/null +++ b/apps/mobile/components/budget/budget-form.tsx @@ -0,0 +1,160 @@ +import { + type BudgetFormValues, + BudgetPeriodTypeSchema, + BudgetTypeSchema, + zBudgetFormValues, +} from '@6pm/validation' +import { zodResolver } from '@hookform/resolvers/zod' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import * as Haptics from 'expo-haptics' +import { useRef } from 'react' +import { + Controller, + FormProvider, + type UseFormReturn, + useForm, + useWatch, +} from 'react-hook-form' +import { ScrollView, View } from 'react-native' +import type { TextInput } from 'react-native' +import { CurrencyField } from '../form-fields/currency-field' +import { InputField } from '../form-fields/input-field' +import { SubmitButton } from '../form-fields/submit-button' +import { Label } from '../ui/label' +import { Text } from '../ui/text' +import { PeriodRangeField } from './period-range-field' +import { SelectBudgetTypeField } from './select-budget-type-field' +import { SelectPeriodTypeField } from './select-period-type-field' + +type BudgetFormProps = { + onSubmit: (data: BudgetFormValues) => void + defaultValues?: Partial + sideOffset?: number +} + +function BudgetSubmitButton({ + form, + onSubmit, +}: { + form: UseFormReturn + onSubmit: (data: BudgetFormValues) => void +}) { + const { i18n } = useLingui() + const amount = useWatch({ name: 'period.amount' }) + + return ( + + {t(i18n)`Save`} + + ) +} + +export const BudgetForm = ({ + onSubmit, + defaultValues, + sideOffset, +}: BudgetFormProps) => { + const { i18n } = useLingui() + const nameInputRef = useRef(null) + const amountInputRef = useRef(null) + + const budgetForm = useForm({ + resolver: zodResolver(zBudgetFormValues), + defaultValues: { + name: '', + description: '', + preferredCurrency: 'USD', + type: BudgetTypeSchema.Enum.SPENDING, + ...defaultValues, + period: { + type: BudgetPeriodTypeSchema.Enum.MONTHLY, + ...defaultValues?.period, + }, + }, + }) + + return ( + + + ( + + + { + onChange(type) + nameInputRef.current?.focus() + }} + /> + + )} + /> + amountInputRef.current?.focus()} + /> + ( + { + onChange(selected) + amountInputRef.current?.focus() + }} + /> + )} + /> + } + /> + ( + + + { + onChange(type) + }} + /> + + )} + /> + + + + + + + ) +} diff --git a/apps/mobile/components/budget/period-range-field.tsx b/apps/mobile/components/budget/period-range-field.tsx new file mode 100644 index 00000000..ea7660bc --- /dev/null +++ b/apps/mobile/components/budget/period-range-field.tsx @@ -0,0 +1,42 @@ +import { useController, useFormState, useWatch } from 'react-hook-form' +import { View } from 'react-native' +import { DateRangePicker } from '../common/date-range-picker' +import { Text } from '../ui/text' + +export function PeriodRangeField() { + const { errors } = useFormState() + const periodType = useWatch({ name: 'period.type' }) + + const { + field: { onChange: onChangeStartDate, value: startDate }, + } = useController({ + name: 'period.startDate', + }) + const { + field: { onChange: onChangeEndDate, value: endDate }, + } = useController({ + name: 'period.endDate', + }) + + if (periodType !== 'CUSTOM') { + return null + } + + return ( + + { + const [startDate, endDate] = dates ?? [] + onChangeStartDate(startDate) + onChangeEndDate(endDate) + }} + /> + {!!errors.period?.root?.message && ( + + {errors.period.root.message.toString()} + + )} + + ) +} diff --git a/apps/mobile/components/budget/select-budget-type-field.tsx b/apps/mobile/components/budget/select-budget-type-field.tsx new file mode 100644 index 00000000..6fa2794a --- /dev/null +++ b/apps/mobile/components/budget/select-budget-type-field.tsx @@ -0,0 +1,102 @@ +import { BudgetTypeSchema } from '@6pm/validation' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import { useMemo } from 'react' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import GenericIcon from '../common/generic-icon' +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from '../ui/select' + +type SelectBudgetTypeFieldProps = { + value: string + onSelect: (type?: string) => void + sideOffset?: number +} + +export function SelectBudgetTypeField({ + value, + onSelect, + sideOffset, +}: SelectBudgetTypeFieldProps) { + const { i18n } = useLingui() + const insets = useSafeAreaInsets() + const contentInsets = { + top: insets.top, + bottom: insets.bottom + Math.abs(sideOffset || 0), + left: 21, + right: 21, + } + + const options = useMemo( + () => [ + { + value: BudgetTypeSchema.Enum.SPENDING, + label: t(i18n)`Spending`, + icon: 'HandCoins', + }, + { + value: BudgetTypeSchema.Enum.SAVING, + label: t(i18n)`Saving`, + icon: 'PiggyBank', + }, + { + value: BudgetTypeSchema.Enum.INVESTING, + label: t(i18n)`Investing`, + icon: 'TrendingUp', + }, + { + value: BudgetTypeSchema.Enum.DEBT, + label: t(i18n)`Debt`, + icon: 'Landmark', + }, + ], + [i18n], + ) + + return ( + + ) +} diff --git a/apps/mobile/components/budget/select-period-type-field.tsx b/apps/mobile/components/budget/select-period-type-field.tsx new file mode 100644 index 00000000..39a4168e --- /dev/null +++ b/apps/mobile/components/budget/select-period-type-field.tsx @@ -0,0 +1,96 @@ +import { BudgetPeriodTypeSchema } from '@6pm/validation' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import { useMemo } from 'react' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from '../ui/select' + +type SelectPeriodTypeFieldProps = { + value: string + onSelect: (type?: string) => void + sideOffset?: number +} + +export function SelectPeriodTypeField({ + value, + onSelect, + sideOffset, +}: SelectPeriodTypeFieldProps) { + const { i18n } = useLingui() + const insets = useSafeAreaInsets() + const contentInsets = { + top: insets.top, + bottom: insets.bottom + Math.abs(sideOffset || 0), + left: 21, + right: 21, + } + + const options = useMemo( + () => [ + { + value: BudgetPeriodTypeSchema.Enum.WEEKLY, + label: t(i18n)`Weekly`, + }, + { + value: BudgetPeriodTypeSchema.Enum.MONTHLY, + label: t(i18n)`Monthly`, + }, + { + value: BudgetPeriodTypeSchema.Enum.QUARTERLY, + label: t(i18n)`Quarterly`, + }, + { + value: BudgetPeriodTypeSchema.Enum.YEARLY, + label: t(i18n)`Yearly`, + }, + { + value: BudgetPeriodTypeSchema.Enum.CUSTOM, + label: t(i18n)`Specific dates`, + }, + ], + [i18n], + ) + + return ( + + ) +} diff --git a/apps/mobile/components/common/date-range-picker.tsx b/apps/mobile/components/common/date-range-picker.tsx new file mode 100644 index 00000000..14ac1b97 --- /dev/null +++ b/apps/mobile/components/common/date-range-picker.tsx @@ -0,0 +1,203 @@ +import { useColorScheme } from '@/hooks/useColorScheme' +import { formatDateShort } from '@/lib/date' +import { theme } from '@/lib/theme' +import { cn, sleep } from '@/lib/utils' +import { + BottomSheetBackdrop, + BottomSheetModal, + BottomSheetView, +} from '@gorhom/bottom-sheet' +import { t } from '@lingui/macro' +import { useLingui } from '@lingui/react' +import DateTimePicker from '@react-native-community/datetimepicker' +import { addDays } from 'date-fns/addDays' +import { subDays } from 'date-fns/subDays' +import * as Haptics from 'expo-haptics' +import { ArrowRightIcon } from 'lucide-react-native' +import { useRef, useState } from 'react' +import { Keyboard, View } from 'react-native' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { FullWindowOverlay } from 'react-native-screens' +import { Button } from '../ui/button' +import { Text } from '../ui/text' + +function SpinnerDatePicker({ + value, + onChange, + maximumDate, + minimumDate, + title, +}: { + value?: Date + onChange: (date: Date | undefined) => void + maximumDate?: Date + minimumDate?: Date + title?: string +}) { + const { i18n } = useLingui() + const [date, setDate] = useState(value ?? new Date()) + + return ( + + + {title} + + { + setDate(selectedDate!) + }} + maximumDate={maximumDate} + minimumDate={minimumDate} + /> + + + ) +} + +export function DateRangePicker({ + value = [], + onChange, + maximumDate, + minimumDate, +}: { + value?: Date[] + onChange?: (date?: Date[]) => void + maximumDate?: Date + minimumDate?: Date +}) { + const { i18n } = useLingui() + const { bottom } = useSafeAreaInsets() + const { colorScheme } = useColorScheme() + const sheetFromRef = useRef(null) + const sheetToRef = useRef(null) + const [fromDate, toDate] = value ?? [] + + return ( + <> + + + + + + ( + + )} + containerComponent={(props) => ( + {props.children} + )} + > + + { + sheetFromRef.current?.close() + await sleep(500) + onChange?.([date, toDate]) + if (!toDate) { + onChange?.([date, addDays(date, 1)]) + sheetToRef.current?.present() + } else { + onChange?.([date, toDate]) + } + }} + maximumDate={toDate ? subDays(toDate, 1) : maximumDate} + minimumDate={minimumDate} + /> + + + ( + + )} + containerComponent={(props) => ( + {props.children} + )} + > + + { + sheetToRef.current?.close() + await sleep(500) + onChange?.([fromDate, date]) + }} + maximumDate={maximumDate} + minimumDate={fromDate ? addDays(fromDate, 1) : minimumDate} + /> + + + + ) +} diff --git a/apps/mobile/components/home/header.tsx b/apps/mobile/components/home/header.tsx index cd09c439..a73455dd 100644 --- a/apps/mobile/components/home/header.tsx +++ b/apps/mobile/components/home/header.tsx @@ -11,7 +11,7 @@ export function HomeHeader() { const { i18n } = useLingui() return ( - + , + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => { + const { open } = DropdownMenuPrimitive.useSubContext() + const Icon = + Platform.OS === 'web' ? ChevronRight : open ? ChevronUp : ChevronDown + return ( + + + {/* biome-ignore lint/complexity/noUselessFragments: */} + <>{children} + + + + ) +}) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { open } = DropdownMenuPrimitive.useSubContext() + return ( + + ) +}) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + overlayStyle?: StyleProp + overlayClassName?: string + portalHost?: string + } +>( + ( + { className, overlayClassName, overlayStyle, portalHost, ...props }, + ref, + ) => { + const { open } = DropdownMenuPrimitive.useRootContext() + return ( + + + + + + ) + }, +) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + + + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {/* biome-ignore lint/complexity/noUselessFragments: */} + <>{children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {/* biome-ignore lint/complexity/noUselessFragments: */} + <>{children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.ComponentPropsWithoutRef) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' + +export { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} diff --git a/apps/mobile/components/ui/select.tsx b/apps/mobile/components/ui/select.tsx new file mode 100644 index 00000000..fa08cf19 --- /dev/null +++ b/apps/mobile/components/ui/select.tsx @@ -0,0 +1,201 @@ +import { cn } from '@/lib/utils' +import * as SelectPrimitive from '@rn-primitives/select' +import { Check, ChevronDown, ChevronUp } from 'lucide-react-native' +import * as React from 'react' +import { Keyboard, Platform, StyleSheet, View } from 'react-native' +import Animated, { FadeIn, FadeOut } from 'react-native-reanimated' + +type Option = SelectPrimitive.Option + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1', + props.disabled && 'web:cursor-not-allowed opacity-50', + className, + )} + {...props} + onPress={(e) => { + Keyboard.dismiss() + props.onPress?.(e) + }} + > + {/* biome-ignore lint/complexity/noUselessFragments: */} + <>{children} + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +/** + * Platform: WEB ONLY + */ +const SelectScrollUpButton = ({ + className, + ...props +}: React.ComponentPropsWithoutRef) => { + if (Platform.OS !== 'web') { + return null + } + return ( + + + + ) +} + +/** + * Platform: WEB ONLY + */ +const SelectScrollDownButton = ({ + className, + ...props +}: React.ComponentPropsWithoutRef) => { + if (Platform.OS !== 'web') { + return null + } + return ( + + + + ) +} + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + portalHost?: string + } +>(({ className, children, position = 'popper', portalHost, ...props }, ref) => { + const { open } = SelectPrimitive.useRootContext() + + return ( + + + + + + + + {children} + + + + + + + + ) +}) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, + type Option, +} diff --git a/apps/mobile/components/wallet/account-form.tsx b/apps/mobile/components/wallet/account-form.tsx index cbe91a12..dc96500c 100644 --- a/apps/mobile/components/wallet/account-form.tsx +++ b/apps/mobile/components/wallet/account-form.tsx @@ -40,7 +40,6 @@ export const AccountForm = ({ onSubmit, defaultValues }: AccountFormProps) => { name="name" label={t(i18n)`Name`} placeholder={t(i18n)`Wallet account name`} - autoCapitalize="none" autoFocus={!defaultValues} className="!pl-[62px]" leftSection={ diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a27667b6..c77b1d6e 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -38,6 +38,11 @@ "@react-native-community/datetimepicker": "8.0.1", "@react-native-community/netinfo": "11.3.1", "@react-navigation/native": "^6.0.2", + "@rn-primitives/dropdown-menu": "^1.0.3", + "@rn-primitives/portal": "^1.0.3", + "@rn-primitives/select": "^1.0.3", + "@rn-primitives/slot": "^1.0.3", + "@rn-primitives/types": "^1.0.3", "@tanstack/query-async-storage-persister": "^5.51.1", "@tanstack/react-query": "^5.40.1", "@tanstack/react-query-persist-client": "^5.51.1", diff --git a/apps/mobile/stores/budget/hooks.tsx b/apps/mobile/stores/budget/hooks.tsx new file mode 100644 index 00000000..7bbfe50b --- /dev/null +++ b/apps/mobile/stores/budget/hooks.tsx @@ -0,0 +1,156 @@ +import { getHonoClient } from '@/lib/client' +import { + type BudgetFormValues, + BudgetSchema, + type BudgetWithRelations, +} from '@6pm/validation' +import { createId } from '@paralleldrive/cuid2' +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { keyBy } from 'lodash-es' +import { useMemo } from 'react' +import { z } from 'zod' +import { budgetQueries } from './queries' +import { useBudgetStore } from './store' + +export const useBudgetList = () => { + const budgets = useBudgetStore().budgets + const setBudgetsState = useBudgetStore((state) => state.setBudgets) + + const query = useQuery({ + ...budgetQueries.all({ setBudgetsState }), + initialData: budgets, + }) + + const { + budgetsDict, + spendingBudgets, + savingBudgets, + investingBudgets, + debtBudgets, + } = useMemo(() => { + const budgetsDict = keyBy(budgets, 'id') + const spendingBudgets = budgets.filter( + (budget) => budget.type === 'SPENDING', + ) + const savingBudgets = budgets.filter((budget) => budget.type === 'SAVING') + const investingBudgets = budgets.filter( + (budget) => budget.type === 'INVESTING', + ) + const debtBudgets = budgets.filter((budget) => budget.type === 'DEBT') + + return { + budgetsDict, + spendingBudgets, + savingBudgets, + investingBudgets, + debtBudgets, + } + }, [budgets]) + + return { + ...query, + budgets, + budgetsDict, + spendingBudgets, + savingBudgets, + investingBudgets, + debtBudgets, + } +} + +export const useBudget = (budgetId: string) => { + const budgets = useBudgetStore().budgets + const budget: BudgetWithRelations | null = useMemo( + () => budgets.find((budget) => budget.id === budgetId) || null, + [budgets, budgetId], + ) + + return { budget } +} + +export const useUpdateBudget = () => { + const updateBudgetInStore = useBudgetStore((state) => state.updateBudget) + const { budgetsDict } = useBudgetList() + const queryClient = useQueryClient() + + const mutation = useMutation( + { + mutationFn: async ({ + id, + data, + }: { id: string; data: BudgetFormValues }) => { + const hc = await getHonoClient() + const result = await hc.v1.budgets[':budgetId'].$put({ + param: { budgetId: id }, + json: data, + }) + + if (result.ok) { + const budget = BudgetSchema.parse(await result.json()) + return budget + } + + throw result + }, + onMutate({ id, data }) { + let budget = budgetsDict[id] + if (!budget) { + return + } + + budget = { ...budget, ...data, updatedAt: new Date() } + + updateBudgetInStore(budget) + + return budget + }, + }, + queryClient, + ) + + return mutation +} + +export const useCreateBudget = () => { + const updateBudgetInStore = useBudgetStore((state) => state.updateBudget) + + const mutation = useMutation({ + mutationFn: async ({ + id = createId(), + data, + }: { id?: string; data: BudgetFormValues }) => { + const hc = await getHonoClient() + const result = await hc.v1.budgets.$post({ + json: { id, ...data }, + }) + + if (result.ok) { + const json = await result.json() + const budget = BudgetSchema.extend({ + id: z.string(), + }).parse(json) + return budget + } + + throw result + }, + onMutate({ id, data }) { + const budget: BudgetWithRelations = { + id: id!, + createdAt: new Date(), + updatedAt: new Date(), + description: '', + budgetUsers: [], + invitations: [], + transactions: [], + ...data, + } + + updateBudgetInStore(budget) + + return budget + }, + }) + + return mutation +} diff --git a/apps/mobile/stores/budget/queries.ts b/apps/mobile/stores/budget/queries.ts new file mode 100644 index 00000000..9588d6f7 --- /dev/null +++ b/apps/mobile/stores/budget/queries.ts @@ -0,0 +1,30 @@ +import { getHonoClient } from '@/lib/client' +import { + type BudgetWithRelations, + BudgetWithRelationsSchema, +} from '@6pm/validation' +import { createQueryKeys } from '@lukemorales/query-key-factory' + +export const budgetQueries = createQueryKeys('budgets', { + all: ({ + setBudgetsState, + }: { setBudgetsState: (budgets: BudgetWithRelations[]) => void }) => ({ + queryKey: [{}], + queryFn: async () => { + const hc = await getHonoClient() + const res = await hc.v1.budgets.$get({ + query: {}, + }) + if (!res.ok) { + throw new Error(await res.text()) + } + + const items = await res.json() + const budgets = items.map((item) => BudgetWithRelationsSchema.parse(item)) + + setBudgetsState(budgets) + + return budgets + }, + }), +}) diff --git a/apps/mobile/stores/budget/store.ts b/apps/mobile/stores/budget/store.ts new file mode 100644 index 00000000..6762dcea --- /dev/null +++ b/apps/mobile/stores/budget/store.ts @@ -0,0 +1,35 @@ +import type { BudgetWithRelations } from '@6pm/validation' +import AsyncStorage from '@react-native-async-storage/async-storage' +import { create } from 'zustand' +import { createJSONStorage, persist } from 'zustand/middleware' + +interface BudgetStore { + budgets: BudgetWithRelations[] + setBudgets: (budgets: BudgetWithRelations[]) => void + updateBudget: (budget: BudgetWithRelations) => void +} + +export const useBudgetStore = create()( + persist( + (set) => ({ + budgets: [], + setBudgets: (budgets: BudgetWithRelations[]) => set({ budgets }), + updateBudget: (budget: BudgetWithRelations) => + set((state) => { + const index = state.budgets.findIndex((c) => c.id === budget.id) + if (index === -1) { + return { + budgets: [...state.budgets, budget], + } + } + + state.budgets[index] = budget + return { budgets: state.budgets } + }), + }), + { + name: 'budget-storage', + storage: createJSONStorage(() => AsyncStorage), + }, + ), +) diff --git a/packages/validation/src/budget.zod.ts b/packages/validation/src/budget.zod.ts index 943810a7..5feb841d 100644 --- a/packages/validation/src/budget.zod.ts +++ b/packages/validation/src/budget.zod.ts @@ -3,17 +3,24 @@ import { BudgetPeriodTypeSchema, BudgetTypeSchema } from './prisma' export const zCreateBudget = z.object({ id: z.string().cuid2().optional(), - name: z.string(), + name: z.string().min(1, 'Budget name is required'), description: z.string().optional(), preferredCurrency: z.string(), type: BudgetTypeSchema, inviteeEmails: z.array(z.string().email()).optional(), - period: z.object({ - type: BudgetPeriodTypeSchema, - amount: z.number().min(0), - startDate: z.date().optional(), - endDate: z.date().optional(), - }), + period: z + .object({ + type: BudgetPeriodTypeSchema, + amount: z.number({ coerce: true }).min(0), + startDate: z.date({ coerce: true }).optional(), + endDate: z.date({ coerce: true }).optional(), + }) + .refine(({ type, startDate, endDate }) => { + if (type === 'CUSTOM') { + return !!startDate && !!endDate + } + return true + }, 'Select period range'), }) export type CreateBudget = z.infer @@ -22,11 +29,21 @@ export const zUpdateBudget = z.object({ description: z.string().optional(), preferredCurrency: z.string().optional(), type: BudgetTypeSchema, - period: z.object({ - type: BudgetPeriodTypeSchema.optional(), - amount: z.number().min(0).optional(), - startDate: z.date().optional(), - endDate: z.date().optional(), - }), + period: z + .object({ + type: BudgetPeriodTypeSchema.optional(), + amount: z.number({ coerce: true }).min(0).optional(), + startDate: z.date({ coerce: true }).optional(), + endDate: z.date({ coerce: true }).optional(), + }) + .refine(({ type, startDate, endDate }) => { + if (type === 'CUSTOM') { + return !!startDate && !!endDate + } + return true + }, 'Select period range'), }) export type UpdateBudget = z.infer + +export const zBudgetFormValues = zCreateBudget +export type BudgetFormValues = z.infer diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index adaabda3..6e4d152a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -165,6 +165,21 @@ importers: '@react-navigation/native': specifier: ^6.0.2 version: 6.1.17(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/dropdown-menu': + specifier: ^1.0.3 + version: 1.0.3(@rn-primitives/portal@1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/portal': + specifier: ^1.0.3 + version: 1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/select': + specifier: ^1.0.3 + version: 1.0.3(@rn-primitives/portal@1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/slot': + specifier: ^1.0.3 + version: 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/types': + specifier: ^1.0.3 + version: 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) '@tanstack/query-async-storage-persister': specifier: ^5.51.1 version: 5.51.1 @@ -224,7 +239,7 @@ importers: version: 15.0.3(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) expo-router: specifier: ~3.5.15 - version: 3.5.16(4mulymdxn7fmzuvb6n5wc7wvuq) + version: 3.5.16(expo-constants@16.0.2(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-linking@6.3.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.10.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-screens@3.31.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)(typescript@5.3.3) expo-secure-store: specifier: ^13.0.1 version: 13.0.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) @@ -1113,7 +1128,7 @@ packages: '@backpackapp-io/react-native-toast@0.11.0': resolution: {integrity: sha512-ZRVYQPK6QOvt6vP1bF0I5oBpN5pnssdrX1JLV+KHPyxXWSNNvl1oo0qdJ5uzM7zj2TxMMUBPIsMofFeLA8E/dw==} peerDependencies: - react: '*' + react: 18.2.0 react-native: '*' react-native-gesture-handler: '>=2.2.1' react-native-reanimated: '>=2.8.0' @@ -1551,7 +1566,7 @@ packages: peerDependencies: '@types/react': '*' '@types/react-native': '*' - react: '*' + react: 18.2.0 react-native: '*' react-native-gesture-handler: '>=1.10.1' react-native-reanimated: '>=2.2.0' @@ -1873,9 +1888,28 @@ packages: '@prisma/get-platform@5.16.0': resolution: {integrity: sha512-ynp2jAYfYdd7OObX+uWaFRpvhPVmpF0nsRMhbrWdVVUj39q3Zr8dGz5WDj2g+BTUE++u1T1Am3RyM3PBQdDZXA==} + '@radix-ui/number@1.1.0': + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + '@radix-ui/primitive@1.0.1': resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-arrow@1.1.0': + resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.0.3': resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} peerDependencies: @@ -1889,6 +1923,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-collection@1.1.0': + resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-compose-refs@1.0.0': resolution: {integrity: sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==} peerDependencies: @@ -1903,6 +1950,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-context@1.0.1': resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: @@ -1912,6 +1968,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-direction@1.0.1': resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} peerDependencies: @@ -1921,6 +1986,63 @@ packages: '@types/react': optional: true + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.1': + resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-id@1.0.1': resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: @@ -1930,6 +2052,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-label@2.0.2': resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} peerDependencies: @@ -1943,6 +2074,45 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-menu@2.1.1': + resolution: {integrity: sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.0': + resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-presence@1.0.1': resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: @@ -1956,6 +2126,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-primitive@1.0.3': resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: @@ -1969,6 +2152,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-roving-focus@1.0.4': resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} peerDependencies: @@ -1982,6 +2178,32 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-roving-focus@1.1.0': + resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.1.1': + resolution: {integrity: sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.0.1': resolution: {integrity: sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==} peerDependencies: @@ -1996,6 +2218,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-switch@1.0.3': resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} peerDependencies: @@ -2031,6 +2262,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-controllable-state@1.0.1': resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: @@ -2040,6 +2280,24 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-layout-effect@1.0.1': resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} peerDependencies: @@ -2049,6 +2307,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-previous@1.0.1': resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} peerDependencies: @@ -2058,6 +2325,24 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-previous@1.1.0': + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.0': + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-size@1.0.1': resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} peerDependencies: @@ -2067,6 +2352,31 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.1.0': + resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.0': + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + '@react-native-async-storage/async-storage@1.23.1': resolution: {integrity: sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==} peerDependencies: @@ -2203,7 +2513,7 @@ packages: resolution: {integrity: sha512-plhc8UvCZs0UkV+sI+3bisIyn78wz9O/BiWZXpounu72k/R/Sj5PuZYFJ1fi6psvriUveMCGh4LeZckAZu2qiQ==} peerDependencies: '@react-navigation/native': ^6.0.0 - react: '*' + react: 18.2.0 react-native: '*' react-native-safe-area-context: '>= 3.0.0' @@ -2219,7 +2529,7 @@ packages: '@react-navigation/native@6.1.17': resolution: {integrity: sha512-mer3OvfwWOHoUSMJyLa4vnBH3zpFmCwuzrBPlw7feXklurr/ZDiLjLxUScOot6jLRMz/67GyilEYMmP99LL0RQ==} peerDependencies: - react: '*' + react: 18.2.0 react-native: '*' '@react-navigation/routers@6.1.9': @@ -2263,6 +2573,92 @@ packages: '@remix-run/web-stream@1.1.0': resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==} + '@rn-primitives/dropdown-menu@1.0.3': + resolution: {integrity: sha512-EztM59jiJ0d5GZQntnoOo1G67Jh3NXYXBsQBEIQdz3kSxRxT4G68ciF0g8Qiw1s7wnxlvhXB96cI970OWKgKuw==} + peerDependencies: + '@rn-primitives/portal': '*' + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/hooks@1.0.3': + resolution: {integrity: sha512-3aI1upO2OteR+tDSqNx9kDxBmJ1xVOs+ziuFjQZxHEWB05AyB7JrGh7uUTJVcfgHmu8yBItYydBIiYgg95rz+Q==} + peerDependencies: + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/portal@1.0.3': + resolution: {integrity: sha512-7WtNh6HVyg/3F9PlSXHb/KcNAxKfCgIn7XXMu0bC8yv3K8hQZ0CZZ16XVJ7OAzJq5MyPbYLX341HHUPgg/TQ+g==} + peerDependencies: + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/select@1.0.3': + resolution: {integrity: sha512-KRMvIpZHj7yQAso0Mgli3CS9MLCarIcYX1wEyrq83eH0lwlmL1xf7xWYviy8NYNNV+L+uDOjN7JY+LUNhoNong==} + peerDependencies: + '@rn-primitives/portal': '*' + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/slot@1.0.3': + resolution: {integrity: sha512-sSDYwD2upLQUOva2cmNfaJqZlN+o0E/wa8uXEDEIYj6MJsG/O0k1t0jGXMqLP8BsQ3ZaTtUbqnG9eW/VQFOmdQ==} + peerDependencies: + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/types@1.0.3': + resolution: {integrity: sha512-5GY4J6SBN2JosYS/8bvQZOZL+HZk85COaFlNnjiL3efoa9gH+v1dNi0F2gW/Gr0PuGF/xo/z0iOiVc5KrDsAkQ==} + peerDependencies: + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + + '@rn-primitives/utils@1.0.3': + resolution: {integrity: sha512-iOIBrr0qV5Crb5FZhJWEEH85RZ9QaOCubPYs2oNp5hbJCyLVGPC56ltdn2hVFwJ7NK6DE1qsjMintDp36a1i5g==} + peerDependencies: + react: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native: + optional: true + react-native-web: + optional: true + '@rnx-kit/chromium-edge-launcher@1.0.0': resolution: {integrity: sha512-lzD84av1ZQhYUS+jsGqJiCMaJO2dn9u+RTT9n9q6D3SaKVwWqv+7AoRKqBu19bkwyE+iFRl1ymr40QS90jVFYg==} engines: {node: '>=14.15'} @@ -2572,6 +2968,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -3274,6 +3674,9 @@ packages: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -3781,6 +4184,10 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -5598,10 +6005,40 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-shallow-renderer@16.15.0: resolution: {integrity: sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==} peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true react-test-renderer@18.2.0: resolution: {integrity: sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==} @@ -6455,11 +6892,31 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-latest-callback@0.1.9: resolution: {integrity: sha512-CL/29uS74AwreI/f2oz2hLTW7ZqVeV5+gxFeGudzQrgkCytrHw33G4KbnQOrRlAEzzAFXi7dDLMC9zhWcVpzmw==} peerDependencies: react: '>=16.8' + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -8845,10 +9302,23 @@ snapshots: dependencies: '@prisma/debug': 5.16.0 + '@radix-ui/number@1.1.0': {} + '@radix-ui/primitive@1.0.1': dependencies: '@babel/runtime': 7.24.7 + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8862,6 +9332,18 @@ snapshots: '@types/react': 18.2.79 '@types/react-dom': 18.3.0 + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-compose-refs@1.0.0(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8874,6 +9356,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-compose-refs@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-context@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8881,6 +9369,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-context@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-direction@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8888,6 +9382,57 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-direction@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + + '@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-focus-guards@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + + '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-id@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8896,6 +9441,13 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-id@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8906,6 +9458,60 @@ snapshots: '@types/react': 18.2.79 '@types/react-dom': 18.3.0 + '@radix-ui/react-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.2.79)(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8917,6 +9523,16 @@ snapshots: '@types/react': 18.2.79 '@types/react-dom': 18.3.0 + '@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8927,6 +9543,15 @@ snapshots: '@types/react': 18.2.79 '@types/react-dom': 18.3.0 + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8945,6 +9570,52 @@ snapshots: '@types/react': 18.2.79 '@types/react-dom': 18.3.0 + '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-select@2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.2.79)(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + '@radix-ui/react-slot@1.0.1(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8959,6 +9630,13 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-slot@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-switch@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -8999,6 +9677,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -9007,6 +9691,20 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -9014,6 +9712,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-use-previous@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -9021,6 +9725,19 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-use-previous@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + + '@radix-ui/react-use-rect@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + '@radix-ui/react-use-size@1.0.1(@types/react@18.2.79)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -9029,6 +9746,24 @@ snapshots: optionalDependencies: '@types/react': 18.2.79 + '@radix-ui/react-use-size@1.1.0(@types/react@18.2.79)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.2.79 + + '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.3.0 + + '@radix-ui/rect@1.1.0': {} + '@react-native-async-storage/async-storage@1.23.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))': dependencies: merge-options: 3.0.4 @@ -9437,6 +10172,79 @@ snapshots: dependencies: web-streams-polyfill: 3.3.3 + '@rn-primitives/dropdown-menu@1.0.3(@rn-primitives/portal@1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-dropdown-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rn-primitives/hooks': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/portal': 1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/slot': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/types': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/utils': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - react-dom + + '@rn-primitives/hooks@1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + '@rn-primitives/types': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@rn-primitives/portal@1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + zustand: 4.5.4(@types/react@18.2.79)(react@18.3.1) + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - immer + + '@rn-primitives/select@1.0.3(@rn-primitives/portal@1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-select': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rn-primitives/hooks': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/portal': 1.0.3(@types/react@18.2.79)(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/slot': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + '@rn-primitives/types': 1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - react-dom + + '@rn-primitives/slot@1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@rn-primitives/types@1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@rn-primitives/utils@1.0.3(react-native-web@0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + react-native: 0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1) + react-native-web: 0.19.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rnx-kit/chromium-edge-launcher@1.0.0': dependencies: '@types/node': 18.11.18 @@ -9757,6 +10565,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.3 + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -10513,6 +11325,8 @@ snapshots: detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + didyoumean@1.2.2: {} diff-sequences@29.6.3: {} @@ -10858,8 +11672,8 @@ snapshots: dependencies: invariant: 2.2.4 - expo-router@3.5.16(4mulymdxn7fmzuvb6n5wc7wvuq): - dependencies: + ? expo-router@3.5.16(expo-constants@16.0.2(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-linking@6.3.1(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.14(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.10.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-screens@3.31.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)(typescript@5.3.3) + : dependencies: '@expo/metro-runtime': 3.2.1(react-native@0.74.2(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.3.1)) '@expo/server': 0.4.3(typescript@5.3.3) '@radix-ui/react-slot': 1.0.1(react@18.3.1) @@ -11143,6 +11957,8 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-nonce@1.0.1: {} + get-package-type@0.1.0: {} get-port@3.2.0: {} @@ -13293,12 +14109,40 @@ snapshots: react-refresh@0.14.2: {} + react-remove-scroll-bar@2.3.6(@types/react@18.2.79)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.1(@types/react@18.2.79)(react@18.3.1) + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.2.79 + + react-remove-scroll@2.5.7(@types/react@18.2.79)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.2.79)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.2.79)(react@18.3.1) + tslib: 2.6.3 + use-callback-ref: 1.3.2(@types/react@18.2.79)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.2.79)(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.79 + react-shallow-renderer@16.15.0(react@18.3.1): dependencies: object-assign: 4.1.1 react: 18.3.1 react-is: 18.3.1 + react-style-singleton@2.2.1(@types/react@18.2.79)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.2.79 + react-test-renderer@18.2.0(react@18.3.1): dependencies: react: 18.3.1 @@ -14172,10 +15016,25 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + use-callback-ref@1.3.2(@types/react@18.2.79)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.2.79 + use-latest-callback@0.1.9(react@18.3.1): dependencies: react: 18.3.1 + use-sidecar@1.1.2(@types/react@18.2.79)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.2.79 + use-sync-external-store@1.2.0(react@18.3.1): dependencies: react: 18.3.1