[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

154 lines
6.5 KiB

// 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