11import { PlusIcon , XMarkIcon } from '@heroicons/react/24/solid'
22import clsx from 'clsx'
33import { ProfileWithoutUser } from 'common/profiles/profile'
4- import { PLATFORM_LABELS , type Site , SITE_ORDER , Socials } from 'common/socials'
4+ import {
5+ getSocialEntries ,
6+ getSocialLinkValues ,
7+ isMultiValueSite ,
8+ PLATFORM_LABELS ,
9+ type Site ,
10+ SITE_ORDER ,
11+ Socials ,
12+ } from 'common/socials'
513import { removeNullOrUndefinedProps } from 'common/util/object'
614import { Fragment , useState } from 'react'
715import { Button , IconButton } from 'web/components/buttons/button'
@@ -19,49 +27,74 @@ interface SocialLinksSectionProps {
1927
2028export function SocialLinksSection ( { profile, setProfile} : SocialLinksSectionProps ) {
2129 const t = useT ( )
22- const [ newLinkPlatform , setNewLinkPlatform ] = useState ( '' )
30+ const [ newLinkPlatform , setNewLinkPlatform ] = useState ( 'site ' )
2331 const [ newLinkValue , setNewLinkValue ] = useState ( '' )
2432
25- const updateUserLink = ( platform : string , value : string | null ) => {
26- setProfile (
27- 'links' ,
28- removeNullOrUndefinedProps ( { ...( ( profile . links as Socials ) ?? { } ) , [ platform ] : value } ) ,
29- )
33+ const setLinks = ( links : Socials ) => {
34+ setProfile ( 'links' , removeNullOrUndefinedProps ( links ) )
35+ }
36+
37+ const updateUserLink = ( platform : string , value : string | null , index = 0 ) => {
38+ const links = { ...( ( profile . links as Socials ) ?? { } ) }
39+ const currentValue = links [ platform ]
40+
41+ if ( Array . isArray ( currentValue ) ) {
42+ const nextValues = [ ...currentValue ]
43+ if ( value == null ) {
44+ nextValues . splice ( index , 1 )
45+ } else {
46+ nextValues [ index ] = value
47+ }
48+ setLinks ( { ...links , [ platform ] : nextValues . length > 0 ? nextValues : null } )
49+ return
50+ }
51+
52+ setLinks ( { ...links , [ platform ] : value } )
3053 }
3154
3255 const addNewLink = ( ) => {
3356 if ( newLinkPlatform && newLinkValue ) {
34- updateUserLink ( newLinkPlatform . toLowerCase ( ) . trim ( ) , newLinkValue . trim ( ) )
35- setNewLinkPlatform ( '' )
57+ const platform = newLinkPlatform . toLowerCase ( ) . trim ( )
58+ const value = newLinkValue . trim ( )
59+ const links = { ...( ( profile . links as Socials ) ?? { } ) }
60+
61+ if ( isMultiValueSite ( platform ) && links [ platform ] != null ) {
62+ setLinks ( {
63+ ...links ,
64+ [ platform ] : [ ...getSocialLinkValues ( links [ platform ] ) . filter ( Boolean ) , value ] ,
65+ } )
66+ } else {
67+ updateUserLink ( platform , value )
68+ }
69+
70+ setNewLinkPlatform ( 'site' )
3671 setNewLinkValue ( '' )
3772 }
3873 }
3974
4075 return (
4176 < Col className = { clsx ( 'pb-4' ) } >
4277 < div className = "grid w-full grid-cols-[8rem_1fr_auto] gap-2" >
43- { Object . entries ( ( profile . links ?? { } ) as Socials )
44- . filter ( ( [ _ , value ] ) => value != null )
45- . map ( ( [ platform , value ] ) => (
46- < Fragment key = { platform } >
47- < div className = "col-span-3 mt-2 flex items-center gap-2 self-center sm:col-span-1" >
48- < SocialIcon site = { platform as any } className = "text-primary-700 h-4 w-4" />
49- { PLATFORM_LABELS [ platform as Site ] ?? platform }
50- </ div >
51- < Input
52- type = "text"
53- value = { value ! }
54- onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
55- updateUserLink ( platform , e . target . value )
56- }
57- className = "col-span-2 sm:col-span-1"
58- />
59- < IconButton onClick = { ( ) => updateUserLink ( platform , null ) } >
60- < XMarkIcon className = "h-6 w-6" />
61- < div className = "sr-only" > { t ( 'common.remove' , 'Remove' ) } </ div >
62- </ IconButton >
63- </ Fragment >
64- ) ) }
78+ { getSocialEntries ( ( profile . links ?? { } ) as Socials ) . map ( ( { platform, value, index} ) => (
79+ < Fragment key = { `${ platform } -${ index } ` } >
80+ < div className = "col-span-3 mt-2 flex items-center gap-2 self-center sm:col-span-1" >
81+ < SocialIcon site = { platform as any } className = "text-primary-700 h-4 w-4" />
82+ { PLATFORM_LABELS [ platform as Site ] ?? platform }
83+ </ div >
84+ < Input
85+ type = "text"
86+ value = { value }
87+ onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
88+ updateUserLink ( platform , e . target . value , index )
89+ }
90+ className = "col-span-2 sm:col-span-1"
91+ />
92+ < IconButton onClick = { ( ) => updateUserLink ( platform , null , index ) } >
93+ < XMarkIcon className = "h-6 w-6" />
94+ < div className = "sr-only" > { t ( 'common.remove' , 'Remove' ) } </ div >
95+ </ IconButton >
96+ </ Fragment >
97+ ) ) }
6598
6699 { /* Spacer */ }
67100 < div className = "col-span-3 h-4" />
0 commit comments