Merge pull request #148 from ThomasRubini/client_admin-pages-improvements-part-2
[Client] Second part of admin pages improvements
This commit is contained in:
commit
7e64dc69d3
@ -9,10 +9,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--admin-black-color: #000000;
|
||||||
--admin-grey-color: #5A5656;
|
--admin-grey-color: #5A5656;
|
||||||
--admin-red-color: #FF0000;
|
--admin-red-color: #FF0000;
|
||||||
--admin-white-color: #FFFFFF;
|
--admin-white-color: #FFFFFF;
|
||||||
--adming-yellow-color: #FFC800;
|
--adming-yellow-color: #D6A851;
|
||||||
|
--alert-dialog-background-color: #000000DF;
|
||||||
--body-margin: 0.375em;
|
--body-margin: 0.375em;
|
||||||
font-family: "Roboto Mono", sans-serif;
|
font-family: "Roboto Mono", sans-serif;
|
||||||
}
|
}
|
||||||
@ -25,6 +27,15 @@ a, body {
|
|||||||
color: var(--admin-white-color);
|
color: var(--admin-white-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:focus, a:hover {
|
||||||
|
background-color: var(--admin-white-color);
|
||||||
|
color: var(--admin-grey-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:focus > .action_icon, .action_button:focus > .action_icon, a:hover > .action_icon, .action_button:hover > .action_icon {
|
||||||
|
fill: var(--admin-grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: unset;
|
color: unset;
|
||||||
}
|
}
|
||||||
@ -33,9 +44,24 @@ body {
|
|||||||
margin: var(--body-margin);
|
margin: var(--body-margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input {
|
button {
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 1em;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input, select {
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: var(--admin-white-color);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0.125em;
|
||||||
|
color: var(--admin-white-color);
|
||||||
font-family: "Roboto Mono", sans-serif;
|
font-family: "Roboto Mono", sans-serif;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
margin: 1em;
|
||||||
|
padding: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -56,20 +82,74 @@ header a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
header a:hover {
|
|
||||||
background-color: var(--admin-white-color);
|
|
||||||
color: var(--admin-grey-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
html {
|
||||||
background-color: var(--admin-grey-color);
|
background-color: var(--admin-grey-color);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noscript dialog {
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--admin-grey-color);
|
||||||
|
border-color: var(--admin-white-color);
|
||||||
|
border-radius: 1em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
left: 50%;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 2em;
|
||||||
|
position: fixed;
|
||||||
|
text-align: center;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: var(--admin-white-color);
|
fill: var(--admin-white-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action_button:focus, .action_button:hover {
|
||||||
|
background-color: var(--admin-white-color);
|
||||||
|
color: var(--admin-grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action_icon {
|
||||||
|
height: 2em;
|
||||||
|
transition-property: fill !important;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert_dialog_background {
|
||||||
|
background-color: var(--alert-dialog-background-color);
|
||||||
|
display: block;
|
||||||
|
height: 100vh;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
width: 100vw;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert_dialog_bottom_link {
|
||||||
|
font-size: 1.125em;
|
||||||
|
padding: 0.25em;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert_dialog_msg {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert_dialog_msg, .alert_dialog_title {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert_dialog_title {
|
||||||
|
font-size: 1.75em;
|
||||||
|
}
|
||||||
|
|
||||||
.page_category {
|
.page_category {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
@ -102,30 +182,3 @@ svg {
|
|||||||
transition-duration: 0.25s;
|
transition-duration: 0.25s;
|
||||||
transition-timing-function: linear;
|
transition-timing-function: linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
#places>section {
|
|
||||||
border: thin solid red;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#section>input{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.questionTypeTag{
|
|
||||||
border: thin solid red;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.questionTypeTag input{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.questionType{
|
|
||||||
border: thin solid red;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.question input{
|
|
||||||
width: 100%;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
.add_npc_icon {
|
|
||||||
height: 2em;
|
|
||||||
transition-property: fill;
|
|
||||||
width: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add_npc_icon:hover {
|
|
||||||
transition-property: fill;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add_npc_link {
|
.add_npc_link {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-color: var(--admin-white-color);
|
border-color: var(--admin-white-color);
|
||||||
@ -24,26 +14,22 @@
|
|||||||
padding: 0.25em;
|
padding: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add_npc_link:hover {
|
|
||||||
background-color: var(--admin-white-color);
|
|
||||||
color: var(--admin-grey-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.add_npc_link:hover > .add_npc_icon {
|
|
||||||
fill: var(--admin-grey-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.character_item {
|
.character_item {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 1em;
|
margin: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character_item a {
|
.character_item a {
|
||||||
|
padding: 0.25em;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-color: var(--admin-white-color);
|
text-decoration-color: var(--admin-white-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.character_item a:hover {
|
||||||
|
text-decoration-color: var(--admin-grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
.character_list {
|
.character_list {
|
||||||
align-content: center;
|
align-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -31,3 +31,9 @@ input {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#login_input_button {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 1em;
|
||||||
|
padding: 0.25em;
|
||||||
|
}
|
||||||
|
@ -1,55 +1,36 @@
|
|||||||
button {
|
img[alt] {
|
||||||
display: flex;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input {
|
img[alt], .info_item, .section_title {
|
||||||
background-color: transparent;
|
text-align: center;
|
||||||
border-color: var(--admin-white-color);
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0.125em;
|
|
||||||
color: var(--admin-white-color);
|
|
||||||
margin: 1em;
|
|
||||||
padding: 0.25em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
width: 20em;
|
width: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action_buttons, .answer_groups {
|
option {
|
||||||
align-content: center;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action_button {
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 1em;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action_button:hover {
|
|
||||||
background-color: var(--admin-white-color);
|
background-color: var(--admin-white-color);
|
||||||
color: var(--admin-grey-color);
|
color: var(--admin-black-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action_button:hover > .action_icon {
|
.action_buttons, .answer_groups, .reaction, #add_reactions {
|
||||||
fill: var(--admin-grey-color);
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action_icon {
|
.action_buttons, .answer_group, .answer_groups, .reaction, #add_reactions {
|
||||||
height: 2em;
|
display: flex;
|
||||||
transition-property: fill;
|
justify-content: center;
|
||||||
width: 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.character_image {
|
.answer_group, .reaction, #add_reactions {
|
||||||
width: 15em;
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character_image, .reaction_image {
|
||||||
|
width: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character_image, #npc_name {
|
.character_image, #npc_name {
|
||||||
@ -65,8 +46,8 @@ input[type="text"] {
|
|||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info_item, .section_title {
|
.reaction, #add_reactions {
|
||||||
text-align: center;
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section_title {
|
.section_title {
|
||||||
|
16
truthinquiry/static/css/admin_ui_places.css
Normal file
16
truthinquiry/static/css/admin_ui_places.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.place {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.place_input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#add_place, #save_changes {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
32
truthinquiry/static/css/admin_ui_questions.css
Normal file
32
truthinquiry/static/css/admin_ui_questions.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.add_question_btn, #save_changes {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete_question_btn, .question_input {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question_input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question_type {
|
||||||
|
border-color: var(--admin-white-color);
|
||||||
|
border-radius: 1em;
|
||||||
|
border-style: solid;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question_type_title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
17
truthinquiry/static/css/admin_ui_traits.css
Normal file
17
truthinquiry/static/css/admin_ui_traits.css
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
.delete_trait_btn, #add_trait, #save_changes {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trait_description_container, .trait_name_container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trait_description_input, .trait_name_input {
|
||||||
|
width: 30em;
|
||||||
|
}
|
@ -1,89 +0,0 @@
|
|||||||
//functions for places.html
|
|
||||||
|
|
||||||
function addInputPlaces(){
|
|
||||||
let newPlace = places.lastElementChild.cloneNode(true);
|
|
||||||
newPlace.id = "";
|
|
||||||
newPlace.querySelector("input").value = "";
|
|
||||||
places.appendChild(newPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteInputPlaces(buttonNode){
|
|
||||||
let placeNode = buttonNode.parentNode;
|
|
||||||
placeNode.parentNode.removeChild(placeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveFormPlaces(){
|
|
||||||
let data = [];
|
|
||||||
for(let section of places.querySelectorAll("section")){
|
|
||||||
let place = {};
|
|
||||||
place["id"] = section.id
|
|
||||||
place["name"] = section.querySelector("input").value
|
|
||||||
data.push(place);
|
|
||||||
}
|
|
||||||
makeAPIRequest("admin/setPlaces", {"places": data, "lang": "FR"}, {"content": "json"})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//functions for traits.html
|
|
||||||
|
|
||||||
|
|
||||||
function addInputTraits(){
|
|
||||||
let newTrait = traits.lastElementChild.cloneNode(true);
|
|
||||||
newTrait.id = "";
|
|
||||||
newTrait.querySelector(".name_input").value = "";
|
|
||||||
newTrait.querySelector(".desc_input").value = "";
|
|
||||||
traits.appendChild(newTrait);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteInputTraits(buttonNode){
|
|
||||||
let traitNode = buttonNode.parentNode;
|
|
||||||
traitNode.parentNode.removeChild(traitNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveFormTraits(){
|
|
||||||
let data = [];
|
|
||||||
for(let section of traits.querySelectorAll("section")){
|
|
||||||
let trait = {};
|
|
||||||
trait["id"] = section.id
|
|
||||||
trait["name"] = section.querySelector(".name_input").value
|
|
||||||
trait["desc"] = section.querySelector(".desc_input").value
|
|
||||||
data.push(trait);
|
|
||||||
}
|
|
||||||
makeAPIRequest("admin/setTraits", {"traits": data, "lang": "FR"}, {"content": "json"})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//functions for questions.html
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function addInputQuestions(button){
|
|
||||||
let questionTypeContent = button.parentNode.querySelector(".questionTypeContent");
|
|
||||||
let newQuestion = questionTypeContent.querySelector(".question").cloneNode(true);
|
|
||||||
newQuestion.id = "";
|
|
||||||
newQuestion.querySelector("input").value = "";
|
|
||||||
questionTypeContent.appendChild(newQuestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteInputQuestions(buttonNode){
|
|
||||||
let placeNode = buttonNode.parentNode;
|
|
||||||
placeNode.parentNode.removeChild(placeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveFormQuestions(){
|
|
||||||
let data = [];
|
|
||||||
|
|
||||||
for(let questionTypeNode of allQuestions.querySelectorAll(".questionType")){
|
|
||||||
let questionsJson = [];
|
|
||||||
let questionTypeJson = {"questions": questionsJson};
|
|
||||||
data.push(questionTypeJson);
|
|
||||||
|
|
||||||
for(let questionNode of questionTypeNode.querySelectorAll("input")){
|
|
||||||
questionsJson.push({"text": questionNode.value})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
makeAPIRequest("admin/setQuestions", {"questions": data, "lang": "FR"}, {"content": "json"})
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
const reactionsDelta = {}
|
const reactionsDelta = {};
|
||||||
|
|
||||||
async function createOrUpdateNpc() {
|
async function createOrUpdateNpc() {
|
||||||
const data = {};
|
const data = {};
|
||||||
@ -9,7 +9,7 @@ async function createOrUpdateNpc() {
|
|||||||
const allAnswersJson = [];
|
const allAnswersJson = [];
|
||||||
data["allAnswers"] = allAnswersJson;
|
data["allAnswers"] = allAnswersJson;
|
||||||
|
|
||||||
for (let answerTypeNode of document.querySelector(".answer_groups").children) {
|
for (const answerTypeNode of document.querySelector(".answer_groups").children) {
|
||||||
const answersJson = [];
|
const answersJson = [];
|
||||||
const answerTypeJson = {"answers": answersJson};
|
const answerTypeJson = {"answers": answersJson};
|
||||||
allAnswersJson.push(answerTypeJson);
|
allAnswersJson.push(answerTypeJson);
|
||||||
@ -20,35 +20,33 @@ async function createOrUpdateNpc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await makeAPIRequest("admin/setNpc", {"npc": data, "lang": "FR"}, {"content": "json"});
|
await makeAPIRequest("admin/setNpc", {"npc": data, "lang": "FR"}, {"content": "json"});
|
||||||
|
|
||||||
await uploadReactionsDelta();
|
await uploadReactionsDelta();
|
||||||
|
|
||||||
alert("Opération effectuée avec succès");
|
alert("Opération effectuée avec succès");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadReactionsDelta() {
|
async function uploadReactionsDelta() {
|
||||||
let requests = [];
|
const requests = [];
|
||||||
|
const npcId = document.querySelector("#npc_id").value;
|
||||||
|
|
||||||
|
for (const [traitId, reactionNode] of Object.entries(reactionsDelta)) {
|
||||||
for(const [traitId, reactionNode] of Object.entries(reactionsDelta)){
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("npc_id", npc_id.value);
|
formData.append("npc_id", npcId);
|
||||||
formData.append("trait_id", traitId);
|
formData.append("trait_id", traitId);
|
||||||
|
|
||||||
if(reactionNode === null) formData.append("file", "null");
|
if (reactionNode === null) {
|
||||||
else{
|
formData.append("file", "null");
|
||||||
const file = reactionNode.querySelector(".img_input").files[0]
|
} else {
|
||||||
|
const file = reactionNode.querySelector(".img_input").files[0];
|
||||||
formData.append("file", file ? file : "");
|
formData.append("file", file ? file : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
requests.push(makeAPIRequest("admin/setReaction", formData, {"content": "form"}));
|
requests.push(makeAPIRequest("admin/setReaction", formData, {"content": "form"}));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(request of requests){
|
for (const request of requests) {
|
||||||
await request;
|
await request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteNpc() {
|
async function deleteNpc() {
|
||||||
@ -62,51 +60,141 @@ async function deleteNpc() {
|
|||||||
document.location = "/admin";
|
document.location = "/admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeReaction(inputNode){
|
function changeImageReaction(imageInputElement) {
|
||||||
const parentNode = inputNode.parentNode;
|
const parentNode = imageInputElement.parentNode;
|
||||||
const imgNode = parentNode.querySelector('img');
|
const imgNode = parentNode.querySelector('img');
|
||||||
const traitId = parentNode.querySelector('.trait_id').value;
|
const traitId = parentNode.querySelector('.trait_id').value;
|
||||||
|
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (e)=>{
|
reader.addEventListener("load", event => {
|
||||||
imgNode.src = e.target.result
|
imgNode.src = event.target.result
|
||||||
}
|
});
|
||||||
reader.readAsDataURL(inputNode.files[0]);
|
reader.readAsDataURL(imageInputElement.files[0]);
|
||||||
|
|
||||||
reactionsDelta[traitId] = parentNode;
|
reactionsDelta[traitId] = parentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteReaction(node){
|
function deleteImageReaction(reactionDeletionButton) {
|
||||||
const reactionNode = node.parentNode;
|
if (!confirm("Voulez-vous vraiment supprimer l'image de cette réaction ?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reactionNode = reactionDeletionButton.parentNode;
|
||||||
const traitId = reactionNode.querySelector(".trait_id").value;
|
const traitId = reactionNode.querySelector(".trait_id").value;
|
||||||
const reactionName = reactionNode.querySelector("p").innerText;
|
const reactionName = reactionNode.querySelector(".reaction_name").innerText;
|
||||||
|
|
||||||
reactionNode.parentNode.removeChild(reactionNode);
|
reactionNode.parentNode.removeChild(reactionNode);
|
||||||
|
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.value = traitId
|
option.value = traitId;
|
||||||
option.innerText = reactionName
|
option.innerText = reactionName;
|
||||||
|
|
||||||
reactions_to_add.appendChild(option);
|
const addReactionsSelectorElement = document.getElementById("add_reactions_selector");
|
||||||
|
if (addReactionsSelectorElement === null) {
|
||||||
|
// No add_reactions_selector element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addReactionsSelectorElement.appendChild(option);
|
||||||
|
|
||||||
reactionsDelta[traitId] = null;
|
reactionsDelta[traitId] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addReaction(selectNode){
|
function addReaction(addReactionsSelectorElement) {
|
||||||
const selectedOptionNode = selectNode.selectedOptions[0];
|
const selectedOptionNode = addReactionsSelectorElement.selectedOptions[0];
|
||||||
|
|
||||||
const traitId = selectedOptionNode.value;
|
const traitId = selectedOptionNode.value;
|
||||||
const reactionName = selectedOptionNode.innerText;
|
const reactionName = selectedOptionNode.innerText;
|
||||||
|
|
||||||
selectNode.removeChild(selectedOptionNode);
|
addReactionsSelectorElement.removeChild(selectedOptionNode);
|
||||||
|
|
||||||
const newReaction = reactions.querySelector("div").cloneNode(true);
|
const newReactionElement = document.createElement("section");
|
||||||
newReaction.querySelector("img").src = "";
|
newReactionElement.classList.add("reaction");
|
||||||
newReaction.querySelector(".img_input").value = null;
|
|
||||||
newReaction.querySelector(".trait_id").value = traitId
|
|
||||||
newReaction.querySelector("p").innerText = reactionName
|
|
||||||
|
|
||||||
reactions.appendChild(newReaction);
|
const reactionNameElement = document.createElement("h3");
|
||||||
|
reactionNameElement.classList.add("reaction_name");
|
||||||
|
reactionNameElement.textContent = reactionName;
|
||||||
|
|
||||||
reactionsDelta[traitId] = newReaction;
|
newReactionElement.appendChild(reactionNameElement);
|
||||||
|
|
||||||
|
const imageElement = document.createElement("img");
|
||||||
|
imageElement.classList.add("reaction_image");
|
||||||
|
imageElement.setAttribute("alt", "Image d'une réaction d'un personnage");
|
||||||
|
imageElement.src = "/static/images/no_photography_white.svg";
|
||||||
|
|
||||||
|
newReactionElement.appendChild(imageElement);
|
||||||
|
|
||||||
|
const imageInputElement = document.createElement("input");
|
||||||
|
imageInputElement.classList.add("img_input");
|
||||||
|
imageInputElement.setAttribute("type", "file");
|
||||||
|
imageInputElement.setAttribute("accept", "image/png, image/jpg, image/jpeg");
|
||||||
|
imageInputElement.addEventListener("change", () => changeImageReaction(imageInputElement));
|
||||||
|
|
||||||
|
newReactionElement.appendChild(imageInputElement);
|
||||||
|
|
||||||
|
const traitIdInputElement = document.createElement("input");
|
||||||
|
traitIdInputElement.classList.add("trait_id");
|
||||||
|
traitIdInputElement.setAttribute("type", "hidden");
|
||||||
|
traitIdInputElement.setAttribute("value", traitId);
|
||||||
|
|
||||||
|
newReactionElement.appendChild(traitIdInputElement);
|
||||||
|
|
||||||
|
const buttonElement = document.createElement("button");
|
||||||
|
buttonElement.classList.add("delete_question_btn", "action_button", "short_color_transition");
|
||||||
|
buttonElement.setAttribute("title", "Cliquez ici pour supprimer l'image de cette réaction");
|
||||||
|
buttonElement.addEventListener("click", () => deleteImageReaction(buttonElement));
|
||||||
|
|
||||||
|
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||||
|
svgElement.classList.add("action_icon", "short_color_transition");
|
||||||
|
svgElement.setAttribute("viewBox", "0 0 48 48");
|
||||||
|
|
||||||
|
const pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||||
|
pathElement.setAttribute("d",
|
||||||
|
"M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z");
|
||||||
|
|
||||||
|
svgElement.appendChild(pathElement);
|
||||||
|
|
||||||
|
buttonElement.appendChild(svgElement);
|
||||||
|
buttonElement.appendChild(document.createTextNode("Supprimer l'image de la réaction"));
|
||||||
|
|
||||||
|
newReactionElement.appendChild(buttonElement);
|
||||||
|
|
||||||
|
const reactionsElement = document.getElementById("reactions");
|
||||||
|
if (reactionsElement === null) {
|
||||||
|
// No add_reactions_selector element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reactionsElement.appendChild(newReactionElement);
|
||||||
|
|
||||||
|
reactionsDelta[traitId] = newReactionElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setListenersToImageInputs() {
|
||||||
|
for (const imageInput of document.getElementsByClassName("img_input")) {
|
||||||
|
imageInput.addEventListener("change", () => changeImageReaction(imageInput));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToImageReactionsRemovalButtons() {
|
||||||
|
for (const imageReactionRemovalButton of document.getElementsByClassName("delete_image_reaction_btn")) {
|
||||||
|
imageReactionRemovalButton.addEventListener("click", () => deleteImageReaction(imageReactionRemovalButton));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToAddReactionsSelector() {
|
||||||
|
const addReactionsSelectorElement = document.getElementById("add_reactions_selector");
|
||||||
|
if (addReactionsSelectorElement === null) {
|
||||||
|
// No add_reactions_selector element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addReactionsSelectorElement.addEventListener("change", () => addReaction(addReactionsSelectorElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
setListenersToImageReactionsRemovalButtons();
|
||||||
|
setListenersToImageInputs();
|
||||||
|
setListenersToAddReactionsSelector();
|
||||||
|
95
truthinquiry/static/js/admin_places.js
Normal file
95
truthinquiry/static/js/admin_places.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
function addPlace() {
|
||||||
|
const placeElement = document.createElement("div");
|
||||||
|
placeElement.classList.add("place");
|
||||||
|
|
||||||
|
const inputElement = document.createElement("input");
|
||||||
|
inputElement.classList.add("place_input");
|
||||||
|
inputElement.setAttribute("type", "text");
|
||||||
|
inputElement.setAttribute("id", "");
|
||||||
|
|
||||||
|
placeElement.appendChild(inputElement);
|
||||||
|
|
||||||
|
const buttonElement = document.createElement("button");
|
||||||
|
buttonElement.classList.add("delete_place_btn", "action_button", "short_color_transition");
|
||||||
|
buttonElement.setAttribute("title", "Cliquez ici pour supprimer ce lieu");
|
||||||
|
|
||||||
|
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||||
|
svgElement.classList.add("action_icon", "short_color_transition");
|
||||||
|
svgElement.setAttribute("viewBox", "0 0 48 48");
|
||||||
|
|
||||||
|
const pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||||
|
pathElement.setAttribute("d",
|
||||||
|
"M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z");
|
||||||
|
|
||||||
|
svgElement.appendChild(pathElement);
|
||||||
|
|
||||||
|
buttonElement.appendChild(svgElement);
|
||||||
|
buttonElement.appendChild(document.createTextNode("Supprimer le lieu"));
|
||||||
|
buttonElement.addEventListener("click", () => deletePlace(buttonElement));
|
||||||
|
|
||||||
|
placeElement.appendChild(buttonElement);
|
||||||
|
|
||||||
|
const placesElement = document.getElementById("places");
|
||||||
|
if (placesElement === null) {
|
||||||
|
// No places element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
placesElement.appendChild(placeElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deletePlace(placeRemoveButton) {
|
||||||
|
if (!confirm("Voulez-vous vraiement supprimer ce lieu ?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeElement = placeRemoveButton.parentNode;
|
||||||
|
placeElement.parentNode.removeChild(placeElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveChanges() {
|
||||||
|
const data = [];
|
||||||
|
for (const section of document.getElementsByClassName("place")) {
|
||||||
|
const place = {};
|
||||||
|
place["id"] = section.id;
|
||||||
|
place["name"] = section.querySelector("input").value;
|
||||||
|
data.push(place);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeAPIRequest("admin/setPlaces", {"places": data, "lang": "FR"}, {"content": "json"}).then(() => {
|
||||||
|
alert("Opération effectuée avec succès");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToPlaceAdditionButton() {
|
||||||
|
const addPlaceButton = document.getElementById("add_place");
|
||||||
|
if (addPlaceButton === null) {
|
||||||
|
// There is no add_place button, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlaceButton.addEventListener("click", addPlace);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToPlaceDeletionButtons() {
|
||||||
|
for (const deletePlaceButton of document.getElementsByClassName("delete_place_btn")) {
|
||||||
|
deletePlaceButton.addEventListener("click", () => deletePlace(deletePlaceButton));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToSaveChangesButton() {
|
||||||
|
const saveChangesButton = document.getElementById("save_changes");
|
||||||
|
if (saveChangesButton === null) {
|
||||||
|
// There is no save_changes button, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveChangesButton.addEventListener("click", saveChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
setListenersToPlaceDeletionButtons();
|
||||||
|
setListenersToPlaceAdditionButton();
|
||||||
|
setListenersToSaveChangesButton();
|
95
truthinquiry/static/js/admin_questions.js
Normal file
95
truthinquiry/static/js/admin_questions.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
function addQuestion(questionAddButton) {
|
||||||
|
const questionElement = document.createElement("div");
|
||||||
|
questionElement.classList.add("question");
|
||||||
|
|
||||||
|
const inputElement = document.createElement("input");
|
||||||
|
inputElement.classList.add("question_input");
|
||||||
|
inputElement.setAttribute("type", "text");
|
||||||
|
|
||||||
|
questionElement.appendChild(inputElement);
|
||||||
|
|
||||||
|
const buttonElement = document.createElement("button");
|
||||||
|
buttonElement.classList.add("delete_question_btn", "action_button", "short_color_transition");
|
||||||
|
buttonElement.setAttribute("title", "Cliquez ici pour supprimer cette question");
|
||||||
|
|
||||||
|
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||||
|
svgElement.classList.add("action_icon", "short_color_transition");
|
||||||
|
svgElement.setAttribute("viewBox", "0 0 48 48");
|
||||||
|
|
||||||
|
const pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||||
|
pathElement.setAttribute("d",
|
||||||
|
"M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z");
|
||||||
|
|
||||||
|
svgElement.appendChild(pathElement);
|
||||||
|
|
||||||
|
buttonElement.appendChild(svgElement);
|
||||||
|
buttonElement.appendChild(document.createTextNode("Supprimer la question"));
|
||||||
|
buttonElement.addEventListener("click", () => deleteQuestion(buttonElement));
|
||||||
|
|
||||||
|
questionElement.appendChild(buttonElement);
|
||||||
|
|
||||||
|
const questionTypeListElements = questionAddButton.parentNode.getElementsByClassName("question_type_list");
|
||||||
|
if (questionTypeListElements.length == 0) {
|
||||||
|
// No question_type_list element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There should be at most one question_type_list element per question type
|
||||||
|
questionTypeListElements[0].appendChild(questionElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteQuestion(questionRemoveButton) {
|
||||||
|
if (!confirm("Voulez-vous vraiement supprimer ce lieu ?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionElement = questionRemoveButton.parentNode;
|
||||||
|
questionElement.parentNode.removeChild(questionElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveChanges() {
|
||||||
|
const data = [];
|
||||||
|
|
||||||
|
for (const questionTypeNode of document.getElementsByClassName("question_type")) {
|
||||||
|
const questionsJson = [];
|
||||||
|
|
||||||
|
for (const questionNode of questionTypeNode.querySelectorAll(
|
||||||
|
".question_type_list .question .question_input")) {
|
||||||
|
questionsJson.push({"text": questionNode.value});
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionTypeJson = {"questions": questionsJson};
|
||||||
|
data.push(questionTypeJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeAPIRequest("admin/setQuestions", {"questions": data, "lang": "FR"}, {"content": "json"}).then(() => {
|
||||||
|
alert("Opération effectuée avec succès");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToQuestionAdditionButtons() {
|
||||||
|
for (const deleteQuestionButton of document.getElementsByClassName("add_question_btn")) {
|
||||||
|
deleteQuestionButton.addEventListener("click", () => addQuestion(deleteQuestionButton));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToQuestionDeletionButtons() {
|
||||||
|
for (const deleteQuestionButton of document.getElementsByClassName("delete_question_btn")) {
|
||||||
|
deleteQuestionButton.addEventListener("click", () => deleteQuestion(deleteQuestionButton));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToSaveChangesButton() {
|
||||||
|
const saveChangesButton = document.getElementById("save_changes");
|
||||||
|
if (saveChangesButton === null) {
|
||||||
|
// There is no save_changes button, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveChangesButton.addEventListener("click", saveChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
setListenersToQuestionAdditionButtons();
|
||||||
|
setListenersToQuestionDeletionButtons();
|
||||||
|
setListenersToSaveChangesButton();
|
127
truthinquiry/static/js/admin_traits.js
Normal file
127
truthinquiry/static/js/admin_traits.js
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
function addTrait() {
|
||||||
|
const traitElement = document.createElement("div");
|
||||||
|
traitElement.classList.add("trait");
|
||||||
|
traitElement.setAttribute("data-id", "");
|
||||||
|
|
||||||
|
const traitNameContainerElement = document.createElement("div");
|
||||||
|
traitNameContainerElement.classList.add("trait_name_container");
|
||||||
|
|
||||||
|
const traitNameTitleElement = document.createElement("h3");
|
||||||
|
traitNameTitleElement.classList.add("trait_name");
|
||||||
|
traitNameTitleElement.appendChild(document.createTextNode("Nom de la réaction\u00A0:"));
|
||||||
|
|
||||||
|
traitNameContainerElement.appendChild(traitNameTitleElement);
|
||||||
|
|
||||||
|
const traitNameInputElement = document.createElement("input");
|
||||||
|
traitNameInputElement.classList.add("trait_name_input");
|
||||||
|
traitNameInputElement.setAttribute("type", "text");
|
||||||
|
traitNameInputElement.setAttribute("value", "");
|
||||||
|
|
||||||
|
traitNameContainerElement.appendChild(traitNameInputElement);
|
||||||
|
|
||||||
|
traitElement.appendChild(traitNameContainerElement);
|
||||||
|
|
||||||
|
const traitDescriptionElement = document.createElement("div");
|
||||||
|
traitDescriptionElement.classList.add("trait_description_container");
|
||||||
|
|
||||||
|
const traitDescriptionTitleElement = document.createElement("h3");
|
||||||
|
traitDescriptionTitleElement.classList.add("trait_description");
|
||||||
|
traitDescriptionTitleElement.appendChild(document.createTextNode("Description de la réaction\u00A0:"));
|
||||||
|
|
||||||
|
traitDescriptionElement.appendChild(traitDescriptionTitleElement);
|
||||||
|
|
||||||
|
const traitDescriptionInputElement = document.createElement("input");
|
||||||
|
traitDescriptionInputElement.classList.add("trait_description_input");
|
||||||
|
traitDescriptionInputElement.setAttribute("type", "text");
|
||||||
|
traitDescriptionInputElement.setAttribute("value", "");
|
||||||
|
|
||||||
|
traitDescriptionElement.appendChild(traitDescriptionInputElement);
|
||||||
|
|
||||||
|
traitElement.appendChild(traitDescriptionElement);
|
||||||
|
|
||||||
|
const buttonElement = document.createElement("button");
|
||||||
|
buttonElement.classList.add("delete_trait_btn", "action_button", "short_color_transition");
|
||||||
|
buttonElement.setAttribute("title", "Cliquez ici pour supprimer cette réaction");
|
||||||
|
|
||||||
|
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||||
|
svgElement.classList.add("action_icon", "short_color_transition");
|
||||||
|
svgElement.setAttribute("viewBox", "0 0 48 48");
|
||||||
|
|
||||||
|
const pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||||
|
pathElement.setAttribute("d",
|
||||||
|
"M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z");
|
||||||
|
|
||||||
|
svgElement.appendChild(pathElement);
|
||||||
|
|
||||||
|
buttonElement.appendChild(svgElement);
|
||||||
|
buttonElement.appendChild(document.createTextNode("Supprimer la réaction"));
|
||||||
|
buttonElement.addEventListener("click", () => deleteTrait(buttonElement));
|
||||||
|
|
||||||
|
traitElement.appendChild(buttonElement);
|
||||||
|
|
||||||
|
const traitsElement = document.getElementById("traits");
|
||||||
|
if (traitsElement === null) {
|
||||||
|
// No places element, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
traitsElement.appendChild(traitElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTrait(traitDeletionButton) {
|
||||||
|
if (!confirm("Voulez-vous vraiement supprimer cette réaction ?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const traitNode = traitDeletionButton.parentNode;
|
||||||
|
traitNode.parentNode.removeChild(traitNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveChanges() {
|
||||||
|
const data = [];
|
||||||
|
|
||||||
|
for (const traitElement of document.getElementsByClassName("trait")) {
|
||||||
|
const trait = {};
|
||||||
|
trait["id"] = traitElement.getAttribute("data-id");
|
||||||
|
trait["name"] = traitElement.querySelector(".trait_name_input").value;
|
||||||
|
trait["desc"] = traitElement.querySelector(".trait_description_input").value;
|
||||||
|
data.push(trait);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeAPIRequest("admin/setTraits", {"traits": data, "lang": "FR"}, {"content": "json"}).then(() => {
|
||||||
|
alert("Opération effectuée avec succès");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToTraitDeletionButtons() {
|
||||||
|
for (const deleteTraitButton of document.getElementsByClassName("delete_trait_btn")) {
|
||||||
|
deleteTraitButton.addEventListener("click", () => deleteTrait(deleteTraitButton));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToTraitAdditionButton() {
|
||||||
|
const addTraitButton = document.getElementById("add_trait");
|
||||||
|
if (addTraitButton === null) {
|
||||||
|
// There is no add_place button, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addTraitButton.addEventListener("click", addTrait);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setListenersToSaveChangesButton() {
|
||||||
|
const saveChangesButton = document.getElementById("save_changes");
|
||||||
|
if (saveChangesButton === null) {
|
||||||
|
// There is no save_changes button, this should never happen
|
||||||
|
// Do nothing in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveChangesButton.addEventListener("click", saveChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
setListenersToTraitDeletionButtons();
|
||||||
|
setListenersToTraitAdditionButton();
|
||||||
|
setListenersToSaveChangesButton();
|
@ -22,7 +22,12 @@
|
|||||||
<label for="password" class="password_label">Mot de passe :</label>
|
<label for="password" class="password_label">Mot de passe :</label>
|
||||||
<input id="password" name="password" type="password" placeholder="Mot de passe" required="required" title="Saisissez votre mot de passe">
|
<input id="password" name="password" type="password" placeholder="Mot de passe" required="required" title="Saisissez votre mot de passe">
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" value="Connexion">
|
<button id="login_input_button" class="action_button short_color_transition" type="submit" title="Cliquez ici pour vous connecter à l'interface d'administration de Truth Inquiry">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
||||||
|
<path d="M483 959v-91h298V284H483v-92h298q36.125 0 63.562 27.206Q872 246.412 872 284v584q0 37.175-27.438 64.088Q817.125 959 781 959H483Zm-90-177-66-63 96-97H89v-91h332l-96-97 66-64 207 207-205 205Z"/>
|
||||||
|
</svg>
|
||||||
|
Connexion
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{% if failed %}
|
{% if failed %}
|
||||||
<p class="invalid_password">Mot de passe invalide !</p>
|
<p class="invalid_password">Mot de passe invalide !</p>
|
||||||
|
@ -29,12 +29,12 @@
|
|||||||
<ul class="character_list">
|
<ul class="character_list">
|
||||||
{%for npc in npcs%}
|
{%for npc in npcs%}
|
||||||
<li class="character_item">
|
<li class="character_item">
|
||||||
<a href="/admin/npc/{{npc['id']}}" title="Cliquez ici pour gérer le personnage « {{npc['name']}} »">{{npc['name']}}</a>
|
<a class="short_color_transition" href="/admin/npc/{{npc['id']}}" title="Cliquez ici pour gérer le personnage « {{npc['name']}} »">{{npc['name']}}</a>
|
||||||
</li>
|
</li>
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</ul>
|
</ul>
|
||||||
<a class="add_npc_link short_color_transition" href="/admin/npc/new" title="Cliquez ici pour créer un nouveau personnage">
|
<a class="add_npc_link short_color_transition" href="/admin/npc/new" title="Cliquez ici pour créer un nouveau personnage">
|
||||||
<svg class="add_npc_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
||||||
<path d="M435 871V622H185v-91h250V281h91v250h250v91H526v249h-91Z"/>
|
<path d="M435 871V622H185v-91h250V281h91v250h250v91H526v249h-91Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
Nouveau personnage
|
Nouveau personnage
|
||||||
|
@ -26,37 +26,41 @@
|
|||||||
<h1 class="page_title">Truth Inquiry - Interface d'administration</h1>
|
<h1 class="page_title">Truth Inquiry - Interface d'administration</h1>
|
||||||
<h2 class="page_category">{{'Gestion' if npc.get('id') else 'Ajout'}} d'un personnage</h2>
|
<h2 class="page_category">{{'Gestion' if npc.get('id') else 'Ajout'}} d'un personnage</h2>
|
||||||
<p class="page_description">Cliquez sur les champs pour éditer les informations. Dans les réponses aux questions lors de l'interrogation, utilisez « {NPC} » pour faire référence au nom d'un personnage et « {SALLE} » pour faire référence au nom d'une salle.</p>
|
<p class="page_description">Cliquez sur les champs pour éditer les informations. Dans les réponses aux questions lors de l'interrogation, utilisez « {NPC} » pour faire référence au nom d'un personnage et « {SALLE} » pour faire référence au nom d'une salle.</p>
|
||||||
<section>
|
<section id="character_info">
|
||||||
<h2 class="section_title">Informations sur le personnage</h2>
|
<h2 class="section_title">Informations sur le personnage</h2>
|
||||||
<input id="npc_id" value="{{ npc.get('id') or ''}}" hidden="hidden">
|
<input id="npc_id" value="{{ npc.get('id') or ''}}" type="hidden">
|
||||||
<p class="info_item">Nom du personnage</p>
|
<p class="info_item">Nom du personnage</p>
|
||||||
<input type="text" id="npc_name" value="{{ npc.get('name') or ''}}" title="Saisissez le nom du personnage" aria-label="Nom du personnage">
|
<input type="text" id="npc_name" value="{{ npc.get('name') or ''}}" title="Saisissez le nom du personnage" aria-label="Nom du personnage">
|
||||||
<p class="info_item">Image du personnage</p>
|
<p class="info_item">Image du personnage</p>
|
||||||
<img class="character_image" alt="{{'Image du personnage' + (' ' + npc.get('name') if npc.get('name') else '')}}" src="{{'/static/images/no_photography_white.svg' if npc.get('img') == None else '/api/v1/getNpcImage?npcid=' + npc.get('img')|string}}">
|
<img class="character_image" alt="{{'Image du personnage' + (' ' + npc.get('name') if npc.get('name') else '')}}" src="{{'/static/images/no_photography_white.svg' if npc.get('img') == None else '/api/v1/getNpcImage?npcid=' + npc.get('img')|string}}">
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="reactions">
|
<section id="reactions">
|
||||||
<h2 class="section_title">Réactions</h2>
|
<h2 class="section_title">Images des réactions</h2>
|
||||||
|
{%for reaction in npc.get("reactions") or []%}
|
||||||
{%for reaction in npc.get("reactions") or []%}
|
<section class="reaction">
|
||||||
<div>
|
<h3 class="reaction_name">{{reaction.get('name')}}</h3>
|
||||||
<p> {{reaction.get('name')}} </p>
|
<img class="reaction_image" alt="Image d'une réaction d'un personnage" src="{{reaction.get('url')}}">
|
||||||
<img src="{{reaction.get('url')}}" style="max-width: 100; max-height: 100px">
|
<input class="img_input" type="file" accept="image/png, image/jpg, image/jpeg">
|
||||||
<input class="img_input", type="file" accept="image/png, image/jpeg" onchange="changeReaction(this)">
|
<input class="trait_id" type="hidden" value="{{reaction.get('trait_id')}}">
|
||||||
<input class="trait_id", type="hidden" value="{{reaction.get('trait_id')}}">
|
<button class="delete_image_reaction_btn action_button short_color_transition" title="Cliquez ici pour supprimer l'image de cette réaction">
|
||||||
<button onclick="deleteReaction(this)">Delete reaction</button>
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
</div>
|
<path d="M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z"/>
|
||||||
{%endfor%}
|
</svg>
|
||||||
</section>
|
Supprimer l'image de la réaction
|
||||||
|
</button>
|
||||||
<select id="reactions_to_add" onchange="addReaction(this)">
|
</section>
|
||||||
<option value="" default></option>
|
|
||||||
{%for reaction_to_add in npc.get("reactions_to_add") or []%}
|
|
||||||
<option value="{{reaction_to_add.get('trait_id')}}">{{reaction_to_add.get('name')}}</option>
|
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</select>
|
</section>
|
||||||
|
<section id="add_reactions">
|
||||||
<section>
|
<h2 class="section_title">Réactions à ajouter</h2>
|
||||||
|
<select id="add_reactions_selector">
|
||||||
|
<option value="" selected="selected">Sélectionnez une réaction à ajouter</option>
|
||||||
|
{%for reaction_to_add in npc.get("reactions_to_add") or []%}
|
||||||
|
<option value="{{reaction_to_add.get('trait_id')}}">{{reaction_to_add.get('name')}}</option>
|
||||||
|
{%endfor%}
|
||||||
|
</select>
|
||||||
|
</section>
|
||||||
|
<section id="interrogation_answers">
|
||||||
<h2 class="section_title">Réponses aux questions lors de l'interrogation</h2>
|
<h2 class="section_title">Réponses aux questions lors de l'interrogation</h2>
|
||||||
<div class="answer_groups">
|
<div class="answer_groups">
|
||||||
{%for answer_type in npc.get("answers") or []%}
|
{%for answer_type in npc.get("answers") or []%}
|
||||||
@ -95,7 +99,8 @@
|
|||||||
<div class="alert_dialog_background"></div>
|
<div class="alert_dialog_background"></div>
|
||||||
<dialog>
|
<dialog>
|
||||||
<h3 class="alert_dialog_title">JavaScript nécessaire</h3>
|
<h3 class="alert_dialog_title">JavaScript nécessaire</h3>
|
||||||
<p class="alert_dialog_msg unsupported_browser_msg">Désolé, mais JavaScript est nécessaire pour faire fonctionner cette page. Veuillez l'activer dans votre navigateur ou en utiliser un qui le supporte afin de pouvoir ajouter ou gérer un personnage.</p>
|
<p class="alert_dialog_msg">Désolé, mais JavaScript est nécessaire pour faire fonctionner cette page. Veuillez l'activer dans votre navigateur ou en utiliser un qui le supporte afin de pouvoir ajouter ou gérer un personnage.</p>
|
||||||
|
<a class="alert_dialog_bottom_link short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Se déconnecter de l'interface d'administration du jeu</a>
|
||||||
</dialog>
|
</dialog>
|
||||||
</noscript>
|
</noscript>
|
||||||
<script src="/static/js/api.js"></script>
|
<script src="/static/js/api.js"></script>
|
||||||
|
@ -1,26 +1,65 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<title>Places</title>
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="admin_ui.css">
|
<title>Truth Inquiry - Gestion des lieux</title>
|
||||||
<script src="/static/js/admin.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui.css">
|
||||||
<script src="/static/js/api.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui_places.css">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_32.png" type="image/png" sizes="32x32">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_64.png" type="image/png" sizes="64x64">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_96.png" type="image/png" sizes="96x96">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_128.png" type="image/png" sizes="128x128">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_192.png" type="image/png" sizes="192x192">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="256x256">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="512x512">
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="/admin"> go Back </a> <br>
|
<header>
|
||||||
|
<a class="short_color_transition" href="/admin" title="Cliquez ici pour revenir à l'accueil de l'interface d'administration du jeu">Accueil</a>
|
||||||
|
<a class="short_color_transition" href="/admin/questions" title="Cliquez ici pour gérer les questions du jeu">Gestion des questions</a>
|
||||||
<section id="places">
|
<a class="short_color_transition" href="/admin/places" title="Cliquez ici pour gérer les lieux du jeu">Gestion des lieux</a>
|
||||||
|
<a class="short_color_transition" href="/admin/traits" title="Cliquez ici pour gérer les réactions du jeu">Gestion des réactions</a>
|
||||||
|
<a class="short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Déconnexion</a>
|
||||||
|
</header>
|
||||||
|
<h1 class="page_title">Truth Inquiry - Interface d'administration</h1>
|
||||||
|
<h2 class="page_category">Gestion des lieux</h2>
|
||||||
|
<p class="page_description">Cliquez sur les champs pour éditer les lieux.</p>
|
||||||
|
<div id="places">
|
||||||
{%for place in places%}
|
{%for place in places%}
|
||||||
<section id="{{place['id']}}">
|
<div id="{{place['id']}}" class="place">
|
||||||
<input value="{{place['name']}}">
|
<input class="place_input" type="text" value="{{place['name']}}">
|
||||||
<button onclick="deleteInputPlaces(this)">Delete place</button>
|
<button class="delete_place_btn action_button short_color_transition" title="Cliquez ici pour supprimer ce lieu">
|
||||||
</section>
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
|
<path d="M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z"/>
|
||||||
|
</svg>
|
||||||
|
Supprimer le lieu
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</section>
|
</div>
|
||||||
<button onclick="addInputPlaces()">Add new</button>
|
<button id="add_place" class="action_button short_color_transition" title="Cliquez ici pour ajouter un lieu">
|
||||||
<button onclick="saveFormPlaces()">Save changes</button>
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
||||||
|
<path d="M435 871V622H185v-91h250V281h91v250h250v91H526v249h-91Z"/>
|
||||||
|
</svg>
|
||||||
|
Ajouter un lieu
|
||||||
|
</button>
|
||||||
|
<button id="save_changes" class="action_button short_color_transition" title="Cliquez ici pour enregistrer vos changements">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
|
<path d="M18.9 36.75 6.65 24.5l3.3-3.3 8.95 9L38 11.1l3.3 3.25Z"/>
|
||||||
|
</svg>
|
||||||
|
Sauvegarder les changements
|
||||||
|
</button>
|
||||||
|
<noscript>
|
||||||
|
<div class="alert_dialog_background"></div>
|
||||||
|
<dialog>
|
||||||
|
<h3 class="alert_dialog_title">JavaScript nécessaire</h3>
|
||||||
|
<p class="alert_dialog_msg">Désolé, mais JavaScript est nécessaire pour faire fonctionner cette page. Veuillez l'activer dans votre navigateur ou en utiliser un qui le supporte afin de pouvoir gérer les lieux.</p>
|
||||||
|
<a class="alert_dialog_bottom_link short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Se déconnecter de l'interface d'administration du jeu</a>
|
||||||
|
</dialog>
|
||||||
|
</noscript>
|
||||||
|
<script src="/static/js/api.js"></script>
|
||||||
|
<script src="/static/js/admin_places.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,34 +1,70 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<title>Admin Page</title>
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="admin_ui.css">
|
<title>Truth Inquiry - Gestion des questions</title>
|
||||||
<script src="/static/js/admin.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui.css">
|
||||||
<script src="/static/js/api.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui_questions.css">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_32.png" type="image/png" sizes="32x32">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_64.png" type="image/png" sizes="64x64">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_96.png" type="image/png" sizes="96x96">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_128.png" type="image/png" sizes="128x128">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_192.png" type="image/png" sizes="192x192">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="256x256">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="512x512">
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<header>
|
||||||
<a href="/admin"> go Back </a> <br>
|
<a class="short_color_transition" href="/admin" title="Cliquez ici pour revenir à l'accueil de l'interface d'administration du jeu">Accueil</a>
|
||||||
|
<a class="short_color_transition" href="/admin/questions" title="Cliquez ici pour gérer les questions du jeu">Gestion des questions</a>
|
||||||
<section id="allQuestions">
|
<a class="short_color_transition" href="/admin/places" title="Cliquez ici pour gérer les lieux du jeu">Gestion des lieux</a>
|
||||||
{%for questionType in questions%}
|
<a class="short_color_transition" href="/admin/traits" title="Cliquez ici pour gérer les réactions du jeu">Gestion des réactions</a>
|
||||||
<div class="questionType">
|
<a class="short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Déconnexion</a>
|
||||||
<section class="questionTypeContent">
|
</header>
|
||||||
{%for question in questionType["questions"]%}
|
<h1 class="page_title">Truth Inquiry - Interface d'administration</h1>
|
||||||
<section class="question">
|
<h2 class="page_category">Gestion des questions</h2>
|
||||||
<input value="{{question['text']}}">
|
<p class="page_description">Cliquez sur les champs pour éditer les questions.</p>
|
||||||
<button onclick="deleteInputQuestions(this)">Delete question</button>
|
{%for questionType in questions%}
|
||||||
</section>
|
<section class="question_type">
|
||||||
{%endfor%}
|
<h3 class="question_type_title">Type de question {{loop.index0}}</h3>
|
||||||
</section>
|
<div class="question_type_list">
|
||||||
<button onclick="addInputQuestions(this)">Add new</button>
|
{%for question in questionType["questions"]%}
|
||||||
|
<div class="question">
|
||||||
|
<input class="question_input" type="text" value="{{question['text']}}">
|
||||||
|
<button class="delete_question_btn action_button short_color_transition" title="Cliquez ici pour supprimer cette question">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
|
<path d="M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z"/>
|
||||||
|
</svg>
|
||||||
|
Supprimer la question
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{%endfor%}
|
||||||
</div>
|
</div>
|
||||||
{%endfor%}
|
<button class="add_question_btn action_button short_color_transition" title="Cliquez ici pour ajouter une question au type {{loop.index0}}">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
||||||
|
<path d="M435 871V622H185v-91h250V281h91v250h250v91H526v249h-91Z"/>
|
||||||
|
</svg>
|
||||||
|
Ajouter une question
|
||||||
|
</button>
|
||||||
</section>
|
</section>
|
||||||
|
{%endfor%}
|
||||||
<br>
|
<button id="save_changes" class="action_button short_color_transition" title="Cliquez ici pour enregistrer vos changements">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
<button onclick="saveFormQuestions()"> Save changes </button>
|
<path d="M18.9 36.75 6.65 24.5l3.3-3.3 8.95 9L38 11.1l3.3 3.25Z"/>
|
||||||
|
</svg>
|
||||||
|
Sauvegarder les changements
|
||||||
|
</button>
|
||||||
|
<noscript>
|
||||||
|
<div class="alert_dialog_background"></div>
|
||||||
|
<dialog>
|
||||||
|
<h3 class="alert_dialog_title">JavaScript nécessaire</h3>
|
||||||
|
<p class="alert_dialog_msg">Désolé, mais JavaScript est nécessaire pour faire fonctionner cette page. Veuillez l'activer dans votre navigateur ou en utiliser un qui le supporte afin de pouvoir gérer les questions.</p>
|
||||||
|
<a class="alert_dialog_bottom_link short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Se déconnecter de l'interface d'administration du jeu</a>
|
||||||
|
</dialog>
|
||||||
|
</noscript>
|
||||||
|
<script src="/static/js/api.js"></script>
|
||||||
|
<script src="/static/js/admin_questions.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,29 +1,72 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<title>Traits</title>
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="admin_ui.css">
|
<title>Truth Inquiry - Gestion des réactions</title>
|
||||||
<script src="/static/js/api.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui.css">
|
||||||
<script src="/static/js/admin.js"></script>
|
<link rel="stylesheet" href="/static/css/admin_ui_traits.css">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_32.png" type="image/png" sizes="32x32">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_64.png" type="image/png" sizes="64x64">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_96.png" type="image/png" sizes="96x96">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_128.png" type="image/png" sizes="128x128">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_192.png" type="image/png" sizes="192x192">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="256x256">
|
||||||
|
<link rel="icon" href="/static/images/favicon/favicon_256.png" type="image/png" sizes="512x512">
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="/admin"> go Back </a> <br>
|
<header>
|
||||||
|
<a class="short_color_transition" href="/admin" title="Cliquez ici pour revenir à l'accueil de l'interface d'administration du jeu">Accueil</a>
|
||||||
<section id="traits">
|
<a class="short_color_transition" href="/admin/questions" title="Cliquez ici pour gérer les questions du jeu">Gestion des questions</a>
|
||||||
|
<a class="short_color_transition" href="/admin/places" title="Cliquez ici pour gérer les lieux du jeu">Gestion des lieux</a>
|
||||||
|
<a class="short_color_transition" href="/admin/traits" title="Cliquez ici pour gérer les réactions du jeu">Gestion des réactions</a>
|
||||||
|
<a class="short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Déconnexion</a>
|
||||||
|
</header>
|
||||||
|
<h1 class="page_title">Truth Inquiry - Interface d'administration</h1>
|
||||||
|
<h2 class="page_category">Gestion des réactions</h2>
|
||||||
|
<p class="page_description">Cliquez sur les champs pour éditer les informations. Les images des émotions sont disponibles par personnage dans leur page de gestion dédiée.</p>
|
||||||
|
<div id="traits">
|
||||||
{%for trait in traits%}
|
{%for trait in traits%}
|
||||||
<section id="{{trait['id']}}">
|
<div data-id="{{trait['id']}}" class="trait">
|
||||||
<p> Name: </p>
|
<div class="trait_name_container">
|
||||||
<input class="name_input" value="{{trait['name']}}">
|
<h3 class="trait_name">Nom de la réaction :</h3>
|
||||||
<p> Description: </p>
|
<input type="text" class="trait_name_input" value="{{trait['name']}}">
|
||||||
<input class="desc_input" value="{{trait['desc']}}">
|
</div>
|
||||||
<button onclick="deleteInputTraits(this)">Delete trait</button>
|
<div class="trait_description_container">
|
||||||
</section>
|
<h3 class="trait_description">Description de la réaction :</h3>
|
||||||
|
<input type="text" class="trait_description_input" value="{{trait['desc']}}">
|
||||||
|
</div>
|
||||||
|
<button class="delete_trait_btn action_button short_color_transition">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
|
<path d="M12.45 38.7 9.3 35.55 20.85 24 9.3 12.5l3.15-3.2L24 20.8 35.55 9.3l3.15 3.2L27.2 24l11.5 11.55-3.15 3.15L24 27.2Z"/>
|
||||||
|
</svg>
|
||||||
|
Supprimer la réaction
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</section>
|
</div>
|
||||||
<button onclick="addInputTraits()">Add new</button>
|
<button id="add_trait" class="action_button short_color_transition">
|
||||||
<button onclick="saveFormTraits()">Save changes</button>
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
|
||||||
|
<path d="M435 871V622H185v-91h250V281h91v250h250v91H526v249h-91Z"/>
|
||||||
<p>Images are viewable in the npc views</p>
|
</svg>
|
||||||
|
Ajouter une nouvelle réaction
|
||||||
|
</button>
|
||||||
|
<button id="save_changes" class="action_button short_color_transition">
|
||||||
|
<svg class="action_icon short_color_transition" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 48 48">
|
||||||
|
<path d="M18.9 36.75 6.65 24.5l3.3-3.3 8.95 9L38 11.1l3.3 3.25Z"/>
|
||||||
|
</svg>
|
||||||
|
Sauvegarder les changements
|
||||||
|
</button>
|
||||||
|
<noscript>
|
||||||
|
<div class="alert_dialog_background"></div>
|
||||||
|
<dialog>
|
||||||
|
<h3 class="alert_dialog_title">JavaScript nécessaire</h3>
|
||||||
|
<p class="alert_dialog_msg">Désolé, mais JavaScript est nécessaire pour faire fonctionner cette page. Veuillez l'activer dans votre navigateur ou en utiliser un qui le supporte afin de pouvoir gérer les émotions.</p>
|
||||||
|
<a class="alert_dialog_bottom_link short_color_transition" href="/api/v1/admin/logout" title="Cliquez ici pour vous déconnecter de l'interface d'administration du jeu">Se déconnecter de l'interface d'administration du jeu</a>
|
||||||
|
</dialog>
|
||||||
|
</noscript>
|
||||||
|
<script src="/static/js/api.js"></script>
|
||||||
|
<script src="/static/js/admin_traits.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user