Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 22 additions & 111 deletions src/api/services/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,20 @@ import axios from 'axios';
import api from '../api';
import { SafeUser, UserLogInInput, UserSignUpInput } from 'models/user.model';

export interface MeResponse {
message: string;
user: SafeUser;
}

export type FieldErrors = Partial<{
username: string;
password: string;
name_first: string;
name_last: string;
email: string;
}>;

export type LoginErrorDetails =
| {
type: 'dbError';
message: string;
}
| {
type: 'fieldErrors';
fieldErrors: FieldErrors;
};

export type LoginResponse = {
token: string | null;
errors: LoginErrorDetails | null;
};

export type SignupFieldErrors = Partial<{
email: string;
username: string;
password: string;
}>;

export type SignupErrorDetails =
| {
type: 'dbError';
message: string;
}
| {
type: 'fieldErrors';
fieldErrors: SignupFieldErrors;
};

export type SignupResponse =
| {
insertedId: string;
errors: null;
}
| {
insertedId: null;
errors: SignupErrorDetails;
};
import {
MeSuccessResponse,
LoginSuccessResponse,
LoginErrorResponse,
LoginResponse,
SignupSuccessResponse,
SignupErrorResponse,
SignupResponse,
} from 'services/auth.service.ts';
import { ErrorResponse } from 'services/general.service.ts';

