diff --git a/components/pages/create.stories.tsx b/components/pages/create.stories.tsx new file mode 100644 index 00000000..e37395e2 --- /dev/null +++ b/components/pages/create.stories.tsx @@ -0,0 +1,66 @@ +import { Meta, StoryObj } from '@storybook/nextjs-vite' +import { Breadcrumb, Card } from 'flowbite-react' +import { HiHome } from 'react-icons/hi' +import CreatePublisherFormContent from '@/components/publisher/CreatePublisherFormContent' + +const CreatePublisherPageLayout = () => { + const handleSuccess = (username: string) => { + console.log('Publisher created successfully:', username) + // In a real scenario, this would navigate to the publisher page + } + + const handleCancel = () => { + console.log('Create publisher cancelled') + // In a real scenario, this would navigate back + } + + return ( +
+
+ + { + e.preventDefault() + console.log('Navigate to home') + }} + className="dark" + > + Home + + + Create Publisher + + +
+ +
+
+
+ + + +
+
+
+
+ ) +} + +const meta: Meta = { + title: 'Pages/Publishers/CreatePublisherPage', + component: CreatePublisherPageLayout, + parameters: { + layout: 'fullscreen', + }, +} + +export default meta +type Story = StoryObj + +export const Default: Story = {} diff --git a/components/publisher/CreatePublisherFormContent.tsx b/components/publisher/CreatePublisherFormContent.tsx new file mode 100644 index 00000000..37f396df --- /dev/null +++ b/components/publisher/CreatePublisherFormContent.tsx @@ -0,0 +1,164 @@ +import { isAxiosError } from 'axios' +import { Button, TextInput } from 'flowbite-react' +import { useRouter } from 'next/router' +import React, { useState } from 'react' +import { toast } from 'react-toastify' +import { useNextTranslation } from 'src/hooks/i18n' +import { customThemeTextInput } from 'utils/comfyTheme' +import { useCreatePublisher, useValidatePublisher } from '@/src/api/generated' + +type CreatePublisherFormContentProps = { + onSuccess?: (username: string) => void + onCancel?: () => void + showTitle?: boolean +} + +const CreatePublisherFormContent: React.FC = ({ + onSuccess, + onCancel, + showTitle = false, +}) => { + const { t } = useNextTranslation() + const router = useRouter() + const [username, setUsername] = useState('') + const [displayName, setDisplayName] = useState('') + const [publisherValidationError, setPublisherValidationError] = useState('') + + const { + data, + isLoading: isLoadingValidation, + error, + } = useValidatePublisher({ + username: username, + }) + const createPublisherMutation = useCreatePublisher() + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault() + createPublisherMutation.mutate( + { + data: { + id: username, + name: displayName, + }, + }, + { + onError: (error) => { + toast.error( + t('Could not create publisher. Please try again.') + ) + }, + onSuccess: () => { + toast.success('Publisher created successfully!') + if (onSuccess) { + onSuccess(username) + } else { + router.push(`/publishers/${username}`) + } + }, + } + ) + } + + React.useEffect(() => { + if (isAxiosError(error)) { + setPublisherValidationError(error.response?.data?.message) + } else { + setPublisherValidationError('') + } + }, [error]) + + return ( + <> + {showTitle && ( +

+ {t('Create Publisher')} +

+ )} +

+ {t( + 'Register a publisher to begin distributing custom nodes on Comfy.' + )} +

+ +
+
+ + setUsername(e.target.value)} + color={ + !isLoadingValidation && publisherValidationError + ? 'failure' + : 'success' + } + helperText={ + <> + {isLoadingValidation && ( + <>{t('Checking username...')} + )} + {!isLoadingValidation && + publisherValidationError && ( + <> + {' '} + {publisherValidationError} + + )} + + } + /> +
+
+ + setDisplayName(e.target.value)} + /> +
+ +
+ + +
+
+ + ) +} + +export default CreatePublisherFormContent diff --git a/components/publisher/CreatePublisherModal.stories.tsx b/components/publisher/CreatePublisherModal.stories.tsx new file mode 100644 index 00000000..2497972c --- /dev/null +++ b/components/publisher/CreatePublisherModal.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from '@storybook/nextjs-vite' +import CreatePublisherModal from './CreatePublisherModal' + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta: Meta = { + title: 'Components/Publisher/CreatePublisherModal', + component: CreatePublisherModal, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout + layout: 'centered', + }, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ['autodocs'], + // More on argTypes: https://storybook.js.org/docs/api/argtypes + argTypes: { + open: { control: 'boolean' }, + onCloseModal: { action: 'onCloseModal' }, + onSuccess: { action: 'onSuccess' }, + }, + // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args + args: { + open: true, + onCloseModal: () => {}, + }, +} + +export default meta +type Story = StoryObj + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: { + open: true, + }, +} + +export const Closed: Story = { + args: { + open: false, + }, +} diff --git a/components/publisher/CreatePublisherModal.tsx b/components/publisher/CreatePublisherModal.tsx index 5e4884fc..b4fd935a 100644 --- a/components/publisher/CreatePublisherModal.tsx +++ b/components/publisher/CreatePublisherModal.tsx @@ -1,11 +1,9 @@ -import { isAxiosError } from 'axios' -import { Button, Card, Modal, TextInput } from 'flowbite-react' +import { Modal } from 'flowbite-react' import { useRouter } from 'next/router' -import React, { useState } from 'react' -import { toast } from 'react-toastify' +import React from 'react' import { useNextTranslation } from 'src/hooks/i18n' -import { customThemeTextInput, customThemeTModal } from 'utils/comfyTheme' -import { useCreatePublisher, useValidatePublisher } from '@/src/api/generated' +import { customThemeTModal } from 'utils/comfyTheme' +import CreatePublisherFormContent from './CreatePublisherFormContent' type CreatePublisherModalProps = { open: boolean @@ -20,53 +18,14 @@ const CreatePublisherModal: React.FC = ({ }) => { const { t } = useNextTranslation() const router = useRouter() - const [username, setUsername] = useState('') - const [displayName, setDisplayName] = useState('') - const [publisherValidationError, setPublisherValidationError] = useState('') - const { - data, - isLoading: isLoadingValidation, - error, - } = useValidatePublisher({ - username: username, - }) - const createPublisherMutation = useCreatePublisher() - - const handleSubmit = (event: React.FormEvent) => { - event.preventDefault() - createPublisherMutation.mutate( - { - data: { - id: username, - name: displayName, - }, - }, - { - onError: (error) => { - toast.error( - t('Could not create publisher. Please try again.') - ) - }, - onSuccess: () => { - toast.success('Publisher created successfully!') - if (onSuccess) { - onSuccess() - } else { - router.push(`/publishers/${username}`) - } - }, - } - ) - } - - React.useEffect(() => { - if (isAxiosError(error)) { - setPublisherValidationError(error.response?.data?.message) + const handleSuccess = (username: string) => { + if (onSuccess) { + onSuccess() } else { - setPublisherValidationError('') + router.push(`/publishers/${username}`) } - }, [error]) + } return ( = ({ {t('Create Publisher')} -

