dev21w43a

This commit is contained in:
Victor Westerlund 2021-10-25 09:56:01 +02:00
parent 7cd3bdb6f4
commit 8f7939aca7
9 changed files with 144 additions and 17 deletions

52
public/api.php Normal file
View file

@ -0,0 +1,52 @@
<?php
require_once dirname(__DIR__,1)."/src/Globals.php";
class APIRouter {
public function __construct($path) {
// List of implemented API services
$this->services = [
"search" => function() {
require_once dirname(__DIR__,1)."/src/search/Search.php";
new Search();
}
];
$this->url = parse_url($path);
$this->run();
}
// Find the requested service by looking at the next URI breadcrumb after "api"
private function get_service() {
$path = explode("/",$this->url["path"]);
$service = array_search("api",$path) + 1; // Next array value
$service = $path[$service];
return $service;
}
private function error($message,$code = 500) {
$output = [
"ok" => false,
"code" => strval($code),
"message" => $message
];
header("Content-Type: application/json");
http_response_code($code);
echo json_encode($output);
}
// Run the requested service if it exists in services list
private function run() {
$service = $this->get_service();
if(!array_key_exists($service,$this->services)) {
$this->error("Inavlid API");
return false;
}
// Import and run requested service
$this->services[$service]();
}
}
new APIRouter($_SERVER["REQUEST_URI"]);

View file

@ -69,8 +69,7 @@ header h1 {
}
#results > p.error::before {
content: "oh crap, ";
font-weight: bold;
content: "😰 ";
}
.card {

View file

@ -42,18 +42,22 @@ export default class Search {
url.searchParams.set("q",query);
const timeout = new Promise(reject => setTimeout(() => reject("Request timed out"),3000));
const api = fetch(url);
const api = fetch(url,{
headers: {
"Content-Type": "text/html"
}
});
const result = Promise.race([api,timeout]);
result.then(response => {
if(!response.ok) {
this.status("something went wrong on my side","error");
console.error("Response from server:",response);
return;
throw new Error("Invalid response from server");
}
this.output(response.text);
});
result.catch(error => this.status(error,"error"));
return response.text();
})
.then(html => this.output(html))
.catch(error => this.status(error,"error"));
}
// Wait until the user stops typing for a few miliseconds
@ -62,9 +66,10 @@ export default class Search {
this.throttle = setTimeout(() => this.search(query),500);
}
async keyEvent(event) {
keyEvent(event) {
const query = event.target.value;
if(query.length < 1) {
this.lastQuery = "";
this.status("search results will appear here as you type");
return;
}

View file

@ -18,14 +18,6 @@
<input type="text" placeholder="start typing to search..">
</div>
<div id="results">
<!--<div class="card">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M3 2.75A2.75 2.75 0 0 1 5.75 0h14.5a.75.75 0 0 1 .75.75v20.5a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h5.25v-4H6A1.5 1.5 0 0 0 4.5 18v.75c0 .716.43 1.334 1.05 1.605a.75.75 0 0 1-.6 1.374A3.25 3.25 0 0 1 3 18.75v-16zM19.5 1.5V15H6c-.546 0-1.059.146-1.5.401V2.75c0-.69.56-1.25 1.25-1.25H19.5z" fill="currentColor"/><path d="M7 18.25a.25.25 0 0 1 .25-.25h5a.25.25 0 0 1 .25.25v5.01a.25.25 0 0 1-.397.201l-2.206-1.604a.25.25 0 0 0-.294 0L7.397 23.46a.25.25 0 0 1-.397-.2v-5.01z" fill="currentColor"/></svg>
<p>github/&ZeroWidthSpace;victorwesterlund.com</p>
</div>
<p>Lorem ipsum</p>
<p class="button">read more</p>
</div>-->
<p>search results will appear here as you type</p>
</div>
<script type="module" src="assets/js/search.js"></script>

14
src/Globals.php Normal file
View file

@ -0,0 +1,14 @@
<?php
class Import {
public static function file($file) {
$content = file_get_contents($file);
return $content;
}
public static function json($file) {
$contents = Import::file($file);
$json = json_decode($contents);
return $json;
}
}

15
src/database/Database.php Normal file
View file

@ -0,0 +1,15 @@
<?php
include_once dirname(__DIR__,1)."/Globals.php";
class Database extends mysqli {
public function __construct() {
$this->config = Import::json("config.json");
}
private function get_server() {
foreach($this->config->servers as $server) {
yield $server;
}
}
}

10
src/database/config.json Normal file
View file

@ -0,0 +1,10 @@
{
"servers": [
{
"host": "",
"user": "",
"pass": "",
"db": ""
}
]
}

32
src/search/Search.php Normal file
View file

@ -0,0 +1,32 @@
<?php
require_once dirname(__DIR__,1)."/Globals.php";
require_once dirname(__DIR__,1)."/database/Database.php";
class Search extends Database {
public function __construct() {
$this->query = $query;
switch($_SERVER["HTTP_CONTENT_TYPE"]) {
case "text/html":
$this->get_html();
break;
default:
case "application/json":
$this->get_json();
break;
}
}
private function get_html() {
header("Content-Type: text/html");
$template = Import::file("templates/default.html");
echo $template;
}
private function get_json() {
header("Content-Type: application/json");
echo "{}";
}
}

View file

@ -0,0 +1,8 @@
<div class="card">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M3 2.75A2.75 2.75 0 0 1 5.75 0h14.5a.75.75 0 0 1 .75.75v20.5a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h5.25v-4H6A1.5 1.5 0 0 0 4.5 18v.75c0 .716.43 1.334 1.05 1.605a.75.75 0 0 1-.6 1.374A3.25 3.25 0 0 1 3 18.75v-16zM19.5 1.5V15H6c-.546 0-1.059.146-1.5.401V2.75c0-.69.56-1.25 1.25-1.25H19.5z" fill="currentColor"/><path d="M7 18.25a.25.25 0 0 1 .25-.25h5a.25.25 0 0 1 .25.25v5.01a.25.25 0 0 1-.397.201l-2.206-1.604a.25.25 0 0 0-.294 0L7.397 23.46a.25.25 0 0 1-.397-.2v-5.01z" fill="currentColor"/></svg>
<p>%s</p>
</div>
<p>%s</p>
<p class="button">read more</p>
</div>