diff --git a/mobile/App.tsx b/mobile/App.tsx
deleted file mode 100644
index c06081d..0000000
--- a/mobile/App.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import "@/global.css";
-
-import { StatusBar } from "expo-status-bar";
-import { Box } from "./components/ui/box";
-import { Button, ButtonText } from "./components/ui/button";
-import { Pressable } from "./components/ui/pressable";
-import { Text } from "./components/ui/text";
-import { GluestackUIProvider } from "./components/ui/gluestack-ui-provider";
-
-export default function App() {
- return (
-
- {/* SafeAreaView 역할을 하는 Box 컴포넌트 */}
-
-
- ✨ Welcome to My App!
- Gluestack UI와 NativeWind 설정이 완료되었습니다.
-
-
-
-
- 더 알아보기
-
-
-
-
-
- );
-}
diff --git a/mobile/app/(tabs)/_layout.tsx b/mobile/app/(tabs)/_layout.tsx
new file mode 100644
index 0000000..6d635ef
--- /dev/null
+++ b/mobile/app/(tabs)/_layout.tsx
@@ -0,0 +1,68 @@
+import { Tabs } from "expo-router";
+import { Ionicons } from "@expo/vector-icons";
+
+export default function TabsLayout() {
+ return (
+
+ (
+
+ ),
+ }}
+ />
+ (
+
+ ),
+ }}
+ />
+ (
+
+ ),
+ }}
+ />
+
+ );
+}
diff --git a/mobile/app/(tabs)/history.tsx b/mobile/app/(tabs)/history.tsx
new file mode 100644
index 0000000..60bffbe
--- /dev/null
+++ b/mobile/app/(tabs)/history.tsx
@@ -0,0 +1,14 @@
+import { VStack } from "@/components/ui/vstack";
+import { Text } from "@/components/ui/text";
+import { View } from "react-native";
+
+export default function HistoryTab() {
+ return (
+
+
+ History 탭
+ 최근 기록이 여기에 표시됩니다.
+
+
+ );
+}
diff --git a/mobile/app/(tabs)/index.tsx b/mobile/app/(tabs)/index.tsx
new file mode 100644
index 0000000..c85e436
--- /dev/null
+++ b/mobile/app/(tabs)/index.tsx
@@ -0,0 +1,18 @@
+import { Input, InputField } from "@/components/ui/input";
+import { Text } from "@/components/ui/text";
+import { VStack } from "@/components/ui/vstack";
+import { Link } from "expo-router";
+import { View } from "react-native";
+
+export default function HomeTab() {
+ return (
+
+
+ Home 탭
+
+
+
+
+
+ );
+}
diff --git a/mobile/app/(tabs)/settings.tsx b/mobile/app/(tabs)/settings.tsx
new file mode 100644
index 0000000..1b6f055
--- /dev/null
+++ b/mobile/app/(tabs)/settings.tsx
@@ -0,0 +1,13 @@
+import { VStack } from "@/components/ui/vstack";
+import { Text } from "@/components/ui/text";
+import { View } from "react-native";
+
+export default function SettingsTab() {
+ return (
+
+
+ Settings 탭
+
+
+ );
+}
diff --git a/mobile/app/_layout.tsx b/mobile/app/_layout.tsx
new file mode 100644
index 0000000..a6d632a
--- /dev/null
+++ b/mobile/app/_layout.tsx
@@ -0,0 +1,17 @@
+import "@/global.css";
+
+import { GluestackUIProvider } from "@/components/ui/gluestack-ui-provider";
+import { StatusBar } from "expo-status-bar";
+import { Stack } from "expo-router";
+import { SafeAreaView } from "react-native-safe-area-context";
+
+export default function RootLayout() {
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/mobile/components/ui/input/index.tsx b/mobile/components/ui/input/index.tsx
new file mode 100644
index 0000000..03d46eb
--- /dev/null
+++ b/mobile/components/ui/input/index.tsx
@@ -0,0 +1,217 @@
+'use client';
+import React from 'react';
+import { createInput } from '@gluestack-ui/core/input/creator';
+import { View, Pressable, TextInput } from 'react-native';
+import { tva } from '@gluestack-ui/utils/nativewind-utils';
+import {
+ withStyleContext,
+ useStyleContext,
+} from '@gluestack-ui/utils/nativewind-utils';
+import { cssInterop } from 'nativewind';
+import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
+import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
+
+const SCOPE = 'INPUT';
+
+const UIInput = createInput({
+ Root: withStyleContext(View, SCOPE),
+ Icon: UIIcon,
+ Slot: Pressable,
+ Input: TextInput,
+});
+
+cssInterop(PrimitiveIcon, {
+ className: {
+ target: 'style',
+ nativeStyleToProp: {
+ height: true,
+ width: true,
+ fill: true,
+ color: 'classNameColor',
+ stroke: true,
+ },
+ },
+});
+
+const inputStyle = tva({
+ base: 'border-background-300 flex-row overflow-hidden content-center data-[hover=true]:border-outline-400 data-[focus=true]:border-primary-700 data-[focus=true]:hover:border-primary-700 data-[disabled=true]:opacity-40 data-[disabled=true]:hover:border-background-300 items-center',
+
+ variants: {
+ size: {
+ xl: 'h-12',
+ lg: 'h-11',
+ md: 'h-10',
+ sm: 'h-9',
+ },
+
+ variant: {
+ underlined:
+ 'rounded-none border-b data-[invalid=true]:border-b-2 data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700',
+
+ outline:
+ 'rounded border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
+
+ rounded:
+ 'rounded-full border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
+ },
+ },
+});
+
+const inputIconStyle = tva({
+ base: 'justify-center items-center text-typography-400 fill-none',
+ parentVariants: {
+ size: {
+ '2xs': 'h-3 w-3',
+ 'xs': 'h-3.5 w-3.5',
+ 'sm': 'h-4 w-4',
+ 'md': 'h-[18px] w-[18px]',
+ 'lg': 'h-5 w-5',
+ 'xl': 'h-6 w-6',
+ },
+ },
+});
+
+const inputSlotStyle = tva({
+ base: 'justify-center items-center web:disabled:cursor-not-allowed',
+});
+
+const inputFieldStyle = tva({
+ base: 'flex-1 text-typography-900 py-0 px-3 placeholder:text-typography-500 h-full ios:leading-[0px] web:cursor-text web:data-[disabled=true]:cursor-not-allowed',
+
+ parentVariants: {
+ variant: {
+ underlined: 'web:outline-0 web:outline-none px-0',
+ outline: 'web:outline-0 web:outline-none',
+ rounded: 'web:outline-0 web:outline-none px-4',
+ },
+
+ size: {
+ '2xs': 'text-2xs',
+ 'xs': 'text-xs',
+ 'sm': 'text-sm',
+ 'md': 'text-base',
+ 'lg': 'text-lg',
+ 'xl': 'text-xl',
+ '2xl': 'text-2xl',
+ '3xl': 'text-3xl',
+ '4xl': 'text-4xl',
+ '5xl': 'text-5xl',
+ '6xl': 'text-6xl',
+ },
+ },
+});
+
+type IInputProps = React.ComponentProps &
+ VariantProps & { className?: string };
+const Input = React.forwardRef, IInputProps>(
+ function Input(
+ { className, variant = 'outline', size = 'md', ...props },
+ ref
+ ) {
+ return (
+
+ );
+ }
+);
+
+type IInputIconProps = React.ComponentProps &
+ VariantProps & {
+ className?: string;
+ height?: number;
+ width?: number;
+ };
+
+const InputIcon = React.forwardRef<
+ React.ComponentRef,
+ IInputIconProps
+>(function InputIcon({ className, size, ...props }, ref) {
+ const { size: parentSize } = useStyleContext(SCOPE);
+
+ if (typeof size === 'number') {
+ return (
+
+ );
+ } else if (
+ (props.height !== undefined || props.width !== undefined) &&
+ size === undefined
+ ) {
+ return (
+
+ );
+ }
+ return (
+
+ );
+});
+
+type IInputSlotProps = React.ComponentProps &
+ VariantProps & { className?: string };
+
+const InputSlot = React.forwardRef<
+ React.ComponentRef,
+ IInputSlotProps
+>(function InputSlot({ className, ...props }, ref) {
+ return (
+
+ );
+});
+
+type IInputFieldProps = React.ComponentProps &
+ VariantProps & { className?: string };
+
+const InputField = React.forwardRef<
+ React.ComponentRef,
+ IInputFieldProps
+>(function InputField({ className, ...props }, ref) {
+ const { variant: parentVariant, size: parentSize } = useStyleContext(SCOPE);
+
+ return (
+
+ );
+});
+
+Input.displayName = 'Input';
+InputIcon.displayName = 'InputIcon';
+InputSlot.displayName = 'InputSlot';
+InputField.displayName = 'InputField';
+
+export { Input, InputField, InputIcon, InputSlot };
diff --git a/mobile/components/ui/vstack/index.tsx b/mobile/components/ui/vstack/index.tsx
new file mode 100644
index 0000000..76e4210
--- /dev/null
+++ b/mobile/components/ui/vstack/index.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
+import { View } from 'react-native';
+
+import { vstackStyle } from './styles';
+
+type IVStackProps = React.ComponentProps &
+ VariantProps;
+
+const VStack = React.forwardRef, IVStackProps>(
+ function VStack({ className, space, reversed, ...props }, ref) {
+ return (
+
+ );
+ }
+);
+
+VStack.displayName = 'VStack';
+
+export { VStack };
diff --git a/mobile/components/ui/vstack/index.web.tsx b/mobile/components/ui/vstack/index.web.tsx
new file mode 100644
index 0000000..2389e1f
--- /dev/null
+++ b/mobile/components/ui/vstack/index.web.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
+
+import { vstackStyle } from './styles';
+
+type IVStackProps = React.ComponentProps<'div'> &
+ VariantProps;
+
+const VStack = React.forwardRef, IVStackProps>(
+ function VStack({ className, space, reversed, ...props }, ref) {
+ return (
+
+ );
+ }
+);
+
+VStack.displayName = 'VStack';
+
+export { VStack };
diff --git a/mobile/components/ui/vstack/styles.tsx b/mobile/components/ui/vstack/styles.tsx
new file mode 100644
index 0000000..83a08cc
--- /dev/null
+++ b/mobile/components/ui/vstack/styles.tsx
@@ -0,0 +1,25 @@
+import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
+import { tva } from '@gluestack-ui/utils/nativewind-utils';
+
+const baseStyle = isWeb
+ ? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
+ : '';
+
+export const vstackStyle = tva({
+ base: `flex-col ${baseStyle}`,
+ variants: {
+ space: {
+ 'xs': 'gap-1',
+ 'sm': 'gap-2',
+ 'md': 'gap-3',
+ 'lg': 'gap-4',
+ 'xl': 'gap-5',
+ '2xl': 'gap-6',
+ '3xl': 'gap-7',
+ '4xl': 'gap-8',
+ },
+ reversed: {
+ true: 'flex-col-reverse',
+ },
+ },
+});
diff --git a/mobile/index.ts b/mobile/index.ts
index 1d6e981..3ae48c6 100644
--- a/mobile/index.ts
+++ b/mobile/index.ts
@@ -1,8 +1,8 @@
-import { registerRootComponent } from 'expo';
+// import { registerRootComponent } from 'expo';
-import App from './App';
+// import App from './App';
-// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
-// It also ensures that whether you load the app in Expo Go or in a native build,
-// the environment is set up appropriately
-registerRootComponent(App);
+// // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
+// // It also ensures that whether you load the app in Expo Go or in a native build,
+// // the environment is set up appropriately
+// registerRootComponent(App);
diff --git a/mobile/package-lock.json b/mobile/package-lock.json
index bdf6239..92134af 100644
--- a/mobile/package-lock.json
+++ b/mobile/package-lock.json
@@ -9,11 +9,14 @@
"version": "1.0.0",
"dependencies": {
"@expo/html-elements": "^0.10.1",
+ "@expo/vector-icons": "^15.0.2",
"@gluestack-ui/core": "^3.0.0",
"@gluestack-ui/utils": "^3.0.0",
"@legendapp/motion": "^2.3.0",
"babel-plugin-module-resolver": "^5.0.2",
"expo": "~53.0.22",
+ "expo-linking": "^7.1.7",
+ "expo-router": "^5.1.4",
"expo-status-bar": "~2.2.3",
"nativewind": "^4.1.23",
"react": "19.0.0",
@@ -21,7 +24,8 @@
"react-dom": "^19.1.1",
"react-native": "0.79.6",
"react-native-reanimated": "^4.1.0",
- "react-native-safe-area-context": "^4.11.0",
+ "react-native-safe-area-context": "^4.14.1",
+ "react-native-screens": "^4.15.4",
"react-native-svg": "^15.2.0",
"react-native-worklets": "^0.5.0",
"react-native-worklets-core": "^1.6.2",
@@ -1862,6 +1866,15 @@
"resolve-from": "^5.0.0"
}
},
+ "node_modules/@expo/metro-runtime": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-5.0.4.tgz",
+ "integrity": "sha512-r694MeO+7Vi8IwOsDIDzH/Q5RPMt1kUDYbiTJwnO15nIqiDwlE8HU55UlRhffKZy6s5FmxQsZ8HA+T8DqUW8cQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react-native": "*"
+ }
+ },
"node_modules/@expo/osascript": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.2.5.tgz",
@@ -1942,6 +1955,18 @@
"integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==",
"license": "MIT"
},
+ "node_modules/@expo/server": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@expo/server/-/server-0.6.3.tgz",
+ "integrity": "sha512-Ea7NJn9Xk1fe4YeJ86rObHSv/bm3u/6WiQPXEqXJ2GrfYpVab2Swoh9/PnSM3KjR64JAgKjArDn1HiPjITCfHA==",
+ "license": "MIT",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "debug": "^4.3.4",
+ "source-map-support": "~0.5.21",
+ "undici": "^6.18.2 || ^7.0.0"
+ }
+ },
"node_modules/@expo/spawn-async": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz",
@@ -1961,12 +1986,12 @@
"license": "MIT"
},
"node_modules/@expo/vector-icons": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.1.0.tgz",
- "integrity": "sha512-7T09UE9h8QDTsUeMGymB4i+iqvtEeaO5VvUjryFB4tugDTG/bkzViWA74hm5pfjjDEhYMXWaX112mcvhccmIwQ==",
+ "version": "15.0.2",
+ "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.2.tgz",
+ "integrity": "sha512-IiBjg7ZikueuHNf40wSGCf0zS73a3guJLdZzKnDUxsauB8VWPLMeWnRIupc+7cFhLUkqyvyo0jLNlcxG5xPOuQ==",
"license": "MIT",
"peerDependencies": {
- "expo-font": "*",
+ "expo-font": ">=14.0.4",
"react": "*",
"react-native": "*"
}
@@ -2595,6 +2620,39 @@
"node": ">=14"
}
},
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
+ "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@react-aria/breadcrumbs": {
"version": "3.5.28",
"resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.28.tgz",
@@ -3801,6 +3859,113 @@
"react-native": "*"
}
},
+ "node_modules/@react-navigation/bottom-tabs": {
+ "version": "7.4.7",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.4.7.tgz",
+ "integrity": "sha512-SQ4KuYV9yr3SV/thefpLWhAD0CU2CrBMG1l0w/QKl3GYuGWdN5OQmdQdmaPZGtsjjVOb+N9Qo7Tf6210P4TlpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.6.4",
+ "color": "^4.2.3"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.17",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
+ "node_modules/@react-navigation/core": {
+ "version": "7.12.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.12.4.tgz",
+ "integrity": "sha512-xLFho76FA7v500XID5z/8YfGTvjQPw7/fXsq4BIrVSqetNe/o/v+KAocEw4ots6kyv3XvSTyiWKh2g3pN6xZ9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/routers": "^7.5.1",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.3.11",
+ "query-string": "^7.1.3",
+ "react-is": "^19.1.0",
+ "use-latest-callback": "^0.2.4",
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "react": ">= 18.2.0"
+ }
+ },
+ "node_modules/@react-navigation/core/node_modules/react-is": {
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz",
+ "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==",
+ "license": "MIT"
+ },
+ "node_modules/@react-navigation/elements": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.6.4.tgz",
+ "integrity": "sha512-O3X9vWXOEhAO56zkQS7KaDzL8BvjlwZ0LGSteKpt1/k6w6HONG+2Wkblrb057iKmehTkEkQMzMLkXiuLmN5x9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "color": "^4.2.3",
+ "use-latest-callback": "^0.2.4",
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "@react-native-masked-view/masked-view": ">= 0.2.0",
+ "@react-navigation/native": "^7.1.17",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-masked-view/masked-view": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-navigation/native": {
+ "version": "7.1.17",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.17.tgz",
+ "integrity": "sha512-uEcYWi1NV+2Qe1oELfp9b5hTYekqWATv2cuwcOAg5EvsIsUPtzFrKIasgUXLBRGb9P7yR5ifoJ+ug4u6jdqSTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/core": "^7.12.4",
+ "escape-string-regexp": "^4.0.0",
+ "fast-deep-equal": "^3.1.3",
+ "nanoid": "^3.3.11",
+ "use-latest-callback": "^0.2.4"
+ },
+ "peerDependencies": {
+ "react": ">= 18.2.0",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@react-navigation/native-stack": {
+ "version": "7.3.26",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.3.26.tgz",
+ "integrity": "sha512-EjaBWzLZ76HJGOOcWCFf+h/M+Zg7M1RalYioDOb6ZdXHz7AwYNidruT3OUAQgSzg3gVLqvu5OYO0jFsNDPCZxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.6.4",
+ "warn-once": "^0.1.1"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.17",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
+ "node_modules/@react-navigation/routers": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.1.tgz",
+ "integrity": "sha512-pxipMW/iEBSUrjxz2cDD7fNwkqR4xoi0E/PcfTQGCcdJwLoaxzab5kSadBLj1MTJyT0YRrOXL9umHpXtp+Dv4w==",
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11"
+ }
+ },
"node_modules/@react-stately/calendar": {
"version": "3.8.4",
"resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.8.4.tgz",
@@ -4654,6 +4819,12 @@
"@types/istanbul-lib-report": "*"
}
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "24.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
@@ -4783,6 +4954,51 @@
"node": ">= 14"
}
},
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
"node_modules/anser": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
@@ -5557,6 +5773,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -5621,6 +5843,19 @@
"node": ">=6"
}
},
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -5639,6 +5874,16 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
"node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@@ -5930,6 +6175,15 @@
"integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"license": "MIT"
},
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -6350,6 +6604,20 @@
"react": "*"
}
},
+ "node_modules/expo-linking": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-7.1.7.tgz",
+ "integrity": "sha512-ZJaH1RIch2G/M3hx2QJdlrKbYFUTOjVVW4g39hfxrE5bPX9xhZUYXqxqQtzMNl1ylAevw9JkgEfWbBWddbZ3UA==",
+ "license": "MIT",
+ "dependencies": {
+ "expo-constants": "~17.1.7",
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/expo-modules-autolinking": {
"version": "2.1.14",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.1.14.tgz",
@@ -6377,6 +6645,60 @@
"invariant": "^2.2.4"
}
},
+ "node_modules/expo-router": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-5.1.4.tgz",
+ "integrity": "sha512-8GulCelVN9x+VSOio74K1ZYTG6VyCdJw417gV+M/J8xJOZZTA7rFxAdzujBZZ7jd6aIAG7WEwOUU3oSvUO76Vw==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/metro-runtime": "5.0.4",
+ "@expo/server": "^0.6.3",
+ "@radix-ui/react-slot": "1.2.0",
+ "@react-navigation/bottom-tabs": "^7.3.10",
+ "@react-navigation/native": "^7.1.6",
+ "@react-navigation/native-stack": "^7.3.10",
+ "client-only": "^0.0.1",
+ "invariant": "^2.2.4",
+ "react-fast-compare": "^3.2.2",
+ "react-native-is-edge-to-edge": "^1.1.6",
+ "schema-utils": "^4.0.1",
+ "semver": "~7.6.3",
+ "server-only": "^0.0.1",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "@react-navigation/drawer": "^7.3.9",
+ "expo": "*",
+ "expo-constants": "*",
+ "expo-linking": "*",
+ "react-native-reanimated": "*",
+ "react-native-safe-area-context": "*",
+ "react-native-screens": "*"
+ },
+ "peerDependenciesMeta": {
+ "@react-navigation/drawer": {
+ "optional": true
+ },
+ "@testing-library/jest-native": {
+ "optional": true
+ },
+ "react-native-reanimated": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/expo-status-bar": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.2.3.tgz",
@@ -6391,12 +6713,29 @@
"react-native": "*"
}
},
+ "node_modules/expo/node_modules/@expo/vector-icons": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.1.0.tgz",
+ "integrity": "sha512-7T09UE9h8QDTsUeMGymB4i+iqvtEeaO5VvUjryFB4tugDTG/bkzViWA74hm5pfjjDEhYMXWaX112mcvhccmIwQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo-font": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/exponential-backoff": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz",
"integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==",
"license": "Apache-2.0"
},
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -6431,6 +6770,22 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"license": "MIT"
},
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/fastq": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
@@ -6461,6 +6816,15 @@
"node": ">=8"
}
},
+ "node_modules/filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -7281,6 +7645,12 @@
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"license": "MIT"
},
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -9066,6 +9436,24 @@
"qrcode-terminal": "bin/qrcode-terminal.js"
}
},
+ "node_modules/query-string": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
+ "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
+ "license": "MIT",
+ "dependencies": {
+ "decode-uri-component": "^0.2.2",
+ "filter-obj": "^1.1.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/queue": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
@@ -9226,6 +9614,24 @@
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"license": "MIT"
},
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-freeze": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
+ "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=17.0.0"
+ }
+ },
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@@ -9383,15 +9789,30 @@
}
},
"node_modules/react-native-safe-area-context": {
- "version": "4.11.0",
- "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.11.0.tgz",
- "integrity": "sha512-Bg7bozxEB+ZS+H3tVYs5yY1cvxNXgR6nRQwpSMkYR9IN5CbxohLnSprrOPG/ostTCd4F6iCk0c51pExEhifSKQ==",
+ "version": "4.14.1",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.14.1.tgz",
+ "integrity": "sha512-+tUhT5WBl8nh5+P+chYhAjR470iCByf9z5EYdCEbPaAK3Yfzw+o8VRPnUgmPAKlSccOgQBxx3NOl/Wzckn9ujg==",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
+ "node_modules/react-native-screens": {
+ "version": "4.15.4",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.15.4.tgz",
+ "integrity": "sha512-aKHPDScUbpQiZEG9eZssHdG5jEQs4yiJ8eMx6g81Ex/xU7DZkv3911enzdCb+v4eJE79X8waizY0ZhauZJQmrw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-freeze": "^1.0.0",
+ "react-native-is-edge-to-edge": "^1.2.1",
+ "warn-once": "^0.1.0"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-svg": {
"version": "15.2.0",
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.2.0.tgz",
@@ -9949,6 +10370,25 @@
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==",
"license": "MIT"
},
+ "node_modules/schema-utils": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+ "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -10129,12 +10569,24 @@
"node": ">= 0.8"
}
},
+ "node_modules/server-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
+ "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
+ "license": "MIT"
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -10203,6 +10655,21 @@
"node": ">= 5.10.0"
}
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/simple-swizzle/node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "license": "MIT"
+ },
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -10264,6 +10731,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -10327,6 +10803,15 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/string-hash-64": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz",
@@ -10920,6 +11405,15 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/use-latest-callback": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.4.tgz",
+ "integrity": "sha512-LS2s2n1usUUnDq4oVh1ca6JFX9uSqUncTfAm44WMg0v6TxL7POUTk1B044NH8TeLkFbNajIsgDHcgNpNzZucdg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
"node_modules/use-sync-external-store": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
diff --git a/mobile/package.json b/mobile/package.json
index 7e0a9e2..b47743c 100644
--- a/mobile/package.json
+++ b/mobile/package.json
@@ -1,7 +1,7 @@
{
"name": "mobile",
"version": "1.0.0",
- "main": "index.ts",
+ "main": "expo-router/entry",
"scripts": {
"start": "expo start",
"android": "expo start --android",
@@ -10,11 +10,14 @@
},
"dependencies": {
"@expo/html-elements": "^0.10.1",
+ "@expo/vector-icons": "^15.0.2",
"@gluestack-ui/core": "^3.0.0",
"@gluestack-ui/utils": "^3.0.0",
"@legendapp/motion": "^2.3.0",
"babel-plugin-module-resolver": "^5.0.2",
"expo": "~53.0.22",
+ "expo-linking": "^7.1.7",
+ "expo-router": "^5.1.4",
"expo-status-bar": "~2.2.3",
"nativewind": "^4.1.23",
"react": "19.0.0",
@@ -22,7 +25,8 @@
"react-dom": "^19.1.1",
"react-native": "0.79.6",
"react-native-reanimated": "^4.1.0",
- "react-native-safe-area-context": "^4.11.0",
+ "react-native-safe-area-context": "^4.14.1",
+ "react-native-screens": "^4.15.4",
"react-native-svg": "^15.2.0",
"react-native-worklets": "^0.5.0",
"react-native-worklets-core": "^1.6.2",
diff --git a/mobile/tsconfig.json b/mobile/tsconfig.json
index 2957096..7c03cfa 100644
--- a/mobile/tsconfig.json
+++ b/mobile/tsconfig.json
@@ -2,13 +2,10 @@
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
+ "types": ["nativewind/types"],
"paths": {
- "@/*": [
- "./*"
- ],
- "tailwind.config": [
- "./tailwind.config.js"
- ]
+ "@/*": ["./*"],
+ "tailwind.config": ["./tailwind.config.js"]
}
}
-}
\ No newline at end of file
+}