From 584ec851f85b132cad73b17298a858d17bd96064 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Mon, 27 May 2019 20:31:12 +0300 Subject: [PATCH] Create structure for signup page --- src/models/SignupForm.ts | 3 +- src/pages/SignUpPage/SignUpPage.scss | 14 +++ src/pages/SignUpPage/SignUpPage.tsx | 128 +++++++++++++++++++++++++++ src/pages/SignUpPage/index.ts | 2 + src/routes.tsx | 2 + 5 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/pages/SignUpPage/SignUpPage.scss create mode 100644 src/pages/SignUpPage/SignUpPage.tsx create mode 100644 src/pages/SignUpPage/index.ts diff --git a/src/models/SignupForm.ts b/src/models/SignupForm.ts index f9effa9..bbc8fa2 100644 --- a/src/models/SignupForm.ts +++ b/src/models/SignupForm.ts @@ -2,13 +2,14 @@ import axios from "axios"; import { getAuthHeader } from "../auth"; import * as qs from "query-string"; const url = `${process.env.API_URL}/signupForm/`; +import { Question } from "../components/SignupQuestionsWidget"; export interface SignupForm { id: number; title: string; start_time: string; end_time: string; - questions: any[]; + questions: string; visible: boolean; } diff --git a/src/pages/SignUpPage/SignUpPage.scss b/src/pages/SignUpPage/SignUpPage.scss new file mode 100644 index 0000000..66bcb97 --- /dev/null +++ b/src/pages/SignUpPage/SignUpPage.scss @@ -0,0 +1,14 @@ +.sign-up-page { + display: flex; + + .question { + display: flex; + flex-flow: column nowrap; + + span { + input { + margin-right: 1rem; + } + } + } +} diff --git a/src/pages/SignUpPage/SignUpPage.tsx b/src/pages/SignUpPage/SignUpPage.tsx new file mode 100644 index 0000000..620ade0 --- /dev/null +++ b/src/pages/SignUpPage/SignUpPage.tsx @@ -0,0 +1,128 @@ +import * as React from "react"; +import Helmet from "react-helmet"; +import "./SignUpPage.scss"; +import { getForm, SignupForm } from "../../models/SignupForm"; +import PageSection from "../../components/PageSection"; +import { BackgroundColor as PageSectionColor } from "../../components/PageSection/PageSection"; +import { Question, optionTypes } from "../../components/SignupQuestionsWidget"; + +export interface SignUpPageProps { + match: { + params: { + id: number; + }, + }; +} + +export interface SignUpPageState { + signUpForm: SignupForm | null; +} + +class SignUpPage extends React.Component { + constructor(props) { + super(props); + const { staticContext } = props; + + if (staticContext) { + /* The static context is an object that manages promises when + rendering on the server. If staticContext exists, that means + we have to store all promises in it. Otherwise, operate + normally. See server/index.ts. */ + if (staticContext.resolutions.getSignUpForm) { + const signUpForm = staticContext.resolutions.getSignUpForm as SignupForm; + this.state = { + signUpForm, + }; + } else { + this.state = { + signUpForm: null, + }; + const promiseSignUpForm = this.fetchSignUp(); + staticContext.promises.getSignUpForm = promiseSignUpForm; + } + } else { + this.state = { + signUpForm: null, + }; + this.fetchSignUp(); + } + } + + fetchSignUp = (): Promise => { + const { match } = this.props; + const { id } = match.params; + const formPromise = getForm(id); + formPromise.then(signUpForm => { + this.setState({ + signUpForm, + }); + }); + return formPromise; + } + + renderAnswerInput = (question: Question) => { + if (!optionTypes.includes(question.type)) { + throw new Error("Unknown question type"); + } + + if (question.type === "text") { + return ; + } + if (question.type === "radiobutton") { + const options = question.options; + return options.map((opt) => ( + + + {opt} + + )); + } + } + + renderQuestion = (question: Question) => { + return ( +
+ {question.name} + {this.renderAnswerInput(question)} +
+ ); + } + + renderForm() { + const { signUpForm } = this.state; + const questions: Question[] = JSON.parse(signUpForm.questions); + const content = questions.map(this.renderQuestion); + + return ( +
+

Title: {signUpForm.title}

+
+ {content} +
+
+ ); + } + + render() { + const { match } = this.props; + const { id } = match.params; + const { signUpForm } = this.state; + + const content = signUpForm !== null + ? this.renderForm() + :
Loading...
; + + return ( +
+ + + + + {content} + +
+ ); + } +} + +export default SignUpPage; diff --git a/src/pages/SignUpPage/index.ts b/src/pages/SignUpPage/index.ts new file mode 100644 index 0000000..ebe4972 --- /dev/null +++ b/src/pages/SignUpPage/index.ts @@ -0,0 +1,2 @@ +import SignUpPage from "./SignUpPage"; +export default SignUpPage; diff --git a/src/routes.tsx b/src/routes.tsx index cbd2284..338b706 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -20,6 +20,7 @@ import FeedCreatePage from "./pages/FeedCreatePage"; import ContactsPage from "./pages/ContactsPage"; import AdminSignupPage from "./pages/AdminSignupPage"; import SignupCreatePage from "./pages/SignupCreatePage"; +import SignUpPage from "./pages/SignUpPage"; const renderPage = (Page) => (props): JSX.Element => { return ; @@ -35,6 +36,7 @@ const renderAdminPage = (Page) => (props): JSX.Element => { const commonRoutes = [ { path: "/", page: FrontPage }, + { path: "/signup/:id", page: SignUpPage }, { path: "/kilta", page: GuildPage }, { path: "/yhteystiedot", page: ContactsPage} ];