(Breaking change) Switch between set password and change password on the settings page. (#15582)
Here is what the PR does: - Surface password state in validatePasswordResetToken, returning hasPassword so the client can tell whether a user is setting or changing their password. - Consume that flag throughout the front end (mock data, stories, GraphQL types) and update the Reset/Set Password modal to swap the heading/button label and success toast accordingly. - After a successful password set/reset, immediately update the logged-in user’s hasPassword flag so the Settings screen reflects the new state without a reload. Modal has two states now - reset password modal uses change password state since it made intuitive sense. <p align="center"> <img width="404" height="397" alt="image" src="https://github.com/user-attachments/assets/c54cc581-1248-4395-833d-0202758e1947" /> </p> <p align="center"> <img width="403" height="393" alt="image" src="https://github.com/user-attachments/assets/d8a39a95-27e6-4037-86f2-1f74176002ba" /> </p> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ export const VALIDATE_PASSWORD_RESET_TOKEN = gql`
|
||||
validatePasswordResetToken(passwordResetToken: $token) {
|
||||
id
|
||||
email
|
||||
hasPassword
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -12,6 +12,7 @@ export type CurrentUser = Pick<
|
||||
| 'userVars'
|
||||
| 'firstName'
|
||||
| 'lastName'
|
||||
| 'hasPassword'
|
||||
>;
|
||||
|
||||
export const currentUserState = createState<CurrentUser | null>({
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ const mockCurrentUser = {
|
||||
userVars: {},
|
||||
firstName: 'fake-first-name',
|
||||
lastName: 'fake-last-name',
|
||||
hasPassword: true,
|
||||
};
|
||||
|
||||
const mockBilling: Billing = {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { H2Title } from 'twenty-ui/display';
|
||||
|
||||
export const ChangePassword = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { handleResetPassword } = useHandleResetPassword();
|
||||
|
||||
return (
|
||||
<>
|
||||
<H2Title
|
||||
title={t`Change Password`}
|
||||
description={t`Receive an email containing password update link`}
|
||||
/>
|
||||
<Button
|
||||
onClick={handleResetPassword()}
|
||||
variant="secondary"
|
||||
title={t`Change Password`}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H2Title } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
|
||||
export const SetOrChangePassword = () => {
|
||||
const { t } = useLingui();
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
|
||||
const { handleResetPassword } = useHandleResetPassword();
|
||||
|
||||
const hasPassword = currentUser?.hasPassword ?? false;
|
||||
const heading = hasPassword ? t`Change Password` : t`Set Password`;
|
||||
const description = hasPassword
|
||||
? t`Receive an email containing password update link`
|
||||
: t`Receive an email containing password set link`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<H2Title title={heading} description={description} />
|
||||
<Button
|
||||
onClick={handleResetPassword()}
|
||||
variant="secondary"
|
||||
title={heading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -18,6 +18,7 @@ export const USER_QUERY_FRAGMENT = gql`
|
||||
firstName
|
||||
lastName
|
||||
email
|
||||
hasPassword
|
||||
canAccessFullAdminPanel
|
||||
canImpersonate
|
||||
supportUserHash
|
||||
|
||||
Reference in New Issue
Block a user