import { type FormEvent, useEffect, useState } from 'react'; import { httpGet, httpPatch } from '../../lib/http'; import { pageProgressMessage } from '../../stores/page'; import type { AllowedCustomRoadmapVisibility, AllowedProfileVisibility, AllowedRoadmapVisibility, UserDocument, } from '../../api/user'; import { SelectionButton } from '../RoadCard/SelectionButton'; import { ArrowUpRight } from 'lucide-react'; import { useToast } from '../../hooks/use-toast'; type RoadmapType = { id: string; title: string; isCustomResource: boolean; }; type GetProfileSettingsResponse = Pick< UserDocument, 'username' | 'profileVisibility' | 'publicConfig' | 'links' >; export function UpdatePublicProfileForm() { const [profileVisibility, setProfileVisibility] = useState('private'); const toast = useToast(); const [publicProfileUrl, setPublicProfileUrl] = useState(''); const [isAvailableForHire, setIsAvailableForHire] = useState(false); const [headline, setHeadline] = useState(''); const [username, setUsername] = useState(''); const [roadmapVisibility, setRoadmapVisibility] = useState('none'); const [customRoadmapVisibility, setCustomRoadmapVisibility] = useState('none'); const [roadmaps, setRoadmaps] = useState([]); const [customRoadmaps, setCustomRoadmaps] = useState([]); const [github, setGithub] = useState(''); const [twitter, setTwitter] = useState(''); const [linkedin, setLinkedin] = useState(''); const [website, setWebsite] = useState(''); const [profileRoadmaps, setProfileRoadmaps] = useState([]); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setIsLoading(true); const { response, error } = await httpPatch( `${import.meta.env.PUBLIC_API_URL}/v1-update-public-profile-config`, { isAvailableForHire, profileVisibility, headline, username, roadmapVisibility, customRoadmapVisibility, roadmaps, customRoadmaps, github, twitter, linkedin, website, }, ); if (error || !response) { setIsLoading(false); toast.error(error?.message || 'Something went wrong'); return; } await loadProfileSettings(); toast.success('Profile updated successfully'); }; const loadProfileSettings = async () => { setIsLoading(true); const { error, response } = await httpGet( `${import.meta.env.PUBLIC_API_URL}/v1-get-profile-settings`, ); if (error || !response) { setIsLoading(false); toast.error(error?.message || 'Something went wrong'); return; } const { links, username, profileVisibility: defaultProfileVisibility, publicConfig, } = response; setPublicProfileUrl(`/u/${username}`); setUsername(username || ''); setGithub(links?.github || ''); setTwitter(links?.twitter || ''); setLinkedin(links?.linkedin || ''); setWebsite(links?.website || ''); setProfileVisibility(defaultProfileVisibility || 'private'); setHeadline(publicConfig?.headline || ''); setRoadmapVisibility(publicConfig?.roadmapVisibility || 'none'); setCustomRoadmapVisibility(publicConfig?.customRoadmapVisibility || 'none'); setCustomRoadmaps(publicConfig?.customRoadmaps || []); setRoadmaps(publicConfig?.roadmaps || []); setCustomRoadmapVisibility(publicConfig?.customRoadmapVisibility || 'none'); setIsAvailableForHire(publicConfig?.isAvailableForHire || false); setIsLoading(false); }; const loadProfileRoadmaps = async () => { setIsLoading(true); const { error, response } = await httpGet<{ roadmaps: RoadmapType[]; }>(`${import.meta.env.PUBLIC_API_URL}/v1-get-profile-roadmaps`); if (error || !response) { setIsLoading(false); toast.error(error?.message || 'Something went wrong'); return; } setProfileRoadmaps(response?.roadmaps || []); setIsLoading(false); }; const updateProfileVisibility = async ( visibility: AllowedProfileVisibility, ) => { pageProgressMessage.set('Updating profile visibility'); setIsLoading(true); const { error } = await httpPatch( `${import.meta.env.PUBLIC_API_URL}/v1-update-public-profile-visibility`, { profileVisibility: visibility, }, ); if (error) { setIsLoading(false); toast.error(error.message || 'Something went wrong'); return; } setProfileVisibility(visibility); setIsLoading(false); pageProgressMessage.set(''); }; // Make a request to the backend to fill in the form with the current values useEffect(() => { Promise.all([loadProfileSettings(), loadProfileRoadmaps()]).finally(() => { pageProgressMessage.set(''); }); }, []); const publicCustomRoadmaps = profileRoadmaps.filter( (r) => r.isCustomResource, ); const publicRoadmaps = profileRoadmaps.filter((r) => !r.isCustomResource); const isAllCustomRoadmapsSelected = customRoadmaps.length === publicCustomRoadmaps.length || customRoadmapVisibility === 'all'; const isAllRoadmapsSelected = roadmaps.length === publicRoadmaps.length || roadmapVisibility === 'all'; return ( <>

Public Profile

{publicProfileUrl && ( )}
updateProfileVisibility('public')} /> updateProfileVisibility('private')} />
setHeadline((e.target as HTMLInputElement).value)} required={profileVisibility === 'public'} />
roadmap.sh/u/ setUsername((e.target as HTMLInputElement).value) } required={profileVisibility === 'public'} />

Show my Learning Activity

{ setRoadmapVisibility('all'); setRoadmaps([...publicRoadmaps.map((r) => r.id)]); }} /> { setRoadmapVisibility('none'); setRoadmaps([]); }} />

Only Following Roadmaps

{publicRoadmaps.length > 0 ? (
{publicRoadmaps.map((r) => ( { if (roadmapVisibility !== 'selected') { setRoadmapVisibility('selected'); } if (roadmaps.includes(r.id)) { setRoadmaps(roadmaps.filter((id) => id !== r.id)); } else { setRoadmaps([...roadmaps, r.id]); } }} /> ))}
) : (

You are not following any roadmaps yet.{' '} Start following roadmaps

)}

Show my Custom Roadmaps

{ setCustomRoadmapVisibility('all'); setCustomRoadmaps([...publicCustomRoadmaps.map((r) => r.id)]); }} /> { setCustomRoadmapVisibility('none'); setCustomRoadmaps([]); }} />

Only Following Roadmaps

{publicCustomRoadmaps.length > 0 ? (
{publicCustomRoadmaps.map((r) => ( { if (customRoadmapVisibility !== 'selected') { setCustomRoadmapVisibility('selected'); } if (customRoadmaps.includes(r.id)) { setCustomRoadmaps( customRoadmaps.filter((id) => id !== r.id), ); } else { setCustomRoadmaps([...customRoadmaps, r.id]); } }} /> ))}
) : (

You have not created any custom roadmaps yet.{' '} Create a custom roadmap

)}
setGithub((e.target as HTMLInputElement).value)} />
setTwitter((e.target as HTMLInputElement).value)} />
setLinkedin((e.target as HTMLInputElement).value)} />
setWebsite((e.target as HTMLInputElement).value)} />
setIsAvailableForHire(e.target.checked)} />

Enable this if you are open to job opportunities, we will show a badge on your profile to indicate that you are available for hire.

); }