From cc75b02f6db2a336195a90cea60e74da3932fac2 Mon Sep 17 00:00:00 2001
From: SofianeLasri <alasri250@gmail.com>
Date: Tue, 10 Aug 2021 15:02:47 +0200
Subject: [PATCH] 15H02 - Settings users+userGroups

---
 vbcms-admin/backTasks.php                     |  23 +++
 vbcms-admin/css/manager.css                   |  17 ++
 vbcms-admin/includes/settings/general.php     |  24 ++-
 vbcms-admin/includes/settings/groups.php      |  66 +++++++
 vbcms-admin/includes/settings/users.php       | 176 +++++++++++++++++-
 vbcms-admin/includes/settingsPage.php         |  22 +--
 .../vbcms-loadingscreens/admin/browse.php     |   3 +-
 .../vbcms-loadingscreens/admin/edit.php       |  12 +-
 .../extensions/vbcms-loadingscreens/init.php  |  14 +-
 vbcms-content/translations/FR.php             |   8 +-
 10 files changed, 319 insertions(+), 46 deletions(-)
 create mode 100644 vbcms-admin/includes/settings/groups.php

diff --git a/vbcms-admin/backTasks.php b/vbcms-admin/backTasks.php
index 25f20cc..520f180 100644
--- a/vbcms-admin/backTasks.php
+++ b/vbcms-admin/backTasks.php
@@ -176,6 +176,29 @@ if (isset($_GET["getNotifications"])) {
 		$fixedAssoc = $bdd->prepare("UPDATE `vbcms-baseModulesAssoc` SET extensionName = ? WHERE name = ?");
 		$fixedAssoc->execute([$extName, $assocName]);
 	}
