Skip to content
Snippets Groups Projects
Commit 692094f1 authored by jankuepper's avatar jankuepper
Browse files

Dateien verschoben

parent c3b0add7
Branches
No related tags found
No related merge requests found
Showing
with 43561 additions and 0 deletions
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
Source diff could not be displayed: it is too large. Options to address this: view the blob.
Source diff could not be displayed: it is too large. Options to address this: view the blob.
{
"name": "dashboard",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"react-scripts": "^2.1.3",
"web-vitals": "^3.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!-- <meta
name="description"
content="Web site created using create-react-app"
/> -->
<!-- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> -->
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Dashboard</title>
</head>
<body>
<!-- <noscript>You need to enable JavaScript to run this app.</noscript> -->
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
\ No newline at end of file
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
publicNotUse/favicon.ico

3.78 KiB

publicNotUse/logo192.png

5.22 KiB

publicNotUse/logo512.png

9.44 KiB

{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Navbar from './Components/Navbar';
import Home from './Components/Home';
import My from './Components/My';
import About from './Components/About';
import Events from './Components/Events';
import NewEvent from './Components/NewEvent';
import Account from './Components/Account';
import Polls from './Components/Polls';
import PollsNewHandel from './Components/PollNewHandel';
import Toast from './Components/Toast';
import { execute } from './Components/sql';
import './Components/App.css';
// alles zurücksetzen und zu Dashboard-Startseite wechseln
function Logout(props) {
const navigate = useNavigate();
useEffect(() => {
localStorage.clear();
props.logout();
navigate("/dashboard/");
});
}
// React Komponente auf die alle weitern Komponenten aufbauen
function App(props) {
const [member, setMember] = useState({});
const [token, setToken] = useState('');
const [memberName, setMemberName] = useState("");
const [memberMail, setMemberMail] = useState(localStorage.getItem("emailData") != null ? localStorage.getItem("emailData") : "");
const [disciplines, setDisciplines] = useState([]);
const [series, setSeries] = useState([]);
const [dsgvo, setdsgvo] = useState(false);
const [form, setForm] = useState("login");
const [toastList, setToastList] = useState([]);
React.useEffect(() => {
getDisciplines();
getSeries();
}, []);
// Disziplinen aus Datenbank laden
function getDisciplines() {
execute("disciplines").then((resData) => {
setDisciplines(resData);
});
}
// Serien aus Datenbank laden
function getSeries() {
execute("series").then((resData) => {
setSeries(resData);
});
}
// Registrierung eines neune Mitglied
function registration() {
if (memberName != "" && memberMail != "" && dsgvo) {
execute("authentication", null, [memberMail]).then((resData) => {
if (resData.length == 0) {
execute("registration", null, [memberMail, memberName, dsgvo]).then((resData) => {
console.log(resData.length)
execute("authentication", null, [memberMail]).then((resData) => {
console.log(resData.length)
if (resData.length) {
setToken(resData[0]["token"]);
execute("member", resData[0]["token"], null, 0).then((resData) => {
if (resData.length) {
setMember(resData[0]);
setMemberName(resData[0]["name"]);
setMemberMail(resData[0]["mail"]);
localStorage.setItem("emailData", resData[0]["mail"]);
}
});
}
});
});
}
else {
setToastList([...toastList, {
id: 7,
title: 'Warning Konto existiert',
description: 'Bitte über Login',
backgroundColor: '#ff9800',
icon: "warning"
}]);
}
});
}
else {
let toastListDummy = []
if (memberName == "") {
toastListDummy = [...toastListDummy, {
id: 1,
title: 'Error Eingabe fehlerhaft',
description: 'Bitte gültigen Namen eintragen',
backgroundColor: '#d9534f',
icon: "cancel"
}];
}
if (memberMail == "") {
toastListDummy = [...toastListDummy, {
id: 2,
title: 'Error Eingabe fehlerhaft',
description: 'Bitte gültige Mailadresse eintragen',
backgroundColor: '#d9534f',
icon: "cancel"
}];
}
if (!dsgvo) {
toastListDummy = [...toastListDummy, {
id: 3,
title: 'Error Eingabe fehlerhaft',
description: 'Bitte Datenschutzhinweise akzeptieren',
backgroundColor: '#d9534f',
icon: "cancel"
}];
}
setToastList([...toastList, ...toastListDummy]);
}
}
// Anmeldung am Dashboard
function login() {
setMember({});
execute("authentication", null, [memberMail]).then((resData1) => {
if (resData1.length) {
setToken(resData1[0]["token"]);
execute("member", resData1[0]["token"], null, 0).then((resData) => {
if (resData.length) {
setMember(resData[0]);
setMemberName(resData[0]["name"]);
setMemberMail(resData[0]["mail"]);
localStorage.setItem("emailData", resData[0]["mail"]);
}
});
} else {
setToastList([...toastList, {
id: 4,
title: 'Error Eingabe fehlerhaft',
description: 'Bitte gültige Mailadresse eintragen',
backgroundColor: '#d9534f',
icon: "cancel"
}]);
}
});
}
// Benutzerdaten aus Speicher löschen
function logout() {
setMember({});
setMemberName("");
setMemberMail("");
}
// nach der Anmeldung werden die Komponenten der einzelnen Seiten geladen
if (member.id == undefined) {
return (
<div style={{ "min-height": "2500px", top: "0", left: "0", bottom: "0", right: "0", " z-index": "100", background: "#202020cf", display: member.id == undefined ? "flex" : "none" }}>
<div class="login-form">
<div class="action">
<input type="button" onClick={e => setForm("login")} style={{ background: form == "login" ? "#2d3b55" : "#e8e9ec", color: form == "login" ? "#fff" : "#777" }} value="Login" />
<input type="button" onClick={e => setForm("registrierung")} style={{ background: form == "registrierung" ? "#2d3b55" : "#e8e9ec", color: form == "registrierung" ? "#fff" : "#777" }} value="Registrierung" />
</div>
<div class="content" style={{ display: form == "login" ? "block" : "none" }}>
<div class="input-field">
<input type="email" id="email" name="email" placeholder="E-Mail" value={memberMail}
onChange={e => setMemberMail(e.target.value)} onKeyPress={e => { if (e.key == 'Enter') { login() } }} />
</div>
<a href="mailto:netzmeister@rv-adler.de" class="link">Zugang vergessen?</a>
<br></br>
<input type="button" onClick={() => login()} value="Anmelden" />
</div>
<div class="content" style={{ display: form == "registrierung" ? "block" : "none" }}>
<div class="input-field">
<input type="text" id="name" name="name" placeholder="Name" value={memberName}
onChange={e => setMemberName(e.target.value)} onKeyPress={e => { if (e.key == 'Enter') { registration() } }} />
</div>
<div class="input-field">
<input type="email" id="email" name="email" placeholder="E-Mail" value={memberMail}
onChange={e => setMemberMail(e.target.value)} onKeyPress={e => { if (e.key == 'Enter') { registration() } }} />
</div>
<div style={{ "padding": "12px 5px", "text-align": "left" }}>
<input type="checkbox" onChange={e => setdsgvo(e.target.checked ? 1 : 0)} checked={dsgvo} />Ich akzeptiere die Datenschutzhinweise
</div>
<details style={{ "text-align": "left" }}>
<summary><b>Hinweis zum Datenschutz</b></summary>
<p style={{ "text-align": "left" }}> Im Rahmen der Registrierung zum Veranstaltungskalender werden Ihre personenbezogenen Daten aufgenommen.
Die Erhebung der personenbezogenen Daten erfolgt auf der Rechtsgrundlage des
Artikels 6 Absatz 1 Ziffer a der DS-GVO ausschließlich zur Abwicklung der Organisation im Rahmen des Veranstaltungskalender.
Zugriff auf die Daten hat nur der RV Adler Lüttringhausen. Auf Wunsch werden Ihre Daten von uns gelöscht.</p>
</details>
<input type="button" onClick={() => registration()} value="Registrieren" />
</div>
</div>
<Toast
toastList={toastList}
position={"bottom-left"}
autoDelete={true}
autoDeleteTime={5000}
/>
</div >
);
}
else {
return (
<div className="App">
<BrowserRouter>
<Navbar member={member} />
<Routes >
<Route exact path="/dashboard" element={<Home member={member} />}></Route>
<Route exact path="/dashboard/veranstaltungen" element={<Events token={token} member={member} disciplines={disciplines} series={series} />}></Route>
<Route exact path="/dashboard/veranstaltungen/neu" element={<NewEvent token={token} member={member} disciplines={disciplines} series={series} setToastList={tost => setToastList([...toastList, tost])} />}></Route>
<Route exact path="/dashboard/meine" element={<My token={token} member={member} />}></Route>
<Route exact path="/dashboard/konto" element={<Account token={token} member={member} login={() => login} setToastList={tost => setToastList([...toastList, tost])} />}></Route>
<Route exact path="/dashboard/infos" element={<About />}></Route>
<Route path="/dashboard/abstimmungen" element={<Polls token={token} member={member} />}></Route>
<Route path="/dashboard/abstimmungen/neu" element={<PollsNewHandel token={token} />} ></Route>
<Route exact path="/dashboard/logout" element={<Logout logout={() => logout()} />}></Route>
</Routes >
</BrowserRouter>
<Toast
toastList={toastList}
position={"bottom-left"}
autoDelete={true}
autoDeleteTime={2500}
/>
</div >
);
}
}
export default App;
\ No newline at end of file
import React, { Component } from 'react';
// Info Seite, hier ist noch was möglich
function About(props) {
return (
<div>
Text
</div>
);
}
export default About;
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { execute } from './sql';
// Benutzerdaten bearbeiten und speichern
function Account(props) {
const [memberName, setMemberName] = useState(props.member.name);
const [memberMail, setMemberMail] = useState(props.member.mail);
function setMember(id) {
execute("member", props.token, [memberName, memberMail, id], 2).then((resData) => {
props.login();
props.setToastList({
id: 6,
title: 'Success',
description: 'Daten wurden geändert',
backgroundColor: '#5cb85c',
icon: "check_circle"
});
});
}
// Formular zum eingeben der Daten
return (
<div>
<div>
<label>Name</label>
<input type="text" value={memberName} onChange={e => setMemberName(e.target.value)} />
<label>Mail</label>
<input type="email" value={memberMail} onChange={e => setMemberMail(e.target.value)} />
</div>
<input type="button" onClick={() => setMember(props.member.id)} value="Speichern" />
</div >
)
}
export default Account;
\ No newline at end of file
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
* {
box-sizing: border-box;
}
html {
box-sizing: border-box
}
html,
body {
font-family: Verdana, sans-serif;
font-size: 15px;
line-height: 1.5;
margin: 0
}
h4 {
font-size: 20px
}
h5 {
font-size: 18px
}
h4,
h5 {
font-family: "Segoe UI", Arial, sans-serif;
font-weight: 400;
margin: 10px 0
}
p {
text-align: center;
font-weight: 500;
}
input,
select {
font: inherit;
margin: 0
}
select,
textarea {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px !important;
margin-bottom: 16px !important;
resize: vertical;
}
input[type=text],
input[type=email],
input[type=date],
input[type=datetime-local] {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
-webkit-appearance: none;
}
input[type=checkbox] {
margin: 8px;
}
input[type=button] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
-webkit-appearance: none;
margin: 5px;
}
input[type=button]:hover {
background-color: #45a049;
}
input[type=button]:disabled {
background-color: #90f795;
}
form {
width: 1000px;
min-height: 2500px;
margin-right: auto;
margin-left: auto;
}
.material-icons {
cursor: pointer;
}
.App {
width: 1000px;
min-height: 2500px;
margin: 0 auto;
padding: 20px;
}
.login-form {
background: #fff;
width: 500px;
margin: 65px auto auto;
display: -webkit-box;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
border-radius: 4px;
box-shadow: 0 2px 25px rgba(0, 0, 0, 0.2);
}
.login-form h1 {
padding: 35px 35px 0 35px;
font-weight: 300;
}
.login-form .content {
padding: 35px;
text-align: center;
}
.login-form .input-field {
padding: 12px 5px;
}
.login-form .input-field input {
font-size: 16px;
display: block;
font-family: 'Rubik', sans-serif;
width: 100%;
padding: 10px 1px;
border: 0;
border-bottom: 1px solid #747474;
outline: none;
-webkit-transition: all .2s;
transition: all .2s;
}
.login-form .input-field input::placeholder {
text-transform: uppercase;
}
.login-form a.link {
text-decoration: none;
color: #747474;
letter-spacing: 0.2px;
text-transform: uppercase;
display: inline-block;
margin-top: 20px;
}
.login-form .action {
display: -webkit-box;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
flex-direction: row;
}
.login-form .action input[type=button] {
width: 100%;
border: none;
padding: 18px;
font-family: 'Rubik', sans-serif;
cursor: pointer;
text-transform: uppercase;
background: #e8e9ec;
color: #777;
border-radius: 4px;
letter-spacing: 0.2px;
outline: 0;
-webkit-transition: all .3s;
transition: all .3s;
}
nav {
background-color: #333;
color: #f2f2f2;
}
nav ul {
padding: 0;
}
nav ul li {
display: inline-block;
}
nav ul li:hover {
background-color: #ddd;
}
.nav-link {
color: #ffffff;
text-decoration: none;
display: inline-block;
padding: 14px 16px;
cursor: pointer;
font-weight: 600;
text-align: center;
font-size: 17px;
}
.nav-link:hover {
color: black;
}
.option-menu {
position: relative;
}
.menu-trigger {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 30px;
cursor: pointer;
margin: 5px;
}
.dots-container {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.dot {
width: 5px;
height: 5px;
border-radius: 50%;
background-color: #333;
margin-bottom: 4px;
}
.menu-options {
position: absolute;
top: 30px;
right: 0;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
padding: 8px;
border-radius: 4px;
display: flex;
flex-direction: column;
z-index: 1;
}
.option {
cursor: pointer;
padding: 8px;
color: rgba(0, 0, 0, 1);
text-align: left;
}
.option:hover {
background-color: #f2f2f2;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 6px;
}
/* Home */
.container {
padding: 0.01em 16px
}
.row-padding,
.row-padding>.quarter {
padding: 8px 8px
}
.quarter {
float: left;
width: 100%;
padding: 8px;
width: 24.99999%
}
.padding-16 {
padding-top: 16px !important;
padding-bottom: 16px !important
}
.left {
float: left !important
}
.right {
float: right !important
}
.clear {
content: "";
display: table;
clear: both
}
.red,
.hover-red:hover {
color: #fff !important;
background-color: #f44336 !important
}
.blue,
.hover-blue:hover {
color: #fff !important;
background-color: #2196F3 !important
}
.teal,
.hover-teal:hover {
color: #fff !important;
background-color: #009688 !important
}
.blue-grey,
.hover-blue-grey:hover,
.blue-gray,
.hover-blue-gray:hover {
color: #fff !important;
background-color: #607d8b !important
}
.orange,
.hover-orange:hover {
color: #fff !important;
background-color: #ff9800 !important
}
.opacity,
.hover-opacity:hover {
opacity: 0.60
}
.medium {
font-size: 15px !important
}
/* Meine */
table {
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #a19e9e;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
/* Events */
.filter-container {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 16px;
}
.filter-container-item {
display: grid;
align-items: center;
justify-content: center;
}
.member-list-item {
display: inline-flex;
margin: 2px;
border-radius: 10px;
background-color: #f2f2f2;
align-items: center;
color: #000000;
padding: 2px 10px 2px 10px;
}
.event-container {
border-radius: 10px 10px 10px 10px;
background-color: rgb(255, 67, 89);
text-align: center;
color: white;
margin: 0px 15px 15px 15px;
position: relative;
padding: 15px;
}
.event-container-view {
display: flex;
justify-content: space-between;
padding: 15px;
}
.event-container-item {
margin: auto;
}
/* Proposals */
.list-proposals {
margin-top: 15px;
width: 100%;
display: inline-block;
}
/* Toast */
.notification-container {
font-size: 14px;
box-sizing: border-box;
position: fixed;
z-index: 999999
}
.top-right {
top: 12px;
right: 12px;
transition: transform .6s ease-in-out;
animation: toast-in-right .7s;
}
.bottom-right {
bottom: 12px;
right: 12px;
transition: transform .6s ease-in-out;
animation: toast-in-right .7s;
}
.top-left {
top: 12px;
left: 12px;
transition: transform .6s ease-in;
animation: toast-in-left .7s;
}
.bottom-left {
bottom: 12px;
left: 12px;
transition: transform .6s ease-in;
animation: toast-in-left .7s;
}
.notification {
background: #fff;
transition: .3s ease;
position: relative;
pointer-events: auto;
overflow: hidden;
margin: 0 0 6px;
padding: 30px;
margin-bottom: 15px;
width: 300px;
max-height: 100px;
border-radius: 3px 3px 3px 3px;
box-shadow: 0 0 10px #999;
color: #000;
opacity: .9;
background-position: 15px;
background-repeat: no-repeat;
}
.notification:hover {
box-shadow: 0 0 12px #fff;
opacity: 1;
cursor: pointer
}
.notification-title {
font-weight: 700;
font-size: 16px;
text-align: left;
margin-top: 0;
margin-bottom: 6px;
width: 300px;
height: 18px;
}
.notification-message {
margin: 0;
text-align: left;
margin-left: -1px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.notification-image {
float: left;
margin-right: 15px;
}
.notification-image img {
width: 30px;
height: 30px;
}
.toast {
width: 365px;
color: #fff;
}
.notification-container button {
position: relative;
right: -.3em;
top: -.3em;
float: right;
font-weight: 700;
color: #fff;
outline: none;
border: none;
text-shadow: 0 1px 0 #fff;
opacity: .8;
line-height: 1;
font-size: 16px;
padding: 0;
cursor: pointer;
background: 0 0;
border: 0
}
@keyframes toast-in-right {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
@keyframes toast-in-left {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { execute } from './sql';
import { Link } from 'react-router-dom';
// neue Veranstaltung hinzufügen
function NewEvent(props) {
const [eventDisciplineId, setEventDisciplineId] = useState(0);
const [eventSeriesId, setEventSeriesId] = useState(0);
const [eventAdult, setEventAdult] = useState(1);
const [eventStudent, setEventStudent] = useState(0);
const [eventStartDate, setEventStartDate] = useState(null);
const [eventEndDate, setEventEndDate] = useState(null);
const [eventLocation, setEventLocation] = useState("");
const [eventUrl, setEventUrl] = useState("");
const [eventName, setEventName] = useState("");
// Disziplinen in Selectbox laden
function listDisciplines() {
return props.disciplines.map((item) => {
return (
<option value={item.id}>{item.bezeichnung}</option>
);
});
}
// Serien in Selectbox laden
function listSeries() {
return props.series.map((item) => {
return (
<option value={item.id}>{item.bezeichnung}</option>
);
});
}
// Daten an Server senden
function handleFormSubmit(event) {
event.preventDefault();
execute("event", props.token, [eventName, eventUrl, eventStartDate, eventEndDate, eventLocation, eventDisciplineId, eventAdult, eventStudent, eventSeriesId, 1]).then((resData) => {
setEventDisciplineId(0);
setEventSeriesId(0);
setEventAdult(1);
setEventStudent(0);
setEventStartDate(null);
setEventEndDate(null);
setEventLocation("");
setEventUrl("");
setEventName("");
props.setToastList({
id: 5,
title: 'Success',
description: 'Veranstaltung wurde hinzugefügt',
backgroundColor: '#5cb85c',
icon: "check_circle"
});
});
}
// Formular zum eingeben der Daten
return (
<div>
<label>Name</label>
<input type="text" name="eventName" value={eventName}
onChange={e => setEventName(e.target.value)} />
<label>URL (Webseite)</label>
<input type="text" name="eventUrl" value={eventUrl}
onChange={e => setEventUrl(e.target.value)} />
<label>Start Datum</label>
<input type="date" name="eventStartDate" value={eventStartDate}
onChange={e => setEventStartDate(e.target.value)} />
<label>End Datum</label>
<input type="date" name="eventEndDate" value={eventEndDate}
onChange={e => setEventEndDate(e.target.value)} />
<label>Ort</label>
<input type="text" name="eventLocation" value={eventLocation}
onChange={e => setEventLocation(e.target.value)} />
<label>Disziplin</label>
<select value={eventDisciplineId} onChange={e => setEventDisciplineId(e.target.value)}>
{listDisciplines()}
</select>
<input type="checkbox" id="erwachsene" name="erwachsene" checked={eventAdult} onChange={e => setEventAdult(e.target.checked ? 1 : 0)} />
<label for="erwachsene"> Erwachsene</label>
<input type="checkbox" id="schueler" name="schueler" checked={eventStudent} onChange={e => setEventStudent(e.target.checked ? 1 : 0)} />
<label for="schueler"> Schüler</label>
<br></br>
<label>Serie</label>
<select value={eventSeriesId} onChange={e => setEventSeriesId(e.target.value)}>
{listSeries()}
</select>
<input type="button" onClick={e => handleFormSubmit(e)} value="Hinzufügen" />
<Link to="/dashboard/veranstaltungen" style={{ float: "right" }}><input type="button" value={"Zurück"}></input></Link>
</div >
)
}
export default NewEvent;
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { execute } from './sql';
import { Link, useSearchParams } from 'react-router-dom';
import Members from './Members';
// Veranstaltungsseite, nach Veranstaltungen filtern
function Events(props) {
const [searchParams, setSearchParams] = useSearchParams();
const [searchDisciplineId, setSearchDisciplineId] = useState(0);
const [searchSeriesId, setSearchSeriesId] = useState(0);
const [searchAdult, setSearchAdult] = useState(0);
const [searchStudent, setSearchStudent] = useState(0);
const [searchMembers, setSearchMembers] = useState([]);
const [searchYear, setSearchYear] = useState(new Date().getFullYear());
const [searchPast, setSearchPast] = useState(1);
const [events, setEvents] = useState([]);
const [members, setMembers] = useState([]);
React.useEffect(() => {
search();
}, []);
// Disziplinen in Selectbox laden
function listDisciplines() {
return props.disciplines.map((item) => {
return (
<option value={item.id}>{item.bezeichnung}</option>
);
});
}
// Serien in Selectbox laden
function listSeries() {
return props.series.map((item) => {
return (
<option value={item.id}>{item.bezeichnung}</option>
);
});
}
// Jahreszahlen in Selectbox laden
function listYears() {
let arr = [];
for (let x = - 2; x < 3; x++) {
arr[x + 2] = x + new Date().getFullYear();
}
return arr.map((item) => {
return (
<option value={item}>{item}</option>
);
});
}
// Veranstaltungen suchen
function search() {
const date = new Date();
execute("events", props.token, ([(searchPast? `${searchYear}-01-01` : `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`), `${searchYear}-12-31`,
searchDisciplineId, searchSeriesId, searchAdult, searchStudent]).concat(searchMembers.map((item) => item["id"]))).then((resData) => {
setEvents(resData);
});
}
// Mitgliederliste laden
function getMembers() {
execute("members", props.token, null, 0).then((resData) => {
setMembers(resData);
});
}
// Status-Meldung verarbeiten
function onEntry(eventId, state) {
execute("entry", props.token, [eventId, props.member.id], 0).then((resData) => {
if (resData.length == 0) {
execute("entry", props.token, [props.member.id, eventId, 0, state], 1).then((resData) => {
search();
});
}
else {
execute("entry", props.token, [state, resData[0]["id"]], 2).then((resData) => {
search();
});
}
});
}
// Veranstaltung aufklappen
function onEvent(eventId) {
if (searchParams.get("veranstaltung") != eventId) {
searchParams.set("veranstaltung", eventId);
}
else {
searchParams.delete("veranstaltung");
}
setSearchParams(searchParams);
}
// Veranstaltungen auflisten
function listevents() {
return events.map((item) => {
return (
<div className="event-container" style={{ "background-color": (new Date().getTime() <= new Date(item.intStartDatum).getTime()) ? "rgb(255, 67, 89)" : "rgb(228, 158, 166)" }}>
<div className="event-container-view">
<div className="event-container-item" style={{ width: "150px" }}>
<a href={item.url} target="_blank" rel="noopener noreferrer" style={{ "color": "#ffffff" }}>{item.name} {item.name.match(`${item.ort}`) ? "" : `(${item.ort})`}</a>
</div>
<div className="event-container-item" style={{ width: "150px" }}>{item.startDatum} {item.endDatum != "00.00.00" ? ` - ${item.endDatum}` : ""}</div>
<div className="event-container-item" style={{ width: "150px" }}>{item.disziplin}</div>
<div className="event-container-item" style={{ width: "150px" }}>
<a href={item.serieUrl} target="_blank" rel="noopener noreferrer" style={{ "color": "#ffffff" }}>{item.serie}</a>
</div>
<div className="event-container-item" style={{ width: "150px", "text-decoration": "underline", cursor: "pointer" }} onClick={() => onEvent(item.id)}>
{item.angemeldet} angemeldet<br></br>{item.interessiert} interessiert
</div>
<div className="event-container-item" style={{ width: "170px", "display": "flex", "justify-content": "right" }}>
<span class="material-icons"
onClick={() => onEntry(item.id, 1)} value="a" style={{ "font-size": "40px", "color": item.status == "1" ? "#FFFFFF" : "#000000" }}>check_circle</span>
<span class="material-icons"
onClick={() => onEntry(item.id, 2)} value="i" style={{ "font-size": "40px", "color": item.status == "2" ? "#FFFFFF" : "#000000" }}>stars</span>
<span class="material-icons"
onClick={() => onEntry(item.id, 4)} value="?" style={{ "font-size": "40px", "color": item.status == "4" ? "#FFFFFF" : "#000000" }}>support_agent</span>
<span class="material-icons"
onClick={() => onEntry(item.id, 3)} value="?" style={{ "font-size": "40px", "color": item.status == "3" ? "#FFFFFF" : "#000000" }}>cancel</span>
</div>
</div>
<div>
{searchParams.get("veranstaltung") == item.id ? <Members id={item.id} typ={"entrys"}></Members> : null}
</div>
</div >
);
});
}
// Filter und Auflistung der geladenen Veranstaltungen
return (
<div>
<Link to="/dashboard/events/neu" style={{ float: "right" }}><input type="button" value={"+"}></input></Link>
<br></br>
<div style={{ "margin-bottom": "16px" }}>
<label>Jahr</label>
<select value={searchYear} onChange={e => setSearchYear(e.target.value)}>
{listYears()}
</select>
</div>
<div className="filter-container">
<div className="filter-container-item">
<label>Disziplin</label>
<select value={searchDisciplineId} onChange={e => setSearchDisciplineId(e.target.value)}>
{listDisciplines()}
</select>
</div>
<div className="filter-container-item">
<label>Serie</label>
<select value={searchSeriesId} onChange={e => setSearchSeriesId(e.target.value)}>
{listSeries()}
</select>
</div>
<div className="filter-container-item" style={{ "display": "flex" }}>
<label for="searchAdult"> Erwachsene</label>
<input type="checkbox" id="searchAdult" name="searchAdult" checked={searchAdult} onChange={e => setSearchAdult(e.target.checked ? 1 : 0)} />
</div>
<div className="filter-container-item" style={{ "display": "flex" }}>
<label for="searchStudent"> Schüler</label>
<input type="checkbox" id="searchStudent" name="searchStudent" checked={searchStudent} onChange={e => setSearchStudent(e.target.checked ? 1 : 0)} />
</div>
</div>
<div>
{searchMembers.map((searchMember) => {
return (
<div className="member-list-item">
<span>{searchMember.name}</span>
<span class="material-icons" style={{ "font-size": "20px" }}
onClick={e => setSearchMembers(searchMembers.filter(item => item.id != searchMember.id))}>delete</span>
</div>
);
})}
</div>
<div style={{ "margin-bottom": "16px" }}>
<div style={{ "display": "inline-flex", "align-items": "center" }} onClick={e => members.length ? setMembers([]) : getMembers()}>
<label style={{ "cursor": "pointer" }}>Alle Mitglieder</label>
<span class="material-icons" style={{ "font-size": "30px", transform: members.length ? "rotate(180deg)" : "rotate(0deg)" }}
>arrow_drop_down</span>
</div>
<br></br>
{members.map((member) => {
return (
<div className="member-list-item" style={{ "text-decoration": "underline", cursor: "pointer" }} onClick={e => setSearchMembers(searchMembers.concat({ id: member.id, name: member.name }))}>
{member.name}
</div>
);
})}
</div>
<div>
<label for="searchPast"> Vergangene events anzeigen</label>
<input type="checkbox" id="searchPast" name="searchPast" checked={searchPast} onChange={e => setSearchPast(e.target.checked ? 1 : 0)} />
</div>
<input type="button" onClick={e => search(e)} value="Suchen" />
<div style={{ "margin-top": "15px" }}>
{listevents()}
</div>
</div >
)
}
export default Events;
\ No newline at end of file
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
// Startseite zur Navigation
function Home(props) {
return (
<div>
<header className="container" style={{ paddingTop: 22 }}>
<h5>
<b>
<i className="fa fa-dashboard" />Dashboard
</b>
</h5>
</header>
<div className="row-padding margin-bottom">
<Link to="/dashboard/veranstaltungen">
<div className="quarter">
<div className="container red padding-16">
<div className="left">
<span class="material-icons" style={{ "font-size": "50px" }}>event</span>
</div>
<div className="right">
</div>
<div className="clear" />
<h4>Veranstaltungen</h4>
</div>
</div>
</Link>
<Link to="/dashboard/abstimmungen">
<div className="quarter">
<div className="container blue padding-16">
<div className="left">
<span class="material-icons" style={{ "font-size": "50px" }}>ballot</span>
</div>
<div className="right">
</div>
<div className="clear" />
<h4>Abstimmungen</h4>
</div>
</div>
</Link>
<Link to="/dashboard/meine">
<div className="quarter">
<div className="container teal padding-16">
<div className="left">
<span class="material-icons" style={{ "font-size": "50px" }}>emoji_events</span>
</div>
<div className="right">
</div>
<div className="clear" />
<h4>Meine</h4>
</div>
</div>
</Link>
<Link to="/dashboard">
<div className="quarter">
<div className="container blue-grey text-white padding-16">
<div className="left">
<span class="material-icons" style={{ "font-size": "50px" }}>groups</span>
</div>
<div className="right">
</div>
<div className="clear" />
<h4>Mitglieder</h4>
</div>
</div>
</Link>
<Link to="/dashboard/infos">
<div className="quarter">
<div className="container orange text-white padding-16">
<div className="left">
<span class="material-icons" style={{ "font-size": "50px" }}>info</span>
</div>
<div className="right">
</div>
<div className="clear" />
<h4>Infos</h4>
</div>
</div>
</Link>
</div >
</div >
)
}
export default Home;
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { execute } from './sql';
// Liste der Mitglieder erstellen die sich für etwas gemeldet oder abgestimmt haben
function Members(props) {
const [entrys, setEntrys] = useState([]);
React.useEffect(() => {
getEntrys(props.id);
}, []);
function getEntrys(id) {
switch (props.typ) {
case "votes":
execute("votes", props.token, [id]).then((resData) => {
setEntrys(resData);
});
break;
case "entrys":
execute("entrys", props.token, [id]).then((resData) => {
setEntrys(resData);
});
break;
}
}
function listEntrys() {
return entrys.map((entry) => {
if (entry.status != 3) {
switch (props.typ) {
case "votes":
return (
<div className="member-list-item" >
{entry.status == 1 ? "passt" : ""}{entry.status == 2 ? "vielleicht" : ""} {entry.name}
</div>
);
break;
case "entrys":
return (
<div className="member-list-item" >
{entry.status == 1 ? "a" : ""}{entry.status == 2 ? "i" : ""}{entry.status == 4 ? "Betreuer" : ""}{entry.distanz != 0 ? entry.distanz : ""} {entry.name} {entry.platzGesamt != 0 ? entry.platzGesamt : ""} {entry.platzAk != 0 ? `AK ${entry.platzAk}` : ""}
</div>
);
break;
}
}
});
}
return (
<div>
{listEntrys()}
</div >
);
}
export default Members;
\ No newline at end of file
import React, { Component, useEffect, useState } from 'react';
import { execute } from './sql';
// gemeldete Veranstaltungen des Benutzer anzeigen
function My(props) {
const [myEvents, setMyEvents] = useState([]);
const [searchYear, setSearchYear] = useState(new Date().getFullYear());
React.useEffect(() => {
getMyEvents();
}, []);
React.useEffect(() => {
getMyEvents();
}, [searchYear]);
function onChange(index, item, value) {
let rennen = [...myEvents];
rennen[index][item] = value;
rennen[index]["bearbeitet"] = true;
setMyEvents(rennen);
}
// Jahreszahlen in Selectbox laden
function listYears() {
let arr = [];
for (let x = - 2; x < 3; x++) {
arr[x + 2] = x + new Date().getFullYear();
}
return arr.map((item) => {
return (
<option value={item}>{item}</option>
);
});
}
// gemeldete Veranstaltungen des Benutzer laden
function getMyEvents() {
execute("entrys", props.token, [props.member.id, `${searchYear}-01-01`, `${searchYear}-12-31`]).then((resData) => {
setMyEvents(resData);
});
}
function handleFormSubmit() {
for (var event of myEvents) {
if (event.bearbeitet) {
execute("entry", props.token, [event.distanz, event.platzGesamt, event.platzAk, event.status, event.id], 2).then((resData) => {
if (event.id == myEvents.length - 1) {
getMyEvents();
}
});
}
}
}
// editierbare Liste der Veranstaltungen generieren
function listMyEvents() {
return myEvents.map((event, index) => {
return (
<tr>
<td><a href={event.url} target="_blank" rel="noopener noreferrer" style={{ "color": "#000000" }}>{event.name}</a></td>
<td>{event.startDatum} {event.endDatum != "00.00.00" ? ` - ${event.endDatum}` : ""}</td>
<td>{event.disziplin}</td>
<td>{event.serie}</td>
<td><input type="text" style={{ margin: "auto" }} value={event.distanz} onChange={e => onChange(index, "distanz", e.target.value)} /></td>
<td><input type="text" style={{ margin: "auto" }} value={event.platzGesamt} onChange={e => onChange(index, "platzGesamt", e.target.value)} /></td>
<td><input type="text" style={{ margin: "auto" }} value={event.platzAk} onChange={e => onChange(index, "platzAk", e.target.value)} /></td>
<td>{event.status}</td>
</tr>
);
});
}
return (
<div>
<div style={{ "margin-bottom": "16px" }}>
<label>Jahr</label>
<select value={searchYear} onChange={e => setSearchYear(e.target.value)}>
{listYears()}
</select>
</div>
<table>
<tr>
<th>Name</th>
<th>Datum</th>
<th>Disziplin</th>
<th>Serie</th>
<th>Distanz</th>
<th>Platz Gesamt</th>
<th>Platz Altersklasse</th>
<th>Status</th>
</tr>
{listMyEvents()}
</table>
<input type="button" onClick={e => handleFormSubmit()} value="Speichern" />
</div>
)
}
export default My;
\ No newline at end of file
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
// Navigationsleiste zum navigieren über die unterschiedlichen Seiten/Ansichten
function Navbar(props) {
return (
<nav >
<ul>
<li><Link to="/dashboard/" className="nav-link"><span class="material-icons" style={{ "font-size": "19px" }}>grid_view</span></Link></li>
<li><Link to="/dashboard/veranstaltungen" className="nav-link">Veranstaltungen</Link></li>
<li><Link to="/dashboard/meine" className="nav-link">Meine</Link></li>
<li><Link to="/dashboard/abstimmungen" className="nav-link">Abstimmungen</Link></li>
<li style={{ float: "right" }}><Link to="/dashboard/logout" className="nav-link">Logout</Link></li>
<li style={{ float: "right" }}><Link to="/dashboard/konto" className="nav-link">{props.member.name}</Link></li>
</ul>
</nav>
)
}
export default Navbar;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment