import { configureAuth } from 'react-query-auth'; import { Navigate, useLocation } from 'react-router-dom'; import { z } from 'zod'; import { AuthResponse, User } from '@/types/api'; import { api } from './api-client'; // api call definitions for auth (types, schemas, requests): // these are not part of features as this is a module shared across features const getUser = (): Promise => { return api.get('/auth/me'); }; const logout = (): Promise => { return api.post('/auth/logout'); }; export const loginInputSchema = z.object({ email: z.string().min(1, 'Required').email('Invalid email'), password: z.string().min(5, 'Required'), }); export type LoginInput = z.infer; const loginWithEmailAndPassword = (data: LoginInput): Promise => { return api.post('/auth/login', data); }; export const registerInputSchema = z .object({ email: z.string().min(1, 'Required'), firstName: z.string().min(1, 'Required'), lastName: z.string().min(1, 'Required'), password: z.string().min(1, 'Required'), }) .and( z .object({ teamId: z.string().min(1, 'Required'), teamName: z.null().default(null), }) .or( z.object({ teamName: z.string().min(1, 'Required'), teamId: z.null().default(null), }), ), ); export type RegisterInput = z.infer; const registerWithEmailAndPassword = ( data: RegisterInput, ): Promise => { return api.post('/auth/register', data); }; const authConfig = { userFn: getUser, loginFn: async (data: LoginInput) => { const response = await loginWithEmailAndPassword(data); return response.user; }, registerFn: async (data: RegisterInput) => { const response = await registerWithEmailAndPassword(data); return response.user; }, logoutFn: logout, }; export const { useUser, useLogin, useLogout, useRegister, AuthLoader } = configureAuth(authConfig); export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => { const user = useUser(); const location = useLocation(); if (!user.data) { return ( ); } return children; };