Compare commits

...

18 Commits
main ... main

Author SHA1 Message Date
e116fee53a Bump year in Title/Description
All checks were successful
continuous-integration/drone/push Build is passing
2024-11-11 13:53:02 +01:00
a313e09410 Trigger CI
All checks were successful
continuous-integration/drone/push Build is passing
2024-11-09 14:28:19 +01:00
e2e6799f49 update 2024-11-09 13:11:57 +01:00
41598ffa32 fix oopsie 2023-11-28 15:58:48 +01:00
3df1360c66 2k23 2023-11-28 15:33:28 +01:00
95ed928f18 logo
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-21 15:19:36 +01:00
9f643fae78 Update wording
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-21 14:53:17 +01:00
8262e1fa5b SS,SH,FB: text rewriting, tech fixes
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-18 14:55:18 +01:00
171d710bac more info
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-17 15:30:01 +01:00
Mrmaxmeier
2e1f63c5f2 more cleanup
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-15 14:36:42 +01:00
Mrmaxmeier
9a227a1e47 remove workarounds
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-15 14:25:40 +01:00
59901b4c92 kill die react kacke im titel 2.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-14 23:54:46 +01:00
9285d46840 titel
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-14 23:44:12 +01:00
21faf7b043 soprafixes
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-14 23:31:30 +01:00
c25d746ecb looks better now
Some checks failed
continuous-integration/drone/push Build is failing
2022-11-14 23:28:16 +01:00
8a5a7cc732 background maybe but not maybe
Some checks failed
continuous-integration/drone/push Build is failing
2022-11-14 22:30:20 +01:00
303aa556cf compiles locally and somewhat works locally
Some checks failed
continuous-integration/drone/push Build is failing
2022-11-14 21:20:26 +01:00
Dominic Zimmer
45f6c958fe Pipeline test
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-14 16:24:09 +01:00
15 changed files with 249 additions and 62 deletions

1
boobs Normal file
View File

@ -0,0 +1 @@
aaaa

View File

@ -3,6 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.2.0",
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@ -10,6 +13,7 @@
"@types/node": "^16.11.64",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"fortawesome": "^0.0.1-security",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",

