From 37f9d0b62d58c3e1aff5c6fa3994546232397ac9 Mon Sep 17 00:00:00 2001 From: Michael Schramm Date: Sat, 30 May 2020 12:59:31 +0200 Subject: [PATCH] add logic for field types --- components/form/types/date.type.tsx | 15 ++- components/form/types/email.type.tsx | 14 ++- components/form/types/link.type.tsx | 14 ++- components/styled/color.change.ts | 25 ++++ components/styled/date.input.tsx | 61 ++++++++++ components/styled/input.tsx | 5 + graphql/fragment/admin.form.fragment.ts | 3 + .../mutation/admin.form.create.mutation.ts | 2 +- pages/_app.tsx | 2 +- pages/admin/forms/[id]/index.tsx | 32 ++--- pages/admin/forms/create.tsx | 115 ++++++++++++++++++ pages/admin/forms/index.tsx | 30 +++-- pages/admin/index.tsx | 4 +- pages/admin/users/[id]/index.tsx | 4 +- pages/admin/users/index.tsx | 4 +- pages/form/[id]/index.tsx | 22 ++-- pages/form/index.tsx | 2 +- pages/index.tsx | 2 +- pages/login/confirm/[code].tsx | 4 +- pages/login/index.tsx | 8 +- pages/login/recover.tsx | 4 +- pages/register.tsx | 8 +- 22 files changed, 307 insertions(+), 73 deletions(-) create mode 100644 components/styled/date.input.tsx create mode 100644 pages/admin/forms/create.tsx diff --git a/components/form/types/date.type.tsx b/components/form/types/date.type.tsx index 130a599..96e2a87 100644 --- a/components/form/types/date.type.tsx +++ b/components/form/types/date.type.tsx @@ -1,21 +1,26 @@ -import {DatePicker, Form} from 'antd' +import {Form} from 'antd' +import moment from 'moment' import React from 'react' +import {StyledDateInput} from '../../styled/date.input' import {FieldTypeProps} from './type.props' -export const DateType: React.FC = ({field}) => { +export const DateType: React.FC = ({field, design}) => { // TODO check min and max return (
- +
) diff --git a/components/form/types/email.type.tsx b/components/form/types/email.type.tsx index 7f3de70..613b32a 100644 --- a/components/form/types/email.type.tsx +++ b/components/form/types/email.type.tsx @@ -1,20 +1,24 @@ -import {Form, Input} from 'antd' +import {Form} from 'antd' import React from 'react' +import {StyledInput} from '../../styled/input' import {FieldTypeProps} from './type.props' -export const EmailType: React.FC = ({field}) => { +export const EmailType: React.FC = ({field, design}) => { return (
- +
) diff --git a/components/form/types/link.type.tsx b/components/form/types/link.type.tsx index 6bc155a..b8c11f0 100644 --- a/components/form/types/link.type.tsx +++ b/components/form/types/link.type.tsx @@ -1,20 +1,24 @@ -import {Form, Input} from 'antd' +import {Form} from 'antd' import React from 'react' +import {StyledInput} from '../../styled/input' import {FieldTypeProps} from './type.props' -export const LinkType: React.FC = ({field}) => { +export const LinkType: React.FC = ({field, design}) => { return (
- +
) diff --git a/components/styled/color.change.ts b/components/styled/color.change.ts index c65c637..13a842c 100644 --- a/components/styled/color.change.ts +++ b/components/styled/color.change.ts @@ -31,5 +31,30 @@ function LightenDarkenColor(col, amt) { return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16); } +export const transparentize = (col: string, amt: number) => { + if (col[0] == "#") { + col = col.slice(1); + } + + const num = parseInt(col, 16) + + let r = (num >> 16) + amt; + + if (r > 255) r = 255; + else if (r < 0) r = 0; + + let b = ((num >> 8) & 0x00FF) + amt; + + if (b > 255) b = 255; + else if (b < 0) b = 0; + + let g = (num & 0x0000FF) + amt; + + if (g > 255) g = 255; + else if (g < 0) g = 0; + + return `rgba(${r}, ${b}, ${g}, ${1 - amt / 100})` +} + export const lighten = (color: string, amount: number) => LightenDarkenColor(color, amount) export const darken = (color: string, amount: number) => LightenDarkenColor(color, -amount) diff --git a/components/styled/date.input.tsx b/components/styled/date.input.tsx new file mode 100644 index 0000000..d33f14f --- /dev/null +++ b/components/styled/date.input.tsx @@ -0,0 +1,61 @@ +import {DatePicker} from 'antd' +import {PickerProps} from 'antd/lib/date-picker/generatePicker' +import {Moment} from 'moment' +import React, {useEffect, useState} from 'react' +import styled from 'styled-components' +import {FormDesignFragment} from '../../graphql/fragment/form.fragment' +import {transparentize} from './color.change' + +type Props = { design: FormDesignFragment } & PickerProps + +export const StyledDateInput: React.FC = ({design, children, ...props}) => { + const [Field, setField] = useState() + + useEffect(() => { + setField( + styled(DatePicker)` + color: ${design.colors.answerColor}; + border-color: ${design.colors.answerColor}; + background: none !important; + border-right: none; + border-top: none; + border-left: none; + border-radius: 0; + width: 100%; + + :hover, + :active { + border-color: ${design.colors.answerColor}; + } + + &.ant-picker { + box-shadow: none + } + + .ant-picker-clear { + background: none; + } + + input { + color: ${design.colors.answerColor}; + + ::placeholder { + color: ${transparentize(design.colors.answerColor, 60)} + } + } + + .anticon { + color: ${design.colors.answerColor}; + } + ` + ) + }, [design]) + + if (!Field) { + return null + } + + return ( + {children} + ) +} diff --git a/components/styled/input.tsx b/components/styled/input.tsx index c3234b6..3a2c9ee 100644 --- a/components/styled/input.tsx +++ b/components/styled/input.tsx @@ -3,6 +3,7 @@ import {InputProps} from 'antd/lib/input/Input' import React, {useEffect, useState} from 'react' import styled from 'styled-components' import {FormDesignFragment} from '../../graphql/fragment/form.fragment' +import {transparentize} from './color.change' interface Props extends InputProps{ design: FormDesignFragment @@ -38,6 +39,10 @@ export const StyledInput: React.FC = ({design, children, ...props}) => { input { background: none !important; color: ${design.colors.answerColor}; + + ::placeholder { + color: ${transparentize(design.colors.answerColor, 60)} + } } .anticon { diff --git a/graphql/fragment/admin.form.fragment.ts b/graphql/fragment/admin.form.fragment.ts index 70760ee..f7f2ee7 100644 --- a/graphql/fragment/admin.form.fragment.ts +++ b/graphql/fragment/admin.form.fragment.ts @@ -104,6 +104,7 @@ export const ADMIN_FORM_FRAGMENT = gql` questionColor answerColor buttonColor + buttonActiveColor buttonTextColor } font @@ -118,6 +119,7 @@ export const ADMIN_FORM_FRAGMENT = gql` action text bgColor + activeColor color } } @@ -131,6 +133,7 @@ export const ADMIN_FORM_FRAGMENT = gql` action text bgColor + activeColor color } } diff --git a/graphql/mutation/admin.form.create.mutation.ts b/graphql/mutation/admin.form.create.mutation.ts index 15d43f6..d2ec8a6 100644 --- a/graphql/mutation/admin.form.create.mutation.ts +++ b/graphql/mutation/admin.form.create.mutation.ts @@ -10,7 +10,7 @@ export interface AdminFormCreateMutationVariables { } export const ADMIN_FORM_CREATE_MUTATION = gql` - mutation update($$form: FormCreateInput!) { + mutation update($form: FormCreateInput!) { form: createForm(form: $form) { ...AdminForm } diff --git a/pages/_app.tsx b/pages/_app.tsx index 30d9d45..3654882 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -5,12 +5,12 @@ import ApolloClient from 'apollo-boost' import 'assets/global.scss' import 'assets/variables.scss' import axios from 'axios' +import {authConfig} from 'components/with.auth' import {AppProps} from 'next/app' import getConfig from 'next/config' import Head from 'next/head' import React from 'react' import {wrapper} from 'store' -import {authConfig} from '../components/with.auth' const { publicRuntimeConfig } = getConfig() diff --git a/pages/admin/forms/[id]/index.tsx b/pages/admin/forms/[id]/index.tsx index ae9b7af..45a852d 100644 --- a/pages/admin/forms/[id]/index.tsx +++ b/pages/admin/forms/[id]/index.tsx @@ -1,26 +1,26 @@ import {useMutation, useQuery} from '@apollo/react-hooks' import {Button, Form, Input, message, Tabs} from 'antd' import {useForm} from 'antd/lib/form/Form' -import {NextPage} from 'next' -import {useRouter} from 'next/router' -import React, {useState} from 'react' -import {cleanInput} from '../../../../components/clean.input' -import {BaseDataTab} from '../../../../components/form/admin/base.data.tab' -import {DesignTab} from '../../../../components/form/admin/design.tab' -import {EndPageTab} from '../../../../components/form/admin/end.page.tab' -import {FieldsTab} from '../../../../components/form/admin/fields.tab' -import {RespondentNotificationsTab} from '../../../../components/form/admin/respondent.notifications.tab' -import {SelfNotificationsTab} from '../../../../components/form/admin/self.notifications.tab' -import {StartPageTab} from '../../../../components/form/admin/start.page.tab' -import Structure from '../../../../components/structure' -import {withAuth} from '../../../../components/with.auth' -import {AdminFormFieldFragment} from '../../../../graphql/fragment/admin.form.fragment' +import {cleanInput} from 'components/clean.input' +import {BaseDataTab} from 'components/form/admin/base.data.tab' +import {DesignTab} from 'components/form/admin/design.tab' +import {EndPageTab} from 'components/form/admin/end.page.tab' +import {FieldsTab} from 'components/form/admin/fields.tab' +import {RespondentNotificationsTab} from 'components/form/admin/respondent.notifications.tab' +import {SelfNotificationsTab} from 'components/form/admin/self.notifications.tab' +import {StartPageTab} from 'components/form/admin/start.page.tab' +import Structure from 'components/structure' +import {withAuth} from 'components/with.auth' +import {AdminFormFieldFragment} from 'graphql/fragment/admin.form.fragment' import { ADMIN_FORM_UPDATE_MUTATION, AdminFormUpdateMutationData, AdminFormUpdateMutationVariables -} from '../../../../graphql/mutation/admin.form.update.mutation' -import {ADMIN_FORM_QUERY, AdminFormQueryData, AdminFormQueryVariables} from '../../../../graphql/query/admin.form.query' +} from 'graphql/mutation/admin.form.update.mutation' +import {ADMIN_FORM_QUERY, AdminFormQueryData, AdminFormQueryVariables} from 'graphql/query/admin.form.query' +import {NextPage} from 'next' +import {useRouter} from 'next/router' +import React, {useState} from 'react' const Index: NextPage = () => { const router = useRouter() diff --git a/pages/admin/forms/create.tsx b/pages/admin/forms/create.tsx new file mode 100644 index 0000000..f4edfed --- /dev/null +++ b/pages/admin/forms/create.tsx @@ -0,0 +1,115 @@ +import {useMutation} from '@apollo/react-hooks' +import {Button, Form, Input, message, Tabs} from 'antd' +import {useForm} from 'antd/lib/form/Form' +import {cleanInput} from 'components/clean.input' +import {BaseDataTab} from 'components/form/admin/base.data.tab' +import Structure from 'components/structure' +import {withAuth} from 'components/with.auth' +import {AdminFormQueryData} from 'graphql/query/admin.form.query' +import {NextPage} from 'next' +import {useRouter} from 'next/router' +import React, {useState} from 'react' +import { + ADMIN_FORM_CREATE_MUTATION, + AdminFormCreateMutationData, + AdminFormCreateMutationVariables +} from '../../../graphql/mutation/admin.form.create.mutation' + +const Create: NextPage = () => { + const router = useRouter() + const [form] = useForm() + const [saving, setSaving] = useState(false) + const [create] = useMutation(ADMIN_FORM_CREATE_MUTATION) + + const save = async (formData: AdminFormQueryData) => { + setSaving(true) + console.log('try to save form!', formData) + + try { + const next = (await create({ + variables: cleanInput(formData), + })).data + + message.success('Form Created') + + router.replace('/admin/forms/[id]', `/admin/forms/${next.form.id}`) + } catch (e) { + console.error('failed to save', e) + message.error('Could not save Form') + } + + setSaving(false) + } + + return ( + + Save + , + ]} + style={{paddingTop: 0}} + > +
{ + message.error('Required fields are missing') + }} + labelCol={{ + xs: { span: 24 }, + sm: { span: 6 }, + }} + wrapperCol={{ + xs: { span: 24 }, + sm: { span: 18 }, + }} + > + + + + {/* + + */} + + {/* + + + + + + */} + +
+
+ ) +} + +export default withAuth(Create, ['admin']) diff --git a/pages/admin/forms/index.tsx b/pages/admin/forms/index.tsx index 7e83f57..f2eae80 100644 --- a/pages/admin/forms/index.tsx +++ b/pages/admin/forms/index.tsx @@ -2,20 +2,20 @@ import {DeleteOutlined, EditOutlined, GlobalOutlined} from '@ant-design/icons/li import {useQuery} from '@apollo/react-hooks' import {Button, Popconfirm, Space, Table, Tooltip} from 'antd' import {PaginationProps} from 'antd/es/pagination' -import {NextPage} from 'next' -import Link from 'next/link' -import React, {useState} from 'react' -import {DateTime} from '../../../components/date.time' -import {FormIsLive} from '../../../components/form/admin/is.live' -import Structure from '../../../components/structure' -import {TimeAgo} from '../../../components/time.ago' -import {withAuth} from '../../../components/with.auth' +import {DateTime} from 'components/date.time' +import {FormIsLive} from 'components/form/admin/is.live' +import Structure from 'components/structure' +import {TimeAgo} from 'components/time.ago' +import {withAuth} from 'components/with.auth' import { PAGER_FORM_QUERY, PagerFormEntryQueryData, PagerFormQueryData, PagerFormQueryVariables -} from '../../../graphql/query/pager.form.query' +} from 'graphql/query/pager.form.query' +import {NextPage} from 'next' +import Link from 'next/link' +import React, {useState} from 'react' const Index: NextPage = () => { const [pagination, setPagination] = useState({ @@ -118,6 +118,18 @@ const Index: NextPage = () => { { href: '/admin', name: 'Home' }, ]} padded={false} + extra={[ + + + , + ]} > { return ( diff --git a/pages/admin/users/[id]/index.tsx b/pages/admin/users/[id]/index.tsx index 87a2da0..9be28ea 100644 --- a/pages/admin/users/[id]/index.tsx +++ b/pages/admin/users/[id]/index.tsx @@ -1,7 +1,7 @@ +import Structure from 'components/structure' +import {withAuth} from 'components/with.auth' import {NextPage} from 'next' import React from 'react' -import Structure from '../../../../components/structure' -import {withAuth} from '../../../../components/with.auth' const Index: NextPage = () => { return ( diff --git a/pages/admin/users/index.tsx b/pages/admin/users/index.tsx index 68e7d56..fa7c0fd 100644 --- a/pages/admin/users/index.tsx +++ b/pages/admin/users/index.tsx @@ -1,7 +1,7 @@ +import Structure from 'components/structure' +import {withAuth} from 'components/with.auth' import {NextPage} from 'next' import React from 'react' -import Structure from '../../../components/structure' -import {withAuth} from '../../../components/with.auth' const Index: NextPage = () => { return ( diff --git a/pages/form/[id]/index.tsx b/pages/form/[id]/index.tsx index 2ea5f6c..5cfa2eb 100644 --- a/pages/form/[id]/index.tsx +++ b/pages/form/[id]/index.tsx @@ -1,15 +1,15 @@ import {useQuery} from '@apollo/react-hooks' +import {ErrorPage} from 'components/error.page' +import {Field} from 'components/form/field' +import {FormPage} from 'components/form/page' +import {LoadingPage} from 'components/loading.page' +import {useWindowSize} from 'components/use.window.size' +import {FORM_QUERY, FormQueryData, FormQueryVariables} from 'graphql/query/form.query' import {NextPage} from 'next' import React, {useState} from 'react' import Swiper from 'react-id-swiper' import {ReactIdSwiperProps} from 'react-id-swiper/lib/types' import * as OriginalSwiper from 'swiper' -import {ErrorPage} from '../../../components/error.page' -import {Field} from '../../../components/form/field' -import {FormPage} from '../../../components/form/page' -import {LoadingPage} from '../../../components/loading.page' -import {useWindowSize} from '../../../components/use.window.size' -import {FORM_QUERY, FormQueryData, FormQueryVariables} from '../../../graphql/query/form.query' interface Props { id: string @@ -62,14 +62,14 @@ const Index: NextPage = ({id}) => { }}> {[ - , + /> : undefined, ...data.form.fields.map(field => ( = ({id}) => { prev={goPrev} /> )), - - ]} + /> : undefined + ].filter(e => !!e)} ) diff --git a/pages/form/index.tsx b/pages/form/index.tsx index ec2d948..b6d7e05 100644 --- a/pages/form/index.tsx +++ b/pages/form/index.tsx @@ -1,6 +1,6 @@ +import {ErrorPage} from 'components/error.page' import {NextPage} from 'next' import React from 'react' -import {ErrorPage} from '../../components/error.page' const Index: NextPage = () => { return ( diff --git a/pages/index.tsx b/pages/index.tsx index b24eb9a..9240497 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,7 +1,7 @@ import {Layout} from 'antd' +import {AuthFooter} from 'components/auth/footer' import {NextPage} from 'next' import React from 'react' -import {AuthFooter} from '../components/auth/footer' const Index: NextPage = () => { return ( diff --git a/pages/login/confirm/[code].tsx b/pages/login/confirm/[code].tsx index 8000ecf..2a0c48a 100644 --- a/pages/login/confirm/[code].tsx +++ b/pages/login/confirm/[code].tsx @@ -1,8 +1,8 @@ import {Alert} from 'antd' +import {AuthFooter} from 'components/auth/footer' +import {AuthLayout} from 'components/auth/layout' import {NextPage} from 'next' import React from 'react' -import {AuthFooter} from '../../../components/auth/footer' -import {AuthLayout} from '../../../components/auth/layout' const Index: NextPage = () => { return ( diff --git a/pages/login/index.tsx b/pages/login/index.tsx index 140005c..9420035 100644 --- a/pages/login/index.tsx +++ b/pages/login/index.tsx @@ -1,14 +1,14 @@ import {useMutation} from '@apollo/react-hooks' import {Button, Form, Input, message} from 'antd' import {useForm} from 'antd/lib/form/Form' +import {AuthFooter} from 'components/auth/footer' +import {AuthLayout} from 'components/auth/layout' +import {setAuth} from 'components/with.auth' +import {LOGIN_MUTATION} from 'graphql/mutation/login.mutation' import {NextPage} from 'next' import Link from 'next/link' import {useRouter} from 'next/router' import React, {useState} from 'react' -import {AuthFooter} from '../../components/auth/footer' -import {AuthLayout} from '../../components/auth/layout' -import {setAuth} from '../../components/with.auth' -import {LOGIN_MUTATION} from '../../graphql/mutation/login.mutation' const Index: NextPage = () => { const [form] = useForm() diff --git a/pages/login/recover.tsx b/pages/login/recover.tsx index b413a95..fce6677 100644 --- a/pages/login/recover.tsx +++ b/pages/login/recover.tsx @@ -1,8 +1,8 @@ import {Alert} from 'antd' +import {AuthFooter} from 'components/auth/footer' +import {AuthLayout} from 'components/auth/layout' import {NextPage} from 'next' import React from 'react' -import {AuthFooter} from '../../components/auth/footer' -import {AuthLayout} from '../../components/auth/layout' const Recover: NextPage = () => { return ( diff --git a/pages/register.tsx b/pages/register.tsx index 4cd12ae..ef43291 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -1,14 +1,14 @@ import {useMutation} from '@apollo/react-hooks' import {Button, Form, Input, message} from 'antd' import {useForm} from 'antd/lib/form/Form' +import {AuthFooter} from 'components/auth/footer' +import {AuthLayout} from 'components/auth/layout' +import {setAuth} from 'components/with.auth' +import {REGISTER_MUTATION} from 'graphql/mutation/register.mutation' import {NextPage} from 'next' import Link from 'next/link' import {useRouter} from 'next/router' import React, {useState} from 'react' -import {AuthFooter} from '../components/auth/footer' -import {AuthLayout} from '../components/auth/layout' -import {setAuth} from '../components/with.auth' -import {REGISTER_MUTATION} from '../graphql/mutation/register.mutation' const Register: NextPage = () => { const [form] = useForm()