|
|
// create-app.tsx
// Copyright (C) 2020 Dwayne Harris
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { FC, useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' import { Link, useHistory } from 'react-router-dom' import { faCheckCircle, faIdCard, faLink, faAddressBook, faCodeBranch } from '@fortawesome/free-solid-svg-icons'
import { checkAppAvailability, createApp } from '../../actions/apps' import { initForm, initField, setFieldNotification } from '../../actions/forms' import { showNotification } from '../../actions/notifications' import { getForm } from '../../selectors/forms' import { getIsFetching } from '../../selectors/requests' import { useTheme } from '../../hooks' import { setTitle, valueFromForm } from '../../utils' import { AppState, NotificationType, AppThunkDispatch, RequestKey } from '../../types'
import Title from '../../components/title' import Section from '../../components/section' import HorizontalRule from '../../components/horizontal-rule' import PrimaryButton from '../../components/controls/primary-button' import TextField from '../../components/controls/text-field' import TextareaField from '../../components/controls/textarea-field' import CheckboxField from '../../components/controls/checkbox-field' import ImageField from '../../components/controls/image-field' import CoverImageField from '../../components/controls/cover-image-field' import IconImageField from '../../components/controls/icon-image-field'
const CreateApp: FC = () => { const theme = useTheme() const form = useSelector(getForm) const fetching = useSelector<AppState, boolean>(state => getIsFetching(state, RequestKey.CreateApp)) const dispatch = useDispatch<AppThunkDispatch>() const history = useHistory()
const checkAvailability = (value: string) => { if (value.length > 3) { dispatch(checkAppAvailability(value)) } }
const handleCreate = async () => { let invalid = false
const name = valueFromForm<string>(form, 'name') const about = valueFromForm<string>(form, 'about') const websiteUrl = valueFromForm<string>(form, 'websiteUrl') const companyName = valueFromForm<string>(form, 'companyName') const version = valueFromForm<string>(form, 'version') const composerUrl = valueFromForm<string>(form, 'composerUrl') const rendererUrl = valueFromForm<string>(form, 'rendererUrl') const imageUrl = valueFromForm<string>(form, 'image') const coverImageUrl = valueFromForm<string>(form, 'coverImage') const iconImageUrl = valueFromForm<string>(form, 'iconImage') const agree = valueFromForm<boolean>(form, 'agree')
if (!name || name === '') { dispatch(setFieldNotification('name', NotificationType.Error, 'This is required')) invalid = true }
if (!version || version === '') { dispatch(setFieldNotification('version', NotificationType.Error, 'This is required')) invalid = true }
if (!agree) { dispatch(setFieldNotification('agree', NotificationType.Error, 'You must agree to the terms and conditions to continue')) dispatch(showNotification(NotificationType.Error, 'You must agree to the terms and conditions to continue.')) invalid = true }
if (invalid) return
const id = await dispatch(createApp({ name: name!, version: version!, about, websiteUrl, companyName, composerUrl, rendererUrl, imageUrl, coverImageUrl, iconImageUrl, }))
dispatch(showNotification(NotificationType.Success, 'App created successfully!'))
setTimeout(() => { history.push(`/a/${id}`) }, 1000) }
useEffect(() => { setTitle('Create a new App')
dispatch(initForm()) dispatch(initField('name', '')) dispatch(initField('about', '')) dispatch(initField('websiteUrl', '')) dispatch(initField('companyName', '')) dispatch(initField('version', '')) dispatch(initField('composerUrl', '')) dispatch(initField('rendererUrl', '')) dispatch(initField('agree', false)) }, []) return ( <div> <Section> <Title>Create a new App</Title> <HorizontalRule />
<TextField name="name" label="Name" icon={faIdCard} placeholder="App ID/Name" onBlur={e => checkAvailability(e.target.value)} /> <TextareaField name="about" label="About" placeholder="Description of this app" /> <TextField name="websiteUrl" label="Website" icon={faLink} placeholder="Website URL (optional)" /> <TextField name="companyName" label="Company" icon={faAddressBook} placeholder="Your company or organization (optional)" /> <TextField name="version" label="Version" icon={faCodeBranch} placeholder="Current Version of the app (ex: 0.0.1beta5)" /> <HorizontalRule />
<ImageField name="image" /> <CoverImageField name="coverImage" /> <IconImageField name="iconImage" /> <HorizontalRule />
<TextField name="composerUrl" label="Composer URL" icon={faLink} placeholder="URL for the composer web page" /> <TextField name="rendererUrl" label="Renderer URL" icon={faLink} placeholder="URL for the renderer template" />
<CheckboxField name="agree"> I agree to the Apps <Link style={{ color: theme.primary }} to="/terms/apps">terms and conditions</Link>. </CheckboxField> <br /><br /> <PrimaryButton text="Create" icon={faCheckCircle} loading={fetching} onClick={() => handleCreate()} /> </Section> </div> ) }
export default CreateApp
|