diff --git a/README.md b/README.md index b4afae2..6879770 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ LISTS_PUBLIC=false TABLE=true # Allow Markdown in item notes. Does not work with TABLE=false. Defaults to false. MARKDOWN=false +# Auto archive pledges +AUTO_ARCHIVE_PLEDGES=false ## Custom HTML Snippets # These are inserted into specific locations in the relevant page @@ -154,7 +156,6 @@ MARKDOWN=false # OIDC_ISSUER=https://accounts.google.com # OIDC_PROVIDER_NAME=Google - # Profile picture upload max size in MB UPLOAD_PFP_MAX_SIZE=5 ``` diff --git a/package.json b/package.json index afab656..c5f61c4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "dev": "nodemon --watch src -e ts,js --exec 'npm run build && node built/index.js'", "postinstall": "node postinstall.cjs", "build": "tsc", - "release": "docker buildx build . --platform linux/amd64,linux/arm64 -t wingysam/christmas-community -t wingysam/christmas-community:$(./node_modules/node-jq/bin/jq -r .version < package.json) --push" + "release": "docker buildx build . --platform linux/amd64,linux/arm64 -t wingysam/christmas-community -t wingysam/christmas-community:$(./node_modules/node-jq/bin/jq -r .version < package.json) --push", + "lint": "eslint src && prettier . --write" }, "author": "Wingysam ", "license": "AGPL-3.0", diff --git a/src/config/index.ts b/src/config/index.ts index 5d48759..6bd092e 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -39,6 +39,7 @@ const config = { oidcEnabled: false, pfpUploadMaxSize: process.env.UPLOAD_PFP_MAX_SIZE || 5, rootUrl: appendSlash(process.env.ROOT_URL ?? process.env.ROOT_PATH ?? '/'), + autoArchivePledges: process.env.AUTO_ARCHIVE_PLEDGES === 'true', base: '', // automatically set below } diff --git a/src/languages/en-us.ts b/src/languages/en-us.ts index 30aed8e..adf8dfd 100644 --- a/src/languages/en-us.ts +++ b/src/languages/en-us.ts @@ -239,6 +239,15 @@ export const strings = { WISHLIST_URL_LABEL: `Item URL or Name (Supported Sites)`, WISHLIST_URL_PLACEHOLDER: 'https://www.amazon.com/dp/B00ZV9RDKK', WISHLIST_URL_REQUIRED: 'Item URL or Name is required', + WISHLIST_ARCHIVE: 'Archive', + WISHLIST_RESTORE: 'Restore', + WISHLIST_ARCHIVED_ITEMS: 'Archived Items', + WISHLIST_ARCHIVE_SUCCESS: 'Successfully archived item.', + WISHLIST_RESTORE_SUCCESS: 'Successfully restored item.', + WISHLIST_ARCHIVE_GUARD: 'You are not allowed to archive this item', + WISHLIST_RESTORE_GUARD: 'You are not allowed to restore this item', + WISHLIST_DELETE_CONFIRM: 'Are you sure you want to delete this item?', + WISHLIST_ITEM_OPTIONS: 'Options', WISHLISTS_COUNTS_SELF: (name) => `${name}: ???/???`, WISHLISTS_COUNTS: (name, pledged, total) => `${name}: ${pledged}/${total}`, WISHLISTS_TITLE: `${_CC.config.siteTitle} - Wishlists`, diff --git a/src/routes/wishlist/index.js b/src/routes/wishlist/index.js index 6c2b465..325e3ea 100644 --- a/src/routes/wishlist/index.js +++ b/src/routes/wishlist/index.js @@ -12,11 +12,15 @@ const DOMPurify = createDOMPurify(window) const totals = (wishlist) => { let unpledged = 0 let pledged = 0 + let active = 0 + let archived = 0 wishlist.forEach((wishItem) => { if (wishItem.pledgedBy) pledged += 1 else unpledged += 1 + if (wishItem.archived) archived += 1 + else active += 1 }) - return { unpledged, pledged } + return { unpledged, pledged, active, archived } } export default function (db) { @@ -31,6 +35,7 @@ export default function (db) { if (row.doc.admin) return res.redirect(`/wishlist/${row.doc._id}`) } } + console.log(docs) res.render('wishlists', { title: _CC.lang('WISHLISTS_TITLE'), users: docs.rows, @@ -106,7 +111,6 @@ export default function (db) { } catch (error) { req.flash('error', `${error}`) } - res.redirect(`/wishlist/${req.params.user}`) }) @@ -253,5 +257,47 @@ export default function (db) { res.redirect(`/wishlist/${req.params.user}/note/${req.params.id}`) }) + router.post('/:user/archive/:itemId', verifyAuth(), async (req, res) => { + try { + const wishlist = await wishlistManager.get(req.params.user) + const item = await wishlist.get(req.params.itemId) + + const isOwnWishlist = req.user._id === wishlist.username + const addedByUser = item.addedBy === req.user._id + if (!isOwnWishlist && !addedByUser) { + throw new Error(_CC.lang('WISHLIST_ARCHIVE_GUARD')) + } + + await wishlist.archive(item.id) + + req.flash('success', _CC.lang('WISHLIST_ARCHIVE_SUCCESS')) + } catch (error) { + req.flash('error', `${error}`) + } + + res.redirect(`/wishlist/${req.params.user}`) + }) + + router.post('/:user/restore/:itemId', verifyAuth(), async (req, res) => { + try { + const wishlist = await wishlistManager.get(req.params.user) + const item = await wishlist.get(req.params.itemId) + + const isOwnWishlist = req.user._id === wishlist.username + const addedByUser = item.addedBy === req.user._id + if (!isOwnWishlist && !addedByUser) { + throw new Error(_CC.lang('WISHLIST_RESTORE_GUARD')) + } + + await wishlist.restore(item.id) + + req.flash('success', _CC.lang('WISHLIST_RESTORE_SUCCESS')) + } catch (error) { + req.flash('error', `${error}`) + } + + res.redirect(`/wishlist/${req.params.user}`) + }) + return router } diff --git a/src/static/css/main.css b/src/static/css/main.css index 2897dd4..2ac4559 100644 --- a/src/static/css/main.css +++ b/src/static/css/main.css @@ -112,3 +112,55 @@ img.logo-image { .print-gift:last-child { margin-bottom: 0; } + +summary { + font-weight: bold; + font-size: 18px; +} + +summary:hover { + cursor: pointer; +} + +.hamburger { + font-size: 24px; + background: none; + border: none; + cursor: pointer; +} + +.hidden-menu { + display: none; + margin-top: 10px; +} + +.hidden-menu button { + display: block; + margin: 5px 0; +} + +.hidden-menu.active { + display: block; +} + +button.button.dropdown-item.is-text { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + width: 100%; + text-align: left; + padding-right: 10px; /* extra Spacing to push icons to the right a bunch */ + text-decoration: none; +} + +/* Ensure the text stays left-aligned */ +button.button.dropdown-item.is-text span { + grid-column: 1; + text-align: left; +} + +/* Ensure the icon is pulled to the right */ +button.button.dropdown-item.is-text i { + grid-column: 3; + margin-left: auto; +} diff --git a/src/static/js/wishlist.js b/src/static/js/wishlist.js index 1f04a4c..79806e3 100644 --- a/src/static/js/wishlist.js +++ b/src/static/js/wishlist.js @@ -163,3 +163,8 @@ document.addEventListener('DOMContentLoaded', () => { updateArrow('price', sortBy) }) }) + +function _toggleMenu(button) { + const menu = button.nextElementSibling + menu.classList.toggle('active') +} diff --git a/src/structures/Wishlist.js b/src/structures/Wishlist.js index 3866fa3..886dd11 100644 --- a/src/structures/Wishlist.js +++ b/src/structures/Wishlist.js @@ -97,6 +97,10 @@ export class Wishlist { async pledge(id, user) { const item = await this.get(id) item.pledgedBy = user + + if (_CC.config.autoArchivePledges) { + item.archived = true + } await this.save() } @@ -183,6 +187,18 @@ export class Wishlist { await this.save() } + + async archive(id) { + const item = await this.get(id) + item.archived = true + await this.save() + } + + async restore(id) { + const item = await this.get(id) + item.archived = false + await this.save() + } } function parseURL(string) { diff --git a/src/views/wishlist.pug b/src/views/wishlist.pug index 47d8a1b..7c8c259 100644 --- a/src/views/wishlist.pug +++ b/src/views/wishlist.pug @@ -6,253 +6,216 @@ mixin sharedInfoProp(key, label) th= lang(label) td= sharedInfo[key] -block title - h1 - .level - .level-left - .level-item - button.button.is-rounded(onclick='this.firstChild.firstChild.classList.add("fa-pulse"); location.reload()') - span.icon - i.fas.fa-sync-alt - .level-item - span= lang('WISHLIST_TITLE', name) - .level-right - .level-item - a(href="#addWishlistItem").button.button.is-primary.is-rounded - span.icon - i.fas.fa-plus - span= lang('WISHLIST_ADD_NEW') - - -block content - script(type='data/user_id')= req.user._id - table.table(style='width: fit-content;') - tbody - +sharedInfoProp('shoeSize', 'PROFILE_SHOE_SIZE') - +sharedInfoProp('ringSize', 'PROFILE_RING_SIZE') - +sharedInfoProp('dressSize', 'PROFILE_DRESS_SIZE') - +sharedInfoProp('sweaterSize', 'PROFILE_SWEATER_SIZE') - +sharedInfoProp('shirtSize', 'PROFILE_SHIRT_SIZE') - +sharedInfoProp('pantsSize', 'PROFILE_PANTS_SIZE') - +sharedInfoProp('coatSize', 'PROFILE_COAT_SIZE') - +sharedInfoProp('hatSize', 'PROFILE_HAT_SIZE') - +sharedInfoProp('phoneModel', 'PROFILE_PHONE_MODEL') - if global._CC.config.wishlist.table - .box - table.table.has-mobile-cards#wishlist-table - thead - th # - th(style='width: 15%;')= lang('WISHLIST_IMAGE') - th(style='width: 25%;')= lang('WISHLIST_NAME') - th(style='width: 50%;')= lang('WISHLIST_NOTE') - th(style='width: 10%; cursor: pointer') - a(href="#", id="sort-price")= lang('WISHLIST_PRICE') - |  - span#price-arrow - th= lang('WISHLIST_EDIT_ITEM') - th= lang('WISHLIST_ADDED_BY') - if req.params.user === req.user._id - th= lang('WISHLIST_MOVE_TOP') - th= lang('WISHLIST_MOVE_UP') - th= lang('WISHLIST_MOVE_DOWN') - th= lang('WISHLIST_MOVE_BOTTOM') - else - th= lang('WISHLIST_PLEDGE') - th= lang('WISHLIST_DELETE') - tbody.wishlist-items - each item, index in items - tr(id=item.id) - td.rank= index + 1 - td - figure(style='width: 100%; margin: 0;') - img(src=item.image, style='width: 100%; max-height: 20em; object-fit: contain;') - if item.url - td.ugc(data-label=lang('WISHLIST_NAME')) - if item.pledgedBy && item.addedBy != req.user._id - strike - a( - href=item.url, - rel='noopener noreferrer', - target='_blank' - )= (item.name ? item.name : item.url) - else - a( - href=item.url, - rel='noopener noreferrer', - target='_blank' - )= (item.name ? item.name : item.url) - else - td.ugc(data-label='Name') - if item.pledgedBy && item.addedBy != req.user._id - strike - span= item.name - else +mixin wishlistTable(items, archived) + .box + table.table.has-mobile-cards + thead + th # + th(style='width: 10%;')= lang('WISHLIST_IMAGE') + th(style='width: 20%;')= lang('WISHLIST_NAME') + th(style='width: 30%;')= lang('WISHLIST_NOTE') + th(style='width: 10%;')= lang('WISHLIST_PRICE') + th= lang('WISHLIST_ADDED_BY') + if !(req.params.user === req.user._id) + th(style='width: 10%;')= lang('WISHLIST_PLEDGE') + else + th(style='width: 10%;')= lang('WISHLIST_ITEM_OPTIONS') + tbody + each item, index in items + tr(id=item.id) + td.rank= index + 1 + td + figure(style='width: 100%; margin: 0;') + img(src=item.image, style='width: 100%; max-height: 20em; object-fit: contain;') + if item.url + td.ugc(data-label=lang('WISHLIST_NAME')) + if item.pledgedBy && item.addedBy != req.user._id + strike + a( + href=item.url, + rel='noopener noreferrer', + target='_blank' + )= (item.name ? item.name : item.url) + else + a( + href=item.url, + rel='noopener noreferrer', + target='_blank' + )= (item.name ? item.name : item.url) + else + td.ugc(data-label='Name') + if item.pledgedBy && item.addedBy != req.user._id + strike span= item.name - if _CC.config.wishlist.note.markdown - td.ugc(data-label=lang('WISHLIST_NOTE')) - div!= compiledNotes[item.id] - else - td.ugc(data-label=lang('WISHLIST_NOTE'))= item.note - td.price.ugc(data-label=lang('WISHLIST_PRICE'))= item.price - td(data-label=lang('WISHLIST_EDIT_ITEM')) - form.inline(method='GET', action=`${_CC.config.base}wishlist/${req.params.user}/note/${item.id}`) - .field.inline - .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;' - disabled=item.addedBy !== req.user._id - ) - span.icon - i.far.fa-edit - if item.addedBy === '_CCUNKNOWN' - td.ugc(data-label=lang('WISHLIST_ADDED_BY'))= lang('WISHLIST_ADDED_BY_GUEST') - else - td.ugc(data-label=lang('WISHLIST_ADDED_BY'))= item.addedBy - if req.params.user === req.user._id - td(data-label=lang('WISHLIST_MOVE_ITEM_TOP')) - form.topForm.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/top/${item.id}`) + else + span= item.name + if _CC.config.wishlist.note.markdown + td.ugc(data-label=lang('WISHLIST_NOTE')) + div!= compiledNotes[item.id] + else + td.ugc(data-label=lang('WISHLIST_NOTE'))= item.note + td.ugc(data-label=lang('WISHLIST_PRICE'))= item.price + if item.addedBy === '_CCUNKNOWN' + td.ugc(data-label=lang('WISHLIST_ADDED_BY'))= lang('WISHLIST_ADDED_BY_GUEST') + else + td.ugc(data-label=lang('WISHLIST_ADDED_BY'))= item.addedBy + if !(req.params.user === req.user._id) + td(data-label=lang('WISHLIST_PLEDGE')) + if req.params.user !== req.user._id && !item.pledgedBy && !item.archived + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/pledge/${item.id}`) .field.inline .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;', - disabled=index === 0 - ) - span.icon - i.fas.fa-angle-double-up - td(data-label=lang('WISHLIST_MOVE_ITEM_UP')) - form.upForm.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/up/${item.id}`) + input.inline.button.is-primary(type='submit' value=lang('WISHLIST_PLEDGE_ITEM')) + if item.pledgedBy === req.user._id + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/unpledge/${item.id}`) .field.inline .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;', - disabled=index === 0 + input.inline.button(type='submit' value=lang('WISHLIST_UNPLEDGE')) + if item.pledgedBy && item.pledgedBy !== req.user._id + if item.pledgedBy === '_CCUNKNOWN' + span.ugc=lang('WISHLIST_PLEDGED_GUEST') + else + span.ugc=lang('WISHLIST_PLEDGED', item.pledgedBy) + if req.params.user === req.user._id + td(data-label=lang('WISHLIST_ITEM_OPTIONS')) + div.dropdown.is-right.is-hoverable + div.dropdown-trigger + button.button.is-primary( + aria-haspopup='true', + aria-controls=`dropdown-menu${index}` + ) + span.icon + i.fas.fa-cog + div.dropdown-menu(id=`dropdown-menu${index}`, role='menu') + div.dropdown-content + form.inline(method='GET', action=`${_CC.config.base}wishlist/${req.params.user}/note/${item.id}`) + button.button.dropdown-item.is-text( + type='submit' ) - span.icon + span= lang('WISHLIST_EDIT_ITEM') + i.far.fa-edit + + if !archived + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/up/${item.id}`) + button.button.dropdown-item.is-text( + type='submit', + disabled=index === 0 + ) + span= lang('WISHLIST_MOVE_ITEM_UP') i.fas.fa-arrow-up - td(data-label=lang('WISHLIST_MOVE_ITEM_DOWN')) - form.downForm.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/down/${item.id}`) - .field.inline - .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;', - disabled=index === items.length - 1 - ) - span.icon + + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/down/${item.id}`) + button.button.dropdown-item.is-text( + type='submit', + disabled=index === items.length - 1 + ) + span= lang('WISHLIST_MOVE_ITEM_DOWN') i.fas.fa-arrow-down - td(data-label=lang('WISHLIST_MOVE_ITEM_BOTTOM')) - form.bottomForm.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/bottom/${item.id}`) - .field.inline - .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;', - disabled=index === items.length - 1 - ) - span.icon + + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/top/${item.id}`) + button.button.dropdown-item.is-text( + type='submit', + disabled=index === 0 + ) + span= lang('WISHLIST_MOVE_ITEM_TOP') + i.fas.fa-angle-double-up + + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/bottom/${item.id}`) + button.button.dropdown-item.is-text( + type='submit', + disabled=index === items.length - 1 + ) + span= lang('WISHLIST_MOVE_ITEM_BOTTOM') i.fas.fa-angle-double-down - else - td(data-label=lang('WISHLIST_PLEDGE')) - if req.params.user !== req.user._id && !item.pledgedBy - form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/pledge/${item.id}`) - .field.inline - .control.inline - input.inline.button.is-primary(type='submit' value=lang('WISHLIST_PLEDGE_ITEM')) - if item.pledgedBy === req.user._id - form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/unpledge/${item.id}`) - .field.inline - .control.inline - input.inline.button(type='submit' value=lang('WISHLIST_UNPLEDGE')) - if item.pledgedBy && item.pledgedBy !== req.user._id - if item.pledgedBy === '_CCUNKNOWN' - span.ugc=lang('WISHLIST_PLEDGED_GUEST') - else - span.ugc=lang('WISHLIST_PLEDGED', item.pledgedBy) - td(data-label='Delete Item') - form.inline( - method='POST', - action=`${_CC.config.base}wishlist/${req.params.user}/remove/${item.id}` - ) - .field.inline - .control.inline - button.button.is-text( - type='submit', - style='text-decoration: none;', - disabled=item.addedBy !== req.user._id - ) - span.icon - i.fas.fa-trash + + hr.dropdown-divider + if !archived + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/archive/${item.id}`) + button.button.dropdown-item.is-text.has-text-danger( + type='submit' + ) + span= lang('WISHLIST_ARCHIVE') + i.fas.fa-archive + else + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/restore/${item.id}`) + button.button.dropdown-item.is-text.has-text-danger( + type='submit' + ) + span= lang('WISHLIST_RESTORE') + i.fas.fa-restore + - else - each item, index in items - if req.user._id === item.addedBy || req.params.user !== req.user._id - .box +mixin wishlistBox(items, archived) + each item, index in items + if req.user._id === item.addedBy || req.params.user !== req.user._id + .box + if item.price + .tag + i.fas.fa-tag(style='margin-right: .5em;') + span= item.price + span.overflowWrap if item.price - .tag - i.fas.fa-tag(style='margin-right: .5em;') - span= item.price - span.overflowWrap - if item.price - span= ' ' - if item.url - if item.pledgedBy && item.addedBy != req.user._id - strike - a( - href=item.url, - rel='noopener noreferrer', - target='_blank' - )= (item.name ? item.name : item.url) - else + span= ' ' + if item.url + if item.pledgedBy && item.addedBy != req.user._id + strike a( href=item.url, rel='noopener noreferrer', target='_blank' )= (item.name ? item.name : item.url) else - if item.pledgedBy && item.addedBy != req.user._id - strike - span= item.name - else + a( + href=item.url, + rel='noopener noreferrer', + target='_blank' + )= (item.name ? item.name : item.url) + else + if item.pledgedBy && item.addedBy != req.user._id + strike span= item.name - hr - if item.note || item.image - .columns - if item.image - .column - figure(style='width: 100%; padding: 2em;') - img(src=item.image, style='width: 100%;') - .column.is-three-quarters - if item.note - textarea.textarea.has-fixed-size( - style='height: 100%;' - readonly - )= item.note - span.overflowWrap=lang('WISHLIST_ADDED_BY_USER', item.addedBy) - hr - div - if req.params.user !== req.user._id && !item.pledgedBy - form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/pledge/${item.id}`) - .field.inline - .control.inline - input.inline.button.is-primary(type='submit' value=lang('WISHLIST_PLEDGE')) - if item.pledgedBy === req.user._id - form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/unpledge/${item.id}`) - .field.inline - .control.inline - input.inline.button(type='submit' value=lang('WISHLIST_UNPLEDGE')) - if req.user._id === req.params.user - form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/remove/${item.id}`) - .field.inline - .control.inline - input.inline.button.is-warning(type='submit' value=lang('WISHLIST_DELETE')) - if req.user._id === req.params.user || req.user._id === item.addedBy - form.inline(method='GET', action=`${_CC.config.base}wishlist/${req.params.user}/note/${item.id}`) - .field.inline - .control.inline - input.inline.button(type='submit', value=lang('WISHLIST_EDIT_ITEM')) + else + span= item.name + hr + if item.note || item.image + .columns + if item.image + .column + figure(style='width: 100%; padding: 2em;') + img(src=item.image, style='width: 100%;') + .column.is-three-quarters + if item.note + textarea.textarea.has-fixed-size( + style='height: 100%;' + readonly + )= item.note + if item.addedBy === '_CCUNKNOWN' + span.overflowWrap=lang('WISHLIST_ADDED_BY', lang('WISHLIST_ADDED_BY_GUEST')) + else + span.overflowWrap=lang('WISHLIST_ADDED_BY', item.addedBy) + hr + div + if req.params.user !== req.user._id && !item.pledgedBy + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/pledge/${item.id}`) + .field.inline + .control.inline + input.inline.button.is-primary(type='submit' value=lang('WISHLIST_PLEDGE')) + if item.pledgedBy === req.user._id + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/unpledge/${item.id}`) + .field.inline + .control.inline + input.inline.button(type='submit' value=lang('WISHLIST_UNPLEDGE')) + if req.user._id === req.params.user + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/remove/${item.id}`, onsubmit=`return confirm("${lang('WISHLIST_DELETE_CONFIRM')}")`) + .field.inline + .control.inline + input.inline.button.is-danger(type='submit' value=lang('WISHLIST_DELETE')) + if req.user._id === req.params.user || req.user._id === item.addedBy + form.inline(method='GET', action=`${_CC.config.base}wishlist/${req.params.user}/note/${item.id}`) + .field.inline + .control.inline + input.inline.button(type='submit', value=lang('WISHLIST_EDIT_ITEM')) + if !archived if index !== 0 && req.user._id === req.params.user form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/move/up/${item.id}`) .field.inline @@ -268,6 +231,56 @@ block content .field.inline .control.inline input.inline.button(type='submit' value=lang('WISHLIST_MOVE_ITEM_BOTTOM')) + if req.user._id === req.params.user + if !archived + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/archive/${item.id}`) + .field.inline + .control.inline + input.inline.button.is-warning(type='submit' value=lang('WISHLIST_ARCHIVE')) + else + form.inline(method='POST', action=`${_CC.config.base}wishlist/${req.params.user}/restore/${item.id}`) + .field.inline + .control.inline + input.inline.button.is-success(type='submit' value=lang('WISHLIST_RESTORE')) + +block title + h1 + .level + .level-left + .level-item + button.button.is-rounded(onclick='this.firstChild.firstChild.classList.add("fa-pulse"); location.reload()') + span.icon + i.fas.fa-sync-alt + .level-item + span= lang('WISHLIST_TITLE', name) + .level-right + .level-item + a(href="#addWishlistItem").button.button.is-primary.is-rounded + span.icon + i.fas.fa-plus + span= lang('WISHLIST_ADD_NEW') + + +block content + script(type='data/user_id')= req.user._id + table.table(style='width: fit-content;') + tbody + +sharedInfoProp('shoeSize', 'PROFILE_SHOE_SIZE') + +sharedInfoProp('ringSize', 'PROFILE_RING_SIZE') + +sharedInfoProp('dressSize', 'PROFILE_DRESS_SIZE') + +sharedInfoProp('sweaterSize', 'PROFILE_SWEATER_SIZE') + +sharedInfoProp('shirtSize', 'PROFILE_SHIRT_SIZE') + +sharedInfoProp('pantsSize', 'PROFILE_PANTS_SIZE') + +sharedInfoProp('coatSize', 'PROFILE_COAT_SIZE') + +sharedInfoProp('hatSize', 'PROFILE_HAT_SIZE') + +sharedInfoProp('phoneModel', 'PROFILE_PHONE_MODEL') + + if global._CC.config.wishlist.table + +wishlistTable(items.filter(item => !item.archived), false) + else + +wishlistBox(items.filter(item => !item.archived), false) + + br form(method='POST')#addWishlistItem .field label.label!=lang('WISHLIST_URL_LABEL') @@ -293,6 +306,13 @@ block content .control input.inline.button(type='submit', value=lang('WISHLIST_SUGGEST'), name='suggest') script(src=`${_CC.config.base}js/wishlist.js`) + br + details + summary= lang('WISHLIST_ARCHIVED_ITEMS') + if global._CC.config.wishlist.table + +wishlistTable(items.filter(item => item.archived), true) + else + +wishlistBox(items.filter(item => item.archived), true) block print h1 #{req.params.user}'s Wishlist diff --git a/src/views/wishlists.pug b/src/views/wishlists.pug index 45f3903..6da89e3 100644 --- a/src/views/wishlists.pug +++ b/src/views/wishlists.pug @@ -8,7 +8,7 @@ mixin wishlistDetails(wishlist, onlyShowAddedByUser) i.fas.fa-chevron-down ul.wishlist-dropdown for item in wishlist - if onlyShowAddedByUser === undefined || item.addedBy === onlyShowAddedByUser + if (!item.archived && onlyShowAddedByUser === undefined) || item.addedBy === onlyShowAddedByUser li if item.pledgedBy && !onlyShowAddedByUser strike= item.name @@ -77,8 +77,8 @@ block content figure.image.is-square.is-fullwidth.is-marginless(style='display: inline-block;') img.is-rounded.is-fullwidth(src=_CC.getUrlForPfp(user.doc.pfp), style='object-fit: cover;') .column - span= lang('WISHLISTS_COUNTS', user.id, totals(user.doc.wishlist).pledged, user.doc.wishlist.length) - progress.progress.is-info(value=totals(user.doc.wishlist).pledged, max=user.doc.wishlist.length) + span= lang('WISHLISTS_COUNTS', user.id, totals(user.doc.wishlist).pledged, totals(user.doc.wishlist).active) + progress.progress.is-info(value=totals(user.doc.wishlist).pledged, max=totals(user.doc.wishlist).active) +wishlistDetails(user.doc.wishlist) script. document.querySelectorAll('.wishlist-dropdown-button')