Added styles for form creation page and all components in it. Some minor improvements in another pages

This commit is contained in:
Dmitriy Shishkov 2020-11-07 06:07:27 +05:00
parent 85d7e48e0d
commit 6ef34c6ab8
No known key found for this signature in database
GPG Key ID: D76D70029F55183E
15 changed files with 331 additions and 77 deletions

View File

@ -14,7 +14,7 @@ const Lists: React.FC<IListsProps> = ({ variants, name, type, onChange }) => {
(type === 'CHECK' && 'check') || (type === 'CHOOSE' && 'radio') || undefined (type === 'CHECK' && 'check') || (type === 'CHOOSE' && 'radio') || undefined
return ( return (
<div> <div className={styles.variantsList}>
{variants.map((el, index) => ( {variants.map((el, index) => (
<label key={index}> <label key={index}>
<input <input

View File

@ -1,3 +1,14 @@
.selector { .selector {
margin-right: 0.5rem; margin-right: 0.5rem;
} }
.variantsList {
display: flex;
gap: 0.5rem;
}
@media (orientation: portrait) {
.variantsList {
flex-direction: column;
}
}

View File

@ -28,9 +28,6 @@
} }
.select { .select {
/* -webkit-appearance: none; */
/* -moz-appearance: none; */
/* appearance: none; */
padding: 0.5rem; padding: 0.5rem;
background: var(--accentColor); background: var(--accentColor);
border-radius: 20px; border-radius: 20px;

View File

@ -21,7 +21,7 @@ const SubmissionList: React.FC<ISubmissionListProps> = ({
questions, questions,
}) => { }) => {
return submissions.length > 0 ? ( return submissions.length > 0 ? (
<ul> <ul className={styles.container}>
{submissions.map((submission, submissionIndex) => ( {submissions.map((submission, submissionIndex) => (
<li className={styles.listItem} key={submissionIndex}> <li className={styles.listItem} key={submissionIndex}>
<h2 className={styles.itemHeader}> <h2 className={styles.itemHeader}>

View File

@ -1,3 +1,9 @@
.container {
display: flex;
flex-direction: column;
gap: 2.3rem;
}
.listItem { .listItem {
list-style-type: none; list-style-type: none;
border: 0.1rem var(--containerColor) solid; border: 0.1rem var(--containerColor) solid;

View File

@ -14,6 +14,7 @@ import {
HandleQuestionTitleChangeFT, HandleQuestionTitleChangeFT,
HandleAnswerVariantChangeFT, HandleAnswerVariantChangeFT,
AddVariantFT, AddVariantFT,
RemoveQuestionFT,
} from './types' } from './types'
const initialState = { title: '', questions: [] } const initialState = { title: '', questions: [] }
@ -52,6 +53,13 @@ export const useFormCreator = <T extends string>(
})) }))
} }
const removeQuestion: RemoveQuestionFT = (number) => {
setState(({ title, questions }) => ({
title,
questions: questions.filter((_, index) => index !== number),
}))
}
const handleQuestionTitleChange: HandleQuestionTitleChangeFT = ( const handleQuestionTitleChange: HandleQuestionTitleChangeFT = (
questionNumber, questionNumber,
e e
@ -107,6 +115,7 @@ export const useFormCreator = <T extends string>(
{ {
handleFormTitleChange, handleFormTitleChange,
addQuestion: createQuestion, addQuestion: createQuestion,
removeQuestion,
handleQuestionTitleChange, handleQuestionTitleChange,
handleAnswerVariantChange, handleAnswerVariantChange,
addVariant, addVariant,

View File

@ -3,6 +3,7 @@ import React from 'react'
import { QuestionTypes } from './types' import { QuestionTypes } from './types'
import { useFormCreator } from './hooks' import { useFormCreator } from './hooks'
import { creationsArray, formatQuestionsToSubmit } from './utils' import { creationsArray, formatQuestionsToSubmit } from './utils'
import styles from './main.module.css'
const CreateForm: React.FC = () => { const CreateForm: React.FC = () => {
const [ const [
@ -10,6 +11,7 @@ const CreateForm: React.FC = () => {
[formSubmit, { submitData, submitError, submitLoading }], [formSubmit, { submitData, submitError, submitLoading }],
{ {
addQuestion, addQuestion,
removeQuestion,
handleFormTitleChange, handleFormTitleChange,
handleQuestionTitleChange, handleQuestionTitleChange,
handleAnswerVariantChange, handleAnswerVariantChange,
@ -19,94 +21,133 @@ const CreateForm: React.FC = () => {
] = useFormCreator<QuestionTypes>(formatQuestionsToSubmit) ] = useFormCreator<QuestionTypes>(formatQuestionsToSubmit)
return ( return (
<> <div className={styles.container}>
<form <form
onSubmit={(e) => { onSubmit={(e) => {
formSubmit(e) formSubmit(e)
resetForm() resetForm()
}} }}
> >
<label> <div className={styles.pageHeader}>
Title: <h1 className={styles.pageTitle}>Create form</h1>
<input <input
className={styles.textInput}
type="text" type="text"
name="Title" name="Title"
placeholder="title"
value={form.title} value={form.title}
onChange={handleFormTitleChange} onChange={handleFormTitleChange}
required required
/> />
</label> </div>
<fieldset> <div className={styles.mainFormContainer}>
<legend>Content</legend> <fieldset className={styles.mainForm}>
<ul> <div className={styles.mainFormTop} />
{creationsArray.flatMap((questionType, index) => <legend className={styles.fieldsetTitle}>Content</legend>
questionType.enabled <ul>
? [ {form.questions.map((quesstion, questionIndex) => (
<li key={index}> <li className={styles.questionToCreateLI} key={questionIndex}>
<div className={styles.questionHeader}>
<h3 className={styles.questionTitle}>
{quesstion.type} question:
</h3>
<input
className={[styles.textInput, styles.fullWidth].join(' ')}
required
type="text"
name="questionTitle"
placeholder="Title"
value={quesstion.title}
onChange={(e) =>
handleQuestionTitleChange(questionIndex, e)
}
/>
<button
className={styles.button}
onClick={(e) => {
e.preventDefault()
removeQuestion(questionIndex)
}}
>
x
</button>
</div>
{(quesstion.type === 'CHECK' ||
quesstion.type === 'CHOOSE' ||
quesstion.type === 'SELECT') && (
<>
<h4 className={styles.variantsHeader}>Variants</h4>
<ul>
{quesstion.variants.map((variant, variantIndex) => (
<li key={variantIndex}>
<input
className={[
styles.textInput,
styles.fullWidth,
styles.variantText,
].join(' ')}
required
placeholder="Variant"
type="text"
value={variant}
onChange={(e) =>
handleAnswerVariantChange(
questionIndex,
variantIndex,
e
)
}
/>
</li>
))}
</ul>
<button <button
type="button" type="button"
onClick={() => addQuestion(questionType.type)} onClick={() => addVariant(questionIndex)}
className={[styles.button, styles.addVariant].join(' ')}
> >
{questionType.title} +
</button> </button>
</li>, </>
] )}
: [] </li>
)} ))}
</ul> </ul>
<ul> <ul>
{form.questions.map((quesstion, questionIndex) => ( {creationsArray.flatMap((questionType, index) =>
<li key={questionIndex}> questionType.enabled
<p>{quesstion.type} question:</p> ? [
<input <li className={styles.questionCreatorLI} key={index}>
required <button
type="text" className={styles.button}
name="questionTitle" type="button"
placeholder="Title" onClick={() => addQuestion(questionType.type)}
value={quesstion.title} >
onChange={(e) => handleQuestionTitleChange(questionIndex, e)} + {questionType.title}
/> </button>
{(quesstion.type === 'CHECK' || </li>,
quesstion.type === 'CHOOSE' || ]
quesstion.type === 'SELECT') && ( : []
<> )}
<ul> </ul>
{quesstion.variants.map((variant, variantIndex) => ( </fieldset>
<li key={variantIndex}> </div>
<input <div className={styles.submitContainer}>
required {submitLoading ? (
placeholder="Variant" 'Loading...'
type="text" ) : (
value={variant} <input
onChange={(e) => className={[styles.button, styles.submitButton].join(' ')}
handleAnswerVariantChange( type="submit"
questionIndex, value="Submit"
variantIndex, />
e )}
) </div>
}
/>
</li>
))}
</ul>
<button
type="button"
onClick={() => addVariant(questionIndex)}
>
+
</button>
</>
)}
</li>
))}
</ul>
</fieldset>
{submitLoading ? 'Loading...' : <input type="submit" value="Submit" />}
</form> </form>
{submitData?.createForm.success && 'Successfully uploaded'} {submitData?.createForm.success && 'Successfully uploaded'}
{submitError && submitError.message} {submitError && submitError.message}
</> </div>
) )
} }

View File

@ -0,0 +1,150 @@
.container {
height: calc(100vh - 4rem);
}
.container form {
height: 100%;
display: flex;
flex-direction: column;
}
.pageHeader {
display: flex;
gap: 1rem;
padding: 2.3rem;
}
.pageTitle {
margin-top: -0.3rem;
}
.textInput {
height: 2.3rem;
border-radius: 100vh;
border: none;
display: inline;
outline: none;
font-size: 1.2rem;
padding: 0 0.7rem;
border-bottom: 0.15rem var(--containerColor) solid;
transition: border 0.1s;
}
.textInput:focus {
border-bottom-width: 0rem;
border-top: 0.15rem var(--containerColor) solid;
}
.mainFormContainer {
margin-top: 2.3rem;
padding: 2.3rem;
padding-top: 0;
flex-grow: 1;
position: relative;
background: #ffffff;
}
.mainFormTop {
top: -2.3rem;
left: 0rem;
position: absolute;
height: 2.3rem;
width: 100%;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
background: #ffffff;
}
.mainForm {
border: none;
}
.fieldsetTitle {
font-size: 1.4rem;
font-weight: bold;
padding-bottom: 2rem;
}
.questionCreatorLI {
list-style: none;
display: inline;
padding-right: 0.5rem;
}
.button {
height: 2.3rem;
border-radius: 100vh;
border: none;
outline: none;
font-size: 1.2rem;
padding: 0 0.7rem;
cursor: pointer;
background-color: var(--accentColor);
color: var(--onAccentFontColor);
box-shadow: 0 1px 6px 0 var(--accentShadowColor);
}
.button:active {
box-shadow: none;
}
.questionToCreateLI {
margin-bottom: 2.3rem;
list-style: none;
border: 0.1rem var(--containerColor) solid;
border-radius: 20px;
padding: 2.3rem;
}
.questionHeader {
display: grid;
grid-template-columns: auto 1fr 2.3rem;
gap: 0.5rem;
}
.questionTitle {
line-height: 2.3rem;
}
.fullWidth {
width: 100%;
}
.variantsHeader {
margin: 1rem 0;
}
.variantText {
margin: 0.5rem;
}
.addVariant {
width: 2.3rem;
margin: auto;
display: block;
line-height: 2.3rem;
}
.submitContainer {
padding: 2.3rem;
background-color: #ffffff;
}
.submitButton {
width: 100%;
}
@media (orientation: portrait) {
.pageHeader {
flex-direction: column;
gap: 0.5rem;
}
.pageTitle {
margin-top: 0;
}
.questionHeader {
grid-template-columns: 1fr;
}
}

View File

@ -28,6 +28,8 @@ export type HandleFormTitleChangeFT = (e: ChangeEvent<HTMLInputElement>) => void
export type CreateQuestionFT<T extends string> = (type: T) => void export type CreateQuestionFT<T extends string> = (type: T) => void
export type RemoveQuestionFT = (number: number) => void
export type HandleQuestionTitleChangeFT = ( export type HandleQuestionTitleChangeFT = (
questionNumber: number, questionNumber: number,
e: ChangeEvent<HTMLInputElement> e: ChangeEvent<HTMLInputElement>
@ -54,6 +56,7 @@ export type UseFormCreatorHookTurpleT<T extends string> = [
{ {
handleFormTitleChange: HandleFormTitleChangeFT handleFormTitleChange: HandleFormTitleChangeFT
addQuestion: CreateQuestionFT<T> addQuestion: CreateQuestionFT<T>
removeQuestion: RemoveQuestionFT
handleQuestionTitleChange: HandleQuestionTitleChangeFT handleQuestionTitleChange: HandleQuestionTitleChangeFT
handleAnswerVariantChange: HandleAnswerVariantChangeFT handleAnswerVariantChange: HandleAnswerVariantChangeFT
addVariant: AddVariantFT addVariant: AddVariantFT

View File

@ -41,7 +41,7 @@ const DoForm: React.FC = () => {
</p> </p>
</header> </header>
<main className={styles.main}> <main className={styles.main}>
<div className={styles.mainTop}></div> <div className={styles.mainTop} />
{form.submissions ? ( {form.submissions ? (
<> <>
<h1 className={styles.mainHeader}>Submissions</h1> <h1 className={styles.mainHeader}>Submissions</h1>

View File

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import { useQuery } from '@apollo/client' import { useQuery } from '@apollo/client'
import { generateFromString } from 'generate-avatar' import { generateFromString } from 'generate-avatar'
import { Redirect, useHistory } from 'react-router-dom' import { Redirect, useHistory, Link } from 'react-router-dom'
import Card from '../../components/Card' import Card from '../../components/Card'
import { USER } from '../../apollo' import { USER } from '../../apollo'
@ -55,6 +55,9 @@ const Home: React.FC = () => {
<Card title={form.title} id={form.id} /> <Card title={form.title} id={form.id} />
</li> </li>
))} ))}
<Link className={styles.createNew} to="/create">
<span>Create new</span> <h3>+</h3>
</Link>
</ul> </ul>
</div> </div>

View File

@ -30,6 +30,31 @@
overflow-y: auto; overflow-y: auto;
} }
.createNew:hover {
border-color: var(--containerColor);
color: var(--containerColor);
}
.createNew {
padding: 1rem;
border-radius: 0.5rem;
border: 0.1rem var(--accentColor) solid;
text-decoration: none;
color: var(--accentColor);
display: flex;
gap: 0.5rem;
justify-content: center;
}
.createNew span {
font-weight: bold;
line-height: 1.17em;
}
.createNew h3 {
line-height: 1.17em;
}
.rightPad { .rightPad {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -5,6 +5,7 @@ import { LOGIN } from '../../apollo'
import { MutationLoginArgs, ServerAnswer } from '../../apollo/typeDefs.gen' import { MutationLoginArgs, ServerAnswer } from '../../apollo/typeDefs.gen'
import styles from './main.module.css' import styles from './main.module.css'
import meme from './meme.png' import meme from './meme.png'
import { Link } from 'react-router-dom'
interface ILoginMutation { interface ILoginMutation {
login: ServerAnswer login: ServerAnswer
@ -47,7 +48,9 @@ const Login: React.FC = () => {
</div> </div>
) : ( ) : (
<> <>
<h1 className={styles.header}>Login</h1> <h1 className={styles.header}>
Log In / <Link to="/register">Register</Link>
</h1>
<input <input
required required
className={styles.input} className={styles.input}

View File

@ -48,6 +48,10 @@
text-align: center; text-align: center;
} }
.header a {
color: var(--accentColor);
}
.input { .input {
border-bottom: 0.15rem var(--containerColor) solid !important; border-bottom: 0.15rem var(--containerColor) solid !important;
transition: border 0.1s; transition: border 0.1s;

View File

@ -1,6 +1,6 @@
import { useMutation } from '@apollo/client' import { useMutation } from '@apollo/client'
import React, { FormEvent } from 'react' import React, { FormEvent } from 'react'
import { Redirect } from 'react-router-dom' import { Redirect, Link } from 'react-router-dom'
import { REGISTER } from '../../apollo' import { REGISTER } from '../../apollo'
import { MutationRegisterArgs, ServerAnswer } from '../../apollo/typeDefs.gen' import { MutationRegisterArgs, ServerAnswer } from '../../apollo/typeDefs.gen'
@ -40,7 +40,9 @@ const Register: React.FC = () => {
alt='Questionform says: "Is mailbox a password?"' alt='Questionform says: "Is mailbox a password?"'
/> />
<form className={styles.form} onSubmit={handleSubmit}> <form className={styles.form} onSubmit={handleSubmit}>
<h1 className={styles.header}>Register</h1> <h1 className={styles.header}>
Register / <Link to="/login">Log In</Link>
</h1>
<input <input
required required
className={styles.input} className={styles.input}