Page-View modifications on SignupPage

This commit is contained in:
Aarni Halinen
2020-07-08 16:43:47 +03:00
parent 92b927faa9
commit 45f9634946
3 changed files with 179 additions and 165 deletions
+15 -154
View File
@@ -1,21 +1,17 @@
import React from "react";
import { Helmet } from "react-helmet";
import Form from "react-jsonschema-form";
import { getForm, SignupForm } from "@models/SignupForm";
import { createSignup, Signup } from "@models/Signup";
import PageSection from "@components/PageSection";
import { Question } from "@components/SignupQuestionsWidget";
import SignUpPageView from "@views/SignUpPage/SignUpPageView";
import { RouteComponentProps } from "react-router-dom";
export interface SignUpPageProps {
match: {
params: {
id: number;
};
};
interface MatchParams {
id: string;
}
export interface SignUpPageState {
type SignUpPageProps = RouteComponentProps<MatchParams>;
interface SignUpPageState {
signUpForm?: SignupForm;
formData: any;
statusMessage?: string;
@@ -38,7 +34,7 @@ class SignUpPage extends React.Component<SignUpPageProps, SignUpPageState> {
fetchSignUp = (): Promise<SignupForm> => {
const { match } = this.props;
const { id } = match.params;
const formPromise = getForm(id);
const formPromise = getForm(Number(id));
formPromise.then(signUpForm => {
this.setState({
signUpForm,
@@ -47,110 +43,6 @@ class SignUpPage extends React.Component<SignUpPageProps, SignUpPageState> {
return formPromise;
}
questionToSchemaProp = (question: Question): {} => {
let obj: any;
if (question.type === "text") {
obj = {
type: "string",
title: question.name,
default: "",
};
}
else if (question.type === "radiobutton") {
obj = {
type: "string",
title: question.name,
enum: question.options,
};
}
else if (question.type === "checkbox") {
obj = {
type: "array",
title: question.name,
items: {
type: "string",
enum: question.options,
},
uniqueItems: true,
};
}
else if (question.type === "email") {
obj = {
type: "string",
title: question.name,
format: "email",
default: ""
}
}
else {
throw new Error(`No mapping to schema prop for question type ${question.type}`);
}
return {
[question.id]: obj,
}
}
questionToUISchemaProp = (question: Question): {} => {
let obj = {};
if (question.type == "checkbox") {
obj = {
"ui:widget": "checkboxes",
};
}
else if (question.type == "radiobutton") {
obj = {
"ui:widget": "radio",
}
}
// else {
// throw new Error(`No mapping to UI schema prop for question type ${question.type}`);
// }
return {
[question.id]: obj,
};
}
buildSchema = () => {
const { error, formData, signUpForm } = this.state;
const {questions} = signUpForm;
const schemaPropsArray = questions.map(this.questionToSchemaProp);
let schemaProps = {};
schemaPropsArray.forEach((schemaProp) => {
schemaProps = {
...schemaProps,
...schemaProp,
};
});
const schema = {
title: signUpForm.id ? signUpForm.title : "Loading...",
type: "object",
required: [],
properties: schemaProps,
};
return schema;
}
buildUISchema = () => {
const { error, formData, signUpForm } = this.state;
const {questions} = signUpForm;
const uiSchemaPropsArray = questions.map(this.questionToUISchemaProp);
let uiSchemaProps = {};
uiSchemaPropsArray.forEach((uiSchemaProp) => {
uiSchemaProps = {
...uiSchemaProps,
...uiSchemaProp,
};
});
const uiSchema = {
...uiSchemaProps,
};
return uiSchema;
}
onSubmit = async (data) => {
const { signUpForm } = this.state;
try {
@@ -187,54 +79,23 @@ class SignUpPage extends React.Component<SignUpPageProps, SignUpPageState> {
console.log(data);
}
renderForm() {
const { signUpForm, formData } = this.state;
const schema = this.buildSchema();
const uiSchema = this.buildUISchema();
return (
<div>
<h1>Title: {signUpForm.title}</h1>
<Form
schema={schema as any}
uiSchema={uiSchema}
formData={formData}
idPrefix="rjsf"
onChange={this.onChange}
onSubmit={this.onSubmit}
/>
</div>
);
}
renderList() {
const { signUpForm } = this.state;
return (
<ol>
{signUpForm.signups.map((s, idx) => (
<li key={idx}>{s}</li>
))}
</ol>
)
}
render() {
const { match } = this.props;
const { id } = match.params;
const { signUpForm, statusMessage } = this.state;
const form = signUpForm !== null
? this.renderForm()
: <div>Loading...</div>;
const signups = signUpForm && signUpForm.signups ? this.renderList() : null;
const { signUpForm, formData, statusMessage } = this.state;
return (
<>
<Helmet>
<link rel="canonical" href={`https://sik.ayy.fi/signup/${id}`} />
</Helmet>
<SignUpPageView form={form} signups={signups} statusMessage={statusMessage} />
<SignUpPageView
signUpForm={signUpForm}
formData={formData}
statusMessage={statusMessage}
onChange={this.onChange}
onSubmit={this.onSubmit}
/>
</>
);
}
+105
View File
@@ -0,0 +1,105 @@
import { Question } from "@components/SignupQuestionsWidget";
import { SignupForm } from "@models/SignupForm";
const questionToSchemaProp = (question: Question): {} => {
let obj: any;
if (question.type === "text") {
obj = {
type: "string",
title: question.name,
default: "",
};
}
else if (question.type === "radiobutton") {
obj = {
type: "string",
title: question.name,
enum: question.options,
};
}
else if (question.type === "checkbox") {
obj = {
type: "array",
title: question.name,
items: {
type: "string",
enum: question.options,
},
uniqueItems: true,
};
}
else if (question.type === "email") {
obj = {
type: "string",
title: question.name,
format: "email",
default: ""
}
}
else {
throw new Error(`No mapping to schema prop for question type ${question.type}`);
}
return {
[question.id]: obj,
}
}
const questionToUISchemaProp = (question: Question): {} => {
let obj = {};
if (question.type == "checkbox") {
obj = {
"ui:widget": "checkboxes",
};
}
else if (question.type == "radiobutton") {
obj = {
"ui:widget": "radio",
}
}
// else {
// throw new Error(`No mapping to UI schema prop for question type ${question.type}`);
// }
return {
[question.id]: obj,
};
}
export const buildSchema = (signUpForm: SignupForm) => {
const {questions} = signUpForm;
const schemaPropsArray = questions.map(questionToSchemaProp);
let schemaProps = {};
schemaPropsArray.forEach((schemaProp) => {
schemaProps = {
...schemaProps,
...schemaProp,
};
});
const schema = {
title: signUpForm.id ? signUpForm.title : "Loading...",
type: "object",
required: [],
properties: schemaProps,
};
return schema;
}
export const buildUISchema = (signUpForm: SignupForm) => {
const {questions} = signUpForm;
const uiSchemaPropsArray = questions.map(questionToUISchemaProp);
let uiSchemaProps = {};
uiSchemaPropsArray.forEach((uiSchemaProp) => {
uiSchemaProps = {
...uiSchemaProps,
...uiSchemaProp,
};
});
const uiSchema = {
...uiSchemaProps,
};
return uiSchema;
}
+59 -11
View File
@@ -1,21 +1,69 @@
import React from "react";
import Form, { IChangeEvent, ISubmitEvent, ErrorSchema } from "react-jsonschema-form";
import "./SignUpPage.scss";
import PageSection from "@components/PageSection";
import { SignupForm } from "@models/SignupForm";
import { buildSchema, buildUISchema } from "./FormUtils";
interface SignUpPageViewProps {
form: React.ReactNode;
signups: React.ReactNode;
signUpForm: SignupForm;
formData: any;
statusMessage: string;
onChange: (e: IChangeEvent<any>, es?: ErrorSchema) => any;
onSubmit: (e: ISubmitEvent<any>) => any;
}
const SignUpPageView: React.FC<SignUpPageViewProps> = ({form, signups, statusMessage}) => (
<div className="sign-up-page">
{statusMessage}
<PageSection backgroundColor="dark-blue">
{form}
{signups}
</PageSection>
</div>
);
const renderList = (signUpForm: SignupForm) => {
return (
<ol>
{signUpForm.signups.map((s, idx) => (
<li key={idx}>{s}</li>
))}
</ol>
)
}
const SignUpPageView: React.FC<SignUpPageViewProps> = ({
signUpForm,
formData,
statusMessage,
onChange,
onSubmit
}) => {
const renderForm = () => {
const schema = buildSchema(signUpForm);
const uiSchema = buildUISchema(signUpForm);
return (
<div>
<h1>Title: {signUpForm.title}</h1>
<Form
schema={schema as any}
uiSchema={uiSchema}
formData={formData}
idPrefix="rjsf"
onChange={onChange}
onSubmit={onSubmit}
/>
</div>
);
}
const form = signUpForm !== null
? renderForm()
: <div>Loading...</div>;
const signups = signUpForm && signUpForm.signups ? renderList(signUpForm) : null;
return (
<div className="sign-up-page">
{statusMessage}
<PageSection backgroundColor="dark-blue">
{form}
{signups}
</PageSection>
</div>
)
}
export default SignUpPageView;