'use client' import type { MouseEventHandler } from 'react' import { useCallback, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiCloseLine, RiQuestionLine, } from '@remixicon/react' import { useRouter } from 'next/navigation' import { useContext, useContextSelector } from 'use-context-selector' import AppIconPicker from '../../base/app-icon-picker' import type { AppIconSelection } from '../../base/app-icon-picker' import s from './style.module.css' import cn from '@/utils/classnames' import AppsContext, { useAppContext } from '@/context/app-context' import { useProviderContext } from '@/context/provider-context' import { ToastContext } from '@/app/components/base/toast' import type { AppMode } from '@/types/app' import { createApp } from '@/service/apps' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import Input from '@/app/components/base/input' import Textarea from '@/app/components/base/textarea' import AppIcon from '@/app/components/base/app-icon' import AppsFull from '@/app/components/billing/apps-full-in-dialog' import { AiText, ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' import Tooltip from '@/app/components/base/tooltip' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' import { getRedirection } from '@/utils/app-redirection' type CreateAppDialogProps = { show: boolean onSuccess: () => void onClose: () => void } const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => { const { t } = useTranslation() const { push } = useRouter() const { notify } = useContext(ToastContext) const mutateApps = useContextSelector(AppsContext, state => state.mutateApps) const [appMode, setAppMode] = useState('chat') const [showChatBotType, setShowChatBotType] = useState(true) const [appIcon, setAppIcon] = useState({ type: 'emoji', icon: '🤖', background: '#FFEAD5' }) const [showAppIconPicker, setShowAppIconPicker] = useState(false) const [name, setName] = useState('') const [description, setDescription] = useState('') const { plan, enableBilling } = useProviderContext() const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps) const { isCurrentWorkspaceEditor } = useAppContext() const isCreatingRef = useRef(false) const onCreate: MouseEventHandler = useCallback(async () => { if (!appMode) { notify({ type: 'error', message: t('app.newApp.appTypeRequired') }) return } if (!name.trim()) { notify({ type: 'error', message: t('app.newApp.nameNotEmpty') }) return } if (isCreatingRef.current) return isCreatingRef.current = true try { const app = await createApp({ name, description, icon_type: appIcon.type, icon: appIcon.type === 'emoji' ? appIcon.icon : appIcon.fileId, icon_background: appIcon.type === 'emoji' ? appIcon.background : undefined, mode: appMode, }) notify({ type: 'success', message: t('app.newApp.appCreated') }) onSuccess() onClose() mutateApps() localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') getRedirection(isCurrentWorkspaceEditor, app, push) } catch (e) { notify({ type: 'error', message: t('app.newApp.appCreateFailed') }) } isCreatingRef.current = false }, [name, notify, t, appMode, appIcon, description, onSuccess, onClose, mutateApps, push, isCurrentWorkspaceEditor]) return ( { }} > {/* Heading */}
{t('app.newApp.startFromBlank')}
{/* app type */}
{t('app.newApp.captionAppType')}
{t('app.newApp.chatbotDescription')}
} >
{ setAppMode('chat') setShowChatBotType(true) }} >
{t('app.types.chatbot')}
{t('app.newApp.completionDescription')}
} >
{ setAppMode('completion') setShowChatBotType(false) }} >
{t('app.newApp.completeApp')}
{t('app.newApp.agentDescription')} } >
{ setAppMode('agent-chat') setShowChatBotType(false) }} >
{t('app.types.agent')}
{t('app.newApp.workflowDescription')}
} >
{ setAppMode('workflow') setShowChatBotType(false) }} >
{t('app.types.workflow')}
BETA
{showChatBotType && (
{t('app.newApp.chatbotType')}
{ setAppMode('chat') }} >
{t('app.newApp.basic')}
{t('app.newApp.basic')}
{t('app.newApp.basicFor')}
{t('app.newApp.basicDescription')}
{t('app.newApp.basicTip')}
{ setAppMode('advanced-chat') }} >
{t('app.newApp.advanced')}
BETA
{t('app.newApp.advanced')}
BETA
{t('app.newApp.advancedFor').toLocaleUpperCase()}
{t('app.newApp.advancedDescription')}
{t('app.newApp.advancedFor')}
)} {/* icon & name */}
{t('app.newApp.captionName')}
{ setShowAppIconPicker(true) }} /> setName(e.target.value)} placeholder={t('app.newApp.appNamePlaceholder') || ''} className='grow h-10' />
{showAppIconPicker && { setAppIcon(payload) setShowAppIconPicker(false) }} onClose={() => { setShowAppIconPicker(false) }} />}
{/* description */}
{t('app.newApp.captionDescription')}