BIN
public/background.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
public/background.mp4 Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -3,11 +3,12 @@
<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"
content="Weihnachtsfeier 2024"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
@ -24,7 +25,7 @@
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>React App</title>
<title>Weihnachtsfeier 2024</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,6 +1,6 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "Weihnachtsfeier",
"name": "Weihnachtsfeier 2023",
"icons": [
{
"src": "favicon.ico",

View File

@ -41,8 +41,7 @@ export const PartyContextProvider: React.FC<{ children: React.ReactNode }> = (pr
const [partyContext, setPartyContext] = useState<PartyContextType>();
const apiEndpoint = useMemo<APIEndPoint>(() => {
// eslint-disable-next-line no-restricted-globals
const href = location.href;
const href = window.location.href;
const p = parseURI(href);
if (!p) return { partyName: "error", token: "" }
return p;

View File

@ -1,44 +1,110 @@
.loading {
height: 100vh;
width: 100vw;
background-color: black;
height: 100vh;
width: 100vw;
background-color: black;
}
.App {
color: white;
font-size: calc(7px + 2vmin);
text-shadow:
-1px -1px 0.2em #000,
1px -1px 0.2em #000,
-1px 1px 0.2em #000,
1px 1px 0.2em #000;
text-align: center;
display: flex;
justify-content: center;
}
.container {
max-width: 1224px;
margin-left: 3ch;
margin-right: 3ch;
}
.fullheight {
min-height: 100vh;
}
.hero {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.hero-outer {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding-bottom: 0.5em;
}
@media (min-width: 1024px) {
.hero-outer {
justify-content: flex-end;
}
}
h1,
h2 {
margin: 1em 0 0.1em 0;
}
p {
margin: 0.3em 0 0.3em 0;
}
.feedback {
line-height: 3em;
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
input[type="radio"] {
display: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
input[type="radio"]+label {
font-size: larger;
cursor: pointer;
padding: 0 1em 0 1em;
border-right: 0.1em solid white;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
input[type="radio"]+label:hover {
text-shadow: 0 0 1em white;
}
input[type="radio"]+label:last-of-type {
border-right: none;
}
input[type="radio"]:checked+label {
color: var(--selected-color);
text-shadow: 0 0 1em var(--selected-color);
text-decoration: underline;
}
#coming-yes+label {
--selected-color: #0f0;
}
#coming-maybe+label {
--selected-color: #fc0;
}
#coming-no+label {
--selected-color: #f00;
}
.hooverdam:hover {
text-shadow: 0 0 1em white;
}
a {
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}

View File

@ -1,27 +1,127 @@
import React, { useContext } from 'react';
import logo from './logo.svg';
import React, { ChangeEvent, useContext, useRef, useState } from 'react';
import './PartyPage.css';
import { PartyContext } from './PartyContext';
import { APIEndPoint, PartyContext, PartyStatus } from './PartyContext';
// import MatrixBackground from './MatrixBackground';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleDown, faCalendarDays, faLocationDot } from '@fortawesome/free-solid-svg-icons';
import { modifySelfRequest, parseURI } from './partyApi';
const myDear = {
"m": "lieber",
"f": "liebe",
"d": "liebes",
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getComingString(party: PartyStatus): string {
if (party.maybe_coming === 0) {
// exact number
if (party.definitely_coming === 0) {
return "Bisher hat noch niemand zugesagt."
} else if (party.definitely_coming === 1) {
return "Bisher hat ein Gast zugesagt."
} else {
return `Es haben schon ${party.definitely_coming} Gäste zugesagt.`
}
} else {
// inexact
if (party.definitely_coming === 0 && party.maybe_coming === 1) {
return "Bisher hat ein Gast vorläufig zugesagt."
} else if (party.definitely_coming === 0) {
return `Bisher haben ${party.maybe_coming} Gäste vorläufig zugesagt.`
} else {
return `Nach den bisherigen Zusagen kommen ${party.definitely_coming} bis ${party.definitely_coming + party.maybe_coming} Gäste.`
}
}
}
export const PartyPage: React.FC = () => {
const partyContext = useContext(PartyContext);
return <div className="App" >
<header className="App-header" >
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code> src/PartyPage.tsx </code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<span>Hello {partyContext.self.name}</span>
</header>
const dear = myDear[partyContext.self.grammatical_gender];
const name = partyContext.self.name;
const wannUndWoRef = useRef<HTMLDivElement>(null)
const executeScroll = () => {
wannUndWoRef.current!.scrollIntoView({ behavior: 'smooth' })
}
const [comingState, setComingState] = useState(partyContext.self.coming);
// SAFETY: If this is undefined, the contextProvider already fails
const endpoint = parseURI(window.location.href) as APIEndPoint;
const handleSelect = async (e: ChangeEvent) => {
const value = (e.target as HTMLInputElement).value;
if (value !== "yes" && value !== "no" && value !== "maybe") {
throw new Error("received invalid value?");
}
const status = await modifySelfRequest(endpoint, { coming: value });
setComingState(status.coming);
}
return <div className="App">
<div className='container'>
<div className='hero fullheight'>
<div className='hero-outer'></div>
<h1>Hallo {dear} {name},</h1>
<p>
am <strong>Freitag, den 13. Dezember</strong> wird in diesem Jahr (hoffentlich) nicht viel Unglück passieren.
</p>
<p>
Wir veranstalten nämlich ab <strong> 19:00 </strong> eine Weihnachtsparty!
</p>
<p>
Wir würden uns sehr freuen, wenn auch du, {dear} {name}, dabei bist :)
</p>
<div className='feedback'>
<input type="radio" id="coming-yes" name="coming" value="yes" checked={comingState === "yes"} onChange={handleSelect} />
<label htmlFor='coming-yes'>Ja</label>
<input type="radio" id="coming-maybe" name="coming" value="maybe" checked={comingState === "maybe"} onChange={handleSelect} />
<label htmlFor='coming-maybe'>Vielleicht</label>
<input type="radio" id="coming-no" name="coming" value="no" checked={comingState === "no"} onChange={handleSelect} />
<label htmlFor='coming-no'>Nein</label>
</div>
<div className='hero-outer' >
<span className='hooverdam' onClick={executeScroll}>
<p>Mehr Infos</p>
<FontAwesomeIcon icon={faAngleDown} />
</span>
</div>
</div>
<div className='hero fullheight' ref={wannUndWoRef}>
<h2>Wann und Wo?</h2>
<p>
<FontAwesomeIcon icon={faCalendarDays} /> <strong>&nbsp;13. Dezember, ab 19:00</strong>. Bitte kommt nicht all zu spät.
</p>
<p>
<FontAwesomeIcon icon={faLocationDot} /> <strong>&nbsp;Gebäude E1 1, Raum 407</strong>, Universität des Saarlandes
</p>
<h2>Was ist geplant?</h2>
<p>
Wir (Sebastian &amp; Simon) wollen uns mit euch auf Weihnachten einstimmen.
Wir planen ein weihnachtliches Programm mit Geschichten, Liedern, Essen und der einen oder anderen Überraschung. Falls du ein Instrument spielst, bring es auch gerne mit.
</p>
<p>
Natürlich haben wir auch genügend Zeit, uns gemütlich bei einem Heißgetränk zu unterhalten.
</p>
<h2>Was gibt es zu Essen?</h2>
<p>
Wir planen ein Potluck-Event. Damit sollte für alle genug Essen dabei sein.
Getränke, insbesondere Glühwein, Kinderpunsch und Ähnliches, wird von uns organisiert.
</p>
<h2>Was soll ich mitbringen?</h2>
<p>
Es wäre super, wenn du zum Potluck ein Gericht mitbringen kannst. Für Inspirationen kannst du uns natürlich gerne fragen, oder schon einmal <a href="https://www.tasteofhome.com/collection/vegetarian-potluck-recipes/">hier</a> vorbeischauen.
Bitte informiere uns kurz, was du gerne mitbringen würdest, damit wir besser kalkulieren können.
Ansonsten darfst du auch sehr gerne Plätzchen, Weihnachtsdeko oder Ähnliches mitbringen.
</p>
<p>
Falls du ansonsten Wünsche oder Anregungen für einen gelungenen Abend hast, teil uns diese gerne mit!
</p>
</div>
</div>
</div>
};

BIN
src/background.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -10,4 +10,15 @@ body {
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
}
body {
background-image: url('./background.gif');
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 100vh;
padding:0;
margin:0;
}

View File

@ -1,16 +1,21 @@
import { APIEndPoint, PartyStatus, SelfStatus, UpdatableSelfStatus } from "./PartyContext";
export const parseURI = (uri: string): APIEndPoint | undefined => {
const x = uri.match(/https?:\/\/(?<partyName>.+)\.party\.leafbla\.de\/(?<token>.+)/);
// const x = uri.match(/https?:\/\/(?<partyName>.+)\.party\.leafbla\.de\/(?<token>.+)/);
const x = uri.match(/https?:\/\/[^/]+\/(?<token>.+)/);
if (x === null || x.groups === undefined) return;
const partyName = x.groups["partyName"];
// const partyName = x.groups["partyName"];
const partyName = "xmas";
const token = x.groups["token"];
if (!partyName || !token) return;
return { partyName, token };
};
const apiUrl = (apiEndPoint : APIEndPoint): string => {
return `https://party.leafbla.de/api/${apiEndPoint.partyName}/${apiEndPoint.token}`;
let a = `https://party.leafbla.de/api/${apiEndPoint.partyName}/${apiEndPoint.token}`;
console.log(a);
return a;
};
export const getSelfStatusRequest = async (apiEndpoint: APIEndPoint): Promise<SelfStatus> => {