Compare commits
8 commits
main
...
feature/#2
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
|
||||
to candymat_anonymous, candymat_person -- maybe change to candymat_person only in the future
|
||||
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 { PersonRoutes } from "./Main";
|
||||
import { UserManagement } from "./UserManagement";
|
||||
import { InfoRounded } from "@material-ui/icons";
|
||||
import { EditInformation } from "./EditInformation";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
container: {
|
||||
|
@ -22,6 +24,7 @@ const useStyles = makeStyles((theme) => ({
|
|||
interface EditorRoutes extends PersonRoutes {
|
||||
question: MenuOption;
|
||||
userManagement: MenuOption;
|
||||
editInformation: MenuOption;
|
||||
}
|
||||
|
||||
export const editorRoutes: EditorRoutes = {
|
||||
|
@ -35,6 +38,11 @@ export const editorRoutes: EditorRoutes = {
|
|||
path: "/benutzer",
|
||||
icon: <PeopleIcon />,
|
||||
},
|
||||
editInformation: {
|
||||
title: "Infos bearbeiten",
|
||||
path: "/edit",
|
||||
icon: <InfoRounded />,
|
||||
},
|
||||
};
|
||||
|
||||
interface HomePageEditorProps {
|
||||
|
@ -54,6 +62,9 @@ export function HomePageEditor(props: HomePageEditorProps): React.ReactElement {
|
|||
<Route path={editorRoutes.userManagement.path}>
|
||||
<UserManagement loggedInPersonRowId={props.loggedInUserRowId} />
|
||||
</Route>
|
||||
<Route path={editorRoutes.editInformation.path}>
|
||||
<EditInformation loggedInPersonRowId={props.loggedInUserRowId} />
|
||||
</Route>
|
||||
</Switch>
|
||||
<Copyright />
|
||||
</Container>
|
||||
|
|
Loading…
Reference in a new issue