Browse Source

改成https

main
Mac 4 weeks ago
parent
commit
0fb5fe6c15
  1. 2
      app.json
  2. 5
      app/constants/config.ts
  3. 7
      app/screens/HomeScreen.tsx
  4. 4
      app/screens/LoginScreen.tsx
  5. 164
      app/screens/ProductCard.tsx
  6. 13
      app/screens/ProductDetailScreen.tsx
  7. 8
      app/services/api/addressApi.ts
  8. 108
      app/services/api/apiClient.ts
  9. 10
      app/services/api/cart.ts
  10. 20
      app/services/api/orders.ts
  11. 4
      app/services/api/payApi.ts
  12. 4
      app/services/api/productApi.ts
  13. 12
      app/services/api/setting.ts
  14. 10
      app/services/api/userApi.ts
  15. BIN
      assets/img/banner en (3)_compressed.png
  16. BIN
      assets/img/banner en (4)_compressed.png
  17. BIN
      assets/img/banner en (5)_compressed.png
  18. 12080
      package-lock.json
  19. 6
      package.json
  20. 5176
      yarn.lock

2
app.json

@ -27,6 +27,8 @@
}
},
"android": {
"permissions": ["INTERNET", "ACCESS_NETWORK_STATE"],
"usesCleartextTraffic": true,
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"

5
app/constants/config.ts

@ -1,5 +1,8 @@
// API配置
export const API_BASE_URL = 'http://ec2-13-245-224-109.af-south-1.compute.amazonaws.com:8080/'; // 替换为您的实际API基础URL
const DEV_API_URL = 'https://api.brainnel.com/backend';
const PROD_API_URL = 'https://api.brainnel.com/backend';
export const API_BASE_URL = PROD_API_URL
// 环境变量配置
export const ENV = {

7
app/screens/HomeScreen.tsx

@ -69,16 +69,15 @@ export const HomeScreen = () => {
page: 1,
page_size: 20,
sort_order: "desc",
category_id: null,
sort_by: "default",
language: "en",
});
const [products, setProducts] = useState<Product[]>([]);
const flatListRef = useRef<FlatList>(null);
const data = [
{ imgUrl: require("../../assets/img/banner en (5).png"),add:'TikTokScreen' },
{ imgUrl: require("../../assets/img/banner en (3).png"),add:'MemberIntroduction' },
{ imgUrl: require("../../assets/img/banner en (4).png"),add:'CompanyScreen' },
{ imgUrl: require("../../assets/img/banner en (5)_compressed.png"),add:'TikTokScreen' },
{ imgUrl: require("../../assets/img/banner en (3)_compressed.png"),add:'MemberIntroduction' },
{ imgUrl: require("../../assets/img/banner en (4)_compressed.png"),add:'CompanyScreen' },
];
const getProductData = async () => {

4
app/screens/LoginScreen.tsx

@ -341,8 +341,8 @@ export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
if (res.access_token) {
const token = res.token_type + " " + res.access_token;
await AsyncStorage.setItem("token", token);
const data = await settingApi.postFirstLogin(221);
setSettings(data);
// const data = await settingApi.postFirstLogin(221);
// setSettings(data);
const user = await userApi.getProfile()
setUser(user);
navigation.navigate("MainTabs", { screen: "Home" });

164
app/screens/ProductCard.tsx

@ -286,84 +286,86 @@ const ProductCard: React.FC<ProductCardProps> = ({
<View style={styles.productTit}>
<Text style={styles.productTitText}>{sizeTitle}</Text>
</View>
<ScrollView
style={styles.sizePrice}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
<View style={styles.sizePriceBox}>
{hasImg &&
hasImg.attributes
?.find((item) => item.has_color)
?.list.map((list, index1) => (
<View style={styles.sizePriceBoxItems} key={index1}>
<View style={styles.sizePriceBoxItem}>
<View style={styles.sizePriceBoxItemTextBox}>
{(list?.size ?? 0) > 0 && (
<Text style={styles.selectedNumText}>
x{list?.size}
<View style={{ flex: 1 }}>
<ScrollView
style={styles.sizePrice}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
<View style={styles.sizePriceBox}>
{hasImg &&
hasImg.attributes
?.find((item) => item.has_color)
?.list.map((list, index1) => (
<View style={styles.sizePriceBoxItems} key={index1}>
<View style={styles.sizePriceBoxItem}>
<View style={styles.sizePriceBoxItemTextBox}>
{(list?.size ?? 0) > 0 && (
<Text style={styles.selectedNumText}>
x{list?.size}
</Text>
)}
<Text style={styles.priceText}>
{list.offer_price || price}
</Text>
)}
<Text style={styles.priceText}>
{list.offer_price || price}
<Text
style={styles.sizePriceBoxItemText}
numberOfLines={1}
ellipsizeMode="tail"
>
{list.attributes[0].value}
</Text>
</View>
<Text style={styles.amountText}>
{list?.amount_on_sale}
</Text>
<Text
style={styles.sizePriceBoxItemText}
numberOfLines={1}
ellipsizeMode="tail"
</View>
<View style={styles.sizePriceBoxStepForward}>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"-",
index1,
list.amount_on_sale
)
}
>
{list.attributes[0].value}
</Text>
<Text>-</Text>
</TouchableOpacity>
<TextInput
style={styles.sizePriceBoxStepForwardInput}
value={list.size?.toString() ?? "0"}
keyboardType="numeric"
onChangeText={(text) =>
handleSizeSelect(
list?.attributes[0]?.value,
text,
index1,
list.amount_on_sale
)
}
/>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"+",
index1,
list.amount_on_sale
)
}
>
<Text>+</Text>
</TouchableOpacity>
</View>
<Text style={styles.amountText}>
{list?.amount_on_sale}
</Text>
</View>
<View style={styles.sizePriceBoxStepForward}>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"-",
index1,
list.amount_on_sale
)
}
>
<Text>-</Text>
</TouchableOpacity>
<TextInput
style={styles.sizePriceBoxStepForwardInput}
value={list.size?.toString() ?? "0"}
keyboardType="numeric"
onChangeText={(text) =>
handleSizeSelect(
list?.attributes[0]?.value,
text,
index1,
list.amount_on_sale
)
}
/>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"+",
index1,
list.amount_on_sale
)
}
>
<Text>+</Text>
</TouchableOpacity>
</View>
</View>
))}
</View>
</ScrollView>
))}
</View>
</ScrollView>
</View>
</View>
)}
{/* 两个都是文字 */}
@ -397,7 +399,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text>
</View>
<ScrollView
style={styles.sizePrice}
style={[styles.sizePrice, { maxHeight: 200 }]}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
@ -483,7 +485,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text>
</View>
<ScrollView
style={styles.sizePriceBox}
style={[styles.sizePrice, { maxHeight: 200 }]}
showsVerticalScrollIndicator={false}
>
{noImgList &&
@ -565,7 +567,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text>
</View>
<ScrollView
style={styles.sizePriceBox}
style={[styles.sizePrice, { maxHeight: 200 }]}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
@ -846,6 +848,8 @@ const styles = StyleSheet.create({
productBox: {
marginTop: 10,
flex: 1,
display: 'flex',
flexDirection: 'column',
},
productTit: {
flexDirection: "row",
@ -885,11 +889,13 @@ const styles = StyleSheet.create({
height: "100%",
borderRadius: 10,
},
sizePrice: {},
sizePrice: {
flex: 1,
width: '100%',
},
sizePriceBox: {
width: "100%",
height: "100%",
flex: 1,
paddingBottom: 10,
},
sizePriceBoxItem: {
width: "70%",

13
app/screens/ProductDetailScreen.tsx

@ -248,9 +248,12 @@ export const ProductDetailScreen = () => {
};
const getProductDetail = async () => {
if (!route.params?.offer_id) return;
const startTime = Date.now();
console.log('开始时间:', startTime);
setIsLoading(true);
try {
const res = await productApi.getProductDetail(route.params.offer_id);
console.log('API 请求完成');
if (res.skus != null) {
const priceSelectedSku = res.skus.find(
(item) => item.offer_price === route.params.price
@ -294,10 +297,14 @@ export const ProductDetailScreen = () => {
const limitedImageUrls = imageUrls.length > 5 ? imageUrls.slice(0, 5) : imageUrls;
setImageUrls(limitedImageUrls);
setGroupList(list);
console.log('数据处理完成');
} catch (error) {
console.error("Error fetching product details:", error);
} finally {
setIsLoading(false);
const endTime = Date.now();
console.log('结束时间:', endTime);
console.log('总执行时间:', endTime - startTime, '毫秒');
}
};
const getSimilars = () => {
@ -348,11 +355,7 @@ export const ProductDetailScreen = () => {
},
[navigation]
);
useEffect(() => {
if (showBottomSheet) {
console.log(123);
}
}, [showBottomSheet])
return (
<View style={{ flex: 1 }}>
{isLoading ? (

8
app/services/api/addressApi.ts

@ -38,20 +38,20 @@ export interface addressData {
export const addressApi = {
getAddress: () => {
return apiService.get<Address>("/api/addresses");
return apiService.get<Address>("/api/addresses/");
},
postAddress: (data: any) => {
return apiService.post("/api/addresses", data );
return apiService.post("/api/addresses/", data );
},
addressesDefault: () => {
return apiService.get<addressData>("/api/addresses/default/");
},
updateAddress: (data: any) => {
return apiService.put(`/api/addresses/${data.address_id}`, data);
return apiService.put(`/api/addresses/${data.address_id}/`, data);
},
deleteAddress: (address_id: number) => {
return apiService.delete(`/api/addresses/${address_id}`);
return apiService.delete(`/api/addresses/${address_id}/`);
},
};

108
app/services/api/apiClient.ts

@ -11,6 +11,9 @@ import {
DEFAULT_HEADERS,
STORAGE_KEYS,
} from "../../constants/config";
import { Platform } from "react-native";
// import https from 'https';
// import { Platform } from "react-native";
// 定义响应类型接口
export interface ApiResponse<T = any> {
@ -27,6 +30,12 @@ export interface ApiError {
data?: any;
}
// 扩展 AxiosRequestConfig 类型
interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
retry?: number;
retryDelay?: (retryCount: number) => number;
}
// 创建axios实例
const apiClient: AxiosInstance = axios.create({
baseURL: API_BASE_URL,
@ -34,11 +43,26 @@ const apiClient: AxiosInstance = axios.create({
headers: DEFAULT_HEADERS,
});
// if (__DEV__ && Platform.OS === "android") {
// apiClient.defaults.httpsAgent = new https.Agent({ rejectUnauthorized: false });
// }
// 请求拦截器
apiClient.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => {
const fullUrl = `${config.baseURL}${config.url}`;
console.log("完整请求地址:", fullUrl); // 例如: https://api.example.com/api/user
const baseUrl = config.baseURL || '';
let fullUrl = baseUrl + config.url;
if (config.params) {
const params = new URLSearchParams(config.params);
fullUrl += (fullUrl.includes('?') ? '&' : '?') + params.toString();
}
// console.log("环境:", __DEV__ ? "开发环境" : "生产环境");
// console.log("平台:", Platform.OS);
// console.log("请求方法:", config.method);
// console.log("完整URL:", fullUrl);
// console.log("请求头:", config.headers);
// console.log("请求参数:", config.params);
// console.log("请求数据:", config.data);
// 从AsyncStorage获取token
const token = await AsyncStorage.getItem("token");
@ -49,6 +73,7 @@ apiClient.interceptors.request.use(
return config;
},
(error: AxiosError) => {
console.error("请求拦截器错误:", error);
return Promise.reject(error);
}
);
@ -57,19 +82,53 @@ apiClient.interceptors.request.use(
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
// 成功响应处理
// console.log("响应成功:", {
// status: response.status,
// statusText: response.statusText,
// headers: response.headers,
// data: response.data,
// });
return response;
},
async (error: AxiosError<any>) => {
// 错误响应处理
const { response } = error;
const { response, config } = error;
console.error("响应错误:", {
status: response?.status,
statusText: response?.statusText,
data: response?.data,
url: config?.url,
method: config?.method,
message: error.message,
code: error.code,
stack: error.stack,
});
// 处理网络错误
if (!response) {
console.error("网络错误:", {
message: error.message,
code: error.code,
stack: error.stack,
});
// 如果是网络错误,尝试重试
const customConfig = config as CustomAxiosRequestConfig;
if (customConfig && customConfig.retry) {
customConfig.retry -= 1;
if (customConfig.retry > 0) {
const delay = customConfig.retryDelay ? customConfig.retryDelay(customConfig.retry) : 1000;
console.log(`重试请求 (${customConfig.retry}): ${customConfig.url}`);
await new Promise(resolve => setTimeout(resolve, delay));
return apiClient(customConfig);
}
}
}
// 处理401错误 (未授权)
if (response && response.status === 401) {
// 清除存储的token
console.log("未授权错误,清除token");
await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
// 这里可以添加重定向到登录页面的逻辑
// 例如使用事件发射器或全局状态管理
}
// 构建标准化的错误对象
@ -88,7 +147,12 @@ export const apiService = {
// GET请求
async get<T>(url: string, params?: any, config?: any): Promise<T> {
try {
const response = await apiClient.get<T>(url, { params, ...config });
const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.get<T>(url, { params, ...customConfig });
return response.data;
} catch (error) {
throw error;
@ -98,7 +162,12 @@ export const apiService = {
// POST请求
async post<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.post<T>(url, data, config);
const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.post<T>(url, data, customConfig);
return response.data;
} catch (error) {
throw error;
@ -108,7 +177,12 @@ export const apiService = {
// PUT请求
async put<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.put<T>(url, data, config);
const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.put<T>(url, data, customConfig);
return response.data;
} catch (error) {
throw error;
@ -118,7 +192,12 @@ export const apiService = {
// PATCH请求
async patch<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.patch<T>(url, data, config);
const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.patch<T>(url, data, customConfig);
return response.data;
} catch (error) {
throw error;
@ -128,7 +207,12 @@ export const apiService = {
// DELETE请求
async delete<T>(url: string, config?: any): Promise<T> {
try {
const response = await apiClient.delete<T>(url, config);
const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.delete<T>(url, customConfig);
return response.data;
} catch (error) {
throw error;

10
app/services/api/cart.ts

@ -50,23 +50,23 @@ export interface GetCartList {
skus:CartSku[]
}
export const cartApi = (data: AddToCartParams) => {
return apiService.post('/api/cart', data);
return apiService.post('/api/cart/', data);
}
export const getCartList = () => {
return apiService.get<GetCartListResponse>('/api/cart');
return apiService.get<GetCartListResponse>('https://api.brainnel.com/backend/api/cart/');
}
export const updateCartItem = (cart_id:number,data?:{cart_item_id?:number | null,selected:number | null,quantity:number | null}) => {
return apiService.put(`/api/cart/${cart_id}`,data);
return apiService.put(`/api/cart/${cart_id}/`,data);
}
// 批量更新选中状态
export const updateBatchCartSelected = (data?:{cart_id?:number | null,selected:number | null,offer_ids:Array<number> | null}) => {
return apiService.patch(`/api/cart/selected`,data);
return apiService.patch(`/api/cart/selected/`,data);
}
export const deleteCartItem = (cart_id:number,cart_item_id:number) => {
return apiService.delete(`/api/cart/${cart_id}?cart_item_id=${cart_item_id}`);
return apiService.delete(`/api/cart/${cart_id}/?cart_item_id=${cart_item_id}`);
}

20
app/services/api/orders.ts

@ -339,43 +339,43 @@ interface Address {
}
}
export const ordersApi = {
getOrders: (data:OrderPreviewData) => apiService.post<OrderData>("/api/orders/preview",data),
getOrders: (data:OrderPreviewData) => apiService.post<OrderData>("/api/orders/preview/",data),
// 获得价格
freightForwarderAddress: (transport_mode:number | null) =>
apiService.get<AddressDataItem>(`/api/freight_forwarder_address/?transport_mode=${transport_mode}`),
// 获得价格
// 获得价格
calcShippingFee: (data:ShippingFeeData) =>
apiService.post<CartShippingFeeData>(`/api/orders/calc_shipping_fee`,data),
apiService.post<CartShippingFeeData>(`/api/orders/calc_shipping_fee/`,data),
// 获得国内价格
calcDomesticShippingFee: (data:ShippingFeeData) =>
apiService.post<CartShippingFeeData>(`/api/orders/calc_domestic_shipping`,data),
apiService.post<CartShippingFeeData>(`/api/orders/calc_domestic_shipping/`,data),
// 创建订单
createOrder: (data: CreateOrderRequest) =>
apiService.post<Order>('/api/orders/cart', data),
apiService.post<Order>('/api/orders/cart/', data),
// 获取所有订单
getAllOrders: (data:PaginatedOrderRequest) =>
apiService.get<PaginatedOrderResponse>(`/api/orders`,data),
apiService.get<PaginatedOrderResponse>(`/api/orders/`,data),
// 获取订单指定信息
getOrderDetails: (order_id:string) =>
apiService.get<OrderDetailsType>(`/api/orders/${order_id}`),
apiService.get<OrderDetailsType>(`/api/orders/${order_id}/`),
// 删除订单
deleteOrder: (order_id:string) =>
apiService.delete<void>(`/api/orders/${order_id}`),
apiService.delete<void>(`/api/orders/${order_id}/`),
// 修改订单
changeOrder: (order_id:string,status:number) =>
apiService.patch<void>(`/api/orders/${order_id}/status?status=${status}`),
apiService.patch<void>(`/api/orders/${order_id}/status/?status=${status}`),
// 修改物流信息
updateOrderShippingInfo: (order_id:string,data:UpdateOrderShippingInfo) =>
apiService.patch<void>(`/api/orders/${order_id}/shipping`,data),
apiService.patch<void>(`/api/orders/${order_id}/shipping/`,data),
};

4
app/services/api/payApi.ts

@ -33,11 +33,11 @@ export interface PayInfoBody {
export const payApi = {
// 获取当前国家支付方式
getCountryPaymentMethods: () => {
return apiService.get<PaymentMethodsResponse>('/api/payment/country_payment_methods');
return apiService.get<PaymentMethodsResponse>('/api/payment/country_payment_methods/');
},
// 获取支付信息
getPayInfo: (data: PayInfoBody) => {
return apiService.post<PaymentInfoResponse>(`/api/payment/initiate`, data);
return apiService.post<PaymentInfoResponse>(`/api/payment/initiate/`, data);
},
};

4
app/services/api/productApi.ts

@ -175,11 +175,11 @@ export type Products = Product[]
},
// 获取商品详情
getProductDetail: (offer_id: string) => {
return apiService.get<ProductDetailParams>('/api/products/'+offer_id);
return apiService.get<ProductDetailParams>(`/api/products/${offer_id}/`);
},
// 获取相似商品
getSimilarProducts: (offer_id: string) => {
return apiService.get<Similars>('/api/products/'+offer_id+'/similar?limit=5');
return apiService.get<Similars>(`/api/products/${offer_id}/similar/?limit=5`);
}
}

12
app/services/api/setting.ts

@ -42,10 +42,10 @@ export interface FirstLogin {
export const settingApi = {
getCountryList: () => apiService.get<Country[]>('/api/user_settings/countries'),
getCurrencyList: () => apiService.get<string[]>('/api/user_settings/currencies'),
getLanguageList: () => apiService.get<string[]>('/api/user_settings/languages'),
getMySetting: () => apiService.get<MySetting>('/api/user_settings/me'),
postFirstLogin: (country: number) => apiService.post<FirstLogin>(`/api/user_settings/first_login?country=${country}`),
putSetting: (setting: object) => apiService.put<MySetting>('/api/user_settings/me', setting),
getCountryList: () => apiService.get<Country[]>('/api/user_settings/countries/'),
getCurrencyList: () => apiService.get<string[]>('/api/user_settings/currencies/'),
getLanguageList: () => apiService.get<string[]>('/api/user_settings/languages/'),
getMySetting: () => apiService.get<MySetting>('/api/user_settings/me/'),
postFirstLogin: (country: number) => apiService.post<FirstLogin>(`/api/user_settings/first_login/?country=${country}`),
putSetting: (setting: object) => apiService.put<MySetting>('/api/user_settings/me/', setting),
}

10
app/services/api/userApi.ts

@ -84,27 +84,27 @@ export const userApi = {
// 获取用户信息
getProfile: () => {
return apiService.get<User>('/api/users/me');
return apiService.get<User>('/api/users/me/');
},
// 更新用户信息
updateProfile: (data: Partial<User>) => {
return apiService.put<User>('/user/profile', data);
return apiService.put<User>('/user/profile/', data);
},
// 更新用户头像
updateAvatar: (file: FormData) => {
return apiService.upload<{avatar: string}>('/user/avatar', file);
return apiService.upload<{avatar: string}>('/user/avatar/', file);
},
// 退出登录
logout: () => {
return apiService.post('/auth/logout');
return apiService.post('/auth/logout/');
},
// 检查邮箱是否可用
checkEmailAvailability: (email: string) => {
return apiService.get<{available: boolean}>('/auth/check-email', { email });
return apiService.get<{available: boolean}>('/auth/check-email/', { email });
}
};

BIN
assets/img/banner en (3)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
assets/img/banner en (4)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
assets/img/banner en (5)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

12080
package-lock.json generated

File diff suppressed because it is too large Load Diff

6
package.json

@ -7,10 +7,12 @@
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
"web": "expo start --web",
"build:web": "expo export:web"
},
"dependencies": {
"@expo/metro-runtime": "~4.0.1",
"@expo/webpack-config": "^19.0.1",
"@react-native-async-storage/async-storage": "^2.1.2",
"@react-native-community/checkbox": "^0.5.17",
"@react-native-community/datetimepicker": "8.2.0",
@ -22,7 +24,6 @@
"events": "^3.3.0",
"expo": "~52.0.41",
"expo-auth-session": "~6.0.3",
"expo-dev-client": "~5.0.20",
"expo-image": "~2.0.7",
"expo-linear-gradient": "~14.0.2",
"expo-localization": "^16.0.1",
@ -64,6 +65,7 @@
"@hancleee/babel-plugin-react-native-pxtodp": "^1.0.8",
"@types/react": "~18.3.12",
"@types/react-native-vector-icons": "^6.4.18",
"expo-module-scripts": "^4.1.7",
"react-native-svg-transformer": "^1.5.0",
"typescript": "^5.3.3"
},

5176
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save