import type { PropsWithChildren } from "react"; import { useState } from "react"; import { Popover, Progress } from "@mantine/core"; import { useScopedI18n } from "@homarr/translation/client"; import { passwordRequirements } from "@homarr/validation/user"; import { PasswordRequirement } from "./password-requirement"; export const PasswordRequirementsPopover = ({ password, children }: PropsWithChildren<{ password: string }>) => { const requirements = useRequirements(); const strength = useStrength(password); const [popoverOpened, setPopoverOpened] = useState(false); const checks = ( <> {requirements.map((requirement) => ( ))} ); const color = strength === 100 ? "teal" : strength > 50 ? "yellow" : "red"; return (
setPopoverOpened(true)} onBlurCapture={() => setPopoverOpened(false)}> {children}
{checks}
); }; const useRequirements = () => { const t = useScopedI18n("user.field.password.requirement"); return passwordRequirements.map(({ check, value }) => ({ check, label: t(value) })); }; function useStrength(password: string) { const requirements = useRequirements(); return (100 / requirements.length) * requirements.filter(({ check }) => check(password)).length; }