Adrian Heine
2 years ago
commit
791a522579
1 changed files with 322 additions and 0 deletions
-
322index.php
@ -0,0 +1,322 @@ |
|||||
|
<?php |
||||
|
$config = require_once './config.php'; |
||||
|
$START_DATE = $config['start_date']; |
||||
|
$EVENTS = $config['events']; |
||||
|
|
||||
|
if ($_SERVER['REQUEST_METHOD'] == "POST") { |
||||
|
$n = 0; |
||||
|
do { |
||||
|
$file_name = $config['data_dir'] . "/" . time(); |
||||
|
$file = fopen($file_name, "x"); |
||||
|
} while ($file === false && ++$n < 5); |
||||
|
if (!$file || !fwrite($file, var_export($_POST, true))) { |
||||
|
echo "Leider konnte deine Anmeldung nicht gespeichert werden. Bitte melde dich bei luetzi-vernetzung-bb@systemli.org damit wir den Fehler beheben können!"; |
||||
|
exit; |
||||
|
} |
||||
|
echo "Danke für deine Anmeldung."; |
||||
|
if ($_POST['email']) { |
||||
|
echo " Wir schreiben dir eine E-Mail falls der Solibus in einem von dir gewählten Zeitraum fährt."; |
||||
|
} |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
$ONE_DAY = new DateInterval("P1D"); |
||||
|
|
||||
|
function get_days_of_week() { |
||||
|
global $ONE_DAY; |
||||
|
$res = []; |
||||
|
$date = (new DateTime())->setTimestamp(strtotime("this week")); |
||||
|
for ($n = 0; $n < 7; ++$n) { |
||||
|
$res[] = IntlDateFormatter::formatObject($date, "ccc"); |
||||
|
$date->add($ONE_DAY); |
||||
|
} |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
$DAYS_OF_WEEK = get_days_of_week(); |
||||
|
|
||||
|
function print_month($start) { |
||||
|
global $DAYS_OF_WEEK, $ONE_DAY, $EVENTS; |
||||
|
$month_start = (new DateTimeImmutable())->setTimestamp(strtotime("first day of this month", $start->getTimestamp())); |
||||
|
$week_start = (new DateTimeImmutable())->setTimestamp(strtotime("this week", $month_start->getTimestamp())); |
||||
|
$month_end = (new DateTimeImmutable())->setTimestamp(strtotime("+1 month", $month_start->getTimestamp())); |
||||
|
$month_name = IntlDateFormatter::formatObject($month_start, "MMMM yyyy"); |
||||
|
?><table class=month>
|
||||
|
<caption><h3><?= $month_name ?></caption>
|
||||
|
<tr><?php foreach ($DAYS_OF_WEEK as $day) { echo "<th>$day</th>"; }?></tr>
|
||||
|
<?php |
||||
|
$date = DateTime::createFromInterface($week_start); |
||||
|
while ($date->diff($month_end)->invert == 0) { |
||||
|
echo "<tr>"; |
||||
|
for ($n = 0; $n < 7; ++$n) { |
||||
|
$invalid = $start->diff($date)->invert == 1 || $month_end->diff($date)->invert == 0; |
||||
|
echo "<td" . ($invalid ? " class=invalid" : "") . ">"; |
||||
|
$label = IntlDateFormatter::formatObject($date, "dd"); |
||||
|
if ($invalid) { |
||||
|
echo $label; |
||||
|
} else { |
||||
|
$id = IntlDateFormatter::formatObject($date, "yyyy-MM-dd"); |
||||
|
echo "<input type=checkbox name=\"date_$id\" id=\"date_$id\"><label for=\"date_$id\">$label";
|
||||
|
if (isset($EVENTS[$id])) { |
||||
|
echo "<div class=event><div class=event-content>".htmlspecialchars($EVENTS[$id])."</div></div>"; |
||||
|
} |
||||
|
echo "</label>"; |
||||
|
} |
||||
|
echo "</td>"; |
||||
|
$date->add($ONE_DAY); |
||||
|
} |
||||
|
} |
||||
|
?>
|
||||
|
</table><?php |
||||
|
} |
||||
|
|
||||
|
?><!DOCTYPE html>
|
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
|
<style> |
||||
|
body { |
||||
|
margin: 0 |
||||
|
} |
||||
|
footer { |
||||
|
border-top: 0.3em dashed #722CA2;
|
||||
|
padding: 1em 1em 0 1em; |
||||
|
background: #f1cc37;
|
||||
|
color: #5A4B0B;
|
||||
|
padding: 1em 0; |
||||
|
} |
||||
|
main { |
||||
|
background: #FFE98E;
|
||||
|
padding: 1em 0; |
||||
|
} |
||||
|
header { |
||||
|
border-bottom: 0.3em dashed #722CA2;
|
||||
|
background: #f1cc37;
|
||||
|
color: #5A4B0B;
|
||||
|
padding: 1em 0; |
||||
|
} |
||||
|
h1 { |
||||
|
margin: 0 |
||||
|
} |
||||
|
footer > *, |
||||
|
header > *, |
||||
|
main > * { |
||||
|
margin: 0 auto; |
||||
|
max-width: 80rem; |
||||
|
padding: 0 1rem; |
||||
|
} |
||||
|
.month { |
||||
|
display: inline-block; |
||||
|
vertical-align: top; |
||||
|
margin-right: 2em; |
||||
|
border-spacing: 0; |
||||
|
} |
||||
|
.month tbody { |
||||
|
border-radius: 0.3em; |
||||
|
color: #5A4B0B;
|
||||
|
} |
||||
|
.month tbody, |
||||
|
.row > input, |
||||
|
.row > select { |
||||
|
box-shadow: .4em .5em 0 0 RGBA(114, 44, 162,0.5); |
||||
|
} |
||||
|
.month ::selection { |
||||
|
background: inherit; |
||||
|
} |
||||
|
.month th, .month td { |
||||
|
width: 3.5em; |
||||
|
height: 3.5em; |
||||
|
border: 1px solid #CBC19A;
|
||||
|
border-width: 1px 0 0 1px; |
||||
|
text-align: center; |
||||
|
padding: 0; |
||||
|
background: white; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.month th:first-of-type { |
||||
|
border-top-left-radius: 0.3em; |
||||
|
} |
||||
|
.month th:last-of-type { |
||||
|
border-top-right-radius: 0.3em; |
||||
|
} |
||||
|
.month tr > :last-of-type { |
||||
|
border-right-width: 1px; |
||||
|
} |
||||
|
.month tr:last-of-type td:first-of-type { |
||||
|
border-bottom-left-radius: 0.3em; |
||||
|
} |
||||
|
.month tr:last-of-type td:last-of-type { |
||||
|
border-bottom-right-radius: 0.3em; |
||||
|
} |
||||
|
.month tr:last-of-type td { |
||||
|
border-bottom-width: 1px; |
||||
|
} |
||||
|
|
||||
|
.month input[type=checkbox] { |
||||
|
appearance: none; |
||||
|
position: absolute |
||||
|
} |
||||
|
.month label { |
||||
|
display: block; |
||||
|
line-height: 3.5em; |
||||
|
} |
||||
|
.month :focus + label { |
||||
|
border: 1px solid #722CA2;
|
||||
|
margin: -1px; |
||||
|
} |
||||
|
:checked + label { |
||||
|
background: #f1cc37;
|
||||
|
} |
||||
|
.invalid { |
||||
|
color: #CBC19A;
|
||||
|
} |
||||
|
@media only screen and (max-width: 55em) { |
||||
|
.month { |
||||
|
margin-right: 1.5vw; |
||||
|
} |
||||
|
.month th, .month td { |
||||
|
width: 6vw; |
||||
|
} |
||||
|
} |
||||
|
@media only screen and (max-width: 40em) { |
||||
|
.month { |
||||
|
margin: 0 auto; |
||||
|
display: table; |
||||
|
} |
||||
|
.month th, .month td { |
||||
|
width: 3.5em; |
||||
|
} |
||||
|
} |
||||
|
.event { |
||||
|
position: relative; |
||||
|
top: -3.5em; |
||||
|
right: -0.9em; |
||||
|
line-height: initial; |
||||
|
} |
||||
|
.event::before { |
||||
|
content: "★"; |
||||
|
position: absolute; |
||||
|
padding: 0.5em; |
||||
|
top: -0.5em; |
||||
|
right: 0.5em; |
||||
|
} |
||||
|
.event-content { |
||||
|
visibility: hidden; |
||||
|
position: absolute; |
||||
|
background: white; |
||||
|
top: 0.4em; |
||||
|
left: 1.8em; |
||||
|
padding: 0.4em; |
||||
|
border: 1px solid #CBC19A;
|
||||
|
border-radius: 0.2em; |
||||
|
box-shadow: .2em .25em 0 0 RGBA(114, 44, 162,0.5); |
||||
|
z-index: 1; |
||||
|
} |
||||
|
.month :focus + label .event-content, |
||||
|
.month td:hover .event-content, |
||||
|
.month td:active .event-content { |
||||
|
visibility: initial; |
||||
|
} |
||||
|
|
||||
|
.row { |
||||
|
display: block; |
||||
|
margin: 1em 0; |
||||
|
} |
||||
|
.row > input, |
||||
|
.row > select { |
||||
|
padding: 0.5rem; |
||||
|
margin-right: 1rem; |
||||
|
width: 12rem; |
||||
|
box-sizing: border-box; |
||||
|
border: 1px solid #5A4B0B;
|
||||
|
border-radius: .3em; |
||||
|
} |
||||
|
.row > input[type="number"] { |
||||
|
margin-left: 8.5rem; |
||||
|
width: 3.5rem; |
||||
|
} |
||||
|
.row > input[type="submit"] { |
||||
|
background: #f1cc37;
|
||||
|
} |
||||
|
.row > input[type="submit"]:active { |
||||
|
background: white; |
||||
|
} |
||||
|
.row :focus-visible { |
||||
|
outline: 0.2em #722CA2 solid;
|
||||
|
} |
||||
|
|
||||
|
</style> |
||||
|
<script> |
||||
|
let checking = null |
||||
|
addEventListener("selectstart", (event) => { |
||||
|
let target = event.target |
||||
|
if (target.nodeType == 3) target = target.parentNode |
||||
|
if (target.tagName == "LABEL") { |
||||
|
const checkbox = document.getElementById(target.htmlFor) |
||||
|
checking = !checkbox.checked |
||||
|
checkbox.checked = checking |
||||
|
} else checking = null |
||||
|
}); |
||||
|
document.addEventListener('selectionchange', () => { |
||||
|
if (checking !== null) { |
||||
|
const range = document.getSelection().getRangeAt(0) |
||||
|
const treeWalker = document.createTreeWalker( |
||||
|
range.commonAncestorContainer, |
||||
|
NodeFilter.SHOW_ELEMENT, |
||||
|
{ acceptNode: (node) => node.nodeName.toLowerCase() === 'input' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP } |
||||
|
) |
||||
|
while (currentNode = treeWalker.nextNode()) { |
||||
|
if (range.intersectsNode(currentNode)) currentNode.checked = checking; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
document.addEventListener('pointerup', () => { |
||||
|
if (checking !== null) { |
||||
|
checking = null |
||||
|
document.getSelection().empty() |
||||
|
} |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<header> |
||||
|
<h1>Soli-Bus-Fahrten von Berlin nach Lützerath</h1> |
||||
|
</header> |
||||
|
<main> |
||||
|
<form method=post> |
||||
|
<p> |
||||
|
Der <a href="https://www.soli-bus.org/">Soli-Bus</a> fährt mit uns nach Lützerath, wenn genug Leute es wollen. Wir brauchen eure Hilfe, um einschätzen zu können, wann es sich lohnt, eine Busfahrt zu organisieren. |
||||
|
</p> |
||||
|
<p> |
||||
|
Zur groben Einordnung: Eine Fahrt dauert rund 9 Stunden und kostet pro Person 20€ (an Betriebskosten). Der Bus fährt üblicherweise einige Tage später auch zurück. Wir können euch ggf. in einigen Städten auf dem Weg einsammeln oder sogar vorher aus Leipzig abholen. |
||||
|
</p> |
||||
|
|
||||
|
<h2>Termine</h2> |
||||
|
<p>Bitte markier alle Tage im Kalender, an denen du mit dem Soli-Bus nach Lützerath fahren oder dort sein wollen würdest. </p> |
||||
|
<?php |
||||
|
|
||||
|
$start = (new DateTimeImmutable())->setTimestamp(mktime(0, 0, 0, $START_DATE[1], $START_DATE[2], $START_DATE[0])); |
||||
|
print_month($start); |
||||
|
$month_end = (new DateTimeImmutable())->setTimestamp(strtotime("first day of next month", $start->getTimestamp())); |
||||
|
print_month($month_end); |
||||
|
$month_end = (new DateTimeImmutable())->setTimestamp(strtotime("first day of next month", $month_end->getTimestamp())); |
||||
|
print_month($month_end); |
||||
|
|
||||
|
?>
|
||||
|
<h3>Tag X</h3> |
||||
|
<label><input type=checkbox name=tagx>Ich möchte im Fall eines Räumungsversuchs mit dem Solibus nach Lützerath fahren.</label> |
||||
|
<h2>Kontaktmöglichkeiten</h2> |
||||
|
<p> |
||||
|
Alle Angaben sind freiwillig. Sie werden nur gespeichert, um euch zu kontaktieren, falls ein Bus im von euch gewählten Zeitraum fährt. |
||||
|
</p> |
||||
|
<label class=row><input name=name placeholder=Feldmaus>Dein Name (gerne ein Waldname oder anderes Pseudonym)</label> |
||||
|
<label class=row><input name=email type=email placeholder=feldmaus@posteo.de>Deine E-Mail-Adresse</label> |
||||
|
<h2>Allgemeines</h2> |
||||
|
<label class=row><input name=count type=number value=1>Wie viele seid ihr?</label> |
||||
|
<label class=row><select name=city><option>Berlin</option><option>Potsdam</option><option>Magdeburg<option>Braunschweig<option>Hannover<option>Leipzig</select>Deine Stadt</label> |
||||
|
<p class=row><input type=submit value=Abschicken> |
||||
|
</form> |
||||
|
</main> |
||||
|
<footer> |
||||
|
<p> |
||||
|
Ein Angebot der Berlin-Lützerath-Vernetzung, erreichbar über luetzi-vernetzung-bb [at] systemli.org. |
||||
|
</p> |
||||
|
</footer> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue