diff --git a/.eslintrc.js b/.eslintrc.js index c8f8a9d..143bf10 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,7 +16,7 @@ module.exports = { 'no-underscore-dangle': [ 'error', { - allow: ['_id', 'artists_sort'], + allow: ['_id', 'artists_sort', 'type_'], }, ], 'camelcase': [ diff --git a/README.md b/README.md index c787da0..fdc754d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # MusicTopus +![MusicTopus](public/img/logo-large.png) + MusicTopus 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 n'importe où. Le code source est publié sous licence libre [GNU GPL-3.0-or-later](LICENSE) et est disponible sur [git.darkou.fr](https://git.darkou.fr/dbroqua/MusicTopus). diff --git a/package.json b/package.json index 77f10de..8c53d5a 100644 --- a/package.json +++ b/package.json @@ -51,10 +51,12 @@ "debug": "^4.3.3", "disconnect": "^1.2.2", "ejs": "^3.1.6", + "excel4node": "^1.7.2", "express": "^4.17.2", "express-session": "^1.17.2", "knacss": "^8.0.4", "moment": "^2.29.1", + "moment-timezone": "^0.5.34", "mongoose": "^6.2.1", "mongoose-unique-validator": "^3.0.0", "passport": "^0.5.2", diff --git a/public/font/icon.eot b/public/font/icon.eot index 1609d73..5a5d395 100644 Binary files a/public/font/icon.eot and b/public/font/icon.eot differ diff --git a/public/font/icon.svg b/public/font/icon.svg index 67c8d09..51f7015 100644 --- a/public/font/icon.svg +++ b/public/font/icon.svg @@ -20,6 +20,12 @@ + + + + + + diff --git a/public/font/icon.ttf b/public/font/icon.ttf index cbdbe4d..488fa0b 100644 Binary files a/public/font/icon.ttf and b/public/font/icon.ttf differ diff --git a/public/font/icon.woff b/public/font/icon.woff index 4bed225..7c3262d 100644 Binary files a/public/font/icon.woff and b/public/font/icon.woff differ diff --git a/public/font/icon.woff2 b/public/font/icon.woff2 index b39dcc9..ac6af3a 100644 Binary files a/public/font/icon.woff2 and b/public/font/icon.woff2 differ diff --git a/public/js/main.js b/public/js/main.js index 710d84b..994b2ae 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,7 +1,7 @@ /** - * Fonction permettant d'afficher un message dans un toastr - * @param {String} message - */ + * Fonction permettant d'afficher un message dans un toastr + * @param {String} message + */ function showToastr(message) { let x = document.getElementById("toastr"); if ( message ) { @@ -114,17 +114,22 @@ document.addEventListener('DOMContentLoaded', () => { } const switchAriaThemeBtn = document.querySelector("#switchAriaTheme"); - switchAriaThemeBtn.addEventListener("click", switchAriaTheme); + if ( switchAriaThemeBtn ) { + switchAriaThemeBtn.addEventListener("click", switchAriaTheme); + } setAriaTheme(getCookie('ariatheme')); const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - toggleSwitch.addEventListener('change', switchTheme, false); + if ( toggleSwitch ) { + 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'; + if ( toggleSwitch) { + toggleSwitch.checked = currentThemeIsDark === 'dark'; + } }); \ No newline at end of file diff --git a/sass/forms.scss b/sass/forms.scss index 0f4aab7..fd302e0 100644 --- a/sass/forms.scss +++ b/sass/forms.scss @@ -3,6 +3,10 @@ display: flex; flex-direction: column; + &.inline { + flex-direction: row; + } + &.has-addons { display: flex; justify-content: flex-start; @@ -40,6 +44,28 @@ } } + input[type="radio"] { + border-radius: 50%; + appearance: none; + width: 1.2rem; + height: 1.2rem; + vertical-align: text-bottom; + outline: 0; + box-shadow: inset 0 0 0 1px var(--input-active-color); + background-color: #fff; + transition: background-size .15s; + cursor: pointer; + + &:checked { + box-shadow: inset 0 0 0 4px var(--input-active-color); + } + } + + input[type="radio"] + label, + label + input[type="radio"] { + margin-left: 12px; + } + select { appearance: none; background-image: url("data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20standalone%3D%22no%22%3F%3E%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20style%3D%22isolation%3Aisolate%22%20viewBox%3D%220%200%2020%2020%22%20width%3D%2220%22%20height%3D%2220%22%3E%3Cpath%20d%3D%22%20M%209.96%2011.966%20L%203.523%205.589%20C%202.464%204.627%200.495%206.842%201.505%207.771%20L%201.505%207.771%20L%208.494%2014.763%20C%209.138%2015.35%2010.655%2015.369%2011.29%2014.763%20L%2011.29%2014.763%20L%2018.49%207.771%20C%2019.557%206.752%2017.364%204.68%2016.262%205.725%20L%2016.262%205.725%20L%209.96%2011.966%20Z%20%22%20fill%3D%22inherit%22/%3E%3C/svg%3E"); diff --git a/sass/global.scss b/sass/global.scss index 2165147..491b9ca 100644 --- a/sass/global.scss +++ b/sass/global.scss @@ -1,5 +1,6 @@ html { min-height: 100vh; + scroll-behavior: smooth; body { background-color: var(--bg-color); @@ -69,4 +70,16 @@ html { .is-hidden { display: none; +} + +.ml-4 { + margin-left: 1rem; +} + +.sm-hidden { + display: none; + + @include respond-to("small-up") { + display: initial; + } } \ No newline at end of file diff --git a/sass/icons.scss b/sass/icons.scss index ec219a8..ca297ea 100644 --- a/sass/icons.scss +++ b/sass/icons.scss @@ -39,6 +39,9 @@ .icon-link:before { content: '\e804'; } /* '' */ .icon-heart:before { content: '\e805'; } /* '' */ .icon-eye:before { content: '\e806'; } /* '' */ +.icon-left-open:before { content: '\e807'; } /* '' */ +.icon-right-open:before { content: '\e808'; } /* '' */ +.icon-export:before { content: '\e809'; } /* '' */ .icon-spin:before { content: '\e839'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ .icon-sun:before { content: '\f185'; } /* '' */ diff --git a/sass/index.scss b/sass/index.scss index a2d268e..aa7557a 100644 --- a/sass/index.scss +++ b/sass/index.scss @@ -19,8 +19,8 @@ // COMPOSANTS (à ajouter au besoin) // @import "../node_modules/knacss/sass/components/button"; // @import "components/burger"; -// @import "components/checkbox"; -// @import "components/radio"; +// @import "../node_modules/knacss/sass/components/checkbox"; +@import "../node_modules/knacss/sass/components/radio"; // @import "../node_modules/knacss/sass/components/select"; // @import "components/quote"; @@ -43,4 +43,5 @@ @import './error'; @import './home'; @import './ajouter-un-album'; -@import './ma-collection'; \ No newline at end of file +@import './ma-collection'; +@import './ma-collection-details'; \ No newline at end of file diff --git a/sass/ma-collection-details.scss b/sass/ma-collection-details.scss new file mode 100644 index 0000000..6d4ba32 --- /dev/null +++ b/sass/ma-collection-details.scss @@ -0,0 +1,55 @@ +.ma-collection-details { + .galerie { + display: flex; + flex-wrap: wrap; + + div { + width: 80px; + height: 80px; + margin: 0.25rem; + padding: 0.25rem; + border: 2px solid var(--font-color); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + img { + max-width: 90%; + } + } + } + + .modal { + button.close { + height: 36px; + max-height: 36px; + max-width: 36px; + min-height: 36px; + min-width: 36px; + width: 36px; + position: absolute; + background-color: rgba(10,10,10,.6); + right: 12px; + top: 12px; + } + + .navigation { + position: absolute; + top: 50%; + cursor: pointer; + z-index: 10; + + &.previous { + left: 12px; + } + &.next { + right: 12px; + } + i { + font-size: 2rem; + color: $nord4; + } + } + } +} \ No newline at end of file diff --git a/sass/modal.scss b/sass/modal.scss index ffe0571..e44de67 100644 --- a/sass/modal.scss +++ b/sass/modal.scss @@ -24,6 +24,47 @@ top: 0; } + button.close { + user-select: none; + background-color: rgba(10,10,10,.2); + border: none; + border-radius: 9999px; + cursor: pointer; + pointer-events: auto; + display: inline-block; + flex-grow: 0; + flex-shrink: 0; + font-size: 0; + height: 20px; + max-height: 20px; + max-width: 20px; + min-height: 20px; + min-width: 20px; + outline: none; + position: relative; + width: 20px; + + &::before, + &::after { + background-color: var(--default-color); + content: ""; + display: block; + left: 50%; + position: absolute; + top: 50%; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform-origin: center center; + } + &::before { + height: 2px; + width: 50%; + } + &::after { + height: 50%; + width: 2px; + } + } + .modal-card { position: relative; width: 300px; @@ -62,47 +103,6 @@ justify-content: space-between; font-size: 1.5rem; @include transition() {} - - button { - user-select: none; - background-color: rgba(10,10,10,.2); - border: none; - border-radius: 9999px; - cursor: pointer; - pointer-events: auto; - display: inline-block; - flex-grow: 0; - flex-shrink: 0; - font-size: 0; - height: 20px; - max-height: 20px; - max-width: 20px; - min-height: 20px; - min-width: 20px; - outline: none; - position: relative; - width: 20px; - - &::before, - &::after { - background-color: var(--default-color); - content: ""; - display: block; - left: 50%; - position: absolute; - top: 50%; - transform: translateX(-50%) translateY(-50%) rotate(45deg); - transform-origin: center center; - } - &::before { - height: 2px; - width: 50%; - } - &::after { - height: 50%; - width: 2px; - } - } } section { background-color: var(--default-color); diff --git a/src/app.js b/src/app.js index d64e63c..0b32d82 100644 --- a/src/app.js +++ b/src/app.js @@ -12,6 +12,7 @@ import config, { env, mongoDbUri, secret } from "./config"; import { isXhr } from "./helpers"; import indexRouter from "./routes"; +import maCollectionRouter from "./routes/ma-collection"; import importAlbumRouterApiV1 from "./routes/api/v1/albums"; import importSearchRouterApiV1 from "./routes/api/v1/search"; @@ -80,6 +81,7 @@ app.use( ); app.use("/", indexRouter); +app.use("/ma-collection", maCollectionRouter); app.use("/api/v1/albums", importAlbumRouterApiV1); app.use("/api/v1/search", importSearchRouterApiV1); diff --git a/src/middleware/Albums.js b/src/middleware/Albums.js index fe795c3..4796207 100644 --- a/src/middleware/Albums.js +++ b/src/middleware/Albums.js @@ -1,4 +1,6 @@ import moment from "moment"; +import momenttz from "moment-timezone"; +import xl from "excel4node"; import Pages from "./Pages"; @@ -9,6 +11,451 @@ import ErrorEvent from "../libs/error"; * Classe permettant la gestion des albums d'un utilisateur */ class Albums extends Pages { + static replaceSpecialChars(str) { + if (!str) { + return ""; + } + let final = str.toString(); + const find = ["&", "<", ">"]; + const replace = ["&", "<", ">"]; + + for (let i = 0; i < find.length; i += 1) { + final = final.replace(new RegExp(find[i], "g"), replace[i]); + } + + return final; + } + + /** + * Méthode permettant de convertir les rows en csv + * @param {Array} rows + * + * @return {string} + */ + static async convertToCsv(rows) { + let data = + "Artiste;Titre;Genre;Styles;Pays;Année;Date de sortie;Format\n\r"; + + for (let i = 0; i < rows.length; i += 1) { + const { + artists_sort, + title, + genres, + styles, + country, + year, + released, + formats, + } = rows[i]; + + let format = ""; + for (let j = 0; j < formats.length; j += 1) { + format += `${format !== "" ? ", " : ""}${formats[j].name}`; + } + + data += `${artists_sort};${title};${genres.join()};${styles.join()};${country};${year};${released};${format}\n\r`; + } + + return data; + } + + /** + * Méthode permettant de convertir les rows en fichier xls + * @param {Array} rows + * + * @return {Object} + */ + static async convertToXls(rows) { + const wb = new xl.Workbook(); + const ws = wb.addWorksheet("MusicTopus"); + + const headerStyle = wb.createStyle({ + font: { + color: "#FFFFFF", + size: 11, + }, + fill: { + type: "pattern", + patternType: "solid", + bgColor: "#595959", + fgColor: "#595959", + }, + }); + const style = wb.createStyle({ + font: { + color: "#000000", + size: 11, + }, + numberFormat: "0000", + }); + + const header = [ + "Artiste", + "Titre", + "Genre", + "Styles", + "Pays", + "Année", + "Date de sortie", + "Format", + ]; + for (let i = 0; i < header.length; i += 1) { + ws.cell(1, i + 1) + .string(header[i]) + .style(headerStyle); + } + + for (let i = 0; i < rows.length; i += 1) { + const currentRow = i + 2; + const { + artists_sort, + title, + genres, + styles, + country, + year, + released, + formats, + } = rows[i]; + + let format = ""; + for (let j = 0; j < formats.length; j += 1) { + format += `${format !== "" ? ", " : ""}${formats[j].name}`; + } + + ws.cell(currentRow, 1).string(artists_sort).style(style); + ws.cell(currentRow, 2).string(title).style(style); + ws.cell(currentRow, 3).string(genres.join()).style(style); + ws.cell(currentRow, 4).string(styles.join()).style(style); + if (country) { + ws.cell(currentRow, 5).string(country).style(style); + } + if (year) { + ws.cell(currentRow, 6).number(year).style(style); + } + if (released) { + ws.cell(currentRow, 7) + .date(momenttz.tz(released, "Europe/Paris").hour(12)) + .style({ numberFormat: "dd/mm/yyyy" }); + } + ws.cell(currentRow, 8).string(format).style(style); + } + + return wb; + } + + /** + * Méthode permettant de convertir les rows en csv pour importer dans MusicTopus + * @param {Array} rows + * + * @return {string} + */ + static async convertToXml(rows) { + let data = '\n\r'; + + for (let i = 0; i < rows.length; i += 1) { + const { + discogsId, + year, + released, + uri, + artists, + artists_sort, + labels, + series, + companies, + formats, + title, + country, + notes, + identifiers, + videos, + genres, + styles, + tracklist, + extraartists, + images, + thumb, + } = rows[i]; + + let artistsList = ""; + let labelList = ""; + let serieList = ""; + let companiesList = ""; + let formatsList = ""; + let identifiersList = ""; + let videosList = ""; + let genresList = ""; + let stylesList = ""; + let tracklistList = ""; + let extraartistsList = ""; + let imagesList = ""; + + for (let j = 0; j < artists.length; j += 1) { + artistsList += ` + ${Albums.replaceSpecialChars(artists[j].name)} + ${Albums.replaceSpecialChars(artists[j].anv)} + ${Albums.replaceSpecialChars(artists[j].join)} + ${Albums.replaceSpecialChars(artists[j].role)} + ${Albums.replaceSpecialChars( + artists[j].tracks + )} + ${Albums.replaceSpecialChars(artists[j].id)} + ${Albums.replaceSpecialChars( + artists[j].resource_url + )} + ${Albums.replaceSpecialChars( + artists[j].thumbnail_url + )} + `; + } + + for (let j = 0; j < labels.length; j += 1) { + labelList += ` + `; + } + + for (let j = 0; j < series.length; j += 1) { + serieList += ` + ${Albums.replaceSpecialChars(series[j].name)} + ${Albums.replaceSpecialChars(series[j].catno)} + ${Albums.replaceSpecialChars( + series[j].entity_type + )} + ${Albums.replaceSpecialChars( + series[j].entity_type_name + )} + ${Albums.replaceSpecialChars(series[j].id)} + ${Albums.replaceSpecialChars( + series[j].resource_url + )} + ${Albums.replaceSpecialChars( + series[j].thumbnail_url + )} + + `; + } + + for (let j = 0; j < companies.length; j += 1) { + companiesList += ` + ${Albums.replaceSpecialChars(companies[j].name)} + ${Albums.replaceSpecialChars(companies[j].catno)} + ${Albums.replaceSpecialChars( + companies[j].entity_type + )} + ${Albums.replaceSpecialChars( + companies[j].entity_type_name + )} + ${Albums.replaceSpecialChars(companies[j].id)} + ${Albums.replaceSpecialChars( + companies[j].resource_url + )} + ${Albums.replaceSpecialChars( + companies[j].thumbnail_url + )} + + `; + } + + for (let j = 0; j < formats.length; j += 1) { + let descriptions = ""; + if (formats[j].descriptions) { + for ( + let k = 0; + k < formats[j].descriptions.length; + k += 1 + ) { + descriptions += `${formats[j].descriptions[k]} + `; + } + } + formatsList += ` + ${Albums.replaceSpecialChars(formats[j].name)} + ${Albums.replaceSpecialChars(formats[j].qty)} + ${Albums.replaceSpecialChars(formats[j].text)} + + ${descriptions} + + + `; + } + + for (let j = 0; j < identifiers.length; j += 1) { + identifiersList += ` + ${Albums.replaceSpecialChars(identifiers[j].type)} + ${Albums.replaceSpecialChars( + identifiers[j].value + )} + ${Albums.replaceSpecialChars( + identifiers[j].description + )} + + `; + } + + for (let j = 0; j < videos.length; j += 1) { + videosList += ` + `; + } + + for (let j = 0; j < genres.length; j += 1) { + genresList += `${Albums.replaceSpecialChars( + genres[j] + )} + `; + } + + for (let j = 0; j < styles.length; j += 1) { + stylesList += ` + `; + } + + for (let j = 0; j < tracklist.length; j += 1) { + tracklistList += ` + ${Albums.replaceSpecialChars(tracklist[j].title)} + + `; + } + + for (let j = 0; j < extraartists.length; j += 1) { + extraartistsList += ` + ${Albums.replaceSpecialChars(extraartists[j].name)} + ${Albums.replaceSpecialChars(extraartists[j].anv)} + ${Albums.replaceSpecialChars(extraartists[j].join)} + ${Albums.replaceSpecialChars(extraartists[j].role)} + ${Albums.replaceSpecialChars( + extraartists[j].tracks + )} + ${Albums.replaceSpecialChars(extraartists[j].id)} + ${Albums.replaceSpecialChars( + extraartists[j].resource_url + )} + ${Albums.replaceSpecialChars( + extraartists[j].thumbnail_url + )} + + `; + } + + for (let j = 0; j < images.length; j += 1) { + imagesList += ` + ${Albums.replaceSpecialChars(images[j].uri)} + ${Albums.replaceSpecialChars( + images[j].resource_url + )} + ${Albums.replaceSpecialChars( + images[j].resource_url + )} + + `; + } + + data += ` + + ${discogsId} + ${Albums.replaceSpecialChars(title)} + ${Albums.replaceSpecialChars(artists_sort)} + + ${artistsList} + + ${year} + ${Albums.replaceSpecialChars(country)} + ${released} + ${uri} + ${thumb} + + ${labelList} + + + ${serieList} + + + ${companiesList} + + + ${formatsList} + + ${Albums.replaceSpecialChars(notes)} + + ${identifiersList} + + + ${videosList} + + + ${genresList} + + + ${stylesList} + + + ${tracklistList} + + + ${extraartistsList} + + + ${imagesList} + + `; + } + + return `${data}`; + } + + /** + * Méthode permettant de convertir les rows en csv pour importer dans MusicTopus + * @param {Array} rows + * + * @return {string} + */ + static async convertToMusicTopus(rows) { + let data = "itemId;createdAt;updatedAt\n\r"; + + for (let i = 0; i < rows.length; i += 1) { + const { discogsId, createdAt, updatedAt } = rows[i]; + + data += `${discogsId};${createdAt};${updatedAt}\n\r`; + } + + data += "v1.0"; + + return data; + } + /** * Méthode permettant d'ajouter un album dans une collection * @param {Object} req @@ -59,16 +506,15 @@ class Albums extends Pages { */ async getAll() { const { - page = 1, - limit = 4, + page, + limit, + exportFormat = "json", sort = "artists_sort", order = "asc", artists_sort, format, } = this.req.query; - const skip = (page - 1) * limit; - const where = {}; if (artists_sort) { @@ -83,25 +529,47 @@ class Albums extends Pages { ...where, }); + let params = { + sort: { + [sort]: order.toLowerCase() === "asc" ? 1 : -1, + }, + }; + + if (page && limit) { + const skip = (page - 1) * limit; + + params = { + ...params, + skip, + limit, + }; + } + const rows = await AlbumsModel.find( { user: this.req.user._id, ...where, }, [], - { - skip, - limit, - sort: { - [sort]: order.toLowerCase() === "asc" ? 1 : -1, - }, - } + params ); - return { - rows, - count, - }; + switch (exportFormat) { + case "csv": + return Albums.convertToCsv(rows); + case "xls": + return Albums.convertToXls(rows); + case "xml": + return Albums.convertToXml(rows); + case "musictopus": + return Albums.convertToMusicTopus(rows); + case "json": + default: + return { + rows, + count, + }; + } } /** @@ -137,6 +605,20 @@ class Albums extends Pages { this.setPageContent("artists", artists); this.setPageContent("formats", formats); } + + /** + * Méthode permettant d'afficher le détails d'un album + */ + async loadItem() { + const { itemId: _id } = this.req.params; + const { _id: User } = this.req.user; + const item = await AlbumsModel.findOne({ + _id, + User, + }); + + this.setPageContent("item", item); + } } export default Albums; diff --git a/src/routes/api/v1/albums.js b/src/routes/api/v1/albums.js index 5d0c68c..164ea40 100644 --- a/src/routes/api/v1/albums.js +++ b/src/routes/api/v1/albums.js @@ -13,10 +13,24 @@ router try { const albums = new Albums(req); const data = await albums.getAll(); + const { exportFormat = "json" } = req.query; - sendResponse(req, res, data); + switch (exportFormat) { + case "csv": + case "musictopus": + res.header("Content-Type", "text/csv"); + return res.status(200).send(data); + case "xml": + res.header("Content-type", "text/xml"); + return res.status(200).send(data); + case "xls": + return data.write("musictopus.xls", res); + case "json": + default: + return sendResponse(req, res, data); + } } catch (err) { - next(err); + return next(err); } }) .post(ensureLoggedIn("/connexion"), async (req, res, next) => { diff --git a/src/routes/index.js b/src/routes/index.js index 8a340a0..95c9a45 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -4,7 +4,6 @@ import { ensureLoggedIn } from "connect-ensure-login"; import Pages from "../middleware/Pages"; import Auth from "../middleware/Auth"; -import Albums from "../middleware/Albums"; import render from "../libs/format"; @@ -89,24 +88,6 @@ router } }); -router - .route("/ma-collection") - .get(ensureLoggedIn("/connexion"), async (req, res, next) => { - try { - const page = new Albums(req, "mon-compte/ma-collection"); - - await page.loadMyCollection(); - - if (page.getPageContent("artists").length > 0) { - render(res, page); - } else { - res.redirect("/ajouter-un-album"); - } - } catch (err) { - next(err); - } - }); - router.route("/nous-contacter").get(async (req, res, next) => { try { const page = new Pages(req, "nous-contacter"); diff --git a/src/routes/ma-collection.js b/src/routes/ma-collection.js new file mode 100644 index 0000000..51ff0ee --- /dev/null +++ b/src/routes/ma-collection.js @@ -0,0 +1,53 @@ +import express from "express"; +import { ensureLoggedIn } from "connect-ensure-login"; + +import Albums from "../middleware/Albums"; + +import render from "../libs/format"; + +// eslint-disable-next-line new-cap +const router = express.Router(); + +router.route("/").get(ensureLoggedIn("/connexion"), async (req, res, next) => { + try { + const page = new Albums(req, "mon-compte/ma-collection"); + + await page.loadMyCollection(); + + if (page.getPageContent("artists").length > 0) { + render(res, page); + } else { + res.redirect("/ajouter-un-album"); + } + } catch (err) { + next(err); + } +}); + +router + .route("/exporter") + .get(ensureLoggedIn("/connexion"), async (req, res, next) => { + try { + const page = new Albums(req, "mon-compte/ma-collection/exporter"); + + render(res, page); + } catch (err) { + next(err); + } + }); + +router + .route("/:itemId") + .get(ensureLoggedIn("/connexion"), async (req, res, next) => { + try { + const page = new Albums(req, "mon-compte/ma-collection/details"); + + await page.loadItem(); + + render(res, page); + } catch (err) { + next(err); + } + }); + +export default router; diff --git a/views/index.ejs b/views/index.ejs index 8d2364f..ddf0b8c 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -68,6 +68,9 @@ Ma collection + + Exporter ma collection + <% } %> diff --git a/views/pages/ajouter-un-album.ejs b/views/pages/ajouter-un-album.ejs index 8a26488..bdebb4e 100644 --- a/views/pages/ajouter-un-album.ejs +++ b/views/pages/ajouter-un-album.ejs @@ -52,12 +52,12 @@ -