vlw.se/public/contact.php
Victor Westerlund 56cf142e0d refactor: major refactor, design overhaul and merge of Reflect API and Vegvisir sources into the same root (#23)
The PR is a huge refactor of all Reflect and Vegvisir code. I've merged the API and "Front-end" codebases together into the same root, this will allow for both Reflect and Vegvisir to use the same resources. Not only that, but I've also added proper database modeling with actual OOP inheritance for database tables.

Reviewed-on: https://codeberg.org/vlw/vlw.se/pulls/23
2025-02-05 04:49:23 +00:00

130 lines
No EOL
6.1 KiB
PHP

<?php
use Vegvisir\Path;
use VLW\API\{Client, Endpoints};
use VLW\Database\Tables\Messages\MessagesTable;
require_once VV::root("src/API/API.php");
require_once VV::root("src/API/Endpoints.php");
require_once VV::root("src/Database/Tables/Messages/Messages.php");
$date = new class extends DateTimeImmutable {
public function __construct() {
// Set DateTime for configured timezone
parent::__construct("now", new DateTimeZone($_ENV["client_time_available"]["time_zone"]));
}
// Return current hour in 24-hour format
private function hour(): int {
return (int) $this->format("G");
}
// Returns true if current time is between available from and to hours
public function is_available(): bool {
return $this->hour() >= $_ENV["client_time_available"]["available_from_hour"] && $this->hour() < $_ENV["client_time_available"]["available_to_hour"];
}
public function get_estimated_reply_hours(): int {
// I'm available! Return the estimated reply time for that
if ($this->is_available()) {
return $_ENV["client_time_available"]["reply_average_hours"];
}
return $this->hour() < $_ENV["client_time_available"]["available_from_hour"]
// Return hours past midnight until I become available (clamped to estimated reply hours)
? max($_ENV["client_time_available"]["available_from_hour"] - $this->hour(), $_ENV["client_time_available"]["reply_average_hours"])
// Return hours before midnight until I become available (clamped to estimated reply hours)
: max($_ENV["client_time_available"]["available_from_hour"] + (24 - $this->hour()), $_ENV["client_time_available"]["reply_average_hours"]);
}
}
?>
<style><?= VV::css("public/assets/css/pages/contact") ?></style>
<section>
<h1>Let's chat!</h1>
<p>The best way to get in touch is definitely by email, or through the form on this page. The time in Sweden is <i><?= $date->format("h:i a") ?></i> right now, I am currently <?= $date->is_available() ? "available" : "not available" ?> and will hopefully reply in about <?= $date->get_estimated_reply_hours() ?> hours.</p>
</section>
<section class="social">
<a href="mailto:victor@vlw.se"><social>
<?= VV::embed("public/assets/media/icons/email.svg") ?>
<p data-hover>e-mail</p>
</social></a>
<a href="matrix:@vlw:vlw.se"><social>
<?= VV::embed("public/assets/media/icons/matrix.svg") ?>
<p data-hover>matrix</p>
</social></a>
<a href="https://web.libera.chat/#vlw.se"><social>
<?= VV::embed("public/assets/media/icons/libera.svg") ?>
<p data-hover>libera.chat</p>
</social></a>
</section>
<?= VV::embed("public/assets/media/line.svg") ?>
<section class="pgp">
<?= VV::embed("public/assets/media/icons/pin.svg") ?>
<h3>encrypt your message with PGP</h3>
<p>Encryption is great, don't let certain <a href="https://web.archive.org/web/https://www.chatcontrol.eu">short-sighted politicians</a> fool you into thinking encryption is only for criminals. I encourage you to encrypt your message with PGP so we can aid normalization of platform-agnostic encryption for everyone. My key is available via <a href="https://wiki.gnupg.org/WKD" target="_blank" rel="noopener noreferer">WKD</a>, and it's also listed on the <a href="https://keys.openpgp.org/search?q=victor%40vlw.se" target="_blank" rel="noopener noreferer">openPGP key server</a>.</p>
<p>Here's the fingerprint for victor@vlw.se<br><strong class="fingerprint">DCE987311CB5D2A252F58951D0AD730E1057DFC6</strong></p>
<div class="buttons">
<a href="https://keys.openpgp.org/vks/v1/by-fingerprint/DCE987311CB5D2A252F58951D0AD730E1057DFC6"><button class="inline solid download">
<p>download ASC</p>
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
</button></a>
<a href="https://emailselfdefense.fsf.org/en/" target="_blank" rel="noopener noreferer"><button class="inline">
<p>email encryption guide</p>
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
</button></a>
</div>
</section>
<section class="center fade">
<p>And for reference, here is the fingerprint for my "non-personal" address info@vlw.se</p>
<p><strong class="fingerprint">DC603DA049903D707B7F1DB39AF727FB576F5A00</strong></p>
</section>
<?= VV::embed("public/assets/media/line.svg") ?>
<?php // Send message on POST request ?>
<?php if ($_SERVER["REQUEST_METHOD"] === "POST"): ?>
<?php
// Send message via API
$send = (new Client())->call(Endpoints::MESSAGES->value)->post([
MessagesTable::EMAIL->value => $_POST[MessagesTable::EMAIL->value],
MessagesTable::MESSAGE->value => $_POST[MessagesTable::MESSAGE->value]
]);
?>
<?php if ($send->ok): ?>
<section class="form-message sent">
<h3>🙏 Message sent!</h3>
</section>
<?php else: ?>
<?php // Show response body from endpoint as error if request failed ?>
<section class="form-message error">
<h3>😟 Oh no, something went wrong</h3>
<p>Response from API:</p>
<pre><?= $send->output() ?></pre>
</section>
<?php endif; ?>
<?php endif; ?>
<section class="form">
<form method="POST">
<input-group>
<label>your email (optional)</label>
<input type="email" name="<?= MessagesTable::EMAIL->value ?>" placeholder="nissehult@example.com" autocomplete="off"></input>
</input-group>
<input-group>
<label title="this field is required">your message (required)</label>
<textarea name="<?= MessagesTable::MESSAGE->value ?>" required placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed molestie dignissim mauris vel dignissim. Sed et aliquet odio, id egestas libero. Vestibulum ut dui a turpis aliquam hendrerit id et dui. Morbi eu tristique quam, sit amet dictum felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac nibh a ex accumsan ullamcorper non quis eros. Nam at suscipit lacus. Nullam placerat semper sapien, vitae aliquet nisl elementum a. Duis viverra quam eros, eu vestibulum quam egestas sit amet. Duis lobortis varius malesuada. Mauris in fringilla mi. "></textarea>
</input-group>
<button class="inline solid">
<?= VV::embed("public/assets/media/icons/email.svg") ?>
<p>send message</p>
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
</button>
</form>
</section>
<script type="module"><?= VV::js("public/assets/js/pages/contact") ?></script>