Skip to content

Add SignUpPage component and improve folder structure #4964

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e9be94e
Update pnpm version requirement to allow newer versions
yuito-it May 20, 2025
48412e5
Add missing localization keys for SignUpPage in LocaleText interface
yuito-it May 20, 2025
710d994
Add missing localization keys for SignUpPage in LocaleText interface
yuito-it May 20, 2025
c45d35b
Move icon modules to shared directory.
yuito-it May 20, 2025
bd71de4
Refactor error handling in signIn function to simplify Auth.js error …
yuito-it May 20, 2025
9b65e9c
Update middleware matcher to exclude auth/signup route
yuito-it May 20, 2025
441b6f4
Add signup action and SignUpPage component for user registration
yuito-it May 20, 2025
91f9708
Fix SignUpPage documentation and update prop names for sign-up functi…
yuito-it May 20, 2025
6abb861
Update SignInPage documentation to clarify sign-in flow and announce …
yuito-it May 20, 2025
4a7a3b1
Add sign-up page components and update documentation for user registr…
yuito-it May 20, 2025
1f5a177
Add warning for experimental status of SignUpPage feature
yuito-it May 20, 2025
e1df987
Merge branch 'master' into feat/SignUpPage
yuito-it May 20, 2025
227608c
Merge branch 'master' into feat/SignUpPage
yuito-it May 21, 2025
f01d344
fix: specify exact version for pnpm in engines
yuito-it May 21, 2025
df5f90b
fix: update pnpm version constraint to allow newer versions
yuito-it May 21, 2025
22a01a1
fix: specify pnpm package manager version in package.json
yuito-it May 21, 2025
afecc25
feat: add sign-up page components for credentials and OAuth providers
yuito-it May 21, 2025
e633fa6
fix: update prop types and documentation for sign-up functionality
yuito-it May 21, 2025
adf994c
Move the files to the 'auth' directory for summarisation.
yuito-it May 21, 2025
bc10c43
feat: add sign-up page and update related API documentation
yuito-it May 21, 2025
f94c225
feat: export authTypes from AuthPage index
yuito-it May 21, 2025
78b4f21
refactor: update import paths from SignInPage to AuthPage across mult…
yuito-it May 21, 2025
1df650e
docs: add Sign-up Page link to all-components documentation
yuito-it May 21, 2025
7847b3c
refactor: update import paths from SignUpPage to AuthPage across mult…
yuito-it May 21, 2025
9af7f10
feat: add Sign-up Page to pages list
yuito-it May 21, 2025
39d580b
fix: correct import path for SignUpPage in API documentation
yuito-it May 21, 2025
d3455ad
Merge branch 'master' into feat/SignUpPage
yuito-it May 31, 2025
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
1 change: 1 addition & 0 deletions docs/data/toolpad/core/all-components/all-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
- [Dashboard Layout](/toolpad/core/react-dashboard-layout/)
- [Page Container](/toolpad/core/react-page-container/)
- [Sign-in Page](/toolpad/core/react-sign-in-page/)
- [Sign-up Page](/toolpad/core/react-sign-up-page/)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Credentials' }];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Credentials' }];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { hiIN } from '@toolpad/core/locales';

const providers = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
} from '@toolpad/core/SignInPage';
} from '@toolpad/core/AuthPage';
import { hiIN } from '@toolpad/core/locales';

const providers = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { AppProvider } from '@toolpad/core/AppProvider';
import { useTheme } from '@mui/material/styles';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SignInPage,
SupportedAuthProvider,
AuthResponse,
} from '@toolpad/core/SignInPage';
} from '@toolpad/core/AuthPage';
import { AppProvider } from '@toolpad/core/AppProvider';
import { useTheme } from '@mui/material/styles';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and password' }];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
} from '@toolpad/core/SignInPage';
} from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and password' }];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import {
AuthResponse,
SignInPage,
type AuthProvider,
} from '@toolpad/core/SignInPage';
import { AuthResponse, SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
const providers = [{ id: 'passkey', name: 'Passkey' }];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage, AuthProvider } from '@toolpad/core/SignInPage';
import { SignInPage, AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
const providers = [{ id: 'passkey', name: 'Passkey' }];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and Password' }];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and Password' }];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';
import { createTheme } from '@mui/material/styles';
import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext';
import { getDesignTokens, inputsCustomizations } from './customTheme';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
} from '@toolpad/core/SignInPage';
} from '@toolpad/core/AuthPage';
import { createTheme } from '@mui/material/styles';
import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext';
import { getDesignTokens, inputsCustomizations } from './customTheme';
Expand Down
18 changes: 15 additions & 3 deletions docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

```tsx
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { SignInPage } from '@toolpad/core/AuthPage';

export default function App() {
return (
Expand All @@ -36,6 +36,12 @@

## OAuth

:::warning

This function works similarly to the sign-up flow to authenticate users, but is focused on signing in existing accounts rather than creating new ones. For details on the sign-up flow, see the [Sign-up Page documentation](/toolpad/core/components/sign-up-page/).

:::

The `SignInPage` component can be set up with an OAuth provider by passing in a list of providers in the `providers` prop, along with a `signIn` function that accepts the `provider` as a parameter.

{{"demo": "OAuthSignInPage.js", "iframe": true, "height": 600}}
Expand Down Expand Up @@ -177,7 +183,7 @@
```tsx title="./app/auth/signin/page.tsx"
// ...
import * as React from 'react';
import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { AuthError } from 'next-auth';
import { providerMap, signIn } from '../../../auth';

