Initial commit
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
## IDE ##
|
||||
.idea/
|
||||
|
||||
## Composer ##
|
||||
vendor/
|
||||
composer.lock
|
||||
|
||||
## App ##
|
||||
db/
|
18
composer.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "madeorsk/poll-verlaine",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"mikecao/flight": "^1.3"
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Madeorsk",
|
||||
"email": "madeorsk@protonmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Tagada",
|
||||
"email": "madeorsk@protonmail.com"
|
||||
}
|
||||
]
|
||||
}
|
50
index.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
require __DIR__ . "/vendor/autoload.php";
|
||||
require __DIR__ . "/models/Poll.php";
|
||||
|
||||
function format_poll($poll)
|
||||
{
|
||||
return [
|
||||
"id" => $poll->id,
|
||||
"title" => $poll->title,
|
||||
"creation_date" => $poll->creation_date,
|
||||
"options" => $poll->options,
|
||||
];
|
||||
}
|
||||
|
||||
Flight::route("POST /polls", function () {
|
||||
$request = Flight::request();
|
||||
if ($request->type === "application/json")
|
||||
{
|
||||
$request_json = $request->data;
|
||||
$poll = Poll::create_poll($request_json);
|
||||
if ($poll)
|
||||
Flight::json(format_poll($poll));
|
||||
else
|
||||
Flight::halt(403, "<h1>403 Forbidden</h1><h3>Invalid data.</h3>");
|
||||
}
|
||||
else
|
||||
Flight::halt(403, "<h1>403 Forbidden</h1><h3>Invalid Content-Type.</h3>");
|
||||
});
|
||||
Flight::route("GET /polls/@id:[a-fA-F0-9]+", function ($id) {
|
||||
$poll = Poll::load_poll($id);
|
||||
if ($poll)
|
||||
{
|
||||
if (Flight::request()->type === "application/json")
|
||||
Flight::json(format_poll($poll));
|
||||
else
|
||||
{
|
||||
Flight::render("poll", ["poll" => $poll], "body_content");
|
||||
Flight::render("layout");
|
||||
}
|
||||
}
|
||||
else
|
||||
Flight::notFound();
|
||||
});
|
||||
|
||||
Flight::route("/", function () {
|
||||
Flight::render("home", [], "body_content");
|
||||
Flight::render("layout");
|
||||
});
|
||||
|
||||
Flight::start();
|
94
models/Poll.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
define("SAVE_PATH", __DIR__ . "/../db");
|
||||
|
||||
class Poll
|
||||
{
|
||||
/**
|
||||
* Create a new poll and save it.
|
||||
*/
|
||||
public static function create_poll($request_data)
|
||||
{
|
||||
try
|
||||
{
|
||||
$poll = new Poll();
|
||||
$poll->title = $request_data->title;
|
||||
$poll->creation_date = (new DateTime())->getTimestamp();
|
||||
$id = 0;
|
||||
foreach ($request_data->options as $option)
|
||||
{
|
||||
$poll->options[] = [
|
||||
"id" => $id,
|
||||
"label" => $option,
|
||||
"votes" => 0,
|
||||
];
|
||||
$id++;
|
||||
}
|
||||
$poll->gen_new_id();
|
||||
$poll->save();
|
||||
return $poll;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load an existing poll.
|
||||
* @param string id - Poll ID.
|
||||
* @return boolean|Poll - Requested poll if found, false otherwise.
|
||||
*/
|
||||
public static function load_poll($id)
|
||||
{
|
||||
$db = dba_open(SAVE_PATH . "/polls.db", "rd");
|
||||
|
||||
if (dba_exists($id, $db))
|
||||
{
|
||||
$poll = new Poll();
|
||||
$saved_poll_data = json_decode(dba_fetch($id, $db));
|
||||
$poll->id = $id;
|
||||
$poll->title = $saved_poll_data->title;
|
||||
$poll->creation_date = $saved_poll_data->creation_date;
|
||||
$poll->options = $saved_poll_data->options;
|
||||
|
||||
dba_close($db);
|
||||
return $poll;
|
||||
}
|
||||
else
|
||||
{
|
||||
dba_close($db);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public $id = null;
|
||||
public $title;
|
||||
public $creation_date;
|
||||
public $options = [];
|
||||
|
||||
public function gen_new_id()
|
||||
{
|
||||
$db = dba_open(SAVE_PATH . "/polls.db", "rd");
|
||||
|
||||
function gen_id()
|
||||
{ return bin2hex(openssl_random_pseudo_bytes(16)); }
|
||||
|
||||
do
|
||||
{ $new_id = gen_id(); }
|
||||
while(dba_exists($new_id, $db));
|
||||
|
||||
dba_close($db);
|
||||
$this->id = $new_id;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$db = dba_open(SAVE_PATH . "/polls.db", "wd");
|
||||
$func = (dba_exists($this->id, $db) ? "dba_replace" : "dba_insert");
|
||||
$func($this->id, json_encode([
|
||||
"title" => $this->title,
|
||||
"creation_date" => $this->creation_date,
|
||||
"options" => $this->options,
|
||||
]), $db);
|
||||
dba_close($db);
|
||||
}
|
||||
}
|
98
static/css/main.css
Normal file
@ -0,0 +1,98 @@
|
||||
@import url("/static/fonts/Nunito/Nunito.css");
|
||||
@import url("/static/fonts/PTSerif/PTSerif.css");
|
||||
|
||||
html, body
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background: #242424;
|
||||
color: #ECECEC;
|
||||
|
||||
font-family: "Nunito", sans-serif;
|
||||
}
|
||||
|
||||
::-moz-focus-inner
|
||||
{ border: none; }
|
||||
|
||||
body h1
|
||||
{
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
font-size: 4em;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main
|
||||
{
|
||||
margin: 0 5%;
|
||||
}
|
||||
|
||||
main form input,
|
||||
main form button
|
||||
{
|
||||
transition: background 0.1s ease-in;
|
||||
display: block;
|
||||
margin: auto;
|
||||
padding: 1em;
|
||||
width: 25rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #141414;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
||||
font-size: 1.3em;
|
||||
text-align: center;
|
||||
}
|
||||
main form input[type="submit"],
|
||||
main form button
|
||||
{ cursor: pointer; }
|
||||
|
||||
main form input[type="submit"]
|
||||
{ margin-top: 1em; }
|
||||
|
||||
main form input:focus,
|
||||
main form input[type="submit"]:hover,
|
||||
main form button:hover
|
||||
{ background: #1D1D1D; }
|
||||
|
||||
main form input[name="title"],
|
||||
main form input[name="title"]:focus
|
||||
{
|
||||
background: transparent;
|
||||
font-family: "PT Serif", serif;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
main #choices .choice
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: auto;
|
||||
width: 25rem;
|
||||
}
|
||||
main #choices .choice > *
|
||||
{ margin: 0; }
|
||||
main #choices .choice input
|
||||
{ font-family: "PT Serif", serif; }
|
||||
main #choices .choice .delete
|
||||
{
|
||||
background: #FF2E31;
|
||||
width: 4em;
|
||||
}
|
||||
|
||||
footer
|
||||
{
|
||||
display: block;
|
||||
margin: 5em;
|
||||
color: #8E8E8E;
|
||||
|
||||
font-size: 0.9em;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
}
|
BIN
static/fonts/Nunito/Nunito-Black.eot
Normal file
5544
static/fonts/Nunito/Nunito-Black.svg
Normal file
After Width: | Height: | Size: 531 KiB |
BIN
static/fonts/Nunito/Nunito-Black.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-Black.woff
Normal file
BIN
static/fonts/Nunito/Nunito-Black.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-BlackItalic.eot
Normal file
5593
static/fonts/Nunito/Nunito-BlackItalic.svg
Normal file
After Width: | Height: | Size: 541 KiB |
BIN
static/fonts/Nunito/Nunito-BlackItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-BlackItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-BlackItalic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-Bold.eot
Normal file
5536
static/fonts/Nunito/Nunito-Bold.svg
Normal file
After Width: | Height: | Size: 532 KiB |
BIN
static/fonts/Nunito/Nunito-Bold.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-Bold.woff
Normal file
BIN
static/fonts/Nunito/Nunito-Bold.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-BoldItalic.eot
Normal file
5573
static/fonts/Nunito/Nunito-BoldItalic.svg
Normal file
After Width: | Height: | Size: 539 KiB |
BIN
static/fonts/Nunito/Nunito-BoldItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-BoldItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-BoldItalic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBold.eot
Normal file
5316
static/fonts/Nunito/Nunito-ExtraBold.svg
Normal file
After Width: | Height: | Size: 516 KiB |
BIN
static/fonts/Nunito/Nunito-ExtraBold.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBold.woff
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBold.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBoldItalic.eot
Normal file
5349
static/fonts/Nunito/Nunito-ExtraBoldItalic.svg
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
static/fonts/Nunito/Nunito-ExtraBoldItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBoldItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraBoldItalic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLight.eot
Normal file
5497
static/fonts/Nunito/Nunito-ExtraLight.svg
Normal file
After Width: | Height: | Size: 518 KiB |
BIN
static/fonts/Nunito/Nunito-ExtraLight.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLight.woff
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLight.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLightItalic.eot
Normal file
5518
static/fonts/Nunito/Nunito-ExtraLightItalic.svg
Normal file
After Width: | Height: | Size: 521 KiB |
BIN
static/fonts/Nunito/Nunito-ExtraLightItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLightItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-ExtraLightItalic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-Italic.eot
Normal file
5555
static/fonts/Nunito/Nunito-Italic.svg
Normal file
After Width: | Height: | Size: 534 KiB |
BIN
static/fonts/Nunito/Nunito-Italic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-Italic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-Italic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-Light.eot
Normal file
5435
static/fonts/Nunito/Nunito-Light.svg
Normal file
After Width: | Height: | Size: 518 KiB |
BIN
static/fonts/Nunito/Nunito-Light.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-Light.woff
Normal file
BIN
static/fonts/Nunito/Nunito-Light.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-LightItalic.eot
Normal file
5462
static/fonts/Nunito/Nunito-LightItalic.svg
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
static/fonts/Nunito/Nunito-LightItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-LightItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-LightItalic.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-Regular.eot
Normal file
5526
static/fonts/Nunito/Nunito-Regular.svg
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
static/fonts/Nunito/Nunito-Regular.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-Regular.woff
Normal file
BIN
static/fonts/Nunito/Nunito-Regular.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBold.eot
Normal file
5528
static/fonts/Nunito/Nunito-SemiBold.svg
Normal file
After Width: | Height: | Size: 528 KiB |
BIN
static/fonts/Nunito/Nunito-SemiBold.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBold.woff
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBold.woff2
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBoldItalic.eot
Normal file
5558
static/fonts/Nunito/Nunito-SemiBoldItalic.svg
Normal file
After Width: | Height: | Size: 535 KiB |
BIN
static/fonts/Nunito/Nunito-SemiBoldItalic.ttf
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBoldItalic.woff
Normal file
BIN
static/fonts/Nunito/Nunito-SemiBoldItalic.woff2
Normal file
168
static/fonts/Nunito/Nunito.css
Normal file
@ -0,0 +1,168 @@
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-ExtraBoldItalic.eot');
|
||||
src: url('Nunito-ExtraBoldItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-ExtraBoldItalic.woff2') format('woff2'),
|
||||
url('Nunito-ExtraBoldItalic.woff') format('woff'),
|
||||
url('Nunito-ExtraBoldItalic.ttf') format('truetype'),
|
||||
url('Nunito-ExtraBoldItalic.svg#Nunito-ExtraBoldItalic') format('svg');
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-ExtraLightItalic.eot');
|
||||
src: url('Nunito-ExtraLightItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-ExtraLightItalic.woff2') format('woff2'),
|
||||
url('Nunito-ExtraLightItalic.woff') format('woff'),
|
||||
url('Nunito-ExtraLightItalic.ttf') format('truetype'),
|
||||
url('Nunito-ExtraLightItalic.svg#Nunito-ExtraLightItalic') format('svg');
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-ExtraBold.eot');
|
||||
src: url('Nunito-ExtraBold.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-ExtraBold.woff2') format('woff2'),
|
||||
url('Nunito-ExtraBold.woff') format('woff'),
|
||||
url('Nunito-ExtraBold.ttf') format('truetype'),
|
||||
url('Nunito-ExtraBold.svg#Nunito-ExtraBold') format('svg');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-Regular.eot');
|
||||
src: url('Nunito-Regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-Regular.woff2') format('woff2'),
|
||||
url('Nunito-Regular.woff') format('woff'),
|
||||
url('Nunito-Regular.ttf') format('truetype'),
|
||||
url('Nunito-Regular.svg#Nunito-Regular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-BlackItalic.eot');
|
||||
src: url('Nunito-BlackItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-BlackItalic.woff2') format('woff2'),
|
||||
url('Nunito-BlackItalic.woff') format('woff'),
|
||||
url('Nunito-BlackItalic.ttf') format('truetype'),
|
||||
url('Nunito-BlackItalic.svg#Nunito-BlackItalic') format('svg');
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-Italic.eot');
|
||||
src: url('Nunito-Italic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-Italic.woff2') format('woff2'),
|
||||
url('Nunito-Italic.woff') format('woff'),
|
||||
url('Nunito-Italic.ttf') format('truetype'),
|
||||
url('Nunito-Italic.svg#Nunito-Italic') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-BoldItalic.eot');
|
||||
src: url('Nunito-BoldItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-BoldItalic.woff2') format('woff2'),
|
||||
url('Nunito-BoldItalic.woff') format('woff'),
|
||||
url('Nunito-BoldItalic.ttf') format('truetype'),
|
||||
url('Nunito-BoldItalic.svg#Nunito-BoldItalic') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-LightItalic.eot');
|
||||
src: url('Nunito-LightItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-LightItalic.woff2') format('woff2'),
|
||||
url('Nunito-LightItalic.woff') format('woff'),
|
||||
url('Nunito-LightItalic.ttf') format('truetype'),
|
||||
url('Nunito-LightItalic.svg#Nunito-LightItalic') format('svg');
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-SemiBoldItalic.eot');
|
||||
src: url('Nunito-SemiBoldItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-SemiBoldItalic.woff2') format('woff2'),
|
||||
url('Nunito-SemiBoldItalic.woff') format('woff'),
|
||||
url('Nunito-SemiBoldItalic.ttf') format('truetype'),
|
||||
url('Nunito-SemiBoldItalic.svg#Nunito-SemiBoldItalic') format('svg');
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-Bold.eot');
|
||||
src: url('Nunito-Bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-Bold.woff2') format('woff2'),
|
||||
url('Nunito-Bold.woff') format('woff'),
|
||||
url('Nunito-Bold.ttf') format('truetype'),
|
||||
url('Nunito-Bold.svg#Nunito-Bold') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-ExtraLight.eot');
|
||||
src: url('Nunito-ExtraLight.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-ExtraLight.woff2') format('woff2'),
|
||||
url('Nunito-ExtraLight.woff') format('woff'),
|
||||
url('Nunito-ExtraLight.ttf') format('truetype'),
|
||||
url('Nunito-ExtraLight.svg#Nunito-ExtraLight') format('svg');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-SemiBold.eot');
|
||||
src: url('Nunito-SemiBold.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-SemiBold.woff2') format('woff2'),
|
||||
url('Nunito-SemiBold.woff') format('woff'),
|
||||
url('Nunito-SemiBold.ttf') format('truetype'),
|
||||
url('Nunito-SemiBold.svg#Nunito-SemiBold') format('svg');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-Black.eot');
|
||||
src: url('Nunito-Black.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-Black.woff2') format('woff2'),
|
||||
url('Nunito-Black.woff') format('woff'),
|
||||
url('Nunito-Black.ttf') format('truetype'),
|
||||
url('Nunito-Black.svg#Nunito-Black') format('svg');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('Nunito-Light.eot');
|
||||
src: url('Nunito-Light.eot?#iefix') format('embedded-opentype'),
|
||||
url('Nunito-Light.woff2') format('woff2'),
|
||||
url('Nunito-Light.woff') format('woff'),
|
||||
url('Nunito-Light.ttf') format('truetype'),
|
||||
url('Nunito-Light.svg#Nunito-Light') format('svg');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
BIN
static/fonts/PTSerif/PTSerif-Bold.eot
Normal file
5104
static/fonts/PTSerif/PTSerif-Bold.svg
Normal file
After Width: | Height: | Size: 433 KiB |
BIN
static/fonts/PTSerif/PTSerif-Bold.ttf
Normal file
BIN
static/fonts/PTSerif/PTSerif-Bold.woff
Normal file
BIN
static/fonts/PTSerif/PTSerif-Bold.woff2
Normal file
BIN
static/fonts/PTSerif/PTSerif-BoldItalic.eot
Normal file
5464
static/fonts/PTSerif/PTSerif-BoldItalic.svg
Normal file
After Width: | Height: | Size: 469 KiB |
BIN
static/fonts/PTSerif/PTSerif-BoldItalic.ttf
Normal file
BIN
static/fonts/PTSerif/PTSerif-BoldItalic.woff
Normal file
BIN
static/fonts/PTSerif/PTSerif-BoldItalic.woff2
Normal file
BIN
static/fonts/PTSerif/PTSerif-Italic.eot
Normal file
5359
static/fonts/PTSerif/PTSerif-Italic.svg
Normal file
After Width: | Height: | Size: 460 KiB |
BIN
static/fonts/PTSerif/PTSerif-Italic.ttf
Normal file
BIN
static/fonts/PTSerif/PTSerif-Italic.woff
Normal file
BIN
static/fonts/PTSerif/PTSerif-Italic.woff2
Normal file
BIN
static/fonts/PTSerif/PTSerif-Regular.eot
Normal file
5019
static/fonts/PTSerif/PTSerif-Regular.svg
Normal file
After Width: | Height: | Size: 424 KiB |
BIN
static/fonts/PTSerif/PTSerif-Regular.ttf
Normal file
BIN
static/fonts/PTSerif/PTSerif-Regular.woff
Normal file
BIN
static/fonts/PTSerif/PTSerif-Regular.woff2
Normal file
48
static/fonts/PTSerif/PTSerif.css
Normal file
@ -0,0 +1,48 @@
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('PTSerif-BoldItalic.eot');
|
||||
src: url('PTSerif-BoldItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('PTSerif-BoldItalic.woff2') format('woff2'),
|
||||
url('PTSerif-BoldItalic.woff') format('woff'),
|
||||
url('PTSerif-BoldItalic.ttf') format('truetype'),
|
||||
url('PTSerif-BoldItalic.svg#PTSerif-BoldItalic') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('PTSerif-Bold.eot');
|
||||
src: url('PTSerif-Bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('PTSerif-Bold.woff2') format('woff2'),
|
||||
url('PTSerif-Bold.woff') format('woff'),
|
||||
url('PTSerif-Bold.ttf') format('truetype'),
|
||||
url('PTSerif-Bold.svg#PTSerif-Bold') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('PTSerif-Italic.eot');
|
||||
src: url('PTSerif-Italic.eot?#iefix') format('embedded-opentype'),
|
||||
url('PTSerif-Italic.woff2') format('woff2'),
|
||||
url('PTSerif-Italic.woff') format('woff'),
|
||||
url('PTSerif-Italic.ttf') format('truetype'),
|
||||
url('PTSerif-Italic.svg#PTSerif-Italic') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('PTSerif-Regular.eot');
|
||||
src: url('PTSerif-Regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('PTSerif-Regular.woff2') format('woff2'),
|
||||
url('PTSerif-Regular.woff') format('woff'),
|
||||
url('PTSerif-Regular.ttf') format('truetype'),
|
||||
url('PTSerif-Regular.svg#PTSerif-Regular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
1
static/js/fetch.min.js
vendored
Normal file
50
static/js/new.js
Normal file
@ -0,0 +1,50 @@
|
||||
let next_id = 1;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let choices = document.getElementById("choices");
|
||||
let choice_template = document.getElementById("choice");
|
||||
|
||||
function create_choice()
|
||||
{
|
||||
let choice = document.createElement("div");
|
||||
choice.classList.add("choice");
|
||||
choice.innerHTML = choice_template.innerHTML.replace(/:id/g, next_id);
|
||||
choice.querySelector("button.delete").addEventListener("click", () => {
|
||||
choices.removeChild(choice);
|
||||
});
|
||||
choices.append(choice);
|
||||
next_id++;
|
||||
}
|
||||
|
||||
document.getElementById("add-choice").addEventListener("click", create_choice);
|
||||
while(next_id < 4) create_choice();
|
||||
|
||||
let form = document.getElementById("newpoll");
|
||||
form.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
function get_choices(form)
|
||||
{
|
||||
let choices = [];
|
||||
form.querySelectorAll("#choices .choice input").forEach((el) => {
|
||||
choices.push(el.value);
|
||||
});
|
||||
return choices;
|
||||
}
|
||||
|
||||
fetch("/polls", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
title: form.querySelector(`input[name="title"]`).value,
|
||||
options: get_choices(form),
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then((res) => {
|
||||
return res.json();
|
||||
}).then((json) => {
|
||||
console.log(json);
|
||||
});
|
||||
});
|
||||
});
|
21
views/home.php
Normal file
@ -0,0 +1,21 @@
|
||||
<body class="home">
|
||||
<script src="/static/js/fetch.min.js"></script>
|
||||
<script src="/static/js/new.js"></script>
|
||||
|
||||
<h1>Poll Verlaine</h1>
|
||||
<main>
|
||||
<form action="#" id="newpoll">
|
||||
<input type="text" name="title" placeholder="What do you want to ask?" />
|
||||
<div id="choices">
|
||||
</div>
|
||||
<button type="button" id="add-choice">New choice</button>
|
||||
<input type="submit" value="Create poll" />
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<template id="choice">
|
||||
<input type="text" id="choice-:id" placeholder="Another choice" />
|
||||
<button type="button" class="delete" tabindex="-1" title="Delete" aria-label="Delete">✕</button>
|
||||
</template>
|
||||
|
||||
</body>
|