Compare commits

..

No commits in common. "62607e2a83ac44669abbee4e187cd7cd05794a0d" and "b1aaeaaef85b32262fc9ca734f482d317d5e31c6" have entirely different histories.

7 changed files with 75 additions and 431 deletions

View file

@ -44,6 +44,7 @@
},
"dependencies": {
"axios": "^0.26.0",
"bulma": "^0.9.3",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"connect-mongo": "^4.6.0",
@ -53,7 +54,6 @@
"ejs": "^3.1.6",
"express": "^4.17.2",
"express-session": "^1.17.2",
"knacss": "^8.0.4",
"moment": "^2.29.1",
"mongoose": "^6.2.1",
"mongoose-unique-validator": "^3.0.0",

View file

@ -1,19 +0,0 @@
html,
body {
min-height: 100vh;
display: flex;
flex-direction: column;
padding-top: 3.25rem;
font-family: BlinkMacSystemFont,-apple-system,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue","Helvetica","Arial",sans-serif;
font-weight: 400;
footer {
margin-top: auto;
padding: 2rem 0 1.5rem;
background-color: #fafafa;
}
a {
color: #485fc7;
}
}

View file

@ -1,8 +1,17 @@
.header {
margin-bottom: 3.25rem;
@include respond-to("small-up") {
height: 30vh;
background-image: url('/header.jpg');
background-size: cover;
margin-bottom: 3.25rem;
}
html,
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
body > footer {
margin-top: auto;
}

View file

@ -1,30 +1,4 @@
// @use '../node_modules/knacss/sass/knacss.scss';
// NOYAU
@import "../node_modules/knacss/sass/abstracts/variables-sass";
@import "../node_modules/knacss/sass/abstracts/mixins-sass";
@import "../node_modules/knacss/sass/base/reset-base";
@import "../node_modules/knacss/sass/base/reset-accessibility";
@import "../node_modules/knacss/sass/base/reset-forms";
@import "../node_modules/knacss/sass/base/reset-print";
@import "../node_modules/knacss/sass/base/layout";
// UTILITAIRES
@import "../node_modules/knacss/sass/utils/utils-global";
@import "../node_modules/knacss/sass/utils/utils-font-sizes";
@import "../node_modules/knacss/sass/utils/utils-spacers";
@import "../node_modules/knacss/sass/utils/grillade";
// COMPOSANTS (à ajouter au besoin)
// @import "../node_modules/knacss/sass/components/button";
// @import "components/burger";
// @import "components/checkbox";
// @import "components/radio";
// @import "components/select";
// @import "components/quote";
// SPÉCIFIQUE AU SITE
@import './global';
@import './navbar';
@import './home';
@use './bulma.scss';
@use './toast.scss';
@use './pagination.scss';
@use './home.scss';

View file

@ -1,325 +0,0 @@
.navbar {
min-height: 3.25rem;
background-color: #f5f5f5;
color: rgba(0,0,0,.7);
position: fixed;
z-index: 30;
top: 0;
right: 0;
left: 0;
@include respond-to("medium-up") {
min-height: 3.25rem;
align-items: stretch;
display: flex;
}
.navbar-brand {
align-items: stretch;
display: flex;
min-height: 3.25rem;
.navbar-item {
align-items: center;
display: flex;
@include respond-to("medium-up") {
// display: block;
}
img {
max-height: 1.75rem;
}
span {
word-break: break-word;
color: #363636;
font-size: 2rem;
font-weight: 600;
line-height: 1.125;
margin-left: .5rem !important;
}
}
}
.navbar-burger {
padding: 0;
margin: 0;
font-size: 1em;
appearance: none;
background: none;
border: none;
cursor: pointer;
display: block;
height: 3.25rem;
position: relative;
width: 3.25rem;
margin-left: auto;
color: rgba(0,0,0,.7);
@include respond-to("medium-up") {
display: none;
}
span {
background-color: currentColor;
display: block;
height: 1px;
left: calc(50% - 8px);
position: absolute;
transform-origin: center;
transition-duration: 86ms;
transition-property: background-color,opacity,transform;
transition-timing-function: ease-out;
width: 16px;
&:nth-child(1) {
top: calc(50% - 6px);
}
&:nth-child(2) {
top: calc(50% - 1px);
}
&:nth-child(3) {
top: calc(50% + 4px);
}
}
&.is-active {
span {
&:nth-child(1) {
transform: translateY(5px) rotate(45deg);
}
&:nth-child(2) {
opacity: 0;
}
&:nth-child(3) {
transform: translateY(-5px) rotate(-45deg);
}
}
}
}
.navbar-item {
line-height: 1.5;
padding: .5rem .75rem;
position: relative;
flex-grow: 0;
flex-shrink: 0;
color: #4a4a4a;
display: block;
&.has-dropdown {
padding: 0;
@include respond-to("medium-up") {
display: flex;
align-items: stretch;
color: rgba(0,0,0,.7);
.navbar-dropdown {
background-color: #fff;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
border-top: 2px solid #dbdbdb;
box-shadow: 0 8px 8px rgba(10,10,10,.1);
display: none;
font-size: .875rem;
left: 0;
min-width: 100%;
position: absolute;
top: 100%;
z-index: 20;
}
&:hover {
.navbar-link {
background-color: #e8e8e8;
color: rgba(0,0,0,.7);
}
.navbar-dropdown {
display: block;
}
}
}
}
@include respond-to("medium-up") {
align-items: center;
display: flex;
}
}
.navbar-link {
color: #4a4a4a;
display: block;
line-height: 1.5;
padding: .5rem .75rem;
position: relative;
cursor: pointer;
padding-right: 2.5em;
@include respond-to("medium-up") {
display: flex;
align-items: center;
}
.icon {
align-items: center;
display: inline-flex;
justify-content: center;
height: 1.5rem;
width: 1.5rem;
}
&::after {
border: 3px solid transparent;
border-radius: 2px;
border-right: 0;
border-top: 0;
content: " ";
display: block;
height: .625em;
pointer-events: none;
position: absolute;
top: 50%;
transform: rotate(-45deg);
transform-origin: center;
width: .625em;
border-color: #485fc7;
margin-top: -0.375em;
right: 1.125em;
@include respond-to("medium-up") {
border-color: rgba(0,0,0,.7);
}
}
}
.navbar-menu {
display: none;
background-color: #fff;
box-shadow: 0 8px 16px rgba(10,10,10,.1);
padding: .5rem 0;
@include respond-to("medium") {
max-height: calc(100vh - 3.25rem);
overflow: auto;
}
@include respond-to("medium-up") {
flex-grow: 1;
flex-shrink: 0;
align-items: stretch;
display: flex;
background-color: initial;
box-shadow: none;
padding: 0;
}
&.is-active {
display: block;
}
@include respond-to("medium-up") {
.navbar-start {
justify-content: flex-start;
margin-right: auto;
align-items: stretch;
display: flex;
.navbar-item {
color: rgba(0,0,0,.7);
align-items: center;
display: flex;
}
}
.navbar-end {
justify-content: flex-end;
margin-left: auto;
align-items: stretch;
display: flex;
}
}
}
.navbar-dropdown {
font-size: .875rem;
padding-bottom: .5rem;
padding-top: .5rem;
.navbar-item {
cursor: pointer;
padding-left: 1.5rem;
padding-right: 1.5rem;
}
@include respond-to("medium-up") {
background-color: #fff;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
border-top: 2px solid #dbdbdb;
box-shadow: 0 8px 8px rgba(10,10,10,.1);
display: none;
font-size: .875rem;
left: 0;
min-width: 100%;
position: absolute;
top: 100%;
z-index: 20;
.navbar-item {
white-space: nowrap;
padding: .375rem 1rem;
padding-right: 3rem;
}
}
}
img {
height: auto;
max-width: 100%;
}
a {
text-decoration: none;
}
.buttons {
align-items: center;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
&:last-child {
margin-bottom: -0.5rem;
}
.button {
cursor: pointer;
justify-content: center;
padding-bottom: calc(0.5em - 1px);
padding-left: 1em;
padding-right: 1em;
padding-top: calc(0.5em - 1px);
text-align: center;
white-space: nowrap;
border-width: 1px;
margin-bottom: .5rem;
&.is-danger {
background-color: #f14668;
border-color: transparent;
color: #fff;
}
&.is-link {
background-color: #485fc7;
border-color: transparent;
color: #fff;
}
}
}
}

View file

@ -51,26 +51,26 @@
});
</script>
</head>
<body>
<nav class="navbar" role="navigation" aria-label="main navigation">
<body class="has-navbar-fixed-top">
<nav class="navbar is-fixed-top is-light" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<img src="/logo.png" alt="Logo">
<span>My Music Library</span>
<h1 class="title ml-2">My Music Library</h1>
</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbar">
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbar" class="navbar-menu">
<div id="navbarBasicExample" class="navbar-menu">
<% if ( user ) { %>
<div class="navbar-start">
<div class="navbar-item">
<div class="buttons">
<p class="control">
<a class="button is-link" href="/ajouter-un-album">
<span class="icon">
<i class="fa-solid fa-plus"></i>
@ -79,14 +79,14 @@
Ajouter un album
</span>
</a>
</div>
</p>
</div>
</div>
<% } %>
<div class="navbar-end">
<% if ( user ) { %>
<div class="navbar-item has-dropdown">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
<span class="icon">
<i class="fa-solid fa-user"></i>
@ -120,12 +120,13 @@
</div>
</nav>
<!-- <div id="toastr" class="notification is-danger">
<div id="toastr" class="notification is-danger">
<button class="delete"></button>
<span></span>
</div> -->
</div>
<!-- <main class="layout-maxed">
<main class="mt-4 mb-5">
<% if ( page.failureFlash || (error && error.length > 0 ) ) {%>
<div class="columns is-mobile">
<div class="
@ -165,16 +166,16 @@
</div>
</div>
<% } %>
</main> -->
<main class="layout-maxed">
<%- include(viewname) %>
</main>
<footer class="footer layout-hero">
<footer class="footer">
<div class="content has-text-centered">
<p>
<strong title="Merci Brunus ! 😜">My Music Library</strong> par <a href="https://www.darkou.fr">Damien Broqua</a>.
Fait avec ❤ à Bordeaux.
Le code source est sous licence <a href="https://www.gnu.org/licenses/gpl-3.0-standalone.html">GNU GPL-3.0-or-later</a>.
</p>
</div>
</footer>
</body>
</html>

View file

@ -1,31 +1,35 @@
<div class="header layout-hero"></div>
<h1>
<section class="section">
<div class="container">
<div class="header"></div>
<h1 class="title is-1">
My Music Library
</h1>
<p>
Retrouvez votre cd-thèque partout depuis votre PC ou votre smartphone.
<p class="subtitle">
Retrouvez votre cdthèque partout depuis votre PC ou votre smartphone.
</p>
<p>
<strong>My Music Library</strong> est une application Web (que vous pouvez auto-héberger) et un site Web (sur lequel vous pouvez créer un compte), permettant de gérer votre liste des CDs et Vinyles, et de l'utiliser facilement et n'importe où.
<strong>My Music Library</strong> est un site web permettant de sauvegarder votre liste des CDs ou Vinyles et de la retrouver facilement et n'importe ou !
<br />
Le code source est publié sous licence libre <a href="https://www.gnu.org/licenses/gpl-3.0-standalone.html" target="_blank" rel="noopener noreferrer">GNU GPL-3.0-or-later</a>. Le code source est disponible sur <a href="https://git.darkou.fr/dbroqua/MyMusicLibrary" target="_blank">git.darkou.fr</a>.
Le code source est publiée sous licence <a href="https://www.gnu.org/licenses/gpl-3.0-standalone.html" target="_blank" rel="noopener noreferrer">GNU GPL-3.0-or-later</a>. Le code source est librement accessible sur <a href="https://git.darkou.fr/dbroqua/MyMusicLibrary" target="_blank">git.darkou.fr</a>.
</p>
<h2>
Pourquoi utiliser My Music Library ?
<h2 class="title is-2">
Pourquoi ?
</h2>
<p>
<strong>My Music Library</strong> est indispensable lorsqu'une collecion, de CD-audios et vyniles, est devenue trop importante pour qu'on puisse se souvenir de tous les albums qu'elle contient. Consulter My Music Library peut par exemple éviter un achat en double, et de savoir qu'on à des albums à céder ou échanger.
<strong>My Music Library</strong> est né d'un besoin personnel lorsque ma collecion de CD est devenu un peu trop grosse pour m'en souvenir et après avoir acheté par accident plusieurs fois le même CD…
<br />
Il existe déjà plusieurs applications de gestion de librairies musicales mais, (au moment de l'édition de cette présentation) aucune facilement accessible via internet, comme par exemple lorsqu'on est chez un discaire.
Il était donc temps de trouver une solution ! Il existe plusieurs logiciel de gestion de librairies musicales mais, à ma connaissance, aucun facilement accessible via internet (genre calé sous la couette ou dans un magasin de musique 😜).
</p>
<h2>
Qu'est ce qui fait tourner My Music Library ?
<h2 class="title is-2">
Comment ?
</h2>
<p>
<strong>My Music Library</strong> c'est un backend, une base de données et un front (à terme une API pour être consommée par une app mobile 🤔).
<ul>
<li>Backend écrit en JavaScript avec <a href="https://nodejs.org/" target="_blank" rel="noopener noreferrer">NodeJS</a>.</li>
<li>Base de données de type <a href="https://fr.wikipedia.org/wiki/NoSQL" target="_blank" rel="noopener noreferrer">NoSQL</a> via <a href="https://www.mongodb.com/" target="_blank" rel="noopener noreferrer">MongoDB</a>.</li>
<li>Front utilisant <a href="https://www.knacss.com/" target="_blank" rel="noopener noreferrer">Knacss</a> et <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer">VueJS</a>.</li>
</ul>
Alors là clairement j'ai pas trop réfléchi… <a href="https://nodejs.org/" target="_blank" rel="noopener noreferrer">NodeJS</a> forcément, déformation pro 😅.
<br />
Pour la base de données je suis parti sur <a href="https://www.mongodb.com/" target="_blank" rel="noopener noreferrer">MongoDB</a> qui me semblait être le plus logique pour stocker une telle collection sans avoir plein de relations dans tous les sens (artiste, pays, genre, style etc…).
<br />
Pour le front j'ai voulu innover en n'utilisant pas <a href="https://jquery.com/" target="_blank" rel="noopener noreferrer">jQuery</a> et <a href="https://getbootstrap.com/" target="_blank" rel="noopener noreferrer">Boostrap</a> mais <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer">VueJS</a> et <a href="https://bulma.io/" target="_blank" rel="noopener noreferrer">Bulma</a> !
</p>
</div>
</section>