diff --git a/src/api/auth/use-login.ts b/src/api/auth/use-login.ts
index 599c917fe..8c54cb739 100644
--- a/src/api/auth/use-login.ts
+++ b/src/api/auth/use-login.ts
@@ -3,8 +3,7 @@ import { createMutation } from 'react-query-kit';
import { client } from '../common';
type Variables = {
- email?: string; // optional because API doesn't require email
- username: string;
+ email: string;
password: string;
expiresInMins?: number;
};
@@ -19,11 +18,13 @@ type Response = {
const login = async (variables: Variables) => {
const { data } = await client({
- url: 'auth/login',
+ url: '/v1/users/sign_in',
method: 'POST',
data: {
- username: variables.username,
- password: variables.password,
+ user: {
+ email: variables.email,
+ password: variables.password,
+ },
},
headers: {
'Content-Type': 'application/json',
diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx
index 0870c98b1..9fafc0531 100644
--- a/src/app/_layout.tsx
+++ b/src/app/_layout.tsx
@@ -33,8 +33,8 @@ export default function RootLayout() {
-
+
);
diff --git a/src/app/sign-in.tsx b/src/app/sign-in.tsx
new file mode 100644
index 000000000..0cfcad314
--- /dev/null
+++ b/src/app/sign-in.tsx
@@ -0,0 +1,30 @@
+import { useRouter } from 'expo-router';
+import { showMessage } from 'react-native-flash-message';
+
+import { useLogin } from '@/api/auth/use-login';
+import type { LoginFormProps } from '@/components/login-form';
+import { LoginForm } from '@/components/login-form';
+import { useAuth } from '@/core';
+import { FocusAwareStatusBar } from '@/ui';
+
+export default function Login() {
+ const router = useRouter();
+ const signIn = useAuth.use.signIn();
+ const { mutate: login } = useLogin({
+ onSuccess: (data) => {
+ signIn({ access: data.accessToken, refresh: data.refreshToken });
+ router.push('/');
+ },
+ onError: (error) => showMessage({ message: error.message, type: 'danger' }),
+ });
+
+ const onSubmit: LoginFormProps['onSubmit'] = (data) => {
+ login(data);
+ };
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/src/components/login-form.test.tsx b/src/components/login-form.test.tsx
index e86cf490c..f0f945996 100644
--- a/src/components/login-form.test.tsx
+++ b/src/components/login-form.test.tsx
@@ -1,12 +1,9 @@
-import { cleanup, fireEvent, render, screen, waitFor } from '@/core/test-utils';
+import { cleanup, fireEvent, render, screen } from '@/core/test-utils';
-import type { LoginFormProps } from './login-form';
import { LoginForm } from './login-form';
afterEach(cleanup);
-const onSubmitMock: jest.Mock = jest.fn();
-
describe('LoginForm Form ', () => {
const LOGIN_BUTTON = 'login-button';
it('renders correctly', async () => {
@@ -18,9 +15,9 @@ describe('LoginForm Form ', () => {
render();
const button = screen.getByTestId(LOGIN_BUTTON);
- expect(screen.queryByText(/Username is required/i)).not.toBeOnTheScreen();
+ expect(screen.queryByText(/Email is required/i)).not.toBeOnTheScreen();
fireEvent.press(button);
- expect(await screen.findByText(/Username is required/i)).toBeOnTheScreen();
+ expect(await screen.findByText(/Email is required/i)).toBeOnTheScreen();
expect(screen.getByText(/Password is required/i)).toBeOnTheScreen();
});
@@ -29,39 +26,13 @@ describe('LoginForm Form ', () => {
const button = screen.getByTestId(LOGIN_BUTTON);
const emailInput = screen.getByTestId('email-input');
- const usernameInput = screen.getByTestId('username-input');
const passwordInput = screen.getByTestId('password-input');
fireEvent.changeText(emailInput, 'yyyy');
- fireEvent.changeText(usernameInput, ' ');
fireEvent.changeText(passwordInput, 'test');
fireEvent.press(button);
- expect(screen.queryByText(/Username is required/i)).not.toBeOnTheScreen();
+ expect(screen.queryByText(/Email is required/i)).not.toBeOnTheScreen();
expect(await screen.findByText(/Invalid Email Format/i)).toBeOnTheScreen();
});
-
- it('Should call LoginForm with correct values when values are valid', async () => {
- render();
-
- const button = screen.getByTestId(LOGIN_BUTTON);
- const emailInput = screen.getByTestId('username-input');
- const passwordInput = screen.getByTestId('password-input');
-
- fireEvent.changeText(emailInput, 'youssef');
- fireEvent.changeText(passwordInput, 'password');
- fireEvent.press(button);
- await waitFor(() => {
- expect(onSubmitMock).toHaveBeenCalledTimes(1);
- });
- // undefined because we don't use second argument of the SubmitHandler
- expect(onSubmitMock).toHaveBeenCalledWith(
- {
- email: undefined,
- username: 'youssef',
- password: 'password',
- },
- undefined,
- );
- });
});
diff --git a/src/components/login-form.tsx b/src/components/login-form.tsx
index b0accbc59..7ad35c850 100644
--- a/src/components/login-form.tsx
+++ b/src/components/login-form.tsx
@@ -8,10 +8,9 @@ import { Button, ControlledInput, Text, View } from '@/ui';
const MIN_CHARS = 6;
const schema = z.object({
- username: z.string({
- required_error: 'Username is required',
- }),
- email: z.string().email('Invalid email format').optional(),
+ email: z
+ .string({ required_error: 'Email is required' })
+ .email('Invalid email format'),
password: z
.string({
required_error: 'Password is required',
@@ -46,13 +45,7 @@ export const LoginForm = ({ onSubmit = () => {} }: LoginFormProps) => {
autoComplete="email"
control={control}
name="email"
- label="Email (optional)"
- />
-