From fe651b21bcfdf7ab9877c1b0a9e7a28611d1ec96 Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Thu, 11 Apr 2024 00:39:31 +0600 Subject: [PATCH] feat: on blur check username --- .../UpdateProfile/ProfileUsername.tsx | 87 +++++++++++++++++++ .../UpdateProfile/UpdatePublicProfileForm.tsx | 81 +++++++---------- 2 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 src/components/UpdateProfile/ProfileUsername.tsx diff --git a/src/components/UpdateProfile/ProfileUsername.tsx b/src/components/UpdateProfile/ProfileUsername.tsx new file mode 100644 index 000000000..1f0ff4cd9 --- /dev/null +++ b/src/components/UpdateProfile/ProfileUsername.tsx @@ -0,0 +1,87 @@ +import { useState } from 'react'; +import type { AllowedProfileVisibility } from '../../api/user'; +import { httpGet, httpPost } from '../../lib/http'; +import { useToast } from '../../hooks/use-toast'; +import { CheckIcon, Loader2, X, XCircle } from 'lucide-react'; + +type ProfileUsernameProps = { + username: string; + setUsername: (username: string) => void; + profileVisibility: AllowedProfileVisibility; + currentUsername?: string; +}; + +export function ProfileUsername(props: ProfileUsernameProps) { + const { username, setUsername, profileVisibility, currentUsername } = props; + + const toast = useToast(); + const [isLoading, setIsLoading] = useState(false); + const [isUnique, setIsUnique] = useState(null); + + const checkIsUnique = async (username: string) => { + if (isLoading || username.length < 3) { + return; + } + + if (currentUsername && username === currentUsername && isUnique !== false) { + setIsUnique(true); + return; + } + + setIsLoading(true); + const { response, error } = await httpPost<{ + isUnique: boolean; + }>(`${import.meta.env.PUBLIC_API_URL}/v1-check-is-unique-username`, { + username, + }); + + if (error || !response) { + setIsUnique(null); + setIsLoading(false); + toast.error(error?.message || 'Something went wrong. Please try again.'); + return; + } + + setIsUnique(response.isUnique); + setIsLoading(false); + }; + + return ( +
+ +
+ + roadmap.sh/u/ + + +
+ setUsername((e.target as HTMLInputElement).value)} + onBlur={(e) => checkIsUnique((e.target as HTMLInputElement).value)} + required={profileVisibility === 'public'} + /> + + + {isLoading ? ( + + ) : isUnique === false ? ( + + ) : isUnique === true ? ( + + ) : null} + +
+
+
+ ); +} diff --git a/src/components/UpdateProfile/UpdatePublicProfileForm.tsx b/src/components/UpdateProfile/UpdatePublicProfileForm.tsx index 8c0b5040f..18231dfe7 100644 --- a/src/components/UpdateProfile/UpdatePublicProfileForm.tsx +++ b/src/components/UpdateProfile/UpdatePublicProfileForm.tsx @@ -12,6 +12,7 @@ import { ArrowUpRight, Eye, EyeOff } from 'lucide-react'; import { useToast } from '../../hooks/use-toast'; import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal.tsx'; import { VisibilityDropdown } from './VisibilityDropdown.tsx'; +import { ProfileUsername } from './ProfileUsername.tsx'; type RoadmapType = { id: string; @@ -43,6 +44,8 @@ export function UpdatePublicProfileForm() { const [roadmaps, setRoadmaps] = useState([]); const [customRoadmaps, setCustomRoadmaps] = useState([]); + const [currentUsername, setCurrentUsername] = useState(''); + const [github, setGithub] = useState(''); const [twitter, setTwitter] = useState(''); const [linkedin, setLinkedin] = useState(''); @@ -109,6 +112,7 @@ export function UpdatePublicProfileForm() { setPublicProfileUrl(username ? `/u/${username}` : ''); setUsername(username || ''); + setCurrentUsername(username || ''); setGithub(links?.github || ''); setTwitter(links?.twitter || ''); setLinkedin(links?.linkedin || ''); @@ -187,26 +191,28 @@ export function UpdatePublicProfileForm() { setIsCreatingRoadmap(false)} /> )} -
-
-

Personal Profile

- {publicProfileUrl && ( - - - Visit - - )} -
- +
+
+

+ Personal Profile +

+ {publicProfileUrl && ( + + + Visit + + )}
-

+ +

+

Set up your public profile to showcase your learning progress.

@@ -229,40 +235,19 @@ export function UpdatePublicProfileForm() { required={profileVisibility === 'public'} />
-
- -
- - roadmap.sh/u/ - - - setUsername((e.target as HTMLInputElement).value) - } - required={profileVisibility === 'public'} - /> -
-
+

Which roadmap progresses do you want to show on your profile?

-
+
Pick your custom roadmaps to show on your profile -
+