var/cache/dev/twig/03/0367d26fe4ee71843fbac68bc1623a40.php line 55

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\CoreExtension;
  6. use Twig\Extension\SandboxExtension;
  7. use Twig\Markup;
  8. use Twig\Sandbox\SecurityError;
  9. use Twig\Sandbox\SecurityNotAllowedTagError;
  10. use Twig\Sandbox\SecurityNotAllowedFilterError;
  11. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  12. use Twig\Source;
  13. use Twig\Template;
  14. use Twig\TemplateWrapper;
  15. /* classroom/show.html.twig */
  16. class __TwigTemplate_0c035c967b72fb6156d097bb36f556af extends Template
  17. {
  18. private Source $source;
  19. /**
  20. * @var array<string, Template>
  21. */
  22. private array $macros = [];
  23. public function __construct(Environment $env)
  24. {
  25. parent::__construct($env);
  26. $this->source = $this->getSourceContext();
  27. $this->blocks = [
  28. 'stylesheets' => [$this, 'block_stylesheets'],
  29. 'content' => [$this, 'block_content'],
  30. 'javascripts' => [$this, 'block_javascripts'],
  31. ];
  32. }
  33. protected function doGetParent(array $context): bool|string|Template|TemplateWrapper
  34. {
  35. // line 1
  36. return "layout/backEndLayout.html.twig";
  37. }
  38. protected function doDisplay(array $context, array $blocks = []): iterable
  39. {
  40. $macros = $this->macros;
  41. $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  42. $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "classroom/show.html.twig"));
  43. $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  44. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "classroom/show.html.twig"));
  45. $this->parent = $this->load("layout/backEndLayout.html.twig", 1);
  46. yield from $this->parent->unwrap()->yield($context, array_merge($this->blocks, $blocks));
  47. $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  48. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  49. }
  50. // line 3
  51. /**
  52. * @return iterable<null|scalar|\Stringable>
  53. */
  54. public function block_stylesheets(array $context, array $blocks = []): iterable
  55. {
  56. $macros = $this->macros;
  57. $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  58. $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
  59. $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  60. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
  61. // line 4
  62. yield from $this->yieldParentBlock("stylesheets", $context, $blocks);
  63. yield "
  64. <style>
  65. /* ══════════════════════════════════════════════════════
  66. TOKENS
  67. ══════════════════════════════════════════════════════ */
  68. :root {
  69. --bg : #f0f4f8; --s1 : #ffffff; --s2 : #e8edf3;
  70. --bdr : rgba(0,0,0,.09); --bdr-hi: rgba(0,0,0,.18);
  71. --blue : #185fa5; --rose : #a32d2d; --amber: #854f0b;
  72. --teal : #0f6e56; --em : #3b6d11; --vi : #534ab7;
  73. --txt : #1a2535; --dim : #4a5568; --muted: #7a8899;
  74. --r: 14px; --font: 'DM Sans','Segoe UI',sans-serif;
  75. }
  76. /* ── Layout ──────────────────────────────────────────── */
  77. .cr-page { font-family:var(--font); color:var(--txt); }
  78. .cr-page * { box-sizing:border-box; }
  79. /* ── Entête classe ───────────────────────────────────── */
  80. .cr-head {
  81. background:var(--s1); border:1px solid var(--bdr);
  82. border-radius:var(--r); padding:20px 24px; margin-bottom:20px;
  83. display:flex; align-items:center; justify-content:space-between;
  84. flex-wrap:wrap; gap:14px;
  85. }
  86. .cr-head__name { font-size:22px; font-weight:700; letter-spacing:-.02em; }
  87. .cr-head__meta { font-size:13px; color:var(--dim); }
  88. .cr-head__badges { display:flex; gap:8px; flex-wrap:wrap; }
  89. .badge-pill {
  90. display:inline-flex; align-items:center; gap:5px; padding:5px 12px;
  91. border-radius:20px; font-size:12px; font-weight:500; border:1px solid var(--bdr);
  92. }
  93. .bp-blue { background:rgba(59,130,246,.15); color:var(--blue); }
  94. .bp-amber { background:rgba(245,158,11,.15); color:var(--amber); }
  95. .bp-teal { background:rgba(20,184,166,.15); color:var(--teal); }
  96. /* ── Actions ─────────────────────────────────────────── */
  97. .cr-actions {
  98. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  99. padding:14px 18px; margin-bottom:20px; display:flex; flex-wrap:wrap; gap:8px;
  100. }
  101. .btn-cr {
  102. display:inline-flex; align-items:center; gap:6px; padding:7px 14px;
  103. border-radius:8px; font-size:12.5px; font-weight:500; text-decoration:none;
  104. border:1px solid var(--bdr); cursor:pointer; transition:background .18s,transform .12s;
  105. color:var(--txt); background:var(--s2);
  106. }
  107. .btn-cr:hover { transform:translateY(-1px); border-color:var(--bdr-hi); color:var(--txt); }
  108. .btn-cr-blue { background:rgba(59,130,246,.15); color:var(--blue); border-color:rgba(59,130,246,.3); }
  109. .btn-cr-amber { background:rgba(245,158,11,.15); color:var(--amber); border-color:rgba(245,158,11,.3); }
  110. .btn-cr-teal { background:rgba(20,184,166,.15); color:var(--teal); border-color:rgba(20,184,166,.3); }
  111. .btn-cr-rose { background:rgba(244,63,94,.15); color:var(--rose); border-color:rgba(244,63,94,.3); }
  112. .btn-cr-vi { background:rgba(139,92,246,.15); color:var(--vi); border-color:rgba(139,92,246,.3); }
  113. .btn-cr-em { background:rgba(16,185,129,.15); color:var(--em); border-color:rgba(16,185,129,.3); }
  114. /* ── Tables ──────────────────────────────────────────── */
  115. .cr-table-wrap {
  116. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  117. overflow:hidden; margin-bottom:20px;
  118. }
  119. .cr-table-title {
  120. padding:14px 18px 12px; border-bottom:1px solid var(--bdr);
  121. font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;
  122. }
  123. .cr-table-title .dot { width:7px;height:7px;border-radius:50%; }
  124. .d-bl{background:var(--blue);box-shadow:0 0 5px var(--blue);}
  125. .d-am{background:var(--amber);box-shadow:0 0 5px var(--amber);}
  126. table.cr-tbl { width:100%; border-collapse:collapse; font-size:13px; }
  127. table.cr-tbl th { padding:10px 14px; color:var(--dim); font-weight:500; font-size:11.5px; text-transform:uppercase; letter-spacing:.05em; border-bottom:1px solid var(--bdr); background:var(--s2); }
  128. table.cr-tbl td { padding:9px 14px; border-bottom:1px solid rgba(0,0,0,.05); }
  129. table.cr-tbl tr:last-child td { border-bottom:none; }
  130. table.cr-tbl tr:hover td { background:rgba(0,0,0,.025); }
  131. .tag-exam { display:inline-block; background:rgba(244,63,94,.15); color:var(--rose); padding:2px 8px; border-radius:4px; font-size:11px; }
  132. /* ── Grille graphiques ───────────────────────────────── */
  133. .chart-grid { display:grid; gap:16px; margin-bottom:16px; }
  134. .cg-2 { grid-template-columns:1fr 1fr; }
  135. .cg-1 { grid-template-columns:1fr; }
  136. @media(max-width:900px){ .cg-2 { grid-template-columns:1fr; } }
  137. /* ── Carte graphique ─────────────────────────────────── */
  138. .cc {
  139. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  140. overflow:hidden; transition:border-color .2s; animation:cIn .4s ease both;
  141. }
  142. .cc:hover { border-color:var(--bdr-hi); }
  143. .cc__hd {
  144. display:flex; align-items:center; justify-content:space-between;
  145. padding:13px 18px 11px; border-bottom:1px solid var(--bdr);
  146. }
  147. .cc__lbl { display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; }
  148. .cc__dot { width:7px;height:7px;border-radius:50%;flex-shrink:0; }
  149. .d-tl{background:var(--teal);box-shadow:0 0 5px var(--teal);}
  150. .d-rs{background:var(--rose);box-shadow:0 0 5px var(--rose);}
  151. .d-vi{background:var(--vi);box-shadow:0 0 5px var(--vi);}
  152. .d-em{background:var(--em);box-shadow:0 0 5px var(--em);}
  153. .cc__sub { font-size:11px; color:var(--muted); }
  154. .cc__bd { padding:16px 18px 18px; }
  155. /* ── Heatmap ─────────────────────────────────────────── */
  156. .heatmap { overflow-x:auto; }
  157. .heatmap table { width:100%; border-collapse:collapse; font-size:12px; }
  158. .heatmap th { padding:7px 10px; color:var(--dim); font-size:11px; text-transform:uppercase; letter-spacing:.05em; text-align:center; font-weight:500; }
  159. .heatmap th.course-th { text-align:left; min-width:140px; }
  160. .heatmap td { padding:5px 8px; text-align:center; border:1px solid rgba(0,0,0,.05); font-weight:500; font-size:12.5px; border-radius:4px; transition:opacity .2s; }
  161. .heatmap td:hover { opacity:.8; }
  162. .heatmap td.course-td { text-align:left; color:var(--txt); font-weight:400; font-size:12px; padding-left:4px; background:transparent !important; border:none; }
  163. .hm-null { background:rgba(0,0,0,.05); color:var(--muted); }
  164. .hm-red { background:rgba(163,45,45,.15); color:#7f1d1d; }
  165. .hm-yellow { background:rgba(133,79,11,.15); color:#451a03; }
  166. .hm-green { background:rgba(15,110,86,.15); color:#064e3b; }
  167. @keyframes cIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  168. .cc:nth-child(1){animation-delay:.04s}.cc:nth-child(2){animation-delay:.1s}
  169. #c-evol { max-height:220px; width:100%!important; }
  170. #c-success{ max-height:260px; width:100%!important; }
  171. #c-radar { max-height:300px; width:100%!important; }
  172. #c-mentions{ max-height:220px; max-width:220px; margin:auto; display:block; }
  173. </style>
  174. ";
  175. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  176. $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  177. yield from [];
  178. }
  179. // line 126
  180. /**
  181. * @return iterable<null|scalar|\Stringable>
  182. */
  183. public function block_content(array $context, array $blocks = []): iterable
  184. {
  185. $macros = $this->macros;
  186. $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  187. $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "content"));
  188. $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  189. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "content"));
  190. // line 127
  191. yield "<div class=\"cr-page p-3\">
  192. ";
  193. // line 130
  194. yield " <div class=\"cr-head\">
  195. <div>
  196. <div class=\"cr-head__name\">";
  197. // line 132
  198. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 132, $this->source); })()), "name", [], "any", false, false, false, 132), "html", null, true);
  199. yield "</div>
  200. <div class=\"cr-head__meta\">
  201. Niveau ";
  202. // line 134
  203. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 134, $this->source); })()), "level", [], "any", false, false, false, 134), "html", null, true);
  204. yield "
  205. ";
  206. // line 135
  207. if ((($tmp = (isset($context["mainteacher"]) || array_key_exists("mainteacher", $context) ? $context["mainteacher"] : (function () { throw new RuntimeError('Variable "mainteacher" does not exist.', 135, $this->source); })())) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  208. yield " · Titulaire : <strong>";
  209. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, (isset($context["mainteacher"]) || array_key_exists("mainteacher", $context) ? $context["mainteacher"] : (function () { throw new RuntimeError('Variable "mainteacher" does not exist.', 135, $this->source); })()), "fullName", [], "any", false, false, false, 135), "html", null, true);
  210. yield "</strong>";
  211. }
  212. // line 136
  213. yield " </div>
  214. </div>
  215. <div class=\"cr-head__badges\">
  216. <span class=\"badge-pill bp-blue\"><i class=\"fa fa-users\"></i> ";
  217. // line 139
  218. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), (isset($context["studentEnrolled"]) || array_key_exists("studentEnrolled", $context) ? $context["studentEnrolled"] : (function () { throw new RuntimeError('Variable "studentEnrolled" does not exist.', 139, $this->source); })())), "html", null, true);
  219. yield " élèves</span>
  220. ";
  221. // line 140
  222. if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 140, $this->source); })()), "apc", [], "any", false, false, false, 140)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  223. // line 141
  224. yield " <span class=\"badge-pill bp-amber\"><i class=\"fa fa-graduation-cap\"></i> Classe d'examen</span>
  225. ";
  226. }
  227. // line 143
  228. yield " </div>
  229. </div>
  230. ";
  231. // line 147
  232. yield " <div class=\"cr-actions\">
  233. <a class=\"btn-cr btn-cr-blue\" href=\"";
  234. // line 148
  235. yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms");
  236. yield "\"><i class=\"fa fa-list\"></i> Liste</a>
  237. ";
  238. // line 149
  239. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  240. // line 150
  241. yield " <a class=\"btn-cr btn-cr-blue\" href=\"";
  242. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_edit", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 150, $this->source); })()), "id", [], "any", false, false, false, 150)]), "html", null, true);
  243. yield "\"><i class=\"fa fa-edit\"></i> Modifier</a>
  244. <a class=\"btn-cr btn-cr-amber\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"";
  245. // line 151
  246. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_recapitulatif_seq", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 151, $this->source); })()), "id", [], "any", false, false, false, 151)]), "html", null, true);
  247. yield "\"><i class=\"fa fa-file-pdf-o\"></i> Recap Seq</a>
  248. <a class=\"btn-cr btn-cr-amber\" href=\"";
  249. // line 152
  250. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_reportcards_seq", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 152, $this->source); })()), "id", [], "any", false, false, false, 152)]), "html", null, true);
  251. yield "\"><i class=\"fa fa-file\"></i> Bull Seq</a>
  252. <a class=\"btn-cr btn-cr-teal\" data-toggle=\"modal\" data-target=\"#form_modal_reportcard_params\" data-action=\"";
  253. // line 153
  254. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_reportcards_trim_2024", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 153, $this->source); })()), "id", [], "any", false, false, false, 153)]), "html", null, true);
  255. yield "\"><i class=\"fa fa-file\"></i> Bull Trim</a>
  256. <a class=\"btn-cr btn-cr-vi\" data-toggle=\"modal\" data-target=\"#form_modal_reportcard_params\" data-action=\"";
  257. // line 154
  258. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_class_reportcards_year_2024", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 154, $this->source); })()), "id", [], "any", false, false, false, 154)]), "html", null, true);
  259. yield "\"><i class=\"fa fa-file-pdf-o\"></i> Bull Ann</a>
  260. <a class=\"btn-cr btn-cr-rose\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"";
  261. // line 155
  262. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_recapitulatif_trim", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 155, $this->source); })()), "id", [], "any", false, false, false, 155)]), "html", null, true);
  263. yield "\"><i class=\"fa fa-file-pdf-o\"></i> Recap Trim</a>
  264. <a class=\"btn-cr btn-cr-em\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"";
  265. // line 156
  266. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_classrooms_recapitulatif_ann_excel", ["id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 156, $this->source); })()), "id", [], "any", false, false, false, 156)]), "html", null, true);
  267. yield "\"><i class=\"fa fa-file-excel-o\"></i> Recap Ann</a>
  268. ";
  269. }
  270. // line 158
  271. yield " </div>
  272. ";
  273. // line 161
  274. yield " <div class=\"cg-2 chart-grid\">
  275. <div class=\"cr-table-wrap\">
  276. <div class=\"cr-table-title\"><span class=\"dot d-bl\"></span>Élèves inscrits</div>
  277. <table class=\"cr-tbl\">
  278. <thead><tr><th>Matricule</th><th>Nom</th><th>Prénom</th>";
  279. // line 166
  280. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  281. yield "<th>Action</th>";
  282. }
  283. yield "</tr></thead>
  284. <tbody>
  285. ";
  286. // line 168
  287. $context["effectif"] = 0;
  288. // line 169
  289. yield " ";
  290. $context['_parent'] = $context;
  291. $context['_seq'] = CoreExtension::ensureTraversable((isset($context["studentEnrolled"]) || array_key_exists("studentEnrolled", $context) ? $context["studentEnrolled"] : (function () { throw new RuntimeError('Variable "studentEnrolled" does not exist.', 169, $this->source); })()));
  292. foreach ($context['_seq'] as $context["_key"] => $context["std"]) {
  293. // line 170
  294. yield " <tr>
  295. <td><a href=\"";
  296. // line 171
  297. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_students_show", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["std"], "id", [], "any", false, false, false, 171)]), "html", null, true);
  298. yield "\" style=\"color:var(--blue)\">";
  299. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["std"], "matricule", [], "any", false, false, false, 171), "html", null, true);
  300. yield "</a></td>
  301. <td>";
  302. // line 172
  303. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["std"], "lastname", [], "any", false, false, false, 172), "html", null, true);
  304. yield "</td>
  305. <td>";
  306. // line 173
  307. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["std"], "firstname", [], "any", false, false, false, 173), "html", null, true);
  308. yield "</td>
  309. ";
  310. // line 174
  311. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  312. // line 175
  313. yield " <td>
  314. <a class=\"btn-cr btn-cr-rose\" style=\"padding:3px 8px;font-size:11px\" href=\"";
  315. // line 176
  316. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_students_unregister", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["std"], "id", [], "any", false, false, false, 176), "room_id" => CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 176, $this->source); })()), "id", [], "any", false, false, false, 176)]), "html", null, true);
  317. yield "\"><i class=\"fa fa-ban\"></i></a>
  318. <a class=\"btn-cr\" style=\"padding:3px 8px;font-size:11px\" href=\"";
  319. // line 177
  320. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_students_edit", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["std"], "id", [], "any", false, false, false, 177)]), "html", null, true);
  321. yield "\"><i class=\"fa fa-pencil-square-o\"></i></a>
  322. </td>
  323. ";
  324. }
  325. // line 180
  326. yield " </tr>
  327. ";
  328. // line 181
  329. $context["effectif"] = ((isset($context["effectif"]) || array_key_exists("effectif", $context) ? $context["effectif"] : (function () { throw new RuntimeError('Variable "effectif" does not exist.', 181, $this->source); })()) + 1);
  330. // line 182
  331. yield " ";
  332. }
  333. $_parent = $context['_parent'];
  334. unset($context['_seq'], $context['_key'], $context['std'], $context['_parent']);
  335. $context = array_intersect_key($context, $_parent) + $_parent;
  336. // line 183
  337. yield " <tr><td colspan=\"2\" style=\"color:var(--dim);font-size:11.5px\">Effectif total</td><td style=\"font-weight:700;color:var(--blue)\">";
  338. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["effectif"]) || array_key_exists("effectif", $context) ? $context["effectif"] : (function () { throw new RuntimeError('Variable "effectif" does not exist.', 183, $this->source); })()), "html", null, true);
  339. yield "</td>";
  340. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  341. yield "<td></td>";
  342. }
  343. yield "</tr>
  344. </tbody>
  345. </table>
  346. </div>
  347. <div class=\"cr-table-wrap\">
  348. <div class=\"cr-table-title\"><span class=\"dot d-am\"></span>Matières programmées</div>
  349. <table class=\"cr-tbl\">
  350. <thead><tr><th>Module</th><th>Code</th><th>Intitulé</th><th>Coef</th><th>Enseignant</th></tr></thead>
  351. <tbody>
  352. ";
  353. // line 193
  354. $context["totalCoef"] = 0;
  355. // line 194
  356. yield " ";
  357. $context['_parent'] = $context;
  358. $context['_seq'] = CoreExtension::ensureTraversable((isset($context["modules"]) || array_key_exists("modules", $context) ? $context["modules"] : (function () { throw new RuntimeError('Variable "modules" does not exist.', 194, $this->source); })()));
  359. foreach ($context['_seq'] as $context["_key"] => $context["module"]) {
  360. // line 195
  361. yield " ";
  362. $context['_parent'] = $context;
  363. $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["module"], "courses", [], "any", false, false, false, 195));
  364. foreach ($context['_seq'] as $context["_key"] => $context["course"]) {
  365. // line 196
  366. yield " <tr>
  367. <td style=\"color:var(--dim);font-size:11.5px\">";
  368. // line 197
  369. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["module"], "name", [], "any", false, false, false, 197), "html", null, true);
  370. yield "</td>
  371. <td><a href=\"";
  372. // line 198
  373. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_courses_show", ["id" => CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 198)]), "html", null, true);
  374. yield "\" style=\"color:var(--blue)\">";
  375. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["course"], "code", [], "any", false, false, false, 198), "html", null, true);
  376. yield "</a></td>
  377. <td>";
  378. // line 199
  379. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["course"], "wording", [], "any", false, false, false, 199), "html", null, true);
  380. yield "</td>
  381. <td style=\"font-weight:600\">";
  382. // line 200
  383. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["course"], "coefficient", [], "any", false, false, false, 200), "html", null, true);
  384. yield "</td>
  385. <td>
  386. ";
  387. // line 202
  388. if (CoreExtension::getAttribute($this->env, $this->source, ($context["attributions"] ?? null), CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 202), [], "array", true, true, false, 202)) {
  389. // line 203
  390. yield " ";
  391. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  392. // line 204
  393. yield " <a href=\"";
  394. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_attributions_edit", ["id" => CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, (isset($context["attributions"]) || array_key_exists("attributions", $context) ? $context["attributions"] : (function () { throw new RuntimeError('Variable "attributions" does not exist.', 204, $this->source); })()), CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 204), [], "array", false, false, false, 204), "id", [], "any", false, false, false, 204)]), "html", null, true);
  395. yield "\" style=\"color:var(--teal)\">";
  396. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, (isset($context["attributions"]) || array_key_exists("attributions", $context) ? $context["attributions"] : (function () { throw new RuntimeError('Variable "attributions" does not exist.', 204, $this->source); })()), CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 204), [], "array", false, false, false, 204), "teacher", [], "any", false, false, false, 204), "fullName", [], "any", false, false, false, 204), "html", null, true);
  397. yield "</a>
  398. ";
  399. } else {
  400. // line 205
  401. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, (isset($context["attributions"]) || array_key_exists("attributions", $context) ? $context["attributions"] : (function () { throw new RuntimeError('Variable "attributions" does not exist.', 205, $this->source); })()), CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 205), [], "array", false, false, false, 205), "teacher", [], "any", false, false, false, 205), "fullName", [], "any", false, false, false, 205), "html", null, true);
  402. }
  403. // line 206
  404. yield " ";
  405. } else {
  406. // line 207
  407. yield " ";
  408. if ((($tmp = $this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_ADMIN")) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  409. yield "<a href=\"";
  410. yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("admin_attributions_new");
  411. yield "\" style=\"color:var(--rose)\">Non attribué</a>";
  412. }
  413. // line 208
  414. yield " ";
  415. }
  416. // line 209
  417. yield " </td>
  418. </tr>
  419. ";
  420. // line 211
  421. $context["totalCoef"] = ((isset($context["totalCoef"]) || array_key_exists("totalCoef", $context) ? $context["totalCoef"] : (function () { throw new RuntimeError('Variable "totalCoef" does not exist.', 211, $this->source); })()) + CoreExtension::getAttribute($this->env, $this->source, $context["course"], "coefficient", [], "any", false, false, false, 211));
  422. // line 212
  423. yield " ";
  424. }
  425. $_parent = $context['_parent'];
  426. unset($context['_seq'], $context['_key'], $context['course'], $context['_parent']);
  427. $context = array_intersect_key($context, $_parent) + $_parent;
  428. // line 213
  429. yield " ";
  430. }
  431. $_parent = $context['_parent'];
  432. unset($context['_seq'], $context['_key'], $context['module'], $context['_parent']);
  433. $context = array_intersect_key($context, $_parent) + $_parent;
  434. // line 214
  435. yield " <tr><td colspan=\"3\" style=\"color:var(--dim);font-size:11.5px\">Total coefficients</td><td style=\"font-weight:700;color:var(--amber)\" colspan=\"2\">";
  436. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["totalCoef"]) || array_key_exists("totalCoef", $context) ? $context["totalCoef"] : (function () { throw new RuntimeError('Variable "totalCoef" does not exist.', 214, $this->source); })()), "html", null, true);
  437. yield "</td></tr>
  438. </tbody>
  439. </table>
  440. </div>
  441. </div>
  442. ";
  443. // line 224
  444. yield "
  445. ";
  446. // line 229
  447. yield " <div class=\"cc\" style=\"margin-bottom:16px\">
  448. <div class=\"cc__hd\">
  449. <div class=\"cc__lbl\"><span class=\"cc__dot d-am\"></span>Performances séquentielles — toutes matières</div>
  450. <span class=\"cc__sub\">rouge &lt;10 · jaune 10–13 · vert ≥14 · gris = pas d'évaluation enregistrée</span>
  451. </div>
  452. <div class=\"cc__bd heatmap\">
  453. <table id=\"heatmap-table\">
  454. <thead>
  455. <tr>
  456. <th class=\"course-th\">Matière</th>
  457. ";
  458. // line 240
  459. yield " </tr>
  460. </thead>
  461. <tbody id=\"heatmap-body\"></tbody>
  462. </table>
  463. </div>
  464. </div>
  465. ";
  466. // line 248
  467. yield " <div class=\"chart-grid cg-2\">
  468. <div class=\"cc\">
  469. <div class=\"cc__hd\">
  470. <div class=\"cc__lbl\"><span class=\"cc__dot d-tl\"></span>Évolution de la moyenne générale</div>
  471. <span class=\"cc__sub\">séquence par séquence · ligne rouge = seuil 10</span>
  472. </div>
  473. <div class=\"cc__bd\"><canvas id=\"c-evol\"></canvas></div>
  474. </div>
  475. <div class=\"cc\">
  476. <div class=\"cc__hd\">
  477. <div class=\"cc__lbl\"><span class=\"cc__dot d-rs\"></span>Réussite vs Échec — ";
  478. // line 260
  479. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["activeSeqLabel"]) || array_key_exists("activeSeqLabel", $context) ? $context["activeSeqLabel"] : (function () { throw new RuntimeError('Variable "activeSeqLabel" does not exist.', 260, $this->source); })()), "html", null, true);
  480. yield "</div>
  481. <span class=\"cc__sub\">séquence active · avec absents</span>
  482. </div>
  483. <div class=\"cc__bd\"><canvas id=\"c-success\"></canvas></div>
  484. </div>
  485. </div>
  486. ";
  487. // line 272
  488. yield " <div class=\"chart-grid ";
  489. yield (((($tmp = CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 272, $this->source); })()), "apc", [], "any", false, false, false, 272)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) ? ("cg-2") : ("cg-1"));
  490. yield "\">
  491. <div class=\"cc\">
  492. <div class=\"cc__hd\">
  493. <div class=\"cc__lbl\"><span class=\"cc__dot d-vi\"></span>Profil trimestriel de la classe</div>
  494. <span class=\"cc__sub\">radar par matière · T1, T2, T3</span>
  495. </div>
  496. <div class=\"cc__bd\"><canvas id=\"c-radar\"></canvas></div>
  497. </div>
  498. ";
  499. // line 282
  500. if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 282, $this->source); })()), "apc", [], "any", false, false, false, 282)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  501. // line 283
  502. yield " <div class=\"cc\">
  503. <div class=\"cc__hd\">
  504. <div class=\"cc__lbl\"><span class=\"cc__dot d-em\"></span>Résultats examens officiels</div>
  505. <span class=\"cc__sub\">répartition des mentions</span>
  506. </div>
  507. <div class=\"cc__bd\" style=\"display:flex;align-items:center;justify-content:center\">
  508. <canvas id=\"c-mentions\"></canvas>
  509. </div>
  510. </div>
  511. ";
  512. }
  513. // line 293
  514. yield "
  515. </div>
  516. </div>";
  517. // line 297
  518. yield "
  519. ";
  520. // line 301
  521. yield "<div class=\"modal fade\" id=\"form_modal_courses\" tabindex=\"-1\" role=\"dialog\">
  522. <div class=\"modal-dialog modal-dialog-centered\">
  523. <div class=\"modal-content\" style=\"background:#ffffff;color:#1a2535;border:1px solid rgba(0,0,0,.12)\">
  524. <div class=\"modal-header border-bottom-0\">
  525. <h5 class=\"modal-title\">Choisir les cours du récapitulatif</h5>
  526. <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"color:var(--txt)\"><span>&times;</span></button>
  527. </div>
  528. <form action=\"#\" method=\"post\">
  529. <div class=\"modal-body\">
  530. ";
  531. // line 310
  532. $context['_parent'] = $context;
  533. $context['_seq'] = CoreExtension::ensureTraversable((isset($context["modules"]) || array_key_exists("modules", $context) ? $context["modules"] : (function () { throw new RuntimeError('Variable "modules" does not exist.', 310, $this->source); })()));
  534. foreach ($context['_seq'] as $context["_key"] => $context["module"]) {
  535. $context['_parent'] = $context;
  536. $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["module"], "courses", [], "any", false, false, false, 310));
  537. foreach ($context['_seq'] as $context["_key"] => $context["course"]) {
  538. // line 311
  539. yield " <li class=\"list-group-item\" style=\"background:transparent;border-color:var(--bdr);color:var(--txt)\">
  540. <input class=\"form-check-input me-1\" type=\"checkbox\" checked name=\"selected_courses[]\" value=\"";
  541. // line 312
  542. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["course"], "id", [], "any", false, false, false, 312), "html", null, true);
  543. yield "\">
  544. ";
  545. // line 313
  546. yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["course"], "wording", [], "any", false, false, false, 313), "html", null, true);
  547. yield "
  548. </li>
  549. ";
  550. }
  551. $_parent = $context['_parent'];
  552. unset($context['_seq'], $context['_key'], $context['course'], $context['_parent']);
  553. $context = array_intersect_key($context, $_parent) + $_parent;
  554. }
  555. $_parent = $context['_parent'];
  556. unset($context['_seq'], $context['_key'], $context['module'], $context['_parent']);
  557. $context = array_intersect_key($context, $_parent) + $_parent;
  558. // line 316
  559. yield " </div>
  560. <div class=\"modal-footer border-top-0 d-flex justify-content-center\">
  561. <button type=\"submit\" class=\"btn-cr btn-cr-em\">Générer</button>
  562. </div>
  563. </form>
  564. </div>
  565. </div>
  566. </div>
  567. <div class=\"modal fade\" id=\"form_modal_reportcard_params\" tabindex=\"-1\" role=\"dialog\">
  568. <div class=\"modal-dialog modal-dialog-centered\">
  569. <div class=\"modal-content\" style=\"background:#ffffff;color:#1a2535;border:1px solid rgba(0,0,0,.12)\">
  570. <div class=\"modal-header border-bottom-0\">
  571. <h5 class=\"modal-title\">Paramètres du bulletin</h5>
  572. <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"color:var(--txt)\"><span>&times;</span></button>
  573. </div>
  574. <form method=\"post\">
  575. <div class=\"modal-body\">
  576. <div class=\"form-check mb-2\"><input class=\"form-check-input\" type=\"checkbox\" name=\"copyright\" id=\"copyright\"><label class=\"form-check-label\" for=\"copyright\">Copyright en pied de page</label></div>
  577. <div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" name=\"reverse\" id=\"reverse\"><label class=\"form-check-label\" for=\"reverse\">Sens inverse</label></div>
  578. </div>
  579. <div class=\"modal-footer border-top-0 d-flex justify-content-center\">
  580. <button type=\"submit\" class=\"btn-cr btn-cr-blue\">Générer</button>
  581. </div>
  582. </form>
  583. </div>
  584. </div>
  585. </div>
  586. ";
  587. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  588. $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  589. yield from [];
  590. }
  591. // line 347
  592. /**
  593. * @return iterable<null|scalar|\Stringable>
  594. */
  595. public function block_javascripts(array $context, array $blocks = []): iterable
  596. {
  597. $macros = $this->macros;
  598. $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  599. $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "javascripts"));
  600. $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  601. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "javascripts"));
  602. // line 348
  603. yield from $this->yieldParentBlock("javascripts", $context, $blocks);
  604. yield "
  605. <script>
  606. (function(){
  607. 'use strict';
  608. /* ── Données depuis le controller ─────────────────────── */
  609. const courseLabels = ";
  610. // line 354
  611. yield (isset($context["courseLabels"]) || array_key_exists("courseLabels", $context) ? $context["courseLabels"] : (function () { throw new RuntimeError('Variable "courseLabels" does not exist.', 354, $this->source); })());
  612. yield ";
  613. const seqLabels = ";
  614. // line 355
  615. yield (isset($context["seqLabels"]) || array_key_exists("seqLabels", $context) ? $context["seqLabels"] : (function () { throw new RuntimeError('Variable "seqLabels" does not exist.', 355, $this->source); })());
  616. yield ";
  617. const seqIds = ";
  618. // line 356
  619. yield (isset($context["seqIds"]) || array_key_exists("seqIds", $context) ? $context["seqIds"] : (function () { throw new RuntimeError('Variable "seqIds" does not exist.', 356, $this->source); })());
  620. yield ";
  621. const heatmapData = ";
  622. // line 357
  623. yield (isset($context["heatmapData"]) || array_key_exists("heatmapData", $context) ? $context["heatmapData"] : (function () { throw new RuntimeError('Variable "heatmapData" does not exist.', 357, $this->source); })());
  624. yield ";
  625. const generalAvgBySeq = ";
  626. // line 358
  627. yield (isset($context["generalAvgBySeq"]) || array_key_exists("generalAvgBySeq", $context) ? $context["generalAvgBySeq"] : (function () { throw new RuntimeError('Variable "generalAvgBySeq" does not exist.', 358, $this->source); })());
  628. yield ";
  629. const successFailData = ";
  630. // line 359
  631. yield (isset($context["successFailData"]) || array_key_exists("successFailData", $context) ? $context["successFailData"] : (function () { throw new RuntimeError('Variable "successFailData" does not exist.', 359, $this->source); })());
  632. yield ";
  633. const quaterProfiles = ";
  634. // line 360
  635. yield (isset($context["quaterProfiles"]) || array_key_exists("quaterProfiles", $context) ? $context["quaterProfiles"] : (function () { throw new RuntimeError('Variable "quaterProfiles" does not exist.', 360, $this->source); })());
  636. yield ";
  637. ";
  638. // line 361
  639. if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 361, $this->source); })()), "apc", [], "any", false, false, false, 361)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  640. // line 362
  641. yield "const mentionCategories = ";
  642. yield (isset($context["mentionCategories"]) || array_key_exists("mentionCategories", $context) ? $context["mentionCategories"] : (function () { throw new RuntimeError('Variable "mentionCategories" does not exist.', 362, $this->source); })());
  643. yield ";
  644. const mentionCountCategories = ";
  645. // line 363
  646. yield (isset($context["mentionCountCategories"]) || array_key_exists("mentionCountCategories", $context) ? $context["mentionCountCategories"] : (function () { throw new RuntimeError('Variable "mentionCountCategories" does not exist.', 363, $this->source); })());
  647. yield ";
  648. ";
  649. }
  650. // line 365
  651. yield "
  652. /* ── Palette & defaults ───────────────────────────────── */
  653. const C = {
  654. blue:'#185fa5', rose:'#a32d2d', amber:'#854f0b',
  655. teal:'#0f6e56', vi:'#534ab7', em:'#3b6d11', orange:'#9a4f0b',
  656. grid:'rgba(0,0,0,.07)', bg:'#ffffff', txt:'#1a2535', dim:'#4a5568'
  657. };
  658. const PALQ = ['rgba(24,95,165,.35)','rgba(15,110,86,.35)','rgba(83,74,183,.35)'];
  659. const PALQ_BD = ['#185fa5', '#0f6e56', '#534ab7'];
  660. const PAL = ['#3b82f6','#f59e0b','#f43f5e','#10b981','#8b5cf6','#14b8a6','#f97316','#84cc16'];
  661. Chart.defaults.color = C.dim;
  662. Chart.defaults.font.family = \"'DM Sans','Segoe UI',sans-serif\";
  663. Chart.defaults.font.size = 12;
  664. const TIP = {backgroundColor:'#ffffff',borderColor:'rgba(0,0,0,.12)',borderWidth:1,titleColor:C.txt,bodyColor:C.dim,padding:12,cornerRadius:10};
  665. const AX = (o={}) => ({grid:{color:C.grid,drawBorder:false},ticks:{color:C.dim},border:{display:false},...o});
  666. /* ══════════════════════════════════════════════════════
  667. 1. HEATMAP — table HTML colorée cours × séquences
  668. Résout le problème de départ : chaque cellule est
  669. indépendante. null = gris \"pas d'éval enregistrée\".
  670. ══════════════════════════════════════════════════════ */
  671. (function buildHeatmap(){
  672. const thead = document.querySelector('#heatmap-table thead tr');
  673. const tbody = document.getElementById('heatmap-body');
  674. // En-têtes séquences
  675. seqLabels.forEach(lbl => {
  676. const th = document.createElement('th');
  677. th.textContent = lbl;
  678. thead.appendChild(th);
  679. });
  680. // Colonne moyenne
  681. const thAvg = document.createElement('th');
  682. thAvg.textContent = 'Moy.';
  683. thead.appendChild(thAvg);
  684. // Lignes de données
  685. heatmapData.forEach(row => {
  686. const tr = document.createElement('tr');
  687. // Cellule nom de la matière
  688. const tdName = document.createElement('td');
  689. tdName.className = 'course-td';
  690. tdName.textContent = row.course;
  691. tr.appendChild(tdName);
  692. let sum = 0, cnt = 0;
  693. // Cellules par séquence
  694. seqIds.forEach(sid => {
  695. const val = row['s' + sid];
  696. const td = document.createElement('td');
  697. if (val === null || val === undefined) {
  698. td.className = 'hm-null';
  699. td.textContent = '—';
  700. } else {
  701. td.className = val < 10 ? 'hm-red' : val < 14 ? 'hm-yellow' : 'hm-green';
  702. td.textContent = val.toFixed(1);
  703. sum += val; cnt++;
  704. }
  705. tr.appendChild(td);
  706. });
  707. // Cellule moyenne
  708. const tdAvg = document.createElement('td');
  709. if (cnt > 0) {
  710. const avg = sum / cnt;
  711. tdAvg.className = avg < 10 ? 'hm-red' : avg < 14 ? 'hm-yellow' : 'hm-green';
  712. tdAvg.textContent = avg.toFixed(1);
  713. tdAvg.style.fontWeight = '700';
  714. } else {
  715. tdAvg.className = 'hm-null';
  716. tdAvg.textContent = '—';
  717. }
  718. tr.appendChild(tdAvg);
  719. tbody.appendChild(tr);
  720. });
  721. })();
  722. /* ══════════════════════════════════════════════════════
  723. 2. ÉVOLUTION MOYENNE GÉNÉRALE
  724. null = séquence pas encore notée → pas de point tracé
  725. ══════════════════════════════════════════════════════ */
  726. if (document.getElementById('c-evol')) {
  727. new Chart('c-evol', {
  728. type: 'line',
  729. data: {
  730. labels: seqLabels,
  731. datasets: [{
  732. label: 'Moyenne générale',
  733. data : generalAvgBySeq,
  734. borderColor: '#0f6e56', backgroundColor: 'rgba(15,110,86,.08)',
  735. borderWidth: 2.5, pointBackgroundColor: '#0f6e56',
  736. pointRadius: generalAvgBySeq.map(v => v !== null ? 5 : 0),
  737. pointHoverRadius: 7, tension: .3, fill: true,
  738. spanGaps: false, // ne pas relier les points si null entre eux
  739. }]
  740. },
  741. options: {
  742. responsive: true,
  743. plugins: {
  744. legend: { display: false },
  745. tooltip: { ...TIP, callbacks: { label: c => c.raw !== null ? ' Moy. : ' + c.raw + '/20' : ' Pas d\\'évaluation' } },
  746. },
  747. scales: {
  748. x: { ...AX() },
  749. y: { ...AX(), min: 0, max: 20, ticks: { ...AX().ticks, stepSize: 5 } },
  750. },
  751. },
  752. plugins: [{
  753. id: 'seuil',
  754. afterDraw(ch) {
  755. const { ctx, chartArea: { left, right }, scales: { y } } = ch;
  756. const yp = y.getPixelForValue(10);
  757. ctx.save();
  758. ctx.beginPath(); ctx.moveTo(left, yp); ctx.lineTo(right, yp);
  759. ctx.strokeStyle = 'rgba(163,45,45,.5)'; ctx.setLineDash([5, 4]);
  760. ctx.lineWidth = 1.5; ctx.stroke();
  761. ctx.fillStyle = 'rgba(163,45,45,.7)'; ctx.font = '11px DM Sans';
  762. ctx.fillText('Seuil 10', left + 4, yp - 5);
  763. ctx.restore();
  764. }
  765. }]
  766. });
  767. }
  768. /* ══════════════════════════════════════════════════════
  769. 3. RÉUSSITE VS ÉCHEC (barres empilées)
  770. Données depuis evaluation.success_h/f + faillures_h/f
  771. → pas depuis mark, déjà agrégées par le controller
  772. ══════════════════════════════════════════════════════ */
  773. if (document.getElementById('c-success') && successFailData.labels.length > 0) {
  774. new Chart('c-success', {
  775. type: 'bar',
  776. data: {
  777. labels: successFailData.labels,
  778. datasets: [
  779. {
  780. label: 'Réussite', data: successFailData.success,
  781. backgroundColor: 'rgba(59,109,17,.55)', borderColor: C.em,
  782. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  783. },
  784. {
  785. label: 'Échec', data: successFailData.failures,
  786. backgroundColor: 'rgba(163,45,45,.55)', borderColor: C.rose,
  787. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  788. },
  789. {
  790. label: 'Absents', data: successFailData.absents,
  791. backgroundColor: 'rgba(133,79,11,.45)', borderColor: C.amber,
  792. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  793. },
  794. ],
  795. },
  796. options: {
  797. responsive: true,
  798. interaction: { mode: 'index', intersect: false },
  799. plugins: {
  800. legend: { position: 'top', align: 'end', labels: { boxWidth: 9, boxHeight: 9, borderRadius: 3, useBorderRadius: true, color: C.txt, padding: 12 } },
  801. tooltip: { ...TIP },
  802. },
  803. scales: {
  804. x: { ...AX(), stacked: true, ticks: { ...AX().ticks, maxRotation: 35 } },
  805. y: { ...AX(), stacked: true, beginAtZero: true },
  806. },
  807. },
  808. });
  809. }
  810. /* ══════════════════════════════════════════════════════
  811. 4. RADAR PAR TRIMESTRE
  812. Révèle le profil de la classe : quelle matière est
  813. forte/faible, stable ou en progression entre trimestres
  814. ══════════════════════════════════════════════════════ */
  815. if (document.getElementById('c-radar') && quaterProfiles.length > 0) {
  816. new Chart('c-radar', {
  817. type: 'radar',
  818. data: {
  819. labels: courseLabels,
  820. datasets: quaterProfiles.map((qp, i) => ({
  821. label : qp.label,
  822. data : qp.data,
  823. backgroundColor : PALQ[i % PALQ.length],
  824. borderColor : PALQ_BD[i % PALQ_BD.length],
  825. borderWidth : 2,
  826. pointBackgroundColor: PALQ_BD[i % PALQ_BD.length],
  827. pointRadius : 4,
  828. spanGaps : true,
  829. })),
  830. },
  831. options: {
  832. responsive: true,
  833. plugins: {
  834. legend: {
  835. position: 'top', align: 'end',
  836. labels: { boxWidth: 9, boxHeight: 9, borderRadius: 3, useBorderRadius: true, color: C.txt, padding: 12 }
  837. },
  838. tooltip: { ...TIP, callbacks: { label: c => ' ' + c.dataset.label + ' : ' + (c.raw !== null ? c.raw + '/20' : '—') } },
  839. },
  840. scales: {
  841. r: {
  842. min: 0, max: 20,
  843. backgroundColor: 'rgba(24,95,165,.04)',
  844. grid : { color: C.grid },
  845. angleLines : { color: C.grid },
  846. ticks : { color: C.dim, backdropColor: 'transparent', stepSize: 5 },
  847. pointLabels : { color: C.dim, font: { size: 11 } },
  848. },
  849. },
  850. },
  851. });
  852. }
  853. /* ══════════════════════════════════════════════════════
  854. 5. DONUT EXAMENS OFFICIELS (seulement si classe examen)
  855. ══════════════════════════════════════════════════════ */
  856. ";
  857. // line 583
  858. if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, (isset($context["classroom"]) || array_key_exists("classroom", $context) ? $context["classroom"] : (function () { throw new RuntimeError('Variable "classroom" does not exist.', 583, $this->source); })()), "apc", [], "any", false, false, false, 583)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
  859. // line 584
  860. yield "if (document.getElementById('c-mentions') && mentionCountCategories.length > 0) {
  861. new Chart('c-mentions', {
  862. type: 'doughnut',
  863. data: {
  864. labels: mentionCategories,
  865. datasets: [{
  866. data: mentionCountCategories,
  867. backgroundColor: PAL.slice(0, mentionCategories.length),
  868. borderColor: '#f0f4f8', borderWidth: 3, hoverOffset: 8,
  869. }],
  870. },
  871. options: {
  872. responsive: true, cutout: '58%',
  873. plugins: {
  874. legend: { position: 'bottom', labels: { boxWidth: 8, boxHeight: 8, borderRadius: 2, useBorderRadius: true, color: C.txt, padding: 8, font: { size: 11 } } },
  875. tooltip: { ...TIP, callbacks: { label: c => ' ' + c.label + ' : ' + c.raw } },
  876. },
  877. },
  878. });
  879. }
  880. ";
  881. }
  882. // line 605
  883. yield "
  884. /* ── Modales actions ──────────────────────────────────── */
  885. \$(document).ready(function () {
  886. \$('#form_modal_courses').on('show.bs.modal', function (e) {
  887. \$('#form_modal_courses form').attr('action', \$(e.relatedTarget).data('action'));
  888. });
  889. \$('[data-toggle=\"modal\"]').on('click', function () {
  890. \$('#form_modal_reportcard_params form').attr('action', \$(this).data('action'));
  891. });
  892. });
  893. })();
  894. </script>
  895. ";
  896. $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  897. $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  898. yield from [];
  899. }
  900. /**
  901. * @codeCoverageIgnore
  902. */
  903. public function getTemplateName(): string
  904. {
  905. return "classroom/show.html.twig";
  906. }
  907. /**
  908. * @codeCoverageIgnore
  909. */
  910. public function isTraitable(): bool
  911. {
  912. return false;
  913. }
  914. /**
  915. * @codeCoverageIgnore
  916. */
  917. public function getDebugInfo(): array
  918. {
  919. return array ( 952 => 605, 929 => 584, 927 => 583, 707 => 365, 702 => 363, 697 => 362, 695 => 361, 691 => 360, 687 => 359, 683 => 358, 679 => 357, 675 => 356, 671 => 355, 667 => 354, 658 => 348, 645 => 347, 606 => 316, 593 => 313, 589 => 312, 586 => 311, 579 => 310, 568 => 301, 565 => 297, 560 => 293, 548 => 283, 546 => 282, 532 => 272, 521 => 260, 507 => 248, 498 => 240, 486 => 229, 483 => 224, 472 => 214, 466 => 213, 460 => 212, 458 => 211, 454 => 209, 451 => 208, 444 => 207, 441 => 206, 438 => 205, 430 => 204, 427 => 203, 425 => 202, 420 => 200, 416 => 199, 410 => 198, 406 => 197, 403 => 196, 398 => 195, 393 => 194, 391 => 193, 373 => 183, 367 => 182, 365 => 181, 362 => 180, 356 => 177, 352 => 176, 349 => 175, 347 => 174, 343 => 173, 339 => 172, 333 => 171, 330 => 170, 325 => 169, 323 => 168, 316 => 166, 309 => 161, 305 => 158, 300 => 156, 296 => 155, 292 => 154, 288 => 153, 284 => 152, 280 => 151, 275 => 150, 273 => 149, 269 => 148, 266 => 147, 261 => 143, 257 => 141, 255 => 140, 251 => 139, 246 => 136, 240 => 135, 236 => 134, 231 => 132, 227 => 130, 223 => 127, 210 => 126, 78 => 4, 65 => 3, 42 => 1,);
  920. }
  921. public function getSourceContext(): Source
  922. {
  923. return new Source("{% extends \"layout/backEndLayout.html.twig\" %}
  924. {% block stylesheets %}
  925. {{ parent() }}
  926. <style>
  927. /* ══════════════════════════════════════════════════════
  928. TOKENS
  929. ══════════════════════════════════════════════════════ */
  930. :root {
  931. --bg : #f0f4f8; --s1 : #ffffff; --s2 : #e8edf3;
  932. --bdr : rgba(0,0,0,.09); --bdr-hi: rgba(0,0,0,.18);
  933. --blue : #185fa5; --rose : #a32d2d; --amber: #854f0b;
  934. --teal : #0f6e56; --em : #3b6d11; --vi : #534ab7;
  935. --txt : #1a2535; --dim : #4a5568; --muted: #7a8899;
  936. --r: 14px; --font: 'DM Sans','Segoe UI',sans-serif;
  937. }
  938. /* ── Layout ──────────────────────────────────────────── */
  939. .cr-page { font-family:var(--font); color:var(--txt); }
  940. .cr-page * { box-sizing:border-box; }
  941. /* ── Entête classe ───────────────────────────────────── */
  942. .cr-head {
  943. background:var(--s1); border:1px solid var(--bdr);
  944. border-radius:var(--r); padding:20px 24px; margin-bottom:20px;
  945. display:flex; align-items:center; justify-content:space-between;
  946. flex-wrap:wrap; gap:14px;
  947. }
  948. .cr-head__name { font-size:22px; font-weight:700; letter-spacing:-.02em; }
  949. .cr-head__meta { font-size:13px; color:var(--dim); }
  950. .cr-head__badges { display:flex; gap:8px; flex-wrap:wrap; }
  951. .badge-pill {
  952. display:inline-flex; align-items:center; gap:5px; padding:5px 12px;
  953. border-radius:20px; font-size:12px; font-weight:500; border:1px solid var(--bdr);
  954. }
  955. .bp-blue { background:rgba(59,130,246,.15); color:var(--blue); }
  956. .bp-amber { background:rgba(245,158,11,.15); color:var(--amber); }
  957. .bp-teal { background:rgba(20,184,166,.15); color:var(--teal); }
  958. /* ── Actions ─────────────────────────────────────────── */
  959. .cr-actions {
  960. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  961. padding:14px 18px; margin-bottom:20px; display:flex; flex-wrap:wrap; gap:8px;
  962. }
  963. .btn-cr {
  964. display:inline-flex; align-items:center; gap:6px; padding:7px 14px;
  965. border-radius:8px; font-size:12.5px; font-weight:500; text-decoration:none;
  966. border:1px solid var(--bdr); cursor:pointer; transition:background .18s,transform .12s;
  967. color:var(--txt); background:var(--s2);
  968. }
  969. .btn-cr:hover { transform:translateY(-1px); border-color:var(--bdr-hi); color:var(--txt); }
  970. .btn-cr-blue { background:rgba(59,130,246,.15); color:var(--blue); border-color:rgba(59,130,246,.3); }
  971. .btn-cr-amber { background:rgba(245,158,11,.15); color:var(--amber); border-color:rgba(245,158,11,.3); }
  972. .btn-cr-teal { background:rgba(20,184,166,.15); color:var(--teal); border-color:rgba(20,184,166,.3); }
  973. .btn-cr-rose { background:rgba(244,63,94,.15); color:var(--rose); border-color:rgba(244,63,94,.3); }
  974. .btn-cr-vi { background:rgba(139,92,246,.15); color:var(--vi); border-color:rgba(139,92,246,.3); }
  975. .btn-cr-em { background:rgba(16,185,129,.15); color:var(--em); border-color:rgba(16,185,129,.3); }
  976. /* ── Tables ──────────────────────────────────────────── */
  977. .cr-table-wrap {
  978. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  979. overflow:hidden; margin-bottom:20px;
  980. }
  981. .cr-table-title {
  982. padding:14px 18px 12px; border-bottom:1px solid var(--bdr);
  983. font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;
  984. }
  985. .cr-table-title .dot { width:7px;height:7px;border-radius:50%; }
  986. .d-bl{background:var(--blue);box-shadow:0 0 5px var(--blue);}
  987. .d-am{background:var(--amber);box-shadow:0 0 5px var(--amber);}
  988. table.cr-tbl { width:100%; border-collapse:collapse; font-size:13px; }
  989. table.cr-tbl th { padding:10px 14px; color:var(--dim); font-weight:500; font-size:11.5px; text-transform:uppercase; letter-spacing:.05em; border-bottom:1px solid var(--bdr); background:var(--s2); }
  990. table.cr-tbl td { padding:9px 14px; border-bottom:1px solid rgba(0,0,0,.05); }
  991. table.cr-tbl tr:last-child td { border-bottom:none; }
  992. table.cr-tbl tr:hover td { background:rgba(0,0,0,.025); }
  993. .tag-exam { display:inline-block; background:rgba(244,63,94,.15); color:var(--rose); padding:2px 8px; border-radius:4px; font-size:11px; }
  994. /* ── Grille graphiques ───────────────────────────────── */
  995. .chart-grid { display:grid; gap:16px; margin-bottom:16px; }
  996. .cg-2 { grid-template-columns:1fr 1fr; }
  997. .cg-1 { grid-template-columns:1fr; }
  998. @media(max-width:900px){ .cg-2 { grid-template-columns:1fr; } }
  999. /* ── Carte graphique ─────────────────────────────────── */
  1000. .cc {
  1001. background:var(--s1); border:1px solid var(--bdr); border-radius:var(--r);
  1002. overflow:hidden; transition:border-color .2s; animation:cIn .4s ease both;
  1003. }
  1004. .cc:hover { border-color:var(--bdr-hi); }
  1005. .cc__hd {
  1006. display:flex; align-items:center; justify-content:space-between;
  1007. padding:13px 18px 11px; border-bottom:1px solid var(--bdr);
  1008. }
  1009. .cc__lbl { display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; }
  1010. .cc__dot { width:7px;height:7px;border-radius:50%;flex-shrink:0; }
  1011. .d-tl{background:var(--teal);box-shadow:0 0 5px var(--teal);}
  1012. .d-rs{background:var(--rose);box-shadow:0 0 5px var(--rose);}
  1013. .d-vi{background:var(--vi);box-shadow:0 0 5px var(--vi);}
  1014. .d-em{background:var(--em);box-shadow:0 0 5px var(--em);}
  1015. .cc__sub { font-size:11px; color:var(--muted); }
  1016. .cc__bd { padding:16px 18px 18px; }
  1017. /* ── Heatmap ─────────────────────────────────────────── */
  1018. .heatmap { overflow-x:auto; }
  1019. .heatmap table { width:100%; border-collapse:collapse; font-size:12px; }
  1020. .heatmap th { padding:7px 10px; color:var(--dim); font-size:11px; text-transform:uppercase; letter-spacing:.05em; text-align:center; font-weight:500; }
  1021. .heatmap th.course-th { text-align:left; min-width:140px; }
  1022. .heatmap td { padding:5px 8px; text-align:center; border:1px solid rgba(0,0,0,.05); font-weight:500; font-size:12.5px; border-radius:4px; transition:opacity .2s; }
  1023. .heatmap td:hover { opacity:.8; }
  1024. .heatmap td.course-td { text-align:left; color:var(--txt); font-weight:400; font-size:12px; padding-left:4px; background:transparent !important; border:none; }
  1025. .hm-null { background:rgba(0,0,0,.05); color:var(--muted); }
  1026. .hm-red { background:rgba(163,45,45,.15); color:#7f1d1d; }
  1027. .hm-yellow { background:rgba(133,79,11,.15); color:#451a03; }
  1028. .hm-green { background:rgba(15,110,86,.15); color:#064e3b; }
  1029. @keyframes cIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  1030. .cc:nth-child(1){animation-delay:.04s}.cc:nth-child(2){animation-delay:.1s}
  1031. #c-evol { max-height:220px; width:100%!important; }
  1032. #c-success{ max-height:260px; width:100%!important; }
  1033. #c-radar { max-height:300px; width:100%!important; }
  1034. #c-mentions{ max-height:220px; max-width:220px; margin:auto; display:block; }
  1035. </style>
  1036. {% endblock %}
  1037. {% block content %}
  1038. <div class=\"cr-page p-3\">
  1039. {# ── Entête classe ────────────────────────────────────────────── #}
  1040. <div class=\"cr-head\">
  1041. <div>
  1042. <div class=\"cr-head__name\">{{ classroom.name }}</div>
  1043. <div class=\"cr-head__meta\">
  1044. Niveau {{ classroom.level }}
  1045. {% if mainteacher %} · Titulaire : <strong>{{ mainteacher.fullName }}</strong>{% endif %}
  1046. </div>
  1047. </div>
  1048. <div class=\"cr-head__badges\">
  1049. <span class=\"badge-pill bp-blue\"><i class=\"fa fa-users\"></i> {{ studentEnrolled|length }} élèves</span>
  1050. {% if classroom.apc %}
  1051. <span class=\"badge-pill bp-amber\"><i class=\"fa fa-graduation-cap\"></i> Classe d'examen</span>
  1052. {% endif %}
  1053. </div>
  1054. </div>
  1055. {# ── Boutons actions ──────────────────────────────────────────── #}
  1056. <div class=\"cr-actions\">
  1057. <a class=\"btn-cr btn-cr-blue\" href=\"{{ path('admin_classrooms') }}\"><i class=\"fa fa-list\"></i> Liste</a>
  1058. {% if is_granted('ROLE_ADMIN') %}
  1059. <a class=\"btn-cr btn-cr-blue\" href=\"{{ path('admin_classrooms_edit', {id: classroom.id}) }}\"><i class=\"fa fa-edit\"></i> Modifier</a>
  1060. <a class=\"btn-cr btn-cr-amber\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"{{ path('admin_classrooms_recapitulatif_seq', {id: classroom.id}) }}\"><i class=\"fa fa-file-pdf-o\"></i> Recap Seq</a>
  1061. <a class=\"btn-cr btn-cr-amber\" href=\"{{ path('admin_classrooms_reportcards_seq', {id: classroom.id}) }}\"><i class=\"fa fa-file\"></i> Bull Seq</a>
  1062. <a class=\"btn-cr btn-cr-teal\" data-toggle=\"modal\" data-target=\"#form_modal_reportcard_params\" data-action=\"{{ path('admin_classrooms_reportcards_trim_2024', {id: classroom.id}) }}\"><i class=\"fa fa-file\"></i> Bull Trim</a>
  1063. <a class=\"btn-cr btn-cr-vi\" data-toggle=\"modal\" data-target=\"#form_modal_reportcard_params\" data-action=\"{{ path('admin_class_reportcards_year_2024', {id: classroom.id}) }}\"><i class=\"fa fa-file-pdf-o\"></i> Bull Ann</a>
  1064. <a class=\"btn-cr btn-cr-rose\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"{{ path('admin_classrooms_recapitulatif_trim', {id: classroom.id}) }}\"><i class=\"fa fa-file-pdf-o\"></i> Recap Trim</a>
  1065. <a class=\"btn-cr btn-cr-em\" data-toggle=\"modal\" data-target=\"#form_modal_courses\" data-action=\"{{ path('admin_classrooms_recapitulatif_ann_excel', {id: classroom.id}) }}\"><i class=\"fa fa-file-excel-o\"></i> Recap Ann</a>
  1066. {% endif %}
  1067. </div>
  1068. {# ── Tables élèves + matières ─────────────────────────────────── #}
  1069. <div class=\"cg-2 chart-grid\">
  1070. <div class=\"cr-table-wrap\">
  1071. <div class=\"cr-table-title\"><span class=\"dot d-bl\"></span>Élèves inscrits</div>
  1072. <table class=\"cr-tbl\">
  1073. <thead><tr><th>Matricule</th><th>Nom</th><th>Prénom</th>{% if is_granted('ROLE_ADMIN') %}<th>Action</th>{% endif %}</tr></thead>
  1074. <tbody>
  1075. {% set effectif = 0 %}
  1076. {% for std in studentEnrolled %}
  1077. <tr>
  1078. <td><a href=\"{{ path('admin_students_show', {id: std.id}) }}\" style=\"color:var(--blue)\">{{ std.matricule }}</a></td>
  1079. <td>{{ std.lastname }}</td>
  1080. <td>{{ std.firstname }}</td>
  1081. {% if is_granted('ROLE_ADMIN') %}
  1082. <td>
  1083. <a class=\"btn-cr btn-cr-rose\" style=\"padding:3px 8px;font-size:11px\" href=\"{{ path('admin_students_unregister', {id: std.id, room_id: classroom.id}) }}\"><i class=\"fa fa-ban\"></i></a>
  1084. <a class=\"btn-cr\" style=\"padding:3px 8px;font-size:11px\" href=\"{{ path('admin_students_edit', {id: std.id}) }}\"><i class=\"fa fa-pencil-square-o\"></i></a>
  1085. </td>
  1086. {% endif %}
  1087. </tr>
  1088. {% set effectif = effectif + 1 %}
  1089. {% endfor %}
  1090. <tr><td colspan=\"2\" style=\"color:var(--dim);font-size:11.5px\">Effectif total</td><td style=\"font-weight:700;color:var(--blue)\">{{ effectif }}</td>{% if is_granted('ROLE_ADMIN') %}<td></td>{% endif %}</tr>
  1091. </tbody>
  1092. </table>
  1093. </div>
  1094. <div class=\"cr-table-wrap\">
  1095. <div class=\"cr-table-title\"><span class=\"dot d-am\"></span>Matières programmées</div>
  1096. <table class=\"cr-tbl\">
  1097. <thead><tr><th>Module</th><th>Code</th><th>Intitulé</th><th>Coef</th><th>Enseignant</th></tr></thead>
  1098. <tbody>
  1099. {% set totalCoef = 0 %}
  1100. {% for module in modules %}
  1101. {% for course in module.courses %}
  1102. <tr>
  1103. <td style=\"color:var(--dim);font-size:11.5px\">{{ module.name }}</td>
  1104. <td><a href=\"{{ path('admin_courses_show', {id: course.id}) }}\" style=\"color:var(--blue)\">{{ course.code }}</a></td>
  1105. <td>{{ course.wording }}</td>
  1106. <td style=\"font-weight:600\">{{ course.coefficient }}</td>
  1107. <td>
  1108. {% if attributions[course.id] is defined %}
  1109. {% if is_granted('ROLE_ADMIN') %}
  1110. <a href=\"{{ path('admin_attributions_edit', {id: attributions[course.id].id}) }}\" style=\"color:var(--teal)\">{{ attributions[course.id].teacher.fullName }}</a>
  1111. {% else %}{{ attributions[course.id].teacher.fullName }}{% endif %}
  1112. {% else %}
  1113. {% if is_granted('ROLE_ADMIN') %}<a href=\"{{ path('admin_attributions_new') }}\" style=\"color:var(--rose)\">Non attribué</a>{% endif %}
  1114. {% endif %}
  1115. </td>
  1116. </tr>
  1117. {% set totalCoef = totalCoef + course.coefficient %}
  1118. {% endfor %}
  1119. {% endfor %}
  1120. <tr><td colspan=\"3\" style=\"color:var(--dim);font-size:11.5px\">Total coefficients</td><td style=\"font-weight:700;color:var(--amber)\" colspan=\"2\">{{ totalCoef }}</td></tr>
  1121. </tbody>
  1122. </table>
  1123. </div>
  1124. </div>
  1125. {# ══════════════════════════════════════════════════════════════
  1126. SECTION GRAPHIQUES
  1127. ══════════════════════════════════════════════════════════════ #}
  1128. {# ── Graphique 1 : Heatmap cours × séquences ──────────────────
  1129. Résout le problème original : chaque cellule est indépendante,
  1130. null (pas d'éval) = gris neutre, aucun décalage possible.
  1131. ─────────────────────────────────────────────────────────────── #}
  1132. <div class=\"cc\" style=\"margin-bottom:16px\">
  1133. <div class=\"cc__hd\">
  1134. <div class=\"cc__lbl\"><span class=\"cc__dot d-am\"></span>Performances séquentielles — toutes matières</div>
  1135. <span class=\"cc__sub\">rouge &lt;10 · jaune 10–13 · vert ≥14 · gris = pas d'évaluation enregistrée</span>
  1136. </div>
  1137. <div class=\"cc__bd heatmap\">
  1138. <table id=\"heatmap-table\">
  1139. <thead>
  1140. <tr>
  1141. <th class=\"course-th\">Matière</th>
  1142. {# Les en-têtes de séquences sont injectées par JS #}
  1143. </tr>
  1144. </thead>
  1145. <tbody id=\"heatmap-body\"></tbody>
  1146. </table>
  1147. </div>
  1148. </div>
  1149. {# ── Graphique 2 + 3 : Évolution + Réussite/Échec ─────────── #}
  1150. <div class=\"chart-grid cg-2\">
  1151. <div class=\"cc\">
  1152. <div class=\"cc__hd\">
  1153. <div class=\"cc__lbl\"><span class=\"cc__dot d-tl\"></span>Évolution de la moyenne générale</div>
  1154. <span class=\"cc__sub\">séquence par séquence · ligne rouge = seuil 10</span>
  1155. </div>
  1156. <div class=\"cc__bd\"><canvas id=\"c-evol\"></canvas></div>
  1157. </div>
  1158. <div class=\"cc\">
  1159. <div class=\"cc__hd\">
  1160. <div class=\"cc__lbl\"><span class=\"cc__dot d-rs\"></span>Réussite vs Échec — {{ activeSeqLabel }}</div>
  1161. <span class=\"cc__sub\">séquence active · avec absents</span>
  1162. </div>
  1163. <div class=\"cc__bd\"><canvas id=\"c-success\"></canvas></div>
  1164. </div>
  1165. </div>
  1166. {# ── Graphique 4 + 5 : Radar + Donut ─────────────────────────
  1167. Radar : profil trimestriel de la classe (points forts/faibles)
  1168. Donut : examens officiels (seulement si classe d'examen)
  1169. ─────────────────────────────────────────────────────────────── #}
  1170. <div class=\"chart-grid {{ classroom.apc ? 'cg-2' : 'cg-1' }}\">
  1171. <div class=\"cc\">
  1172. <div class=\"cc__hd\">
  1173. <div class=\"cc__lbl\"><span class=\"cc__dot d-vi\"></span>Profil trimestriel de la classe</div>
  1174. <span class=\"cc__sub\">radar par matière · T1, T2, T3</span>
  1175. </div>
  1176. <div class=\"cc__bd\"><canvas id=\"c-radar\"></canvas></div>
  1177. </div>
  1178. {% if classroom.apc %}
  1179. <div class=\"cc\">
  1180. <div class=\"cc__hd\">
  1181. <div class=\"cc__lbl\"><span class=\"cc__dot d-em\"></span>Résultats examens officiels</div>
  1182. <span class=\"cc__sub\">répartition des mentions</span>
  1183. </div>
  1184. <div class=\"cc__bd\" style=\"display:flex;align-items:center;justify-content:center\">
  1185. <canvas id=\"c-mentions\"></canvas>
  1186. </div>
  1187. </div>
  1188. {% endif %}
  1189. </div>
  1190. </div>{# /.cr-page #}
  1191. {# ══════════════════════════════════════════════════════════════
  1192. MODALES (inchangées)
  1193. ══════════════════════════════════════════════════════════════ #}
  1194. <div class=\"modal fade\" id=\"form_modal_courses\" tabindex=\"-1\" role=\"dialog\">
  1195. <div class=\"modal-dialog modal-dialog-centered\">
  1196. <div class=\"modal-content\" style=\"background:#ffffff;color:#1a2535;border:1px solid rgba(0,0,0,.12)\">
  1197. <div class=\"modal-header border-bottom-0\">
  1198. <h5 class=\"modal-title\">Choisir les cours du récapitulatif</h5>
  1199. <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"color:var(--txt)\"><span>&times;</span></button>
  1200. </div>
  1201. <form action=\"#\" method=\"post\">
  1202. <div class=\"modal-body\">
  1203. {% for module in modules %}{% for course in module.courses %}
  1204. <li class=\"list-group-item\" style=\"background:transparent;border-color:var(--bdr);color:var(--txt)\">
  1205. <input class=\"form-check-input me-1\" type=\"checkbox\" checked name=\"selected_courses[]\" value=\"{{ course.id }}\">
  1206. {{ course.wording }}
  1207. </li>
  1208. {% endfor %}{% endfor %}
  1209. </div>
  1210. <div class=\"modal-footer border-top-0 d-flex justify-content-center\">
  1211. <button type=\"submit\" class=\"btn-cr btn-cr-em\">Générer</button>
  1212. </div>
  1213. </form>
  1214. </div>
  1215. </div>
  1216. </div>
  1217. <div class=\"modal fade\" id=\"form_modal_reportcard_params\" tabindex=\"-1\" role=\"dialog\">
  1218. <div class=\"modal-dialog modal-dialog-centered\">
  1219. <div class=\"modal-content\" style=\"background:#ffffff;color:#1a2535;border:1px solid rgba(0,0,0,.12)\">
  1220. <div class=\"modal-header border-bottom-0\">
  1221. <h5 class=\"modal-title\">Paramètres du bulletin</h5>
  1222. <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"color:var(--txt)\"><span>&times;</span></button>
  1223. </div>
  1224. <form method=\"post\">
  1225. <div class=\"modal-body\">
  1226. <div class=\"form-check mb-2\"><input class=\"form-check-input\" type=\"checkbox\" name=\"copyright\" id=\"copyright\"><label class=\"form-check-label\" for=\"copyright\">Copyright en pied de page</label></div>
  1227. <div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" name=\"reverse\" id=\"reverse\"><label class=\"form-check-label\" for=\"reverse\">Sens inverse</label></div>
  1228. </div>
  1229. <div class=\"modal-footer border-top-0 d-flex justify-content-center\">
  1230. <button type=\"submit\" class=\"btn-cr btn-cr-blue\">Générer</button>
  1231. </div>
  1232. </form>
  1233. </div>
  1234. </div>
  1235. </div>
  1236. {% endblock %}
  1237. {% block javascripts %}
  1238. {{ parent() }}
  1239. <script>
  1240. (function(){
  1241. 'use strict';
  1242. /* ── Données depuis le controller ─────────────────────── */
  1243. const courseLabels = {{ courseLabels | raw }};
  1244. const seqLabels = {{ seqLabels | raw }};
  1245. const seqIds = {{ seqIds | raw }};
  1246. const heatmapData = {{ heatmapData | raw }};
  1247. const generalAvgBySeq = {{ generalAvgBySeq | raw }};
  1248. const successFailData = {{ successFailData | raw }};
  1249. const quaterProfiles = {{ quaterProfiles | raw }};
  1250. {% if classroom.apc %}
  1251. const mentionCategories = {{ mentionCategories | raw }};
  1252. const mentionCountCategories = {{ mentionCountCategories | raw }};
  1253. {% endif %}
  1254. /* ── Palette & defaults ───────────────────────────────── */
  1255. const C = {
  1256. blue:'#185fa5', rose:'#a32d2d', amber:'#854f0b',
  1257. teal:'#0f6e56', vi:'#534ab7', em:'#3b6d11', orange:'#9a4f0b',
  1258. grid:'rgba(0,0,0,.07)', bg:'#ffffff', txt:'#1a2535', dim:'#4a5568'
  1259. };
  1260. const PALQ = ['rgba(24,95,165,.35)','rgba(15,110,86,.35)','rgba(83,74,183,.35)'];
  1261. const PALQ_BD = ['#185fa5', '#0f6e56', '#534ab7'];
  1262. const PAL = ['#3b82f6','#f59e0b','#f43f5e','#10b981','#8b5cf6','#14b8a6','#f97316','#84cc16'];
  1263. Chart.defaults.color = C.dim;
  1264. Chart.defaults.font.family = \"'DM Sans','Segoe UI',sans-serif\";
  1265. Chart.defaults.font.size = 12;
  1266. const TIP = {backgroundColor:'#ffffff',borderColor:'rgba(0,0,0,.12)',borderWidth:1,titleColor:C.txt,bodyColor:C.dim,padding:12,cornerRadius:10};
  1267. const AX = (o={}) => ({grid:{color:C.grid,drawBorder:false},ticks:{color:C.dim},border:{display:false},...o});
  1268. /* ══════════════════════════════════════════════════════
  1269. 1. HEATMAP — table HTML colorée cours × séquences
  1270. Résout le problème de départ : chaque cellule est
  1271. indépendante. null = gris \"pas d'éval enregistrée\".
  1272. ══════════════════════════════════════════════════════ */
  1273. (function buildHeatmap(){
  1274. const thead = document.querySelector('#heatmap-table thead tr');
  1275. const tbody = document.getElementById('heatmap-body');
  1276. // En-têtes séquences
  1277. seqLabels.forEach(lbl => {
  1278. const th = document.createElement('th');
  1279. th.textContent = lbl;
  1280. thead.appendChild(th);
  1281. });
  1282. // Colonne moyenne
  1283. const thAvg = document.createElement('th');
  1284. thAvg.textContent = 'Moy.';
  1285. thead.appendChild(thAvg);
  1286. // Lignes de données
  1287. heatmapData.forEach(row => {
  1288. const tr = document.createElement('tr');
  1289. // Cellule nom de la matière
  1290. const tdName = document.createElement('td');
  1291. tdName.className = 'course-td';
  1292. tdName.textContent = row.course;
  1293. tr.appendChild(tdName);
  1294. let sum = 0, cnt = 0;
  1295. // Cellules par séquence
  1296. seqIds.forEach(sid => {
  1297. const val = row['s' + sid];
  1298. const td = document.createElement('td');
  1299. if (val === null || val === undefined) {
  1300. td.className = 'hm-null';
  1301. td.textContent = '—';
  1302. } else {
  1303. td.className = val < 10 ? 'hm-red' : val < 14 ? 'hm-yellow' : 'hm-green';
  1304. td.textContent = val.toFixed(1);
  1305. sum += val; cnt++;
  1306. }
  1307. tr.appendChild(td);
  1308. });
  1309. // Cellule moyenne
  1310. const tdAvg = document.createElement('td');
  1311. if (cnt > 0) {
  1312. const avg = sum / cnt;
  1313. tdAvg.className = avg < 10 ? 'hm-red' : avg < 14 ? 'hm-yellow' : 'hm-green';
  1314. tdAvg.textContent = avg.toFixed(1);
  1315. tdAvg.style.fontWeight = '700';
  1316. } else {
  1317. tdAvg.className = 'hm-null';
  1318. tdAvg.textContent = '—';
  1319. }
  1320. tr.appendChild(tdAvg);
  1321. tbody.appendChild(tr);
  1322. });
  1323. })();
  1324. /* ══════════════════════════════════════════════════════
  1325. 2. ÉVOLUTION MOYENNE GÉNÉRALE
  1326. null = séquence pas encore notée → pas de point tracé
  1327. ══════════════════════════════════════════════════════ */
  1328. if (document.getElementById('c-evol')) {
  1329. new Chart('c-evol', {
  1330. type: 'line',
  1331. data: {
  1332. labels: seqLabels,
  1333. datasets: [{
  1334. label: 'Moyenne générale',
  1335. data : generalAvgBySeq,
  1336. borderColor: '#0f6e56', backgroundColor: 'rgba(15,110,86,.08)',
  1337. borderWidth: 2.5, pointBackgroundColor: '#0f6e56',
  1338. pointRadius: generalAvgBySeq.map(v => v !== null ? 5 : 0),
  1339. pointHoverRadius: 7, tension: .3, fill: true,
  1340. spanGaps: false, // ne pas relier les points si null entre eux
  1341. }]
  1342. },
  1343. options: {
  1344. responsive: true,
  1345. plugins: {
  1346. legend: { display: false },
  1347. tooltip: { ...TIP, callbacks: { label: c => c.raw !== null ? ' Moy. : ' + c.raw + '/20' : ' Pas d\\'évaluation' } },
  1348. },
  1349. scales: {
  1350. x: { ...AX() },
  1351. y: { ...AX(), min: 0, max: 20, ticks: { ...AX().ticks, stepSize: 5 } },
  1352. },
  1353. },
  1354. plugins: [{
  1355. id: 'seuil',
  1356. afterDraw(ch) {
  1357. const { ctx, chartArea: { left, right }, scales: { y } } = ch;
  1358. const yp = y.getPixelForValue(10);
  1359. ctx.save();
  1360. ctx.beginPath(); ctx.moveTo(left, yp); ctx.lineTo(right, yp);
  1361. ctx.strokeStyle = 'rgba(163,45,45,.5)'; ctx.setLineDash([5, 4]);
  1362. ctx.lineWidth = 1.5; ctx.stroke();
  1363. ctx.fillStyle = 'rgba(163,45,45,.7)'; ctx.font = '11px DM Sans';
  1364. ctx.fillText('Seuil 10', left + 4, yp - 5);
  1365. ctx.restore();
  1366. }
  1367. }]
  1368. });
  1369. }
  1370. /* ══════════════════════════════════════════════════════
  1371. 3. RÉUSSITE VS ÉCHEC (barres empilées)
  1372. Données depuis evaluation.success_h/f + faillures_h/f
  1373. → pas depuis mark, déjà agrégées par le controller
  1374. ══════════════════════════════════════════════════════ */
  1375. if (document.getElementById('c-success') && successFailData.labels.length > 0) {
  1376. new Chart('c-success', {
  1377. type: 'bar',
  1378. data: {
  1379. labels: successFailData.labels,
  1380. datasets: [
  1381. {
  1382. label: 'Réussite', data: successFailData.success,
  1383. backgroundColor: 'rgba(59,109,17,.55)', borderColor: C.em,
  1384. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  1385. },
  1386. {
  1387. label: 'Échec', data: successFailData.failures,
  1388. backgroundColor: 'rgba(163,45,45,.55)', borderColor: C.rose,
  1389. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  1390. },
  1391. {
  1392. label: 'Absents', data: successFailData.absents,
  1393. backgroundColor: 'rgba(133,79,11,.45)', borderColor: C.amber,
  1394. borderWidth: 1.5, borderRadius: 4, borderSkipped: false,
  1395. },
  1396. ],
  1397. },
  1398. options: {
  1399. responsive: true,
  1400. interaction: { mode: 'index', intersect: false },
  1401. plugins: {
  1402. legend: { position: 'top', align: 'end', labels: { boxWidth: 9, boxHeight: 9, borderRadius: 3, useBorderRadius: true, color: C.txt, padding: 12 } },
  1403. tooltip: { ...TIP },
  1404. },
  1405. scales: {
  1406. x: { ...AX(), stacked: true, ticks: { ...AX().ticks, maxRotation: 35 } },
  1407. y: { ...AX(), stacked: true, beginAtZero: true },
  1408. },
  1409. },
  1410. });
  1411. }
  1412. /* ══════════════════════════════════════════════════════
  1413. 4. RADAR PAR TRIMESTRE
  1414. Révèle le profil de la classe : quelle matière est
  1415. forte/faible, stable ou en progression entre trimestres
  1416. ══════════════════════════════════════════════════════ */
  1417. if (document.getElementById('c-radar') && quaterProfiles.length > 0) {
  1418. new Chart('c-radar', {
  1419. type: 'radar',
  1420. data: {
  1421. labels: courseLabels,
  1422. datasets: quaterProfiles.map((qp, i) => ({
  1423. label : qp.label,
  1424. data : qp.data,
  1425. backgroundColor : PALQ[i % PALQ.length],
  1426. borderColor : PALQ_BD[i % PALQ_BD.length],
  1427. borderWidth : 2,
  1428. pointBackgroundColor: PALQ_BD[i % PALQ_BD.length],
  1429. pointRadius : 4,
  1430. spanGaps : true,
  1431. })),
  1432. },
  1433. options: {
  1434. responsive: true,
  1435. plugins: {
  1436. legend: {
  1437. position: 'top', align: 'end',
  1438. labels: { boxWidth: 9, boxHeight: 9, borderRadius: 3, useBorderRadius: true, color: C.txt, padding: 12 }
  1439. },
  1440. tooltip: { ...TIP, callbacks: { label: c => ' ' + c.dataset.label + ' : ' + (c.raw !== null ? c.raw + '/20' : '—') } },
  1441. },
  1442. scales: {
  1443. r: {
  1444. min: 0, max: 20,
  1445. backgroundColor: 'rgba(24,95,165,.04)',
  1446. grid : { color: C.grid },
  1447. angleLines : { color: C.grid },
  1448. ticks : { color: C.dim, backdropColor: 'transparent', stepSize: 5 },
  1449. pointLabels : { color: C.dim, font: { size: 11 } },
  1450. },
  1451. },
  1452. },
  1453. });
  1454. }
  1455. /* ══════════════════════════════════════════════════════
  1456. 5. DONUT EXAMENS OFFICIELS (seulement si classe examen)
  1457. ══════════════════════════════════════════════════════ */
  1458. {% if classroom.apc %}
  1459. if (document.getElementById('c-mentions') && mentionCountCategories.length > 0) {
  1460. new Chart('c-mentions', {
  1461. type: 'doughnut',
  1462. data: {
  1463. labels: mentionCategories,
  1464. datasets: [{
  1465. data: mentionCountCategories,
  1466. backgroundColor: PAL.slice(0, mentionCategories.length),
  1467. borderColor: '#f0f4f8', borderWidth: 3, hoverOffset: 8,
  1468. }],
  1469. },
  1470. options: {
  1471. responsive: true, cutout: '58%',
  1472. plugins: {
  1473. legend: { position: 'bottom', labels: { boxWidth: 8, boxHeight: 8, borderRadius: 2, useBorderRadius: true, color: C.txt, padding: 8, font: { size: 11 } } },
  1474. tooltip: { ...TIP, callbacks: { label: c => ' ' + c.label + ' : ' + c.raw } },
  1475. },
  1476. },
  1477. });
  1478. }
  1479. {% endif %}
  1480. /* ── Modales actions ──────────────────────────────────── */
  1481. \$(document).ready(function () {
  1482. \$('#form_modal_courses').on('show.bs.modal', function (e) {
  1483. \$('#form_modal_courses form').attr('action', \$(e.relatedTarget).data('action'));
  1484. });
  1485. \$('[data-toggle=\"modal\"]').on('click', function () {
  1486. \$('#form_modal_reportcard_params form').attr('action', \$(this).data('action'));
  1487. });
  1488. });
  1489. })();
  1490. </script>
  1491. {% endblock %}
  1492. ", "classroom/show.html.twig", "/var/www/bethesda/templates/classroom/show.html.twig");
  1493. }
  1494. }