Author SHA1 Message Date
imperosol 0c6594b3cd remove CounterAdminMixin 2026-10-09 21:59:37 +02:00
33 changed files with 273 additions and 256 deletions

No files matched your search

+1
View File
@@ -5,6 +5,7 @@
margin-top: 20px; margin-top: 20px;
padding: 0.4em; padding: 0.4em;
width: 80%; width: 80%;
background: $white-color;
h4 { h4 {
margin-top: 1em; margin-top: 1em;
+8 -8
View File
@@ -32,7 +32,7 @@
h3 { h3 {
--box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 3px 7px 2px; --box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 3px 7px 2px;
background: var(--bg-yellow); background: lighten($second-color, 5%);
box-shadow: var(--box-shadow); box-shadow: var(--box-shadow);
padding: .75rem; padding: .75rem;
margin: 0 0 0.5em 0; margin: 0 0 0.5em 0;
@@ -85,7 +85,7 @@
#links_content { #links_content {
overflow: auto; overflow: auto;
box-shadow: var(--bg-darkened-off-white) 1px 1px 1px; box-shadow: $shadow-color 1px 1px 1px;
min-height: 20em; min-height: 20em;
padding: 1em; padding: 1em;
@@ -111,7 +111,7 @@
} }
#birthdays_content { #birthdays_content {
box-shadow: var(--bg-darkened-off-white) 1px 1px 1px; box-shadow: $shadow-color 1px 1px 1px;
padding: 1em; padding: 1em;
ul.birthdays_year { ul.birthdays_year {
@@ -123,7 +123,7 @@
padding: 0.5em; padding: 0.5em;
&:nth-child(even) { &:nth-child(even) {
background: var(--bg-off-white); background: $secondary-neutral-light-color;
} }
} }
@@ -141,7 +141,7 @@
/* EVENTS TODAY AND NEXT FEW DAYS */ /* EVENTS TODAY AND NEXT FEW DAYS */
.news_events_group { .news_events_group {
box-shadow: var(--bg-darkened-off-white) 1px 1px 1px; box-shadow: $shadow-color 1px 1px 1px;
margin-left: 0; margin-left: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;
@@ -153,8 +153,8 @@
display: table-cell; display: table-cell;
padding: 0.6em; padding: 0.6em;
vertical-align: middle; vertical-align: middle;
background: var(--deepblue); background: $primary-neutral-dark-color;
color: var(--text-white); color: $white-color;
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
@@ -180,7 +180,7 @@
} }
.news_event:nth-of-type(even) { .news_event:nth-of-type(even) {
background: var(--bg-white); background: $primary-neutral-light-color;
} }
.news_event { .news_event {
+29 -25
View File
@@ -1,37 +1,41 @@
/** $first-color: hsl(220, 100%, 50%);
* Sith theme variables $second-color: hsl(48, 100%, 67%);
*/ $primary-color: hsl(219.9, 53.7%, 50%);
:root { $secondary-color: hsl(204, 64%, 44%);
--bg-yellow: #ffe270; $primary-color-text: hsl(0, 0%, 100%);
--bg-white: #f9fafb; $secondary-color-text: hsla(0, 0%, 0%, 0.87);
--bg-off-white: #f0f0f0;
--bg-darkened-off-white: #e3e3e3;
--bg-lightgrey: #d4d4d4;
--text-white: #f9fafb; $primary-light-color: hsl(219.8, 46.4%, 64.9%);
--text-black: #2b2b2b; $primary-dark-color: hsl(203, 75%, 40%);
--text-red: #eb2f06;
--blue: #3b69c4; $secondary-light-color: hsl(40, 68%, 65%);
--lightblue: #1a78b3; $secondary-dark-color: hsl(40, 68%, 35%);
// darkened-deepblue is 10% darker than deepblue
// This is explicitely declared, because the `darken` scss function $primary-neutral-color: hsl(219.6, 20.8%, 50%);
// isn't called at compile-time somehow. $primary-neutral-light-color: hsl(0, 0%, 94%);
--deepblue: #354a5f; $primary-neutral-dark-color: hsl(210, 29%, 29%);
--darkened-deepblue: #23313e;
} $secondary-neutral-color: hsl(204, 64%, 44%);
$secondary-neutral-light-color: hsl(0, 0%, 91%);
$secondary-neutral-dark-color: hsl(40, 57.6%, 17%);
$white-color: hsl(219.6, 20.8%, 98%);
$black-color: hsl(0, 0%, 17%);
$red-text-color: #eb2f06;
$hovered-red-text-color: #ff4d4d;
/**
* Brand colours.
* Those are officially defined by their respective companies,
* and so are more appropriate as scss variables.
*/
$faceblue: hsl(221, 44%, 41%); $faceblue: hsl(221, 44%, 41%);
$twitblue: hsl(206, 82%, 63%); $twitblue: hsl(206, 82%, 63%);
$discordblurple: #7289da; $discordblurple: #7289da;
$instagradient: radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%); $instagradient: radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%);
$githubblack: rgb(22, 22, 20); $githubblack: rgb(22, 22, 20);
$shadow-color: rgb(223, 223, 223);
$background-button-color: hsl(0, 0%, 95%);
$deepblue: #354a5f;
@mixin shadow { @mixin shadow {
box-shadow: rgba(60, 64, 67, 0.3) 0 1px 3px 0, box-shadow: rgba(60, 64, 67, 0.3) 0 1px 3px 0,
rgba(60, 64, 67, 0.15) 0 4px 8px 3px; rgba(60, 64, 67, 0.15) 0 4px 8px 3px;
+3 -3
View File
@@ -17,7 +17,7 @@
} }
.card { .card {
background-color: var(--bg-off-white); background-color: $primary-neutral-light-color;
border-radius: 5px; border-radius: 5px;
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
@@ -30,12 +30,12 @@
gap: 20px; gap: 20px;
&:disabled { &:disabled {
background-color: var(--bg-darkened-off-white); background-color: darken($primary-neutral-light-color, 5%);
opacity: 65%; opacity: 65%;
} }
&.clickable:not(:disabled):hover { &.clickable:not(:disabled):hover {
background-color: var(--bg-darkened-off-white); background-color: darken($primary-neutral-light-color, 5%);
} }
&.selected { &.selected {
+4 -8
View File
@@ -11,7 +11,7 @@ ui-tab-group {
.tab-headers { .tab-headers {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
background-color: var(--bg-off-white); background-color: $primary-neutral-light-color;
padding: 3px 12px 12px; padding: 3px 12px 12px;
column-gap: 20px; column-gap: 20px;
border-top-left-radius: 5px; border-top-left-radius: 5px;
@@ -25,27 +25,23 @@ ui-tab-group {
background-color: unset; background-color: unset;
position: relative; position: relative;
&:hover {
background-color: var(--bg-lightgrey);
}
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
border-bottom: 4px solid var(--bg-lightgrey); border-bottom: 4px solid darken($primary-neutral-light-color, 10%);
border-radius: 2px; border-radius: 2px;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
} }
&:hover:after { &:hover:after {
filter: brightness(85%); border-bottom-color: darken($primary-neutral-light-color, 20%);
} }
&.active:after { &.active:after {
border-bottom-color: var(--lightblue); border-bottom-color: $primary-dark-color;
} }
} }
} }
+13 -11
View File
@@ -9,7 +9,7 @@ footer.bottom-links {
@media (max-width: $small-devices) { @media (max-width: $small-devices) {
margin-top: 0.6em; margin-top: 0.6em;
padding: 1.25em; padding: 1.25em;
background-color: var(--deepblue); background-color: $primary-neutral-dark-color;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -28,24 +28,24 @@ footer.bottom-links {
} }
a { a {
color: var(--text-white); color: $white-color;
width: auto; width: auto;
&:hover { &:hover {
color: var(--text-white); color: $white-color;
text-shadow: 0.5px 0.5px 0.5px var(--bg-darkened-off-white); text-shadow: 0.5px 0.5px 0.5px $shadow-color;
} }
} }
.fa-github { .fa-github {
color: var(--text-white); color: $white-color;
} }
hr { hr {
width: 100%; width: 100%;
height: 0; height: 0px;
border: none; border: none;
border-top: 0.5px solid var(--bg-white); border-top: 0.5px solid $white-color;
} }
} }
@@ -59,22 +59,24 @@ footer.bottom-links {
section:first-of-type { section:first-of-type {
margin: 0.6em 0; margin: 0.6em 0;
color: var(--text-white); color: $white-color;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
background-color: var(--deepblue); background-color: $primary-neutral-dark-color;
box-shadow: var(--bg-white) 0 0 15px; box-shadow: $shadow-color 0 0 15px;
a { a {
color: $white-color;
width: auto; width: auto;
padding: 0.8em; padding: 0.8em;
flex: 1; flex: 1;
font-weight: bold; font-weight: bold;
&:hover { &:hover {
text-shadow: 0.5px 0.5px 0.5px var(--bg-white); color: $white-color;
text-shadow: 0.5px 0.5px 0.5px $shadow-color;
} }
} }
} }
+14 -10
View File
@@ -16,6 +16,7 @@
input[type="file"] { input[type="file"] {
border: none; border: none;
text-decoration: none; text-decoration: none;
background-color: $background-button-color;
padding: 0.4em; padding: 0.4em;
margin: 0.1em; margin: 0.1em;
font-size: 1.2em; font-size: 1.2em;
@@ -23,7 +24,7 @@
color: black; color: black;
&:not(.link-like):not(:disabled):hover { &:not(.link-like):not(:disabled):hover {
background: var(--bg-lightgrey); background: hsl(0, 0%, 83%);
} }
} }
@@ -52,7 +53,7 @@
.ts-control { .ts-control {
border: none; border: none;
text-decoration: none; text-decoration: none;
//background-color: $background-button-color; background-color: $background-button-color;
padding: 0.4em; padding: 0.4em;
margin: 0.1em; margin: 0.1em;
font-size: 1.2em; font-size: 1.2em;
@@ -63,7 +64,7 @@
textarea { textarea {
border: none; border: none;
text-decoration: none; text-decoration: none;
//background-color: $background-button-color; background-color: $background-button-color;
padding: 7px; padding: 7px;
font-size: 1.2em; font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
@@ -74,7 +75,7 @@
border: none; border: none;
text-decoration: none; text-decoration: none;
font-size: 1.2em; font-size: 1.2em;
//background-color: $background-button-color; background-color: $background-button-color;
padding: 10px; padding: 10px;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
@@ -82,14 +83,14 @@
a:not(.button) { a:not(.button) {
text-decoration: none; text-decoration: none;
color: var(--lightblue); color: $primary-dark-color;
&:hover { &:hover {
color: var(--blue); color: $primary-light-color;
} }
&:active { &:active {
color: var(--blue); color: $primary-color;
} }
} }
} }
@@ -761,13 +762,16 @@ form {
// a submit input that should look like a regular <a> // a submit input that should look like a regular <a>
input[type="submit"], button { input[type="submit"], button {
&.link-like { &.link-like {
color: var(--lightblue); color: $primary-dark-color;
&:hover { &:hover {
color: var(--blue); color: $primary-light-color;
} }
&.link-red { &.link-red {
color: var(--text-red); color: $red-text-color;
&:hover {
color: $hovered-red-text-color;
}
} }
font-weight: normal; font-weight: normal;
font-size: 100%; font-size: 100%;
+4 -4
View File
@@ -7,7 +7,7 @@ $background-color-hovered: #283747;
.header { .header {
box-sizing: border-box; box-sizing: border-box;
background-color: var(--deepblue); background-color: $deepblue;
box-shadow: 3px 3px 3px 0 #dfdfdf; box-shadow: 3px 3px 3px 0 #dfdfdf;
border-radius: 0; border-radius: 0;
width: 100%; width: 100%;
@@ -96,7 +96,7 @@ $background-color-hovered: #283747;
border-radius: 0; border-radius: 0;
margin: 0; margin: 0;
box-sizing: border-box; box-sizing: border-box;
background-color: var(--deepblue); background-color: $deepblue;
width: 45px; width: 45px;
height: 25px; height: 25px;
padding: 0; padding: 0;
@@ -212,7 +212,7 @@ $background-color-hovered: #283747;
background-position: center center; background-position: center center;
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: var(--deepblue); background-color: $deepblue;
} }
>.options { >.options {
@@ -298,7 +298,7 @@ $background-color-hovered: #283747;
width: 10px; width: 10px;
height: 10px; height: 10px;
padding: 5px; padding: 5px;
background-color: var(--text-red); background-color: $red-text-color;
border-radius: 50%; border-radius: 50%;
position: absolute; position: absolute;
top: -50%; top: -50%;
+5 -2
View File
@@ -1,4 +1,7 @@
.markdown { .markdown {
--bg-lightgrey: rgb(240, 241, 245);
--border-lightgrey: rgb(215, 216, 220);
h1, h1,
h2, h2,
h3, h3,
@@ -25,8 +28,8 @@
font-size: 14px; font-size: 14px;
tab-size: 4; tab-size: 4;
border-radius: 4px; border-radius: 4px;
border: 1px solid var(--bg-lightgrey); border: 1px solid var(--border-lightgrey);
background-color: var(--bg-off-white); background-color: var(--bg-lightgrey);
padding: 1px 2px; padding: 1px 2px;
} }
+1 -1
View File
@@ -3,7 +3,7 @@
$desktop-size: 500px; $desktop-size: 500px;
nav.navbar { nav.navbar {
background-color: var(--lightblue); background-color: $primary-dark-color;
margin: 1em; margin: 1em;
color: white; color: white;
border-radius: 0.6em; border-radius: 0.6em;
+10 -4
View File
@@ -6,21 +6,27 @@
margin: 30px; margin: 30px;
button { button {
background-color: var(--bg-off-white); background-color: $secondary-neutral-light-color;
min-width: 37px; min-width: 37px;
&:hover { &:hover {
background-color: var(--bg-lightgrey); background-color: darken($secondary-neutral-light-color, 10%);
}
&:disabled {
color: #fff;
background-color: darken($secondary-neutral-light-color, 5%);
} }
&.active, &.active,
&.active:hover { &.active:hover {
background-color: var(--deepblue); background-color: $primary-neutral-color;
color: white; color: white;
border-radius: 50%; border-radius: 50%;
} }
.pagination-arrow { &:first-of-type,
&:last-of-type {
// previous and next buttons // previous and next buttons
&:disabled { &:disabled {
// Hide the arrows when they are disabled, without // Hide the arrows when they are disabled, without
+24 -23
View File
@@ -57,7 +57,7 @@ body {
.collapse-header { .collapse-header {
color: white; color: white;
background-color: var(--deepblue); background-color: $deepblue;
padding: 5px 10px; padding: 5px 10px;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -141,7 +141,7 @@ body {
} }
#info_box { #info_box {
background: var(--bg-off-white); background: $primary-neutral-light-color;
&:before { &:before {
content: "\f05a"; content: "\f05a";
@@ -150,11 +150,11 @@ body {
} }
#alert_box { #alert_box {
background: var(--bg-yellow); background: $second-color;
&:before { &:before {
content: "\f06a"; content: "\f06a";
color: var(--text-white); color: $white-color;
} }
} }
} }
@@ -189,10 +189,10 @@ body {
border-radius: 5px; border-radius: 5px;
&.btn-blue { &.btn-blue {
background-color: var(--deepblue); background-color: $deepblue;
&:not(:disabled):hover { &:not(:disabled):hover {
background-color: var(--darkened-deepblue); background-color: darken($deepblue, 10%);
} }
&:disabled { &:disabled {
@@ -215,7 +215,7 @@ body {
&.btn-green { &.btn-green {
$bg-color: rgba(0, 210, 83, 0.4); $bg-color: rgba(0, 210, 83, 0.4);
background-color: $bg-color; background-color: $bg-color;
color: var(--text-black); color: $black-color;
&:not(:disabled):hover { &:not(:disabled):hover {
background-color: darken($bg-color, 15%); background-color: darken($bg-color, 15%);
@@ -272,8 +272,8 @@ body {
/*--------------------------------CONTENT------------------------------*/ /*--------------------------------CONTENT------------------------------*/
#content { #content {
padding: 1.5em 3%; padding: 1.5em 3%;
box-shadow: var(--bg-darkened-off-white) 0 5px 10px; box-shadow: $shadow-color 0 5px 10px;
background: var(--bg-white); background: $white-color;
overflow: auto; overflow: auto;
} }
@@ -343,7 +343,7 @@ body {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
float: right; float: right;
background: var(--bg-off-white); background: $primary-neutral-light-color;
padding: 5px; padding: 5px;
border-radius: 6px; border-radius: 6px;
text-align: center; text-align: center;
@@ -351,7 +351,7 @@ body {
a { a {
padding: 7px; padding: 7px;
display: inline-block; display: inline-block;
color: var(--text-black); color: $black-color;
font-weight: bold; font-weight: bold;
margin: 2px; margin: 2px;
flex: 1; flex: 1;
@@ -359,14 +359,14 @@ body {
white-space: nowrap; white-space: nowrap;
&.selected_tab { &.selected_tab {
background: var(--blue); background: $primary-color;
color: var(--text-white); color: $white-color;
border-radius: 6px; border-radius: 6px;
} }
&:hover { &:hover {
background: var(--blue); background: $primary-color;
color: var(--text-white); color: $white-color;
border-radius: 6px; border-radius: 6px;
} }
} }
@@ -556,23 +556,23 @@ thead td {
} }
thead { thead {
background-color: var(--deepblue); background-color: $deepblue;
color: white; color: white;
} }
tbody>tr { tbody>tr {
&:nth-child(even):not(.highlight) { &:nth-child(even):not(.highlight) {
background: var(--bg-off-white); background: $primary-neutral-light-color;
} }
&.clickable:hover { &.clickable:hover {
cursor: pointer; cursor: pointer;
background: var(--bg-lightgrey); background: $secondary-neutral-light-color;
width: 100%; width: 100%;
} }
&.highlight { &.highlight {
color: var(--lightblue); color: $primary-dark-color;
font-style: italic; font-style: italic;
} }
} }
@@ -598,7 +598,7 @@ em {
} }
.highlight { .highlight {
background: var(--bg-yellow); background: $second-color;
font-weight: bold; font-weight: bold;
} }
@@ -700,15 +700,15 @@ u,
height: 18em; height: 18em;
overflow: hidden; overflow: hidden;
border: 1px solid black; border: 1px solid black;
box-shadow: var(--bg-darkened-off-white) 1px 1px 1px; box-shadow: $shadow-color 1px 1px 1px;
&:hover { &:hover {
box-shadow: 1px 1px 5px var(--bg-yellow); box-shadow: 1px 1px 5px $second-color;
} }
} }
.matmat_user a { .matmat_user a {
color: var(--deepblue); color: $primary-neutral-dark-color;
height: 100%; height: 100%;
width: 100%; width: 100%;
margin: 0; margin: 0;
@@ -723,6 +723,7 @@ u,
display: block; display: block;
margin: 10px; margin: 10px;
padding: 10px; padding: 10px;
background: $white-color;
} }
textarea { textarea {
+1 -1
View File
@@ -71,7 +71,7 @@ main {
border-radius: 50%; border-radius: 50%;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: var(--bg-white); background-color: $primary-neutral-light-color;
> span { > span {
font-size: small; font-size: small;
+1 -1
View File
@@ -62,7 +62,7 @@
} }
&:enabled>.fa { &:enabled>.fa {
background-color: var(--deepblue); background-color: #354a5f;
color: white; color: white;
} }
+4 -10
View File
@@ -102,7 +102,6 @@
@click.prevent="{{ page }}--" @click.prevent="{{ page }}--"
:disabled="{{ page }} <= 1" :disabled="{{ page }} <= 1"
@keyup.right.window="{{ page }} = Math.min({{ nb_pages }}, {{ page }} + 1)" @keyup.right.window="{{ page }} = Math.min({{ nb_pages }}, {{ page }} + 1)"
class="pagination-arrow"
> >
<i class="fa fa-caret-left"></i> <i class="fa fa-caret-left"></i>
</button> </button>
@@ -113,7 +112,6 @@
@click.prevent="{{ page }}++" @click.prevent="{{ page }}++"
:disabled="{{ page }} >= {{ nb_pages }}" :disabled="{{ page }} >= {{ nb_pages }}"
@keyup.left.window="{{ page }} = Math.max(1, {{ page }} - 1)" @keyup.left.window="{{ page }} = Math.max(1, {{ page }} - 1)"
class="pagination-arrow"
> >
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>
</button> </button>
@@ -165,14 +163,12 @@
href="?{{ querystring(request, page=current_page.previous_page_number()) }}" href="?{{ querystring(request, page=current_page.previous_page_number()) }}"
{%- endif -%} {%- endif -%}
> >
<button class="pagination-arrow"> <button>
<i class="fa fa-caret-left"></i> <i class="fa fa-caret-left"></i>
</button> </button>
</a> </a>
{% else %} {% else %}
<button disabled="disabled" class="pagination-arrow"> <button disabled="disabled"><i class="fa fa-caret-left"></i></button>
<i class="fa fa-caret-left"></i>
</button>
{% endif %} {% endif %}
{% for i in paginator.get_elided_page_range(current_page.number) %} {% for i in paginator.get_elided_page_range(current_page.number) %}
{% if i == current_page.number %} {% if i == current_page.number %}
@@ -205,14 +201,12 @@
{%- else -%} {%- else -%}
href="?{{querystring(request, page=current_page.next_page_number())}}" href="?{{querystring(request, page=current_page.next_page_number())}}"
{%- endif -%} {%- endif -%}
><button class="pagination-arrow"> ><button>
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>
</button> </button>
</a> </a>
{% else %} {% else %}
<button disabled="disabled" class="pagination-arrow"> <button disabled="disabled"><i class="fa fa-caret-right"></i></button>
<i class="fa fa-caret-right"></i>
</button>
{% endif %} {% endif %}
</nav> </nav>
{% endmacro %} {% endmacro %}
@@ -71,7 +71,7 @@
padding: 0.5em; padding: 0.5em;
margin: 0.2em; margin: 0.2em;
height: 100%; height: 100%;
background: var(--bg-off-white); background: $secondary-neutral-light-color;
img { img {
max-width: 70%; max-width: 70%;
+19 -7
View File
@@ -83,8 +83,17 @@
{% endmacro %} {% endmacro %}
{% block content %} {% block content %}
<div class="alert alert-yellow">
<div class="alert-main">
{%- trans trimmed -%}
You can see product details.
However, you cannot edit it, thus you won't be able
to submit this form.
{%- endtrans -%}
</div>
</div>
{% if object %} {% if object %}
<h2>{% trans name=object %}Edit product {{ name }}{% endtrans %}</h2> <h2>{{ object }}</h2>
<p><i>{% trans %}Creation date{% endtrans %} : {{ object.created_at|date }}</i></p> <p><i>{% trans %}Creation date{% endtrans %} : {{ object.created_at|date }}</i></p>
<p><i>{% trans %}Last update{% endtrans %} : {{ object.updated_at|date }}</i></p> <p><i>{% trans %}Last update{% endtrans %} : {{ object.updated_at|date }}</i></p>
{% else %} {% else %}
@@ -127,19 +136,17 @@
{{ form.price_formset.management_form }} {{ form.price_formset.management_form }}
<div x-ref="formContainer"> <div x-ref="formContainer">
{%- for form in form.price_formset.forms -%} {%- for form in form.price_formset.forms -%}
<div> <div>{{ price_form(form) }}</div>
{{ price_form(form) }}
</div>
{%- endfor -%} {%- endfor -%}
</div> </div>
<template x-ref="formTemplate"> <template x-ref="formTemplate">
<div> <div>{{ price_form(form.price_formset.empty_form) }}</div>
{{ price_form(form.price_formset.empty_form) }}
</div>
</template> </template>
{% if user.has_perm("counter.change_product") %}
<button class="btn btn-grey" @click.prevent="addForm()"> <button class="btn btn-grey" @click.prevent="addForm()">
<i class="fa fa-plus"></i> {% trans %}Add a price{% endtrans %} <i class="fa fa-plus"></i> {% trans %}Add a price{% endtrans %}
</button> </button>
{% endif %}
</div> </div>
<br /> <br />
@@ -165,11 +172,16 @@
<template x-ref="formTemplate"> <template x-ref="formTemplate">
{{ action_form(form.action_formset.empty_form) }} {{ action_form(form.action_formset.empty_form) }}
</template> </template>
{% if user.has_perm("counter.change_product") %}
<button @click.prevent="addForm()" class="btn btn-grey"> <button @click.prevent="addForm()" class="btn btn-grey">
<i class="fa fa-plus"></i>{% trans %}Add action{% endtrans %} <i class="fa fa-plus"></i>{% trans %}Add action{% endtrans %}
</button> </button>
{% endif %}
</div> </div>
<div class="row gap margin-bottom">{{ form.archived.as_field_group() }}</div> <div class="row gap margin-bottom">{{ form.archived.as_field_group() }}</div>
{% if user.has_perm("counter.change_product") %}
<p><input class="btn btn-blue" type="submit" value="{% trans %}Save{% endtrans %}" /></p> <p><input class="btn btn-blue" type="submit" value="{% trans %}Save{% endtrans %}" /></p>
{% endif %}
</form> </form>
{% endblock %} {% endblock %}
@@ -80,9 +80,11 @@
<h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3> <h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3>
<div class="row margin-bottom"> <div class="row margin-bottom">
{% if user.has_perm("counter.add_product") %}
<a href="{{ url('counter:new_product') }}" class="btn btn-blue"> <a href="{{ url('counter:new_product') }}" class="btn btn-blue">
{% trans %}New product{% endtrans %} <i class="fa fa-plus"></i> {% trans %}New product{% endtrans %} <i class="fa fa-plus"></i>
</a> </a>
{% endif %}
<button <button
class="btn btn-blue" class="btn btn-blue"
@click="downloadCsv()" @click="downloadCsv()"
@@ -13,12 +13,12 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<p> {% if user.has_perm("counter.add_producttype") %}
<a href="{{ url('counter:new_product_type') }}" class="btn btn-blue"> <a href="{{ url('counter:new_product_type') }}" class="btn btn-blue margin-bottom">
{% trans %}New product type{% endtrans %} {% trans %}New product type{% endtrans %}
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
</a> </a>
</p> {% endif %}
{% if product_types %} {% if product_types %}
<aside> <aside>
<p> <p>
+34 -21
View File
@@ -48,7 +48,7 @@ from counter.models import (
Selling, Selling,
) )
from counter.utils import is_logged_in_counter from counter.utils import is_logged_in_counter
from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin from counter.views.mixins import CounterAdminTabsMixin
class CounterListView(CounterAdminTabsMixin, CanViewMixin, ListView): class CounterListView(CounterAdminTabsMixin, CanViewMixin, ListView):
@@ -84,17 +84,18 @@ class CounterEditView(
return reverse_lazy("counter:admin", kwargs={"counter_id": self.object.id}) return reverse_lazy("counter:admin", kwargs={"counter_id": self.object.id})
class CounterEditPropView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView): class CounterEditPropView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView):
"""Edit a counter's main informations (for the counter's admin).""" """Edit a counter's main infos."""
model = Counter model = Counter
form_class = modelform_factory(Counter, fields=["name", "club", "type"]) form_class = modelform_factory(Counter, fields=["name", "club", "type"])
pk_url_kwarg = "counter_id" pk_url_kwarg = "counter_id"
template_name = "core/edit.jinja" template_name = "core/edit.jinja"
current_tab = "counters" current_tab = "counters"
permission_required = "counter.change_counter"
class CounterCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView): class CounterCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView):
"""Create a counter (for the admins).""" """Create a counter (for the admins)."""
model = Counter model = Counter
@@ -105,9 +106,10 @@ class CounterCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
) )
template_name = "core/create.jinja" template_name = "core/create.jinja"
current_tab = "counters" current_tab = "counters"
permission_required = "counter.add_counter"
class CounterDeleteView(CounterAdminTabsMixin, CounterAdminMixin, DeleteView): class CounterDeleteView(CounterAdminTabsMixin, PermissionRequiredMixin, DeleteView):
"""Delete a counter (for the admins).""" """Delete a counter (for the admins)."""
model = Counter model = Counter
@@ -115,30 +117,33 @@ class CounterDeleteView(CounterAdminTabsMixin, CounterAdminMixin, DeleteView):
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
success_url = reverse_lazy("counter:admin_list") success_url = reverse_lazy("counter:admin_list")
current_tab = "counters" current_tab = "counters"
permission_required = "counter.delete_counter"
# Product management # Product management
class ProductTypeListView(CounterAdminTabsMixin, CounterAdminMixin, ListView): class ProductTypeListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView):
"""A list view for the admins.""" """A list view for the admins."""
model = ProductType model = ProductType
template_name = "counter/product_type_list.jinja" template_name = "counter/product_type_list.jinja"
current_tab = "product_types" current_tab = "product_types"
context_object_name = "product_types" context_object_name = "product_types"
permission_required = "counter.view_producttype"
class ProductTypeCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView): class ProductTypeCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView):
"""A create view for the admins.""" """A create view for the admins."""
model = ProductType model = ProductType
fields = ["name", "description", "comment", "icon"] fields = ["name", "description", "comment", "icon"]
template_name = "core/create.jinja" template_name = "core/create.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.add_producttype"
class ProductTypeEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView): class ProductTypeEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView):
"""An edit view for the admins.""" """An edit view for the admins."""
model = ProductType model = ProductType
@@ -146,23 +151,26 @@ class ProductTypeEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
fields = ["name", "description", "comment", "icon"] fields = ["name", "description", "comment", "icon"]
pk_url_kwarg = "type_id" pk_url_kwarg = "type_id"
current_tab = "products" current_tab = "products"
permission_required = "counter.change_producttype"
class ProductListView(CounterAdminTabsMixin, CounterAdminMixin, TemplateView): class ProductListView(CounterAdminTabsMixin, PermissionRequiredMixin, TemplateView):
current_tab = "products" current_tab = "products"
template_name = "counter/product_list.jinja" template_name = "counter/product_list.jinja"
permission_required = "counter.view_product"
class ProductCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView): class ProductCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView):
"""A create view for the admins.""" """A create view for the admins."""
model = Product model = Product
form_class = ProductForm form_class = ProductForm
template_name = "counter/product_form.jinja" template_name = "counter/product_form.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.add_product"
class ProductEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView): class ProductEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView):
"""An edit view for the admins.""" """An edit view for the admins."""
model = Product model = Product
@@ -170,6 +178,13 @@ class ProductEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
pk_url_kwarg = "product_id" pk_url_kwarg = "product_id"
template_name = "counter/product_form.jinja" template_name = "counter/product_form.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.change_product"
def has_permission(self):
return self.request.user.has_perm("counter.change_product") or (
self.request.method == "GET"
and self.request.user.has_perm("counter.view_product")
)
class ProductFormulaListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView): class ProductFormulaListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView):
@@ -299,7 +314,6 @@ class RefillingDeleteView(DeleteView):
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if timezone.now() - self.object.date <= timedelta( if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT minutes=settings.SITH_LAST_OPERATIONS_LIMIT
@@ -324,7 +338,6 @@ class SellingDeleteView(DeleteView):
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if timezone.now() - self.object.date <= timedelta( if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT minutes=settings.SITH_LAST_OPERATIONS_LIMIT
@@ -376,23 +389,23 @@ class CounterStatView(PermissionRequiredMixin, DetailView):
return kwargs return kwargs
class CounterRefillingListView(CounterAdminTabsMixin, CounterAdminMixin, ListView): class CounterRefillingListView(
CounterAdminTabsMixin, PermissionRequiredMixin, ListView
):
"""List of refillings on a counter.""" """List of refillings on a counter."""
model = Refilling model = Refilling
template_name = "counter/refilling_list.jinja" template_name = "counter/refilling_list.jinja"
current_tab = "counters" current_tab = "counters"
paginate_by = 30 paginate_by = 30
permission_required = "counter.view_refilling"
def dispatch(self, request, *args, **kwargs): def get_queryset(self):
self.counter = get_object_or_404(Counter, pk=kwargs["counter_id"]) self.counter = get_object_or_404(Counter, pk=self.kwargs["counter_id"])
self.queryset = Refilling.objects.filter(counter__id=self.counter.id) return Refilling.objects.filter(counter=self.counter).order_by("-date")
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs = super().get_context_data(**kwargs) return super().get_context_data(**kwargs) | {"counter": self.counter}
kwargs["counter"] = self.counter
return kwargs
class RefoundAccountView(UserPassesTestMixin, FormView): class RefoundAccountView(UserPassesTestMixin, FormView):
+8 -5
View File
@@ -12,7 +12,7 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
@@ -21,28 +21,30 @@ from django.views.generic.edit import CreateView, UpdateView
from core.auth.mixins import CanViewMixin from core.auth.mixins import CanViewMixin
from counter.forms import EticketForm from counter.forms import EticketForm
from counter.models import Eticket, Selling from counter.models import Eticket, Selling
from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin from counter.views.mixins import CounterAdminTabsMixin
class EticketListView(CounterAdminTabsMixin, CounterAdminMixin, ListView): class EticketListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView):
"""A list view for the admins.""" """A list view for the admins."""
model = Eticket model = Eticket
template_name = "counter/eticket_list.jinja" template_name = "counter/eticket_list.jinja"
ordering = ["id"] ordering = ["id"]
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.view_eticket"
class EticketCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView): class EticketCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView):
"""Create an eticket.""" """Create an eticket."""
model = Eticket model = Eticket
template_name = "core/create.jinja" template_name = "core/create.jinja"
form_class = EticketForm form_class = EticketForm
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.add_eticket"
class EticketEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView): class EticketEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView):
"""Edit an eticket.""" """Edit an eticket."""
model = Eticket model = Eticket
@@ -50,6 +52,7 @@ class EticketEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
form_class = EticketForm form_class = EticketForm
pk_url_kwarg = "eticket_id" pk_url_kwarg = "eticket_id"
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.change_eticket"
class EticketPDFView(CanViewMixin, DetailView): class EticketPDFView(CanViewMixin, DetailView):
+35 -35
View File
@@ -13,38 +13,13 @@
# #
# #
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic.base import View
from core.views.mixins import TabedViewMixin from core.views.mixins import TabedViewMixin
from counter.utils import is_logged_in_counter from counter.utils import is_logged_in_counter
class CounterAdminMixin(View):
"""Protect counter admin section."""
edit_group = [settings.SITH_GROUP_COUNTER_ADMIN_ID]
edit_club = []
def _test_group(self, user):
return any(user.is_in_group(pk=grp_id) for grp_id in self.edit_group)
def _test_club(self, user):
return any(c.can_be_edited_by(user) for c in self.edit_club)
def dispatch(self, request, *args, **kwargs):
if not (
request.user.is_root
or self._test_group(request.user)
or self._test_club(request.user)
):
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
class CounterTabsMixin(TabedViewMixin): class CounterTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
return self.object return self.object
@@ -89,45 +64,70 @@ class CounterTabsMixin(TabedViewMixin):
class CounterAdminTabsMixin(TabedViewMixin): class CounterAdminTabsMixin(TabedViewMixin):
tabs_title = _("Counter administration") tabs_title = _("Counter administration")
list_of_tabs = [
def get_list_of_tabs(self):
user = self.request.user
res = [
{ {
"url": reverse_lazy("counter:admin_list"), "url": reverse_lazy("counter:admin_list"),
"slug": "counters", "slug": "counters",
"name": _("Counters"), "name": _("Counters"),
}, }
]
if user.has_perm("counter.view_product"):
res.append(
{ {
"url": reverse_lazy("counter:product_list"), "url": reverse_lazy("counter:product_list"),
"slug": "products", "slug": "products",
"name": _("Products"), "name": _("Products"),
}, }
)
if user.has_perm("counter.view_productformula"):
res.append(
{ {
"url": reverse_lazy("counter:product_formula_list"), "url": reverse_lazy("counter:product_formula_list"),
"slug": "formulas", "slug": "formulas",
"name": _("Formulas"), "name": _("Formulas"),
}, }
)
if user.has_perm("counter.view_producttype"):
res.append(
{ {
"url": reverse_lazy("counter:product_type_list"), "url": reverse_lazy("counter:product_type_list"),
"slug": "product_types", "slug": "product_types",
"name": _("Product types"), "name": _("Product types"),
}, }
)
if user.has_perm("counter.view_returnableproduct"):
res.append(
{ {
"url": reverse_lazy("counter:returnable_list"), "url": reverse_lazy("counter:returnable_list"),
"slug": "returnable_products", "slug": "returnable_products",
"name": _("Returnable products"), "name": _("Returnable products"),
}, }
)
if user.has_perm("counter.view_cashregistersummary"):
res.append(
{ {
"url": reverse_lazy("counter:cash_summary_list"), "url": reverse_lazy("counter:cash_summary_list"),
"slug": "cash_summary", "slug": "cash_summary",
"name": _("Cash register summaries"), "name": _("Cash register summaries"),
}, }
)
if user.has_perm("counter.view_invoicecall"):
res.append(
{ {
"url": reverse_lazy("counter:invoices_call"), "url": reverse_lazy("counter:invoices_call"),
"slug": "invoices_call", "slug": "invoices_call",
"name": _("Invoices call"), "name": _("Invoices call"),
}, }
)
if user.has_perm("counter.view_eticket"):
res.append(
{ {
"url": reverse_lazy("counter:eticket_list"), "url": reverse_lazy("counter:eticket_list"),
"slug": "etickets", "slug": "etickets",
"name": _("Etickets"), "name": _("Etickets"),
}, }
] )
return res
+7 -5
View File
@@ -48,7 +48,7 @@ des scripts complets mais qui restent lisibles,
``` ```
Ok, c'est de la triche, on installe un package externe. Ok, c'est de la triche, on installe un package externe.
Mais bon, ça marche, et l'équivalent pur bash Mais bon, ça marche, et l'équivalent pur bash
serait un pur enfer. serait carrément plus moche.
=== "nu" === "nu"
@@ -59,18 +59,20 @@ des scripts complets mais qui restent lisibles,
Nombre de lignes total : Nombre de lignes total :
```nu ```nu
ls **/*.py | par-each { open $in.name | lines | length } | math sum ls **/*.py | insert linecount { get name | open | lines | length } | math sum
``` ```
Vous pouvez aussi exlure les lignes vides Vous pouvez aussi exlure les lignes vides
et les les lignes de commentaire : et les les lignes de commentaire :
```nu ```nu
ls **/*.py | ls **/*.py |
par-each { insert linecount {
open $in.name | get name |
open |
lines | lines |
each { str trim } | each { str trim } |
where { |l| ($l | str length) > 0 and not ($l | str starts-with "#") } | filter { |l| not ($l | str starts-with "#") } | # commentaires
filter { |l| ($l | str length) > 0 } | # lignes vides
length length
} | } |
math sum math sum
+9 -33
View File
@@ -18,8 +18,7 @@ il n'est pas possible de développer le site sur ce système d'exploitation.
Heureusement, il existe une alternative qui ne requiert pas de désinstaller votre Heureusement, il existe une alternative qui ne requiert pas de désinstaller votre
OS ni de mettre un dual boot sur votre ordinateur : `WSL`. OS ni de mettre un dual boot sur votre ordinateur : `WSL`.
- **Prérequis:** vous devez être sur Windows 10 version 2004 ou ultérieure (build 19041 & versions ultérieures) ou - **Prérequis:** vous devez être sur Windows 10 version 2004 ou ultérieure (build 19041 & versions ultérieures) ou Windows 11.
Windows 11.
- **Plus d'info:** [docs.microsoft.com](https://docs.microsoft.com/fr-fr/windows/wsl/install) - **Plus d'info:** [docs.microsoft.com](https://docs.microsoft.com/fr-fr/windows/wsl/install)
```shell ```shell
@@ -44,7 +43,7 @@ il suffit d'utiliser la commande suivante :
cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
``` ```
!!!success !!!note
À ce stade, si vous avez réussi votre installation de `WSL` ou bien qu'il À ce stade, si vous avez réussi votre installation de `WSL` ou bien qu'il
était déjà installé, vous pouvez effectuer la mise en place du projet en suivant était déjà installé, vous pouvez effectuer la mise en place du projet en suivant
@@ -102,10 +101,10 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
ln -s /usr/bin/valkey-server /usr/bin/redis-server ln -s /usr/bin/valkey-server /usr/bin/redis-server
``` ```
=== "macOS" === "macOS"
Pour installer les dépendances, il est fortement recommandé Pour installer les dépendances, il est fortement recommandé d'installer le gestionnaire de paquets `homebrew <https://brew.sh/index_fr>`_.
d'installer le gestionnaire de paquets `homebrew <https://brew.sh/index_fr>`_.
Il est également nécessaire d'avoir installé xcode Il est également nécessaire d'avoir installé xcode
```bash ```bash
@@ -117,15 +116,12 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
!!!note !!!note
Si vous rencontrez des erreurs lors de votre configuration, Si vous rencontrez des erreurs lors de votre configuration, n'hésitez pas à vérifier l'état de votre installation homebrew avec :code:`brew doctor`
n'hésitez pas à vérifier l'état de votre installation homebrew
avec :code:`brew doctor`
!!!note !!!note
Python ne fait pas parti des dépendances puisqu'il est automatiquement Python ne fait pas parti des dépendances puisqu'il est automatiquement
installé par uv. Il est cependant parfois nécessaire d'installer installé par uv. Il est cependant parfois nécessaire d'installer les headers Python nécessaire à la compilation de certains paquets.
les headers Python nécessaire à la compilation de certains paquets.
## Finaliser l'installation ## Finaliser l'installation
@@ -149,6 +145,7 @@ uv run ./manage.py install_xapian
de texte à l'écran. de texte à l'écran.
C'est normal, il ne faut pas avoir peur. C'est normal, il ne faut pas avoir peur.
La modification de la configuration passe par la modification de variables La modification de la configuration passe par la modification de variables
d'environnement. d'environnement.
Ces variables sont stockées dans un fichier `.env`. Ces variables sont stockées dans un fichier `.env`.
@@ -186,33 +183,12 @@ Il suffit ensuite d'utiliser cette commande :
uv run ./manage.py runserver uv run ./manage.py runserver
``` ```
!!!note
Le serveur est alors accessible à l'adresse Le serveur est alors accessible à l'adresse
[http://localhost:8000](http://localhost:8000) [http://localhost:8000](http://localhost:8000)
ou bien [http://127.0.0.1:8000/](http://127.0.0.1:8000/). ou bien [http://127.0.0.1:8000/](http://127.0.0.1:8000/).
Pour vous connecter, vous pouvez utiliser un des comptes utilisateur
créés durant l'installation :
| username | description |
|------------------|----------------------------------------------------------------------------|
| `root` | super-utilisateur<br/>il peut tout faire et tout voir |
| `subscriber` | simple cotisant |
| `old_subscriber` | ancien cotisant |
| `public` | non-cotisant |
| `krophil` | cotisant<br/>barman Foyer<br/>président du Troll Penché |
| `sli` | cotisant<br/>VP Troll |
| `skia` | cotisant<br/>barman MDE<br/>membre du bureau AE<br/>ancien membre du Troll |
| `comunity` | cotisant<br/>membre du bureau PdF<br/>admin communication |
| `counter` | cotisant<br/>admin comptoirs |
| `comptable` | cotisant<br/>admin comptabilité |
| `rbatsbak` | cotisant<br/>membre du Troll |
En plus de ces dernier, quelques centaines d'utilisateurs
supplémentaires sont générés procéduralement,
afin de rajouter un peu de volume de données.
Tous les utilisateurs ont le mot de passe `plop`.
!!!note !!!note
Le serveur de développement se charge de lancer redis Le serveur de développement se charge de lancer redis
+1 -1
View File
@@ -67,7 +67,7 @@
.fa-plus, .fa-plus,
.fa-minus { .fa-minus {
cursor: pointer; cursor: pointer;
background-color: var(--deepblue); background-color: #354a5f;
color: white; color: white;
border-radius: 50%; border-radius: 50%;
padding: 5px; padding: 5px;
+1 -1
View File
@@ -288,7 +288,7 @@ $min_col_width: 100px;
border: none; border: none;
color: black; color: black;
text-decoration: none; text-decoration: none;
background-color: var(--bg-white); background-color: $primary-neutral-light-color;
padding: 0.4em; padding: 0.4em;
margin: 0.1em; margin: 0.1em;
font-size: 1.18em; font-size: 1.18em;
+8 -9
View File
@@ -13,8 +13,7 @@
} }
.topic { .topic {
border: solid var(--darkened-deepblue) 1px; border: solid $primary-neutral-color 1px;
border-radius: 5px;
padding: 1px; padding: 1px;
margin: 1px; margin: 1px;
@@ -24,7 +23,7 @@
} }
a { a {
color: var(--text-black); color: $black-color;
} }
a:hover { a:hover {
@@ -57,7 +56,7 @@
} }
.forum { .forum {
background: var(--bg-white); background: $primary-neutral-light-color;
padding: 1px; padding: 1px;
margin: 1px; margin: 1px;
@@ -67,7 +66,7 @@
} }
a { a {
color: var(--text-black); color: $black-color;
} }
a:hover { a:hover {
text-decoration: underline; text-decoration: underline;
@@ -92,7 +91,7 @@
.category { .category {
margin-top: 5px; margin-top: 5px;
background: var(--deepblue); background: $secondary-color;
color: white; color: white;
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
.title { .title {
@@ -106,12 +105,12 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
background: var(--bg-off-white); background: $secondary-neutral-light-color;
border-radius: 5px; border-radius: 5px;
border: 1px var(--bg-lightgrey) solid; border: 1px darken($secondary-neutral-light-color, 10%) solid;
&:nth-child(odd) { &:nth-child(odd) {
background: var(--bg-white); background: $primary-neutral-light-color;
} }
.message-header { .message-header {
+2 -5
View File
@@ -346,16 +346,13 @@ class ForumTopicDetailView(CanViewMixin, DetailView):
return kwargs return kwargs
class ForumMessageView(SingleObjectMixin, UserPassesTestMixin, RedirectView): class ForumMessageView(SingleObjectMixin, RedirectView):
model = ForumMessage model = ForumMessage
pk_url_kwarg = "message_id" pk_url_kwarg = "message_id"
permanent = False permanent = False
def test_func(self) -> bool:
self.object = self.get_object()
return self.request.user.can_view(self.object)
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
self.object = self.get_object()
return self.object.get_url() return self.object.get_url()
+11 -13
View File
@@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-10-02 12:56+0200\n" "POT-Creation-Date: 2026-10-09 21:44+0200\n"
"PO-Revision-Date: 2016-07-18\n" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n" "Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@@ -236,7 +236,7 @@ msgstr "vous devez spécifier au moins un utilisateur ou une adresse email"
msgid "Begin date" msgid "Begin date"
msgstr "Date de début" msgstr "Date de début"
#: club/forms.py com/forms.py counter/forms.py subscription/forms.py #: club/forms.py com/forms.py counter/forms.py
msgid "End date" msgid "End date"
msgstr "Date de fin" msgstr "Date de fin"
@@ -1093,7 +1093,7 @@ msgstr "Prix d'achat"
msgid "Format: 16:9 | Resolution: 1920x1080" msgid "Format: 16:9 | Resolution: 1920x1080"
msgstr "Format : 16:9 | Résolution : 1920x1080" msgstr "Format : 16:9 | Résolution : 1920x1080"
#: com/forms.py subscription/forms.py #: com/forms.py
msgid "Start date" msgid "Start date"
msgstr "Date de début" msgstr "Date de début"
@@ -4102,7 +4102,6 @@ msgstr "Nouvelle formule"
#: counter/templates/counter/fragments/create_student_card.jinja #: counter/templates/counter/fragments/create_student_card.jinja
#: counter/templates/counter/invoices_call.jinja #: counter/templates/counter/invoices_call.jinja
#: sas/templates/sas/picture.jinja #: sas/templates/sas/picture.jinja
#: subscription/templates/subscription/stats.jinja
msgid "Go" msgid "Go"
msgstr "Valider" msgstr "Valider"
@@ -4237,9 +4236,12 @@ msgid "Remove price"
msgstr "Retirer le prix" msgstr "Retirer le prix"
#: counter/templates/counter/product_form.jinja #: counter/templates/counter/product_form.jinja
#, python-format msgid ""
msgid "Edit product %(name)s" "You can see product details. However, you cannot edit it, thus you won't be "
msgstr "Édition du produit %(name)s" "able to submit this form."
msgstr ""
"Vous pouvez voir ce produit. Cependant, vous ne pouvez pas l'éditer ; vous "
"ne serez donc pas en mesure de soumettre le formulaire."
#: counter/templates/counter/product_form.jinja #: counter/templates/counter/product_form.jinja
msgid "Creation date" msgid "Creation date"
@@ -5985,12 +5987,8 @@ msgid "Create another subscription"
msgstr "Créer une nouvelle cotisation" msgstr "Créer une nouvelle cotisation"
#: subscription/templates/subscription/stats.jinja #: subscription/templates/subscription/stats.jinja
msgid "Total subscriptions" msgid "All subscriptions"
msgstr "Cotisations totales" msgstr "Toutes les cotisations"
#: subscription/templates/subscription/stats.jinja
msgid "Subscriptions by type"
msgstr "Cotisations par type"
#: subscription/templates/subscription/subscription.jinja #: subscription/templates/subscription/subscription.jinja
msgid "Existing member" msgid "Existing member"
+6 -2
View File
@@ -23,6 +23,7 @@ $pedagogy-white-text: #f0f0f0;
overflow-wrap: break-word; overflow-wrap: break-word;
.closed td.title { .closed td.title {
color: lighten($black-color, 10%);
font-style: italic; font-style: italic;
} }
@@ -68,6 +69,9 @@ $pedagogy-white-text: #f0f0f0;
min-width: 300px; min-width: 300px;
} }
.info-container { .info-container {
// Darken the background color just enough to make this part
// stand out a little, while not being too perceptible
background: darken($white-color, 1%);
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
border-radius: 5px; border-radius: 5px;
@@ -154,9 +158,9 @@ $pedagogy-white-text: #f0f0f0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
background: var(--bg-off-white); background: $primary-neutral-light-color;
border-radius: 5px; border-radius: 5px;
border: 1px var(--bg-lightgrey) solid; border: 1px darken($secondary-neutral-light-color, 10%) solid;
&.reported { &.reported {
border: #fc8181 1px solid; border: #fc8181 1px solid;
+2 -2
View File
@@ -27,7 +27,7 @@ main {
font-size: 1.2em; font-size: 1.2em;
line-height: 1.2em; line-height: 1.2em;
color: black; color: black;
background-color: var(--bg-white); background-color: $primary-neutral-light-color;
border-radius: 5px; border-radius: 5px;
font-weight: bold; font-weight: bold;
@@ -36,7 +36,7 @@ main {
} }
&:disabled { &:disabled {
background-color: var(--bg-white); background-color: $primary-neutral-light-color;
color: #d4d4d4; color: #d4d4d4;
} }
} }
+1 -1
View File
@@ -239,7 +239,7 @@
>.tools { >.tools {
flex: 1; flex: 1;
.btn { .btn {
background-color: var(--bg-white); background-color: $primary-neutral-light-color;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@@ -6,7 +6,7 @@
display: block; display: block;
margin: 2em auto; margin: 2em auto;
.header { .header {
background-color: var(--bg-white); background-color: $white-color;
font-weight: bold; font-weight: bold;
box-shadow: none; box-shadow: none;
width: calc(100% - var(--hour-side-width) - 10px); width: calc(100% - var(--hour-side-width) - 10px);