global provider and useAppwrite
This commit is contained in:
parent
962d9c7341
commit
321032ee7b
@ -3,6 +3,7 @@ import { useFonts } from "expo-font";
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
// import * as SplashScreen from "expo-splash-screen";
|
// import * as SplashScreen from "expo-splash-screen";
|
||||||
import "./global.css";
|
import "./global.css";
|
||||||
|
import GlobalProvider from "@/lib/globalProvider";
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
const [fontLoaded] = useFonts({
|
const [fontLoaded] = useFonts({
|
||||||
@ -19,5 +20,9 @@ export default function RootLayout() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Stack screenOptions={{headerShown: false}}/>;
|
return(
|
||||||
|
<GlobalProvider>
|
||||||
|
<Stack screenOptions={{headerShown: false}}/>;
|
||||||
|
</GlobalProvider>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,20 @@
|
|||||||
import {View, Text, SafeAreaView, ScrollView, Image, TouchableOpacity} from "react-native";
|
import {View, Text, SafeAreaView, ScrollView, Image, TouchableOpacity, Alert} from "react-native";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import images from "@/constants/images";
|
import images from "@/constants/images";
|
||||||
import icons from "@/constants/icons";
|
import icons from "@/constants/icons";
|
||||||
|
import {login} from "@/lib/appwrite";
|
||||||
|
import {useGlobalContext} from "@/lib/globalProvider";
|
||||||
|
|
||||||
const SignIn = () => {
|
const SignIn = () => {
|
||||||
const handleLogin = () => {}
|
const {refetch, loading, isLoggedIn} = useGlobalContext();
|
||||||
|
const handleLogin = async () => {
|
||||||
|
const result = await login();
|
||||||
|
if (result) {
|
||||||
|
console.log('logon successful');
|
||||||
|
} else {
|
||||||
|
Alert.alert('Login failed')
|
||||||
|
}
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<SafeAreaView className="bg-white h-full">
|
<SafeAreaView className="bg-white h-full">
|
||||||
<ScrollView contentContainerClassName="h-full">
|
<ScrollView contentContainerClassName="h-full">
|
||||||
|
|||||||
@ -55,12 +55,28 @@ export async function login (){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function logOut(): Promise<boolean> {
|
export async function getCurrentUser() {
|
||||||
try {
|
try {
|
||||||
await account.deleteSession(sessionId: 'current');
|
const response = await account.get();
|
||||||
return true;
|
if(response.$id){
|
||||||
|
const userAvatar = avatar.getInitials(response.name)
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
avatar: userAvatar.toString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to log out user:", error);
|
console.error(error)
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export async function logOut(): Promise<boolean> {
|
||||||
|
// try {
|
||||||
|
// await account.deleteSession(sessionId: 'current');
|
||||||
|
// return true;
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Failed to log out user:", error);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
62
lib/globalProvider.tsx
Normal file
62
lib/globalProvider.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import React, { createContext, useContext, ReactNode } from "react";
|
||||||
|
|
||||||
|
import { getCurrentUser } from "./appwrite";
|
||||||
|
import { useAppwrite } from "./useAppwrite";
|
||||||
|
import { Redirect } from "expo-router";
|
||||||
|
// import {replace} from "@remix-run/router";
|
||||||
|
|
||||||
|
interface GlobalContextType {
|
||||||
|
isLoggedIn: boolean;
|
||||||
|
user: User | null;
|
||||||
|
loading: boolean;
|
||||||
|
refetch: (newParams?: Record<string, string | number>) => Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
$id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
avatar: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GlobalContext = createContext<GlobalContextType | undefined>(undefined);
|
||||||
|
|
||||||
|
interface GlobalProviderProps {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GlobalProvider = ({ children }: {children: ReactNode}) => {
|
||||||
|
const {
|
||||||
|
data: user,
|
||||||
|
loading,
|
||||||
|
refetch,
|
||||||
|
} = useAppwrite({
|
||||||
|
fn: getCurrentUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLoggedIn = !!user;
|
||||||
|
console.log(JSON.stringify(user));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GlobalContext.Provider
|
||||||
|
value={{
|
||||||
|
isLoggedIn,
|
||||||
|
user,
|
||||||
|
loading,
|
||||||
|
refetch,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</GlobalContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGlobalContext = (): GlobalContextType => {
|
||||||
|
const context = useContext(GlobalContext);
|
||||||
|
if (!context)
|
||||||
|
throw new Error("useGlobalContext must be used within a GlobalProvider");
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GlobalProvider;
|
||||||
55
lib/useAppwrite.ts
Normal file
55
lib/useAppwrite.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Alert } from "react-native";
|
||||||
|
import { useEffect, useState, useCallback } from "react";
|
||||||
|
|
||||||
|
interface UseAppwriteOptions<T, P extends Record<string, string | number>> {
|
||||||
|
fn: (params: P) => Promise<T>;
|
||||||
|
params?: P;
|
||||||
|
skip?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UseAppwriteReturn<T, P> {
|
||||||
|
data: T | null;
|
||||||
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
refetch: (newParams: P) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAppwrite = <T, P extends Record<string, string | number>>({
|
||||||
|
fn,
|
||||||
|
params = {} as P,
|
||||||
|
skip = false,
|
||||||
|
}: UseAppwriteOptions<T, P>): UseAppwriteReturn<T, P> => {
|
||||||
|
const [data, setData] = useState<T | null>(null);
|
||||||
|
const [loading, setLoading] = useState(!skip);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const fetchData = useCallback(
|
||||||
|
async (fetchParams: P) => {
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await fn(fetchParams);
|
||||||
|
setData(result);
|
||||||
|
} catch (err: unknown) {
|
||||||
|
const errorMessage =
|
||||||
|
err instanceof Error ? err.message : "An unknown error occurred";
|
||||||
|
setError(errorMessage);
|
||||||
|
Alert.alert("Error", errorMessage);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[fn]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!skip) {
|
||||||
|
fetchData(params);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const refetch = async (newParams: P) => await fetchData(newParams);
|
||||||
|
|
||||||
|
return { data, loading, error, refetch };
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user