diff --git a/client/src/components/Login/Login.scss b/client/src/components/Login/Login.scss
index 1d2060b561763fe1b18e3ca65d965688d744dbc6..241e470edac1154b1238619c36a9fc838599ceba 100644
--- a/client/src/components/Login/Login.scss
+++ b/client/src/components/Login/Login.scss
@@ -9,4 +9,4 @@
 .login-card {
   width: 20vw;
   min-width: 350px;
-}
\ No newline at end of file
+}
diff --git a/client/src/components/Login/Login.tsx b/client/src/components/Login/Login.tsx
index 350f62d3dcce89159e0068c7be4336f700bae356..271ba52399d798e5a2be136964972ec02bea315d 100644
--- a/client/src/components/Login/Login.tsx
+++ b/client/src/components/Login/Login.tsx
@@ -1,25 +1,39 @@
 import { useState } from 'react';
 import { useNavigate } from 'react-router-dom';
 import { useForm } from 'react-hook-form';
+import { AxiosError } from 'axios';
 import { useAuth } from '../../hooks/useAuth';
+import { loginUser } from '../../services/Login/Login';
 import './Login.scss';
 
-interface ILogin {
+export interface ILoginForm {
   email: string;
   password: string;
 }
 
 export function Login() {
-  const [error, setError] = useState('');
-  const { giveAuth } = useAuth();
+  const { giveAuth, updateUser } = useAuth();
   const navigate = useNavigate();
-  const { register, handleSubmit } = useForm<ILogin>({mode: 'onChange'});
+  const [error, setError] = useState('');
+  const { register, handleSubmit } = useForm<ILoginForm>({mode: 'onChange'});
+
+  const onSubmit = async (formValue: ILoginForm) => {
+    setError('');
+
+    try {
+      const result = await loginUser(formValue);
+      giveAuth();
+      updateUser(result.data);
+      navigate('/customer-dashboard');
+    } catch (error) {
+      const errorMessage = (error as AxiosError).response?.data;
 
-  const onSubmit = (formValue: ILogin) => {
-    setError('TODO: remove me once actual errors are implemented');
-    console.log('ready to make login api call', formValue);
-    giveAuth();
-    navigate('/');
+      if (typeof errorMessage == 'string') {
+        setError(errorMessage);
+      } else {
+        setError('An unexpected error has occurred');
+      }
+    }
   };
 
   return (
@@ -51,4 +65,4 @@ export function Login() {
   );  
 }
 
-export default Login;
\ No newline at end of file
+export default Login;
diff --git a/client/src/components/Register/Register.tsx b/client/src/components/Register/Register.tsx
index d3db23c8f59008459aeea3923ab0d74e7fffc100..7a431c62ef55779c491617f0c54ffdc3ea301aa0 100644
--- a/client/src/components/Register/Register.tsx
+++ b/client/src/components/Register/Register.tsx
@@ -39,7 +39,13 @@ export function Register() {
       updateUser(result.data);
       navigate('/customer-dashboard');
     } catch (error) {
-      setError(((error as AxiosError).response?.data ?? 'unexpected error') as string);
+      const errorMessage = (error as AxiosError).response?.data;
+
+      if (typeof errorMessage == 'string') {
+        setError(errorMessage);
+      } else {
+        setError('An unexpected error has occurred');
+      }
     }
   };
 
diff --git a/client/src/services/Login/Login.ts b/client/src/services/Login/Login.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f29ae643f8a43d357f3a0c46238349b6f9e0bff2
--- /dev/null
+++ b/client/src/services/Login/Login.ts
@@ -0,0 +1,11 @@
+import { AxiosResponse } from 'axios';
+import Api from '../../helpers/Api';
+import { ILoginForm } from '../../components/Login/Login';
+import { IUser } from '../../providers/AuthProvider';
+
+export async function loginUser(form: ILoginForm): Promise<AxiosResponse<IUser>> {
+  return Api.post('User/login', {
+    Email: form.email,
+    Password: form.password
+  });
+}