mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-18 18:31:20 +00:00
small UI update to library tab
This commit is contained in:
parent
656e79ba91
commit
8c7db4e778
BIN
app/(tabs)/._layout.tsx.swp
Normal file
BIN
app/(tabs)/._layout.tsx.swp
Normal file
Binary file not shown.
@ -2,26 +2,27 @@
|
||||
import React from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import { Tabs } from 'expo-router';
|
||||
import { useTheme } from '@react-navigation/native'; // Change this import
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
import { Dumbbell, Library, Users, History, User } from 'lucide-react-native';
|
||||
import { CUSTOM_COLORS } from '@/lib/constants';
|
||||
import { convertHSLValues } from '@/lib/theme';
|
||||
|
||||
export default function TabLayout() {
|
||||
const { colors } = useTheme();
|
||||
const { colors, dark } = useTheme();
|
||||
const { purple, mutedForeground } = convertHSLValues(dark ? 'dark' : 'light');
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
tabBarStyle: {
|
||||
backgroundColor: colors.card,
|
||||
backgroundColor: colors.background,
|
||||
borderTopColor: colors.border,
|
||||
borderTopWidth: Platform.OS === 'ios' ? 0.5 : 1,
|
||||
elevation: 0,
|
||||
shadowOpacity: 0,
|
||||
},
|
||||
tabBarActiveTintColor: CUSTOM_COLORS.purple,
|
||||
tabBarInactiveTintColor: colors.text, // Changed this from colors.background
|
||||
tabBarActiveTintColor: purple,
|
||||
tabBarInactiveTintColor: mutedForeground,
|
||||
tabBarShowLabel: true,
|
||||
tabBarLabelStyle: {
|
||||
fontSize: 12,
|
||||
|
@ -1,41 +1,106 @@
|
||||
// app/(tabs)/library/_layout.native.tsx
|
||||
import { View } from 'react-native';
|
||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import { ThemeToggle } from '@/components/ThemeToggle';
|
||||
import { SearchPopover } from '@/components/library/SearchPopover';
|
||||
import { FilterPopover } from '@/components/library/FilterPopover';
|
||||
import { FilterSheet, type FilterOptions, type SourceType } from '@/components/library/FilterSheet';
|
||||
import ExercisesScreen from './exercises';
|
||||
import TemplatesScreen from './templates';
|
||||
import ProgramsScreen from './programs';
|
||||
import { CUSTOM_COLORS } from '@/lib/constants';
|
||||
import Header from '@/components/Header';
|
||||
import { useState } from 'react';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
import { convertHSLValues } from '@/lib/theme';
|
||||
|
||||
const Tab = createMaterialTopTabNavigator();
|
||||
|
||||
// Default available filters
|
||||
const availableFilters = {
|
||||
equipment: ['Barbell', 'Dumbbell', 'Bodyweight', 'Machine', 'Cables', 'Other'],
|
||||
tags: ['Strength', 'Cardio', 'Mobility', 'Recovery'],
|
||||
source: ['local', 'powr', 'nostr'] as SourceType[] // Fixed: Create mutable array of SourceType
|
||||
};
|
||||
|
||||
// Initial filter state
|
||||
const initialFilters: FilterOptions = {
|
||||
equipment: [],
|
||||
tags: [],
|
||||
source: []
|
||||
};
|
||||
|
||||
export default function LibraryLayout() {
|
||||
const { colors } = useTheme();
|
||||
const { colors, dark } = useTheme();
|
||||
const { purple, mutedForeground } = convertHSLValues(dark ? 'dark' : 'light');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [activeFilters, setActiveFilters] = useState(0);
|
||||
const [filterSheetOpen, setFilterSheetOpen] = useState(false);
|
||||
const [currentFilters, setCurrentFilters] = useState<FilterOptions>(initialFilters);
|
||||
|
||||
const handleApplyFilters = (filters: FilterOptions) => {
|
||||
setCurrentFilters(filters);
|
||||
// Count total active filters
|
||||
const totalFilters = Object.values(filters).reduce(
|
||||
(acc, curr) => acc + curr.length,
|
||||
0
|
||||
);
|
||||
setActiveFilters(totalFilters);
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
{/* Header */}
|
||||
<View className="flex-row justify-between items-center px-4 pt-14 pb-4 bg-card">
|
||||
<Text className="text-2xl font-bold">Library</Text>
|
||||
<ThemeToggle />
|
||||
</View>
|
||||
<Header
|
||||
title="Library"
|
||||
rightElement={
|
||||
<View className="flex-row items-center gap-2">
|
||||
<SearchPopover
|
||||
searchQuery={searchQuery}
|
||||
onSearchChange={setSearchQuery}
|
||||
/>
|
||||
<FilterPopover
|
||||
activeFilters={activeFilters}
|
||||
onOpenFilters={() => setFilterSheetOpen(true)}
|
||||
/>
|
||||
<ThemeToggle />
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<Text className="text-muted-foreground text-sm mt-1">
|
||||
12 exercises • 5 templates
|
||||
</Text>
|
||||
</Header>
|
||||
|
||||
<FilterSheet
|
||||
isOpen={filterSheetOpen}
|
||||
onClose={() => setFilterSheetOpen(false)}
|
||||
options={currentFilters}
|
||||
onApplyFilters={handleApplyFilters}
|
||||
availableFilters={availableFilters}
|
||||
/>
|
||||
|
||||
<Tab.Navigator
|
||||
initialRouteName="templates"
|
||||
screenOptions={{
|
||||
tabBarActiveTintColor: CUSTOM_COLORS.purple,
|
||||
tabBarInactiveTintColor: colors.text,
|
||||
tabBarActiveTintColor: purple,
|
||||
tabBarInactiveTintColor: mutedForeground,
|
||||
tabBarLabelStyle: {
|
||||
fontSize: 14,
|
||||
textTransform: 'capitalize',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
tabBarIndicatorStyle: {
|
||||
backgroundColor: CUSTOM_COLORS.purple,
|
||||
backgroundColor: purple,
|
||||
height: 2,
|
||||
},
|
||||
tabBarStyle: { backgroundColor: colors.card }
|
||||
tabBarStyle: {
|
||||
backgroundColor: colors.background,
|
||||
elevation: 0,
|
||||
shadowOpacity: 0,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
tabBarPressColor: colors.primary,
|
||||
}}
|
||||
>
|
||||
<Tab.Screen
|
||||
|
@ -1,106 +1,59 @@
|
||||
// app/(tabs)/library/exercises.tsx
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { View, ScrollView } from 'react-native';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import { ExerciseCard } from '@/components/exercises/ExerciseCard';
|
||||
import { FloatingActionButton } from '@/components/shared/FloatingActionButton';
|
||||
import { SearchHeader } from '@/components/library/SearchHeader';
|
||||
import { FilterSheet, type FilterOptions } from '@/components/library/FilterSheet';
|
||||
import { NewExerciseSheet } from '@/components/library/NewExerciseSheet';
|
||||
import { Dumbbell } from 'lucide-react-native';
|
||||
import { Exercise, ExerciseCategory, ExerciseEquipment, ContentSource } from '@/types/library';
|
||||
import { Exercise } from '@/types/library';
|
||||
|
||||
const initialExercises: Exercise[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Barbell Back Squat',
|
||||
category: 'Legs' as ExerciseCategory,
|
||||
equipment: 'barbell' as ExerciseEquipment,
|
||||
category: 'Legs',
|
||||
equipment: 'barbell',
|
||||
tags: ['compound', 'strength'],
|
||||
source: 'local' as ContentSource,
|
||||
source: 'local',
|
||||
description: 'A compound exercise that primarily targets the quadriceps, hamstrings, and glutes.',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Pull-ups',
|
||||
category: 'Pull' as ExerciseCategory,
|
||||
equipment: 'bodyweight' as ExerciseEquipment,
|
||||
category: 'Pull',
|
||||
equipment: 'bodyweight',
|
||||
tags: ['upper-body', 'compound'],
|
||||
source: 'local' as ContentSource,
|
||||
source: 'local',
|
||||
description: 'An upper body pulling exercise that targets the latissimus dorsi and biceps.',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Bench Press',
|
||||
category: 'Push' as ExerciseCategory,
|
||||
equipment: 'barbell' as ExerciseEquipment,
|
||||
category: 'Push',
|
||||
equipment: 'barbell',
|
||||
tags: ['push', 'strength'],
|
||||
source: 'nostr' as ContentSource,
|
||||
source: 'nostr',
|
||||
description: 'A compound pushing exercise that targets the chest, shoulders, and triceps.',
|
||||
},
|
||||
];
|
||||
|
||||
export default function ExercisesScreen() {
|
||||
const [exercises, setExercises] = useState<Exercise[]>(initialExercises);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
const [showNewExercise, setShowNewExercise] = useState(false);
|
||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
||||
equipment: [],
|
||||
tags: [],
|
||||
source: []
|
||||
});
|
||||
|
||||
// Filter exercises
|
||||
const filteredExercises = useCallback(() => {
|
||||
return exercises.filter(exercise => {
|
||||
// Search filter - make case insensitive
|
||||
if (searchQuery.trim()) {
|
||||
const searchLower = searchQuery.toLowerCase().trim();
|
||||
const matchesSearch =
|
||||
exercise.title.toLowerCase().includes(searchLower) ||
|
||||
exercise.description?.toLowerCase().includes(searchLower) ||
|
||||
exercise.tags.some(tag => tag.toLowerCase().includes(searchLower)) ||
|
||||
exercise.equipment?.toLowerCase().includes(searchLower);
|
||||
|
||||
if (!matchesSearch) return false;
|
||||
}
|
||||
|
||||
// Equipment filter
|
||||
if (filterOptions.equipment.length > 0) {
|
||||
if (!filterOptions.equipment.includes(exercise.equipment || '')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Tags filter
|
||||
if (filterOptions.tags.length > 0) {
|
||||
if (!exercise.tags.some(tag => filterOptions.tags.includes(tag))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Source filter
|
||||
if (filterOptions.source.length > 0) {
|
||||
if (!filterOptions.source.includes(exercise.source)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, [exercises, searchQuery, filterOptions]);
|
||||
|
||||
const handleAddExercise = (newExercise: Exercise) => {
|
||||
const handleAddExercise = (exerciseData: Omit<Exercise, 'id' | 'source'>) => {
|
||||
const newExercise: Exercise = {
|
||||
...exerciseData,
|
||||
id: crypto.randomUUID(),
|
||||
source: 'local',
|
||||
};
|
||||
setExercises(prev => [...prev, newExercise]);
|
||||
setShowNewExercise(false);
|
||||
};
|
||||
|
||||
// Get recent and filtered exercises
|
||||
// Get recent exercises
|
||||
const recentExercises = exercises.slice(0, 2);
|
||||
const allExercises = filteredExercises();
|
||||
const activeFilterCount = Object.values(filterOptions)
|
||||
.reduce((count, filters) => count + filters.length, 0);
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
setExercises(current => current.filter(ex => ex.id !== id));
|
||||
@ -110,21 +63,8 @@ export default function ExercisesScreen() {
|
||||
console.log('Selected exercise:', exerciseId);
|
||||
};
|
||||
|
||||
const availableFilters = {
|
||||
equipment: ['barbell', 'dumbbell', 'bodyweight', 'machine', 'cable', 'other'] as ExerciseEquipment[],
|
||||
tags: ['strength', 'compound', 'isolation', 'push', 'pull', 'legs'],
|
||||
source: ['local', 'powr', 'nostr'] as ContentSource[]
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-background">
|
||||
<SearchHeader
|
||||
searchQuery={searchQuery}
|
||||
onSearchChange={setSearchQuery}
|
||||
activeFilters={activeFilterCount}
|
||||
onOpenFilters={() => setShowFilters(true)}
|
||||
/>
|
||||
|
||||
<ScrollView className="flex-1">
|
||||
{/* Recent Exercises Section */}
|
||||
<View className="py-4">
|
||||
@ -145,7 +85,7 @@ export default function ExercisesScreen() {
|
||||
<View className="py-4">
|
||||
<Text className="text-lg font-semibold mb-4 px-4">All Exercises</Text>
|
||||
<View className="gap-3">
|
||||
{allExercises.map(exercise => (
|
||||
{exercises.map(exercise => (
|
||||
<ExerciseCard
|
||||
key={exercise.id}
|
||||
{...exercise}
|
||||
@ -162,14 +102,6 @@ export default function ExercisesScreen() {
|
||||
onPress={() => setShowNewExercise(true)}
|
||||
/>
|
||||
|
||||
<FilterSheet
|
||||
isOpen={showFilters}
|
||||
onClose={() => setShowFilters(false)}
|
||||
options={filterOptions}
|
||||
onApplyFilters={setFilterOptions}
|
||||
availableFilters={availableFilters}
|
||||
/>
|
||||
|
||||
<NewExerciseSheet
|
||||
isOpen={showNewExercise}
|
||||
onClose={() => setShowNewExercise(false)}
|
||||
|
@ -1,15 +1,12 @@
|
||||
// app/(tabs)/library/templates.tsx
|
||||
import { View, ScrollView } from 'react-native';
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import { TemplateCard } from '@/components/templates/TemplateCard';
|
||||
import { FloatingActionButton } from '@/components/shared/FloatingActionButton';
|
||||
import { SearchHeader } from '@/components/library/SearchHeader';
|
||||
import { FilterSheet } from '@/components/library/FilterSheet';
|
||||
import { NewTemplateSheet } from '@/components/library/NewTemplateSheet';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { Plus } from 'lucide-react-native';
|
||||
import { Template, FilterOptions, ContentSource, ExerciseEquipment } from '@/types/library';
|
||||
import { Template } from '@/types/library';
|
||||
|
||||
// Mock data - move to a separate file later
|
||||
const initialTemplates: Template[] = [
|
||||
@ -44,58 +41,9 @@ const initialTemplates: Template[] = [
|
||||
];
|
||||
|
||||
export default function TemplatesScreen() {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
const [showNewTemplate, setShowNewTemplate] = useState(false);
|
||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
||||
equipment: [],
|
||||
tags: [],
|
||||
source: []
|
||||
});
|
||||
const [templates, setTemplates] = useState(initialTemplates);
|
||||
|
||||
const availableFilters = {
|
||||
equipment: ['barbell', 'dumbbell', 'bodyweight', 'machine', 'cable', 'other'] as ExerciseEquipment[],
|
||||
tags: ['strength', 'circuit', 'emom', 'amrap', 'Full Body', 'Upper Body', 'Lower Body', 'Conditioning'],
|
||||
source: ['local', 'powr', 'nostr'] as ContentSource[]
|
||||
};
|
||||
|
||||
const filteredTemplates = useCallback(() => {
|
||||
return templates.filter(template => {
|
||||
// Search filter
|
||||
if (searchQuery) {
|
||||
const searchLower = searchQuery.toLowerCase();
|
||||
if (!template.title.toLowerCase().includes(searchLower) &&
|
||||
!template.exercises.some(ex =>
|
||||
ex.title.toLowerCase().includes(searchLower)
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Tags filter (includes type and category)
|
||||
if (filterOptions.tags.length > 0) {
|
||||
if (!filterOptions.tags.includes(template.type) &&
|
||||
!filterOptions.tags.includes(template.category) &&
|
||||
!template.tags.some(tag => filterOptions.tags.includes(tag))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Source filter
|
||||
if (filterOptions.source.length > 0) {
|
||||
if (!filterOptions.source.includes(template.source)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, [templates, searchQuery, filterOptions]);
|
||||
|
||||
const activeFilterCount = Object.values(filterOptions)
|
||||
.reduce((count, filters) => count + filters.length, 0);
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
setTemplates(current => current.filter(t => t.id !== id));
|
||||
};
|
||||
@ -131,13 +79,6 @@ export default function TemplatesScreen() {
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-background">
|
||||
<SearchHeader
|
||||
searchQuery={searchQuery}
|
||||
onSearchChange={setSearchQuery}
|
||||
activeFilters={activeFilterCount}
|
||||
onOpenFilters={() => setShowFilters(true)}
|
||||
/>
|
||||
|
||||
<ScrollView className="flex-1">
|
||||
{/* Favorites Section */}
|
||||
{favoriteTemplates.length > 0 && (
|
||||
@ -201,14 +142,6 @@ export default function TemplatesScreen() {
|
||||
onClose={() => setShowNewTemplate(false)}
|
||||
onSubmit={handleAddTemplate}
|
||||
/>
|
||||
|
||||
<FilterSheet
|
||||
isOpen={showFilters}
|
||||
onClose={() => setShowFilters(false)}
|
||||
options={filterOptions}
|
||||
onApplyFilters={setFilterOptions}
|
||||
availableFilters={availableFilters}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
@ -7,10 +7,13 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import Header from '@/components/Header';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
const PLACEHOLDER_IMAGE = 'https://github.com/shadcn.png'; // Placeholder profile image
|
||||
const PLACEHOLDER_IMAGE = 'https://github.com/shadcn.png';
|
||||
|
||||
export default function ProfileScreen() {
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
<Header
|
||||
@ -20,7 +23,6 @@ export default function ProfileScreen() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onPress={() => {
|
||||
// TODO: Navigate to settings
|
||||
console.log('Open settings');
|
||||
}}
|
||||
>
|
||||
@ -29,7 +31,12 @@ export default function ProfileScreen() {
|
||||
}
|
||||
/>
|
||||
|
||||
<ScrollView className="flex-1">
|
||||
<ScrollView
|
||||
className="flex-1"
|
||||
contentContainerStyle={{
|
||||
paddingBottom: insets.bottom + 20
|
||||
}}
|
||||
>
|
||||
{/* Profile Header Section */}
|
||||
<View className="items-center pt-6 pb-8">
|
||||
<Avatar className="w-24 h-24 mb-4" alt="Profile picture">
|
||||
@ -64,7 +71,6 @@ export default function ProfileScreen() {
|
||||
variant="outline"
|
||||
className="mb-2"
|
||||
onPress={() => {
|
||||
// TODO: Navigate to edit profile
|
||||
console.log('Edit profile');
|
||||
}}
|
||||
>
|
||||
@ -75,7 +81,6 @@ export default function ProfileScreen() {
|
||||
variant="outline"
|
||||
className="mb-2"
|
||||
onPress={() => {
|
||||
// TODO: Navigate to account settings
|
||||
console.log('Account settings');
|
||||
}}
|
||||
>
|
||||
@ -86,14 +91,12 @@ export default function ProfileScreen() {
|
||||
variant="outline"
|
||||
className="mb-2"
|
||||
onPress={() => {
|
||||
// TODO: Navigate to preferences
|
||||
console.log('Preferences');
|
||||
}}
|
||||
>
|
||||
<Text>Preferences</Text>
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
|
@ -1,11 +1,32 @@
|
||||
// app/(tabs)/index.tsx (and similar for other tab screens)
|
||||
import { View } from 'react-native';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Bell } from 'lucide-react-native';
|
||||
import Header from '@/components/Header';
|
||||
|
||||
export default function HomeScreen() {
|
||||
export default function SocialScreen() {
|
||||
return (
|
||||
<View className="flex-1 items-center justify-center">
|
||||
<Text>Home Screen</Text>
|
||||
<View className="flex-1">
|
||||
<Header
|
||||
title="Social"
|
||||
rightElement={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onPress={() => {
|
||||
// TODO: Open notifications
|
||||
console.log('Open notifications');
|
||||
}}
|
||||
>
|
||||
{/* Add a notification badge if needed */}
|
||||
<View className="relative">
|
||||
<Bell className="text-foreground" />
|
||||
<View className="absolute -top-1 -right-1 w-2 h-2 bg-primary rounded-full" />
|
||||
</View>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,36 @@
|
||||
// components/Header.tsx
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { View, Platform } from 'react-native';
|
||||
import { Text } from '@/components/ui/text';
|
||||
import { ThemeToggle } from '@/components/ThemeToggle';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
interface HeaderProps {
|
||||
title: string;
|
||||
rightElement?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Header({ title, rightElement }: HeaderProps) {
|
||||
export default function Header({ title, rightElement, children }: HeaderProps) {
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
return (
|
||||
<View className="flex-row justify-between items-center px-4 pt-14 pb-4 bg-card">
|
||||
<Text className="text-2xl font-bold">{title}</Text>
|
||||
{rightElement || <ThemeToggle />}
|
||||
<View
|
||||
className="flex-row items-center justify-between bg-card border-b border-border"
|
||||
style={{
|
||||
paddingTop: Platform.OS === 'ios' ? insets.top : insets.top + 8,
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 12,
|
||||
}}
|
||||
>
|
||||
<View className="flex-1">
|
||||
<Text className="text-2xl font-bold">{title}</Text>
|
||||
{children}
|
||||
</View>
|
||||
{rightElement && (
|
||||
<View className="ml-4">
|
||||
{rightElement}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
37
components/library/FilterPopover.tsx
Normal file
37
components/library/FilterPopover.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
// components/library/FilterPopover.tsx
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Filter } from 'lucide-react-native';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { FilterOptions } from './FilterSheet';
|
||||
import { Text } from 'components/ui/text';
|
||||
|
||||
interface FilterPopoverProps {
|
||||
activeFilters: number;
|
||||
onOpenFilters: () => void;
|
||||
}
|
||||
|
||||
export function FilterPopover({ activeFilters, onOpenFilters }: FilterPopoverProps) {
|
||||
return (
|
||||
<View className="relative">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onPress={onOpenFilters}
|
||||
>
|
||||
<Filter className="text-foreground" />
|
||||
</Button>
|
||||
{activeFilters > 0 && (
|
||||
<Badge
|
||||
className="absolute -top-2 -right-2 w-5 h-5 flex items-center justify-center p-0"
|
||||
>
|
||||
<Text className="text-xs text-primary-foreground">
|
||||
{activeFilters}
|
||||
</Text>
|
||||
</Badge>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
@ -74,6 +74,13 @@ export function FilterSheet({
|
||||
}: FilterSheetProps) {
|
||||
const [localOptions, setLocalOptions] = React.useState(options);
|
||||
|
||||
const handleReset = () => {
|
||||
const resetOptions = { equipment: [], tags: [], source: [] };
|
||||
setLocalOptions(resetOptions);
|
||||
// Immediately apply reset
|
||||
onApplyFilters(resetOptions);
|
||||
};
|
||||
|
||||
const toggleFilter = (
|
||||
category: keyof FilterOptions,
|
||||
value: string | SourceType
|
||||
@ -88,9 +95,6 @@ export function FilterSheet({
|
||||
|
||||
return (
|
||||
<Sheet isOpen={isOpen} onClose={onClose}>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Filter Exercises</SheetTitle>
|
||||
</SheetHeader>
|
||||
<SheetContent>
|
||||
<View className="gap-4">
|
||||
<Accordion type="single" collapsible>
|
||||
@ -102,7 +106,7 @@ export function FilterSheet({
|
||||
<Button
|
||||
variant="outline"
|
||||
className="flex-1"
|
||||
onPress={() => setLocalOptions({ equipment: [], tags: [], source: [] })}
|
||||
onPress={handleReset}
|
||||
>
|
||||
<Text>Reset</Text>
|
||||
</Button>
|
||||
|
47
components/library/SearchPopover.tsx
Normal file
47
components/library/SearchPopover.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
// components/library/SearchPopover.tsx
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Search, X } from 'lucide-react-native';
|
||||
|
||||
interface SearchPopoverProps {
|
||||
searchQuery: string;
|
||||
onSearchChange: (query: string) => void;
|
||||
}
|
||||
|
||||
export function SearchPopover({ searchQuery, onSearchChange }: SearchPopoverProps) {
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
|
||||
return (
|
||||
<Popover onOpenChange={setIsOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<Search className="text-foreground" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-80 p-0" align="end">
|
||||
<View className="flex-row items-center p-2 gap-2">
|
||||
<Input
|
||||
placeholder="Search exercises..."
|
||||
value={searchQuery}
|
||||
onChangeText={onSearchChange}
|
||||
className="flex-1"
|
||||
autoFocus
|
||||
placeholderTextColor="text-muted-foreground"
|
||||
/>
|
||||
{searchQuery.length > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onPress={() => onSearchChange('')}
|
||||
>
|
||||
<X size={20} className="text-muted-foreground" />
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
@ -24,7 +24,7 @@ const buttonVariants = cva(
|
||||
secondary: 'bg-secondary web:hover:opacity-80 active:opacity-80',
|
||||
ghost: 'web:hover:bg-accent web:hover:text-accent-foreground active:bg-accent',
|
||||
link: 'web:underline-offset-4 web:hover:underline web:focus:underline',
|
||||
purple: 'bg-[#8B5CF6] web:hover:bg-[#7C3AED] active:bg-[#7C3AED]', // Added purple variant
|
||||
purple: 'bg-[hsl(var(--purple))] text-white hover:bg-[hsl(var(--purple-pressed))]',
|
||||
},
|
||||
size: {
|
||||
default: 'h-10 px-4 py-2 native:h-12 native:px-5 native:py-3',
|
||||
|
@ -24,6 +24,8 @@
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 5.9% 10%;
|
||||
--purple: 261 90% 66%;
|
||||
--purple-pressed: 262 84% 58%;
|
||||
}
|
||||
|
||||
.dark:root {
|
||||
|
@ -1,25 +1,30 @@
|
||||
// lib/constants.ts
|
||||
export const NAV_THEME = {
|
||||
import type { NavigationThemeColors } from './theme';
|
||||
|
||||
export const NAV_THEME: {
|
||||
light: NavigationThemeColors;
|
||||
dark: NavigationThemeColors;
|
||||
} = {
|
||||
light: {
|
||||
background: 'hsl(0 0% 100%)', // background
|
||||
border: 'hsl(240 5.9% 90%)', // border
|
||||
card: 'hsl(0 0% 100%)', // card
|
||||
notification: 'hsl(0 84.2% 60.2%)', // destructive
|
||||
primary: 'hsl(240 5.9% 10%)', // primary
|
||||
text: 'hsl(240 10% 3.9%)', // foreground
|
||||
background: 'hsl(0, 0%, 100%)',
|
||||
border: 'hsl(240, 5.9%, 90%)',
|
||||
card: 'hsl(0, 0%, 100%)',
|
||||
notification: 'hsl(0, 84.2%, 60.2%)',
|
||||
primary: 'hsl(261, 90%, 66%)',
|
||||
text: 'hsl(240, 10%, 3.9%)',
|
||||
tabActive: 'hsl(261, 90%, 66%)',
|
||||
tabInactive: 'hsl(240, 3.8%, 46.1%)',
|
||||
tabIndicator: 'hsl(261, 90%, 66%)',
|
||||
},
|
||||
dark: {
|
||||
background: 'hsl(240 10% 3.9%)', // background
|
||||
border: 'hsl(240 3.7% 15.9%)', // border
|
||||
card: 'hsl(240 10% 3.9%)', // card
|
||||
notification: 'hsl(0 72% 51%)', // destructive
|
||||
primary: 'hsl(0 0% 98%)', // primary
|
||||
text: 'hsl(0 0% 98%)', // foreground
|
||||
background: 'hsl(240, 10%, 3.9%)',
|
||||
border: 'hsl(240, 3.7%, 15.9%)',
|
||||
card: 'hsl(240, 10%, 3.9%)',
|
||||
notification: 'hsl(0, 72%, 51%)',
|
||||
primary: 'hsl(261, 90%, 66%)',
|
||||
text: 'hsl(0, 0%, 98%)',
|
||||
tabActive: 'hsl(261, 90%, 66%)',
|
||||
tabInactive: 'hsl(240, 5%, 64.9%)',
|
||||
tabIndicator: 'hsl(261, 90%, 66%)',
|
||||
},
|
||||
};
|
||||
|
||||
export const CUSTOM_COLORS = {
|
||||
purple: '#8B5CF6',
|
||||
purplePressed: '#7C3AED', // Slightly darker for pressed state
|
||||
orange: '#F97316'
|
||||
} as const;
|
||||
};
|
93
lib/theme.ts
Normal file
93
lib/theme.ts
Normal file
@ -0,0 +1,93 @@
|
||||
// lib/theme.ts
|
||||
import { Theme } from '@react-navigation/native';
|
||||
import { ColorSchemeName } from 'react-native';
|
||||
|
||||
// Update the interface for our navigation theme colors
|
||||
export interface NavigationThemeColors {
|
||||
primary: string;
|
||||
background: string;
|
||||
card: string;
|
||||
text: string;
|
||||
border: string;
|
||||
notification: string;
|
||||
tabActive: string;
|
||||
tabInactive: string;
|
||||
tabIndicator: string;
|
||||
}
|
||||
|
||||
// Original ThemeColors interface remains the same
|
||||
export interface ThemeColors {
|
||||
background: string;
|
||||
foreground: string;
|
||||
card: string;
|
||||
'card-foreground': string;
|
||||
popover: string;
|
||||
'popover-foreground': string;
|
||||
primary: string;
|
||||
'primary-foreground': string;
|
||||
secondary: string;
|
||||
'secondary-foreground': string;
|
||||
muted: string;
|
||||
'muted-foreground': string;
|
||||
accent: string;
|
||||
'accent-foreground': string;
|
||||
destructive: string;
|
||||
'destructive-foreground': string;
|
||||
border: string;
|
||||
input: string;
|
||||
ring: string;
|
||||
purple: string;
|
||||
'purple-pressed': string;
|
||||
}
|
||||
|
||||
// Export the color conversion function
|
||||
export function convertHSLValues(colorScheme: 'light' | 'dark') {
|
||||
const purple = colorScheme === 'light'
|
||||
? 'hsl(261, 90%, 66%)'
|
||||
: 'hsl(261, 90%, 66%)';
|
||||
const mutedForeground = colorScheme === 'light'
|
||||
? 'hsl(240, 3.8%, 46.1%)'
|
||||
: 'hsl(240, 5%, 64.9%)';
|
||||
|
||||
return {
|
||||
purple,
|
||||
mutedForeground,
|
||||
};
|
||||
}
|
||||
|
||||
export function getNavigationTheme(scheme: ColorSchemeName): Theme {
|
||||
const colorScheme = scheme ?? 'light';
|
||||
const { purple, mutedForeground } = convertHSLValues(colorScheme as 'light' | 'dark');
|
||||
|
||||
const theme: Theme = {
|
||||
dark: colorScheme === 'dark',
|
||||
colors: {
|
||||
primary: purple,
|
||||
background: colorScheme === 'dark' ? 'hsl(240, 10%, 3.9%)' : 'hsl(0, 0%, 100%)',
|
||||
card: colorScheme === 'dark' ? 'hsl(240, 10%, 5.9%)' : 'hsl(0, 0%, 100%)',
|
||||
text: colorScheme === 'dark' ? 'hsl(0, 0%, 98%)' : 'hsl(240, 10%, 3.9%)',
|
||||
border: colorScheme === 'dark' ? 'hsl(240, 3.7%, 15.9%)' : 'hsl(240, 5.9%, 90%)',
|
||||
notification: colorScheme === 'dark' ? 'hsl(0, 72%, 51%)' : 'hsl(0, 84.2%, 60.2%)',
|
||||
},
|
||||
fonts: {
|
||||
regular: {
|
||||
fontFamily: 'System',
|
||||
fontWeight: '400',
|
||||
},
|
||||
medium: {
|
||||
fontFamily: 'System',
|
||||
fontWeight: '500',
|
||||
},
|
||||
bold: {
|
||||
fontFamily: 'System',
|
||||
fontWeight: '700',
|
||||
},
|
||||
heavy: {
|
||||
fontFamily: 'System',
|
||||
fontWeight: '900',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return theme;
|
||||
}
|
299
package-lock.json
generated
299
package-lock.json
generated
@ -41,18 +41,18 @@
|
||||
"@rn-primitives/types": "~1.1.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"expo": "^52.0.25",
|
||||
"expo": "~52.0.33",
|
||||
"expo-linking": "~7.0.4",
|
||||
"expo-navigation-bar": "~4.0.7",
|
||||
"expo-navigation-bar": "~4.0.8",
|
||||
"expo-router": "~4.0.16",
|
||||
"expo-splash-screen": "~0.29.20",
|
||||
"expo-status-bar": "~2.0.1",
|
||||
"expo-system-ui": "~4.0.7",
|
||||
"expo-system-ui": "~4.0.8",
|
||||
"lucide-react-native": "^0.378.0",
|
||||
"nativewind": "^4.1.23",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-native": "0.76.6",
|
||||
"react-native": "0.76.7",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-pager-view": "^6.5.1",
|
||||
"react-native-reanimated": "~3.16.1",
|
||||
@ -166,13 +166,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.26.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
|
||||
"integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
|
||||
"version": "7.26.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz",
|
||||
"integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.26.5",
|
||||
"@babel/types": "^7.26.5",
|
||||
"@babel/parser": "^7.26.8",
|
||||
"@babel/types": "^7.26.8",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"jsesc": "^3.0.2"
|
||||
@ -515,12 +515,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
|
||||
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
|
||||
"version": "7.26.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz",
|
||||
"integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.26.7"
|
||||
"@babel/types": "^7.26.8"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -2167,14 +2167,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
|
||||
"integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
|
||||
"version": "7.26.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz",
|
||||
"integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.25.9",
|
||||
"@babel/parser": "^7.25.9",
|
||||
"@babel/types": "^7.25.9"
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/parser": "^7.26.8",
|
||||
"@babel/types": "^7.26.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -2200,16 +2200,16 @@
|
||||
},
|
||||
"node_modules/@babel/traverse--for-generate-function-map": {
|
||||
"name": "@babel/traverse",
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
|
||||
"integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
|
||||
"version": "7.26.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz",
|
||||
"integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/generator": "^7.26.5",
|
||||
"@babel/parser": "^7.26.7",
|
||||
"@babel/template": "^7.25.9",
|
||||
"@babel/types": "^7.26.7",
|
||||
"@babel/generator": "^7.26.8",
|
||||
"@babel/parser": "^7.26.8",
|
||||
"@babel/template": "^7.26.8",
|
||||
"@babel/types": "^7.26.8",
|
||||
"debug": "^4.3.1",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
@ -2218,9 +2218,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
|
||||
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
|
||||
"version": "7.26.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz",
|
||||
"integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
@ -2255,16 +2255,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli": {
|
||||
"version": "0.22.12",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.12.tgz",
|
||||
"integrity": "sha512-i7mYb2s4RzlcLIsMewYtKol5rOIECOgLymAUfTwgvsAjg1r+11gmovsi3xdM0k1QiHmeJf0Wqz3sl7FJNsSKnw==",
|
||||
"version": "0.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.15.tgz",
|
||||
"integrity": "sha512-iXG8E+Fcyq21yM0g5hwdRyAQ9G/T0B+fAXXhwNmUP1jyoqb5wZUmld3gYycsByEJbM2TX9xKMnjtq/zyjYxYOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@0no-co/graphql.web": "^1.0.8",
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/code-signing-certificates": "^0.0.5",
|
||||
"@expo/config": "~10.0.8",
|
||||
"@expo/config-plugins": "~9.0.14",
|
||||
"@expo/config": "~10.0.9",
|
||||
"@expo/config-plugins": "~9.0.15",
|
||||
"@expo/devcert": "^1.1.2",
|
||||
"@expo/env": "~0.4.1",
|
||||
"@expo/image-utils": "^0.6.4",
|
||||
@ -2273,12 +2273,12 @@
|
||||
"@expo/osascript": "^2.1.5",
|
||||
"@expo/package-manager": "^1.7.1",
|
||||
"@expo/plist": "^0.2.1",
|
||||
"@expo/prebuild-config": "^8.0.25",
|
||||
"@expo/prebuild-config": "^8.0.26",
|
||||
"@expo/rudder-sdk-node": "^1.1.1",
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
"@expo/ws-tunnel": "^1.0.1",
|
||||
"@expo/xcpretty": "^4.3.0",
|
||||
"@react-native/dev-middleware": "0.76.6",
|
||||
"@react-native/dev-middleware": "0.76.7",
|
||||
"@urql/core": "^5.0.6",
|
||||
"@urql/exchange-retry": "^1.3.0",
|
||||
"accepts": "^1.3.8",
|
||||
@ -2360,14 +2360,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/config": {
|
||||
"version": "10.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.8.tgz",
|
||||
"integrity": "sha512-RaKwi8e6PbkMilRexdsxObLMdQwxhY6mlgel+l/eW+IfIw8HEydSU0ERlzYUjlGJxHLHUXe4rC2vw8FEvaowyQ==",
|
||||
"version": "10.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.9.tgz",
|
||||
"integrity": "sha512-dEw2PKnSjzik3nc2mMzWnLtfiFpd3uGsdBdSl8tEbaRwtMAu74/BOJ1qCgh8slWppikaTcQLQ0xWlqlQU2i4aw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "~7.10.4",
|
||||
"@expo/config-plugins": "~9.0.14",
|
||||
"@expo/config-types": "^52.0.3",
|
||||
"@expo/config-plugins": "~9.0.15",
|
||||
"@expo/config-types": "^52.0.4",
|
||||
"@expo/json-file": "^9.0.1",
|
||||
"deepmerge": "^4.3.1",
|
||||
"getenv": "^1.0.0",
|
||||
@ -2381,12 +2381,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/config-plugins": {
|
||||
"version": "9.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.14.tgz",
|
||||
"integrity": "sha512-Lx1ebV95rTFKKQmbu4wMPLz65rKn7mqSpfANdCx+KwRxuLY2JQls8V4h3lQjG6dW8NWf9qV5QaEFAgNB6VMyOQ==",
|
||||
"version": "9.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.15.tgz",
|
||||
"integrity": "sha512-elKY/zIpAJ40RH26iwfyp+hwgeyPgIXX0SrCSOcjeJLsMsCmMac9ewvb+AN8y4k+N7m5lD/dMZupsaateKTFwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@expo/config-types": "^52.0.3",
|
||||
"@expo/config-types": "^52.0.4",
|
||||
"@expo/json-file": "~9.0.1",
|
||||
"@expo/plist": "^0.2.1",
|
||||
"@expo/sdk-runtime-versions": "^1.0.0",
|
||||
@ -2415,9 +2415,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/config-types": {
|
||||
"version": "52.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-52.0.3.tgz",
|
||||
"integrity": "sha512-muxvuARmbysH5OGaiBRlh1Y6vfdmL56JtpXxB+y2Hfhu0ezG1U4FjZYBIacthckZPvnDCcP3xIu1R+eTo7/QFA==",
|
||||
"version": "52.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-52.0.4.tgz",
|
||||
"integrity": "sha512-oMGrb2o3niVCIfjnIHFrOoiDA9jGb0lc3G4RI1UiO//KjULBaQr3QTBoKDzZQwMqDV1AgYgSr9mgEcnX3LqhIg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@expo/config/node_modules/@babel/code-frame": {
|
||||
@ -2484,9 +2484,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/fingerprint": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.8.tgz",
|
||||
"integrity": "sha512-XzDOHr+fTpYPGFe+bIlWtwnLahzuQi7htPgpjLsfL+hKE/2S7wWYlRgB0omScyEBz2yXxzCk3GHJTcG+dffLAg==",
|
||||
"version": "0.11.9",
|
||||
"resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.9.tgz",
|
||||
"integrity": "sha512-db99WKkC4JKAnCLL55LOUJ2OvGQOrxOPyQ4stBOgWb5v/OM25rtREqwLtGDpJ5VBvr5DKbXbscWd1yxginq99g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@expo/spawn-async": "^1.7.2",
|
||||
@ -2734,17 +2734,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config": {
|
||||
"version": "8.0.25",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.25.tgz",
|
||||
"integrity": "sha512-xYHV8eiydZEDedf2AGaOFRFwcGlaSzrqQH94dwX42urNCU03FO0RUb7yPp4nkb7WNFg5Ov6PDsV7ES+YwzNgYQ==",
|
||||
"version": "8.0.26",
|
||||
"resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.26.tgz",
|
||||
"integrity": "sha512-SryIKBXPkykUzoCUVP3nt7GclChE74TM8xAstxZ7paXxgcSMN68mNVyUr/zOivLTYQijXltD1I9rNj20Vm5aFw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@expo/config": "~10.0.8",
|
||||
"@expo/config-plugins": "~9.0.14",
|
||||
"@expo/config-types": "^52.0.3",
|
||||
"@expo/config-plugins": "~9.0.15",
|
||||
"@expo/config-types": "^52.0.4",
|
||||
"@expo/image-utils": "^0.6.4",
|
||||
"@expo/json-file": "^9.0.1",
|
||||
"@react-native/normalize-colors": "0.76.6",
|
||||
"@react-native/normalize-colors": "0.76.7",
|
||||
"debug": "^4.3.1",
|
||||
"fs-extra": "^9.0.0",
|
||||
"resolve-from": "^5.0.0",
|
||||
@ -2858,9 +2858,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/ws-tunnel": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.1.tgz",
|
||||
"integrity": "sha512-b1VoJfK7u6RVlOoDONyKQQ7JWnHZqa8+bFdWxDmvFUCoiI1ri4MAapSNd308QgADYohSecqIZkITt9hDS722Iw=="
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.4.tgz",
|
||||
"integrity": "sha512-spXCVXxbeKOe8YZ9igd+MDfXZe6LeDvFAdILijeTSG+XcxGrZLmqMWWkFKR0nV8lTWZ+NugUT3CoiXmEuKKQ7w=="
|
||||
},
|
||||
"node_modules/@expo/xcpretty": {
|
||||
"version": "4.3.2",
|
||||
@ -3750,30 +3750,30 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@react-native/assets-registry": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.6.tgz",
|
||||
"integrity": "sha512-YI8HoReYiIwdFQs+k9Q9qpFTnsyYikZxgs/UVtVbhKixXDQF6F9LLvj2naOx4cfV+RGybNKxwmDl1vUok/dRFQ==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.7.tgz",
|
||||
"integrity": "sha512-o79whsqL5fbPTUQO9w1FptRd4cw1TaeOrXtQSLQeDrMVAenw/wmsjyPK10VKtvqxa1KNMtWEyfgxcM8CVZVFmg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-plugin-codegen": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.6.tgz",
|
||||
"integrity": "sha512-yFC9I/aDBOBz3ZMlqKn2NY/mDUtCksUNZ7AQmBiTAeVTUP0ujEjE0hTOx5Qd+kok7A7hwZEX87HdSgjiJZfr5g==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.7.tgz",
|
||||
"integrity": "sha512-+8H4DXJREM4l/pwLF/wSVMRzVhzhGDix5jLezNrMD9J1U1AMfV2aSkWA1XuqR7pjPs/Vqf6TaPL7vJMZ4LU05Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-native/codegen": "0.76.6"
|
||||
"@react-native/codegen": "0.76.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/babel-preset": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.6.tgz",
|
||||
"integrity": "sha512-ojlVWY6S/VE/nb9hIRetPMTsW9ZmGb2R3dnToEXAtQQDz41eHMHXbkw/k2h0THp6qhas25ruNvn3N5n2o+lBzg==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.7.tgz",
|
||||
"integrity": "sha512-/c5DYZ6y8tyg+g8tgXKndDT7mWnGmkZ9F+T3qNDfoE3Qh7ucrNeC2XWvU9h5pk8eRtj9l4SzF4aO1phzwoibyg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
@ -3817,7 +3817,7 @@
|
||||
"@babel/plugin-transform-typescript": "^7.25.2",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.7",
|
||||
"@babel/template": "^7.25.0",
|
||||
"@react-native/babel-plugin-codegen": "0.76.6",
|
||||
"@react-native/babel-plugin-codegen": "0.76.7",
|
||||
"babel-plugin-syntax-hermes-parser": "^0.25.1",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"react-refresh": "^0.14.0"
|
||||
@ -3830,9 +3830,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/codegen": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.6.tgz",
|
||||
"integrity": "sha512-BABb3e5G/+hyQYEYi0AODWh2km2d8ERoASZr6Hv90pVXdUHRYR+yxCatX7vSd9rnDUYndqRTzD0hZWAucPNAKg==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.7.tgz",
|
||||
"integrity": "sha512-FAn585Ll65YvkSrKDyAcsdjHhhAGiMlSTUpHh0x7J5ntudUns+voYms0xMP+pEPt0XuLdjhD7zLIIlAWP407+g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.25.3",
|
||||
@ -3873,13 +3873,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/community-cli-plugin": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.6.tgz",
|
||||
"integrity": "sha512-nETlc/+U5cESVluzzgN0OcVfcoMijGBaDWzOaJhoYUodcuqnqtu75XsSEc7yzlYjwNQG+vF83mu9CQGezruNMA==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.7.tgz",
|
||||
"integrity": "sha512-lrcsY2WPLCEWU1pjdNV9+Ccj8vCEwCCURZiPa5aqi7lKB4C++1hPrxA8/CWWnTNcQp76DsBKGYqTFj7Ud4aupw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-native/dev-middleware": "0.76.6",
|
||||
"@react-native/metro-babel-transformer": "0.76.6",
|
||||
"@react-native/dev-middleware": "0.76.7",
|
||||
"@react-native/metro-babel-transformer": "0.76.7",
|
||||
"chalk": "^4.0.0",
|
||||
"execa": "^5.1.1",
|
||||
"invariant": "^2.2.4",
|
||||
@ -4004,26 +4004,27 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@react-native/debugger-frontend": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.6.tgz",
|
||||
"integrity": "sha512-kP97xMQjiANi5/lmf8MakS7d8FTJl+BqYHQMqyvNiY+eeWyKnhqW2GL2v3eEUBAuyPBgJGivuuO4RvjZujduJg==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.7.tgz",
|
||||
"integrity": "sha512-89ZtZXt7ZxE94i7T94qzZMhp4Gfcpr/QVpGqEaejAxZD+gvDCH21cYSF+/Rz2ttBazm0rk5MZ0mFqb0Iqp1jmw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/dev-middleware": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.6.tgz",
|
||||
"integrity": "sha512-1bAyd2/X48Nzb45s5l2omM75vy764odx/UnDs4sJfFCuK+cupU4nRPgl0XWIqgdM/2+fbQ3E4QsVS/WIKTFxvQ==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.7.tgz",
|
||||
"integrity": "sha512-Jsw8g9DyLPnR9yHEGuT09yHZ7M88/GL9CtU9WmyChlBwdXSeE3AmRqLegsV3XcgULQ1fqdemokaOZ/MwLYkjdA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@isaacs/ttlcache": "^1.4.1",
|
||||
"@react-native/debugger-frontend": "0.76.6",
|
||||
"@react-native/debugger-frontend": "0.76.7",
|
||||
"chrome-launcher": "^0.15.2",
|
||||
"chromium-edge-launcher": "^0.2.0",
|
||||
"connect": "^3.6.5",
|
||||
"debug": "^2.2.0",
|
||||
"invariant": "^2.2.4",
|
||||
"nullthrows": "^1.1.1",
|
||||
"open": "^7.0.3",
|
||||
"selfsigned": "^2.4.1",
|
||||
@ -4059,31 +4060,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/gradle-plugin": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.6.tgz",
|
||||
"integrity": "sha512-sDzpf4eiynryoS6bpYCweGoxSmWgCSx9lzBoxIIW+S6siyGiTaffzZHWCm8mIn9UZsSPlEO37q62ggnR9Zu/OA==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.7.tgz",
|
||||
"integrity": "sha512-gQI6RcrJbigU8xk7F960C5xQIgvbBj20TUvGecD+N2PHfbLpqR+92cj7hz3UcbrCONmTP40WHnbMMJ8P+kLsrA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/js-polyfills": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.6.tgz",
|
||||
"integrity": "sha512-cDD7FynxWYxHkErZzAJtzPGhJ13JdOgL+R0riTh0hCovOfIUz9ItffdLQv2nx48lnvMTQ+HZXMnGOZnsFCNzQw==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.7.tgz",
|
||||
"integrity": "sha512-+iEikj6c6Zvrg1c3cYMeiPB+5nS8EaIC3jCtP6Muk3qc7c386IymEPM2xycIlfg04DPZvO3D4P2/vaO9/TCnUg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/metro-babel-transformer": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.6.tgz",
|
||||
"integrity": "sha512-xSBi9jPliThu5HRSJvluqUlDOLLEmf34zY/U7RDDjEbZqC0ufPcPS7c5XsSg0GDPiXc7lgjBVesPZsKFkoIBgA==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.7.tgz",
|
||||
"integrity": "sha512-jDS1wR7q46xY5ah+jF714Mvss9l7+lmwW/tplahZgLKozkYDC8Td5o9TOCgKlv18acw9H1V7zv8ivuRSj8ICPg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.76.6",
|
||||
"@react-native/babel-preset": "0.76.7",
|
||||
"hermes-parser": "0.23.1",
|
||||
"nullthrows": "^1.1.1"
|
||||
},
|
||||
@ -4095,15 +4096,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/normalize-colors": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.6.tgz",
|
||||
"integrity": "sha512-1n4udXH2Cla31iA/8eLRdhFHpYUYK1NKWCn4m1Sr9L4SarWKAYuRFliK1fcLvPPALCFoFlWvn8I0ekdUOHMzDQ==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.7.tgz",
|
||||
"integrity": "sha512-ST1xxBuYVIXPdD81dR6+tzIgso7m3pa9+6rOBXTh5Xm7KEEFik7tnQX+GydXYMp3wr1gagJjragdXkPnxK6WNg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@react-native/virtualized-lists": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.6.tgz",
|
||||
"integrity": "sha512-0HUWVwJbRq1BWFOu11eOWGTSmK9nMHhoMPyoI27wyWcl/nqUx7HOxMbRVq0DsTCyATSMPeF+vZ6o1REapcNWKw==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.7.tgz",
|
||||
"integrity": "sha512-pRUf1jUO8H9Ft04CaWv76t34QI9wY0sydoYlIwEtqXjjMJgmgDoOCAWBjArgn2mk8/rK+u/uicI67ZCYCp1pJw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"invariant": "^2.2.4",
|
||||
@ -9565,9 +9566,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/babel-preset-expo": {
|
||||
"version": "12.0.6",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.6.tgz",
|
||||
"integrity": "sha512-az3H7gDVo0wxNBAFES8h5vLLWE8NPGkD9g5P962hDEOqZUdyPacb9MOzicypeLmcq9zQWr6E3iVtEHoNagCTTQ==",
|
||||
"version": "12.0.7",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.7.tgz",
|
||||
"integrity": "sha512-XT2ZOnonTU343eRnd/UBuqYLxmaB47g+RtLMANMsj/j9XL2kkTk3a6yepLbV4BrACaTf2ddiBZDi+BQ0lgjVaw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-decorators": "^7.12.9",
|
||||
@ -9576,7 +9577,7 @@
|
||||
"@babel/plugin-transform-parameters": "^7.22.15",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.23.0",
|
||||
"@react-native/babel-preset": "0.76.6",
|
||||
"@react-native/babel-preset": "0.76.7",
|
||||
"babel-plugin-react-native-web": "~0.19.13",
|
||||
"react-refresh": "^0.14.2"
|
||||
},
|
||||
@ -10341,9 +10342,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/compression": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz",
|
||||
"integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==",
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
|
||||
"integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
@ -11170,26 +11171,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo": {
|
||||
"version": "52.0.30",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-52.0.30.tgz",
|
||||
"integrity": "sha512-CQP75djQOMWpNqniV7IBhsUiY/hpVnGWCPfEuYQIsZBEGa/ZQOuOQEVF7MaFeWEOYR1/qaDyv7ON3ON9QPJydg==",
|
||||
"version": "52.0.33",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-52.0.33.tgz",
|
||||
"integrity": "sha512-8lgeJtqw5N1m7910n/pc8cWBT8bzwaNue1mWXElwdhpKSEpPsCYG1sNQ8eqRnC37Y8aj6i6TrNFmSP++7zUS3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/cli": "0.22.12",
|
||||
"@expo/config": "~10.0.8",
|
||||
"@expo/config-plugins": "~9.0.14",
|
||||
"@expo/fingerprint": "0.11.8",
|
||||
"@expo/cli": "0.22.15",
|
||||
"@expo/config": "~10.0.9",
|
||||
"@expo/config-plugins": "~9.0.15",
|
||||
"@expo/fingerprint": "0.11.9",
|
||||
"@expo/metro-config": "0.19.9",
|
||||
"@expo/vector-icons": "^14.0.0",
|
||||
"babel-preset-expo": "~12.0.6",
|
||||
"babel-preset-expo": "~12.0.7",
|
||||
"expo-asset": "~11.0.3",
|
||||
"expo-constants": "~17.0.5",
|
||||
"expo-file-system": "~18.0.9",
|
||||
"expo-file-system": "~18.0.10",
|
||||
"expo-font": "~13.0.3",
|
||||
"expo-keep-awake": "~14.0.2",
|
||||
"expo-modules-autolinking": "2.0.7",
|
||||
"expo-modules-core": "2.2.0",
|
||||
"expo-modules-core": "2.2.1",
|
||||
"fbemitter": "^3.0.0",
|
||||
"web-streams-polyfill": "^3.3.2",
|
||||
"whatwg-url-without-unicode": "8.0.0-3"
|
||||
@ -11248,9 +11249,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-file-system": {
|
||||
"version": "18.0.9",
|
||||
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.9.tgz",
|
||||
"integrity": "sha512-DPuAyLP1012SFC92LKNJpLJw3QBbyxfYXNj9nTOdq299MYTf8kyOjLuVNMQqg1jX+yGiRDp0lHFoCgln0xsZYA==",
|
||||
"version": "18.0.10",
|
||||
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.10.tgz",
|
||||
"integrity": "sha512-+GnxkI+J9tOzUQMx+uIOLBEBsO2meyoYHxd87m9oT9M//BpepYqI1AvYBH8YM4dgr9HaeaeLr7z5XFVqfL8tWg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"web-streams-polyfill": "^3.3.2"
|
||||
@ -11353,21 +11354,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-modules-core": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.2.0.tgz",
|
||||
"integrity": "sha512-mOFEHIe6jZ7G5pYUVSQ2Ghs3CUr9Uz6DOh4JI+4PsTf0gmEvMmMEOrxirS89jRWQjXPJ7QaGBK0CJrZlj/Sdeg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.2.1.tgz",
|
||||
"integrity": "sha512-pxQpfgevHiy5EVRDE0w3mrVu0UTNHELr4GDXEQWAE1g4JVS5ZGNq/Gu2VGgFbBP18KGPNB+gEy8UFI48ADbiuw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"invariant": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-navigation-bar": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/expo-navigation-bar/-/expo-navigation-bar-4.0.7.tgz",
|
||||
"integrity": "sha512-0dU6nU4XzLBFfkX7KTeYj6qX/3W/peYV9LjKymBsRPY0/uVgEcgFgS+omQAZE6DVD4Duy3GcT+91ozCUmvEEdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/expo-navigation-bar/-/expo-navigation-bar-4.0.8.tgz",
|
||||
"integrity": "sha512-rmQkCCwfYeR29GTPwoNuN7eWE8bYCW5UGJ/5CnZQxIaiBmOeepoDXu50AzEM5ZFPMK6J12nvyu1yj0ujbLUpsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-native/normalize-colors": "0.76.6",
|
||||
"@react-native/normalize-colors": "0.76.7",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@ -11452,12 +11453,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo-system-ui": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-4.0.7.tgz",
|
||||
"integrity": "sha512-x1VDoE7J8m4wxTgWyUBEYqsf1KabIg64dOLzYiZjg0cWOE6o6kX2Mg6n3abVWEEC01WhZBoo9+Urcce/6ZJ3tg==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-4.0.8.tgz",
|
||||
"integrity": "sha512-0AmWXJ3ObwMYxi2YGagwRQikydoUZJXLeK4A0FY1PsZpnlorSQ4IAfEVS38JmA54tf5CpP4TjBp5ZVEjRyv1rw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@react-native/normalize-colors": "0.76.6",
|
||||
"@react-native/normalize-colors": "0.76.7",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@ -11472,9 +11473,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/exponential-backoff": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
|
||||
"integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
|
||||
"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": {
|
||||
@ -15361,19 +15362,19 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-native": {
|
||||
"version": "0.76.6",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.6.tgz",
|
||||
"integrity": "sha512-AsRi+ud6v6ADH7ZtSOY42kRB4nbM0KtSu450pGO4pDudl4AEK/AF96ai88snb2/VJJSGGa/49QyJVFXxz/qoFg==",
|
||||
"version": "0.76.7",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.7.tgz",
|
||||
"integrity": "sha512-GPJcQeO3qUi1MvuhsC2DC6tH8gJQ4uc4JWPORrdeuCGFWE3QLsN8/hiChTEvJREHLfQSV61YPI8gIOtAQ8c37g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jest/create-cache-key-function": "^29.6.3",
|
||||
"@react-native/assets-registry": "0.76.6",
|
||||
"@react-native/codegen": "0.76.6",
|
||||
"@react-native/community-cli-plugin": "0.76.6",
|
||||
"@react-native/gradle-plugin": "0.76.6",
|
||||
"@react-native/js-polyfills": "0.76.6",
|
||||
"@react-native/normalize-colors": "0.76.6",
|
||||
"@react-native/virtualized-lists": "0.76.6",
|
||||
"@react-native/assets-registry": "0.76.7",
|
||||
"@react-native/codegen": "0.76.7",
|
||||
"@react-native/community-cli-plugin": "0.76.7",
|
||||
"@react-native/gradle-plugin": "0.76.7",
|
||||
"@react-native/js-polyfills": "0.76.7",
|
||||
"@react-native/normalize-colors": "0.76.7",
|
||||
"@react-native/virtualized-lists": "0.76.7",
|
||||
"abort-controller": "^3.0.0",
|
||||
"anser": "^1.4.9",
|
||||
"ansi-regex": "^5.0.0",
|
||||
@ -17183,9 +17184,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.38.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.38.0.tgz",
|
||||
"integrity": "sha512-a4GD5R1TjEeuCT6ZRiYMHmIf7okbCPEuhQET8bczV6FrQMMlFXA1n+G0KKjdlFCm3TEHV77GxfZB3vZSUQGFpg==",
|
||||
"version": "5.38.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.38.2.tgz",
|
||||
"integrity": "sha512-w8CXxxbFA5zfNsR/i8HZq5bvn18AK0O9jj7hyo1YqkovLxEFa0uP0LCVGZRqiRaKRFxXhELBp8SteeAjEnfeJg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
|
18
package.json
18
package.json
@ -12,6 +12,14 @@
|
||||
"clean": "rm -rf .expo node_modules",
|
||||
"postinstall": "npx tailwindcss -i ./global.css -o ./node_modules/.cache/nativewind/global.css"
|
||||
},
|
||||
"expo": {
|
||||
"doctor": {
|
||||
"reactNativeDirectoryCheck": {
|
||||
"exclude": ["lucide-react-native"],
|
||||
"listUnknownPackages": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-alert-dialog": "^1.1.6",
|
||||
"@react-navigation/material-top-tabs": "^7.1.0",
|
||||
@ -45,18 +53,18 @@
|
||||
"@rn-primitives/types": "~1.1.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"expo": "^52.0.25",
|
||||
"expo": "~52.0.33",
|
||||
"expo-linking": "~7.0.4",
|
||||
"expo-navigation-bar": "~4.0.7",
|
||||
"expo-navigation-bar": "~4.0.8",
|
||||
"expo-router": "~4.0.16",
|
||||
"expo-splash-screen": "~0.29.20",
|
||||
"expo-status-bar": "~2.0.1",
|
||||
"expo-system-ui": "~4.0.7",
|
||||
"expo-system-ui": "~4.0.8",
|
||||
"lucide-react-native": "^0.378.0",
|
||||
"nativewind": "^4.1.23",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-native": "0.76.6",
|
||||
"react-native": "0.76.7",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-pager-view": "^6.5.1",
|
||||
"react-native-reanimated": "~3.16.1",
|
||||
@ -77,4 +85,4 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
}
|
@ -15,5 +15,5 @@
|
||||
".expo/types/**/*.ts",
|
||||
"expo-env.d.ts",
|
||||
"nativewind-env.d.ts"
|
||||
]
|
||||
, "jest.config.js", "jest.setup.js" ]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user