feat: add forgot password flow and reusable password field

This commit is contained in:
2026-06-17 16:55:10 +05:30
parent 4c2241ff72
commit b325975282
15 changed files with 541 additions and 44 deletions

View File

@@ -0,0 +1,67 @@
'use client';
import { EyeIcon, EyeOffIcon } from 'lucide-react';
import { useState, type ComponentProps, type ReactNode } from 'react';
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from '@/components/ui/input-group';
import { FormField } from './FormField';
interface PasswordFieldProps
extends Omit<ComponentProps<typeof InputGroupInput>, 'type'> {
label: ReactNode;
required?: boolean;
error?: ReactNode;
labelEnd?: ReactNode;
fieldClassName?: string;
}
export function PasswordField({
id,
label,
required = false,
error,
labelEnd,
fieldClassName,
disabled,
...props
}: PasswordFieldProps) {
const [showPassword, setShowPassword] = useState(false);
const ToggleIcon = showPassword ? EyeOffIcon : EyeIcon;
return (
<FormField
id={id}
label={label}
required={required}
error={error}
labelEnd={labelEnd}
className={fieldClassName}
>
<InputGroup data-disabled={disabled ? 'true' : undefined}>
<InputGroupInput
id={id}
type={showPassword ? 'text' : 'password'}
disabled={disabled}
{...props}
/>
<InputGroupAddon align="inline-end">
<InputGroupButton
type="button"
size="icon-xs"
aria-label={showPassword ? 'Hide password' : 'Show password'}
disabled={disabled}
onClick={() => setShowPassword((current) => !current)}
>
<ToggleIcon />
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</FormField>
);
}

View File

@@ -1 +1,2 @@
export { FormField } from './FormField';
export { PasswordField } from './PasswordField';