mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-02 13:52:46 +02:00
Validation on the username
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import type { AllowedProfileVisibility } from '../../api/user';
|
import type { AllowedProfileVisibility } from '../../api/user';
|
||||||
import { httpGet, httpPost } from '../../lib/http';
|
import { httpGet, httpPost } from '../../lib/http';
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import { CheckIcon, Loader2, X, XCircle } from 'lucide-react';
|
import { CheckIcon, Loader2, X, XCircle } from 'lucide-react';
|
||||||
|
import { useDebounceValue } from '../../hooks/use-debounce.ts';
|
||||||
|
|
||||||
type ProfileUsernameProps = {
|
type ProfileUsernameProps = {
|
||||||
username: string;
|
username: string;
|
||||||
@@ -17,6 +18,11 @@ export function ProfileUsername(props: ProfileUsernameProps) {
|
|||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isUnique, setIsUnique] = useState<boolean | null>(null);
|
const [isUnique, setIsUnique] = useState<boolean | null>(null);
|
||||||
|
const debouncedUsername = useDebounceValue(username, 500);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkIsUnique(debouncedUsername).then();
|
||||||
|
}, [debouncedUsername]);
|
||||||
|
|
||||||
const checkIsUnique = async (username: string) => {
|
const checkIsUnique = async (username: string) => {
|
||||||
if (isLoading || username.length < 3) {
|
if (isLoading || username.length < 3) {
|
||||||
@@ -66,7 +72,22 @@ export function ProfileUsername(props: ProfileUsernameProps) {
|
|||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
value={username}
|
value={username}
|
||||||
title="Username must be at least 3 characters long and can only contain letters, numbers, and underscores"
|
title="Username must be at least 3 characters long and can only contain letters, numbers, and underscores"
|
||||||
onChange={(e) => setUsername((e.target as HTMLInputElement).value)}
|
onKeyDown={(e) => {
|
||||||
|
// only allow letters, numbers
|
||||||
|
const keyCode = e.key;
|
||||||
|
const validKey = /^[a-zA-Z0-9]*$/.test(keyCode);
|
||||||
|
if (
|
||||||
|
!validKey &&
|
||||||
|
!['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight'].includes(
|
||||||
|
keyCode,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
setUsername((e.target as HTMLInputElement).value.toLowerCase());
|
||||||
|
}}
|
||||||
onBlur={(e) => checkIsUnique((e.target as HTMLInputElement).value)}
|
onBlur={(e) => checkIsUnique((e.target as HTMLInputElement).value)}
|
||||||
required={profileVisibility === 'public'}
|
required={profileVisibility === 'public'}
|
||||||
/>
|
/>
|
||||||
|
Reference in New Issue
Block a user