|  | 
|  | 1 | +import { isAxiosError } from 'axios' | 
|  | 2 | +import { Button, TextInput } from 'flowbite-react' | 
|  | 3 | +import { useRouter } from 'next/router' | 
|  | 4 | +import React, { useState } from 'react' | 
|  | 5 | +import { toast } from 'react-toastify' | 
|  | 6 | +import { useNextTranslation } from 'src/hooks/i18n' | 
|  | 7 | +import { customThemeTextInput } from 'utils/comfyTheme' | 
|  | 8 | +import { useCreatePublisher, useValidatePublisher } from '@/src/api/generated' | 
|  | 9 | + | 
|  | 10 | +type CreatePublisherFormContentProps = { | 
|  | 11 | +    onSuccess?: (username: string) => void | 
|  | 12 | +    onCancel?: () => void | 
|  | 13 | +    showTitle?: boolean | 
|  | 14 | +} | 
|  | 15 | + | 
|  | 16 | +const CreatePublisherFormContent: React.FC<CreatePublisherFormContentProps> = ({ | 
|  | 17 | +    onSuccess, | 
|  | 18 | +    onCancel, | 
|  | 19 | +    showTitle = false, | 
|  | 20 | +}) => { | 
|  | 21 | +    const { t } = useNextTranslation() | 
|  | 22 | +    const router = useRouter() | 
|  | 23 | +    const [username, setUsername] = useState('') | 
|  | 24 | +    const [displayName, setDisplayName] = useState('') | 
|  | 25 | +    const [publisherValidationError, setPublisherValidationError] = useState('') | 
|  | 26 | + | 
|  | 27 | +    const { | 
|  | 28 | +        data, | 
|  | 29 | +        isLoading: isLoadingValidation, | 
|  | 30 | +        error, | 
|  | 31 | +    } = useValidatePublisher({ | 
|  | 32 | +        username: username, | 
|  | 33 | +    }) | 
|  | 34 | +    const createPublisherMutation = useCreatePublisher() | 
|  | 35 | + | 
|  | 36 | +    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => { | 
|  | 37 | +        event.preventDefault() | 
|  | 38 | +        createPublisherMutation.mutate( | 
|  | 39 | +            { | 
|  | 40 | +                data: { | 
|  | 41 | +                    id: username, | 
|  | 42 | +                    name: displayName, | 
|  | 43 | +                }, | 
|  | 44 | +            }, | 
|  | 45 | +            { | 
|  | 46 | +                onError: (error) => { | 
|  | 47 | +                    toast.error( | 
|  | 48 | +                        t('Could not create publisher. Please try again.') | 
|  | 49 | +                    ) | 
|  | 50 | +                }, | 
|  | 51 | +                onSuccess: () => { | 
|  | 52 | +                    toast.success('Publisher created successfully!') | 
|  | 53 | +                    if (onSuccess) { | 
|  | 54 | +                        onSuccess(username) | 
|  | 55 | +                    } else { | 
|  | 56 | +                        router.push(`/publishers/${username}`) | 
|  | 57 | +                    } | 
|  | 58 | +                }, | 
|  | 59 | +            } | 
|  | 60 | +        ) | 
|  | 61 | +    } | 
|  | 62 | + | 
|  | 63 | +    React.useEffect(() => { | 
|  | 64 | +        if (isAxiosError(error)) { | 
|  | 65 | +            setPublisherValidationError(error.response?.data?.message) | 
|  | 66 | +        } else { | 
|  | 67 | +            setPublisherValidationError('') | 
|  | 68 | +        } | 
|  | 69 | +    }, [error]) | 
|  | 70 | + | 
|  | 71 | +    return ( | 
|  | 72 | +        <> | 
|  | 73 | +            {showTitle && ( | 
|  | 74 | +                <h2 className="text-2xl font-bold text-white mb-4"> | 
|  | 75 | +                    {t('Create Publisher')} | 
|  | 76 | +                </h2> | 
|  | 77 | +            )} | 
|  | 78 | +            <p className="flex justify-center text-sm font-medium text-gray-400 "> | 
|  | 79 | +                {t( | 
|  | 80 | +                    'Register a publisher to begin distributing custom nodes on Comfy.' | 
|  | 81 | +                )} | 
|  | 82 | +            </p> | 
|  | 83 | + | 
|  | 84 | +            <form | 
|  | 85 | +                className="mt-4 space-y-4 lg:space-y-6" | 
|  | 86 | +                onSubmit={handleSubmit} | 
|  | 87 | +            > | 
|  | 88 | +                <div> | 
|  | 89 | +                    <label className="block mb-1 text-xs font-bold text-white"> | 
|  | 90 | +                        {t('Username')} | 
|  | 91 | +                    </label> | 
|  | 92 | +                    <TextInput | 
|  | 93 | +                        id="name" | 
|  | 94 | +                        placeholder={t('E.g. janedoe55')} | 
|  | 95 | +                        required | 
|  | 96 | +                        theme={customThemeTextInput} | 
|  | 97 | +                        type="text" | 
|  | 98 | +                        sizing="sm" | 
|  | 99 | +                        value={username} | 
|  | 100 | +                        onChange={(e) => setUsername(e.target.value)} | 
|  | 101 | +                        color={ | 
|  | 102 | +                            !isLoadingValidation && publisherValidationError | 
|  | 103 | +                                ? 'failure' | 
|  | 104 | +                                : 'success' | 
|  | 105 | +                        } | 
|  | 106 | +                        helperText={ | 
|  | 107 | +                            <> | 
|  | 108 | +                                {isLoadingValidation && ( | 
|  | 109 | +                                    <>{t('Checking username...')}</> | 
|  | 110 | +                                )} | 
|  | 111 | +                                {!isLoadingValidation && | 
|  | 112 | +                                    publisherValidationError && ( | 
|  | 113 | +                                        <> | 
|  | 114 | +                                            <span className="font-medium"></span>{' '} | 
|  | 115 | +                                            {publisherValidationError} | 
|  | 116 | +                                        </> | 
|  | 117 | +                                    )} | 
|  | 118 | +                            </> | 
|  | 119 | +                        } | 
|  | 120 | +                    /> | 
|  | 121 | +                </div> | 
|  | 122 | +                <div> | 
|  | 123 | +                    <label className="block mb-1 text-xs font-bold text-white"> | 
|  | 124 | +                        {t('Display Name')} | 
|  | 125 | +                    </label> | 
|  | 126 | +                    <TextInput | 
|  | 127 | +                        sizing="sm" | 
|  | 128 | +                        theme={customThemeTextInput} | 
|  | 129 | +                        id="displayName" | 
|  | 130 | +                        className="border-gray-700 " | 
|  | 131 | +                        placeholder={t('E.g. Jane Doe')} | 
|  | 132 | +                        required | 
|  | 133 | +                        type="text" | 
|  | 134 | +                        value={displayName} | 
|  | 135 | +                        onChange={(e) => setDisplayName(e.target.value)} | 
|  | 136 | +                    /> | 
|  | 137 | +                </div> | 
|  | 138 | + | 
|  | 139 | +                <div className="flex center gap-4"> | 
|  | 140 | +                    <Button | 
|  | 141 | +                        type="button" | 
|  | 142 | +                        onClick={onCancel} | 
|  | 143 | +                        color="light" | 
|  | 144 | +                        className=" bg-gray-900" | 
|  | 145 | +                    > | 
|  | 146 | +                        <span className="text-white">{t('Cancel')}</span> | 
|  | 147 | +                    </Button> | 
|  | 148 | +                    <Button | 
|  | 149 | +                        type="submit" | 
|  | 150 | +                        color="blue" | 
|  | 151 | +                        size="sm" | 
|  | 152 | +                        disabled={ | 
|  | 153 | +                            isLoadingValidation || !!publisherValidationError | 
|  | 154 | +                        } | 
|  | 155 | +                    > | 
|  | 156 | +                        {t('Create')} | 
|  | 157 | +                    </Button> | 
|  | 158 | +                </div> | 
|  | 159 | +            </form> | 
|  | 160 | +        </> | 
|  | 161 | +    ) | 
|  | 162 | +} | 
|  | 163 | + | 
|  | 164 | +export default CreatePublisherFormContent | 
0 commit comments