diff --git a/assets/images/bg.jpg b/assets/images/bg.jpg new file mode 100644 index 00000000..d601fcfe Binary files /dev/null and b/assets/images/bg.jpg differ diff --git a/assets/images/bg_1.jpg b/assets/images/bg_1.jpg deleted file mode 100644 index 1b85b7f0..00000000 Binary files a/assets/images/bg_1.jpg and /dev/null differ diff --git a/assets/images/bg_2.jpg b/assets/images/bg_2.jpg deleted file mode 100644 index df2c53be..00000000 Binary files a/assets/images/bg_2.jpg and /dev/null differ diff --git a/assets/images/bg_3.jpg b/assets/images/bg_3.jpg deleted file mode 100644 index 04be9fe7..00000000 Binary files a/assets/images/bg_3.jpg and /dev/null differ diff --git a/client/index.js b/client/index.js index 48f04872..7f5c2c19 100644 --- a/client/index.js +++ b/client/index.js @@ -1,17 +1,4 @@ 'use strict' -let logic = document.documentElement.dataset.logic - -switch (logic) { - case 'error': - require('./scss/error.scss') - break - case 'login': - require('./scss/login.scss') - require('./js/login.js') - break - default: - require('./scss/app.scss') - require('./js/app.js') - break -} +require('./scss/app.scss') +require('./js/app.js') diff --git a/client/js/app.js b/client/js/app.js index 7c4b5899..00991909 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -1,28 +1,21 @@ 'use strict' -/* global $, siteRoot */ +/* global siteConfig */ /* eslint-disable no-new */ import Vue from 'vue' import VueResource from 'vue-resource' import VueClipboards from 'vue-clipboards' -import VueLodash from 'vue-lodash' import store from './store' -import io from 'socket-io-client' import i18next from 'i18next' import i18nextXHR from 'i18next-xhr-backend' import VueI18Next from '@panter/vue-i18next' -import 'jquery-contextmenu' -import 'jquery-simple-upload' -import 'jquery-smooth-scroll' -import 'jquery-sticky' // ==================================== // Load Helpers // ==================================== import helpers from './helpers' -import _ from './helpers/lodash' // ==================================== // Load Vue Components @@ -63,7 +56,6 @@ import sourceViewComponent from './pages/source-view.component.js' Vue.use(VueResource) Vue.use(VueClipboards) Vue.use(VueI18Next) -Vue.use(VueLodash, _) Vue.use(helpers) // ==================================== @@ -105,39 +97,27 @@ i18next .use(i18nextXHR) .init({ backend: { - loadPath: siteRoot + '/js/i18n/{{lng}}.json' + loadPath: siteConfig.path + '/js/i18n/{{lng}}.json' }, - lng: siteLang, - fallbackLng: siteLang + lng: siteConfig.lang, + fallbackLng: siteConfig.lang }) -$(() => { +document.addEventListener('DOMContentLoaded', ev => { // ==================================== // Notifications // ==================================== - $(window).bind('beforeunload', () => { + window.addEventListener('beforeunload', () => { store.dispatch('startLoading') }) - $(document).ajaxSend(() => { - store.dispatch('startLoading') - }).ajaxComplete(() => { - store.dispatch('stopLoading') - }) - - // ==================================== - // Establish WebSocket connection - // ==================================== - - let socket = io(window.location.origin) - window.socket = socket // ==================================== // Bootstrap Vue // ==================================== const i18n = new VueI18Next(i18next) - window.wikijs = new Vue({ + window.wiki = new Vue({ mixins: [helpers], components: {}, store, @@ -151,9 +131,7 @@ $(() => { } }, mounted() { - $('a:not(.toc-anchor)').smoothScroll({ speed: 500, offset: -50 }) - $('#header').sticky({ topSpacing: 0 }) - $('.sidebar-pagecontents').sticky({ topSpacing: 15, bottomSpacing: 75 }) + } }) }) diff --git a/client/js/app.old.js b/client/js/app.old.js new file mode 100644 index 00000000..fc69cfc3 --- /dev/null +++ b/client/js/app.old.js @@ -0,0 +1,153 @@ +'use strict' + +/* global $, siteConfig */ +/* eslint-disable no-new */ + +import Vue from 'vue' +import VueResource from 'vue-resource' +import VueClipboards from 'vue-clipboards' +import VueLodash from 'vue-lodash' +import store from './store' +import i18next from 'i18next' +import i18nextXHR from 'i18next-xhr-backend' +import VueI18Next from '@panter/vue-i18next' +import 'jquery-contextmenu' +import 'jquery-simple-upload' +import 'jquery-smooth-scroll' +import 'jquery-sticky' + +// ==================================== +// Load Helpers +// ==================================== + +import helpers from './helpers' +import _ from './helpers/lodash' + +// ==================================== +// Load Vue Components +// ==================================== + +import alertComponent from './components/alert.vue' +import anchorComponent from './components/anchor.vue' +import colorPickerComponent from './components/color-picker.vue' +import editorCodeblockComponent from './components/editor-codeblock.vue' +import editorFileComponent from './components/editor-file.vue' +import editorVideoComponent from './components/editor-video.vue' +import historyComponent from './components/history.vue' +import loadingSpinnerComponent from './components/loading-spinner.vue' +import modalCreatePageComponent from './components/modal-create-page.vue' +import modalCreateUserComponent from './components/modal-create-user.vue' +import modalDeleteUserComponent from './components/modal-delete-user.vue' +import modalDiscardPageComponent from './components/modal-discard-page.vue' +import modalMovePageComponent from './components/modal-move-page.vue' +import modalProfile2faComponent from './components/modal-profile-2fa.vue' +import modalUpgradeSystemComponent from './components/modal-upgrade-system.vue' +import pageLoaderComponent from './components/page-loader.vue' +import searchComponent from './components/search.vue' +import toggleComponent from './components/toggle.vue' +import treeComponent from './components/tree.vue' + +import adminEditUserComponent from './pages/admin-edit-user.component.js' +import adminProfileComponent from './pages/admin-profile.component.js' +import adminSettingsComponent from './pages/admin-settings.component.js' +import adminThemeComponent from './pages/admin-theme.component.js' +import contentViewComponent from './pages/content-view.component.js' +import editorComponent from './components/editor.component.js' +import sourceViewComponent from './pages/source-view.component.js' + +// ==================================== +// Initialize Vue Modules +// ==================================== + +Vue.use(VueResource) +Vue.use(VueClipboards) +Vue.use(VueI18Next) +Vue.use(VueLodash, _) +Vue.use(helpers) + +// ==================================== +// Register Vue Components +// ==================================== + +Vue.component('alert', alertComponent) +Vue.component('adminEditUser', adminEditUserComponent) +Vue.component('adminProfile', adminProfileComponent) +Vue.component('adminSettings', adminSettingsComponent) +Vue.component('adminTheme', adminThemeComponent) +Vue.component('anchor', anchorComponent) +Vue.component('colorPicker', colorPickerComponent) +Vue.component('contentView', contentViewComponent) +Vue.component('editor', editorComponent) +Vue.component('editorCodeblock', editorCodeblockComponent) +Vue.component('editorFile', editorFileComponent) +Vue.component('editorVideo', editorVideoComponent) +Vue.component('history', historyComponent) +Vue.component('loadingSpinner', loadingSpinnerComponent) +Vue.component('modalCreatePage', modalCreatePageComponent) +Vue.component('modalCreateUser', modalCreateUserComponent) +Vue.component('modalDeleteUser', modalDeleteUserComponent) +Vue.component('modalDiscardPage', modalDiscardPageComponent) +Vue.component('modalMovePage', modalMovePageComponent) +Vue.component('modalProfile2fa', modalProfile2faComponent) +Vue.component('modalUpgradeSystem', modalUpgradeSystemComponent) +Vue.component('pageLoader', pageLoaderComponent) +Vue.component('search', searchComponent) +Vue.component('sourceView', sourceViewComponent) +Vue.component('toggle', toggleComponent) +Vue.component('tree', treeComponent) + +// ==================================== +// Load Localization strings +// ==================================== + +i18next + .use(i18nextXHR) + .init({ + backend: { + loadPath: siteConfig.path + '/js/i18n/{{lng}}.json' + }, + lng: siteConfig.lang, + fallbackLng: siteConfig.lang + }) + +$(() => { + // ==================================== + // Notifications + // ==================================== + + $(window).bind('beforeunload', () => { + store.dispatch('startLoading') + }) + $(document).ajaxSend(() => { + store.dispatch('startLoading') + }).ajaxComplete(() => { + store.dispatch('stopLoading') + }) + + // ==================================== + // Bootstrap Vue + // ==================================== + + const i18n = new VueI18Next(i18next) + if (document.querySelector('#root')) { + window.wikijs = new Vue({ + mixins: [helpers], + components: {}, + store, + i18n, + el: '#root', + methods: { + changeTheme(opts) { + this.$el.className = `has-stickynav is-primary-${opts.primary} is-alternate-${opts.alt}` + this.$refs.header.className = `nav is-${opts.primary}` + this.$refs.footer.className = `footer is-${opts.footer}` + } + }, + mounted() { + $('a:not(.toc-anchor)').smoothScroll({ speed: 500, offset: -50 }) + $('#header').sticky({ topSpacing: 0 }) + $('.sidebar-pagecontents').sticky({ topSpacing: 15, bottomSpacing: 75 }) + } + }) + } +}) diff --git a/client/js/helpers/index.js b/client/js/helpers/index.js index 6f802e8b..6335809b 100644 --- a/client/js/helpers/index.js +++ b/client/js/helpers/index.js @@ -1,6 +1,7 @@ 'use strict' const helpers = { + _: require('./lodash'), common: require('./common'), form: require('./form'), pages: require('./pages') diff --git a/client/js/login.js b/client/js/login.js deleted file mode 100644 index 892e3306..00000000 --- a/client/js/login.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -/* global $ */ - -$(() => { - $('#login-user').focus() -}) diff --git a/client/scss/app.scss b/client/scss/app.scss index 8bf44dd7..fc68ef23 100644 --- a/client/scss/app.scss +++ b/client/scss/app.scss @@ -42,6 +42,7 @@ @import 'layout/_header'; @import 'layout/_loader'; -@import 'pages/_welcome'; +@import 'pages/login'; +@import 'pages/welcome'; @import 'base/print'; diff --git a/client/scss/components/button.scss b/client/scss/components/button.scss index 97338a0e..c53754a3 100644 --- a/client/scss/components/button.scss +++ b/client/scss/components/button.scss @@ -4,7 +4,7 @@ .button { border: 1px solid mc('orange','700'); border-radius: 3px; display: inline-flex; - height: 30px; + height: 40px; align-items: center; padding: 0 15px; font-size: 13px; @@ -74,7 +74,13 @@ .button { &.is-featured { animation: btnInvertedPulse .6s ease alternate infinite; - } + } + + &.is-fullwidth { + width: 100%; + text-align: center; + justify-content: center; + } &.is-disabled, &:disabled { background-color: mc('grey', '300'); diff --git a/client/scss/pages/_login.scss b/client/scss/pages/_login.scss index abfd9c93..284bf7f6 100644 --- a/client/scss/pages/_login.scss +++ b/client/scss/pages/_login.scss @@ -1,306 +1,161 @@ +.login { + background-size: cover; + background-position: center center; + background-image: url('../images/bg.jpg'); + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; -body { - padding: 0; - margin: 0; - font-family: $core-font-standard; - font-size: 14px; -} - -a { - color: #FFF; - transition: color 0.4s ease; - text-decoration: none; - - &:hover { - color: mc('orange','600'); - text-decoration: underline; - } - -} - -#bg { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1; - background-color: #000; - - > div { - background-size: cover; - background-position: center center; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - opacity: 0; - visibility: hidden; - transition: opacity 3s ease, visibility 3s; - animation: bg 30s linear infinite; - - &:nth-child(1) { - animation-delay: 10s; - } - - &:nth-child(2) { - animation-delay: 20s; - } - - } - -} - -#root { - position: fixed; - top: 15vh; - left: 10vw; - z-index: 2; - color: #FFF; - display: flex; - flex-direction: column; - - h1 { - font-size: 4rem; - font-weight: bold; - color: #FFF; - padding: 0; - margin: 0; - animation: headerIntro 3s ease; - } - - h2 { - font-size: 1.5rem; - font-weight: normal; - color: rgba(255,255,255,0.7); - padding: 0; - margin: 0 0 25px 0; - animation: headerIntro 3s ease; - } - - h3 { - font-size: 1.25rem; - font-weight: normal; - color: #FB8C00; - padding: 0; - margin: 0; - animation: shake 1s ease; - - > .fa { - margin-right: 7px; - } - - } - - h4 { - font-size: 0.8rem; - font-weight: normal; - color: rgba(255,255,255,0.7); - padding: 0; - margin: 0 0 15px 0; - animation: fadeIn 3s ease; - } - - form { - display: flex; - flex-direction: column; - } - - input[type=text], input[type=password] { - width: 350px; - max-width: 80vw; - border: 1px solid rgba(255,255,255,0.3); - border-radius: 3px; - background-color: rgba(0,0,0,0.2); - padding: 0 15px; - height: 40px; - margin: 0 0 10px 0; - color: #FFF; - font-weight: bold; - font-size: 14px; - transition: all 0.4s ease; - - &:focus { - outline: none; - border-color: mc('orange','600'); - } - - } - - button { - background-color: mc('orange','600'); - color: #FFF; - border: 1px solid lighten(mc('orange','600'), 10%); - border-radius: 3px; - height: 40px; - width: 125px; - padding: 0; - font-weight: bold; - margin: 15px 0 0 0; - transition: all 0.4s ease; - cursor: pointer; - - span { - font-weight: bold; - } - - &:focus { - outline: none; - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('orange','600'), 10%); - } - - } - - #social { - margin-top: 25px; - - > span { - display: block; - font-weight: bold; - color: rgba(255,255,255,0.7); - } - - button { - margin-right: 5px; - width: auto; - padding: 0 15px; - - > i { - margin-right: 10px; - font-size: 16px; - } - - &.ms { - background-color: mc('blue','600'); - border-color: lighten(mc('blue','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('blue','600'), 10%); - } - - } - - &.google { - background-color: mc('light-blue','600'); - border-color: lighten(mc('light-blue','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('light-blue','600'), 10%); - } - - } - - &.facebook { - background-color: mc('indigo','600'); - border-color: lighten(mc('indigo','600'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('indigo','600'), 10%); - } - - } - - &.github { - background-color: mc('blue-grey','700'); - border-color: lighten(mc('blue-grey','700'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('blue-grey','700'), 10%); - } - } - - &.slack { - background-color: mc('purple','700'); - border-color: lighten(mc('purple','700'), 10%); - - &:focus { - border-color: #FFF; - } - - &:hover { - background-color: darken(mc('purple','700'), 10%); - } - } - - } - - } - -} - -#copyright { - display: flex; - align-items: center; - justify-content: flex-start; - position: absolute; - left: 10vw; - bottom: 10vh; - z-index: 2; - color: rgba(255,255,255,0.5); - font-weight: bold; - - .icon { - font-size: 1.2rem; - margin: 0 8px; - } - - a { - opacity: 0.75; - } - -} - -@include keyframes(bg) { - 0% { - @include prefix(transform, scale(1,1)); - visibility: visible; - opacity: 0; - }, - 5% { - opacity: 0.5; - }, - 33% { - opacity: 0.5; - }, - 38% { - @include prefix(transform, scale(1.2, 1.2)); - opacity: 0; - }, - 39% { - visibility: hidden; - } - 100% { - visibility: hidden; - opacity: 0; - } -} - -@include keyframes(headerIntro) { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } + &-container { + display: flex; + width: 650px; + align-items: stretch; + box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); + } + + &-providers { + display: flex; + flex-direction: column; + width: 200px; + border: 1px solid #FFF; + background-color: mc('grey', '900'); + z-index: 1; + + button { + flex: 1 1; + padding: 0 15px; + border: none; + color: #FFF; + background-color: mc('grey', '800'); + border-top: 1px solid mc('grey', '900'); + font-family: $core-font-standard; + font-weight: 600; + text-align: left; + min-height: 40px; + + &:first-child { + border-top: none; + } + + &.is-active { + background-color: mc('grey', '100'); + background-image: radial-gradient(circle at top left, rgba(mc('grey', '200'),1) 0%,rgba(255,255,255,1) 100%); + color: mc('grey', '700'); + } + + i { + margin-right: 10px; + font-size: 16px; + } + + span { + font-weight: 600; + } + } + } + + &-frame { + background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%); + border: 1px solid #FFF; + width: 450px; + padding: 1rem; + color: mc('grey', '700'); + display: flex; + justify-content: center; + flex-direction: column; + text-align: center; + + h1 { + font-size: 2rem; + font-weight: 600; + color: mc('grey', '700'); + padding: 0; + margin: 0; + } + + h2 { + font-size: 1.5rem; + font-weight: 300; + color: mc('grey', '700'); + padding: 0; + margin: 0 0 25px 0; + } + + h3 { + font-size: 1.25rem; + font-weight: normal; + color: #FB8C00; + padding: 0; + margin: 0; + animation: shake 1s ease; + + > .fa { + margin-right: 7px; + } + + } + + h4 { + font-size: .8rem; + font-weight: normal; + color: rgba(255,255,255,0.7); + padding: 0; + margin: 0 0 15px 0; + animation: fadeIn 3s ease; + } + + form { + display: flex; + flex-direction: column; + } + + input[type=text], input[type=password] { + width: 100%; + border: 1px solid #FFF; + border-radius: 3px; + background-color: rgba(255,255,255,.7); + padding: 0 15px; + height: 40px; + margin: 0 0 10px 0; + color: mc('grey', '700'); + font-weight: 600; + font-size: .8rem; + transition: all 0.4s ease; + text-align: center; + + &:focus { + outline: none; + border-color: mc('grey','400'); + } + + } + + } + + &-copyright { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + left: 0; + bottom: 10vh; + width: 100%; + z-index: 2; + color: #FFF; + font-weight: 400; + text-shadow: 1px 1px 0 #000; + + .icon { + font-size: 1.2rem; + margin: 0 8px; + } + + a { + font-weight: 600; + color: #FFF; + } + + } } diff --git a/package.json b/package.json index 7545f72b..7e27ce96 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "axios": "0.16.2", "bcryptjs-then": "1.0.1", "bluebird": "3.5.0", - "body-parser": "1.17.2", - "bull": "3.0.0", + "body-parser": "1.18.0", + "bull": "3.1.0", "bunyan": "1.8.12", "cheerio": "1.0.0-rc.2", "child-process-promise": "2.2.1", @@ -63,7 +63,7 @@ "follow-redirects": "1.2.4", "fs-extra": "4.0.1", "git-wrapper2-promise": "0.2.9", - "graphql": "0.11.2", + "graphql": "0.11.3", "graphql-tools": "1.2.2", "highlight.js": "9.12.0", "i18next": "9.0.0", @@ -73,7 +73,7 @@ "ioredis": "3.1.4", "jimp": "0.2.28", "js-yaml": "3.9.1", - "jsonwebtoken": "7.4.3", + "jsonwebtoken": "8.0.0", "klaw": "2.1.0", "levelup": "1.3.9", "lodash": "4.17.4", @@ -88,7 +88,7 @@ "markdown-it-mathjax": "2.0.0", "markdown-it-task-lists": "2.0.1", "mathjax-node": "1.2.0", - "memdown": "1.2.4", + "memdown": "1.2.7", "mime-types": "2.1.17", "moment": "2.18.1", "moment-timezone": "0.5.13", @@ -108,24 +108,24 @@ "passport.socketio": "3.7.0", "pg": "7.3.0", "pg-hstore": "2.3.2", - "pg-promise": "6.5.1", + "pg-promise": "6.5.2", "pm2": "2.6.1", - "pug": "2.0.0-rc.3", + "pug": "2.0.0-rc.4", "read-chunk": "2.1.0", "remove-markdown": "0.2.2", "request": "2.81.0", "search-index-adder": "0.3.9", "search-index-searcher": "0.2.10", "semver": "5.4.1", - "sequelize": "4.8.0", + "sequelize": "4.8.2", "serve-favicon": "2.4.3", "simplemde": "1.11.2", "socket.io": "2.0.3", - "stopword": "0.1.6", + "stopword": "0.1.7", "stream-to-promise": "2.2.0", "tar": "4.0.1", "through2": "2.0.3", - "validator": "8.1.0", + "validator": "8.2.0", "validator-as-promised": "1.0.2", "winston": "2.3.1", "yargs": "8.0.2" @@ -134,7 +134,7 @@ "@glimpse/glimpse": "0.22.15", "@panter/vue-i18next": "0.5.1", "babel-cli": "6.26.0", - "babel-jest": "21.0.0", + "babel-jest": "21.0.2", "babel-plugin-transform-object-assign": "6.22.0", "babel-preset-es2015": "6.24.1", "brace": "0.10.0", @@ -146,18 +146,18 @@ "eslint-plugin-node": "5.1.1", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "3.0.1", - "fuse-box": "2.2.3", + "fuse-box": "^2.2.31", "i18next-xhr-backend": "1.4.2", - "jest": "21.0.0", + "jest": "21.0.2", "jquery": "3.2.1", - "jquery-contextmenu": "2.5.0", + "jquery-contextmenu": "2.6.2", "jquery-simple-upload": "1.0.0", "jquery-smooth-scroll": "2.2.0", "jquery-sticky": "1.0.4", "lodash-cli": "4.17.4", "lodash-es": "4.17.4", "node-sass": "4.5.3", - "nodemon": "1.11.0", + "nodemon": "1.12.0", "pug-lint": "2.5.0", "twemoji-awesome": "1.0.6", "typescript": "2.5.2", diff --git a/server/master.js b/server/master.js index 85754011..844eee05 100644 --- a/server/master.js +++ b/server/master.js @@ -136,10 +136,10 @@ module.exports = Promise.join( // ---------------------------------------- app.locals._ = require('lodash') - app.locals.t = wiki.lang.t.bind(wiki.config.site.lang) + app.locals.t = wiki.lang.t.bind(wiki.lang) app.locals.moment = require('moment') app.locals.moment.locale(wiki.config.site.lang) - app.locals.appconfig = wiki.config + app.locals.config = wiki.config app.use(mw.flash) // ---------------------------------------- diff --git a/server/modules/config.js b/server/modules/config.js index 334fba3c..5884b8cf 100644 --- a/server/modules/config.js +++ b/server/modules/config.js @@ -47,11 +47,11 @@ module.exports = { appconfig.port = process.env.PORT || 80 } - // Convert booleans + // Convert booleans - appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') + appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true') - // List authentication strategies + // List authentication strategies wiki.config = appconfig wiki.data = appdata }, diff --git a/server/views/auth/login.pug b/server/views/auth/login.pug index ad860349..14105179 100644 --- a/server/views/auth/login.pug +++ b/server/views/auth/login.pug @@ -1,75 +1,54 @@ -doctype html -html(data-logic='login') - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png') - title= appconfig.title - - // Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href='/manifest.json') - - // JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') +extends ../master.pug +block body body - #bg - each bg in _.sampleSize([1, 2, 3],3) - div(style='background-image:url(/images/bg_' + bg + '.jpg);') - #root - h1= appconfig.title - h2= t('auth:loginrequired') - if appflash.length > 0 - h3 - i.icon-warning-outline - = appflash[0].title - h4= appflash[0].message - if appconfig.auth.local.enabled - form(method='post', action='/login') - input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser')) - input#login-pass(type='password', name='password', placeholder=t('auth:fields.password')) - button(type='submit')= t('auth:actions.login') - if appconfig.authStrategies.socialEnabled - #social - if appconfig.auth.local.enabled - span= t('auth:loginusingalt') - else - span= t('auth:loginusing') - if appconfig.auth.microsoft && appconfig.auth.microsoft.enabled - button.ms(onclick='window.location.assign("/login/ms")') - i.icon-windows2 - span= t('auth:providers.windowslive') - if appconfig.auth.azure && appconfig.auth.azure.enabled - button.ms(onclick='window.location.assign("/login/azure")') - i.icon-windows2 - span= t('auth:providers.azure') - if appconfig.auth.google && appconfig.auth.google.enabled - button.google(onclick='window.location.assign("/login/google")') - i.icon-google - span= t('auth:providers.google') - if appconfig.auth.facebook && appconfig.auth.facebook.enabled - button.facebook(onclick='window.location.assign("/login/facebook")') - i.icon-facebook - span= t('auth:providers.facebook') - if appconfig.auth.github && appconfig.auth.github.enabled - button.github(onclick='window.location.assign("/login/github")') - i.icon-github - span= t('auth:providers.github') - if appconfig.auth.slack && appconfig.auth.slack.enabled - button.slack(onclick='window.location.assign("/login/slack")') - i.icon-slack - span= t('auth:providers.slack') - #copyright - = t('footer.poweredby') + ' ' - a.icon(href='https://github.com/Requarks/wiki') - i.icon-github - a(href='https://wiki.requarks.io/') Wiki.js + .login#root + .login-container + if config.authStrategies.socialEnabled + .login-providers + button.is-active(onclick='window.location.assign("/login/ms")') + i.nc-icon-outline.ui-1_database + span= t('auth:providers.local') + if config.auth.microsoft && config.auth.microsoft.enabled + button(onclick='window.location.assign("/login/ms")') + i.icon-windows2 + span= t('auth:providers.windowslive') + if config.auth.azure && config.auth.azure.enabled + button(onclick='window.location.assign("/login/azure")') + i.icon-windows2 + span= t('auth:providers.azure') + if config.auth.google && config.auth.google.enabled + button(onclick='window.location.assign("/login/google")') + i.icon-google + span= t('auth:providers.google') + if config.auth.facebook && config.auth.facebook.enabled + button(onclick='window.location.assign("/login/facebook")') + i.icon-facebook + span= t('auth:providers.facebook') + if config.auth.github && config.auth.github.enabled + button(onclick='window.location.assign("/login/github")') + i.icon-github + span= t('auth:providers.github') + if config.auth.slack && config.auth.slack.enabled + button(onclick='window.location.assign("/login/slack")') + i.icon-slack + span= t('auth:providers.slack') + .login-frame + h1= config.site.title + h2= t('auth:loginrequired') + if appflash.length > 0 + h3 + i.icon-warning-outline + = appflash[0].title + h4= appflash[0].message + if config.auth.local.enabled + form(method='post', action='/login') + input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser')) + input#login-pass(type='password', name='password', placeholder=t('auth:fields.password')) + button.button.is-light-green.is-fullwidth(type='submit') + span= t('auth:actions.login') + .login-copyright + = t('footer.poweredby') + ' ' + a.icon(href='https://github.com/Requarks/wiki') + i.icon-github + a(href='https://wiki.requarks.io/') Wiki.js diff --git a/server/views/error.pug b/server/views/error.pug index 3ef6c43f..51b53efe 100644 --- a/server/views/error.pug +++ b/server/views/error.pug @@ -1,32 +1,12 @@ -doctype html -html(data-logic='error') - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content=appconfig.host + '/favicons/ms-icon-144x144.png') - title= appconfig.title - - // Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href=appconfig.host + '/manifest.json') - - // JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') +extends ./master.pug +block body body(class='is-error') .container - a(href='/'): img(src=appconfig.host + '/images/logo.png') + a(href='/'): img(src=config.site.path + '/images/logo.png') h1= message h2= t('errors:generic') - a.button.is-amber.is-inverted.is-featured(href=appconfig.host + '/')= t('errors:actions.gohome') + a.button.is-amber.is-inverted.is-featured(href=config.site.path+ '/')= t('errors:actions.gohome') if error.stack h3= t('errors:debugmsg') diff --git a/server/views/layout.pug b/server/views/layout.pug index 4e0f0a9f..49d4747a 100644 --- a/server/views/layout.pug +++ b/server/views/layout.pug @@ -1,33 +1,6 @@ -doctype html -html - head - meta(http-equiv='X-UA-Compatible', content='IE=edge') - meta(charset='UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - meta(name='theme-color', content='#009688') - meta(name='msapplication-TileColor', content='#009688') - meta(name='msapplication-TileImage', content=appconfig.host + '/favicons/ms-icon-144x144.png') - title= appconfig.title - - //- Favicon - each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] - link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') - link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png') - each favsize in [32, 96, 16] - link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') - link(rel='manifest', href=appconfig.host + '/manifest.json') - - //- Site Lang - script. - var siteLang = '!{appconfig.lang}'; - var siteRoot = '!{appconfig.host}'; - - //- JS / CSS - script(type='text/javascript', src=appconfig.host + '/js/vendor.js') - script(type='text/javascript', src=appconfig.host + '/js/app.js') - - block head +extends ./master.pug +block body body #root.has-stickynav(class=['is-primary-' + appconfig.theme.primary, 'is-alternate-' + appconfig.theme.alt]) include ./common/header.pug diff --git a/server/views/master.pug b/server/views/master.pug new file mode 100644 index 00000000..e924fd32 --- /dev/null +++ b/server/views/master.pug @@ -0,0 +1,30 @@ +doctype html +html + head + meta(http-equiv='X-UA-Compatible', content='IE=edge') + meta(charset='UTF-8') + meta(name='viewport', content='width=device-width, initial-scale=1') + meta(name='theme-color', content='#009688') + meta(name='msapplication-TileColor', content='#009688') + meta(name='msapplication-TileImage', content=config.site.path + '/favicons/ms-icon-144x144.png') + title= config.title + + //- Favicon + each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180] + link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href=config.site.path + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png') + link(rel='icon', type='image/png', sizes='192x192', href=config.site.path + '/favicons/android-icon-192x192.png') + each favsize in [32, 96, 16] + link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=config.site.path + '/favicons/favicon-' + favsize + 'x' + favsize + '.png') + link(rel='manifest', href=config.site.path + '/manifest.json') + + //- Site Lang + script. + var siteConfig = !{JSON.stringify(config.site)} + + //- JS / CSS + script(type='text/javascript', src=config.site.path + '/js/vendor.js') + script(type='text/javascript', src=config.site.path + '/js/app.js') + + block head + + block body diff --git a/tools/fuse.js b/tools/fuse.js index 9fc79274..ef404827 100644 --- a/tools/fuse.js +++ b/tools/fuse.js @@ -126,7 +126,8 @@ globalTasks.then(() => { switch (mode) { case 'dev': - bundleApp.watch() + bundleApp.hmr().watch() + fuse.dev({ httpServer: false }) break case 'dev-configure': bundleSetup.watch() diff --git a/yarn.lock b/yarn.lock index 5d936277..0a625c96 100644 Binary files a/yarn.lock and b/yarn.lock differ