129 lines
3.2 KiB
TypeScript
129 lines
3.2 KiB
TypeScript
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 { ColorEnum } from "../../index";
|
|
import { Question, optionTypes } from "../../components/SignupQuestionsWidget";
|
|
|
|
export interface SignUpPageProps {
|
|
match: {
|
|
params: {
|
|
id: number;
|
|
},
|
|
};
|
|
}
|
|
|
|
export interface SignUpPageState {
|
|
signUpForm: SignupForm | null;
|
|
}
|
|
|
|
class SignUpPage extends React.Component<SignUpPageProps, SignUpPageState> {
|
|
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<SignupForm> => {
|
|
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 <input type="text" name={question.id} />;
|
|
}
|
|
if (question.type === "radiobutton") {
|
|
const options = question.options;
|
|
return options.map((opt) => (
|
|
<span>
|
|
<input type="radio" name={`${question.id}`} />
|
|
{opt}
|
|
</span>
|
|
));
|
|
}
|
|
}
|
|
|
|
renderQuestion = (question: Question) => {
|
|
return (
|
|
<div className="question">
|
|
{question.name}
|
|
{this.renderAnswerInput(question)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
renderForm() {
|
|
const { signUpForm } = this.state;
|
|
const questions: Question[] = JSON.parse(signUpForm.questions);
|
|
const content = questions.map(this.renderQuestion);
|
|
|
|
return (
|
|
<div>
|
|
<h1>Title: {signUpForm.title}</h1>
|
|
<div>
|
|
{content}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
render() {
|
|
const { match } = this.props;
|
|
const { id } = match.params;
|
|
const { signUpForm } = this.state;
|
|
|
|
const content = signUpForm !== null
|
|
? this.renderForm()
|
|
: <div>Loading...</div>;
|
|
|
|
return (
|
|
<div className="sign-up-page">
|
|
<Helmet>
|
|
<link rel="canonical" href={`https://sik.ayy.fi/signup/${id}`} />
|
|
</Helmet>
|
|
<PageSection backgroundColor={ColorEnum.DarkBlue}>
|
|
{content}
|
|
</PageSection>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default SignUpPage;
|