mirror of
https://github.com/SrIzan10/featheroom.git
synced 2026-06-06 00:56:49 +00:00
feat: query classes and screen to show them
This commit is contained in:
@@ -20,45 +20,6 @@ const TabLayout = () => {
|
||||
name="index"
|
||||
options={{
|
||||
title: 'Home',
|
||||
headerRight: () => (
|
||||
<>
|
||||
<Tooltip title="Search">
|
||||
<Appbar.Action
|
||||
icon="magnify"
|
||||
onPress={() => router.push('/search')}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
statusBarHeight={48}
|
||||
visible={visible}
|
||||
onDismiss={() => setVisible(false)}
|
||||
anchor={
|
||||
<Tooltip title="Options">
|
||||
<Appbar.Action
|
||||
icon="dots-vertical"
|
||||
onPress={() => setVisible(true)}
|
||||
/>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<Menu.Item
|
||||
title="Settings"
|
||||
leadingIcon="cog"
|
||||
onPress={() => router.push('/(tabs)/settings')}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Stack Navigation"
|
||||
leadingIcon="card-multiple-outline"
|
||||
onPress={() => router.push('/modal')}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Drawer Navigation"
|
||||
leadingIcon="gesture-swipe"
|
||||
onPress={() => router.push('/drawer')}
|
||||
/>
|
||||
</Menu>
|
||||
</>
|
||||
),
|
||||
tabBarIcon: (props) => (
|
||||
<MaterialCommunityIcons
|
||||
{...props}
|
||||
@@ -72,14 +33,6 @@ const TabLayout = () => {
|
||||
name="settings"
|
||||
options={{
|
||||
title: 'Settings',
|
||||
headerRight: () => (
|
||||
<Tooltip title="Drawer Navigation">
|
||||
<Appbar.Action
|
||||
icon="gesture-swipe"
|
||||
onPress={() => router.push('/drawer')}
|
||||
/>
|
||||
</Tooltip>
|
||||
),
|
||||
tabBarIcon: (props) => (
|
||||
<MaterialCommunityIcons
|
||||
{...props}
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
import { List, Surface, Text } from 'react-native-paper'
|
||||
|
||||
import { useCourses } from '@/lib/clients/classroom'
|
||||
import { View } from 'react-native'
|
||||
import React from 'react'
|
||||
import { Surface } from 'react-native-paper'
|
||||
import { Link } from 'expo-router'
|
||||
import Loading from '@/lib/ui/components/Loading'
|
||||
|
||||
import { ScreenInfo, styles } from '@/lib/ui'
|
||||
function TabsHome() {
|
||||
const { data, isLoading } = useCourses()
|
||||
|
||||
const TabsHome = () => (
|
||||
<Surface style={styles.screen}>
|
||||
<ScreenInfo title="Home" path="app/(tabs)/index.tsx" />
|
||||
</Surface>
|
||||
)
|
||||
if (isLoading) {
|
||||
return <Loading />
|
||||
}
|
||||
|
||||
return (
|
||||
<Surface className="flex-1">
|
||||
<Text>My Courses</Text>
|
||||
{data?.courses.map((course) => (
|
||||
<Link href={`/drawer/courses/${course.id}`} key={course.id}>
|
||||
{course.name}
|
||||
</Link>
|
||||
))}
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabsHome
|
||||
|
||||
@@ -75,7 +75,6 @@ const RootLayoutNav = () => {
|
||||
>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="drawer" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="search" options={{ title: 'Search' }} />
|
||||
<Stack.Screen
|
||||
name="modal"
|
||||
options={{ title: 'Modal', presentation: 'modal' }}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { router } from 'expo-router'
|
||||
import { Drawer } from 'expo-router/drawer'
|
||||
import React from 'react'
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
||||
import { Appbar, Menu, Tooltip, useTheme } from 'react-native-paper'
|
||||
import { useTheme } from 'react-native-paper'
|
||||
|
||||
import { DrawerContent, DrawerHeader } from '@/lib/ui'
|
||||
import { DrawerContent, DrawerHeader } from '../../../lib/ui/components'
|
||||
|
||||
const DrawerLayout = () => {
|
||||
const theme = useTheme()
|
||||
const [visible, setVisible] = React.useState(false)
|
||||
|
||||
return (
|
||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||
@@ -32,64 +29,10 @@ const DrawerLayout = () => {
|
||||
}}
|
||||
>
|
||||
<Drawer.Screen
|
||||
name="index"
|
||||
name="courses/[id]"
|
||||
options={{
|
||||
drawerLabel: 'Home',
|
||||
title: 'Home',
|
||||
headerRight: () => (
|
||||
<>
|
||||
<Tooltip title="Search">
|
||||
<Appbar.Action
|
||||
icon="magnify"
|
||||
onPress={() => router.push('/search')}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
statusBarHeight={48}
|
||||
visible={visible}
|
||||
onDismiss={() => setVisible(false)}
|
||||
anchor={
|
||||
<Tooltip title="Options">
|
||||
<Appbar.Action
|
||||
icon="dots-vertical"
|
||||
onPress={() => setVisible(true)}
|
||||
/>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<Menu.Item
|
||||
title="Settings"
|
||||
leadingIcon="cog"
|
||||
onPress={() => router.push('/drawer/settings')}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Stack Navigation"
|
||||
leadingIcon="card-multiple-outline"
|
||||
onPress={() => router.push('/modal')}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Drawer Navigation"
|
||||
leadingIcon="gesture-swipe"
|
||||
onPress={() => router.push('/drawer')}
|
||||
/>
|
||||
</Menu>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Drawer.Screen
|
||||
name="settings"
|
||||
options={{
|
||||
drawerLabel: 'Settings',
|
||||
title: 'Settings',
|
||||
headerRight: () => (
|
||||
<Tooltip title="Stack Navigation">
|
||||
<Appbar.Action
|
||||
icon="card-multiple-outline"
|
||||
onPress={() => router.push('/modal')}
|
||||
/>
|
||||
</Tooltip>
|
||||
),
|
||||
drawerLabel: 'Courses',
|
||||
title: 'Courses',
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
|
||||
20
app/(app)/drawer/courses/[id].tsx
Normal file
20
app/(app)/drawer/courses/[id].tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useCourse } from '@/lib/clients/classroom'
|
||||
import Loading from '@/lib/ui/components/Loading'
|
||||
import { useLocalSearchParams } from 'expo-router'
|
||||
import { Surface, Text } from 'react-native-paper'
|
||||
|
||||
export default function Courses() {
|
||||
const { id } = useLocalSearchParams() as { id: string }
|
||||
const { data: course, isLoading } = useCourse(id)
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading />
|
||||
}
|
||||
|
||||
return (
|
||||
<Surface className="flex-1">
|
||||
<Text>hi this is class with name {course?.name}</Text>
|
||||
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
5
app/(app)/drawer/courses/index.tsx
Normal file
5
app/(app)/drawer/courses/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Text } from 'react-native-paper'
|
||||
|
||||
export default function Index() {
|
||||
return <Text>nuh uh</Text>
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Surface } from 'react-native-paper'
|
||||
|
||||
import { ScreenInfo, styles } from '@/lib/ui'
|
||||
|
||||
const DrawerHome = () => (
|
||||
<Surface style={styles.screen}>
|
||||
<ScreenInfo title="Home" path="app/drawer/index.tsx" />
|
||||
</Surface>
|
||||
)
|
||||
|
||||
export default DrawerHome
|
||||
@@ -1,254 +0,0 @@
|
||||
import * as SecureStore from 'expo-secure-store'
|
||||
import React from 'react'
|
||||
import { Platform, useColorScheme } from 'react-native'
|
||||
import {
|
||||
Surface,
|
||||
List,
|
||||
Menu,
|
||||
Button,
|
||||
IconButton,
|
||||
Snackbar,
|
||||
Icon,
|
||||
} from 'react-native-paper'
|
||||
|
||||
import { Color, Setting } from '@/lib/types'
|
||||
import { Colors, LoadingIndicator, ScreenInfo, styles } from '@/lib/ui'
|
||||
|
||||
const Settings = () => {
|
||||
const colorScheme = useColorScheme()
|
||||
const [loading, setLoading] = React.useState<boolean>(false)
|
||||
const [message, setMessage] = React.useState({ visible: false, content: '' })
|
||||
const [settings, setSettings] = React.useState<Setting>({
|
||||
color: 'default',
|
||||
theme: 'auto',
|
||||
})
|
||||
const [display, setDisplay] = React.useState({
|
||||
color: false,
|
||||
theme: false,
|
||||
})
|
||||
|
||||
React.useEffect(() => {
|
||||
setLoading(true)
|
||||
|
||||
if (Platform.OS !== 'web') {
|
||||
SecureStore.getItemAsync('settings')
|
||||
.then((result) =>
|
||||
setSettings(JSON.parse(result ?? JSON.stringify(settings))),
|
||||
)
|
||||
.catch((res) =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: res.message,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const themeColors =
|
||||
Colors[
|
||||
settings.theme === 'auto' ? (colorScheme ?? 'light') : settings.theme
|
||||
]
|
||||
|
||||
return (
|
||||
<Surface style={{ flex: 1 }}>
|
||||
{loading ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<Surface elevation={0}>
|
||||
<List.AccordionGroup>
|
||||
<List.Accordion
|
||||
id="1"
|
||||
title="Appearance"
|
||||
left={(props) => <List.Icon {...props} icon="palette" />}
|
||||
>
|
||||
<List.Item
|
||||
title="Mode"
|
||||
description="Change Mode"
|
||||
left={(props) => (
|
||||
<List.Icon
|
||||
{...props}
|
||||
icon={
|
||||
settings.theme === 'auto'
|
||||
? 'theme-light-dark'
|
||||
: settings.theme === 'light'
|
||||
? 'weather-sunny'
|
||||
: 'weather-night'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
right={(props) => (
|
||||
<Menu
|
||||
visible={display.theme}
|
||||
onDismiss={() => setDisplay({ ...display, theme: false })}
|
||||
anchor={
|
||||
<IconButton
|
||||
{...props}
|
||||
icon="pencil"
|
||||
onPress={() => setDisplay({ ...display, theme: true })}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Menu.Item
|
||||
title="System"
|
||||
leadingIcon="theme-light-dark"
|
||||
trailingIcon={
|
||||
settings.theme === 'auto' ? 'check' : undefined
|
||||
}
|
||||
onPress={() => {
|
||||
setSettings({ ...settings, theme: 'auto' })
|
||||
setDisplay({ ...display, theme: false })
|
||||
}}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Light Mode"
|
||||
leadingIcon="weather-sunny"
|
||||
trailingIcon={
|
||||
settings.theme === 'light' ? 'check' : undefined
|
||||
}
|
||||
onPress={() => {
|
||||
setSettings({ ...settings, theme: 'light' })
|
||||
setDisplay({ ...display, theme: false })
|
||||
}}
|
||||
/>
|
||||
<Menu.Item
|
||||
title="Dark Mode"
|
||||
leadingIcon="weather-night"
|
||||
trailingIcon={
|
||||
settings.theme === 'dark' ? 'check' : undefined
|
||||
}
|
||||
onPress={() => {
|
||||
setSettings({ ...settings, theme: 'dark' })
|
||||
setDisplay({ ...display, theme: false })
|
||||
}}
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
/>
|
||||
<List.Item
|
||||
title="Color"
|
||||
description="Change Color"
|
||||
left={(props) => (
|
||||
<List.Icon
|
||||
{...props}
|
||||
icon="palette-swatch-variant"
|
||||
color={
|
||||
Colors[
|
||||
settings.theme === 'auto'
|
||||
? (colorScheme ?? 'light')
|
||||
: settings.theme
|
||||
][settings.color]?.primary
|
||||
}
|
||||
/>
|
||||
)}
|
||||
right={(props) => (
|
||||
<Menu
|
||||
visible={display.color}
|
||||
onDismiss={() => setDisplay({ ...display, color: false })}
|
||||
anchor={
|
||||
<IconButton
|
||||
{...props}
|
||||
icon="pencil"
|
||||
onPress={() => setDisplay({ ...display, color: true })}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{Object.keys(Colors.light).map((color) => (
|
||||
<Surface
|
||||
key={color}
|
||||
elevation={0}
|
||||
style={{
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Surface
|
||||
elevation={0}
|
||||
style={{
|
||||
padding: 4,
|
||||
marginLeft: 8,
|
||||
borderRadius: 16,
|
||||
backgroundColor:
|
||||
color !== settings.color
|
||||
? undefined
|
||||
: themeColors[color]?.primary,
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
size={24}
|
||||
source="palette"
|
||||
color={
|
||||
color !== settings.color
|
||||
? themeColors[color as Color]?.primary
|
||||
: themeColors[color].onPrimary
|
||||
}
|
||||
/>
|
||||
</Surface>
|
||||
|
||||
<Menu.Item
|
||||
key={color}
|
||||
title={color}
|
||||
onPress={() => {
|
||||
setSettings({
|
||||
...settings,
|
||||
color: color as Color,
|
||||
})
|
||||
setDisplay({ ...display, color: false })
|
||||
}}
|
||||
/>
|
||||
</Surface>
|
||||
))}
|
||||
</Menu>
|
||||
)}
|
||||
/>
|
||||
</List.Accordion>
|
||||
</List.AccordionGroup>
|
||||
</Surface>
|
||||
)}
|
||||
|
||||
<Surface elevation={0} style={styles.screen}>
|
||||
<ScreenInfo title="Settings" path="app/(tabs)/settings.tsx" />
|
||||
</Surface>
|
||||
|
||||
<Button
|
||||
mode="contained"
|
||||
style={{ margin: 16 }}
|
||||
onPress={() =>
|
||||
Platform.OS !== 'web'
|
||||
? SecureStore.setItemAsync('settings', JSON.stringify(settings))
|
||||
.then(() =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: 'Please restart the app to apply changes.',
|
||||
}),
|
||||
)
|
||||
.catch((res) =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: res.message,
|
||||
}),
|
||||
)
|
||||
: setMessage({
|
||||
visible: true,
|
||||
content: 'This feature is not available on the web.',
|
||||
})
|
||||
}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
|
||||
<Snackbar
|
||||
visible={message.visible}
|
||||
onDismiss={() => setMessage({ ...message, visible: false })}
|
||||
onIconPress={() => setMessage({ ...message, visible: false })}
|
||||
>
|
||||
{message.content}
|
||||
</Snackbar>
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
|
||||
export default Settings
|
||||
@@ -1,38 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Searchbar, Surface } from 'react-native-paper'
|
||||
|
||||
import { ScreenInfo, styles } from '@/lib/ui'
|
||||
|
||||
const Search = () => {
|
||||
const [query, setQuery] = React.useState('')
|
||||
const [loading, setLoading] = React.useState(false)
|
||||
|
||||
// Search logic
|
||||
React.useEffect(() => {
|
||||
if (query !== '') {
|
||||
setLoading(true)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setLoading(false)
|
||||
}, 1000)
|
||||
}, [query])
|
||||
|
||||
return (
|
||||
<Surface style={{ flex: 1, gap: 16 }}>
|
||||
<Searchbar
|
||||
value={query}
|
||||
loading={loading}
|
||||
onChangeText={(v) => setQuery(v)}
|
||||
placeholder="Type here to search..."
|
||||
style={{ marginTop: 16, marginHorizontal: 16 }}
|
||||
/>
|
||||
|
||||
<Surface style={styles.screen}>
|
||||
<ScreenInfo title="Search" path="app/search.tsx" />
|
||||
</Surface>
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
|
||||
export default Search
|
||||
@@ -8,6 +8,9 @@ import { Setting } from '@/lib/types'
|
||||
import { Themes } from '@/lib/ui'
|
||||
|
||||
import '../global.css'
|
||||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { queryClient } from '@/lib/clients/classroom'
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
||||
|
||||
export default function Root() {
|
||||
const colorScheme = useColorScheme()
|
||||
@@ -39,9 +42,11 @@ export default function Root() {
|
||||
][settings.color]
|
||||
}
|
||||
>
|
||||
<AuthProvider>
|
||||
<Slot />
|
||||
</AuthProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<Slot />
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</PaperProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useRouter } from 'expo-router'
|
||||
import { useEffect } from 'react'
|
||||
import { useColorScheme, View } from 'react-native'
|
||||
import { Button, Text } from 'react-native-paper'
|
||||
import { verifyInstallation } from 'nativewind'
|
||||
|
||||
import { useAuth } from '@/lib/providers/auth'
|
||||
|
||||
@@ -9,6 +10,7 @@ function Login() {
|
||||
const { signIn, user } = useAuth()
|
||||
const router = useRouter()
|
||||
const colorScheme = useColorScheme()
|
||||
verifyInstallation()
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = function (api: { cache: (arg0: boolean) => void }) {
|
||||
module.exports = function (api) {
|
||||
api.cache(true)
|
||||
return {
|
||||
presets: [
|
||||
67
lib/clients/classroom.ts
Normal file
67
lib/clients/classroom.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/* eslint-disable no-throw-literal */
|
||||
import { type classroom_v1 } from '@googleapis/classroom'
|
||||
import { GoogleSignin } from '@react-native-google-signin/google-signin'
|
||||
import { QueryClient, useQuery } from '@tanstack/react-query'
|
||||
|
||||
type ApiError = {
|
||||
message: string
|
||||
status: number
|
||||
}
|
||||
|
||||
// Query Client
|
||||
export const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 1000 * 60, // 1 minute
|
||||
retry: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// API Functions
|
||||
const BASE_URL = 'https://classroom.googleapis.com'
|
||||
|
||||
async function fetchApi<T>(
|
||||
endpoint: string,
|
||||
options?: RequestInit,
|
||||
): Promise<T> {
|
||||
const token = (await GoogleSignin.getTokens()).accessToken
|
||||
const response = await fetch(`${BASE_URL}${endpoint}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(token && { Authorization: `Bearer ${token}` }),
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw { message: response.statusText, status: response.status } as ApiError
|
||||
}
|
||||
|
||||
return response.json()
|
||||
}
|
||||
|
||||
// Query Keys
|
||||
export const keys = {
|
||||
courses: {
|
||||
all: ['courses'],
|
||||
one: (id: string) => ['courses', id],
|
||||
},
|
||||
}
|
||||
|
||||
// Hooks
|
||||
export function useCourses() {
|
||||
return useQuery({
|
||||
queryKey: keys.courses.all,
|
||||
queryFn: () =>
|
||||
fetchApi<{ courses: classroom_v1.Schema$Course[] }>('/v1/courses'),
|
||||
})
|
||||
}
|
||||
|
||||
export function useCourse(id: string) {
|
||||
return useQuery({
|
||||
queryKey: keys.courses.one(id),
|
||||
queryFn: () => fetchApi<classroom_v1.Schema$Course>(`/v1/courses/${id}`),
|
||||
})
|
||||
}
|
||||
@@ -14,18 +14,6 @@ const DrawerContent = (props: DrawerContentProps) => (
|
||||
icon="arrow-left"
|
||||
onPress={() => router.replace('/')}
|
||||
/>
|
||||
<Drawer.Item
|
||||
label="Home"
|
||||
icon="home"
|
||||
active={props.navProps.state.index === 0}
|
||||
onPress={() => router.push('/drawer')}
|
||||
/>
|
||||
<Drawer.Item
|
||||
label="Settings"
|
||||
icon="cog"
|
||||
active={props.navProps.state.index === 2}
|
||||
onPress={() => router.push('/drawer/settings')}
|
||||
/>
|
||||
</Drawer.Section>
|
||||
)
|
||||
|
||||
|
||||
9
lib/ui/components/Loading.tsx
Normal file
9
lib/ui/components/Loading.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ActivityIndicator, Surface } from 'react-native-paper'
|
||||
|
||||
export default function Loading() {
|
||||
return (
|
||||
<Surface className="flex-1 h-screen flex justify-center items-center">
|
||||
<ActivityIndicator size="large" />
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
@@ -2,6 +2,6 @@ const { getDefaultConfig } = require('expo/metro-config')
|
||||
const { withNativeWind } = require('nativewind/metro')
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const config = getDefaultConfig(__dirname)
|
||||
const config = getDefaultConfig(__dirname, { isCSSEnabled: true })
|
||||
|
||||
module.exports = withNativeWind(config, { input: './global.css' })
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
"@expo-google-fonts/jetbrains-mono": "^0.2.3",
|
||||
"@expo-google-fonts/noto-sans": "^0.2.3",
|
||||
"@expo/vector-icons": "^14.0.0",
|
||||
"@googleapis/classroom": "^4.4.0",
|
||||
"@react-native-google-signin/google-signin": "^13.1.0",
|
||||
"@react-navigation/drawer": "^6.6.15",
|
||||
"@react-navigation/native": "^6.0.2",
|
||||
"@shopify/flash-list": "1.6.4",
|
||||
"@shopify/react-native-skia": "1.2.3",
|
||||
"@tanstack/react-query": "^5.59.16",
|
||||
"expo": "~51.0.31",
|
||||
"expo-font": "~12.0.5",
|
||||
"expo-image": "~1.13.0",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
// NOTE: Update this to include the paths to all of your component files.
|
||||
content: ["./app/**/*.{js,jsx,ts,tsx}", "./lib/**/*.{js,jsx,ts,tsx}"],
|
||||
presets: [require("nativewind/preset")],
|
||||
content: ['./app/**/*.{js,jsx,ts,tsx}', './lib/**/*.{js,jsx,ts,tsx}'],
|
||||
presets: [require('nativewind/preset')],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"**/*.tsx",
|
||||
".expo/types/**/*.ts",
|
||||
"expo-env.d.ts",
|
||||
"app/(app)/plushtml.old",
|
||||
"nativewind-env.d.ts"
|
||||
, "babel.config.js" ]
|
||||
, "babel.config.js", "app/(app)/drawer/_layout.tsx" ]
|
||||
}
|
||||
Reference in New Issue
Block a user