issue/19 (#20)

!19

Co-authored-by: dbroqua <contact@darkou.fr>
Reviewed-on: dbroqua/MyMusicLibrary#20
Co-authored-by: Damien Broqua <dbroqua@noreply.localhost>
Co-committed-by: Damien Broqua <dbroqua@noreply.localhost>
This commit is contained in:
Damien Broqua 2022-03-01 16:09:46 +01:00
parent 18d4970ebd
commit a0f9ab1f45
35 changed files with 973 additions and 366 deletions

Binary file not shown.

View file

@ -24,6 +24,10 @@
<glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" /> <glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
<glyph glyph-name="sun" unicode="&#xf185;" d="M821 350q0 65-25 125t-69 102-102 69-125 25-125-25-102-69-69-102-25-125 25-125 69-102 102-69 125-25 125 25 102 69 69 102 25 125z m154-155q-2-8-11-11l-163-53v-171q0-9-7-15-8-5-16-2l-163 53-100-139q-6-7-15-7t-14 7l-101 139-163-53q-8-3-16 2-7 6-7 15v171l-163 53q-9 3-11 11-3 10 2 17l100 138-100 138q-5 8-2 17 2 8 11 11l163 53v171q0 9 7 15 8 5 16 2l163-53 101 139q5 6 14 6t15-6l100-139 163 53q8 3 16-2 7-6 7-15v-171l163-53q9-3 11-11 3-9-2-17l-100-138 100-138q5-7 2-17z" horiz-adv-x="1000" />
<glyph glyph-name="moon" unicode="&#xf186;" d="M704 123q-30-5-61-5-102 0-188 50t-137 137-50 188q0 107 58 199-112-33-183-128t-72-214q0-72 29-139t76-113 114-77 139-28q80 0 152 34t123 96z m114 47q-53-113-159-181t-230-68q-87 0-167 34t-136 92-92 137-34 166q0 85 32 163t87 135 132 92 161 38q25 1 34-22 11-23-8-40-48-43-73-101t-26-122q0-83 41-152t111-111 152-41q66 0 127 29 23 10 40-7 8-8 10-19t-2-22z" horiz-adv-x="857.1" />
<glyph glyph-name="trash" unicode="&#xf1f8;" d="M286 82v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m143 0v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m142 0v393q0 8-5 13t-12 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q7 0 12 5t5 13z m-303 554h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" /> <glyph glyph-name="trash" unicode="&#xf1f8;" d="M286 82v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m143 0v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m142 0v393q0 8-5 13t-12 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q7 0 12 5t5 13z m-303 554h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
<glyph glyph-name="blind" unicode="&#xf29d;" d="M204 677q-35 0-61 25t-26 62q0 35 26 61t61 25 61-25 26-61q0-37-26-62t-61-25z m308-359q0-28-17-37t-35-4-27 19l-205 244q-4 7-8 9t-6 1l-1-2q-4-4 2-12l68-77 1-198-90-255q-38-107-52-130-8-15-15-18-28-15-58-1-16 7-23 24t-5 32q1 9 110 345l3 232-48-91 20-124q2-14-1-24t-8-15-10-9-10-4l-4-1q-10-2-19 1t-13 9-8 13-4 10-2 6l-25 167 118 212q12 19 63 19 41 0 59-22l237-291q4-3 8-9l1-2 0-1q4-7 4-16z m-225-83q24-64 49-126t39-94l13-31q21-51 24-69 6-39-20-54-20-13-37-9t-28 12-17 19h0q-4 9-5 14l-69 196z m460-331q17-27 17-32 0-3-2-4-5-2-8 1t-8 14-9 17q-64 96-236 369 1 0 4 1t3 2l2 1q6 5 6 10z" horiz-adv-x="785.7" /> <glyph glyph-name="blind" unicode="&#xf29d;" d="M204 677q-35 0-61 25t-26 62q0 35 26 61t61 25 61-25 26-61q0-37-26-62t-61-25z m308-359q0-28-17-37t-35-4-27 19l-205 244q-4 7-8 9t-6 1l-1-2q-4-4 2-12l68-77 1-198-90-255q-38-107-52-130-8-15-15-18-28-15-58-1-16 7-23 24t-5 32q1 9 110 345l3 232-48-91 20-124q2-14-1-24t-8-15-10-9-10-4l-4-1q-10-2-19 1t-13 9-8 13-4 10-2 6l-25 167 118 212q12 19 63 19 41 0 59-22l237-291q4-3 8-9l1-2 0-1q4-7 4-16z m-225-83q24-64 49-126t39-94l13-31q21-51 24-69 6-39-20-54-20-13-37-9t-28 12-17 19h0q-4 9-5 14l-69 196z m460-331q17-27 17-32 0-3-2-4-5-2-8 1t-8 14-9 17q-64 96-236 369 1 0 4 1t3 2l2 1q6 5 6 10z" horiz-adv-x="785.7" />

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

130
public/js/main.js Normal file
View file

@ -0,0 +1,130 @@
/**
* Fonction permettant d'afficher un message dans un toastr
* @param {String} message
*/
function showToastr(message) {
let x = document.getElementById("toastr");
if ( message ) {
x.getElementsByTagName("SPAN")[0].innerHTML = message;
}
x.className = `${x.className} show`;
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
};
/**
* Fonction permettant de masquer le toastr
*/
function hideToastr() {
let x = document.getElementById("toastr");
x.className = x.className.replace("show", "");
x.getElementsByTagName("SPAN")[0].innerHTML = "";
}
/**
* Fonction permettant de récupérer la valeur d'un cookie
* @param {String} cname
* @param {String} defaultValue
*
* @return {String}
*/
function getCookie(cname, defaultValue = 'false') {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i < ca.length; i+=1) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return defaultValue;
}
/**
* Fonction permettant de créer un cookie
* @param {String} cname
* @param {String} cvalue
* @param {Number} exdays
*/
function setCookie(cname, cvalue, exdays = 30) {
const d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
let expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
/**
* Fonction de ()charger le thème accessible
* @param {String} value
*/
function setAriaTheme(value) {
let body = document.body;
if ( value === 'true' ) {
let classesString = body.className || "";
if (classesString.indexOf("is-accessible") === -1) {
body.classList.add("is-accessible");
}
} else {
body.classList.remove("is-accessible");
}
}
/**
* Fonction de ()charger le thème accessible
*/
function switchAriaTheme() {
let body = document.body;
body.classList.toggle("is-accessible");
setCookie('ariatheme', body.classList.contains("is-accessible"));
}
/**
* Fonction permettant de switcher de thème clair/sombre
* @param {Object} e
*/
function switchTheme(e) {
const theme = e.target.checked ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', theme);
setCookie('theme', theme);
}
/**
* Ensemble d'actions effectuées au chargement de la page
*/
document.addEventListener('DOMContentLoaded', () => {
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
if ($navbarBurgers.length > 0) {
$navbarBurgers.forEach( el => {
el.addEventListener('click', () => {
const target = el.dataset.target;
const $target = document.getElementById(target);
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
}
const switchAriaThemeBtn = document.querySelector("#switchAriaTheme");
switchAriaThemeBtn.addEventListener("click", switchAriaTheme);
setAriaTheme(getCookie('ariatheme'));
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
toggleSwitch.addEventListener('change', switchTheme, false);
let currentThemeIsDark = getCookie('theme');
if ( currentThemeIsDark === 'false' && window.matchMedia ) {
currentThemeIsDark = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
console.log('currentThemeIsDark:', currentThemeIsDark);
switchTheme({target: {checked: currentThemeIsDark === 'dark'}});
toggleSwitch.checked = currentThemeIsDark === 'dark';
});

26
sass/box.scss Normal file
View file

@ -0,0 +1,26 @@
.box {
background-color: var(--box-bg-color);
border-radius: 6px;
box-shadow: var(--box-shadow-color) 0px 3px 6px 0px;
color: var(--font-color);
display: block;
padding: 1.25rem;
width: calc(100% - 2rem);
margin: auto;
@include transition() {}
@include respond-to("small-up") {
width: 65%;
}
@include respond-to("medium-up") {
width: 35%;
}
h1 {
margin-top: 0;
}
button {
margin-top: 2rem;
}
}

View file

@ -7,43 +7,57 @@
padding-top: calc(0.5em - 1px); padding-top: calc(0.5em - 1px);
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
border-width: 1px; border: 1px solid transparent;
margin-bottom: .5rem; margin-bottom: .5rem;
background-color: #fff; background-color: $nord9;
border-color: #dbdbdb;
border-radius: 0.375rem; border-radius: 0.375rem;
color: $button-font-color;
@include transition() {}
&.is-danger { &:hover {
background-color: #d73455; background-color: darken($nord9, $hoverAmount);
border-color: transparent;
color: #fff;
&:hover {
background-color: #d70933;
border-color: transparent;
color: #fff;
}
} }
&.is-link { &.is-danger {
background-color: #485fc7; background-color: $danger-color;
border-color: transparent; color: $button-alternate-color;
color: #fff;
&:hover { &:hover {
background-color: #3e56c4; background-color: $danger-color-hl;
border-color: transparent;
color: #fff;
} }
} }
&.is-primary { &.is-primary {
background-color: #2d7c58; background-color: $primary-color;
border-color: transparent;
color: #fff;
&:hover { &:hover {
background-color: #267953; background-color: $primary-color-hl;
}
}
&.is-warning {
background-color: $warning-color;
&:hover {
background-color: $warning-color-hl;
}
}
&.is-success {
background-color: $success-color;
&:hover {
background-color: $success-color-hl;
}
}
&.is-link {
background-color: transparent;
border-color: $nord9;
color: $nord9;
&:hover {
border-color: darken($nord9, $hoverAmount);
} }
} }
} }

74
sass/colors.scss Normal file
View file

@ -0,0 +1,74 @@
$hoverAmount: 10%;
$white: #ffffff;
$darken-white: #F8F9FB;
/* Couleurs du thème Nord (https://www.nordtheme.com/) */
$nord0: #2e3440;
$nord1: #3b4252;
$nord2: #434c5e;
$nord3: #4C566A;
$nord4: #d8dee9;
$nord5: #e5e9f0;
$nord6: #eceff4;
$nord7: #8fbcbb;
$nord8: #88c0d0;
$nord9: #81a1c1;
$nord10: #5e81ac;
$nord11: #d08770;
$nord12: #bf616a;
$nord13: #ebcb8b;
$nord14: #a3be8c;
$nord15: #b48ead;
$primary-color: $nord8;
$danger-color: $nord11;
$warning-color: $nord13;
$success-color: $nord14;
$primary-color-hl: darken($primary-color, $hoverAmount);
$danger-color-hl: darken($danger-color, $hoverAmount);
$warning-color-hl: darken($warning-color, $hoverAmount);
$success-color-hl: darken($success-color, $hoverAmount);
$button-font-color: $nord1;
$button-alternate-color: #01103C;
$pagination-border-color: $nord3;
$pagination-hover-color: rgb(115, 151, 186);
:root {
--default-color: #{$white};
--bg-color: #{darken($white, 5%)};
--font-color: #{$nord3};
--footer-color: #{$darken-white};
--link-color: #{$nord1};
--input-font-color: #{$nord3};
--input-color: #{$white};
--input-active-color: #{$nord5};
--navbar-color: #{darken($white, 5%)};
--box-bg-color: #F8F9FB;
--box-shadow-color: #{rgba($nord4, 0.35)};
--border-color: #{$nord4};
}
[data-theme="dark"] {
--default-color: #{$nord3};
--bg-color: #{lighten($nord0, 2%)};
--font-color: #{$nord6};
--footer-color: #{$nord1};
--link-color: #{$nord4};
--input-font-color: #{$nord6};
--input-color: #{$nord0};
--input-active-color: #{$nord3};
--navbar-color: #{$nord0};
--box-bg-color: #{$nord1};
--box-shadow-color: #{rgba($nord4, 0.2)};
--border-color: #{$nord1};
}

View file

@ -1,28 +0,0 @@
.connexion,
.inscription {
background-color: #fff;
border-radius: 6px;
box-shadow: 0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);
color: #4a4a4a;
display: block;
padding: 1.25rem;
width: calc(100% - 2rem);
margin: auto;
@include respond-to("small-up") {
width: 65%;
}
@include respond-to("medium-up") {
width: 35%;
}
button {
background-color: #485fc7;
border-color: transparent;
color: #fff;
&:hover {
background-color: #3e56c4;
}
}
}

View file

@ -1,10 +1,4 @@
.error { .error {
min-height: calc(100vh - 3.25rem - 100px); min-height: calc(100vh - 3.25rem - 100px);
padding-top: 4rem; padding-top: 4rem;
pre {
padding: 0.75rem;
border: 1px dotted #cecccc;
background: #f9f9f9;
}
} }

View file

@ -1,10 +1,10 @@
.flash { .flash {
background-color: #d73455; background-color: $danger-color;
border-radius: 6px; border-radius: 6px;
box-shadow: 0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02); box-shadow: var(--box-shadow-color) 0px 3px 6px 0px;
color: #fff; color: $button-alternate-color;
display: block; display: block;
padding: 1.25rem; padding: 1.25rem;
width: calc(100% - 6rem); width: calc(100% - 6rem);
margin: 2rem auto; margin: 2rem auto;

File diff suppressed because one or more lines are too long

View file

@ -26,17 +26,17 @@
input, input,
textarea, textarea,
select { select {
border-radius: 0.375rem; border-radius: 4px;
box-shadow: inset 0 .0625em .125em rgba(10,10,10,.05);
max-width: 100%; max-width: 100%;
width: 100%; width: 100%;
background-color: #fff; background-color: var(--input-color);
border: 1px solid #dbdbdb !important; border: 1px solid transparent !important;
color: #363636; color: var(--input-font-color);
@include transition() {}
&:focus-visible { &:focus-visible {
border: 1px solid #b9b9b9 !important;
outline: unset; outline: unset;
border-color: var(--input-active-color) !important;
} }
} }
@ -48,4 +48,78 @@
background-size: 1.2rem; background-size: 1.2rem;
padding-right: 2.4rem; padding-right: 2.4rem;
} }
} }
.theme-switch-wrapper {
display: flex;
align-items: center;
em {
margin-left: 10px;
font-size: 1rem;
}
}
.theme-switch {
display: inline-block;
height: 34px;
position: relative;
width: 60px;
}
.theme-switch input {
display:none;
}
.slider {
background-color: #ccc;
bottom: 0;
cursor: pointer;
left: 0;
position: absolute;
right: 0;
top: 0;
transition: .4s;
@include transition() {}
}
.slider:before {
background-color: #fff;
bottom: 4px;
content: '\f185';
height: 26px;
left: 4px;
position: absolute;
transition: .4s;
width: 26px;
padding: 0;
font-family: "icon";
font-style: normal;
font-weight: normal;
display: inline-block;
text-decoration: inherit;
text-align: center;
font-variant: normal;
text-transform: none;
}
input:checked + .slider {
background-color: $primary-color;
@include transition() {}
}
input:checked + .slider:before {
transform: translateX(26px);
content: '\f186';
background-color: var(--input-active-color);
@include transition() {}
}
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}

