Files
web2.0-frontend/src/pages/admin/JobAdCreatePage.tsx
T
2020-11-24 18:03:16 +02:00

184 lines
4.6 KiB
TypeScript

import React, { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import Form from "react-jsonschema-form";
import { RouteComponentProps } from "react-router-dom";
import { JobAd, getJobAd, createJobAd, updateJobAd } from "@models/JobAd";
import DatetimeWidget from "@components/Widgets/DatetimeWidget/DatetimeWidget";
import SectionDividerWidget from "@components/Widgets/SectionDividerWidget/SectionDividerWidget";
import MarkdownEditorWidget from "@components/Widgets/MarkdownEditorWidget";
const widgets = {
datetime: DatetimeWidget,
section_divider: SectionDividerWidget,
markdownEditor: MarkdownEditorWidget
};
const buildSchema = (title: string) => {
const date = new Date();
const monthFromNow = new Date();
monthFromNow.setDate(date.getDate() + 30);
const schema = {
title,
type: "object",
required: ["title_fi", "title_en", "description_fi", "description_en", "content_fi", "content_en", "autohide_at", "autohide_enabled", "visible"],
properties: {
visible: {
type: "boolean",
title: "Visible",
default: true,
},
autohide_enabled: {
type: "boolean",
title: "Autohide enabled",
default: false,
},
autohide_at: {
type: "string",
title: "Autohide time",
default: monthFromNow.toISOString(),
},
finnish_section_divider: {
title: "Finnish",
type: "string",
},
title_fi: {
type: "string",
title: "Title",
default: ""
},
description_fi: {
type: "string",
title: "Description",
default: "",
},
content_fi: {
type: "string",
title: "Content",
default: "",
},
english_section_divider: {
title: "English",
type: "string",
},
title_en: {
type: "string",
title: "Title",
default: ""
},
description_en: {
type: "string",
title: "Description",
default: "",
},
content_en: {
type: "string",
title: "Content",
default: "",
},
}
};
return schema;
}
const buildUISchema = (formData: JobAd) => ({
content_fi: {
"ui:widget": "markdownEditor",
},
content_en: {
"ui:widget": "markdownEditor",
},
autohide_at: {
"ui:widget": formData && formData.autohide_enabled ? "datetime" : "hidden",
},
finnish_section_divider: {
"ui:widget": "section_divider",
"ui:options": {
label: false
},
},
english_section_divider: {
"ui:widget": "section_divider",
"ui:options": {
label: false
},
},
});
interface MatchParams {
id?: string;
}
type JobAdCreatePageProps = RouteComponentProps<MatchParams>;
const JobAdCreatePage: React.FC<JobAdCreatePageProps> = ({ match: { params: { id } } }) => {
const [formData, setFormData] = useState<JobAd>(null);
useEffect(() => {
const jobId = id && Number(id);
if (jobId !== undefined) {
getJobAd(jobId, true)
.then(res => setFormData(res))
}
}, [id])
const [error, setError] = useState<string>(null);
const [statusMessage, setStatusMessage] = useState<string>(null);
const onSubmit = async (data) => {
try {
const payload = data.formData;
if (payload.id === undefined) {
const resp = await createJobAd(payload);
setStatusMessage("Post created successfully");
setFormData(resp);
} else {
const resp = await updateJobAd(payload);
setStatusMessage("Post updated successfully");
setFormData(resp);
}
} catch (err) {
setError(err);
}
}
const onError = (data) => {
console.error("error, data:");
console.log(data);
}
const onChange = (data) => setFormData(data.formData);
const onFocus = () => setStatusMessage(null);
const title = formData?.id
? `Edit Ad "${formData.title_fi}"`
: "Create Ad";
return (
<div className="post-create-page">
<Helmet>
<link rel="canonical" href="https://sik.ayy.fi/admin/jobads/create" />
</Helmet>
<h1>{title}</h1>
{statusMessage && <div className="success">{statusMessage}</div>}
<Form
schema={buildSchema(formData?.id ? formData.title_fi : "New Post") as any}
uiSchema={buildUISchema(formData)}
formData={formData}
idPrefix="rjsf"
widgets={widgets as any}
onChange={onChange}
onSubmit={onSubmit}
onError={onError}
onFocus={onFocus} />
{error && <div className="error">{error}</div>}
</div>
);
}
export default JobAdCreatePage;