global provider and useAppwrite

This commit is contained in:
dimitar 2025-01-05 08:28:09 +01:00
parent 962d9c7341
commit 321032ee7b
5 changed files with 157 additions and 9 deletions

View File

@ -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>
)
} }

View File

@ -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">

View File

@ -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
View 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
View 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 };
};