@@ -9,8 +9,9 @@ import type {
99} from '../../api/user' ;
1010import { SelectionButton } from '../RoadCard/SelectionButton' ;
1111import {
12- ArrowUpRight ,
12+ ArrowUpRight , Check ,
1313 CheckCircle ,
14+ Copy ,
1415 Eye ,
1516 EyeOff ,
1617 FileBadge ,
@@ -22,6 +23,8 @@ import { VisibilityDropdown } from './VisibilityDropdown.tsx';
2223import { ProfileUsername } from './ProfileUsername.tsx' ;
2324import UploadProfilePicture from './UploadProfilePicture.tsx' ;
2425import { SkillProfileAlert } from './SkillProfileAlert.tsx' ;
26+ import { useCopyText } from '../../hooks/use-copy-text.ts' ;
27+ import { cn } from '../../lib/classname.ts' ;
2528
2629type RoadmapType = {
2730 id : string ;
@@ -67,6 +70,8 @@ export function UpdatePublicProfileForm() {
6770
6871 const [ isLoading , setIsLoading ] = useState ( false ) ;
6972
73+ const { isCopied, copyText } = useCopyText ( ) ;
74+
7075 const handleSubmit = async ( e : FormEvent < HTMLFormElement > ) => {
7176 e . preventDefault ( ) ;
7277 setIsLoading ( true ) ;
@@ -167,31 +172,6 @@ export function UpdatePublicProfileForm() {
167172 setIsLoading ( false ) ;
168173 } ;
169174
170- const updateProfileVisibility = async (
171- visibility : AllowedProfileVisibility ,
172- ) => {
173- pageProgressMessage . set ( 'Updating profile visibility' ) ;
174- setIsLoading ( true ) ;
175-
176- const { error } = await httpPatch (
177- `${ import . meta. env . PUBLIC_API_URL } /v1-update-public-profile-visibility` ,
178- {
179- profileVisibility : visibility ,
180- } ,
181- ) ;
182-
183- if ( error ) {
184- setIsLoading ( false ) ;
185- toast . error ( error . message || 'Something went wrong' ) ;
186-
187- return ;
188- }
189-
190- setProfileVisibility ( visibility ) ;
191- setIsLoading ( false ) ;
192- pageProgressMessage . set ( '' ) ;
193- } ;
194-
195175 // Make a request to the backend to fill in the form with the current values
196176 useEffect ( ( ) => {
197177 Promise . all ( [ loadProfileSettings ( ) , loadProfileRoadmaps ( ) ] ) . finally ( ( ) => {
@@ -216,14 +196,31 @@ export function UpdatePublicProfileForm() {
216196 < div className = "flex flex-grow flex-row items-center gap-2 sm:items-center" >
217197 < h3 className = "mr-1 text-xl font-bold sm:text-3xl" > Skill Profile</ h3 >
218198 { publicProfileUrl && (
219- < a
220- href = { publicProfileUrl }
221- target = "_blank"
222- className = "flex shrink-0 flex-row items-center gap-1 rounded-lg border border-black py-0.5 pl-1.5 pr-2.5 text-xs uppercase transition-colors hover:bg-black hover:text-white"
223- >
224- < ArrowUpRight className = "h-3 w-3 stroke-[3]" />
225- Visit
226- </ a >
199+ < >
200+ < a
201+ href = { publicProfileUrl }
202+ target = "_blank"
203+ className = "flex shrink-0 flex-row items-center gap-1 rounded-lg border border-black py-0.5 pl-1.5 pr-2.5 text-xs uppercase transition-colors hover:bg-black hover:text-white"
204+ >
205+ < ArrowUpRight className = "h-3 w-3 stroke-[3]" />
206+ Visit
207+ </ a >
208+ < button
209+ onClick = { ( ) => {
210+ copyText ( `${ window . location . origin } ${ publicProfileUrl } ` ) ;
211+ } }
212+ className = { cn (
213+ 'flex shrink-0 flex-row items-center gap-1 rounded-lg border border-black py-0.5 pl-1.5 pr-2.5 text-xs uppercase transition-colors hover:bg-black hover:text-white' ,
214+ {
215+ 'bg-black text-white' : isCopied ,
216+ } ,
217+ ) }
218+ >
219+ { ! isCopied && < Copy className = "h-3 w-3 stroke-[2.5]" /> }
220+ { isCopied && < Check className = "h-3 w-3 stroke-[2.5]" /> }
221+ { ! isCopied ? 'Copy' : 'Copied!' }
222+ </ button >
223+ </ >
227224 ) }
228225 </ div >
229226 < VisibilityDropdown
0 commit comments