Simple email & list views for Signups

This commit is contained in:
Aarni Halinen
2020-11-08 00:15:00 +02:00
parent a54e2db64e
commit acaea6934b
5 changed files with 210 additions and 1 deletions
+29
View File
@@ -2,6 +2,7 @@ import axios from "axios";
import { getAuthHeader } from "@utils/auth";
const url = `${process.env.API_URL}/signupForm/`;
import { Question } from "@components/Widgets/SignupQuestionsWidget";
import { Signup } from "./Signup";
export interface SignupForm {
id?: number;
@@ -77,3 +78,31 @@ export async function updateForm(data): Promise<SignupForm> {
throw err;
}
}
export const signupFormSendEmail = async (data, id): Promise<any> => {
try {
const resp = await axios.post(`${process.env.API_URL}/signupForm/${id}/sendemail/`, data, {
headers: {
"Authorization": getAuthHeader(),
},
});
return resp.data;
} catch (err) {
console.error(err);
throw err;
}
}
export const getSignups = async (id): Promise<Signup[]> => {
try {
const resp = await axios.get(`${process.env.API_URL}/signupForm/${id}/signups/`, {
headers: {
"Authorization": getAuthHeader(),
},
});
return resp.data;
} catch (err) {
console.error(err);
throw err;
}
}
+4
View File
@@ -85,6 +85,8 @@ class AdminSignupPage extends React.Component<AdminSignupPageProps, AdminSignupP
<th>Title</th>
<th>Start time</th>
<th>End time</th>
<th>Sign-ups</th>
<th>Send email</th>
</tr>
</thead>
<tbody>
@@ -93,6 +95,8 @@ class AdminSignupPage extends React.Component<AdminSignupPageProps, AdminSignupP
<td><Anchor to={`/admin/signups/${signupForm.id}`}>{signupForm.title_fi}</Anchor></td>
<td>{formatRelative(new Date(signupForm.start_time), new Date())}</td>
<td>{formatRelative(new Date(signupForm.end_time), new Date())}</td>
<td><Anchor to={`/admin/signups/${signupForm.id}/list`}>View</Anchor></td>
<td><Anchor to={`/admin/signups/${signupForm.id}/email`}>Send</Anchor></td>
</tr>
))}
</tbody>
+110
View File
@@ -0,0 +1,110 @@
import React, { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import Form from "react-jsonschema-form";
import { RouteComponentProps } from "react-router-dom";
import MarkdownEditorWidget from "@components/Widgets/MarkdownEditorWidget";
import { SignupForm, getForm, signupFormSendEmail } from "@models/SignupForm";
const widgets = {
markdownEditor: MarkdownEditorWidget
};
const buildSchema = (title: string) => {
return {
title,
type: "object",
required: ["subject", "content", "mode"],
properties: {
subject: {
type: "string",
title: "Title",
default: ""
},
content: {
type: "string",
title: "Content",
default: "",
},
mode: {
type: "string",
title: "Send to",
enum : [
"all",
"actual",
"reserved"
],
default: "all",
}
}
};
}
const buildUISchema = () => ({
content: {
"ui:widget": "markdownEditor",
},
});
interface MatchParams {
id?: string;
}
type SignupEmailPageProps = RouteComponentProps<MatchParams>;
const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id } } }) => {
const [signupForm, setSignupForm] = useState<SignupForm>(null);
useEffect(() => {
const formId = Number(id);
if (formId !== undefined) {
getForm(formId, true)
.then(res => setSignupForm(res))
}
}, [id])
const [error, setError] = useState<string>(null);
const [statusMessage, setStatusMessage] = useState<string>(null);
const onSubmit = async (data) => {
try {
const payload = data.formData;
await signupFormSendEmail(payload, id);
setStatusMessage("Email sent successfully");
} 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 = signupForm ? signupForm.title_fi : "Loading..."
return (
<div>
<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(title) as any}
uiSchema={buildUISchema()}
// 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 SignupEmailPage;
+62
View File
@@ -0,0 +1,62 @@
import React, { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import { RouteComponentProps } from "react-router-dom";
import { SignupForm, getForm, getSignups } from "@models/SignupForm";
import { Signup } from "@models/Signup";
interface MatchParams {
id?: string;
}
type SignupEmailPageProps = RouteComponentProps<MatchParams>;
const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id } } }) => {
const [signupForm, setSignupForm] = useState<SignupForm>(null);
const [signups, setSignups] = useState<Signup[]>([]);
useEffect(() => {
const formId = Number(id);
getForm(formId, true)
.then(res => setSignupForm(res))
getSignups(formId).then(res => setSignups(res))
}, [id]);
const questions = signupForm ? signupForm.questions.map(q => ({
title: q.name,
id: q.id
})) : [];
const title = signupForm ? signupForm.title_fi : "Loading..."
return (
<div>
<Helmet>
<link rel="canonical" href="https://sik.ayy.fi/admin/jobads/create" />
</Helmet>
<h1>{title}: Sign-ups</h1>
<table>
<thead>
<tr>
{questions.map(q => (
<th key={q.id}>{q.title}</th>
))}
</tr>
</thead>
<tbody>
{signups.map(s => (
<tr key={s.id}>
{questions.map(q => (
<td key={`${s.id} - ${q.id}`}>
{s.answer[q.id]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)};
export default SignupEmailPage;
+5 -1
View File
@@ -1,5 +1,5 @@
import React from "react";
import { Switch, Route, Redirect } from "react-router-dom";
import { Switch, Route } from "react-router-dom";
import { Helmet } from "react-helmet";
import FrontPage from "./pages/FrontPage";
import GuildPage from "./pages/GuildPage";
@@ -18,6 +18,8 @@ import EventCreatePage from "./pages/admin/EventCreatePage";
import FeedCreatePage from "./pages/admin/FeedCreatePage";
import ContactsPage from "./pages/ContactsPage";
import SignupCreatePage from "./pages/admin/SignupCreatePage";
import SignupEmailPage from "./pages/admin/SignupEmailPage";
import SignupListPage from "./pages/admin/SignupListPage";
import SignUpPage from "./pages/SignUpPage";
import ActualPage from "./pages/ActualPage";
import FreshmenPage from "./pages/FreshmenPage";
@@ -70,6 +72,8 @@ const adminRoutes = [
{ path: "/admin/signups", page: AdminSignupPage },
{ path: "/admin/signups/create", page: SignupCreatePage },
{ path: "/admin/signups/:id", page: SignupCreatePage },
{ path: "/admin/signups/:id/list", page: SignupListPage },
{ path: "/admin/signups/:id/email", page: SignupEmailPage },
{ path: "/admin/jobads", page: AdminJobAdPage },
{ path: "/admin/jobads/create", page: JobAdCreatePage },
{ path: "/admin/jobads/:id", page: JobAdCreatePage },