export const getMe = async (): Promise<SafeUser | null> => {
try {
const { data } = await api.get<MeResponse>('/auth/me');
const { data } = await api.get<MeSuccessResponse>('/auth/me');
return data.user;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401) {
Expand All @@ -72,40 +29,18 @@ export const login = async (
credentials: UserLogInInput,
): Promise<LoginResponse> => {
try {
const { data } = await api.post<{ token: string }>(
const { data } = await api.post<LoginSuccessResponse>(
'/auth/login',
credentials,
);
return {
token: data.token,
errors: null,
};
return data;
} catch (error) {
if (
axios.isAxiosError(error) &&
error.response?.data?.errors?.fieldErrors
) {
const fieldErrors = error.response.data.errors.fieldErrors;

return {
token: null,
errors: {
type: 'fieldErrors',
fieldErrors: {
username: fieldErrors.username,
password: fieldErrors.password,
},
},
};
if (axios.isAxiosError(error) && error.response?.data?.errors) {
return error.response.data as LoginErrorResponse;
}

if (axios.isAxiosError(error) && error.response?.data?.error) {
return {
token: null,
errors: {
type: 'dbError',
message: error.response.data.error,
},
};
return error.response.data as ErrorResponse;
}

throw error;
Expand All @@ -126,42 +61,18 @@ export const signup = async (
credentials: UserSignUpInput,
): Promise<SignupResponse> => {
try {
const { data } = await api.post<{ insertedId: string }>(
const { data } = await api.post<SignupSuccessResponse>(
'/auth/signup',
credentials,
);
return {
insertedId: data.insertedId,
errors: null,
};
return data as SignupSuccessResponse;
} catch (error) {
if (
axios.isAxiosError(error) &&
error.response?.data?.errors?.fieldErrors
) {
const fieldErrors = error.response.data.errors.fieldErrors;

return {
insertedId: null,
errors: {
type: 'fieldErrors',
fieldErrors: {
email: fieldErrors.email,
username: fieldErrors.username,
password: fieldErrors.password,
},
},
};
if (axios.isAxiosError(error) && error.response?.data?.errors) {
return error.response.data as SignupErrorResponse;
}

if (axios.isAxiosError(error) && error.response?.data?.error) {
return {
insertedId: null,
errors: {
type: 'dbError',
message: error.response.data.error,
},
};
return error.response.data as ErrorResponse;
}

throw error;
Expand Down
31 changes: 13 additions & 18 deletions src/api/services/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import axios from 'axios';
import api from '../api';

import { Event } from 'models/event.model';
import {
GeneralResponse,
MessageResponse,
ErrorResponse,
} from 'services/general.service';

export const getEventByMode = async (modes: string[]) => {
console.log('getting events by mode...');
Expand Down Expand Up @@ -31,38 +36,28 @@ export const getEventById = async (id: string) => {
return events;
};

export interface UpdateEventResponse {
message: string;
}

export const updateEventById = async (
id: string,
event: Event,
): Promise<UpdateEventResponse | null> => {
): Promise<GeneralResponse> => {
try {
const { data } = await api.put<UpdateEventResponse>('/events/' + id, event);
return data;
const { data } = await api.put<GeneralResponse>('/events/' + id, event);
return data as MessageResponse;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401) {
return null;
return error.response.data as ErrorResponse;
}
throw error;
}
};

export interface DeleteEventResponse {
message: string;
}

export const deleteEventById = async (
id: string,
): Promise<DeleteEventResponse | null> => {
export const deleteEventById = async (id: string): Promise<GeneralResponse> => {
try {
const { data } = await api.delete<DeleteEventResponse>('/events/' + id);
return data;
const { data } = await api.delete<GeneralResponse>('/events/' + id);
return data as MessageResponse;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401) {
return null;
return error.response.data as ErrorResponse;
}
throw error;
}
Expand Down
5 changes: 3 additions & 2 deletions src/pages/EditEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import NavBar from '../components/major/nav-bar';
import FormInput from '../components/minor/FormInput';

import { Event } from 'models/event.model.ts';
import { GeneralResponse } from 'services/general.service.ts';

export default function EditEvent() {
let { id } = useParams();
Expand Down Expand Up @@ -47,8 +48,8 @@ export default function EditEvent() {
e.preventDefault();

if (!formData) return;
const result = await updateEventById(eventId, formData);
if (result && result.message) setMessage(result.message);
const result: GeneralResponse = await updateEventById(eventId, formData);
if (result && 'message' in result) setMessage(result.message);
}

return (
Expand Down
31 changes: 13 additions & 18 deletions src/pages/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import DirectButton from '../components/minor/DirectButton';
import FormInput from '../components/minor/FormInput';
import { useState } from 'react';
import { useNavigate } from 'react-router';
import { FieldErrors, login } from '../api/services/auth.ts';
import { login } from '../api/services/auth.ts';
import { useAuth } from '../auth/useAuth.tsx';
import { UserLogInInput } from 'models/user.model.ts';
import { LoginErrorDetails, LoginResponse } from 'services/auth.service.ts';

export default function Login() {
const [formData, setFormData] = useState<UserLogInInput>({
Expand All @@ -26,12 +27,12 @@ export default function Login() {
setFormData((prevState) => ({ ...prevState, [name]: value }));
};

const displayErrors = (error: string | FieldErrors) => {
const displayErrors = (error: string | LoginErrorDetails) => {
if (typeof error === 'string') {
setFieldErrorStates({ username: false, password: false });
setErrorMessage(error);
} else {
const { username, password } = error;
const { username, password } = error.fieldErrors;
const messages = [
username && `Username too short`,
password && `Password too short`,
Expand All @@ -52,24 +53,18 @@ export default function Login() {

async function handleLogin(e: React.FormEvent) {
e.preventDefault();
const { token, errors } = await login(formData);
const result: LoginResponse = await login(formData);

if (token) {
localStorage.setItem('token', token);
if ('token' in result) {
localStorage.setItem('token', result.token);
await refreshUser();
navigate('/userhome');
} else if (errors) {
switch (errors.type) {
case 'dbError':
displayErrors(errors.message);
break;
case 'fieldErrors':
displayErrors(errors.fieldErrors);
break;
default:
displayErrors('An unknown error occurred.');
break;
}
} else if ('errors' in result) {
displayErrors(result.errors);
} else if ('error' in result) {
displayErrors(result.error);
} else {
displayErrors('An unknown error occurred.');
}
}

Expand Down
Loading