- {t( - 'Register a publisher to begin distributing custom nodes on Comfy.' - )} -

- -
-
- - setUsername(e.target.value)} - color={ - !isLoadingValidation && publisherValidationError - ? 'failure' - : 'success' - } - helperText={ - <> - {isLoadingValidation && ( - <>{t('Checking username...')} - )} - {!isLoadingValidation && - publisherValidationError && ( - <> - {' '} - {publisherValidationError} - - )} - - } - /> -
-
- - setDisplayName(e.target.value)} - /> -
- -
- - -
-
+
) diff --git a/pages/publishers/create.tsx b/pages/publishers/create.tsx index 5ed11b73..6c785c31 100644 --- a/pages/publishers/create.tsx +++ b/pages/publishers/create.tsx @@ -1,61 +1,22 @@ -import { isAxiosError } from 'axios' -import { Breadcrumb, Button, Card, TextInput } from 'flowbite-react' +import { Breadcrumb, Card } from 'flowbite-react' import { useRouter } from 'next/router' -import React, { useState } from 'react' +import React from 'react' import { HiHome } from 'react-icons/hi' -import { toast } from 'react-toastify' -import { customThemeTextInput } from 'utils/comfyTheme' import withAuth from '@/components/common/HOC/withAuth' -import { useCreatePublisher, useValidatePublisher } from '@/src/api/generated' +import CreatePublisherFormContent from '@/components/publisher/CreatePublisherFormContent' import { useNextTranslation } from '@/src/hooks/i18n' const CreatePublisher = () => { const router = useRouter() const { t } = useNextTranslation() - const [username, setUsername] = useState('') - const [displayName, setDisplayName] = useState('') - const [publisherValidationError, setPublisherValidationError] = useState('') - - const { - data, - isLoading: isLoadingValidation, - error, - } = useValidatePublisher({ - username: username, - }) - const createPublisherMutation = useCreatePublisher() - - const handleSubmit = (event: React.FormEvent) => { - event.preventDefault() - createPublisherMutation.mutate( - { - data: { - id: username, - name: displayName, - }, - }, - { - onError: (error) => { - toast.error( - t('Could not create publisher. Please try again.') - ) - }, - onSuccess: () => { - toast.success('Publisher created successfully!') - router.push(`/publishers/${username}`) - }, - } - ) + const handleSuccess = (username: string) => { + router.push(`/publishers/${username}`) } - React.useEffect(() => { - if (isAxiosError(error)) { - setPublisherValidationError(error.response?.data?.message) - } else { - setPublisherValidationError('') - } - }, [error]) + const handleCancel = () => { + router.back() + } return (
@@ -82,102 +43,11 @@ const CreatePublisher = () => {
-

- {t( - 'Register a publisher to begin distributing custom nodes on Comfy.' - )} -

- -
-
- - - setUsername(e.target.value) - } - color={ - !isLoadingValidation && - publisherValidationError - ? 'failure' - : 'success' - } - helperText={ - <> - {isLoadingValidation && ( - <> - {t( - 'Checking username...' - )} - - )} - {!isLoadingValidation && - publisherValidationError && ( - <> - {' '} - { - publisherValidationError - } - - )} - - } - /> -
-
- - - setDisplayName(e.target.value) - } - /> -
- -
- - -
-
+
diff --git a/utils/comfyTheme.tsx b/utils/comfyTheme.tsx index f3aa003d..2882db22 100644 --- a/utils/comfyTheme.tsx +++ b/utils/comfyTheme.tsx @@ -32,10 +32,10 @@ export const customThemeTModal: CustomFlowbiteTheme = { }, content: { base: 'relative h-full w-full p-4 md:h-auto rounded-2xl bg-gray-800', - inner: 'relative flex max-h-[90dvh] flex-col rounded-lg bg-white bg-gray-200', + inner: 'relative flex max-h-[90dvh] flex-col rounded-lg bg-gray-800', }, body: { - base: 'flex-1 overflow-auto p-6 bg-gray-100', + base: 'flex-1 overflow-auto p-6 bg-gray-800', popup: 'pt-0', }, header: {