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>
|