Improve public screen page
This commit is contained in:
parent
612c80366f
commit
11a3fc9a49
7 changed files with 223 additions and 102 deletions
|
@ -384,6 +384,7 @@ angular.module("FICApp")
|
||||||
|
|
||||||
$scope.types = {
|
$scope.types = {
|
||||||
"welcome": "Messages de bienvenue",
|
"welcome": "Messages de bienvenue",
|
||||||
|
"countdown": "Compte à rebours",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
"panel": "Boîte",
|
"panel": "Boîte",
|
||||||
"exercice": "Exercice",
|
"exercice": "Exercice",
|
||||||
|
@ -391,16 +392,18 @@ angular.module("FICApp")
|
||||||
"rank": "Classement",
|
"rank": "Classement",
|
||||||
};
|
};
|
||||||
$scope.welcome_types = {
|
$scope.welcome_types = {
|
||||||
"init": "Accueil des équipes",
|
"teams": "Accueil des équipes",
|
||||||
"public": "Accueil du public",
|
"public": "Accueil du public",
|
||||||
"countdown": "Compte à rebours lancement",
|
|
||||||
};
|
};
|
||||||
$scope.panel_types = {
|
$scope.colors = {
|
||||||
"panel-default": "Default",
|
"primary": "Primaire",
|
||||||
"panel-info": "Info",
|
"secondary": "Secondaire",
|
||||||
"panel-success": "Success",
|
"info": "Info",
|
||||||
"panel-warning": "Warning",
|
"success": "Success",
|
||||||
"panel-danger": "Danger",
|
"warning": "Warning",
|
||||||
|
"danger": "Danger",
|
||||||
|
"light": "Clair",
|
||||||
|
"dark": "Foncé",
|
||||||
};
|
};
|
||||||
$scope.rank_types = {
|
$scope.rank_types = {
|
||||||
"general": "Classement général",
|
"general": "Classement général",
|
||||||
|
@ -415,6 +418,50 @@ angular.module("FICApp")
|
||||||
$scope.someUpdt = true;
|
$scope.someUpdt = true;
|
||||||
$scope.scenes = [];
|
$scope.scenes = [];
|
||||||
};
|
};
|
||||||
|
$scope.presetScene = function(scene) {
|
||||||
|
$scope.someUpdt = true;
|
||||||
|
if (scene == "registration")
|
||||||
|
$scope.scenes = [
|
||||||
|
{
|
||||||
|
type: "welcome",
|
||||||
|
params: { kind: "teams" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "welcome",
|
||||||
|
params: { kind: "public", notitle: true },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
else if (scene == "welcome")
|
||||||
|
$scope.scenes = [
|
||||||
|
{
|
||||||
|
type: "welcome",
|
||||||
|
params: { kind: "public" },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
else if (scene == "start")
|
||||||
|
$scope.scenes = [
|
||||||
|
{
|
||||||
|
type: "welcome",
|
||||||
|
params: { kind: "public" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "countdown",
|
||||||
|
params: { color: "success", end: null, lead: "Go, go, go !", title: "Le challenge forensic va bientôt commencer !" },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
else if (scene == "summary") {
|
||||||
|
$scope.scenes = [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
params: { kind: "levels", themes: $scope.themes.map(function(z, i) { return z.id; }), total: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "rank",
|
||||||
|
params: { limit: 5, which: "general" },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
$scope.saveScenes = function() {
|
$scope.saveScenes = function() {
|
||||||
$scope.someUpdt = false;
|
$scope.someUpdt = false;
|
||||||
var prms = Scene.update($scope.scenes);
|
var prms = Scene.update($scope.scenes);
|
||||||
|
|
|
@ -1,133 +1,175 @@
|
||||||
<form ng-submit="saveScenes()" class="form-horizontal">
|
<form ng-submit="saveScenes()" class="form-horizontal">
|
||||||
<h2>Interface publique<a ng-click="clearScene()" class="pull-right btn btn-danger"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span> Vider la scène</a><a ng-click="addScene()" class="pull-right btn btn-primary" style="margin-right: 10px"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter un élément</a><button type="submit" style="margin-right: 10px" class="pull-right btn btn-success"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Publier cette scène</button>
|
<h2>
|
||||||
|
Interface publique
|
||||||
|
<div class="float-right dropdown">
|
||||||
|
<button class="btn btn-secondary dropdown-toggle mr-sm-2" type="button" data-toggle="dropdown">
|
||||||
|
Charger scène
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" ng-click="presetScene('registration')">Enregistrement équipes</a>
|
||||||
|
<a class="dropdown-item" ng-click="presetScene('welcome')">Accueil public</a>
|
||||||
|
<a class="dropdown-item" ng-click="presetScene('start')">Lancement</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" ng-click="presetScene('summary')">Résumé</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" ng-click="clearScene()">Scène vide</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button ng-click="addScene()" class="float-right btn btn-primary mr-sm-2"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter un élément</button>
|
||||||
|
<button type="submit" class="float-right btn btn-success mr-sm-2"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Publier cette scène</button>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
|
||||||
<div class="alert alert-info" ng-if="!scenes.length">
|
<div class="alert alert-info" ng-if="!scenes.length">
|
||||||
<strong ng-if="!someUpdt">Aucun contenu n'est actuellement affiché.</strong>
|
<strong ng-if="!someUpdt">Aucun contenu n'est actuellement affiché.</strong>
|
||||||
<strong ng-if="someUpdt">Aucun contenu à afficher.</strong>
|
<strong ng-if="someUpdt">Aucun contenu à afficher.</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="well" ng-repeat="scene in scenes">
|
|
||||||
<div class="form-group">
|
<div class="card" ng-repeat="scene in scenes">
|
||||||
<div class="col-sm-offset-2 col-sm-6">
|
<div class="card-body">
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
<div class="form-group row">
|
||||||
<input type="checkbox" ng-model="scene.params.hide"> Masquer temporairement
|
<label for="type" class="col-sm-2 col-form-label col-form-label-sm">Type de scène</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select class="custom-select custom-select-sm" id="type" ng-model="scene.type" ng-options="k as v for (k, v) in types"></select>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 form-inline">
|
||||||
|
<div class="form-check mb-2 mr-sm-2 mb-sm-0">
|
||||||
|
<label class="custom-control custom-checkbox">
|
||||||
|
<input class="custom-control-input" type="checkbox" ng-model="scene.params.hide">
|
||||||
|
<span class="custom-control-indicator"></span>
|
||||||
|
<span class="custom-control-description">Masquer</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<button ng-click="upScene(scene)" class="btn btn-sm btn-light mb-2 mr-sm-2 mb-sm-0"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span></button>
|
||||||
<div class="col-sm-2">
|
<button ng-click="downScene(scene)" class="btn btn-sm btn-light mb-2 mr-sm-2 mb-sm-0"><span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span></button>
|
||||||
<a ng-click="upScene(scene)" class="pull-right btn btn-default"><span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span> Up</a>
|
<button ng-click="delScene(scene)" class="btn btn-sm btn-warning mb-2 mr-sm-2 mb-sm-0"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Supprimer</button>
|
||||||
<a ng-click="downScene(scene)" class="pull-right btn btn-default"><span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span> Down</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<a ng-click="delScene(scene)" class="pull-right btn btn-warning"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Supprimer</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group row" ng-if="scene.type == 'welcome'">
|
||||||
<label for="type" class="col-sm-2 control-label">Type de scène</label>
|
<label for="wtype" class="col-sm-2 col-form-label col-form-label-sm">Sorte</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="type" ng-model="scene.type" ng-options="k as v for (k, v) in types"></select>
|
<select class="custom-select custom-select-sm" id="wtype" ng-model="scene.params.kind" ng-options="k as v for (k, v) in welcome_types"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'welcome'">
|
<div class="form-group row" ng-if="scene.type == 'panel' || scene.type == 'countdown'">
|
||||||
<label for="wtype" class="col-sm-2 control-label">Sorte</label>
|
<label for="ptype" class="col-sm-2 col-form-label col-form-label-sm">Couleur du cadre</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="wtype" ng-model="scene.params.kind" ng-options="k as v for (k, v) in welcome_types"></select>
|
<select class="custom-select custom-select-sm" id="ptype" ng-model="scene.params.color" ng-options="k as v for (k, v) in colors"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'panel'">
|
<div class="form-group row" ng-if="scene.type == 'message' || scene.type == 'panel' || scene.type == 'countdown'">
|
||||||
<label for="ptype" class="col-sm-2 control-label">Type de cadre</label>
|
<label for="mtitle" class="col-sm-2 col-form-label col-form-label-sm">Titre</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="ptype" ng-model="scene.params.kind" ng-options="k as v for (k, v) in panel_types"></select>
|
<input type="text" id="mtitle" ng-model="scene.params.title" class="form-control form-control-sm">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'message' || scene.type == 'panel'">
|
<div class="form-group row" ng-if="scene.type == 'message' || scene.type == 'panel' || scene.type == 'countdown'">
|
||||||
<label for="mtitle" class="col-sm-2 control-label">Titre</label>
|
<label for="mlead" class="col-sm-2 col-form-label col-form-label-sm" ng-if="scene.type != 'countdown'">Lead</label>
|
||||||
|
<label for="mlead" class="col-sm-2 col-form-label col-form-label-sm" ng-if="scene.type == 'countdown'">Message final</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" id="mtitle" ng-model="scene.params.title" class="form-control">
|
<input type="text" id="mlead" ng-model="scene.params.lead" class="form-control form-control-sm">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'message'">
|
<div class="form-group row" ng-if="scene.type == 'message' || scene.type == 'panel'">
|
||||||
<label for="mlead" class="col-sm-2 control-label">Lead</label>
|
<label for="mcnt" class="col-sm-2 col-form-label col-form-label-sm">Contenu HTML</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" id="mlead" ng-model="scene.params.lead" class="form-control">
|
<textarea class="form-control form-control-sm" id="mcnt" ng-model="scene.params.html"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'message' || scene.type == 'panel'">
|
<div class="form-group row" ng-if="scene.type == 'exercice'">
|
||||||
<label for="mcnt" class="col-sm-2 control-label">Contenu HTML</label>
|
<label for="eex" class="col-sm-2 col-form-label col-form-label-sm">Exercice</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea class="form-control" id="mcnt" ng-model="scene.params.html"></textarea>
|
<select class="custom-select custom-select-sm" id="eex" ng-model="scene.params.exercice" ng-options="ex.id as ex.title for ex in exercices">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'exercice'">
|
|
||||||
<label for="eex" class="col-sm-2 control-label">Exercice</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="form-control" id="eex" ng-model="scene.params.exercice" ng-options="ex.id as ex.title for ex in exercices">
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'rank'">
|
<div class="form-group row" ng-if="scene.type == 'countdown'">
|
||||||
<label for="rtype" class="col-sm-2 control-label">Sorte</label>
|
<label for="cend" class="col-sm-2 col-form-label col-form-label-sm">Date de fin</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="rtype" ng-model="scene.params.which" ng-options="k as v for (k, v) in rank_types"></select>
|
<input type="text" id="cend" ng-model="scene.params.end" class="form-control form-control-sm">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'rank'">
|
<div class="form-group row" ng-if="scene.type == 'rank'">
|
||||||
<label for="rlimit" class="col-sm-2 control-label">Nombre d'éléments</label>
|
<label for="rtype" class="col-sm-2 col-form-label col-form-label-sm">Sorte</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" id="rlimit" ng-model="scene.params.limit" class="form-control" integer>
|
<select class="custom-select custom-select-sm" id="rtype" ng-model="scene.params.which" ng-options="k as v for (k, v) in rank_types"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'rank'">
|
<div class="form-group row" ng-if="scene.type == 'rank'">
|
||||||
<label for="begin" class="col-sm-2 control-label">Début du classement (à partir de 0)</label>
|
<label for="rlimit" class="col-sm-2 col-form-label col-form-label-sm">Nombre d'éléments</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" id="rbegin" ng-model="scene.params.begin" class="form-control" integer>
|
<input type="text" id="rlimit" ng-model="scene.params.limit" class="form-control form-control-sm" integer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'table'">
|
<div class="form-group row" ng-if="scene.type == 'rank'">
|
||||||
<label for="ttable" class="col-sm-2 control-label">Quelle table ?</label>
|
<label for="begin" class="col-sm-2 col-form-label col-form-label-sm">Début du classement (à partir de 0)</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="ttable" ng-model="scene.params.kind" ng-options="k as v for (k, v) in table_types">
|
<input type="text" id="rbegin" ng-model="scene.params.begin" class="form-control form-control-sm" integer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row" ng-if="scene.type == 'table'">
|
||||||
|
<label for="ttable" class="col-sm-2 col-form-label col-form-label-sm">Quelle table ?</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="custom-select custom-select-sm" id="ttable" ng-model="scene.params.kind" ng-options="k as v for (k, v) in table_types">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'table'">
|
<div class="form-group row" ng-if="scene.type == 'table'">
|
||||||
<label for="ttheme" class="col-sm-2 control-label">Thèmes à afficher</label>
|
<label for="ttheme" class="col-sm-2 col-form-label col-form-label-sm">Thèmes à afficher</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="ttheme" multiple="1" ng-model="scene.params.themes" ng-options="th.id as th.name for th in themes">
|
<select class="custom-select custom-select-sm" id="ttheme" multiple="1" ng-model="scene.params.themes" ng-options="th.id as th.name for th in themes">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'table' && scene.params.kind == 'teams'">
|
<div class="form-group row" ng-if="scene.type == 'table' && scene.params.kind == 'teams'">
|
||||||
<label for="tteams" class="col-sm-2 control-label">Équipes à afficher</label>
|
<label for="tteams" class="col-sm-2 col-form-label col-form-label-sm">Équipes à afficher</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" id="tteams" multiple="1" ng-model="scene.params.teams" ng-options="t.id as (t.rank + 'e - ' + t.name) for t in teams">
|
<select class="custom-select custom-select-sm" id="tteams" multiple="1" ng-model="scene.params.teams" ng-options="t.id as (t.rank + 'e - ' + t.name) for t in teams">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="scene.type == 'table'">
|
<div class="form-group row" ng-if="scene.type == 'table'">
|
||||||
<div class="col-sm-offset-2 col-sm-6">
|
<div class="col-sm-2"></div>
|
||||||
<div class="checkbox">
|
<div class="col-sm-10">
|
||||||
<label>
|
<div class="form-check">
|
||||||
<input type="checkbox" ng-model="scene.params.total"> Ligne de total
|
<label class="custom-control custom-checkbox">
|
||||||
|
<input class="custom-control-input" type="checkbox" ng-model="scene.params.total">
|
||||||
|
<span class="custom-control-indicator"></span>
|
||||||
|
<span class="custom-control-description">Ligne de total</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row" ng-if="scene.type == 'welcome'">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="form-check">
|
||||||
|
<label class="custom-control custom-checkbox">
|
||||||
|
<input class="custom-control-input" type="checkbox" ng-model="scene.params.notitle">
|
||||||
|
<span class="custom-control-indicator"></span>
|
||||||
|
<span class="custom-control-description">Masquer le titre</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -25,6 +25,12 @@ body {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-public {
|
||||||
|
background-image: url('../img/logo-epita-bw.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
.beautiful {
|
.beautiful {
|
||||||
font-family: "Linux Biolinum",Helvetica,Arial,sans-serif;
|
font-family: "Linux Biolinum",Helvetica,Arial,sans-serif;
|
||||||
}
|
}
|
||||||
|
|
BIN
frontend/static/img/logo-epita-bw.png
Normal file
BIN
frontend/static/img/logo-epita-bw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 220 KiB |
|
@ -29,6 +29,7 @@ angular.module("FICApp")
|
||||||
})
|
})
|
||||||
.filter("time", function() {
|
.filter("time", function() {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
|
input = Math.floor(input);
|
||||||
if (input == undefined) {
|
if (input == undefined) {
|
||||||
return "--";
|
return "--";
|
||||||
} else if (input >= 10) {
|
} else if (input >= 10) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ angular.module("FICApp")
|
||||||
if (time.st > 0 && time.st <= srv_cur) {
|
if (time.st > 0 && time.st <= srv_cur) {
|
||||||
remain = time.st + time.du - srv_cur;
|
remain = time.st + time.du - srv_cur;
|
||||||
} else if (time.st > 0) {
|
} else if (time.st > 0) {
|
||||||
$rootScope.startIn = Math.floor(time.st - srv_cur);
|
$rootScope.startAt = time.st;
|
||||||
}
|
}
|
||||||
if (remain < 0) {
|
if (remain < 0) {
|
||||||
remain = 0;
|
remain = 0;
|
||||||
|
@ -109,6 +109,26 @@ angular.module("FICApp")
|
||||||
refreshEvents()
|
refreshEvents()
|
||||||
$interval(refreshEvents, 2100);
|
$interval(refreshEvents, 2100);
|
||||||
})
|
})
|
||||||
|
.controller("CountdownController", function($scope, $interval) {
|
||||||
|
$scope.duration = 0;
|
||||||
|
|
||||||
|
$scope.init = function(end) {
|
||||||
|
console.log(end);
|
||||||
|
console.log(Date.parse(end)/1000);
|
||||||
|
$scope.initT(Date.parse(end)/1000);
|
||||||
|
}
|
||||||
|
$scope.initT = function(end) {
|
||||||
|
var time = angular.fromJson(sessionStorage.userService);
|
||||||
|
var srv_cur = (Date.now() + (time.cu * 1000 - time.he)) / 1000;
|
||||||
|
$scope.duration += Math.floor(end - srv_cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stop = $interval(function() {
|
||||||
|
$scope.duration -= 1;
|
||||||
|
if ($scope.duration < -10)
|
||||||
|
$interval.cancel(stop);
|
||||||
|
}, 1000);
|
||||||
|
})
|
||||||
.controller("DataController", function($scope, $http, $rootScope, $interval) {
|
.controller("DataController", function($scope, $http, $rootScope, $interval) {
|
||||||
var refreshScene = function() {
|
var refreshScene = function() {
|
||||||
$http.get("/public.json").then(function(response) {
|
$http.get("/public.json").then(function(response) {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<link href="/css/fic.css" type="text/css" rel="stylesheet" media="screen">
|
<link href="/css/fic.css" type="text/css" rel="stylesheet" media="screen">
|
||||||
<script src="/js/angular.min.js"></script>
|
<script src="/js/angular.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-light" style="overflow: hidden;" class="container-fluid" ng-controller="DataController">
|
<body class="bg-light bg-public" style="overflow: hidden;" class="container-fluid" ng-controller="DataController">
|
||||||
<div class="row" style="margin:10px 0">
|
<div class="row" style="margin:10px 0">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<noscript>
|
<noscript>
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
|
|
||||||
<div ng-repeat="(k,s) in scene" class="repeatedd-item" style="margin-bottom: 15px;">
|
<div ng-repeat="(k,s) in scene" class="repeatedd-item" style="margin-bottom: 15px;">
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'init'">
|
<div class="card" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'teams'">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h1>Bienvenue au challenge forensic !</h1>
|
<h1 ng-if="!s.params.notitle">Bienvenue au challenge forensic !</h1>
|
||||||
<p class="lead text-justify">
|
<p class="lead text-justify">
|
||||||
Avant de vous installer, venez récupérer votre clef USB auprès
|
Avant de vous installer, venez récupérer votre clef USB auprès
|
||||||
de notre équipe. Elle contient le certificat qui vous permettra
|
de notre équipe. Elle contient le certificat qui vous permettra
|
||||||
|
@ -42,17 +42,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card border-success" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'countdown'">
|
<div class="card border-{{s.params.color}}" ng-if="s.type == 'countdown' && !s.params.hide">
|
||||||
<div class="card-header bg-success text-white">
|
<div class="card-header bg-{{s.params.color}} text-white" ng-if="s.params.title">
|
||||||
<h3 style="margin:0"><strong>Le {{ settings.title }} est sur le point de commencer !</strong></h3>
|
<h3 style="margin:0"><strong ng-bind="s.params.title"></strong></h3>
|
||||||
|
</div>
|
||||||
|
<div ng-controller="CountdownController" ng-init="s.params.end?init(s.params.end):initT(startAt)">
|
||||||
|
<div class="card-body text-center" style="font-size: 450%;" ng-if="duration > 0">{{ duration / 60 | time }} <span class="point">:</span> {{ duration % 60 | time }}</div>
|
||||||
|
<div class="card-body text-center" style="font-size: 450%;" ng-if="!duration || duration <= 0">{{ s.params.lead }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body text-center" style="font-size: 450%;" ng-if="startIn">{{ startIn }}</div>
|
|
||||||
<div class="card-body text-center" style="font-size: 450%;" ng-if="!startIn">Go, go, go !</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'public'">
|
<div class="card" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'public'">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h1>Bienvenue au challenge forensic !</h1>
|
<h1 ng-if="!s.params.notitle">Bienvenue au challenge forensic !</h1>
|
||||||
<p class="lead text-justify">
|
<p class="lead text-justify">
|
||||||
Durant ce challenge, les équipes doivent <strong>remonter des scénarii
|
Durant ce challenge, les équipes doivent <strong>remonter des scénarii
|
||||||
d'attaques</strong> auxquels nos systèmes d'information <strong>font faces
|
d'attaques</strong> auxquels nos systèmes d'information <strong>font faces
|
||||||
|
@ -72,18 +74,21 @@
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'message' && !s.params.hide">
|
<div class="card" ng-if="s.type == 'message' && !s.params.hide">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h1 ng-if="s.params.title"><strong>{{ s.params.title }}</strong></h1>
|
<h1 ng-if="s.params.title"><strong ng-bind="s.params.title"></strong></h1>
|
||||||
<p ng-if="s.params.lead" class="lead text-justify">{{ s.params.lead }}</p>
|
<p ng-if="s.params.lead" class="lead text-justify" ng-bind="s.params.lead"></p>
|
||||||
<p ng-bind-html="s.params.html" ng-if="s.params.html"></p>
|
<p ng-bind-html="s.params.html" ng-if="s.params.html"></p>
|
||||||
<p ng-if="s.params.text">{{ s.params.text }}</p>
|
<p ng-if="s.params.text" ng-bind="s.params.text"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'panel' && !s.params.hide">
|
<div class="card border-{{ s.params.color }}" ng-if="s.type == 'panel' && !s.params.hide">
|
||||||
<div class="card-header {{ s.params.kind }}" ng-if="s.params.title">
|
<div class="card-header bg-{{ s.params.color }} text-white" ng-if="s.params.title">
|
||||||
<h3 style="margin:0">{{ s.params.title }}</h3>
|
<h3 style="margin:0" ng-bind="s.params.title"></h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" ng-if="s.params.text || s.params.lead">
|
||||||
|
<h4 ng-if="s.params.lead" class="card-title text-justify" ng-bind="s.params.lead"></h4>
|
||||||
|
<p class="card-text" ng-bind="s.params.text"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body" ng-if="s.params.text">{{ s.params.text }}</div>
|
|
||||||
<div class="card-body" ng-if="s.params.html" ng-bind-html="s.params.html"></div>
|
<div class="card-body" ng-if="s.params.html" ng-bind-html="s.params.html"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -105,16 +110,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'table' && !s.params.hide">
|
<div ng-if="s.type == 'table' && !s.params.hide">
|
||||||
<table class="table table-bordered table-striped table-sm">
|
<table class="table table-striped table-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr class="text-light">
|
||||||
<th class="frotated"></th>
|
<th class="frotated"></th>
|
||||||
<th class="rotated" ng-repeat="(tid,th) in themes" ng-if="s.params.themes.indexOf(tid-0) !== -1"><div><span>{{ th.name }}</span></div></th>
|
<th class="rotated" ng-repeat="(tid,th) in themes" ng-if="s.params.themes.indexOf(tid-0) !== -1"><div class="bg-dark"><span>{{ th.name }}</span></div></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody ng-if="s.params.kind == 'levels'">
|
<tbody class="table-bordered bg-secondary text-dark" ng-if="s.params.kind == 'levels'">
|
||||||
<tr ng-repeat="lvl in [1,2,3,4,5]">
|
<tr ng-repeat="lvl in [1,2,3,4,5,6,7,8,9,10]">
|
||||||
<th class="text-center"><nobr>Niveau {{ lvl }}</nobr></th>
|
<th class="text-center"><nobr>Niveau {{ lvl }}</nobr></th>
|
||||||
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="s.params.themes.indexOf(tid-0) !== -1">
|
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="s.params.themes.indexOf(tid-0) !== -1">
|
||||||
<span ng-repeat="exercice in th.exercices" ng-if="$index == lvl-1 && (exercice.tried || lvl == 1)" ng-class="{'text-primary': exercice.solved == 0, 'text-success': exercice.solved >= 1, 'text-bold': exercice.solved >= 1, 'text-warning': exercice.solved == 0 && exercice.tried}">
|
<span ng-repeat="exercice in th.exercices" ng-if="$index == lvl-1 && (exercice.tried || lvl == 1)" ng-class="{'text-primary': exercice.solved == 0, 'text-success': exercice.solved >= 1, 'text-bold': exercice.solved >= 1, 'text-warning': exercice.solved == 0 && exercice.tried}">
|
||||||
|
@ -124,7 +129,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tbody ng-if="s.params.kind == 'teams'">
|
<tbody class="table-bordered bg-secondary text-dark" ng-if="s.params.kind == 'teams'">
|
||||||
<tr ng-repeat="team in rank | orderBy: 'rank' | limitTo: s.params.limit: s.params.begin" ng-if="s.params.teams.indexOf(team.id-0) !== -1" ng-controller="TeamController">
|
<tr ng-repeat="team in rank | orderBy: 'rank' | limitTo: s.params.limit: s.params.begin" ng-if="s.params.teams.indexOf(team.id-0) !== -1" ng-controller="TeamController">
|
||||||
<th class="text-center">{{ team.rank }}<sup ng-if="team.rank == 1">er</sup><sup ng-if="team.rank > 1">e</sup><br><span style="text-overflow: ellipsis; display: inline-block; width: 82px;overflow: hidden;">{{ team.name }}</span></th>
|
<th class="text-center">{{ team.rank }}<sup ng-if="team.rank == 1">er</sup><sup ng-if="team.rank > 1">e</sup><br><span style="text-overflow: ellipsis; display: inline-block; width: 82px;overflow: hidden;">{{ team.name }}</span></th>
|
||||||
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
||||||
|
@ -135,12 +140,12 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot ng-if="s.params.total" ng-init="team={id:0}">
|
<tfoot ng-if="s.params.total" ng-init="team={id:0}">
|
||||||
<tr ng-controller="TeamController">
|
<tr ng-controller="TeamController">
|
||||||
<td class="text-right">
|
<td class="text-right text-dark">
|
||||||
<span ng-if="s.params.kind == 'levels'">Résolus</span>
|
<span ng-if="s.params.kind == 'levels'">Résolus</span>
|
||||||
<span ng-if="s.params.kind == 'teams'">Total résolus</span><br>
|
<span ng-if="s.params.kind == 'teams'">Total résolus</span><br>
|
||||||
Tentatives
|
Tentatives
|
||||||
</td>
|
</td>
|
||||||
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
<td class="table-bordered bg-dark" ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
||||||
<strong>{{ mystats.themes[tid].solved }}</strong><br>
|
<strong>{{ mystats.themes[tid].solved }}</strong><br>
|
||||||
{{ mystats.themes[tid].tries }}
|
{{ mystats.themes[tid].tries }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -151,7 +156,7 @@
|
||||||
|
|
||||||
<div class="card" ng-if="s.type == 'rank' && !s.params.hide">
|
<div class="card" ng-if="s.type == 'rank' && !s.params.hide">
|
||||||
<table class="table table-bordered table-striped table-sm">
|
<table class="table table-bordered table-striped table-sm">
|
||||||
<thead>
|
<thead class="thead-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-right">Place</th>
|
<th class="text-right">Place</th>
|
||||||
<th>Équipe</th>
|
<th>Équipe</th>
|
||||||
|
@ -204,7 +209,7 @@
|
||||||
<div style="position: fixed; bottom: 0; right: 0; width: 33vw; height: 14vh" class="bg-primary">
|
<div style="position: fixed; bottom: 0; right: 0; width: 33vw; height: 14vh" class="bg-primary">
|
||||||
<div class="carousel slide" id="carousel-logos" data-ride="carousel" data-interval="10500">
|
<div class="carousel slide" id="carousel-logos" data-ride="carousel" data-interval="10500">
|
||||||
<div class="carousel-inner">
|
<div class="carousel-inner">
|
||||||
<div class="carousel-item active">
|
<div class="carousel-item">
|
||||||
<div class="carousel-caption">
|
<div class="carousel-caption">
|
||||||
<a href="http://www.epita.fr/"><img src="/img/epita.png" alt="Epita" style="max-height:14vh"></a>
|
<a href="http://www.epita.fr/"><img src="/img/epita.png" alt="Epita" style="max-height:14vh"></a>
|
||||||
<img src="/img/rcc.png" alt="Réserve Citoyenne Cyberdéfense" style="height:14vh">
|
<img src="/img/rcc.png" alt="Réserve Citoyenne Cyberdéfense" style="height:14vh">
|
||||||
|
@ -212,7 +217,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="carousel-item">
|
<div class="carousel-item">
|
||||||
<div class="carousel-caption">
|
<div class="carousel-caption">
|
||||||
<h2>Bienvenue au challenge forensic !</h2>
|
<h2 style="margin: 17px">Bienvenue au challenge forensic !</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="carousel-item">
|
<div class="carousel-item">
|
||||||
|
@ -252,9 +257,9 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="carousel-item">
|
<div class="carousel-item active">
|
||||||
<div class="carousel-caption" style="padding: 3px 25px; width: 32vw;">
|
<div class="carousel-caption">
|
||||||
<table class="table table-bordered table-sm table-striped">
|
<table class="table table-sm table-striped">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>11 h</td>
|
<td>11 h</td>
|
||||||
|
|
Reference in a new issue