File "social-profiles.js"

Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/surerank/src/apps/admin-onboarding/steps/social-profiles.js
File size: 5.8 KB
MIME-type: text/html
Charset: utf-8

import { __ } from '@wordpress/i18n';
import { useState, Fragment, useMemo } from '@wordpress/element';
import {
	FacebookIcon,
	TwitterIcon,
	InstagramIcon,
	LinkedInIcon,
	YouTubeIcon,
	PinterestIcon,
	TikTokIcon,
	MediumIcon,
	TumblrIcon,
	ThreadsIcon,
	YelpIcon,
	WhatsAppIcon,
	TelegramIcon,
	BlueSkyIcon,
} from '../icons';
import { Button, DropdownMenu, Title } from '@bsf/force-ui';
import { PlusIcon, LinkIcon } from 'lucide-react';
import StepNavButtons from '../components/nav-buttons';
import { useOnboardingState } from '@Onboarding/store';
import { focusHelper } from '../utils';

const iconMap = {
	facebook: FacebookIcon,
	twitter: TwitterIcon,
	instagram: InstagramIcon,
	linkedin: LinkedInIcon,
	youtube: YouTubeIcon,
	pinterest: PinterestIcon,
	tiktok: TikTokIcon,
	medium: MediumIcon,
	tumblr: TumblrIcon,
	threads: ThreadsIcon,
	yelp: YelpIcon,
	whatsapp: WhatsAppIcon,
	telegram: TelegramIcon,
	link: LinkIcon,
	bluesky: BlueSkyIcon,
};

const socialProfiles = surerank_admin_common?.social_profiles
	.filter( ( item ) => ! item.extra )
	.map( ( item ) => ( {
		...item,
		icon: iconMap[ item.id ] || iconMap.link,
	} ) );

const dropdownOptions = surerank_admin_common?.social_profiles
	.filter( ( item ) => item.extra )
	.map( ( item ) => ( {
		...item,
		icon: iconMap[ item.id ] || iconMap.link,
	} ) );

/**
 * Get the initial list of social profiles to render.
 *
 * @param {Object} formState - The form state.
 * @return {Array} The initial list of social profiles to render.
 */
const getInitialList = ( formState ) => {
	return [
		...socialProfiles,
		...dropdownOptions.filter( ( item ) => item.id in formState ),
	];
};

const SocialProfiles = () => {
	const [ { socialProfilesURLs = {} }, dispatch ] = useOnboardingState();
	// Local states
	const [ formState, setFormState ] = useState( socialProfilesURLs );
	const [ socialProfileLists, setSocialProfileLists ] = useState(
		getInitialList( formState )
	);

	const handleSubmit = ( event ) => {
		event.preventDefault();
	};

	const handleAddProfileToList = ( socialMediaItem ) => {
		setSocialProfileLists( ( prev ) => [ ...prev, socialMediaItem ] );
	};

	const filteredDropdownOptions = useMemo( () => {
		return dropdownOptions.filter(
			( item ) =>
				! socialProfileLists.some(
					( listItem ) => listItem.id === item.id
				)
		);
	}, [ socialProfileLists ] );

	const handleChange = ( id ) => ( event ) => {
		setFormState( ( prev ) => ( { ...prev, [ id ]: event.target.value } ) );
	};

	const handleSaveForm = () => {
		dispatch( {
			socialProfilesURLs: formState,
		} );
	};

	return (
		<form className="flex flex-col gap-6" onSubmit={ handleSubmit }>
			<div className="space-y-1">
				<Title
					tag="h4"
					title={ __( 'Social Profiles', 'surerank' ) }
					size="md"
				/>
				<p className="w-full">
					{ __(
						'Please enter your social media profiles. These links can appear in the knowledge panel of the search results for your website.',
						'surerank'
					) }
				</p>
			</div>
			{ /* Settings / options */ }
			<div className="flex flex-col border border-solid border-border-subtle rounded-lg p-1">
				{ socialProfileLists.map(
					( { label, id, placeholder, icon: Icon }, index ) => (
						<Fragment key={ id }>
							<div className="flex items-center gap-3 w-full p-2.5">
								<div className="flex items-center gap-3 w-2/4">
									<Icon className="size-5" />
									<span className="hidden md:inline-block text-field-label text-sm font-medium whitespace-nowrap">
										{ label }
									</span>
								</div>
								<input
									className="text-sm text-right text-text-primary placeholder:text-text-tertiary w-full border-none bg-transparent focus:outline-none focus:ring-0"
									placeholder={ placeholder }
									onChange={ handleChange( id ) }
									value={ formState[ id ] || '' }
									{ ...( index === 0 && {
										ref: focusHelper,
									} ) }
								/>
							</div>
							{ ( !! filteredDropdownOptions.length ||
								index < socialProfileLists.length - 1 ) && (
								<span className="w-full block px-2.5">
									<hr className="border-border-subtle border-b border-t-0 border-x-0 my-1 w-full" />
								</span>
							) }
						</Fragment>
					)
				) }
				{ !! filteredDropdownOptions.length && (
					<DropdownMenu>
						<DropdownMenu.Trigger>
							<Button
								type="button"
								variant="ghost"
								className="w-max my-2 mx-auto"
								size="xs"
								icon={ <PlusIcon className="size-4" /> }
								iconPosition="right"
							>
								{ __( 'Add another profile', 'surerank' ) }
							</Button>
						</DropdownMenu.Trigger>
						<DropdownMenu.Portal id="surerank-root">
							<DropdownMenu.ContentWrapper>
								<DropdownMenu.Content className="w-60">
									<DropdownMenu.List>
										{ filteredDropdownOptions.map(
											( {
												label,
												id,
												icon: Icon,
												placeholder,
											} ) => (
												<DropdownMenu.Item
													key={ id }
													onClick={ () =>
														handleAddProfileToList(
															{
																label,
																id,
																icon: Icon,
																placeholder,
															}
														)
													}
												>
													<div className="flex items-center gap-3 w-full">
														<Icon className="size-4" />
														<span className="text-field-label text-sm font-medium">
															{ label }
														</span>
													</div>
												</DropdownMenu.Item>
											)
										) }
									</DropdownMenu.List>
								</DropdownMenu.Content>
							</DropdownMenu.ContentWrapper>
						</DropdownMenu.Portal>
					</DropdownMenu>
				) }
			</div>
			<StepNavButtons
				className="my-0"
				nextProps={ {
					onClick: handleSaveForm,
				} }
				backProps={ {
					onClick: handleSaveForm,
				} }
			/>
		</form>
	);
};

export default SocialProfiles;