parent
947cda494a
commit
6f3899fb5f
@ -0,0 +1,24 @@
|
||||
import React, {useRef, useState} from "react";
|
||||
import "../style/title_input.css";
|
||||
|
||||
export default function TitleInput({default_value, on_validated}: {
|
||||
default_value: string,
|
||||
on_validated: (a: string) => void
|
||||
}) {
|
||||
const [value, setValue] = useState(default_value);
|
||||
const ref = useRef<HTMLInputElement>(null);
|
||||
|
||||
return (
|
||||
<input className="title_input"
|
||||
ref={ref}
|
||||
type="text"
|
||||
value={value}
|
||||
onChange={event => setValue(event.target.value)}
|
||||
onBlur={_ => on_validated(value)}
|
||||
onKeyDown={event => {
|
||||
if (event.key == 'Enter')
|
||||
ref.current?.blur();
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
:root {
|
||||
--main-color: #ffffff;
|
||||
--second-color: #ccde54;
|
||||
|
||||
--background-color: #d2cdd3;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
@import "colors.css";
|
||||
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
#topbar {
|
||||
display: flex;
|
||||
background-color: var(--main-color);
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.title_input {
|
||||
width: 25ch;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
.title_input {
|
||||
background: transparent;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
text-align: center;
|
||||
|
||||
border-bottom-width: 2px;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.title_input:focus {
|
||||
outline: none;
|
||||
|
||||
border-bottom-color: blueviolet;
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import "../style/editor.css";
|
||||
import TitleInput from "../components/TitleInput";
|
||||
|
||||
|
||||
export default function Editor({id, name}: { id: number, name: string }) {
|
||||
return (
|
||||
<div id="main">
|
||||
<div id="topbar">
|
||||
<div>LEFT</div>
|
||||
<TitleInput default_value={name} on_validated={name => update_tactic_name(id, name)}/>
|
||||
<div>RIGHT</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function update_tactic_name(id: number, new_name: string) {
|
||||
//FIXME avoid absolute path as they would not work on staging server
|
||||
fetch(`/api/tactic/${id}/edit/name`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: new_name
|
||||
})
|
||||
}).then(response => {
|
||||
if (!response.ok)
|
||||
alert("could not update tactic name!")
|
||||
})
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
require "../../config.php";
|
||||
require "../../vendor/autoload.php";
|
||||
require "../../sql/database.php";
|
||||
|
||||
use App\Api\TacticEndpoint;
|
||||
use App\Connexion;
|
||||
use App\Gateway\TacticInfoGateway;
|
||||
|
||||
$con = new Connexion(get_database());
|
||||
|
||||
$router = new AltoRouter();
|
||||
$router->setBasePath("/api");
|
||||
|
||||
$tacticEndpoint = new TacticEndpoint(new TacticInfoGateway($con));
|
||||
$router->map("POST", "/tactic/[i:id]/edit/name", fn(int $id) => $tacticEndpoint->update_name($id));
|
||||
$router->map("GET", "/tactic/[i:id]", fn(int $id) => $tacticEndpoint->get_tactic_info($id));
|
||||
$router->map("POST", "/tactic/new", fn() => $tacticEndpoint->new_tactic());
|
||||
|
||||
$match = $router->match();
|
||||
|
||||
if ($match == null) {
|
||||
echo "404 not found";
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
call_user_func_array($match['target'], $match['params']);
|
@ -1,8 +1,12 @@
|
||||
|
||||
-- drop tables here
|
||||
DROP TABLE IF EXISTS FormEntries;
|
||||
DROP TABLE IF EXISTS TacticInfo;
|
||||
|
||||
CREATE TABLE FormEntries(name varchar, description varchar);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE TacticInfo(
|
||||
id integer PRIMARY KEY AUTOINCREMENT,
|
||||
name varchar,
|
||||
creation_date timestamp
|
||||
);
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api;
|
||||
use App\Gateway\TacticInfoGateway;
|
||||
|
||||
/**
|
||||
* API endpoint related to tactics
|
||||
*/
|
||||
class TacticEndpoint {
|
||||
private TacticInfoGateway $tactics;
|
||||
|
||||
/**
|
||||
* @param TacticInfoGateway $tactics
|
||||
*/
|
||||
public function __construct(TacticInfoGateway $tactics) {
|
||||
$this->tactics = $tactics;
|
||||
}
|
||||
|
||||
|
||||
public function update_name(int $tactic_id) {
|
||||
$request_body = file_get_contents('php://input');
|
||||
$data = json_decode($request_body);
|
||||
|
||||
$new_name = $data->name;
|
||||
|
||||
$this->tactics->update($tactic_id, $new_name);
|
||||
}
|
||||
|
||||
public function new_tactic() {
|
||||
$request_body = file_get_contents('php://input');
|
||||
$data = json_decode($request_body);
|
||||
|
||||
$initial_name = $data->name;
|
||||
$id = $this->tactics->insert($initial_name)->getId();
|
||||
|
||||
echo "{id: $id}";
|
||||
}
|
||||
|
||||
public function get_tactic_info(int $id) {
|
||||
$tactic_info = $this->tactics->get($id);
|
||||
echo json_encode($tactic_info);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Data\TacticInfo;
|
||||
use App\Gateway\TacticInfoGateway;
|
||||
|
||||
class EditorController {
|
||||
|
||||
const TACTIC_DEFAULT_NAME = "Nouvelle tactique";
|
||||
|
||||
private TacticInfoGateway $tactics;
|
||||
|
||||
/**
|
||||
* @param TacticInfoGateway $tactics
|
||||
*/
|
||||
public function __construct(TacticInfoGateway $tactics) {
|
||||
$this->tactics = $tactics;
|
||||
}
|
||||
|
||||
private function openEditor(TacticInfo $tactic) {
|
||||
send_react_front("views/Editor.tsx", ["name" => $tactic->getName(), "id" => $tactic->getId()]);
|
||||
}
|
||||
|
||||
public function makeNew() {
|
||||
$info = $this->tactics->insert(self::TACTIC_DEFAULT_NAME);
|
||||
$this->openEditor($info);
|
||||
}
|
||||
|
||||
public function edit(int $id) {
|
||||
$tactic = $this->tactics->get($id);
|
||||
|
||||
$this->openEditor($tactic);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Data;
|
||||
|
||||
class TacticInfo implements \JsonSerializable {
|
||||
private int $id;
|
||||
private string $name;
|
||||
private int $creation_date;
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @param int $creation_date
|
||||
*/
|
||||
public function __construct(int $id, string $name, int $creation_date) {
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->creation_date = $creation_date;
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getCreationDate(): int {
|
||||
return $this->creation_date;
|
||||
}
|
||||
|
||||
public function jsonSerialize() {
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Gateway;
|
||||
|
||||
use App\Connexion;
|
||||
use App\Data\TacticInfo;
|
||||
use \PDO;
|
||||
|
||||
class TacticInfoGateway {
|
||||
private Connexion $con;
|
||||
|
||||
/**
|
||||
* @param Connexion $con
|
||||
*/
|
||||
public function __construct(Connexion $con) {
|
||||
$this->con = $con;
|
||||
}
|
||||
|
||||
public function get(int $id): TacticInfo {
|
||||
$row = $this->con->fetch(
|
||||
"SELECT * FROM TacticInfo WHERE id = :id",
|
||||
[":id" => [$id, PDO::PARAM_INT]]
|
||||
)[0];
|
||||
|
||||
return new TacticInfo($id, $row["name"], strtotime($row["creation_date"]));
|
||||
}
|
||||
|
||||
public function insert(string $name): TacticInfo {
|
||||
$row = $this->con->fetch(
|
||||
"INSERT INTO TacticInfo(name, creation_date) VALUES(:name, CURRENT_TIMESTAMP) RETURNING id, creation_date",
|
||||
[":name" => [$name, PDO::PARAM_STR]]
|
||||
)[0];
|
||||
return new TacticInfo(intval($row["id"]), $name, strtotime($row["creation_date"]));
|
||||
}
|
||||
|
||||
public function update(int $id, string $name) {
|
||||
$this->con->exec(
|
||||
"UPDATE TacticInfo SET name = :name WHERE id = :id",
|
||||
[
|
||||
":name" => [$name, PDO::PARAM_STR],
|
||||
":id" => [$id, PDO::PARAM_INT]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue