#Integrating context code for Appwrite authentication with app router
1 messages · Page 1 of 1 (latest)
Here's the error:
./src/hooks/user.tsx
Error:
× You're importing a component that needs createContext. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
│ Learn more:
│
│
╭─[/Projects/my-app/src/hooks/user.tsx:3:1]
3 │ import { redirect } from 'next/navigation';
4 │ import {
5 │ useContext,
6 │ createContext,
· ─────────────
7 │ useEffect,
8 │ useState,
9 │ ReactNode,
╰────
Here's my code for user.tsx
import { account } from '@/utils/appwrite';
import { AppwriteException, Models } from 'appwrite';
import { redirect } from 'next/navigation';
import {
useContext,
createContext,
useEffect,
useState,
ReactNode,
} from 'react';
export interface UserState {
user: Models.User<Models.Preferences> | null;
loading: boolean;
error: string | null;
logout: () => Promise<void>;
login: (email: string, password: string) => Promise<void>;
signup: (email: string, password: string, name: string) => Promise<void>;
}
const defaultState: UserState = {
user: null,
loading: true,
error: null,
logout: async () => {},
signup: async () => {},
login: async () => {},
};
const userContext = createContext<UserState>(defaultState);
type UserProviderProps = {
children: ReactNode;
};
export const UserProvider = ({ children }: UserProviderProps) => {
const [user, setUser] = useState<Models.User<Models.Preferences> | null>(
null
);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const loadAccount = async () => {
try {
const loadedAccount = await account.get();
setUser(loadedAccount);
} catch (error) {
console.error(error);
setError('failed to load user');
} finally {
setLoading(false);
}
};
const login = async (email: string, password: string) => {
console.log('Do you copy?')
try {
await account.createEmailSession(email, password);
await loadAccount();
redirect('/');
} catch (error: any) {
const appwriteException = error as AppwriteException;
console.error(appwriteException.message);
}
};
const signup = async (email: string, password: string, name: string) => {
try {
const session = await account.create('unique()', email, password, name);
setUser(session);
await account.createEmailSession(email, password);
redirect('/');
} catch (error) {
console.error(error);
}
};
const logout = async () => {
await account.deleteSession('current');
setUser(null);
redirect('/');
};
useEffect(() => {
loadAccount();
}, []);
return (
<userContext.Provider
value={{ user, loading, error, logout, login, signup }}
>
{children}
</userContext.Provider>
);
};
export const useUser = () => {
const context = useContext<UserState>(userContext);
return context;
};
I've wrapped the content in my layout.tsx file with the UserProvider.
Any ideas on how I could fix this? Any help is greatly appreciated 🙏