Skip to content

Commit

Permalink
fix(signup): remove zxcvbn
Browse files Browse the repository at this point in the history
  • Loading branch information
tfkhdyt committed Jul 7, 2024
1 parent cd13a03 commit 454070b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 94 deletions.
4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@
"@trpc/server": "^10.45.2",
"@uidotdev/usehooks": "^2.4.1",
"@uploadthing/react": "^6.7.2",
"@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2",
"@zxcvbn-ts/language-id": "^3.0.2",
"argon2": "^0.40.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 25 additions & 90 deletions src/app/auth/sign-up/signup-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@ import { signIn } from 'next-auth/react';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import toast from 'react-hot-toast';
import { match } from 'ts-pattern';
import { zxcvbnOptions, zxcvbnAsync, type ZxcvbnResult } from '@zxcvbn-ts/core';
import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common';
import * as zxcvbnEnPackage from '@zxcvbn-ts/language-en';
import * as zxcvbnIdPackage from '@zxcvbn-ts/language-id';

import { Button } from '@/components/ui/button';
import {
Expand All @@ -29,34 +25,6 @@ import { Input } from '@/components/ui/input';
import { environment } from '@/environment.mjs';
import { type SignupSchema, signupSchema } from '@/schema/signup-schema';
import { api } from '@/trpc/react';
import { Progress } from '@/components/ui/progress';
import { cn } from '@/lib/utils';
import { useDebounce } from '@uidotdev/usehooks';

const options = {
dictionary: {
...zxcvbnCommonPackage.dictionary,
...zxcvbnEnPackage.dictionary,
...zxcvbnIdPackage.dictionary,
},
graphs: zxcvbnCommonPackage.adjacencyGraphs,
useLevenshteinDistance: true,
translations: zxcvbnEnPackage.translations,
};
zxcvbnOptions.setOptions(options);

const usePasswordStrength = (password: string) => {
const [result, setResult] = useState<ZxcvbnResult | undefined>();
const deferredPassword = useDebounce(password, 500);

useEffect(() => {
if (deferredPassword) {
zxcvbnAsync(deferredPassword).then((response) => setResult(response));
}
}, [deferredPassword]);

return result;
};

export function SignupForm() {
const [isPasswordShowed, setIsPasswordShowed] = useState(false);
Expand All @@ -65,13 +33,6 @@ export function SignupForm() {
const form = useForm<SignupSchema>({
resolver: zodResolver(signupSchema),
});
const password = useWatch({ control: form.control, name: 'password' });
const passwordStrength = usePasswordStrength(password);
const pwdStrengthValue = useMemo(
() =>
passwordStrength?.score ? ((passwordStrength.score + 1) / 5) * 100 : 20,
[passwordStrength],
);

const router = useRouter();

Expand Down Expand Up @@ -185,55 +146,29 @@ export function SignupForm() {
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<div>
<span className='flex space-x-2'>
<Input
placeholder='Password'
type={isPasswordShowed ? 'text' : 'password'}
{...field}
className='rounded-full'
/>
<Button
aria-label='Show password'
className='rounded-full p-2'
onClick={() => {
setIsPasswordShowed((v) => !v);
}}
tabIndex={-1}
type='button'
variant='outline'
>
{match(isPasswordShowed)
.with(true, () => <EyeOff size={20} />)
.with(false, () => <Eye size={20} />)
.exhaustive()}
</Button>
</span>
<div className='flex items-center space-x-2 justify-between'>
<Progress
value={password ? pwdStrengthValue : 0}
className={cn(
match(passwordStrength?.score ?? 0)
.with(0, () => '[&>*]:bg-red-500')
.with(1, () => '[&>*]:bg-orange-500')
.with(2, () => '[&>*]:bg-yellow-500')
.with(3, () => '[&>*]:bg-green-500')
.with(4, () => '[&>*]:bg-blue-500')
.otherwise(() => ''),
'grow',
)}
/>
<span className='text-sm text-center font-medium text-nowrap'>
{match(passwordStrength?.score ?? 0)
.with(0, () => 'Very weak')
.with(1, () => 'Weak')
.with(2, () => 'Fair')
.with(3, () => 'Good')
.with(4, () => 'Strong')
.otherwise(() => 'Empty')}
</span>
</div>
</div>
<span className='flex space-x-2'>
<Input
placeholder='Password'
type={isPasswordShowed ? 'text' : 'password'}
{...field}
className='rounded-full'
/>
<Button
aria-label='Show password'
className='rounded-full p-2'
onClick={() => {
setIsPasswordShowed((v) => !v);
}}
tabIndex={-1}
type='button'
variant='outline'
>
{match(isPasswordShowed)
.with(true, () => <EyeOff size={20} />)
.with(false, () => <Eye size={20} />)
.exhaustive()}
</Button>
</span>
</FormControl>
<FormMessage />
</FormItem>
Expand Down

0 comments on commit 454070b

Please sign in to comment.