View file

@ -2,31 +2,62 @@ html {
min-height: 100vh; min-height: 100vh;
body { body {
background-color: var(--bg-color);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding-top: 3.5rem; padding-top: 3.5rem;
font-family: 'open_sansregular'; font-family: 'open_sansregular';
font-weight: 400; font-weight: 400;
min-height: 100vh; min-height: 100vh;
color: var(--font-color);
@include transition() {}
&.is-accessible { &.is-accessible {
font-family: 'lucioleregular'; font-family: 'lucioleregular';
.text-justify {
text-align: left;
}
} }
footer.footer { footer.footer {
margin-top: auto; margin-top: auto;
padding: 2rem 0.7rem 1.5rem; padding: 2rem 0.7rem 1.5rem;
background-color: #fafafa; background-color: var(--footer-color);
@include transition() {}
} }
a { a {
color: #485fc7; color: var(--link-color);
cursor: pointer; cursor: pointer;
@include transition() {}
&:hover {
color: var(--font-color);
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: var(--font-color);
} }
h1 { h1 {
margin-top: 2rem; margin-top: 2rem;
} }
pre {
font-family: 'fira_codelight';
margin: 0.75rem 0;
padding: 0.75rem;
border-left: 2px solid $nord10;
background: var(--box-bg-color);
color: var(--font-color);
}
} }
} }

