diff --git a/public/locales/en/manage/users/create.json b/public/locales/en/manage/users/create.json
index c8c34de42..dcf8d4fe6 100644
--- a/public/locales/en/manage/users/create.json
+++ b/public/locales/en/manage/users/create.json
@@ -15,14 +15,7 @@
"title": "Second step",
"text": "Password",
"password": {
- "label": "Password",
- "requirements": {
- "number": "Includes number",
- "lowercase": "Includes lowercase letter",
- "uppercase": "Includes uppercase letter",
- "special": "Includes special character",
- "length": "Includes at least {{count}} characters"
- }
+ "label": "Password"
}
},
"finish": {
diff --git a/public/locales/en/password-requirements.json b/public/locales/en/password-requirements.json
new file mode 100644
index 000000000..605007553
--- /dev/null
+++ b/public/locales/en/password-requirements.json
@@ -0,0 +1,7 @@
+{
+ "number": "Includes number",
+ "lowercase": "Includes lowercase letter",
+ "uppercase": "Includes uppercase letter",
+ "special": "Includes special character",
+ "length": "Includes at least {{count}} characters"
+}
\ No newline at end of file
diff --git a/src/components/Manage/User/Create/security-step.tsx b/src/components/Manage/User/Create/security-step.tsx
index 1cbcf573a..5e76e5ac8 100644
--- a/src/components/Manage/User/Create/security-step.tsx
+++ b/src/components/Manage/User/Create/security-step.tsx
@@ -1,48 +1,13 @@
-import {
- Box,
- Button,
- Card,
- Flex,
- Group,
- PasswordInput,
- Popover,
- Progress,
- Text,
-} from '@mantine/core';
+import { Button, Card, Flex, Group, PasswordInput, Popover } from '@mantine/core';
import { useForm } from '@mantine/form';
-import {
- IconArrowLeft,
- IconArrowRight,
- IconCheck,
- IconDice,
- IconKey,
- IconX,
-} from '@tabler/icons-react';
+import { IconArrowLeft, IconArrowRight, IconDice, IconKey } from '@tabler/icons-react';
import { useTranslation } from 'next-i18next';
import { useState } from 'react';
import { z } from 'zod';
+import { PasswordRequirements } from '~/components/Password/password-requirements';
import { api } from '~/utils/api';
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
-import { minPasswordLength, passwordSchema } from '~/validations/user';
-
-const requirements = [
- { re: /[0-9]/, label: 'number' },
- { re: /[a-z]/, label: 'lowercase' },
- { re: /[A-Z]/, label: 'uppercase' },
- { re: /[$&+,:;=?@#|'<>.^*()%!-]/, label: 'special' },
-];
-
-function getStrength(password: string) {
- let multiplier = password.length >= minPasswordLength ? 0 : 1;
-
- requirements.forEach((requirement) => {
- if (!requirement.re.test(password)) {
- multiplier += 1;
- }
- });
-
- return Math.max(100 - (100 / (requirements.length + 1)) * multiplier, 10);
-}
+import { passwordSchema } from '~/validations/user';
interface CreateAccountSecurityStepProps {
defaultPassword: string;
@@ -70,16 +35,6 @@ export const CreateAccountSecurityStep = ({
const { mutateAsync, isLoading } = api.password.generate.useMutation();
const [popoverOpened, setPopoverOpened] = useState(false);
- const checks = requirements.map((requirement, index) => (
-
- ));
-
- const strength = getStrength(form.values.password);
- const color = strength === 100 ? 'teal' : strength > 50 ? 'yellow' : 'red';
return (
@@ -122,12 +77,7 @@ export const CreateAccountSecurityStep = ({
-
- = minPasswordLength}
- />
- {checks}
+
@@ -153,26 +103,6 @@ export const CreateAccountSecurityStep = ({
);
};
-const PasswordRequirement = ({ meets, label }: { meets: boolean; label: string }) => {
- const { t } = useTranslation('manage/users/create');
-
- return (
-
- {meets ? : }{' '}
-
- {t(`steps.security.password.requirements.${label}`, {
- count: minPasswordLength,
- })}
-
-
- );
-};
-
export const createAccountSecurityStepValidationSchema = z.object({
password: passwordSchema,
});
diff --git a/src/components/Onboarding/onboarding-steps.tsx b/src/components/Onboarding/onboarding-steps.tsx
index 036f4fb31..0e9f8c245 100644
--- a/src/components/Onboarding/onboarding-steps.tsx
+++ b/src/components/Onboarding/onboarding-steps.tsx
@@ -2,14 +2,13 @@ import { Stack, Stepper } from '@mantine/core';
import { useState } from 'react';
import { StepCreateAccount } from './step-create-account';
-import { StepDockerImport } from './step-docker-import';
import { StepDocumentation } from './step-documentation';
import { StepOnboardingFinished } from './step-onboarding-finished';
import { StepUpdatePathMappings } from './step-update-path-mappings';
export const OnboardingSteps = ({ isUpdate }: { isUpdate: boolean }) => {
const [currentStep, setCurrentStep] = useState(0);
- const nextStep = () => setCurrentStep((current) => (current < 4 ? current + 1 : current));
+ const nextStep = () => setCurrentStep((current) => (current < 3 ? current + 1 : current));
const prevStep = () => setCurrentStep((current) => (current > 0 ? current - 1 : current));
return (
@@ -31,9 +30,6 @@ export const OnboardingSteps = ({ isUpdate }: { isUpdate: boolean }) => {
-
-
-
diff --git a/src/components/Onboarding/step-create-account.tsx b/src/components/Onboarding/step-create-account.tsx
index de7a8b3d8..e2d7dd10d 100644
--- a/src/components/Onboarding/step-create-account.tsx
+++ b/src/components/Onboarding/step-create-account.tsx
@@ -1,4 +1,4 @@
-import { Button, Group, PasswordInput, Stack, TextInput, Title } from '@mantine/core';
+import { Button, Card, Group, PasswordInput, Stack, TextInput, Title } from '@mantine/core';
import { useForm } from '@mantine/form';
import { IconArrowLeft, IconArrowRight } from '@tabler/icons-react';
import { signIn } from 'next-auth/react';
@@ -8,6 +8,7 @@ import { api } from '~/utils/api';
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
import { signUpFormSchema } from '~/validations/user';
+import { PasswordRequirements } from '../Password/password-requirements';
import { OnboardingStepWrapper } from './common-wrapper';
export const StepCreateAccount = ({
@@ -22,6 +23,11 @@ export const StepCreateAccount = ({
const { i18nZodResolver } = useI18nZodResolver();
const form = useForm>({
+ initialValues: {
+ password: '',
+ username: '',
+ passwordConfirmation: '',
+ },
validate: i18nZodResolver(signUpFormSchema),
validateInputOnBlur: true,
});
@@ -70,6 +76,10 @@ export const StepCreateAccount = ({
{...form.getInputProps('password')}
/>
+
+
+
+
void }) => {
- return (
-
-
- Automatic container import
-
-
-
- } fullWidth>
- Next
-
-
-
- );
-};
diff --git a/src/components/Password/password-requirement.tsx b/src/components/Password/password-requirement.tsx
new file mode 100644
index 000000000..720fdad55
--- /dev/null
+++ b/src/components/Password/password-requirement.tsx
@@ -0,0 +1,24 @@
+import { Box, Text } from "@mantine/core";
+import { IconCheck, IconX } from "@tabler/icons-react";
+import { useTranslation } from "react-i18next";
+import { minPasswordLength } from "~/validations/user";
+
+export const PasswordRequirement = ({ meets, label }: { meets: boolean; label: string }) => {
+ const { t } = useTranslation('password-requirements');
+
+ return (
+
+ {meets ? : }{' '}
+
+ {t(`${label}`, {
+ count: minPasswordLength,
+ })}
+
+
+ );
+ };
\ No newline at end of file
diff --git a/src/components/Password/password-requirements.tsx b/src/components/Password/password-requirements.tsx
new file mode 100644
index 000000000..2a25a54fb
--- /dev/null
+++ b/src/components/Password/password-requirements.tsx
@@ -0,0 +1,39 @@
+import { Progress } from '@mantine/core';
+import { minPasswordLength } from '~/validations/user';
+
+import { PasswordRequirement } from './password-requirement';
+
+const requirements = [
+ { re: /[0-9]/, label: 'number' },
+ { re: /[a-z]/, label: 'lowercase' },
+ { re: /[A-Z]/, label: 'uppercase' },
+ { re: /[$&+,:;=?@#|'<>.^*()%!-]/, label: 'special' },
+];
+
+function getStrength(password: string) {
+ let multiplier = password.length >= minPasswordLength ? 0 : 1;
+
+ requirements.forEach((requirement) => {
+ if (!requirement.re.test(password)) {
+ multiplier += 1;
+ }
+ });
+
+ return Math.max(100 - (100 / (requirements.length + 1)) * multiplier, 10);
+}
+
+export const PasswordRequirements = ({ value }: { value: string }) => {
+ const checks = requirements.map((requirement, index) => (
+
+ ));
+
+ const strength = getStrength(value);
+ const color = strength === 100 ? 'teal' : strength > 50 ? 'yellow' : 'red';
+ return (
+ <>
+
+ = minPasswordLength} />
+ {checks}
+ >
+ );
+};
diff --git a/src/pages/manage/users/create.tsx b/src/pages/manage/users/create.tsx
index 3f200e431..421290cc8 100644
--- a/src/pages/manage/users/create.tsx
+++ b/src/pages/manage/users/create.tsx
@@ -139,7 +139,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
}
const translations = await getServerSideTranslations(
- manageNamespaces,
+ [...manageNamespaces, 'password-requirements'],
ctx.locale,
ctx.req,
ctx.res
diff --git a/src/pages/onboard.tsx b/src/pages/onboard.tsx
index c93ceb93b..d17b980ae 100644
--- a/src/pages/onboard.tsx
+++ b/src/pages/onboard.tsx
@@ -77,7 +77,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
const configs = files.map((file) => getConfig(file));
const configSchemaVersions = configs.map((config) => config.schemaVersion);
- const translations = await getServerSideTranslations([], ctx.locale, ctx.req, ctx.res);
+ const translations = await getServerSideTranslations(['password-requirements'], ctx.locale, ctx.req, ctx.res);
return {
props: {