Compare commits
8 commits
main
...
feature/#3
Author | SHA1 | Date | |
---|---|---|---|
Philipp Lohner | 48d976d263 | ||
ce343c8c21 | |||
Philipp Lohner | 4bac42f2c7 | ||
Philipp Lohner | 4ac4738a06 | ||
Philipp Lohner | e71faf536d | ||
Philipp Lohner | ee23820cce | ||
Philipp Lohner | 56691a3135 | ||
Philipp Lohner | e5f0cf24f5 |
|
@ -49,3 +49,19 @@ create policy select_answer
|
||||||
for select
|
for select
|
||||||
to candymat_anonymous, candymat_person -- maybe change to candymat_person only in the future
|
to candymat_anonymous, candymat_person -- maybe change to candymat_person only in the future
|
||||||
using (true);
|
using (true);
|
||||||
|
|
||||||
|
drop table if exists candymat_data.user_app_info;
|
||||||
|
create table candymat_data.user_app_info
|
||||||
|
(
|
||||||
|
row_id character varying(50) primary key,
|
||||||
|
title character varying(300) NOT NULL,
|
||||||
|
content character varying(15000)
|
||||||
|
);
|
||||||
|
grant select on table candymat_data.user_app_info to candymat_anonymous, candymat_person;
|
||||||
|
grant insert, update, delete on table candymat_data.user_app_info to candymat_editor;
|
||||||
|
delete from candymat_data.user_app_info where row_id = 'about_page';
|
||||||
|
delete from candymat_data.user_app_info where row_id = 'legal_page';
|
||||||
|
insert into candymat_data.user_app_info (row_id, title, content) values
|
||||||
|
('about_page', 'About Candymat', '<h1>Wer steckt eigentlich hinter dem Kandimat?</h1><p>Der Kandimat wurde von den ehrenamtlichen Mitgliedern des Netzbegrünung e.V. entwickelt. Eure Geschäftsstelle und die Kandidat*innen haben die redaktionelle Arbeit für die Inhalte des Kandimats geleistet.</p>');
|
||||||
|
insert into candymat_data.user_app_info (row_id, title, content) values
|
||||||
|
('legal_page', 'Legal Candymat', '<h1>Impressum</h1><p>Impressum Infos</p>');
|
||||||
|
|
25
redaktions-app/src/backend/mutations/page_info.ts
Normal file
25
redaktions-app/src/backend/mutations/page_info.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { gql } from "@apollo/client";
|
||||||
|
import { GetAllPageInfoResponse } from "../queries/page_info";
|
||||||
|
|
||||||
|
export const EDIT_INFOS = gql`
|
||||||
|
mutation UpdateInfos(
|
||||||
|
$id: ID!
|
||||||
|
$title: String
|
||||||
|
$content: String
|
||||||
|
$rowId: String
|
||||||
|
) {
|
||||||
|
updateUserAppInfo(
|
||||||
|
input: {
|
||||||
|
id: $id
|
||||||
|
userAppInfoPatch: { content: $content, rowId: $rowId, title: $title }
|
||||||
|
clientMutationId: ""
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
clientMutationId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface EditInfosResponse {
|
||||||
|
updateUserAppInfo: GetAllPageInfoResponse;
|
||||||
|
}
|
28
redaktions-app/src/backend/queries/page_info.ts
Normal file
28
redaktions-app/src/backend/queries/page_info.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { gql } from "@apollo/client";
|
||||||
|
|
||||||
|
export const GET_ALL_PAGE_INFO = gql`
|
||||||
|
query AllInfos {
|
||||||
|
allUserAppInfos {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
rowId
|
||||||
|
title
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface PageInfo {
|
||||||
|
id: string;
|
||||||
|
rowId: string;
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetAllPageInfoResponse {
|
||||||
|
allUserAppInfos: {
|
||||||
|
nodes: Array<PageInfo>;
|
||||||
|
__typename: "UserAppInfosConnection";
|
||||||
|
};
|
||||||
|
}
|
59
redaktions-app/src/components/EditInformation.tsx
Normal file
59
redaktions-app/src/components/EditInformation.tsx
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Paper, Typography } from "@material-ui/core";
|
||||||
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
import { useQuery } from "@apollo/client";
|
||||||
|
import {
|
||||||
|
GET_ALL_PAGE_INFO,
|
||||||
|
GetAllPageInfoResponse,
|
||||||
|
PageInfo,
|
||||||
|
} from "../backend/queries/page_info";
|
||||||
|
import { EditInformationField } from "./EditInformationField";
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
root: {
|
||||||
|
width: "100%",
|
||||||
|
padding: theme.spacing(1),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
},
|
||||||
|
textArea: {
|
||||||
|
width: "85%",
|
||||||
|
height: "150px",
|
||||||
|
padding: theme.spacing(1),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
marginTop: theme.spacing(1),
|
||||||
|
resize: "none",
|
||||||
|
overflow: "auto",
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface EditInformationProps {
|
||||||
|
loggedInPersonRowId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EditInformation(
|
||||||
|
props: EditInformationProps
|
||||||
|
): React.ReactElement {
|
||||||
|
const infos =
|
||||||
|
useQuery<GetAllPageInfoResponse, null>(GET_ALL_PAGE_INFO).data
|
||||||
|
?.allUserAppInfos.nodes || [];
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Typography component={"h2"} variant="h6" gutterBottom>
|
||||||
|
Bearbeite hier die Webseiten Info-Texte für deinen Candymat:
|
||||||
|
</Typography>
|
||||||
|
<Paper className={classes.root}>
|
||||||
|
{infos.map((info: PageInfo) => {
|
||||||
|
return (
|
||||||
|
<EditInformationField
|
||||||
|
loggedInPersonRowId={props.loggedInPersonRowId}
|
||||||
|
key={info.id}
|
||||||
|
info={info}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Paper>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
74
redaktions-app/src/components/EditInformationField.tsx
Normal file
74
redaktions-app/src/components/EditInformationField.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { IconButton, Typography } from "@material-ui/core";
|
||||||
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
import { useMutation } from "@apollo/client";
|
||||||
|
import { Save } from "@material-ui/icons";
|
||||||
|
import { EDIT_INFOS, EditInfosResponse } from "../backend/mutations/page_info";
|
||||||
|
import { PageInfo } from "../backend/queries/page_info";
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
root: {
|
||||||
|
width: "100%",
|
||||||
|
padding: theme.spacing(1),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
},
|
||||||
|
textArea: {
|
||||||
|
width: "85%",
|
||||||
|
height: "150px",
|
||||||
|
padding: theme.spacing(1),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
marginTop: theme.spacing(1),
|
||||||
|
resize: "none",
|
||||||
|
overflow: "auto",
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface EditInformationFieldProps {
|
||||||
|
info: PageInfo;
|
||||||
|
loggedInPersonRowId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EditInformationField(
|
||||||
|
props: EditInformationFieldProps
|
||||||
|
): React.ReactElement {
|
||||||
|
const [info, setInfo] = useState(props.info);
|
||||||
|
const [edit, { loading, error }] = useMutation<EditInfosResponse>(EDIT_INFOS);
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
if (loading) console.log("Loading");
|
||||||
|
if (error) return <p>An error occurred</p>;
|
||||||
|
|
||||||
|
function changeInfo(e: React.ChangeEvent<HTMLTextAreaElement>) {
|
||||||
|
const changeInfoText = e.target.value;
|
||||||
|
setInfo({ ...info, content: changeInfoText });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>
|
||||||
|
{info.title}
|
||||||
|
</Typography>
|
||||||
|
<form>
|
||||||
|
<textarea
|
||||||
|
className={classes.textArea}
|
||||||
|
onChange={changeInfo}
|
||||||
|
value={info.content}
|
||||||
|
>
|
||||||
|
{/*Hier kommt der Inhalt aus der Datenbank*/}
|
||||||
|
</textarea>
|
||||||
|
<IconButton
|
||||||
|
onClick={() =>
|
||||||
|
edit({
|
||||||
|
variables: {
|
||||||
|
id: info.id,
|
||||||
|
content: info.content,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Save />
|
||||||
|
</IconButton>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import PeopleIcon from "@material-ui/icons/People";
|
||||||
import { MenuOption } from "./MainMenu";
|
import { MenuOption } from "./MainMenu";
|
||||||
import { PersonRoutes } from "./Main";
|
import { PersonRoutes } from "./Main";
|
||||||
import { UserManagement } from "./UserManagement";
|
import { UserManagement } from "./UserManagement";
|
||||||
|
import { InfoRounded } from "@material-ui/icons";
|
||||||
|
import { EditInformation } from "./EditInformation";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
container: {
|
container: {
|
||||||
|
@ -22,6 +24,7 @@ const useStyles = makeStyles((theme) => ({
|
||||||
interface EditorRoutes extends PersonRoutes {
|
interface EditorRoutes extends PersonRoutes {
|
||||||
question: MenuOption;
|
question: MenuOption;
|
||||||
userManagement: MenuOption;
|
userManagement: MenuOption;
|
||||||
|
editInformation: MenuOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const editorRoutes: EditorRoutes = {
|
export const editorRoutes: EditorRoutes = {
|
||||||
|
@ -35,6 +38,11 @@ export const editorRoutes: EditorRoutes = {
|
||||||
path: "/benutzer",
|
path: "/benutzer",
|
||||||
icon: <PeopleIcon />,
|
icon: <PeopleIcon />,
|
||||||
},
|
},
|
||||||
|
editInformation: {
|
||||||
|
title: "Infos bearbeiten",
|
||||||
|
path: "/edit",
|
||||||
|
icon: <InfoRounded />,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
interface HomePageEditorProps {
|
interface HomePageEditorProps {
|
||||||
|
@ -54,6 +62,9 @@ export function HomePageEditor(props: HomePageEditorProps): React.ReactElement {
|
||||||
<Route path={editorRoutes.userManagement.path}>
|
<Route path={editorRoutes.userManagement.path}>
|
||||||
<UserManagement loggedInPersonRowId={props.loggedInUserRowId} />
|
<UserManagement loggedInPersonRowId={props.loggedInUserRowId} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path={editorRoutes.editInformation.path}>
|
||||||
|
<EditInformation loggedInPersonRowId={props.loggedInUserRowId} />
|
||||||
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
<Copyright />
|
<Copyright />
|
||||||
</Container>
|
</Container>
|
||||||
|
|
Loading…
Reference in a new issue