+} elseif (isset($_GET["getNetIdLocalAccount"])&&!empty($_GET["getNetIdLocalAccount"]) && verifyUserPermission($_SESSION['user_id'], "vbcms", 'manageUsersSettings')){
+	$localAccountExist = $bdd->prepare("SELECT * FROM `vbcms-localAccounts` WHERE netIdAssoc = ?");
+	$localAccountExist->execute([$_GET["getNetIdLocalAccount"]]);
+	$localAccountExist = $localAccountExist->fetch(PDO::FETCH_ASSOC);
+	echo json_encode($localAccountExist);
+	
+}  elseif (isset($_GET["changeUserGroup"])&&!empty($_GET["changeUserGroup"]) && verifyUserPermission($_SESSION['user_id'], "vbcms", 'manageUsersSettings')){
+	$modificationDetail = json_decode($_GET["changeUserGroup"], true);
+	$query = $bdd->prepare("UPDATE `vbcms-users` SET `groupId` = ? WHERE `vbcms-users`.`netId` = ?");
+	$query->execute([$modificationDetail['groupId'], $modificationDetail['netId']]);
+	
+} elseif (isset($_GET["setNetIdLocalAccount"])&&!empty($_GET["setNetIdLocalAccount"]) && (isset($_POST)&&!empty($_POST))  && verifyUserPermission($_SESSION['user_id'], "vbcms", 'manageUsersSettings')) {
+	$localAccountExist = $bdd->prepare("SELECT * FROM `vbcms-localAccounts` WHERE netIdAssoc = ?");
+	$localAccountExist->execute([$_GET["setNetIdLocalAccount"]]);
+	$localAccountExist = $localAccountExist->fetch(PDO::FETCH_ASSOC);
+	
+	if(!empty($localAccountExist)){
+		$modify = $bdd->prepare("UPDATE `vbcms-localAccounts` SET username = ?, password = ? WHERE netIdAssoc = ?");
+		$modify->execute([$_POST['localUserUsername'], password_hash($_POST['localUserPassword1'], PASSWORD_DEFAULT), $_GET["setNetIdLocalAccount"]]);
+	}else{
+		$query = $bdd->prepare('INSERT INTO `vbcms-localAccounts` (`id`, `netIdAssoc`, `username`, `password`, `profilePic`) VALUES (NULL, ?,?,?,?)');
+		$query->execute([$_GET["setNetIdLocalAccount"], $_POST['localUserUsername'], password_hash($_POST['localUserPassword1'], PASSWORD_DEFAULT), VBcmsGetSetting("websiteUrl")."vbcms-admin/images/misc/programmer.png"]);
+	}
 } elseif(isset($_GET)&&!empty($_GET)){
 	echo "Commande \"".array_key_first($_GET)."(".$_GET[array_key_first($_GET)].")\" non reconnue.";
 } else {?>
diff --git a/vbcms-admin/css/manager.css b/vbcms-admin/css/manager.css
index 2550cb1..74a33c9 100644
--- a/vbcms-admin/css/manager.css
+++ b/vbcms-admin/css/manager.css
@@ -771,8 +771,25 @@ header .menu-item{
 	padding: .5em;
 }
 
+.userCard .roundedLink{
+	position: relative;
+	width: 25px;
+	height: 25px;
+	border-radius: 50%;
+	background-color: #dadada;
+	color: #6c757d;
+}
+
+.userCard .roundedLink i{
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+}
+
 .userCard:hover{
 	background-color: #dadada;
+	cursor: pointer;
 }
 
 .userCard .userProfilPic{
diff --git a/vbcms-admin/includes/settings/general.php b/vbcms-admin/includes/settings/general.php
index 3c878d0..4da3e95 100644
--- a/vbcms-admin/includes/settings/general.php
+++ b/vbcms-admin/includes/settings/general.php
@@ -131,4 +131,26 @@
             </div>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
+
+<script type="text/javascript">
+function saveChanges(){
+    $.post( "<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/backTasks?saveSettings", $( "#form" ).serialize() )
+    .done(function( data ) {
+        if(data!=""){
+            SnackBar({
+                message: data,
+                status: "danger",
+                timeout: false
+            });
+        } else {
+            SnackBar({
+                message: '<?=translate("success-saving")?>',
+                status: "success"
+            });
+            // On peut reload le contenu de la page avec cette fonction
+            setSettingsContent();
+        }
+    });
+}
+</script>
\ No newline at end of file
diff --git a/vbcms-admin/includes/settings/groups.php b/vbcms-admin/includes/settings/groups.php
new file mode 100644
index 0000000..682add0
--- /dev/null
+++ b/vbcms-admin/includes/settings/groups.php
@@ -0,0 +1,66 @@
+<div class="d-flex">
+    <div class="flex-grow-1 d-flex flex-column">
+        <div class="mt-2">
+            <button class="btn btn-sm btn-brown" data-toggle="modal" data-target="#createGroupModal"><i class="fas fa-users"></i> <?=translate('createGroup')?></button>
+            <!--<a href="#" class="btn btn-outline-brown btn-sm"><i class="fas fa-user-plus"></i> <?=translate('localAccountCreation')?></a>-->
+        </div>
+
+        <div class="d-flex p-4">
+            <div style="min-width:360px;">
+                <h5>Groupes</h5>
+                <table style="width:100%;">
+                    <tbody>
+                        <?php
+                            $userGroups=$bdd->query("SELECT * FROM `vbcms-userGroups` ORDER BY `groupId` ASC")->fetchAll(PDO::FETCH_ASSOC);
+                            foreach($userGroups as $userGroup){
+                                $systemGroups = ["superadmins", "admins", "users"];
+                                if(in_array($userGroup['groupName'], $systemGroups)) $modify = false;
+                                else $modify = true;
+                                $usersCount = $bdd->prepare("SELECT COUNT(*) FROM `vbcms-users` WHERE groupId = ?");
+                                $usersCount->execute([$userGroup['groupId']]);
+                                $usersCount=$usersCount->fetchColumn();
+                                
+                                echo('<tr class="userCard" style="height:2em;">
+                                <th>
+                                    <span>'.translate($userGroup['groupName']).'</span>
+                                </th>
+                                <td>
+                                    <span class="text-muted">'.$usersCount.' <i class="fas fa-user"></i></span>
+                                </td>
+                                <td>
+                                    <div class="roundedLink" data-toggle="tooltip" data-placement="top" title="Plus"><i class="fas fa-ellipsis-h"></i></div>
+                                </td>
+                            </tr>');
+                            }
+                        ?>
+                    </tbody>
+                </table>
+            </div>
+            <div class="flex-fill">
+                <h5>Permissions</h5>
+            </div>
+        </div>
+    </div>
+    <div class="admin-tips" style="position: relative !important; ">
+        <div class="tip">
+            <h5>Gérer les groupes</h5>
+            <p>Les groupes d'utilisateurs permettent de faciliter la gestion des permissions. 
+            <br><br><strong>Par défaut, chaque nouvel utilisateur est affecté au groupe des utilisateurs.</strong> Ce groupe ne permet pas l'accès au panneau d'administration et ne possède par défaut aucune permission.
+            <br><br><strong>Chaque utilisateur d'un groupe héritera les permissions de ce dernier</strong>, sauf s'il possède ses propres permissions (qui remplaceront celles du groupe).</p>
+        </div>
+    </div>
+</div>
+
+<script type="text/javascript">
+$(function() {
+    $('.userCard').hover(function() {
+        $(this).find('.roundedLink').css('background-color', 'var(--mainBrown)');
+        $(this).find('.roundedLink').css('color', 'white');
+    }, function() {
+        // on mouseout, reset the background colour
+        $(this).find('.roundedLink').css('background-color', '#dadada');
+        $(this).find('.roundedLink').css('color', '#6c757d');
+    });
+});
+
+</script>
\ No newline at end of file
diff --git a/vbcms-admin/includes/settings/users.php b/vbcms-admin/includes/settings/users.php
index 958eb86..04d48a0 100644
--- a/vbcms-admin/includes/settings/users.php
+++ b/vbcms-admin/includes/settings/users.php
@@ -61,14 +61,14 @@
                             <div class="userProfilPic" style="background-image:url(\''.$userProfilPic.'\')"></div>
                             <div class="ml-2">
                                 <h6 class="mb-n1">'.$user['username'].'</h6>
-                                <small class="text-muted">'.translate('joinedOn').': '. $joinedDate->format('l jS F').'</small><br>
-                                <small><a href="#" class="text-brown">'.translate("modifyUser").'</a></small>
+                                <small class="text-muted">'.translate('joinedOn').': '. $joinedDate->format('l jS F Y').'</small><br>
+                                <small><a href="#" onclick="toogle(\'edit-'.$user['username'].'\')" class="text-brown">'.translate("modifyUser").'</a> <a href="#" onclick="editLocalAccount(\''.$user['netId'].'\')" class="text-brown">'.translate("modifyLocalAccount").'</a></small>
                             </div>
                         </div>');
-                        echo ('<div class="d-flex flex-column mt-2" id="edit-'.$user['username'].'">
+                        echo ('<div id="edit-'.$user['username'].'" style="display: none;"><div class="d-flex flex-column mt-2"">
                             <div class="form-inline">
                                 <label>Changer de groupe</label>
-                                <select class="form-control form-control-sm flex-grow-1 ml-2" id="newGroup">
+                                <select class="form-control form-control-sm flex-grow-1 ml-2" id="groupUser'.$user['netId'].'" onchange="changeUserGroup('.$user['netId'].')">
                                     '.$groupsOptions.'
                                 </select>
                             </div>
@@ -76,15 +76,15 @@
                                 <button class="btn btn-sm btn-brown">Modifier ses permissions</button>
                                 <button class="btn btn-sm btn-danger ml-2">Expulser</button>
                             </div>
-                        </div>');
+                        </div></div>');
                     }else{
                         echo ('<div class="userCard d-flex flex-column">
                         <div class="d-flex">
                             <div class="userProfilPic" style="background-image:url(\''.$userProfilPic.'\')"></div>
                             <div class="ml-2">
                                 <h6 class="mb-n1">'.$user['username'].'</h6>
-                                <small class="text-muted">'.translate('joinedOn').': '. $joinedDate->format('l jS F').'</small><br>
-                                <small class="text-brown">Toi :)</small>
+                                <small class="text-muted">'.translate('joinedOn').': '. $joinedDate->format('l jS F Y').'</small><br>
+                                <small class="text-brown"><a href="#" onclick="editLocalAccount(\''.$user['netId'].'\')" class="text-brown">'.translate("modifyLocalAccount").'</a></small>
                             </div>
                         </div>');
                     }
@@ -114,7 +114,7 @@
     <div class="admin-tips" style="position: relative !important; ">
         <div class="tip">
             <h5>Gérer les utilisateurs</h5>
-            <p>VBcms peut être utilisé par plusieurs peronnes en même temps. Ici tu peux gérer leur compte, mais également inviter d'autres personnes.<br><strong>Fais bien attention à qui aura accès au panneau d'administration.</strong></p>
+            <p>VBcms peut être utilisé par plusieurs personnes en même temps. Ici tu peux gérer leur compte, mais également inviter d'autres personnes.<br><strong>Fais bien attention à qui aura accès au panneau d'administration.</strong></p>
         </div>
     </div>
 </div>
@@ -157,7 +157,165 @@
     </div>
 </div>
 
+<div class="modal fade" id="localAccountCreationModal" >
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header bg-brown text-white">
+                <h5 id="extensionActivationModalTitle" class="modal-title"><?=translate('modifyLocalAccount')?></h5>
+                <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form id="localAccountCreationForm" class="needs-validation" novalidate>
+                    <div class="form-group">
+                        <label><?=translate('username')?></label>
+                        <input type="text" class="form-control" name="localUserUsername" id="localUserUsername" placeholder="" value="<?=$_SESSION['user_username']?>" required>
+                        <small class="form-text text-muted"><?=translate("localAccountCreation_loginCanBeDifferent")?></small>
+                        <div class="invalid-feedback"><?=translate("localAccountCreation_pleaseEnterLogin")?></div>
+                    </div>
+                    <div class="form-group">
+                        <label><?=translate('password')?></label>
+                        <input type="password" class="form-control" name="localUserPassword1" id="localUserPassword1" placeholder="" required>
+                        <div class="invalid-feedback" id="localUserPassword1Alert">
+                            <?=translate('localAccountCreation_youCreateAnAccountWithoutPassword')?> <img height="16" src="<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/images/emojis/thinkingHard.png">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label><?=translate('repeatPassword')?></label>
+                        <input type="password" class="form-control" name="localUserPassword2" id="localUserPassword2" placeholder="" required>
+                        <div class="invalid-feedback" id="localUserPassword2Alert"><?=translate("localAccountCreation_pleaseRewriteYourPassword")?></div>
+                    </div>
+
+                    <div>
+                        <h5><?=translate("whyCreateALocalAccount")?></h5>
+                        <p>Autant le dire tout de suite, les serveurs de VBcms ne sont pas réputés pour être très fiables... Il sera assez fréquent de les voir inaccessibles, surtout à ce stade du développement.<br><br><strong>Le compte local te permettera d'accéder au panneau d'administration, même en cas de panne générale.</strong> Tu ne pourras pas télécharger d'extensions ni mettre VBcms à jour, mais au moins tu pourras continuer à gérer ton site. :D</p>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-outline-brown" data-dismiss="modal"><?=translate("cancel")?></button>
+                    <button id="registerBtn" type="button" class="btn btn-brown" disabled><?=translate("create")?></button>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+
 <script type="text/javascript">
+(function() {
+'use strict';
+window.addEventListener('load', function() {
+    // Fetch all the forms we want to apply custom Bootstrap validation styles to
+    var forms = document.getElementsByClassName('needs-validation');
+    // Loop over them and prevent submission
+    var validation = Array.prototype.filter.call(forms, function(form) {
+    form.addEventListener('submit', function(event) {
+        if (form.checkValidity() === false) {
+        event.preventDefault();
+        event.stopPropagation();
+        }
+        form.classList.add('was-validated');
+    }, false);
+    });
+}, false);
+})();
+
+function editLocalAccount(netId) {
+    $.get("<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/backTasks/?getNetIdLocalAccount="+netId, function(data) {
+        var json = JSON.parse(data);
+        if(!jQuery.isEmptyObject(json)){
+            $("#localUserUsername").val(json.username);
+        } else{
+            $("#localUserUsername").val("");
+        }
+    });
+    $("#registerBtn").attr("onclick", "sendLocalAccountInfos('"+netId+"')");
+    $('#localAccountCreationModal').modal('show');
+}
+
+$("#localUserPassword1").change(function() {
+    checkPassword();
+});
+$("#localUserPassword2").change(function() {
+    checkPassword();
+});
+
+function sendLocalAccountInfos(netId){
+    $.post( "<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/backTasks?setNetIdLocalAccount="+netId, $( "#localAccountCreationForm" ).serialize() )
+    .done(function( data ) {
+        if(data!=""){
+            SnackBar({
+                message: data,
+                status: "danger",
+                timeout: false
+            });
+        } else {
+            SnackBar({
+                message: '<?=translate("success-saving")?>',
+                status: "success"
+            });
+            $('#localAccountCreationModal').modal('hide');
+        }
+    });
+}
+
+function changeUserGroup(netId){
+    var array = {
+        netId: netId,
+        groupId: $("#groupUser"+netId).val()
+    };
+    $.get("<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/backTasks/?changeUserGroup="+JSON.stringify(array), function(data) {
+        if(data!=""){
+            SnackBar({
+                message: data,
+                status: "danger",
+                timeout: false
+            });
+        } else {
+            SnackBar({
+                message: '<?=translate("success-saving")?>',
+                status: "success"
+            });
+        }
+    });
+
+    
+}
+
+function checkPassword(){
+    if ($("#localUserPassword1").val()!=$("#localUserPassword2").val()) {
+        $("#localUserPassword1Alert").html("<?=translate("localAccountCreation_passwordsDontMatches")?>");
+        $("#localUserPassword1Alert").css("display","block");
+        $("#localUserPassword2Alert").html("<?=translate("localAccountCreation_passwordsDontMatches")?>");
+        $("#localUserPassword2Alert").css("display","block");
+        $("#registerBtn").attr("disabled", "");
+    } else {
+        var passw = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,32}$/;
+        if($("#localUserPassword1").val().match(passw)) { 
+            $("#localUserPassword1Alert").html('<?=translate('localAccountCreation_youCreateAnAccountWithoutPassword')?> <img height="16" src="<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/images/emojis/thinkingHard.png">');
+            $("#localUserPassword1Alert").css("display","");
+            $("#localUserPassword2Alert").html('<?=translate("localAccountCreation_pleaseRewriteYourPassword")?>');
+            $("#localUserPassword2Alert").css("display","");
+            $("#registerBtn").removeAttr("disabled");
+        } else { 
+            $("#localUserPassword1Alert").html("<?=translate("localAccountCreation_yourPasswordIsTooWeak")?>");
+            $("#localUserPassword1Alert").css("display","block");
+            $("#localUserPassword2Alert").html("<?=translate("localAccountCreation_yourPasswordIsTooWeak")?>");
+            $("#localUserPassword2Alert").css("display","block");
+            $("#registerBtn").attr("disabled", "");
+        }
+        
+    }
+}
+
+function toogle(idToToogle){
+    if($("#"+idToToogle).css("display") == "none"){
+        $("#"+idToToogle).css("display", "block");
+    }else{
+        $("#"+idToToogle).css("display", "none");
+    }
+}
+
 document.getElementById('searchNetUser').addEventListener("change", function (evt) {
     checkUser();
 }, false);
@@ -205,7 +363,7 @@ function fillInviteUser(username){
 function sendInvite(){
     var array = {
         username: $("#searchNetUser").val(),
-        key: "<?=$GLOBALS['encryptionKey']?>"
+        key: "<?=VBcmsGetSetting('encryptionKey')?>"
     };
     $.get("https://api.vbcms.net/profiles/v1/invite/"+encodeURIComponent(JSON.stringify(array)), function(data, statusText, xhr) {
         if(xhr.status==200){
diff --git a/vbcms-admin/includes/settingsPage.php b/vbcms-admin/includes/settingsPage.php
index 955d1d8..942c4de 100644
--- a/vbcms-admin/includes/settingsPage.php
+++ b/vbcms-admin/includes/settingsPage.php
@@ -62,6 +62,8 @@ function getSettingsHTML($params){
                     include "settings/general.php";    
                 }elseif($params=="users" && verifyUserPermission($_SESSION['user_id'], "vbcms", 'manageUsersSettings')){ 
                     include "settings/users.php"; 
+                }elseif($params=="userGroups" && verifyUserPermission($_SESSION['user_id'], "vbcms", 'manageuserGroupsSettings')){ 
+                    include "settings/groups.php"; 
                 } ?>
     </div>
 
@@ -102,26 +104,6 @@ function getSettingsHTML($params){
             // Enfin on lance la fonction qui affiche la page
             setSettingsContent();
         }
-
-        function saveChanges(){
-            $.post( "<?=VBcmsGetSetting("websiteUrl")?>vbcms-admin/backTasks?saveSettings", $( "#form" ).serialize() )
-            .done(function( data ) {
-                if(data!=""){
-                    SnackBar({
-                        message: data,
-                        status: "danger",
-                        timeout: false
-                    });
-                } else {
-                    SnackBar({
-                        message: '<?=translate("success-saving")?>',
-                        status: "success"
-                    });
-                    // On peut reload le contenu de la page avec cette fonction
-                    setSettingsContent();
-                }
-            });
-        }
     </script>
     <?php
 }
\ No newline at end of file
diff --git a/vbcms-content/extensions/vbcms-loadingscreens/admin/browse.php b/vbcms-content/extensions/vbcms-loadingscreens/admin/browse.php
index 62e8ac4..928811b 100644
--- a/vbcms-content/extensions/vbcms-loadingscreens/admin/browse.php
+++ b/vbcms-content/extensions/vbcms-loadingscreens/admin/browse.php
@@ -23,6 +23,7 @@
 			</div>');
 			}
 			?>
+			<!--
 			<div class="ld-card border rounded mx-1 my-1" style="background-image: url('https://sofianelasri.mtxserv.com/vbcms-content/uploads/stayonline.jpg');">
 				<div class="ld-card-content p-2">
 					<span><strong>Un super loading screen</strong></span>
@@ -49,7 +50,7 @@
 					<span><strong>Un super loading screen</strong></span>
 					<a href="#" class="btn btn-sm btn-brown float-right">Modifier</a>
 				</div>
-			</div>
+			</div> -->
 		</div>
 	</div>
 
diff --git a/vbcms-content/extensions/vbcms-loadingscreens/admin/edit.php b/vbcms-content/extensions/vbcms-loadingscreens/admin/edit.php
index 2af4b08..04449e0 100644
--- a/vbcms-content/extensions/vbcms-loadingscreens/admin/edit.php
+++ b/vbcms-content/extensions/vbcms-loadingscreens/admin/edit.php
@@ -12,9 +12,13 @@ if(isset($_GET['id'])){
     <div style="padding: 30px 50px; background-color:#3e3e3e;">
         <div class="d-flex text-white">
            <div style="margin-right: 50px;">
-                <h4><?=translate("loadingscreens_openEditor")?></h4>
-                <button type="button" class="btn btn-brown"><?=translate("loadingscreens_openEditor")?></button>
-                <h4><?=translate("modifyProperties")?></h4>
+                <h4><?=translate("commands")?></h4>
+                <div class="d-flex">
+                    <button type="button" class="btn btn-brown btn-sm flex-fill"><?=translate("loadingscreens_openEditor")?></button>
+                    <a href="<?=VBcmsGetSetting("websiteUrl")?><?=$this->clientAccess?>/<?=$loadingScreenIdentifier?>" class="btn btn-brown btn-sm mx-2 flex-fill"><?=translate("visualize")?></a>
+                    <button type="button" class="btn btn-danger btn-sm flex-fill"><i class="fas fa-trash-alt"></i></button>
+                </div>
+                <h4 style="margin-top: 50px;"><?=translate("modifyProperties")?></h4>
                 <div class="form-group">
                     <label><?=translate("theme")?></label>
                     <select class="form-control form-control-sm" id="themeSelection">
@@ -38,7 +42,7 @@ if(isset($_GET['id'])){
            </div>
            <div class="flex-grow-1 ">
                <h4>Prévisualisation</h4>
-               <div id="loadingScreenPreview" class="rounded" style="background-image: url('https://api.apiflash.com/v1/urltoimage?access_key=65e037cb81b44087ba537b58dd19e4ff&format=jpeg&quality=80&response_type=image&url=<?php echo urlencode(VBcmsGetSetting("websiteUrl")."loadingscreen/".$loadingScreenIdentifier."?preview"); ?>&width=1920&height=1080');"></div>
+               <div id="loadingScreenPreview" class="rounded" style="background-image: url('https://api.apiflash.com/v1/urltoimage?access_key=65e037cb81b44087ba537b58dd19e4ff&format=jpeg&quality=80&response_type=image&url=<?php echo urlencode(VBcmsGetSetting("websiteUrl").$this->clientAccess.'/'.$loadingScreenIdentifier.'?preview'); ?>&width=1920&height=1080');"></div>
            </div>
         </div>
     </div>
diff --git a/vbcms-content/extensions/vbcms-loadingscreens/init.php b/vbcms-content/extensions/vbcms-loadingscreens/init.php
index c432d84..e9d5759 100644
--- a/vbcms-content/extensions/vbcms-loadingscreens/init.php
+++ b/vbcms-content/extensions/vbcms-loadingscreens/init.php
@@ -2,15 +2,15 @@
 function enable($name, $path, $adminAccess, $clientAccess){
     global $bdd;
     adminNavbarAddCategory($name, "loadingscreens");
-    adminNavbarAddItem($name, "fas fa-plus-circle", "create", "/create");
+    //adminNavbarAddItem($name, "fas fa-plus-circle", "create", "/create");
     adminNavbarAddItem($name, "fas fa-list", "list", "/browse");
     adminNavbarAddItem($name, "fas fa-brush", "themes", "/themes");
 
     // On va créer les tables
     if(!tableExist("vbcmsLoadingScreens_list")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_list` ( `identifier` VARCHAR(128) NOT NULL , `visibility` INT NOT NULL , `sequenceId` INT NULL DEFAULT NULL , `showName` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , PRIMARY KEY (`identifier`)) ENGINE = InnoDB;");
-    if(!tableExist("vbcmsLoadingScreens_sequences")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_sequences` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;");
-    if(!tableExist("vbcmsLoadingScreens_sequencesData")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_sequencesData` ( `sequenceId` INT NOT NULL , `dataId` INT NOT NULL , `parentId` INT NULL DEFAULT NULL , `type` VARCHAR(128) NOT NULL , `data` JSON NOT NULL , PRIMARY KEY (`sequenceId`, `dataId`)) ENGINE = InnoDB;");
-    if(!tableExist("vbcmsLoadingScreens_tempSequencesData")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_tempSequencesData` ( `sequenceId` INT NOT NULL , `dataId` INT NOT NULL , `parentId` INT NULL DEFAULT NULL , `type` VARCHAR(128) NOT NULL , `data` JSON NOT NULL , `date` DATETIME NOT NULL , PRIMARY KEY (`sequenceId`, `dataId`)) ENGINE = InnoDB;");
+    if(!tableExist("vbcmsLoadingScreens_themes")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_themes` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;");
+    if(!tableExist("vbcmsLoadingScreens_themesData")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_themesData` ( `sequenceId` INT NOT NULL , `dataId` INT NOT NULL , `parentId` INT NULL DEFAULT NULL , `type` VARCHAR(128) NOT NULL , `data` JSON NOT NULL , PRIMARY KEY (`sequenceId`, `dataId`)) ENGINE = InnoDB;");
+    if(!tableExist("vbcmsLoadingScreens_tempThemesData")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_tempThemesData` ( `sequenceId` INT NOT NULL , `dataId` INT NOT NULL , `parentId` INT NULL DEFAULT NULL , `type` VARCHAR(128) NOT NULL , `data` JSON NOT NULL , `date` DATETIME NOT NULL , PRIMARY KEY (`sequenceId`, `dataId`)) ENGINE = InnoDB;");
     if(!tableExist("vbcmsLoadingScreens_clientsData")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_clientsData` ( `identifier` VARCHAR(64) NOT NULL , `stringId` VARCHAR(32) NOT NULL , `data` JSON NOT NULL , PRIMARY KEY (`identifier`)) ENGINE = InnoDB;");
     if(!tableExist("vbcmsLoadingScreens_previewTokens")) $bdd->query("CREATE TABLE `vbcmsLoadingScreens_previewTokens` ( `stringId` VARCHAR(32) NOT NULL , `lsId` INT NOT NULL , `expire` DATETIME NOT NULL , PRIMARY KEY (`stringId`)) ENGINE = InnoDB;");
 }
@@ -18,9 +18,9 @@ function enable($name, $path, $adminAccess, $clientAccess){
 function deleteData(){
     global $bdd;
     $bdd->query('DROP TABLE vbcmsLoadingScreens_list');
-    $bdd->query('DROP TABLE vbcmsLoadingScreens_sequences');
-    $bdd->query('DROP TABLE vbcmsLoadingScreens_sequencesData');
-    $bdd->query('DROP TABLE vbcmsLoadingScreens_tempSequencesData');
+    $bdd->query('DROP TABLE vbcmsLoadingScreens_themes');
+    $bdd->query('DROP TABLE vbcmsLoadingScreens_themesData');
+    $bdd->query('DROP TABLE vbcmsLoadingScreens_tempThemesData');
     $bdd->query('DROP TABLE vbcmsLoadingScreens_clientsData');
     $bdd->query('DROP TABLE vbcmsLoadingScreens_previewTokens');
 }
diff --git a/vbcms-content/translations/FR.php b/vbcms-content/translations/FR.php
index e9d10d2..caa81eb 100644
--- a/vbcms-content/translations/FR.php
+++ b/vbcms-content/translations/FR.php
@@ -51,8 +51,8 @@ $translation["invite"] = "Inviter";
 $translation["themes"] = "Thèmes";
 $translation["theme"] = "Thème";
 $translation["cancel"] = "Annuler";
-$translation["sample"] = "sample";
-$translation["sample"] = "sample";
+$translation["visualize"] = "Visualiser";
+$translation["commands"] = "Commandes";
 $translation["sample"] = "sample";
 $translation["sample"] = "sample";
 $translation["sample"] = "sample";
@@ -106,8 +106,8 @@ $translation["unknownType"] = "Type inconnu";
 $translation["alreadyUsed"] = "Déjà utilisé";
 $translation["noCommandSpecified"] = "Aucune commande de spcécifiée";
 $translation["noPostData"] = "Pas de donnée POST :(";
-$translation["sample"] = "sample";
-$translation["sample"] = "sample";
+$translation["modifyLocalAccount"] = "Modifier le compte local";
+$translation["createGroup"] = "Créer un groupe";
 $translation["sample"] = "sample";
 $translation["sample"] = "sample";
 $translation["sample"] = "sample";
-- 
GitLab