Basic polls display + UI work

v1.2.0
aymm 2021-03-27 20:37:17 +01:00
parent 64b2e9e685
commit ac27c87c59
Signed by: phlaym
GPG Key ID: A06651BAB6777237
9 changed files with 199 additions and 32 deletions

View File

@ -3,6 +3,7 @@
require __DIR__ .'/vendor/autoload.php';
use APnutI\APnutI;
use Monolog\Logger;
session_start();
$config = include(__DIR__.'/config.php');
@ -12,5 +13,8 @@ $api = new APnutI(
$config['permission_scopes'],
$config['app_name'],
$config['callback_url'],
__DIR__.'/'.$config['log_file']
__DIR__.'/'.$config['log_file'],
$config['log_level']
);
require_once __DIR__ . '/globals.php';

2
composer.lock generated
View File

@ -12,7 +12,7 @@
"dist": {
"type": "path",
"url": "../APnutI",
"reference": "99eee326abe217a901fbc6f8415e70f64bcb5959"
"reference": "c2434cfedcd88d729408ebfffc868d064260cbf1"
},
"require": {
"ext-curl": "*",

View File

@ -4,6 +4,7 @@ return [
'client_id' => '',
'client_secret' => '',
'log_file' => '../../logs/Dragonpolls.log', // Relative to index.php
'log_level' => 'INFO',
'app_name' => 'Playground',
'callback_url' => 'http://localhost/auth_callback.php',
'permission_scopes' => 'basic' //comma seperated string

50
globals.php Normal file
View File

@ -0,0 +1,50 @@
<?php
function jslog($obj)
{
global $config;
if (!($config['log_level'] == 'DEBUG' || $config['log_level'] === Logger::DEBUG)) {
return;
}
echo '<script>console.log('.json_encode($obj).');</script>';
}
function get_page_header(
?string $page_title = null,
bool $include_app_name = true,
array $scripts = []
): string {
global $api;
$greeting = '';
$logout_link = '';
if ($api->isAuthenticated(false, true)) {
$u = $api->getAuthorizedUser();
$greeting = 'Welcome, ' . ($u->name ?? '@'.$u->username);
$logout_link = '<a href="logout.php" class="logout">Logout</a>';
} else {
$greeting = '<a href="' . $api->getAuthURL() . '">Login with pnut</a>';
}
$title = '';
if ($include_app_name) {
$title = $api->app_name;
}
if (!empty($page_title)) {
$title .= $include_app_name ? ' > ' : '';
$title .= $page_title;
}
$script_str = '';
foreach ($scripts as $script) {
//$script_str .= '<link rel="script" href="scripts/' . $script . '.js">';
$script_str .= '<script src="scripts/' . $script . '.js">';
}
return '<html><head><meta charset="utf-8"><title>'.$title.'</title><link rel="stylesheet" href="styles/style.css">'
. $script_str
. '</head><body><header>'
. '<a href="index.php" class="homelink" title="Home"><div class="linkcontents">'
. file_get_contents(__DIR__.'/icons/home.svg')
. '<span class="linklabel">Home</span></div></a>'
. $greeting
. '<div class="spacer"></div>'
. $logout_link
. '</header>';
}

5
icons/home.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
<g transform="matrix(1.66314,0,0,1.66314,-16.8693,-35.7851)">
<path d="M31.997,73.06L14.734,73.06L70.27,29.643L125.806,73.06L108.544,73.06L108.544,133.645L31.997,133.645L31.997,73.06Z" style="fill:none;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 535 B

View File

@ -2,10 +2,4 @@
require_once __DIR__ .'/bootstrap.php';
$is_authenticated = $api->isAuthenticated();
if (!$is_authenticated) {
echo '<a href="' . $api->getAuthURL() . '">Login with pnut</a>';
} else {
$u = $api->getAuthorizedUser();
echo 'Welcome @'.$u->username;
}
echo get_page_header();

10
scripts/poll.js Normal file
View File

@ -0,0 +1,10 @@
window.addEventListener('DOMContentLoaded', (event) => {
displayLocalTimestamps();
});
function displayLocalTimestamps() {
for (const el of document.getElementsByTagName('time')) {
let dateObj = new Date(el.getAttribute('datetime'));
el.innerText = dateObj.toLocaleString();
}
}

91
styles/style.css Normal file
View File

@ -0,0 +1,91 @@
/* Globals */
:root {
--main-bg-color: rgb(48, 48, 48);
--secondary-bg-color: rgba(10, 10, 10, 0.7);
--main-fg-color: white;
--main-accent-color: rgb(253, 122, 0)
}
@supports (color: color(display-p3 1 1 1)) {
:root {
--main-accent-color: color(display-p3 0.927 0.506 0.028)
}
}
a:visited, a {
color: var(--main-accent-color);
}
a svg {
stroke: var(--main-accent-color);
width: 1.5em;
height: 1.5em;
stroke-width: 0.5em;
}
body {
background: var(--main-bg-color);
color: var(--main-fg-color);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
/* Header */
header {
display: flex;
align-items: center;
padding: 8px;
margin-bottom: 8px;
background: var(--secondary-bg-color);
}
.spacer {
flex-grow: 1;
}
.linklabel {
margin-left: 0.1em;
}
.linkcontents {
display: flex;
align-items: center;
}
.homelink {
margin-right: 1em;
}
/* Polls */
.poll {
display: inline-block;
}
.poll .header {
/*display: flex;
align-items: center;*/
margin-bottom: 8px;
}
.poll .user {
display: flex;
align-items: center;
margin-bottom: 4px;
}
.poll .user .avatar {
margin-right: 8px;
}
.datewrapper {
display: grid;
grid-column-gap: 8px;
}
.created_at {
grid-row: 1;
}
.closed_at {
grid-row: 2;
}
datewrapper time {
grid-column: 2;
}

View File

@ -9,17 +9,14 @@ use APnutI\Exceptions\NotAuthorizedException;
use APnutI\Exceptions\PollAccessRestrictedException;
use APnutI\Entities\Poll;
echo get_page_header('Poll', true, ['poll']);
if (empty($_GET['id']) || !is_numeric($_GET['id']) || $_GET['id'] <= 0) {
die('Invalid poll ID');
}
$poll_id = (int)$_GET['id'];
$poll = null;
if ($api->isAuthenticated()) {
$user = $api->getAuthorizedUser();
echo 'Welcome ' . ($user->name ?? $user->username) . '<br>';
}
try {
$poll_token = array_key_exists('polltoken', $_GET) ? $_GET['polltoken'] : null;
$poll = $api->getPoll($poll_id, $poll_token);
@ -39,30 +36,45 @@ try {
);
}
#echo json_encode($poll);
#$user_avatar_url = $api->getAvatarUrl($poll->user->id, 50);
$user_avatar_url = $poll->user->getAvatarUrl(50);
#$prompt = '@' . $poll->user->username . ' asks: ' . $poll->prompt;
$username = '@' . $poll->user->username;
#echo '<img src="'.$user_avatar_url.'"/>';
#echo $prompt;
$disabled = $poll->canVote() ? '' : 'disabled';
$user_name = $poll->user->name ?? '';
$created_at = $poll->created_at;
$closed_at = $poll->closed_at;
jslog('teyt');
?>
<div class="poll">
<div class="header">
<img src="<?= $user_avatar_url ?>" />
<span class="username"><?= $username ?></span> asks:
<span class="prompt"><?= $poll->prompt ?></span>
<div class="options">
<?php
foreach ($poll->options as $option) {
$checked = $option->is_your_response ? 'checked' : ''; ?>
<div class="options">
<input type="checkbox" <?= $checked.' '.$disabled ?>/>
<span class="option-text"><?= $option->text ?></span>
</div>
<?php } ?>
<div class="user">
<img src="<?= $user_avatar_url ?>" class="avatar"/>
<div class="usernames">
<b><?= $user_name.'<br>' ?></b>
<span class="username"><a href="http://pnut.io/<?= $username ?>"><?= $username ?></a></span>
</div>
<div class="spacer"></div>
<div class="datewrapper">
<span class="created_at">Created</span>
<span class="closed_at"><?= $poll->isClosed() ? 'Closed' : 'Closing' ?></span>
<time class="created_at" datetime="<?= $created_at->format(\DateTime::ISO8601) ?>">
<?= $created_at->format('Y-m-d, H:i:s e') ?>
</time>
<time class="closed_at" datetime="<?= $closed_at->format(\DateTime::ISO8601) ?>">
<?= $closed_at->format('Y-m-d, H:i:s e') ?>
</time>
</div>
</div>
<span class="prompt"><em><?= $poll->prompt ?></em></span>
</div>
<div class="options">
<?php
foreach ($poll->options as $option) {
$checked = $option->is_your_response ? 'checked' : ''; ?>
<div class="options">
<input type="checkbox" <?= $checked.' '.$disabled ?>/>
<span class="option-text"><?= $option->text ?></span>
</div>
<?php } ?>
</div>
</div>
<?= json_encode($poll);?>