Skip to content
Snippets Groups Projects
Commit 83a4d60e authored by Niklas Schrötler's avatar Niklas Schrötler
Browse files

Merge branch 'gremienpanel' into 'master'

Gremien-Panel

See merge request !2
parents 374cef50 65878b89
Branches
No related tags found
No related merge requests found
......@@ -21,6 +21,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11",
"react-qr-code": "^2.0.12",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
......@@ -14103,6 +14104,11 @@
"teleport": ">=0.2.0"
}
},
"node_modules/qr.js": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
......@@ -14375,6 +14381,24 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-qr-code": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.12.tgz",
"integrity": "sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==",
"dependencies": {
"prop-types": "^15.8.1",
"qr.js": "0.0.0"
},
"peerDependencies": {
"react": "^16.x || ^17.x || ^18.x",
"react-native-svg": "*"
},
"peerDependenciesMeta": {
"react-native-svg": {
"optional": true
}
}
},
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
......@@ -27194,6 +27218,11 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="
},
"qr.js": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
},
"qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
......@@ -27393,6 +27422,15 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"react-qr-code": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.12.tgz",
"integrity": "sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==",
"requires": {
"prop-types": "^15.8.1",
"qr.js": "0.0.0"
}
},
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
......@@ -16,6 +16,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11",
"react-qr-code": "^2.0.12",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
......
{
"id": "default",
"schedule": {
"always": true
"times": [
{
"from": "2023-12-19T21:30",
"to": "2023-12-20T21:00"
}
]
},
"panels": [
{
......@@ -29,44 +34,60 @@
}
},
{
"type": "bild",
"type": "gremium",
"position": {
"x": 9,
"y": 0,
"w": 16,
"h": 5
"h": 4
},
"config": {
"url": "/content/warning.png",
"title": "Achtung, Testbetrieb",
"description": "Wie du vielleicht siehst, sieht dieser Bildschirm heute anders aus. Dürfen wir vorstellen: Der neue Infoscreen. Bitte beachte allerdings, dass wir gerade einen Testbetrieb machen. Bitte melde daher Fehler und auch sonstige Wünsche an die Admins unter root@oh14.de."
"gremien": [
{
"name": "FSR",
"description": "Fachschaftsrat",
"link": "https://oh14.de/fsr",
"time": "Mittwoch, 12:15 Uhr",
"location": "Chaos-Zentrum-Informatik (OH14 - E39)"
},
{
"name": "FOSS-AG",
"description": "Free and Open Source Software - AG",
"link": "https://foss-ag.de/",
"time": "Montag, 18:00 Uhr",
"location": "Chaos-Zentrum-Informatik (OH14 - E39)"
},
{
"name": "CyberSec-AG",
"description": "Cybersecurity - AG",
"link": "https://oh14.de/cybersec",
"time": "Donnerstag, 18:00 Uhr",
"location": "Chaos-Zentrum-Informatik (OH14 - E39)"
}
]
}
},
{
"type": "placeholder",
"type": "callout",
"position": {
"x": 9,
"y": 5,
"w": 8,
"h": 2
}
},
{
"type": "placeholder",
"position": {
"x": 17,
"y": 5,
"w": 8,
"y": 4,
"w": 16,
"h": 2
},
"config": {
"type": "warning",
"title": "Achtung, Testbetrieb",
"description": "Der neue Infoscreen ist da! Bitte melde Fehler an die Admins unter root@oh14.de."
}
},
{
"type": "mensaplan",
"position": {
"x": 9,
"y": 7,
"y": 6,
"w": 16,
"h": 6
"h": 7
},
"config": {
"canteenId": 341,
......
import React, { useEffect, useRef, useState } from 'react'
import PanelWrapper from "../../meta/PanelWrapper";
import PanelContent from "../../meta/PanelContent";
import PanelTitle from '../../meta/PanelTitle'
import QRCode from "react-qr-code";
import { Clock, MapPin } from '@phosphor-icons/react'
export type GremiumPanelDefinition = {
gremien: [Gremium]
}
type Gremium = {
name: string,
description: string,
link: string,
time: string,
location: string
}
const GremiumPanel = (props: {definition: GremiumPanelDefinition}) => {
const [gremium, setGremium] = useState<Gremium>(props.definition.gremien[0]);
const cycle = useRef<number>(0);
useEffect(() => {
const update = async () => {
setGremium(props.definition.gremien[cycle.current++ % props.definition.gremien.length]);
console.log(gremium);
console.log(cycle.current);
}
update();
const interval = setInterval(update, 20 * 1000);
return () => {
clearInterval(interval);
}
}, []);
return (
<PanelWrapper>
<PanelTitle title={gremium.name}/>
<PanelContent>
<div className={"relative h-full"}>
<div className={"absolute -top-12 right-0 p-1 bg-white rounded"}>
<QRCode value={gremium.link} className={"h-24 w-24"}/>
</div>
<div className={"absolute bottom-0"}>
<p>{gremium.description}</p>
<p className={"text-sm text-gray-400"}>
<Clock size={20} className={"inline mb-1.5 mr-1"}/>
{gremium.time}
</p>
<p className={"text-sm text-gray-400"}>
<MapPin size={20} className={"inline mb-1.5 mr-1"}/>
{gremium.location}
</p>
</div>
</div>
</PanelContent>
</PanelWrapper>
);
};
export default GremiumPanel;
......@@ -10,13 +10,14 @@ import PanelWrapper from "../meta/PanelWrapper";
import BildPanel from "./Bild/BildPanel";
import MensaplanPanel from "./Mensaplan/MensaplanPanel";
import CalloutPanel from "./Callout/CalloutPanel";
import GremiumPanel from "./Gremium/GremiumPanel";
/*
* First, please claim a unique id for your panel here. Convention is that it is all lowercase, in snake-case to be
* precise. So if you want to call your panel "My awesome Panel", please claim "my-awesome-panel". Add it by adding
* `| "my-awesome-panel"` before the semicolon in the type below this comment.
*/
export type PanelTypes = "fahrplan" | "bild" | "mensaplan" | "callout";
export type PanelTypes = "fahrplan" | "bild" | "mensaplan" | "callout" | "gremium";
/*
* Next, add your renderer. You'll get the definition that was written in the layout config as a prop. If you'd like to
......@@ -28,6 +29,7 @@ export const PanelRenderers: {[panelType: string]: React.FC<any & {definition: P
"bild": BildPanel,
"mensaplan": MensaplanPanel,
"callout": CalloutPanel,
"gremium": GremiumPanel,
"placeholder": () => (
<PanelWrapper className={"flex flex-col items-center justify-center text-zinc-400"}>
Dieses Panel wird noch entwickelt
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment