Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

Commit

Permalink
fix: update loading buttons, add error messages (#363)
Browse files Browse the repository at this point in the history
* fix: update loading buttons, add error messages and more nicer loading of invitations

* fix: udpate with constants from sdk

* fix: update validation

* fix: intercept reply on invitation error

* fix: typo in readme

* fix: typo in env var and tests

* fix: udpate sdk dependency
  • Loading branch information
spaenleh authored Apr 15, 2024
1 parent 574dbe5 commit 8a14958
Show file tree
Hide file tree
Showing 23 changed files with 277 additions and 183 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Graasp Auth

[![gitlocalized ](https://gitlocalize.com/repo/9425/whole_project/badge.svg)](https://gitlocalize.com/repo/9425?utm_source=badge)
[gitlocalized](https://gitlocalize.com/repo/9425/whole_project/badge.svg)](<https://gitlocalize.com/repo/9425?utm_source=badge>)

Create an `.env.development` file with:

```sh
VITE_PORT=3001
VITE_API_HOST=http://localhost:3000
VITE_GRAASP_API_HOST=http://localhost:3000
VITE_VERSION=latest
VITE_GRAASP_BUILDER_HOST=http://localhost:3111
VITE_SHOW_NOTIFICATIONS=true
VITE_GRAASP_AUT_HOST=http://localhost:3001
VITE_GRAASP_AUTH_HOST=http://localhost:3001
VITE_GRAASP_LANDING_PAGE_ORIGIN=https://graasp.org

VITE_RECAPTCHA_SITE_KEY=
Expand All @@ -22,11 +22,11 @@ For running tests locally create a `.env.test` file:

```sh
VITE_PORT=3002
VITE_API_HOST=http://localhost:3636
VITE_GRAASP_API_HOST=http://localhost:3636
VITE_VERSION=latest
VITE_GRAASP_BUILDER_HOST=http://localhost:3111
VITE_SHOW_NOTIFICATIONS=true
VITE_GRAASP_AUT_HOST=http://localhost:3001
VITE_GRAASP_AUTH_HOST=http://localhost:3001

VITE_RECAPTCHA_SITE_KEY=
```
2 changes: 1 addition & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default defineConfig({
const newConfig = {
...config,
env: {
API_HOST: process.env.REACT_APP_API_HOST,
VITE_GRAASP_API_HOST: process.env.VITE_GRAASP_API_HOST,
},
};
setupEvents(on, newConfig);
Expand Down
3 changes: 3 additions & 0 deletions cypress/e2e/SignIn.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { SIGN_IN_PATH } from '../../src/config/paths';
import { MEMBERS } from '../fixtures/members';

describe('Name and Email Validation', () => {
beforeEach(() => {
cy.setUpApi();
});
it('Sign In', () => {
const { GRAASP, WRONG_EMAIL } = MEMBERS;
cy.visit(SIGN_IN_PATH);
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/SignUp.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe('SignUp', () => {
};
cy.intercept(API_ROUTES.buildGetInvitationRoute(invitation.id), {
statusCode: 404,
body: '404 Not Found!',
body: { message: '404 Not Found!' },
});
const search = new URLSearchParams();
search.set('invitationId', invitation.id);
Expand Down
7 changes: 7 additions & 0 deletions cypress/fixtures/members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const MEMBERS: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
GRAASP_OTHER: {
id: 'graasp_other-id',
Expand All @@ -33,6 +34,7 @@ export const MEMBERS: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
WRONG_NAME: {
id: 'id1',
Expand All @@ -45,6 +47,7 @@ export const MEMBERS: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
WRONG_EMAIL: {
id: 'id2',
Expand All @@ -58,6 +61,7 @@ export const MEMBERS: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
WRONG_PASSWORD: {
id: 'id3',
Expand All @@ -71,6 +75,7 @@ export const MEMBERS: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
BOB: {
id: 'ecafbd2a-5642-31fb-ae93-0242ac130004',
Expand All @@ -80,6 +85,7 @@ export const MEMBERS: {
extra: { lang: 'en' },
type: MemberType.Individual,
updatedAt: new Date().toISOString(),
enableSaveActions: true,
},
CEDRIC: {
id: 'ecafbd2a-5642-31fb-ae93-0242ac130006',
Expand All @@ -89,6 +95,7 @@ export const MEMBERS: {
type: MemberType.Individual,
updatedAt: new Date().toISOString(),
extra: {},
enableSaveActions: true,
},
};

Expand Down
13 changes: 7 additions & 6 deletions cypress/support/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const { buildGetMember, GET_CURRENT_MEMBER_ROUTE } = API_ROUTES;
// use simple id format for tests
export const ID_FORMAT = '(?=.*[0-9])(?=.*[a-zA-Z])([a-z0-9-]+)';

const API_HOST = Cypress.env('API_HOST');
const API_HOST = Cypress.env('VITE_GRAASP_API_HOST');

export const redirectionReply = {
headers: { 'content-type': 'application/json' },
Expand Down Expand Up @@ -89,16 +89,17 @@ export const mockGetMembers = (members) => {
).as('getMembers');
};

export const mockGetStatus = () => {
export const mockGetStatus = (shouldThrowServerError = false) => {
cy.intercept(
{
method: 'get',
url: `${API_HOST}/status`,
},
({ url, reply }) => {
return reply({
statusCode: StatusCodes.OK,
});
({ reply }) => {
if (shouldThrowServerError) {
return reply({ statusCode: StatusCodes.INTERNAL_SERVER_ERROR });
}
return reply({ statusCode: StatusCodes.OK });
},
).as('getStatus');
};
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -19,7 +19,7 @@
<!-- Load Roboto font from Google fonts -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap"
/>
<title>Graasp Auth</title>
</head>
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.0",
"@graasp/query-client": "3.0.2",
"@graasp/sdk": "4.2.1",
"@graasp/sdk": "4.7.2",
"@graasp/translations": "1.25.3",
"@graasp/ui": "4.11.0",
"@graasp/ui": "4.14.2",
"@mui/icons-material": "5.15.14",
"@mui/lab": "5.0.0-alpha.169",
"@mui/material": "5.15.14",
Expand Down
12 changes: 6 additions & 6 deletions src/components/App.tsx → src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import * as Sentry from '@sentry/react';
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';

import ErrorFallback from './components/ErrorFallback';
import MobileAuth from './components/MobileAuth';
import Redirection from './components/Redirection';
import SignIn from './components/SignIn';
import SignUp from './components/SignUp';
import {
HOME_PATH,
MOBILE_AUTH_PATH,
SIGN_IN_PATH,
SIGN_UP_PATH,
} from '../config/paths';
import ErrorFallback from './ErrorFallback';
import MobileAuth from './MobileAuth';
import Redirection from './Redirection';
import SignIn from './SignIn';
import SignUp from './SignUp';
} from './config/paths';

const App = () => (
<Sentry.ErrorBoundary fallback={<ErrorFallback />} showDialog>
Expand Down
2 changes: 1 addition & 1 deletion src/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ThemeProvider } from '@graasp/ui';

import { CssBaseline } from '@mui/material';

import App from './components/App';
import App from './App';
import { RECAPTCHA_SITE_KEY, SHOW_NOTIFICATIONS } from './config/env';
import i18nConfig, { useCommonTranslation } from './config/i18n';
import {
Expand Down
2 changes: 1 addition & 1 deletion src/components/EmailInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const EmailInput: FC<Props> = ({
required={required}
value={value}
error={Boolean(error)}
helperText={error}
helperText={t(error)}
onChange={handleEmailOnChange}
id={id}
type="email"
Expand Down
52 changes: 41 additions & 11 deletions src/components/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Link, useLocation } from 'react-router-dom';
import { RecaptchaAction } from '@graasp/sdk';
import { Button, GraaspLogo } from '@graasp/ui';

import { LoadingButton } from '@mui/lab';
import { Stack, useTheme } from '@mui/material';
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
Expand Down Expand Up @@ -31,6 +32,7 @@ import EmailInput from './EmailInput';
import FullscreenContainer from './FullscreenContainer';
import StyledTextField from './StyledTextField';
import SuccessContent from './SuccessContent';
import ErrorDisplay from './common/ErrorDisplay';

const {
SIGN_IN_BUTTON,
Expand Down Expand Up @@ -58,19 +60,35 @@ const SignIn: FC = () => {
// enable validation after first click
const [shouldValidate, setShouldValidate] = useState(false);

const { mutateAsync: signIn, isSuccess: signInSuccess } =
mutations.useSignIn();
const { mutateAsync: mobileSignIn, isSuccess: mobileSignInSuccess } =
mutations.useMobileSignIn();
const {
mutateAsync: signIn,
isSuccess: signInSuccess,
isLoading: isLoadingSignIn,
error: webSignInError,
} = mutations.useSignIn();
const {
mutateAsync: mobileSignIn,
isSuccess: mobileSignInSuccess,
isLoading: isLoadingMobileSignIn,
error: mobileSignInError,
} = mutations.useMobileSignIn();
const {
mutateAsync: signInWithPassword,
isSuccess: signInWithPasswordSuccess,
isLoading: isLoadingPasswordSignIn,
error: webPasswordSignInError,
} = mutations.useSignInWithPassword();
const {
mutateAsync: mobileSignInWithPassword,
isSuccess: mobileSignInWithPasswordSuccess,
isLoading: isLoadingMobilePasswordSignIn,
error: mobilePasswordSignInError,
} = mutations.useMobileSignInWithPassword();

const signInError = webSignInError || mobileSignInError;
const passwordSignInError =
webPasswordSignInError || mobilePasswordSignInError;

const handleSignIn = async () => {
const lowercaseEmail = email.toLowerCase();
const checkingEmail = emailValidator(lowercaseEmail);
Expand Down Expand Up @@ -196,26 +214,38 @@ const SignIn: FC = () => {
variant="outlined"
value={password}
error={Boolean(passwordError)}
helperText={passwordError}
helperText={t(passwordError)}
onChange={handleOnChangePassword}
id={PASSWORD_SIGN_IN_FIELD_ID}
type="password"
onKeyDown={handleKeypress}
/>
<Button
<ErrorDisplay error={passwordSignInError} />
<LoadingButton
id={PASSWORD_SIGN_IN_BUTTON_ID}
variant="contained"
color="primary"
onClick={handlePasswordSignIn}
id={PASSWORD_SIGN_IN_BUTTON_ID}
loading={
isLoadingMobilePasswordSignIn || isLoadingPasswordSignIn
}
>
{t(SIGN_IN_BUTTON)}
</Button>
</LoadingButton>
</>
)}
{signInMethod === SIGN_IN_METHODS.EMAIL && (
<Button onClick={handleSignIn} id={SIGN_IN_BUTTON_ID}>
{t(SIGN_IN_BUTTON)}
</Button>
<>
<ErrorDisplay error={signInError} />
<LoadingButton
id={SIGN_IN_BUTTON_ID}
variant="contained"
onClick={handleSignIn}
loading={isLoadingMobileSignIn || isLoadingSignIn}
>
{t(SIGN_IN_BUTTON)}
</LoadingButton>
</>
)}
</Stack>
</FormControl>
Expand Down
Loading

0 comments on commit 8a14958

Please sign in to comment.