Expand Down Expand Up @@ -294,6 +300,12 @@

The `SignInPage` component has versions with different layouts for authentication - one column, two column and others such. The APIs of these components are identical. This is in progress.

### 🚧 SignUp

A dedicated `SignUpPage` component is planned to provide a seamless registration experience for new users. This will support multiple authentication providers and allow for custom fields, validation, and branding, similar to the `SignInPage`. Stay tuned for updates and check the [Sign-up Page documentation](/toolpad/core/components/sign-up-page/) for the latest information.

Check warning on line 305 in docs/data/toolpad/core/components/sign-in-page/sign-in-page.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "docs/data/toolpad/core/components/sign-in-page/sign-in-page.md", "range": {"start": {"line": 305, "column": 113}}}, "severity": "WARNING"}

## 🚧 Other authentication flows

Besides the `SignInPage` , the team is planning work on several other components that enable new workflows such as [sign up](https://github.com/mui/toolpad/issues/4068) and [password reset](https://github.com/mui/toolpad/issues/4265).
Additional authentication flows such as password reset, multi-factor authentication (MFA), and account recovery are on the roadmap. These features aim to enhance security and user experience. Follow the [Toolpad GitHub issues](https://github.com/mui/toolpad/issues) for progress and upcoming releases.

Besides the `SignInPage` , the team is planning work on several other components that enable new workflows such as [password reset](https://github.com/mui/toolpad/issues/4265).
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignUpPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
const providers = [{ id: 'credentials', name: 'Email and Password' }];
// preview-end

const signIn = async (provider, formData) => {
const promise = new Promise((resolve) => {
setTimeout(() => {
alert(
`Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}`,
);
resolve();
}, 300);
});
return promise;
};

export default function CredentialsSignUpPage() {
const theme = useTheme();
return (
// preview-start
<AppProvider theme={theme}>
<SignUpPage
signUp={signIn}
providers={providers}
slotProps={{ emailField: { autoFocus: false }, form: { noValidate: true } }}
/>
</AppProvider>
// preview-end
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignUpPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

// preview-start
const providers = [{ id: 'credentials', name: 'Email and Password' }];
// preview-end

const signIn: (provider: AuthProvider, formData: FormData) => void = async (
provider,
formData,
) => {
const promise = new Promise<void>((resolve) => {
setTimeout(() => {
alert(
`Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}`,
);
resolve();
}, 300);
});
return promise;
};

export default function CredentialsSignUpPage() {
const theme = useTheme();
return (
// preview-start
<AppProvider theme={theme}>
<SignUpPage
signUp={signIn}
providers={providers}
slotProps={{ emailField: { autoFocus: false }, form: { noValidate: true } }}
/>
</AppProvider>
// preview-end
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const providers = [{ id: 'credentials', name: 'Email and Password' }];

// ...

<AppProvider theme={theme}>
<SignUpPage
signUp={signIn}
providers={providers}
slotProps={{ emailField: { autoFocus: false }, form: { noValidate: true } }}
/>
</AppProvider>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignUpPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and password' }];

const signUp = async (provider, formData) => {
const promise = new Promise((resolve) => {
setTimeout(() => {
const email = formData?.get('email');
const password = formData?.get('password');
alert(
`Signing up with "${provider.name}" and credentials: ${email}, ${password}`,
);
// preview-start
resolve({
error: 'Invalid credentials.',
});
// preview-end
}, 300);
});
return promise;
};

export default function NotificationsSignUpPageError() {
const theme = useTheme();
return (
// preview-start
<AppProvider theme={theme}>
<SignUpPage
signUp={signUp}
providers={providers}
slotProps={{ emailField: { autoFocus: false }, form: { noValidate: true } }}
/>
</AppProvider>
// preview-end
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import {
SignUpPage,
type AuthProvider,
type SignUpActionResponse,
} from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';

const providers = [{ id: 'credentials', name: 'Email and password' }];

const signUp: (
provider: AuthProvider,
formData?: FormData,
) => Promise<SignUpActionResponse> | void = async (provider, formData) => {
const promise = new Promise<SignUpActionResponse>((resolve) => {
setTimeout(() => {
const email = formData?.get('email');
const password = formData?.get('password');
alert(
`Signing up with "${provider.name}" and credentials: ${email}, ${password}`,
);
// preview-start
resolve({
error: 'Invalid credentials.',
});
// preview-end
}, 300);
});
return promise;
};

export default function NotificationsSignUpPageError() {
const theme = useTheme();
return (
// preview-start
<AppProvider theme={theme}>
<SignUpPage
signUp={signUp}
providers={providers}
slotProps={{ emailField: { autoFocus: false }, form: { noValidate: true } }}
/>
</AppProvider>
// preview-end
);
}
Loading
Loading