mirror of
https://github.com/pikami/scrummie-poker.git
synced 2024-12-24 17:34:16 +00:00
Protect routes that need authentication
This commit is contained in:
parent
253d13abd4
commit
c05febd1f5
@ -8,8 +8,9 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { account } from '../appwrite';
|
import { account } from '../appwrite';
|
||||||
|
|
||||||
interface UserContextType {
|
export interface UserContextType {
|
||||||
current: Models.Session | Models.User<Models.Preferences> | null;
|
current: Models.Session | Models.User<Models.Preferences> | null;
|
||||||
|
isLoading: boolean;
|
||||||
login: (email: string, password: string) => Promise<void>;
|
login: (email: string, password: string) => Promise<void>;
|
||||||
logout: () => Promise<void>;
|
logout: () => Promise<void>;
|
||||||
register: (email: string, password: string) => Promise<void>;
|
register: (email: string, password: string) => Promise<void>;
|
||||||
@ -30,11 +31,15 @@ export const UserProvider = (props: PropsWithChildren) => {
|
|||||||
const [user, setUser] = useState<
|
const [user, setUser] = useState<
|
||||||
Models.Session | Models.User<Models.Preferences> | null
|
Models.Session | Models.User<Models.Preferences> | null
|
||||||
>(null);
|
>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
const login = async (email: string, password: string) => {
|
const login = async (email: string, password: string) => {
|
||||||
const loggedIn = await account.createEmailPasswordSession(email, password);
|
const loggedIn = await account.createEmailPasswordSession(email, password);
|
||||||
setUser(loggedIn);
|
setUser(loggedIn);
|
||||||
window.location.replace('/'); // you can use different redirect method for your application
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const redirectPath = params.get('redirect');
|
||||||
|
window.location.replace(redirectPath || '/');
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
@ -50,7 +55,10 @@ export const UserProvider = (props: PropsWithChildren) => {
|
|||||||
const loginAsGuest = async () => {
|
const loginAsGuest = async () => {
|
||||||
const session = await account.createAnonymousSession();
|
const session = await account.createAnonymousSession();
|
||||||
setUser(session);
|
setUser(session);
|
||||||
window.location.replace('/'); // you can use different redirect method for your application
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const redirectPath = params.get('redirect');
|
||||||
|
window.location.replace(redirectPath || '/');
|
||||||
};
|
};
|
||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
@ -59,6 +67,8 @@ export const UserProvider = (props: PropsWithChildren) => {
|
|||||||
setUser(loggedIn);
|
setUser(loggedIn);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setUser(null);
|
setUser(null);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,7 +78,14 @@ export const UserProvider = (props: PropsWithChildren) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<UserContext.Provider
|
<UserContext.Provider
|
||||||
value={{ current: user, login, logout, register, loginAsGuest }}
|
value={{
|
||||||
|
current: user,
|
||||||
|
isLoading,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
register,
|
||||||
|
loginAsGuest,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</UserContext.Provider>
|
</UserContext.Provider>
|
||||||
|
52
src/main.tsx
52
src/main.tsx
@ -2,24 +2,48 @@ import { StrictMode } from 'react';
|
|||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import {
|
import {
|
||||||
createRootRoute,
|
createRootRouteWithContext,
|
||||||
createRoute,
|
createRoute,
|
||||||
createRouter,
|
createRouter,
|
||||||
|
Outlet,
|
||||||
|
redirect,
|
||||||
RouterProvider,
|
RouterProvider,
|
||||||
} from '@tanstack/react-router';
|
} from '@tanstack/react-router';
|
||||||
import Home from './pages/Home';
|
import Home from './pages/Home';
|
||||||
import { UserProvider } from './lib/context/user';
|
import { UserContextType, UserProvider, useUser } from './lib/context/user';
|
||||||
import Login from './pages/Login';
|
import Login from './pages/Login';
|
||||||
import { EstimationSessionProvider } from './lib/context/estimationSession';
|
import { EstimationSessionProvider } from './lib/context/estimationSession';
|
||||||
import { EstimationContextProvider } from './lib/context/estimation';
|
import { EstimationContextProvider } from './lib/context/estimation';
|
||||||
import Estimation from './pages/Estimation/Estimation';
|
import Estimation from './pages/Estimation/Estimation';
|
||||||
|
|
||||||
const rootRoute = createRootRoute();
|
interface RouterContext {
|
||||||
|
userContext: UserContextType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootRoute = createRootRouteWithContext<RouterContext>()({
|
||||||
|
component: () => <Outlet />,
|
||||||
|
});
|
||||||
|
|
||||||
|
const authenticatedRoute = createRoute({
|
||||||
|
id: '_authenticated',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
beforeLoad: async ({ location, context }) => {
|
||||||
|
console.log(context);
|
||||||
|
if (!context.userContext.current) {
|
||||||
|
throw redirect({
|
||||||
|
to: '/login',
|
||||||
|
search: {
|
||||||
|
redirect: location.href,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const indexRoute = createRoute({
|
const indexRoute = createRoute({
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Home,
|
component: Home,
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => authenticatedRoute,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loginRoute = createRoute({
|
const loginRoute = createRoute({
|
||||||
@ -31,15 +55,17 @@ const loginRoute = createRoute({
|
|||||||
const estimationSessionRoute = createRoute({
|
const estimationSessionRoute = createRoute({
|
||||||
path: 'estimate/session/$sessionId',
|
path: 'estimate/session/$sessionId',
|
||||||
component: Estimation,
|
component: Estimation,
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => authenticatedRoute,
|
||||||
});
|
});
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
routeTree: rootRoute.addChildren([
|
routeTree: rootRoute.addChildren([
|
||||||
indexRoute,
|
authenticatedRoute.addChildren([indexRoute, estimationSessionRoute]),
|
||||||
loginRoute,
|
loginRoute,
|
||||||
estimationSessionRoute,
|
|
||||||
]),
|
]),
|
||||||
|
context: {
|
||||||
|
userContext: undefined!,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
@ -48,13 +74,23 @@ declare module '@tanstack/react-router' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const InnerApp = () => {
|
||||||
|
const userContext = useUser();
|
||||||
|
|
||||||
|
return userContext.isLoading ? (
|
||||||
|
<p>Loading...</p>
|
||||||
|
) : (
|
||||||
|
<RouterProvider router={router} context={{ userContext }} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<UserProvider>
|
<UserProvider>
|
||||||
<EstimationSessionProvider>
|
<EstimationSessionProvider>
|
||||||
<EstimationContextProvider>
|
<EstimationContextProvider>
|
||||||
{/* TODO: Move ctx providers to layout */}
|
{/* TODO: Move ctx providers to layout */}
|
||||||
<RouterProvider router={router} />
|
<InnerApp />
|
||||||
</EstimationContextProvider>
|
</EstimationContextProvider>
|
||||||
</EstimationSessionProvider>
|
</EstimationSessionProvider>
|
||||||
</UserProvider>
|
</UserProvider>
|
||||||
|
@ -9,7 +9,7 @@ import CreateTicketForm from './components/CreateTicketForm';
|
|||||||
|
|
||||||
const fibonacciSequence = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 100];
|
const fibonacciSequence = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 100];
|
||||||
|
|
||||||
const route = getRouteApi('/estimate/session/$sessionId');
|
const route = getRouteApi('/_authenticated/estimate/session/$sessionId');
|
||||||
|
|
||||||
const Estimation: React.FC = () => {
|
const Estimation: React.FC = () => {
|
||||||
const { sessionId } = route.useParams();
|
const { sessionId } = route.useParams();
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
} from '../components';
|
} from '../components';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
const route = getRouteApi('/');
|
const route = getRouteApi('/_authenticated/');
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
const user = useUser();
|
const user = useUser();
|
||||||
|
Loading…
Reference in New Issue
Block a user