View file

@ -1,4 +1,5 @@
.home { .home {
margin-bottom: 0.75rem;
.header { .header {
@include respond-to("small-up") { @include respond-to("small-up") {
height: 30vh; height: 30vh;

View file

@ -41,6 +41,8 @@
.icon-eye:before { content: '\e806'; } /* '' */ .icon-eye:before { content: '\e806'; } /* '' */
.icon-spin:before { content: '\e839'; } /* '' */ .icon-spin:before { content: '\e839'; } /* '' */
.icon-link-ext:before { content: '\f08e'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */
.icon-sun:before { content: '\f185'; } /* '' */
.icon-moon:before { content: '\f186'; } /* '' */
.icon-trash:before { content: '\f1f8'; } /* '' */ .icon-trash:before { content: '\f1f8'; } /* '' */
.icon-blind:before { content: '\f29d'; } /* '' */ .icon-blind:before { content: '\f29d'; } /* '' */

View file

@ -26,21 +26,21 @@
// SPÉCIFIQUE AU SITE // SPÉCIFIQUE AU SITE
@import './fonts'; @import './fonts';
@import './colors';
@import './mixin';
@import './global'; @import './global';
@import './navbar'; @import './navbar';
@import './forms'; @import './forms';
@import './button.scss'; @import './button.scss';
@import './table';
@import './modal'; @import './modal';
@import './toast'; @import './toast';
@import './flash'; @import './flash';
@import './pagination'; @import './pagination';
@import './icons'; @import './icons';
@import './list'; @import './list';
@import './box';
@import './error'; @import './error';
@import './home'; @import './home';
@import './connexion';
@import './ajouter-un-album'; @import './ajouter-un-album';
@import './ma-collection'; @import './ma-collection';
@import './nous-contacter';

View file

@ -1,28 +1,33 @@
.list { .list {
margin-top: 2rem; margin: 2rem 0;
.item{ .item{
padding: 0.5rem 0.75rem; padding: 0.5rem 0.75rem;
border-bottom: 1px solid #dbdbdb; border-bottom: 1px solid var(--border-color);
@include transition() {}
@include respond-to("medium") { @include respond-to("medium") {
&:nth-child(2n) { &:nth-child(2n) {
background-color: #fafafa; background-color: var(--default-color);
} }
} }
@include respond-to("medium-up") { @include respond-to("medium-up") {
border-left: 1px solid #dbdbdb; border-left: 1px solid var(--border-color);
&:first-child, &:first-child,
&:nth-child(2) { &:nth-child(2) {
border-top: 1px solid #dbdbdb; border-top: 1px solid var(--border-color);
} }
&:nth-child(2n), &:nth-child(2n),
&:last-child { &:last-child {
border-right: 1px solid #dbdbdb; border-right: 1px solid var(--border-color);
margin-right: -1px; margin-right: -1px;
} }
&:hover {
background-color: var(--default-color);
}
} }
.title { .title {
@ -35,7 +40,7 @@
} }
img { img {
border: 2px solid #4a4a4a; border: 2px solid var(--font-color);
max-width: 90%; max-width: 90%;
} }
} }

View file

@ -27,16 +27,17 @@
.title { .title {
.icon-trash { .icon-trash {
cursor: pointer; cursor: pointer;
color: #d73455; color: $danger-color;
@include transition() {}
&:hover { &:hover {
color: #d70933; color: $danger-color-hl;
} }
} }
} }
} }
.total { .total {
margin: 1rem 0; margin: 0.75rem 0;
} }
} }

4
sass/mixin.scss Normal file
View file

@ -0,0 +1,4 @@
@mixin transition() {
transition: background-color 200ms ease-in 0s, border-color 200ms ease-in 0s, box-shadow 200ms ease-in 0s, color 200ms ease-in 0s;
@content;
}

View file

@ -43,25 +43,25 @@
width: 1200; width: 1200;
} }
header, header,
footer { footer {
align-items: center; align-items: center;
background-color: #f5f5f5; background-color: var(--navbar-color);
display: flex; display: flex;
flex-shrink: 0; flex-shrink: 0;
justify-content: flex-start; justify-content: flex-start;
padding: 0.75rem; padding: 0.75rem;
position: relative; position: relative;
@include transition() {}
} }
header { header {
border-bottom: 1px solid #dbdbdb; border-bottom: 1px solid var(--border-color);
border-top-left-radius: 6px; border-top-left-radius: 6px;
border-top-right-radius: 6px; border-top-right-radius: 6px;
justify-content: space-between; justify-content: space-between;
font-size: 1.5rem; font-size: 1.5rem;
@include transition() {}
button { button {
user-select: none; user-select: none;
@ -85,7 +85,7 @@
&::before, &::before,
&::after { &::after {
background-color: #fff; background-color: var(--default-color);
content: ""; content: "";
display: block; display: block;
left: 50%; left: 50%;
@ -105,16 +105,17 @@
} }
} }
section { section {
background-color: #fff; background-color: var(--default-color);
flex-grow: 1; flex-grow: 1;
flex-shrink: 1; flex-shrink: 1;
overflow: auto; overflow: auto;
padding: 20px; padding: 20px;
@include transition() {}
} }
footer { footer {
border-bottom-left-radius: 6px; border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px; border-bottom-right-radius: 6px;
border-top: 1px solid #dbdbdb; border-top: 1px solid var(--border-color);
.button:not(:last-child) { .button:not(:last-child) {
margin-right: .5em; margin-right: .5em;

View file

@ -1,12 +1,14 @@
.navbar { .navbar {
min-height: 3.25rem; min-height: 3.25rem;
background-color: #f5f5f5; background-color: var(--navbar-color);
box-shadow: rgba(216, 222, 233, 0.15) 0px 5px 10px 0px;
color: rgba(0,0,0,.7); color: rgba(0,0,0,.7);
position: fixed; position: fixed;
z-index: 30; z-index: 30;
top: 0; top: 0;
right: 0; right: 0;
left: 0; left: 0;
@include transition() {}
@include respond-to("medium-up") { @include respond-to("medium-up") {
min-height: 3.25rem; min-height: 3.25rem;
@ -22,18 +24,19 @@
.navbar-item { .navbar-item {
align-items: center; align-items: center;
display: flex; display: flex;
img { img {
max-height: 1.75rem; max-height: 1.75rem;
} }
span { span {
word-break: break-word; word-break: break-word;
color: #363636; color: var(--font-color);
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
line-height: 1.125; line-height: 1.125;
margin-left: .5rem !important; margin-left: .5rem !important;
@include transition() {}
} }
} }
} }
@ -101,8 +104,9 @@
position: relative; position: relative;
flex-grow: 0; flex-grow: 0;
flex-shrink: 0; flex-shrink: 0;
color: #4a4a4a; color: var(--font-color);
display: block; display: block;
@include transition() {}
&.has-dropdown { &.has-dropdown {
padding: 0; padding: 0;
@ -113,10 +117,10 @@
color: rgba(0,0,0,.7); color: rgba(0,0,0,.7);
.navbar-dropdown { .navbar-dropdown {
background-color: #fff; background-color: var(--default-color);
border-bottom-left-radius: 6px; border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px; border-bottom-right-radius: 6px;
border-top: 2px solid #dbdbdb; border-top: 2px solid var(--default-hl-color);
box-shadow: 0 8px 8px rgba(10,10,10,.1); box-shadow: 0 8px 8px rgba(10,10,10,.1);
display: none; display: none;
font-size: .875rem; font-size: .875rem;
@ -129,7 +133,7 @@
&:hover { &:hover {
.navbar-link { .navbar-link {
background-color: #e8e8e8; background-color: var(--default-hl-color);
color: rgba(0,0,0,.7); color: rgba(0,0,0,.7);
} }
@ -147,13 +151,14 @@
} }
.navbar-link { .navbar-link {
color: #4a4a4a; color: var(--font-color);
display: block; display: block;
line-height: 1.5; line-height: 1.5;
padding: .5rem .75rem; padding: .5rem .75rem;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
padding-right: 2.5em; padding-right: 2.5em;
@include transition() {}
@include respond-to("medium-up") { @include respond-to("medium-up") {
display: flex; display: flex;
@ -182,7 +187,7 @@
transform: rotate(-45deg); transform: rotate(-45deg);
transform-origin: center; transform-origin: center;
width: .625em; width: .625em;
border-color: #485fc7; border-color: var(--secondary-color);
margin-top: -0.375em; margin-top: -0.375em;
right: 1.125em; right: 1.125em;
@ -194,9 +199,10 @@
.navbar-menu { .navbar-menu {
display: none; display: none;
background-color: #fff; background-color: var(--default-color);
box-shadow: 0 8px 16px rgba(10,10,10,.1); box-shadow: 0 8px 16px rgba(10,10,10,.1);
padding: .5rem 0; padding: .5rem 0;
@include transition() {}
@include respond-to("medium") { @include respond-to("medium") {
max-height: calc(100vh - 3.25rem); max-height: calc(100vh - 3.25rem);
@ -253,10 +259,10 @@
} }
@include respond-to("medium-up") { @include respond-to("medium-up") {
background-color: #fff; background-color: var(--default-color);
border-bottom-left-radius: 6px; border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px; border-bottom-right-radius: 6px;
border-top: 2px solid #dbdbdb; border-top: 2px solid var(--default-hl-color);
box-shadow: 0 8px 8px rgba(10,10,10,.1); box-shadow: 0 8px 8px rgba(10,10,10,.1);
display: none; display: none;
font-size: .875rem; font-size: .875rem;
@ -297,4 +303,11 @@
margin-bottom: -0.5rem; margin-bottom: -0.5rem;
} }
} }
}
[data-theme="dark"] {
.navbar {
box-shadow: none;
}
} }

View file

@ -1,15 +0,0 @@
.nous-contacter {
width: calc(100% - 2rem);
margin: 2rem auto;
@include respond-to("small-up") {
width: 55%;
}
@include respond-to("medium-up") {
width: 35%;
}
button {
margin-top: 2rem;
}
}

View file

@ -4,73 +4,8 @@
display: flex; display: flex;
text-align: center; text-align: center;
justify-content: space-between; justify-content: space-between;
margin: 1rem 0; margin: 0.75rem 0;
.pagination-previous,
.pagination-next,
.pagination-link {
align-items: center;
border: 1px solid transparent;
border-radius: .375em;
box-shadow: none;
display: inline-flex;
font-size: 1rem;
height: 2.5em;
justify-content: flex-start;
line-height: 1.5;
padding-bottom: calc(.5em - 1px);
padding-left: calc(.75em - 1px);
padding-right: calc(.75em - 1px);
padding-top: calc(.5em - 1px);
position: relative;
vertical-align: top;
text-decoration: none;
&:hover {
border-color: #b5b5b5;
color: #363636;
}
&.is-disabled {
background-color: #dbdbdb;
border-color: #dbdbdb;
box-shadow: none;
color: #7a7a7a;
opacity: .5;
}
}
.pagination-previous,
.pagination-next,
.pagination-link {
user-select: none;
text-align: center;
font-size: 1em;
justify-content: center;
margin: .25rem;
border-color: #dbdbdb;
color: #363636;
min-width: 2.5em;
padding-left: .75em;
padding-right: .75em;
white-space: nowrap;
margin-bottom: 0;
margin-top: 0;
}
.pagination-previous {
order: 2;
}
.pagination-next {
order: 3;
}
.pagination-link {
&.is-current {
background-color: #485fc7;
border-color: #485fc7;
color: #fff;
}
}
.pagination-list { .pagination-list {
align-items: center; align-items: center;
@ -79,7 +14,56 @@
flex-wrap: wrap; flex-wrap: wrap;
flex-grow: 1; flex-grow: 1;
flex-shrink: 1; flex-shrink: 1;
justify-content: flex-start; justify-content: flex-end;
order: 1;
@include respond-to("small") {
justify-content: center;
}
.pagination-link {
align-items: center;
border: 1px solid transparent;
border-radius: .375em;
box-shadow: none;
display: inline-flex;
font-size: 1rem;
height: 2.5em;
justify-content: flex-start;
line-height: 1.5;
padding: calc(.5em - 1px) calc(.75em - 1px);
position: relative;
vertical-align: top;
text-decoration: none;
user-select: none;
text-align: center;
font-size: 1em;
justify-content: center;
margin: .25rem;
border-color: $pagination-border-color;
color: var(--font-color);
min-width: 2.5em;
white-space: nowrap;
@include transition() {}
&:hover {
border-color: $pagination-hover-color;
color: $pagination-hover-color;
}
&.is-disabled {
background-color: var(--default-hl-color);
border-color: var(--default-hl-color);
box-shadow: none;
color: var(--disabled-color);
opacity: .5;
}
&.is-current {
background-color: $primary-color;
border-color: $primary-color;
color: $button-font-color;
}
}
} }
} }

View file

@ -1,24 +0,0 @@
table {
color: #363636;
th, td {
padding: .5em .75em;
border-bottom: 1px solid #dbdbdb;
}
th {
border-bottom-width: 2px;
}
tr:nth-child(2n) {
background-color: #fafafa;
}
tbody {
tr {
&:hover {
background-color: #f5f5f5;
}
}
}
}

View file

@ -9,8 +9,9 @@
font-size: 17px; font-size: 17px;
padding: 1.25rem 2.5rem 1.25rem 1.5rem; padding: 1.25rem 2.5rem 1.25rem 1.5rem;
background-color: #d73455; background-color: $danger-color;
color: #fff; color: $button-alternate-color;
border-radius: 6px;
&.show { &.show {
visibility: visible; visibility: visible;
@ -43,7 +44,7 @@
&::before, &::before,
&::after { &::after {
background-color: #fff; background-color: var(--default-color);
content: ""; content: "";
display: block; display: block;
left: 50%; left: 50%;

View file

@ -117,6 +117,16 @@ router.route("/nous-contacter").get(async (req, res, next) => {
} }
}); });
router.route("/composants").get(async (req, res, next) => {
try {
const page = new Pages(req, "composants");
render(res, page);
} catch (err) {
next(err);
}
});
router.route("/se-deconnecter").get((req, res) => { router.route("/se-deconnecter").get((req, res) => {
req.logout(); req.logout();
req.session.destroy(() => { req.session.destroy(() => {

View file

@ -1,9 +1,9 @@
<!doctype html> <!doctype html>
<html lang="fr"> <html lang="fr" data-theme="light">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title><% if (page.title) { %><%= page.title %> <% } else { %> DarKou - My Music Library <% } %></title> <title><% if (page.title) { %><%= page.title %> <% } else { %> DarKou - My Music Library <% } %></title>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
@ -13,123 +13,12 @@
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c"> <meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<link href="/css/main.css" rel="stylesheet" /> <link href="/css/main.css" rel="stylesheet" />
<script src="/libs/axios/axios.min.js"></script> <script src="/libs/axios/axios.min.js"></script>
<script src="/libs/vue/vue.global.prod.js"></script> <script src="/libs/vue/vue.global.prod.js"></script>
<script src="/js/main.js"></script>
<script>
/**
* Fonction permettant d'afficher un message dans un toastr
* @param {String} message
*/
function showToastr(message) {
let x = document.getElementById("toastr");
if ( message ) {
x.getElementsByTagName("SPAN")[0].innerHTML = message;
}
x.className = `${x.className} show`;
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
};
/**
* Fonction permettant de masquer le toastr
*/
function hideToastr() {
let x = document.getElementById("toastr");
x.className = x.className.replace("show", "");
x.getElementsByTagName("SPAN")[0].innerHTML = "";
}
/**
* Fonction permettant de récupérer la valeur d'un cookie
* @param {String} cname
* @param {String} defaultValue
*
* @return {String}
*/
function getCookie(cname, defaultValue = 'false') {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i < ca.length; i+=1) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return defaultValue;
}
/**
* Fonction permettant de créer un cookie
* @param {String} cname
* @param {String} cvalue
* @param {Number} exdays
*/
function setCookie(cname, cvalue, exdays = 30) {
const d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
let expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
/**
* Fonction de (dé)charger le thème accessible
* @param {String} value
*/
function setAriaTheme(value) {
let body = document.body;
if ( value === 'true' ) {
let classesString = body.className || "";
if (classesString.indexOf("is-accessible") === -1) {
body.classList.add("is-accessible");
}
} else {
body.classList.remove("is-accessible");
}
}
/**
* Fonction de (dé)charger le thème accessible
*/
function switchAriaTheme() {
let body = document.body;
body.classList.toggle("is-accessible");
setCookie('ariatheme', body.classList.contains("is-accessible"));
}
/**
* Ensemble d'actions effectuées au chargement de la page
*/
document.addEventListener('DOMContentLoaded', () => {
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
if ($navbarBurgers.length > 0) {
$navbarBurgers.forEach( el => {
el.addEventListener('click', () => {
const target = el.dataset.target;
const $target = document.getElementById(target);
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
}
const switchAriaThemeBtn = document.querySelector("#switchAriaTheme");
switchAriaThemeBtn.addEventListener("click", switchAriaTheme);
setAriaTheme(getCookie('ariatheme'));
});
</script>
</head> </head>
<body> <body>
<nav class="navbar" aria-label="Navigation principale"> <nav class="navbar" aria-label="Navigation principale">
@ -138,20 +27,20 @@
<img src="/img/logo.png" alt="Logo My Music Library"> <img src="/img/logo.png" alt="Logo My Music Library">
<span>My Music Library</span> <span>My Music Library</span>
</a> </a>
<a role="button" class="navbar-burger" aria-label="Afficher le menu" aria-expanded="false" data-target="navbar"> <a role="button" class="navbar-burger" aria-label="Afficher le menu" aria-expanded="false" data-target="navbar">
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
</a> </a>
</div> </div>
<div id="navbar" class="navbar-menu"> <div id="navbar" class="navbar-menu">
<% if ( user ) { %> <% if ( user ) { %>
<div class="navbar-start"> <div class="navbar-start">
<div class="navbar-item"> <div class="navbar-item">
<div class="buttons"> <div class="buttons">
<a class="button is-link" href="/ajouter-un-album"> <a class="button is-primary" href="/ajouter-un-album">
<i class="icon-plus"></i> <i class="icon-plus"></i>
<span> <span>
Ajouter un album Ajouter un album
@ -161,7 +50,7 @@
</div> </div>
</div> </div>
<% } %> <% } %>
<div class="navbar-end"> <div class="navbar-end">
<a class="navbar-item" href="/nous-contacter"> <a class="navbar-item" href="/nous-contacter">
Nous contacter Nous contacter
@ -174,7 +63,7 @@
<%= user.username %> <%= user.username %>
</span> </span>
</a> </a>
<div class="navbar-dropdown"> <div class="navbar-dropdown">
<a class="navbar-item" href="/ma-collection"> <a class="navbar-item" href="/ma-collection">
Ma collection Ma collection
@ -182,13 +71,21 @@
</div> </div>
</div> </div>
<% } %> <% } %>
<div class="navbar-item apparence">
<div class="theme-switch-wrapper">
<label class="theme-switch" for="checkbox" aria-label="Passer du thème clair au thème sombre et inversement">
<input type="checkbox" id="checkbox" />
<div class="slider round"></div>
</label>
</div>
</div>
<div class="navbar-item"> <div class="navbar-item">
<div class="buttons"> <div class="buttons">
<button type="button" class="button is-link" id="switchAriaTheme" aria-label="Renforcer la visibilité de ce site"> <button type="button" class="button is-primary" id="switchAriaTheme" aria-label="Renforcer la visibilité de ce site" title="Renforcer la visibilité de ce site">
<i class="icon-eye"></i> <i class="icon-eye"></i>
</button> </button>
<% if ( !user ) { %> <% if ( !user ) { %>
<a class="button is-link" href="/connexion"> <a class="button is-primary" href="/connexion">
<strong>Connexion</strong> <strong>Connexion</strong>
</a> </a>
<% } else { %> <% } else { %>
@ -203,7 +100,7 @@
</nav> </nav>
<div id="toastr"> <div id="toastr">
<button class="delete" onclick="hideToastr()"></button> <button class="delete" onclick="hideToastr()" aria-label="Masquer la notification"></button>
<span></span> <span></span>
</div> </div>
@ -216,7 +113,7 @@
<div class="body"> <div class="body">
<%= page.failureFlash %> <%= page.failureFlash %>
</div> </div>
<% } %> <% } %>
<% <%
if (error && error.length > 0) { if (error && error.length > 0) {
for( let i = 0 ; i < error.length ; i += 1 ) { for( let i = 0 ; i < error.length ; i += 1 ) {
@ -229,11 +126,11 @@
</div> </div>
<% <%
} }
} }
%> %>
</div> </div>
<% } %> <% } %>
<%- include(viewname) %> <%- include(viewname) %>
<footer class="footer layout-hero"> <footer class="footer layout-hero">

View file

@ -6,7 +6,7 @@
<label for="q">Nom de l'album ou code barre</label> <label for="q">Nom de l'album ou code barre</label>
<div class="field has-addons"> <div class="field has-addons">
<input type="text" name="q" id="q" v-model="q" placeholder="ex : Hybrid Theory" autofocus> <input type="text" name="q" id="q" v-model="q" placeholder="ex : Hybrid Theory" autofocus>
<button class="button is-link" :disabled="loading" aria-label="Chercher"> <button class="button is-primary" :disabled="loading" aria-label="Chercher">
<i class="icon-search" v-if="!loading"></i> <i class="icon-search" v-if="!loading"></i>
<i class="icon-spin animate-spin" v-if="loading"></i> <i class="icon-spin animate-spin" v-if="loading"></i>
</button> </button>
@ -14,13 +14,13 @@
</form> </form>
</div> </div>
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-2 list"> <div class="grid grid-cols-1 md:grid-cols-2 list">
<div class="item" v-if="!loading" v-for="item in items"> <div class="item" v-if="!loading" v-for="item in items">
<a @click="loadDetails(item.id)" class="title">{{ item.artists_sort }} {{ item.title }}</a> <a @click="loadDetails(item.id)" class="title">{{ item.artists_sort }} {{ item.title }}</a>
<div class="grid grid-cols-2 md:grid-cols-4"> <div class="grid grid-cols-2 md:grid-cols-4">
<div> <div>
<img :src="item.thumb" :alt="item.title" style="max-width: 120px;" @click="loadDetails(item.id)"/> <img :src="item.thumb" :alt="item.title" @click="loadDetails(item.id)"/>
</div> </div>
<div class="md:col-span-3"> <div class="md:col-span-3">
<span><strong>Année :</strong> {{ item.year }}</span> <span><strong>Année :</strong> {{ item.year }}</span>
@ -35,7 +35,7 @@
</span> </span>
<br /> <br />
<span> <span>
<strong>Genre : </strong> <strong>Genre : </strong>
<template v-for="(genre, index) in item.genre"> <template v-for="(genre, index) in item.genre">
{{ genre }}<template v-if="index < item.genre.length - 1">, </template> {{ genre }}<template v-if="index < item.genre.length - 1">, </template>
</template> </template>

403
views/pages/composants.ejs Normal file
View file

@ -0,0 +1,403 @@
<main class="layout-maxed" id="app">
<h1>Les composants</h1>
<ul>
<li><a href="#titres">Les titres</a></li>
<li><a href="#grilles">Les grilles</a></li>
<li><a href="#boutons">Les boutons</a></li>
<li><a href="#formulaires">Les formulaires</a></li>
<li><a href="#modales">Les modales</a></li>
<li><a href="#boites">Les boites</a></li>
<li><a href="#flash">Les messages flash</a></li>
<li><a href="#notifications">Les notifications</a></li>
<li><a href="#icones">Les icônes</a></li>
<li><a href="#listes">Les listes</a></li>
<li><a href="#paginations">Les paginations</a></li>
<li><a href="#barres-de-navigation">Les barres de navigation</a></li>
</ul>
<h2 id="titres">Les titres</h2>
<h1>Titre de niveau 1</h1>
<h2>Titre de niveau 2</h2>
<h3>Titre de niveau 3</h3>
<h4>Titre de niveau 4</h4>
<h5>Titre de niveau 5</h5>
<h6>Titre de niveau 6</h6>
<h2 id="grilles">Les grilles</h2>
<p>
Se référer à la documentation de <a href="https://www.knacss.com/doc.html#grid" target="_blank" rel="noopener noreferrer">Knacss</a>.
</p>
<h2 id="boutons">Les boutons</h2>
<div type="button" class="button">.button</div>
<div type="button" class="button is-link">.button.is-link</div>
<div type="button" class="button is-primary">.button.is-primary</div>
<div type="button" class="button is-success">.button.is-success</div>
<div type="button" class="button is-danger">.button.is-danger</div>
<div type="button" class="button is-warning">.button.is-warning</div>
<h2 id="formulaires">Les formulaires</h2>
<div class="field">
<label for="email">Adresse e-mail</label>
<input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr">
</div>
<pre>
&lt;div class="field"&gt;
&lt;label for="email"&gt;Adresse e-mail&lt;/label&gt;
&lt;input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr"&gt;
&lt;/div&gt;
</pre>
<div class="field">
<label for="message">Message*</label>
<textarea name="message" id="message" rows="6" required ></textarea>
</div>
<pre>
&lt;div class="field"&gt;
&lt;label for="message"&gt;Message*&lt;/label&gt;
&lt;textarea name="message" id="message" rows="6" required &gt;&lt;/textarea&gt;
&lt;/div&gt;
</pre>
<div class="field">
<label for="sortOrder">Trier par</label>
<select id="sortOrder" v-model="sortOrder" @change="changeSort">
<option value="artists_sort-asc">Artiste (A-Z)</option>
<option value="artists_sort-desc">Artiste (Z-A)</option>
<option value="year-asc">Année (A-Z)</option>
<option value="year-desc">Année (Z-A)</option>
<option value="country-asc">Pays (A-Z)</option>
<option value="country-desc">Pays (Z-A)</option>
<option value="formats.name-asc">Format (A-Z)</option>
<option value="formats.name-desc">Format (Z-A)</option>
</select>
</div>
<pre>
&lt;div class="field"&gt;
&lt;label for="sortOrder"&gt;Trier par&lt;/label&gt;
&lt;select id="sortOrder"&gt;
&lt;option value="artists_sort-asc"&gt;Artiste (A-Z)&lt;/option&gt;
&lt;option value="artists_sort-desc"&gt;Artiste (Z-A)&lt;/option&gt;
&lt;option value="year-asc"&gt;Année (A-Z)&lt;/option&gt;
&lt;option value="year-desc"&gt;Année (Z-A)&lt;/option&gt;
&lt;option value="country-asc"&gt;Pays (A-Z)&lt;/option&gt;
&lt;option value="country-desc"&gt;Pays (Z-A)&lt;/option&gt;
&lt;option value="formats.name-asc"&gt;Format (A-Z)&lt;/option&gt;
&lt;option value="formats.name-desc"&gt;Format (Z-A)&lt;/option&gt;
&lt;/select&gt;
&lt;/div&gt;
</pre>
<div class="field">
<label for="choix1">choix 1</label>
<input type="radio" id="choix1" name="choix" value="choix1" checked>
<label for="choix2">choix 2</label>
<input type="radio" id="choix2" name="choix" value="choix2">
</div>
<pre>
&lt;div class="field"&gt;
&lt;label for="choix1"&gt;choix 1&lt;/label&gt;
&lt;input type="radio" id="choix1" name="choix" value="choix1" checked&gt;
&lt;label for="choix2"&gt;choix 2&lt;/label&gt;
&lt;input type="radio" id="choix2" name="choix" value="choix2"&gt;
&lt;/div&gt;
</pre>
<div class="field">
<label for="checkbox1">choix 1</label>
<input type="checkbox" id="checkbox1" name="checkbox" value="checkbox1" checked>
<label for="checkbox2">choix 2</label>
<input type="checkbox" id="checkbox2" name="checkbox" value="checkbox2">
</div>
<pre>
&lt;div class="field"&gt;
&lt;label for="checkbox1"&gt;choix 1&lt;/label&gt;
&lt;input type="checkbox" id="checkbox1" name="checkbox" value="checkbox1" checked&gt;
&lt;label for="checkbox2"&gt;choix 2&lt;/label&gt;
&lt;input type="checkbox" id="checkbox2" name="checkbox" value="checkbox2"&gt;
&lt;/div&gt;
</pre>
<h2 id="modales">Les modales</h2>
<button type="button" class="button is-primary" @click="toggleModal">Ouvrir la modale</button>
<pre>
&lt;div class="modal" :class="{'is-visible': showModal}"&gt;
&lt;div class="modal-background"&gt;&lt;/div&gt;
&lt;div class="modal-card"&gt;
&lt;header&gt;Titre&lt;/header&gt;
&lt;section&gt;
Ceci est une modale
&lt;/section&gt;
&lt;footer&gt;
&lt;button class="button is-primary" @click="toggleModal"&gt;Ok&lt;/button&gt;
&lt;button class="button" @click="toggleModal"&gt;Annuler&lt;/button&gt;
&lt;/footer&gt;
&lt;/div&gt;
&lt;/div&gt;
</pre>
<div class="modal" :class="{'is-visible': showModal}">
<div class="modal-background"></div>
<div class="modal-card">
<header>Titre</header>
<section>
Ceci est une modale
</section>
<footer>
<button class="button is-primary" @click="toggleModal">Ok</button>
<button class="button" @click="toggleModal">Annuler</button>
</footer>
</div>
</div>
<h2 id="boites">Les boites</h2>
<div class="box">
<form method="POST">
<h1>
Connexion
</h1>
<div class="field">
<label for="email">Adresse e-mail</label>
<input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr">
</div>
<div class="field">
<label for="password">Mot de passe</label>
<input type="password" name="password" id="password" placeholder="********">
</div>
<div class="text-right mt-10">
<p>Pas encore inscrit ? <a href="/inscription">Inscrivez-vous</a></p>
</div>
<button type="submit" class="button is-primary">Connexion</button>
</form>
</div>
<pre>
&lt;div class="box"&gt;
Contenu
&lt;/div&gt;
</pre>
<h2 id="flash">Les messages flash</h2>
<div class="flash">
<div class="header">
Erreur
</div>
<div class="body">
Ceci est une erreur
</div>
</div>
<pre>
&lt;div class="flash"&gt;
&lt;div class="header"&gt;
Erreur
&lt;/div&gt;
&lt;div class="body"&gt;
Ceci est une erreur
&lt;/div&gt;
&lt;/div&gt;
</pre>
<h2 id="notifications">Les notifications</h2>
<button type="button" class="button is-primary" onclick="showToastr('Ceci est une notification');">Afficher une notification</button>
<div id="toastr">
<button class="delete" onclick="hideToastr()" aria-label="Masquer la notification"></button>
<span></span>
</div>
<pre>
&lt;button
type="button"
class="button is-primary"
onclick="showToastr('Ceci est une notification');"
&gt;
Afficher une notification
&lt;/button&gt;
&lt;div id="toastr"&gt;
&lt;button class="delete" onclick="hideToastr()" aria-label="Masquer la notification"&gt;&lt;/button&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<h2 id="icones">Les icônes</h2>
<i class="icon-plus">.icon-plus</i>
<i class="icon-user">.icon-user</i>
<i class="icon-search">.icon-search</i>
<i class="icon-mail">.icon-mail</i>
<i class="icon-link">.icon-link</i>
<i class="icon-link-ext">.icon-link-ext</i>
<i class="icon-heart">.icon-heart</i>
<i class="icon-eye">.icon-eye</i>
<i class="icon-spin">.icon-spin</i>
<i class="icon-sun">.icon-sun</i>
<i class="icon-moon">.icon-moon</i>
<i class="icon-trash">.icon-trash</i>
<i class="icon-blind">.icon-blind</i>
<h2 id="listes">Les listes</h2>
<div class="grid grid-cols-1 md:grid-cols-2 list">
<div class="item" v-for="item in items">
<span class="title">
{{ item.title }}
</span>
<div class="grid grid-cols-2 md:grid-cols-4">
<div>
<img :src="item.thumb" :alt="item.title" />
</div>
<div class="md:col-span-3">
{{ item.lorem }}
</div>
</div>
</div>
</div>
<pre>
&lt;div class="grid grid-cols-1 md:grid-cols-2 list"&gt;
&lt;div class="item"&gt;
Contenu
&lt;/div&gt;
&lt;/div&gt;
</pre>
<h2 id="paginations">Les paginations</h2>
<nav class="pagination" role="navigation" aria-label="Pagination">
<ul class="pagination-list">
<template v-for="p in Array.from({length: totalPages}, (v, i) => (i+1))">
<template v-if="p < 2 || p > (totalPages - 1) || (page - 1) <= p && page + 1 >= p">
<li>
<a class="pagination-link" :class="{'is-current': p === page}" @click="goTo(p)" aria-label="Aller à la page {{p}}">{{ p }}</a>
</li>
</template>
<template v-if="(page - 3 === p && page - 2 > 1) || (page + 2 === p && page + 2 < totalPages - 1)">
<li>
<a class="pagination-link is-disabled">…</a>
</li>
</template>
</template>
</ul>
</nav>
<pre>
&lt;nav class="pagination" role="navigation" aria-label="Pagination"&gt;
&lt;ul class="pagination-list"&gt;
&lt;li&gt;&lt;a class="pagination-link is-current" aria-label="Aller à la page 1"&gt;1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="pagination-link" aria-label="Aller à la page 2"&gt;2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="pagination-link is-disabled"&gt;…&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="pagination-link" aria-label="Aller à la page 11"&gt;11&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
</pre>
<h2 id="barres-de-navigation">Les barres de navigation</h2>
<pre>
&lt;nav class="navbar" aria-label="Navigation principale"&gt;
&lt;div class="navbar-brand"&gt;
&lt;a class="navbar-item" href="/"&gt;
&lt;img src="/img/logo.png" alt="Logo My Music Library"&gt;
&lt;span&gt;My Music Library&lt;/span&gt;
&lt;/a&gt;
&lt;a role="button" class="navbar-burger" aria-label="Afficher le menu" aria-expanded="false" data-target="navbar"&gt;
&lt;span aria-hidden="true"&gt;&lt;/span&gt;
&lt;span aria-hidden="true"&gt;&lt;/span&gt;
&lt;span aria-hidden="true"&gt;&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div id="navbar" class="navbar-menu"&gt;
&lt;div class="navbar-start"&gt;
&lt;div class="navbar-item"&gt;
&lt;div class="buttons"&gt;
&lt;a class="button is-primary" href="/ajouter-un-album"&gt;
&lt;i class="icon-plus"&gt;&lt;/i&gt;
&lt;span&gt;
Ajouter un album
&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="navbar-end"&gt;
&lt;a class="navbar-item" href="/nous-contacter"&gt;
Nous contacter
&lt;/a&gt;
&lt;div class="navbar-item has-dropdown"&gt;
&lt;a class="navbar-link"&gt;
&lt;i class="icon-user"&gt;&lt;/i&gt;
&lt;span&gt;
&lt;%= user.username %&gt;
&lt;/span&gt;
&lt;/a&gt;
&lt;div class="navbar-dropdown"&gt;
&lt;a class="navbar-item" href="/ma-collection"&gt;
Ma collection
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="navbar-item apparence"&gt;
&lt;div class="theme-switch-wrapper"&gt;
&lt;label class="theme-switch" for="checkbox" aria-label="Passer du thème clair au thème sombre et inversement"&gt;
&lt;input type="checkbox" id="checkbox" /&gt;
&lt;div class="slider round"&gt;&lt;/div&gt;
&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="navbar-item"&gt;
&lt;div class="buttons"&gt;
&lt;button type="button" class="button is-primary" id="switchAriaTheme" aria-label="Renforcer la visibilité de ce site" title="Renforcer la visibilité de ce site"&gt;
&lt;i class="icon-eye"&gt;&lt;/i&gt;
&lt;/button&gt;
&lt;a class="button is-danger" href="/se-deconnecter"&gt;
Déconnexion
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/nav&gt;
</pre>
</main>
<script>
Vue.createApp({
data() {
return {
showModal: false,
totalPages: 16,
page: 1,
items: [
{
'title': 'Titre 1',
'thumb': 'https://via.placeholder.com/150',
'lorem': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed interdum mollis justo, id sodales ipsum tincidunt quis. Pellentesque volutpat enim vitae metus mollis, et volutpat nisi egestas. Maecenas vel volutpat felis, sit amet finibus risus. Vestibulum bibendum tempus luctus. Ut rutrum iaculis porta. Donec ultricies orci non tortor posuere faucibus. Cras posuere a augue quis faucibus. Integer consequat libero egestas tempus luctus. Praesent ac arcu eget neque interdum volutpat quis sed augue. Etiam egestas purus ac accumsan consectetur. Etiam vel nibh aliquet, hendrerit leo sed, molestie dui. Nulla eget mauris nec odio facilisis condimentum varius suscipit arcu. Sed vitae felis porta, ornare enim non, egestas velit. Nam tempor ipsum dapibus neque vulputate, at sagittis est commodo. Cras eu rhoncus arcu. ',
},
{
'title': 'Titre 2',
'thumb': 'https://via.placeholder.com/150',
'lorem': 'Quisque ipsum nunc, placerat non euismod at, varius quis urna. Vivamus augue augue, vulputate vel nunc eu, interdum eleifend eros. Nam finibus mattis commodo. Donec sem leo, feugiat sed venenatis et, ultricies sit amet tortor. Fusce feugiat nibh id ex suscipit, a auctor orci iaculis. Donec vulputate quis dolor in posuere. Nullam non luctus dolor. Morbi congue massa metus, vel scelerisque quam aliquam placerat. Aenean pharetra, neque sed sollicitudin finibus, massa quam tristique lacus, vitae egestas tellus mauris sed enim. ',
},
{
'title': 'Titre 3',
'thumb': 'https://via.placeholder.com/150',
'lorem': 'Nulla facilisi. Curabitur at leo nunc. Cras volutpat congue condimentum. Donec euismod rhoncus nisl non bibendum. Nullam nec lorem eget mi facilisis tincidunt id non sapien. Maecenas in sem sed risus hendrerit dapibus. Nulla eget ex laoreet, sollicitudin neque et, luctus ligula. Curabitur viverra a justo ut bibendum. Aenean lacinia dolor quis quam pellentesque tempus. Praesent a volutpat est. Proin dignissim, dui luctus dapibus commodo, nunc arcu tincidunt est, quis molestie erat elit bibendum nisi. Vestibulum hendrerit lacinia tortor a varius. Proin nec sem ligula. Aenean eleifend odio a mi laoreet, sed hendrerit massa efficitur. ',
},
{
'title': 'Titre 4',
'thumb': 'https://via.placeholder.com/150',
'lorem': 'Integer sed eleifend arcu. Morbi eget ipsum ut leo pellentesque commodo eget a ipsum. Nam vel enim sed neque bibendum ultricies nec non odio. Vivamus a fermentum ligula. Mauris in gravida tellus, eu pretium turpis. Mauris et mi tincidunt, molestie velit sit amet, euismod nunc. Fusce malesuada mi ante, vel accumsan lacus consequat non. Maecenas leo tellus, tincidunt nec hendrerit eget, convallis vel ex. Donec eleifend nisi erat, a aliquet ex vulputate congue. Sed efficitur eu ligula ac aliquam. Nullam sit amet blandit nisl. ',
},
{
'title': 'Titre 5',
'thumb': 'https://via.placeholder.com/150',
'lorem': 'Nulla facilisi. Aliquam et suscipit est, in faucibus felis. Nunc at risus rutrum, fermentum sem facilisis, porttitor diam. Mauris vitae neque enim. Sed in lobortis augue, eget hendrerit nunc. Donec in arcu vitae eros lobortis eleifend. Proin non vulputate sem, a pharetra felis. In tortor purus, blandit nec enim a, mattis pulvinar magna. Praesent vel felis vel sapien interdum suscipit ut a justo. Quisque non felis ac velit maximus tincidunt ac at nibh. ',
},
]
}
},
methods: {
toggleModal() {
this.showModal = !this.showModal;
},
goTo(page) {
this.page = page;
},
}
}).mount('#app')
</script>

View file

@ -1,4 +1,4 @@
<div class="connexion"> <div class="box">
<form method="POST"> <form method="POST">
<h1> <h1>
Connexion Connexion
@ -6,7 +6,7 @@
<div class="field"> <div class="field">
<label for="email">Adresse e-mail</label> <label for="email">Adresse e-mail</label>
<input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr"> <input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr">
</div> </div>
<div class="field"> <div class="field">
<label for="password">Mot de passe</label> <label for="password">Mot de passe</label>
<input type="password" name="password" id="password" placeholder="********"> <input type="password" name="password" id="password" placeholder="********">
@ -15,7 +15,7 @@
<div class="text-right mt-10"> <div class="text-right mt-10">
<p>Pas encore inscrit ? <a href="/inscription">Inscrivez-vous</a></p> <p>Pas encore inscrit ? <a href="/inscription">Inscrivez-vous</a></p>
</div> </div>
<button type="submit" class="button">Connexion</button> <button type="submit" class="button is-primary">Connexion</button>
</form> </form>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="connexion"> <div class="box">
<form method="POST"> <form method="POST">
<h1> <h1>
Inscription Inscription
@ -6,11 +6,11 @@
<div class="field"> <div class="field">
<label for="username">Nom d'utilisateur</label> <label for="username">Nom d'utilisateur</label>
<input type="text" name="username" id="username" placeholder="ex : darkou"> <input type="text" name="username" id="username" placeholder="ex : darkou">
</div> </div>
<div class="field"> <div class="field">
<label for="email">Adresse e-mail</label> <label for="email">Adresse e-mail</label>
<input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr"> <input type="email" name="email" id="email" placeholder="ex : damien@darkou.fr">
</div> </div>
<div class="field"> <div class="field">
<label for="password">Mot de passe</label> <label for="password">Mot de passe</label>
<input type="password" name="password" id="password" placeholder="********"> <input type="password" name="password" id="password" placeholder="********">
@ -19,7 +19,7 @@
<div class="text-right mt-10"> <div class="text-right mt-10">
<p>Déjà inscrit ? <a href="/connexion">Connectez-vous</a></p> <p>Déjà inscrit ? <a href="/connexion">Connectez-vous</a></p>
</div> </div>
<button type="submit" class="button">Inscription</button> <button type="submit" class="button is-primary">Inscription</button>
</form> </form>
</div> </div>

View file

@ -55,7 +55,7 @@
<span> <span>
<strong>Format : </strong> <strong>Format : </strong>
<span v-for="(format, index) in item.formats"> <span v-for="(format, index) in item.formats">
{{ format.name }} {{ format.name }}
<template v-if="format.descriptions"> <template v-if="format.descriptions">
(<template v-for="(description, j) in format.descriptions"> (<template v-for="(description, j) in format.descriptions">
{{description}}<template v-if="j < format.descriptions.length - 1">, </template> {{description}}<template v-if="j < format.descriptions.length - 1">, </template>
@ -70,22 +70,20 @@
<span><strong>Style :</strong> <template v-for="(style, index) in item.styles">{{ style }}<template v-if="index < item.styles.length - 1">, </template></template></span> <span><strong>Style :</strong> <template v-for="(style, index) in item.styles">{{ style }}<template v-if="index < item.styles.length - 1">, </template></template></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="total"> <div class="total">
<strong>Nombre total d'éléments : </strong>{{total}} <strong>Nombre total d'éléments : </strong>{{total}}
</div> </div>
<nav class="pagination" role="navigation" aria-label="Pagination"> <nav class="pagination" role="navigation" aria-label="Pagination">
<a class="pagination-previous" :class="{'is-disabled': page === 1}" @click="previous">Précédent</a>
<a class="pagination-next" :class="{'is-disabled': !total || (page*limit) >= total}" @click="next">Suivant</a>
<ul class="pagination-list"> <ul class="pagination-list">
<template v-for="p in Array.from({length: totalPages}, (v, i) => (i+1))"> <template v-for="p in Array.from({length: totalPages}, (v, i) => (i+1))">
<template v-if="p < 4 || p > (totalPages - 3) || (page - 3) <= p && page + 3 >= p"> <template v-if="p < 2 || p > (totalPages - 1) || (page - 1) <= p && page + 1 >= p">
<li> <li>
<a class="pagination-link" :class="{'is-current': p === page}" @click="goTo(p)" aria-label="Aller à la page {{p}}">{{ p }}</a> <a class="pagination-link" :class="{'is-current': p === page}" @click="goTo(p)" aria-label="Aller à la page {{p}}">{{ p }}</a>
</li> </li>
</template> </template>
<template v-if="(page - 3 - 1 === p && page - 4 > 3) || (page + 4 === p && page + 3 < totalPages - 3)"> <template v-if="(page - 3 === p && page - 2 > 1) || (page + 2 === p && page + 2 < totalPages - 1)">
<li> <li>
<a class="pagination-link is-disabled">…</a> <a class="pagination-link is-disabled">…</a>
</li> </li>
@ -118,7 +116,7 @@
total: 0, total: 0,
page: 1, page: 1,
totalPages: 1, totalPages: 1,
limit: 10, limit: 16,
artist: '', artist: '',
format: '', format: '',
sortOrder: 'artists_sort-asc', sortOrder: 'artists_sort-asc',

View file

@ -1,4 +1,4 @@
<section class="nous-contacter"> <section class="box">
<h1>Nous contacter</h1> <h1>Nous contacter</h1>
<form action="https://formspree.io/f/<%= config.formspreeId %>" method="POST"> <form action="https://formspree.io/f/<%= config.formspreeId %>" method="POST">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-16"> <div class="grid grid-cols-1 lg:grid-cols-2 gap-16">
@ -11,12 +11,12 @@
<input type="text" name="name" id="name" /> <input type="text" name="name" id="name" />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label for="message">Message*</label> <label for="message">Message*</label>
<textarea name="message" id="message" rows="6" required ></textarea> <textarea name="message" id="message" rows="6" required ></textarea>
</div> </div>
<button type="submit" class="button is-primary">Envoyer</button> <button type="submit" class="button is-primary">Envoyer</button>
</form> </form>
</section> </section>