import { Alert, AlertIcon, Box, FormControl, FormLabel, IconButton, Input, InputGroup, InputRightElement, Stack, Tag, TagCloseButton, TagLabel, Text, } from '@chakra-ui/react'; import { __ } from '@wordpress/i18n'; import React, { useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { MdOutlineKeyboardReturn } from 'react-icons/md'; import { accountPageFormLabelStyles } from '../../../../../../assets/js/account/utils/general'; import localized from '../../../../../../assets/js/account/utils/global'; interface Props { defaultValue?: string[]; maxGroupSize?: number; disabled?: boolean; displayStatus?: 'active' | 'pending' | 'inactive'; } const EmailsInput: React.FC = ({ defaultValue = [], maxGroupSize, disabled = false, displayStatus, }) => { const { setValue, watch, trigger, formState: { errors }, setError, clearErrors, } = useFormContext(); const [input, setInput] = useState(''); const emails = watch('emails') || defaultValue; // Use prop if provided, otherwise fallback to global limit const groupLimit = maxGroupSize || localized?.group_courses?.group_limit || 0; const isValidEmail = (email: string) => { const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(email.toLowerCase()); }; const handleAddEmail = () => { if (!isValidEmail(input)) { setError('emails', { type: 'manual', message: __('Invalid email address.', 'learning-management-system'), }); return; } if (emails.includes(input)) { setError('emails', { type: 'manual', message: __('Email already added.', 'learning-management-system'), }); return; } if (groupLimit > 0 && emails.length >= groupLimit) { setError('emails', { type: 'manual', message: __( `Maximum group size of ${groupLimit} members reached`, 'learning-management-system', ), }); return; } const updatedEmails = [...emails, input]; setValue('emails', updatedEmails, { shouldValidate: true }); setInput(''); clearErrors('emails'); trigger('emails'); }; const handleInputChange = (e: React.ChangeEvent) => { setInput(e.target.value); if (e.target.value.length === 0 || isValidEmail(e.target.value)) { clearErrors(['emails']); } }; const handleRemoveEmail = (emailToRemove: string) => { const updatedEmails = emails.filter( (email: string) => email !== emailToRemove, ); setValue('emails', updatedEmails, { shouldValidate: true }); trigger('emails'); }; return ( {__('Members', 'learning-management-system')} {groupLimit > 0 ? ` (${__('Max', 'learning-management-system')}: ${groupLimit})` : ` (${__('Unlimited', 'learning-management-system')})`} {disabled && ( {displayStatus === 'inactive' ? __( 'This group is inactive. Complete your purchase to manage members.', 'learning-management-system', ) : __( 'Group is pending approval. Members cannot be modified until the group is approved.', 'learning-management-system', )} )} { if (e.key === 'Enter') { e.preventDefault(); handleAddEmail(); } }} isDisabled={ disabled || (groupLimit > 0 && emails.length >= groupLimit) } /> } onClick={handleAddEmail} isDisabled={ disabled || !isValidEmail(input) || emails.includes(input) || (groupLimit > 0 && emails.length >= groupLimit) } variant="solid" colorScheme="primary" /> {errors.emails && ( {errors.emails.message?.toString()} )} {emails.length > 0 && ( {emails.map((email: string, index: number) => ( {email} handleRemoveEmail(email)} isDisabled={disabled} /> ))} )} ); }; export default EmailsInput;