diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 9a23fe2a1..1ba8b97db 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -231,7 +231,6 @@ class RegisterController extends Controller return redirect('/register/confirm'); } - $this->emailConfirmationService->sendConfirmation($user); session()->flash('success', trans('auth.email_confirm_resent')); return redirect('/register/confirm'); } diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php index eecb7839f..d515d83a3 100644 --- a/app/Http/Controllers/BookController.php +++ b/app/Http/Controllers/BookController.php @@ -36,12 +36,17 @@ class BookController extends Controller */ public function index() { - $books = $this->entityRepo->getAllPaginated('book', 16); + $books = $this->entityRepo->getAllPaginated('book', 20); $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false; - $popular = $this->entityRepo->getPopular('book', 3, 0); - $books_display = $this->currentUser->books_display; + $popular = $this->entityRepo->getPopular('book', 4, 0); + $new = $this->entityRepo->getRecentlyCreated('book', 4, 0); $this->setPageTitle('Books'); - return view('books/index', ['books' => $books, 'recents' => $recents, 'popular' => $popular, 'books_display' => $books_display] ); + return view('books/index', [ + 'books' => $books, + 'recents' => $recents, + 'popular' => $popular, + 'new' => $new + ]); } /** @@ -85,7 +90,12 @@ class BookController extends Controller $bookChildren = $this->entityRepo->getBookChildren($book); Views::add($book); $this->setPageTitle($book->getShortName()); - return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]); + return view('books/show', [ + 'book' => $book, + 'current' => $book, + 'bookChildren' => $bookChildren, + 'activity' => Activity::entityActivity($book, 20, 0) + ]); } /** diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 7f60d7009..7d109b70a 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -29,15 +29,25 @@ class HomeController extends Controller $activity = Activity::latest(10); $draftPages = $this->signedIn ? $this->entityRepo->getUserDraftPages(6) : []; $recentFactor = count($draftPages) > 0 ? 0.5 : 1; - $recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 10*$recentFactor); - $recentlyCreatedPages = $this->entityRepo->getRecentlyCreated('page', 5); - $recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 5); - return view('home', [ + $recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor); + $recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12); + + // Custom homepage + $customHomepage = false; + $homepageSetting = setting('app-homepage'); + if ($homepageSetting) { + $id = intval(explode(':', $homepageSetting)[0]); + $customHomepage = $this->entityRepo->getById('page', $id, false, true); + $this->entityRepo->renderPage($customHomepage, true); + } + + $view = $customHomepage ? 'home-custom' : 'home'; + return view($view, [ 'activity' => $activity, 'recents' => $recents, - 'recentlyCreatedPages' => $recentlyCreatedPages, 'recentlyUpdatedPages' => $recentlyUpdatedPages, - 'draftPages' => $draftPages + 'draftPages' => $draftPages, + 'customHomepage' => $customHomepage ]); } diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 9a8525c23..21572db29 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -167,7 +167,7 @@ class PageController extends Controller return view('pages/show', [ 'page' => $page,'book' => $page->book, 'current' => $page, 'sidebarTree' => $sidebarTree, - 'pageNav' => $pageNav, 'pageContent' => $pageContent]); + 'pageNav' => $pageNav]); } /** @@ -380,6 +380,7 @@ class PageController extends Controller return view('pages/revision', [ 'page' => $page, 'book' => $page->book, + 'revision' => $revision ]); } @@ -409,6 +410,7 @@ class PageController extends Controller 'page' => $page, 'book' => $page->book, 'diff' => $diff, + 'revision' => $revision ]); } diff --git a/app/PageRevision.php b/app/PageRevision.php index ff469f0ed..0a9764729 100644 --- a/app/PageRevision.php +++ b/app/PageRevision.php @@ -47,4 +47,16 @@ class PageRevision extends Model return null; } + /** + * Allows checking of the exact class, Used to check entity type. + * Included here to align with entities in similar use cases. + * (Yup, Bit of an awkward hack) + * @param $type + * @return bool + */ + public static function isA($type) + { + return $type === 'revision'; + } + } diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php index d87c40f9b..a682e696b 100644 --- a/app/Repos/EntityRepo.php +++ b/app/Repos/EntityRepo.php @@ -137,10 +137,15 @@ class EntityRepo * @param string $type * @param integer $id * @param bool $allowDrafts + * @param bool $ignorePermissions * @return Entity */ - public function getById($type, $id, $allowDrafts = false) + public function getById($type, $id, $allowDrafts = false, $ignorePermissions = false) { + if ($ignorePermissions) { + $entity = $this->getEntity($type); + return $entity->newQuery()->find($id); + } return $this->entityQuery($type, $allowDrafts)->find($id); } @@ -671,9 +676,10 @@ class EntityRepo /** * Render the page for viewing, Parsing and performing features such as page transclusion. * @param Page $page + * @param bool $ignorePermissions * @return mixed|string */ - public function renderPage(Page $page) + public function renderPage(Page $page, $ignorePermissions = false) { $content = $page->html; $matches = []; @@ -685,7 +691,7 @@ class EntityRepo $pageId = intval($splitInclude[0]); if (is_nan($pageId)) continue; - $page = $this->getById('page', $pageId); + $page = $this->getById('page', $pageId, false, $ignorePermissions); if ($page === null) { $content = str_replace($matches[0][$index], '', $content); continue; @@ -710,6 +716,7 @@ class EntityRepo $content = str_replace($matches[0][$index], trim($innerContent), $content); } + $page->renderedHTML = $content; return $content; } diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index 78cef41a4..40402dbce 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -27,9 +27,9 @@ class ExportService */ public function pageToContainedHtml(Page $page) { + $this->entityRepo->renderPage($page); $pageHtml = view('pages/export', [ - 'page' => $page, - 'pageContent' => $this->entityRepo->renderPage($page) + 'page' => $page ])->render(); return $this->containHtml($pageHtml); } @@ -74,9 +74,9 @@ class ExportService */ public function pageToPdf(Page $page) { + $this->entityRepo->renderPage($page); $html = view('pages/pdf', [ - 'page' => $page, - 'pageContent' => $this->entityRepo->renderPage($page) + 'page' => $page ])->render(); return $this->htmlToPdf($html); } diff --git a/app/Services/SearchService.php b/app/Services/SearchService.php index 3d1d45c3b..bb92a1d7c 100644 --- a/app/Services/SearchService.php +++ b/app/Services/SearchService.php @@ -92,7 +92,7 @@ class SearchService return [ 'total' => $total, 'count' => count($results), - 'results' => $results->sortByDesc('score') + 'results' => $results->sortByDesc('score')->values() ]; } diff --git a/app/Services/ViewService.php b/app/Services/ViewService.php index 3285745ce..770a9e39f 100644 --- a/app/Services/ViewService.php +++ b/app/Services/ViewService.php @@ -62,7 +62,7 @@ class ViewService $query->whereIn('viewable_type', $filterModel); } else if ($filterModel) { $query->where('viewable_type', '=', get_class($filterModel)); - }; + } return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable'); } diff --git a/gulpfile.js b/gulpfile.js index f851dd7d6..c9f3f7956 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,16 +3,20 @@ const argv = require('yargs').argv; const gulp = require('gulp'), plumber = require('gulp-plumber'); + const autoprefixer = require('gulp-autoprefixer'); -const uglify = require('gulp-uglify'); const minifycss = require('gulp-clean-css'); const sass = require('gulp-sass'); +const sourcemaps = require('gulp-sourcemaps'); + const browserify = require("browserify"); const source = require('vinyl-source-stream'); const buffer = require('vinyl-buffer'); const babelify = require("babelify"); const watchify = require("watchify"); const envify = require("envify"); +const uglify = require('gulp-uglify'); + const gutil = require("gulp-util"); const liveReload = require('gulp-livereload'); @@ -21,6 +25,7 @@ let isProduction = argv.production || process.env.NODE_ENV === 'production'; gulp.task('styles', () => { let chain = gulp.src(['resources/assets/sass/**/*.scss']) + .pipe(sourcemaps.init()) .pipe(plumber({ errorHandler: function (error) { console.log(error.message); @@ -29,6 +34,7 @@ gulp.task('styles', () => { .pipe(sass()) .pipe(autoprefixer('last 2 versions')); if (isProduction) chain = chain.pipe(minifycss()); + chain = chain.pipe(sourcemaps.write()); return chain.pipe(gulp.dest('public/css/')).pipe(liveReload()); }); diff --git a/package.json b/package.json index f447ec786..ed8338abb 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "clipboard": "^1.7.1", "codemirror": "^5.26.0", "dropzone": "^4.0.1", + "gulp-sourcemaps": "^2.6.1", "gulp-util": "^3.0.8", "markdown-it": "^8.3.1", "markdown-it-task-lists": "^2.0.0", diff --git a/readme.md b/readme.md index 5d099ad5f..1d4ed682e 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # BookStack -[![GitHub release](https://img.shields.io/github/release/BookStackApp/BookStack.svg?maxAge=2592000)](https://github.com/BookStackApp/BookStack/releases/latest) -[![license](https://img.shields.io/github/license/BookStackApp/BookStack.svg?maxAge=2592000)](https://github.com/BookStackApp/BookStack/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/BookStackApp/BookStack.svg)](https://github.com/BookStackApp/BookStack/releases/latest) +[![license](https://img.shields.io/github/license/BookStackApp/BookStack.svg)](https://github.com/BookStackApp/BookStack/blob/master/LICENSE) [![Build Status](https://travis-ci.org/BookStackApp/BookStack.svg)](https://travis-ci.org/BookStackApp/BookStack) A platform for storing and organising information and documentation. General information and documentation for BookStack can be found at https://www.bookstackapp.com/. @@ -13,6 +13,12 @@ A platform for storing and organising information and documentation. General inf * *Password: `password`* * [BookStack Blog](https://www.bookstackapp.com/blog) +## Project Definition + +BookStack is an opinionated wiki system that provides a pleasant and simple out of the box experience. New users to an instance should find the experience intuitive and only basic word-processing skills should be required to get involved in creating content on BookStack. The platform should provide advanced power features to those that desire it but they should not interfere with the core simple user experience. + +BookStack is not designed as an extensible platform to be used for purposes that differ to the statement above. + ## Development & Testing All development on BookStack is currently done on the master branch. When it's time for a release the master branch is merged into release with built & minified CSS & JS then tagged at it's version. Here are the current development requirements: diff --git a/resources/assets/js/components/entity-selector-popup.js b/resources/assets/js/components/entity-selector-popup.js new file mode 100644 index 000000000..64c0c62e9 --- /dev/null +++ b/resources/assets/js/components/entity-selector-popup.js @@ -0,0 +1,47 @@ + +class EntitySelectorPopup { + + constructor(elem) { + this.elem = elem; + window.EntitySelectorPopup = this; + + this.callback = null; + this.selection = null; + + this.selectButton = elem.querySelector('.entity-link-selector-confirm'); + this.selectButton.addEventListener('click', this.onSelectButtonClick.bind(this)); + + window.$events.listen('entity-select-change', this.onSelectionChange.bind(this)); + window.$events.listen('entity-select-confirm', this.onSelectionConfirm.bind(this)); + } + + show(callback) { + this.callback = callback; + this.elem.components.overlay.show(); + } + + hide() { + this.elem.components.overlay.hide(); + } + + onSelectButtonClick() { + this.hide(); + if (this.selection !== null && this.callback) this.callback(this.selection); + } + + onSelectionConfirm(entity) { + this.hide(); + if (this.callback && entity) this.callback(entity); + } + + onSelectionChange(entity) { + this.selection = entity; + if (entity === null) { + this.selectButton.setAttribute('disabled', 'true'); + } else { + this.selectButton.removeAttribute('disabled'); + } + } +} + +module.exports = EntitySelectorPopup; \ No newline at end of file diff --git a/resources/assets/js/components/entity-selector.js b/resources/assets/js/components/entity-selector.js new file mode 100644 index 000000000..53358378a --- /dev/null +++ b/resources/assets/js/components/entity-selector.js @@ -0,0 +1,118 @@ + +class EntitySelector { + + constructor(elem) { + this.elem = elem; + this.search = ''; + this.lastClick = 0; + + let entityTypes = elem.hasAttribute('entity-types') ? elem.getAttribute('entity-types') : 'page,book,chapter'; + this.searchUrl = window.baseUrl(`/ajax/search/entities?types=${encodeURIComponent(entityTypes)}`); + + this.input = elem.querySelector('[entity-selector-input]'); + this.searchInput = elem.querySelector('[entity-selector-search]'); + this.loading = elem.querySelector('[entity-selector-loading]'); + this.resultsContainer = elem.querySelector('[entity-selector-results]'); + + this.elem.addEventListener('click', this.onClick.bind(this)); + + let lastSearch = 0; + this.searchInput.addEventListener('input', event => { + lastSearch = Date.now(); + this.showLoading(); + setTimeout(() => { + if (Date.now() - lastSearch < 199) return; + this.searchEntities(this.searchInput.value); + }, 200); + }); + this.searchInput.addEventListener('keydown', event => { + if (event.keyCode === 13) event.preventDefault(); + }); + + this.showLoading(); + this.initialLoad(); + } + + showLoading() { + this.loading.style.display = 'block'; + this.resultsContainer.style.display = 'none'; + } + + hideLoading() { + this.loading.style.display = 'none'; + this.resultsContainer.style.display = 'block'; + } + + initialLoad() { + window.$http.get(this.searchUrl).then(resp => { + this.resultsContainer.innerHTML = resp.data; + this.hideLoading(); + }) + } + + searchEntities(searchTerm) { + this.input.value = ''; + let url = this.searchUrl + `&term=${encodeURIComponent(searchTerm)}`; + window.$http.get(url).then(resp => { + this.resultsContainer.innerHTML = resp.data; + this.hideLoading(); + }); + } + + isDoubleClick() { + let now = Date.now(); + let answer = now - this.lastClick < 300; + this.lastClick = now; + return answer; + } + + onClick(event) { + let t = event.target; + console.log('click', t); + + if (t.matches('.entity-list-item *')) { + event.preventDefault(); + event.stopPropagation(); + let item = t.closest('[data-entity-type]'); + this.selectItem(item); + } else if (t.matches('[data-entity-type]')) { + this.selectItem(t) + } + + } + + selectItem(item) { + let isDblClick = this.isDoubleClick(); + let type = item.getAttribute('data-entity-type'); + let id = item.getAttribute('data-entity-id'); + let isSelected = !item.classList.contains('selected') || isDblClick; + + this.unselectAll(); + this.input.value = isSelected ? `${type}:${id}` : ''; + + if (!isSelected) window.$events.emit('entity-select-change', null); + if (isSelected) { + item.classList.add('selected'); + item.classList.add('primary-background'); + } + if (!isDblClick && !isSelected) return; + + let link = item.querySelector('.entity-list-item-link').getAttribute('href'); + let name = item.querySelector('.entity-list-item-name').textContent; + let data = {id: Number(id), name: name, link: link}; + + if (isDblClick) window.$events.emit('entity-select-confirm', data); + if (isSelected) window.$events.emit('entity-select-change', data); + } + + unselectAll() { + let selected = this.elem.querySelectorAll('.selected'); + for (let i = 0, len = selected.length; i < len; i++) { + selected[i].classList.remove('selected'); + selected[i].classList.remove('primary-background'); + } + } + +} + +module.exports = EntitySelector; \ No newline at end of file diff --git a/resources/assets/js/components/index.js b/resources/assets/js/components/index.js index 43466a0d9..988409fbc 100644 --- a/resources/assets/js/components/index.js +++ b/resources/assets/js/components/index.js @@ -6,6 +6,10 @@ let componentMapping = { 'notification': require('./notification'), 'chapter-toggle': require('./chapter-toggle'), 'expand-toggle': require('./expand-toggle'), + 'entity-selector-popup': require('./entity-selector-popup'), + 'entity-selector': require('./entity-selector'), + 'sidebar': require('./sidebar'), + 'page-picker': require('./page-picker'), }; window.components = {}; diff --git a/resources/assets/js/components/notification.js b/resources/assets/js/components/notification.js index 1a9819702..daef5bd6f 100644 --- a/resources/assets/js/components/notification.js +++ b/resources/assets/js/components/notification.js @@ -6,7 +6,7 @@ class Notification { this.type = elem.getAttribute('notification'); this.textElem = elem.querySelector('span'); this.autohide = this.elem.hasAttribute('data-autohide'); - window.Events.listen(this.type, text => { + window.$events.listen(this.type, text => { this.show(text); }); elem.addEventListener('click', this.hide.bind(this)); diff --git a/resources/assets/js/components/page-picker.js b/resources/assets/js/components/page-picker.js new file mode 100644 index 000000000..e697d5f68 --- /dev/null +++ b/resources/assets/js/components/page-picker.js @@ -0,0 +1,60 @@ + +class PagePicker { + + constructor(elem) { + this.elem = elem; + this.input = elem.querySelector('input'); + this.resetButton = elem.querySelector('[page-picker-reset]'); + this.selectButton = elem.querySelector('[page-picker-select]'); + this.display = elem.querySelector('[page-picker-display]'); + this.defaultDisplay = elem.querySelector('[page-picker-default]'); + this.buttonSep = elem.querySelector('span.sep'); + + this.value = this.input.value; + this.setupListeners(); + } + + setupListeners() { + // Select click + this.selectButton.addEventListener('click', event => { + window.EntitySelectorPopup.show(entity => { + this.setValue(entity.id, entity.name); + }); + }); + + this.resetButton.addEventListener('click', event => { + this.setValue('', ''); + }); + } + + setValue(value, name) { + this.value = value; + this.input.value = value; + this.controlView(name); + } + + controlView(name) { + let hasValue = this.value && this.value !== 0; + toggleElem(this.resetButton, hasValue); + toggleElem(this.buttonSep, hasValue); + toggleElem(this.defaultDisplay, !hasValue); + toggleElem(this.display, hasValue); + if (hasValue) { + let id = this.getAssetIdFromVal(); + this.display.textContent = `#${id}, ${name}`; + this.display.href = window.baseUrl(`/link/${id}`); + } + } + + getAssetIdFromVal() { + return Number(this.value); + } + +} + +function toggleElem(elem, show) { + let display = (elem.tagName === 'BUTTON' || elem.tagName === 'SPAN') ? 'inline-block' : 'block'; + elem.style.display = show ? display : 'none'; +} + +module.exports = PagePicker; \ No newline at end of file diff --git a/resources/assets/js/components/sidebar.js b/resources/assets/js/components/sidebar.js new file mode 100644 index 000000000..fc801618e --- /dev/null +++ b/resources/assets/js/components/sidebar.js @@ -0,0 +1,16 @@ + +class Sidebar { + + constructor(elem) { + this.elem = elem; + this.toggleElem = elem.querySelector('.sidebar-toggle'); + this.toggleElem.addEventListener('click', this.toggle.bind(this)); + } + + toggle(show = true) { + this.elem.classList.toggle('open'); + } + +} + +module.exports = Sidebar; \ No newline at end of file diff --git a/resources/assets/js/directives.js b/resources/assets/js/directives.js index fc92121ff..8813eb881 100644 --- a/resources/assets/js/directives.js +++ b/resources/assets/js/directives.js @@ -252,7 +252,7 @@ module.exports = function (ngApp, events) { // Show the popup link selector and insert a link when finished function showLinkSelector() { let cursorPos = cm.getCursor('from'); - window.showEntityLinkSelector(entity => { + window.EntitySelectorPopup.show(entity => { let selectedText = cm.getSelection() || entity.name; let newText = `[${selectedText}](${entity.link})`; cm.focus(); @@ -387,154 +387,6 @@ module.exports = function (ngApp, events) { } }]); - ngApp.directive('entityLinkSelector', [function($http) { - return { - restrict: 'A', - link: function(scope, element, attrs) { - - const selectButton = element.find('.entity-link-selector-confirm'); - let callback = false; - let entitySelection = null; - - // Handle entity selection change, Stores the selected entity locally - function entitySelectionChange(entity) { - entitySelection = entity; - if (entity === null) { - selectButton.attr('disabled', 'true'); - } else { - selectButton.removeAttr('disabled'); - } - } - events.listen('entity-select-change', entitySelectionChange); - - // Handle selection confirm button click - selectButton.click(event => { - hide(); - if (entitySelection !== null) callback(entitySelection); - }); - - // Show selector interface - function show() { - element.fadeIn(240); - } - - // Hide selector interface - function hide() { - element.fadeOut(240); - } - scope.hide = hide; - - // Listen to confirmation of entity selections (doubleclick) - events.listen('entity-select-confirm', entity => { - hide(); - callback(entity); - }); - - // Show entity selector, Accessible globally, and store the callback - window.showEntityLinkSelector = function(passedCallback) { - show(); - callback = passedCallback; - }; - - } - }; - }]); - - - ngApp.directive('entitySelector', ['$http', '$sce', function ($http, $sce) { - return { - restrict: 'A', - scope: true, - link: function (scope, element, attrs) { - scope.loading = true; - scope.entityResults = false; - scope.search = ''; - - // Add input for forms - const input = element.find('[entity-selector-input]').first(); - - // Detect double click events - let lastClick = 0; - function isDoubleClick() { - let now = Date.now(); - let answer = now - lastClick < 300; - lastClick = now; - return answer; - } - - // Listen to entity item clicks - element.on('click', '.entity-list a', function(event) { - event.preventDefault(); - event.stopPropagation(); - let item = $(this).closest('[data-entity-type]'); - itemSelect(item, isDoubleClick()); - }); - element.on('click', '[data-entity-type]', function(event) { - itemSelect($(this), isDoubleClick()); - }); - - // Select entity action - function itemSelect(item, doubleClick) { - let entityType = item.attr('data-entity-type'); - let entityId = item.attr('data-entity-id'); - let isSelected = !item.hasClass('selected') || doubleClick; - element.find('.selected').removeClass('selected').removeClass('primary-background'); - if (isSelected) item.addClass('selected').addClass('primary-background'); - let newVal = isSelected ? `${entityType}:${entityId}` : ''; - input.val(newVal); - - if (!isSelected) { - events.emit('entity-select-change', null); - } - - if (!doubleClick && !isSelected) return; - - let link = item.find('.entity-list-item-link').attr('href'); - let name = item.find('.entity-list-item-name').text(); - - if (doubleClick) { - events.emit('entity-select-confirm', { - id: Number(entityId), - name: name, - link: link - }); - } - - if (isSelected) { - events.emit('entity-select-change', { - id: Number(entityId), - name: name, - link: link - }); - } - } - - // Get search url with correct types - function getSearchUrl() { - let types = (attrs.entityTypes) ? encodeURIComponent(attrs.entityTypes) : encodeURIComponent('page,book,chapter'); - return window.baseUrl(`/ajax/search/entities?types=${types}`); - } - - // Get initial contents - $http.get(getSearchUrl()).then(resp => { - scope.entityResults = $sce.trustAsHtml(resp.data); - scope.loading = false; - }); - - // Search when typing - scope.searchEntities = function() { - scope.loading = true; - input.val(''); - let url = getSearchUrl() + '&term=' + encodeURIComponent(scope.search); - $http.get(url).then(resp => { - scope.entityResults = $sce.trustAsHtml(resp.data); - scope.loading = false; - }); - }; - } - }; - }]); - ngApp.directive('commentReply', [function () { return { restrict: 'E', diff --git a/resources/assets/js/dom-polyfills.js b/resources/assets/js/dom-polyfills.js new file mode 100644 index 000000000..fcd89b766 --- /dev/null +++ b/resources/assets/js/dom-polyfills.js @@ -0,0 +1,20 @@ +/** + * Polyfills for DOM API's + */ + +if (!Element.prototype.matches) { + Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; +} + +if (!Element.prototype.closest) { + Element.prototype.closest = function (s) { + var el = this; + var ancestor = this; + if (!document.documentElement.contains(el)) return null; + do { + if (ancestor.matches(s)) return ancestor; + ancestor = ancestor.parentElement; + } while (ancestor !== null); + return null; + }; +} \ No newline at end of file diff --git a/resources/assets/js/global.js b/resources/assets/js/global.js index 966adb75d..176aff733 100644 --- a/resources/assets/js/global.js +++ b/resources/assets/js/global.js @@ -1,5 +1,6 @@ "use strict"; require("babel-polyfill"); +require('./dom-polyfills'); // Url retrieval function window.baseUrl = function(path) { @@ -13,9 +14,11 @@ window.baseUrl = function(path) { class EventManager { constructor() { this.listeners = {}; + this.stack = []; } emit(eventName, eventData) { + this.stack.push({name: eventName, data: eventData}); if (typeof this.listeners[eventName] === 'undefined') return this; let eventsToStart = this.listeners[eventName]; for (let i = 0; i < eventsToStart.length; i++) { @@ -32,7 +35,7 @@ class EventManager { } } -window.Events = new EventManager(); +window.$events = new EventManager(); const Vue = require("vue"); const axios = require("axios"); @@ -47,13 +50,13 @@ axiosInstance.interceptors.request.use(resp => { return resp; }, err => { if (typeof err.response === "undefined" || typeof err.response.data === "undefined") return Promise.reject(err); - if (typeof err.response.data.error !== "undefined") window.Events.emit('error', err.response.data.error); - if (typeof err.response.data.message !== "undefined") window.Events.emit('error', err.response.data.message); + if (typeof err.response.data.error !== "undefined") window.$events.emit('error', err.response.data.error); + if (typeof err.response.data.message !== "undefined") window.$events.emit('error', err.response.data.message); }); window.$http = axiosInstance; Vue.prototype.$http = axiosInstance; -Vue.prototype.$events = window.Events; +Vue.prototype.$events = window.$events; // AngularJS - Create application and load components @@ -78,8 +81,8 @@ require("./components"); // Load in angular specific items const Directives = require('./directives'); const Controllers = require('./controllers'); -Directives(ngApp, window.Events); -Controllers(ngApp, window.Events); +Directives(ngApp, window.$events); +Controllers(ngApp, window.$events); //Global jQuery Config & Extensions diff --git a/resources/assets/js/pages/page-form.js b/resources/assets/js/pages/page-form.js index 08e4c0c34..497dc0212 100644 --- a/resources/assets/js/pages/page-form.js +++ b/resources/assets/js/pages/page-form.js @@ -274,7 +274,7 @@ module.exports = function() { file_browser_callback: function (field_name, url, type, win) { if (type === 'file') { - window.showEntityLinkSelector(function(entity) { + window.EntitySelectorPopup.show(function(entity) { let originalField = win.document.getElementById(field_name); originalField.value = entity.link; $(originalField).closest('.mce-form').find('input').eq(2).val(entity.name); diff --git a/resources/assets/js/pages/page-show.js b/resources/assets/js/pages/page-show.js index 7754840af..832ec4b36 100644 --- a/resources/assets/js/pages/page-show.js +++ b/resources/assets/js/pages/page-show.js @@ -106,25 +106,25 @@ let setupPageShow = window.setupPageShow = function (pageId) { goToText(event.target.getAttribute('href').substr(1)); }); - // Make the book-tree sidebar stick in view on scroll + // Make the sidebar stick in view on scroll let $window = $(window); - let $bookTree = $(".book-tree"); - let $bookTreeParent = $bookTree.parent(); + let $sidebar = $("#sidebar .scroll-body"); + let $bookTreeParent = $sidebar.parent(); // Check the page is scrollable and the content is taller than the tree - let pageScrollable = ($(document).height() > $window.height()) && ($bookTree.height() < $('.page-content').height()); + let pageScrollable = ($(document).height() > $window.height()) && ($sidebar.height() < $('.page-content').height()); // Get current tree's width and header height let headerHeight = $("#header").height() + $(".toolbar").height(); let isFixed = $window.scrollTop() > headerHeight; // Function to fix the tree as a sidebar function stickTree() { - $bookTree.width($bookTreeParent.width() + 15); - $bookTree.addClass("fixed"); + $sidebar.width($bookTreeParent.width() + 15); + $sidebar.addClass("fixed"); isFixed = true; } // Function to un-fix the tree back into position function unstickTree() { - $bookTree.css('width', 'auto'); - $bookTree.removeClass("fixed"); + $sidebar.css('width', 'auto'); + $sidebar.removeClass("fixed"); isFixed = false; } // Checks if the tree stickiness state should change diff --git a/resources/assets/sass/_blocks.scss b/resources/assets/sass/_blocks.scss index e3a0d6952..c5b850507 100644 --- a/resources/assets/sass/_blocks.scss +++ b/resources/assets/sass/_blocks.scss @@ -180,4 +180,28 @@ &.warning:before { content: '\f1f1'; } +} + +.card { + margin: $-m; + background-color: #FFF; + box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.2); + h3 { + padding: $-m; + border-bottom: 1px solid #E8E8E8; + margin: 0; + font-size: $fs-s; + color: #888; + font-weight: 400; + text-transform: uppercase; + } + .body, p.empty-text { + padding: $-m; + } +} + +.well { + background-color: #F8F8F8; + padding: $-m; + border: 1px solid #DDD; } \ No newline at end of file diff --git a/resources/assets/sass/_buttons.scss b/resources/assets/sass/_buttons.scss index 202eb935b..f9c6d9b9a 100644 --- a/resources/assets/sass/_buttons.scss +++ b/resources/assets/sass/_buttons.scss @@ -2,9 +2,12 @@ @mixin generate-button-colors($textColor, $backgroundColor) { background-color: $backgroundColor; color: $textColor; + text-transform: uppercase; + border: 1px solid $backgroundColor; + vertical-align: top; &:hover { background-color: lighten($backgroundColor, 8%); - box-shadow: $bs-med; + //box-shadow: $bs-med; text-decoration: none; color: $textColor; } @@ -26,16 +29,16 @@ $button-border-radius: 2px; text-decoration: none; font-size: $fs-m; line-height: 1.4em; - padding: $-xs $-m; + padding: $-xs*1.3 $-m; margin: $-xs $-xs $-xs 0; display: inline-block; border: none; - font-weight: 500; + font-weight: 400; outline: 0; border-radius: $button-border-radius; cursor: pointer; transition: all ease-in-out 120ms; - box-shadow: 0 0.5px 1.5px 0 rgba(0, 0, 0, 0.21); + box-shadow: 0; @include generate-button-colors(#EEE, $primary); } @@ -51,13 +54,47 @@ $button-border-radius: 2px; @include generate-button-colors(#EEE, $secondary); } &.muted { - @include generate-button-colors(#EEE, #888); + @include generate-button-colors(#EEE, #AAA); } &.muted-light { @include generate-button-colors(#666, #e4e4e4); } } +.button.outline { + background-color: transparent; + color: #888; + border: 1px solid #DDD; + &:hover, &:focus, &:active { + box-shadow: none; + background-color: #EEE; + } + &.page { + border-color: $color-page; + color: $color-page; + &:hover, &:focus, &:active { + background-color: $color-page; + color: #FFF; + } + } + &.chapter { + border-color: $color-chapter; + color: $color-chapter; + &:hover, &:focus, &:active { + background-color: $color-chapter; + color: #FFF; + } + } + &.book { + border-color: $color-book; + color: $color-book; + &:hover, &:focus, &:active { + background-color: $color-book; + color: #FFF; + } + } +} + .text-button { @extend .link; background-color: transparent; diff --git a/resources/assets/sass/_codemirror.scss b/resources/assets/sass/_codemirror.scss index e281d4c0d..89ed0f54e 100644 --- a/resources/assets/sass/_codemirror.scss +++ b/resources/assets/sass/_codemirror.scss @@ -366,9 +366,9 @@ span.CodeMirror-selectedtext { background: none; } .cm-s-base16-light span.cm-atom { color: #aa759f; } .cm-s-base16-light span.cm-number { color: #aa759f; } -.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; } +.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #678c30; } .cm-s-base16-light span.cm-keyword { color: #ac4142; } -.cm-s-base16-light span.cm-string { color: #f4bf75; } +.cm-s-base16-light span.cm-string { color: #e09c3c; } .cm-s-base16-light span.cm-variable { color: #90a959; } .cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; } @@ -392,7 +392,7 @@ span.CodeMirror-selectedtext { background: none; } } .cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 1px solid #DDD; } -.flex-fill .CodeMirror { +.code-fill .CodeMirror { position: absolute; top: 0; bottom: 0; diff --git a/resources/assets/sass/_forms.scss b/resources/assets/sass/_forms.scss index d372359cc..700c15336 100644 --- a/resources/assets/sass/_forms.scss +++ b/resources/assets/sass/_forms.scss @@ -2,14 +2,13 @@ .input-base { background-color: #FFF; border-radius: 3px; - border: 1px solid #CCC; + border: 1px solid #D4D4D4; display: inline-block; font-size: $fs-s; - padding: $-xs; - color: #222; + padding: $-xs*1.5; + color: #666; width: 250px; max-width: 100%; - //-webkit-appearance:none; &.neg, &.invalid { border: 1px solid $negative; } @@ -24,6 +23,11 @@ } } +.fake-input { + @extend .input-base; + overflow: auto; +} + #html-editor { display: none; } @@ -84,8 +88,9 @@ label { display: block; line-height: 1.4em; font-size: 0.94em; - font-weight: 500; - color: #666; + font-weight: 400; + color: #999; + text-transform: uppercase; padding-bottom: 2px; margin-bottom: 0.2em; &.inline { @@ -186,28 +191,15 @@ input:checked + .toggle-switch { } .inline-input-style { - border: 2px dotted #BBB; display: block; width: 100%; - padding: $-xs $-s; -} - -.title-input .input { - width: 100%; -} - -.title-input label, .description-input label{ - margin-top: $-m; - color: #666; + padding: $-s; } .title-input input[type="text"] { - @extend h1; @extend .inline-input-style; margin-top: 0; - padding-right: 0; - width: 100%; - color: #444; + font-size: 2em; } .title-input.page-title { @@ -250,8 +242,8 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] { padding: 0; cursor: pointer; position: absolute; - left: 7px; - top: 7px; + left: 8px; + top: 9.5px; } input { display: block; diff --git a/resources/assets/sass/_grid.scss b/resources/assets/sass/_grid.scss index de1ee83fb..d24ffcfaf 100644 --- a/resources/assets/sass/_grid.scss +++ b/resources/assets/sass/_grid.scss @@ -20,19 +20,122 @@ body.flexbox { align-items: stretch; min-height: 0; position: relative; - .flex, &.flex { - min-height: 0; - flex: 1; + &.rows { + flex-direction: row; } + &.columns { + flex-direction: column; + } +} + +.flex { + min-height: 0; + flex: 1; +} + +.flex.scroll { + //overflow-y: auto; + display: flex; + &.sidebar { + margin-right: -14px; + } +} +.flex.scroll .scroll-body { + overflow-y: scroll; + flex: 1; } .flex-child > div { flex: 1; } -//body.ie .flex-child > div { -// flex: 1 0 0px; -//} +.flex.sidebar { + flex: 1; + background-color: #F2F2F2; + max-width: 360px; + min-height: 90vh; +} +.flex.sidebar + .flex.content { + flex: 3; + background-color: #FFFFFF; + padding: 0 $-l; + border-left: 1px solid #DDD; + max-width: 100%; +} +.flex.sidebar .sidebar-toggle { + display: none; +} + +@include smaller-than($xl) { + body.sidebar-layout { + padding-left: 30px; + } + .flex.sidebar { + position: fixed; + top: 0; + left: 0; + bottom: 0; + z-index: 100; + padding-right: 30px; + width: 360px; + box-shadow: none; + transform: translate3d(-330px, 0, 0); + transition: transform ease-in-out 120ms; + } + .flex.sidebar.open { + box-shadow: 1px 2px 2px 1px rgba(0,0,0,.10); + transform: translate3d(0, 0, 0); + .sidebar-toggle i { + transform: rotate(180deg); + } + } + .flex.sidebar .sidebar-toggle { + display: block; + position: absolute; + opacity: 0.9; + right: 0; + top: 0; + bottom: 0; + width: 30px; + color: #666; + font-size: 20px; + vertical-align: middle; + text-align: center; + border: 1px solid #DDD; + border-top: 1px solid #BBB; + padding-top: $-m; + cursor: pointer; + i { + opacity: 0.5; + transition: all ease-in-out 120ms; + padding: 0; + } + &:hover i { + opacity: 1; + } + } + #sidebar .scroll-body.fixed { + width: auto !important; + } +} + +@include larger-than($xl) { + #sidebar .scroll-body.fixed { + z-index: 5; + position: fixed; + top: 0; + padding-right: $-m; + width: 30%; + left: 0; + height: 100%; + overflow-y: scroll; + -ms-overflow-style: none; + //background-color: $primary-faded; + border-left: 1px solid #DDD; + &::-webkit-scrollbar { width: 0 !important } + } +} + /** Rules for all columns */ div[class^="col-"] img { diff --git a/resources/assets/sass/_header.scss b/resources/assets/sass/_header.scss index 49bd74b07..b9d9d68ef 100644 --- a/resources/assets/sass/_header.scss +++ b/resources/assets/sass/_header.scss @@ -85,7 +85,7 @@ header { } header .search-box { display: inline-block; - margin-top: $-s; + margin-top: 10px; input { background-color: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.3); @@ -171,6 +171,10 @@ header .search-box { background-color: $primary-faded; } +.toolbar-container { + background-color: #FFF; +} + .breadcrumbs .text-button, .action-buttons .text-button { display: inline-block; padding: $-s; diff --git a/resources/assets/sass/_html.scss b/resources/assets/sass/_html.scss index 27ca04eb7..65f05a71d 100644 --- a/resources/assets/sass/_html.scss +++ b/resources/assets/sass/_html.scss @@ -9,6 +9,9 @@ html { &.flexbox { overflow-y: hidden; } + &.shaded { + background-color: #F2F2F2; + } } body { @@ -16,6 +19,9 @@ body { line-height: 1.6; color: #616161; -webkit-font-smoothing: antialiased; + &.shaded { + background-color: #F2F2F2; + } } button { diff --git a/resources/assets/sass/_lists.scss b/resources/assets/sass/_lists.scss index d08ccc9bb..2dd4732f2 100644 --- a/resources/assets/sass/_lists.scss +++ b/resources/assets/sass/_lists.scss @@ -86,31 +86,8 @@ // Sidebar list .book-tree { - padding: $-xs 0 0 0; - position: relative; - right: 0; - top: 0; transition: ease-in-out 240ms; transition-property: right, border; - border-left: 0px solid #FFF; - background-color: #FFF; - max-width: 320px; - &.fixed { - background-color: #FFF; - z-index: 5; - position: fixed; - top: 0; - padding-left: $-l; - padding-right: $-l + 15; - width: 30%; - right: -15px; - height: 100%; - overflow-y: scroll; - -ms-overflow-style: none; - //background-color: $primary-faded; - border-left: 1px solid #DDD; - &::-webkit-scrollbar { width: 0 !important } - } } .book-tree h4 { padding: $-m $-s 0 $-s; @@ -245,6 +222,9 @@ .left + .right { margin-left: 30px + $-s; } + &:last-of-type { + border-bottom: 0; + } } ul.pagination { @@ -297,9 +277,6 @@ ul.pagination { h4 { margin: 0; } - p { - margin: $-xs 0 0 0; - } hr { margin: 0; } @@ -316,6 +293,11 @@ ul.pagination { } } +.card .entity-list-item, .card .activity-list-item { + padding-left: $-m; + padding-right: $-m; +} + .entity-list.compact { font-size: 0.6em; h4, a { @@ -324,9 +306,11 @@ ul.pagination { .entity-item-snippet { display: none; } - p { + .entity-list-item p { font-size: $fs-m * 0.8; padding-top: $-xs; + } + p { margin: 0; } > p.empty-text { diff --git a/resources/assets/sass/_pages.scss b/resources/assets/sass/_pages.scss index 65fdfbc4b..f73bbd546 100755 --- a/resources/assets/sass/_pages.scss +++ b/resources/assets/sass/_pages.scss @@ -1,12 +1,3 @@ -#page-show { - >.row .col-md-9 { - z-index: 2; - } - >.row .col-md-3 { - z-index: 1; - } -} - .page-editor { display: flex; flex-direction: column; @@ -36,6 +27,8 @@ .page-content { max-width: 840px; + margin: 0 auto; + margin-top: $-xxl; overflow-wrap: break-word; .align-left { text-align: left; @@ -252,8 +245,6 @@ } .tag-display { - width: 100%; - //opacity: 0.7; position: relative; table { width: 100%; diff --git a/resources/assets/sass/_text.scss b/resources/assets/sass/_text.scss index d38a5c515..719126526 100644 --- a/resources/assets/sass/_text.scss +++ b/resources/assets/sass/_text.scss @@ -2,7 +2,7 @@ * Fonts */ -body, button, input, select, label { +body, button, input, select, label, textarea { font-family: $text; } .Codemirror, pre, #markdown-editor-input, .editor-toolbar, .code-base { @@ -378,12 +378,6 @@ span.sep { display: block; } -.action-header { - h1 { - margin-top: $-m; - } -} - /** * Icons */ diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss index 51e47ea74..b0b41afc7 100644 --- a/resources/assets/sass/styles.scss +++ b/resources/assets/sass/styles.scss @@ -217,22 +217,15 @@ $btt-size: 40px; } .center-box { - margin: $-xl auto 0 auto; - padding: $-m $-xxl $-xl $-xxl; + margin: $-xxl auto 0 auto; width: 420px; max-width: 100%; display: inline-block; text-align: left; vertical-align: top; - //border: 1px solid #DDD; input { width: 100%; } - &.login { - background-color: #EEE; - box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1); - border: 1px solid #DDD; - } } diff --git a/resources/lang/en/common.php b/resources/lang/en/common.php index 9f35ddac7..8af2e4b2c 100644 --- a/resources/lang/en/common.php +++ b/resources/lang/en/common.php @@ -10,6 +10,7 @@ return [ 'save' => 'Save', 'continue' => 'Continue', 'select' => 'Select', + 'more' => 'More', /** * Form Labels @@ -36,7 +37,6 @@ return [ 'remove' => 'Remove', 'add' => 'Add', - /** * Misc */ @@ -46,7 +46,7 @@ return [ 'back_to_top' => 'Back to top', 'toggle_details' => 'Toggle Details', 'toggle_thumbnails' => 'Toggle Thumbnails', - + 'details' => 'Details', /** * Header */ diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index 43053df10..b8be379cd 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -73,11 +73,13 @@ return [ 'books_empty' => 'No books have been created', 'books_popular' => 'Popular Books', 'books_recent' => 'Recent Books', + 'books_new' => 'New Books', 'books_popular_empty' => 'The most popular books will appear here.', + 'books_new_empty' => 'The most recently created books will appear here.', 'books_create' => 'Create New Book', 'books_delete' => 'Delete Book', 'books_delete_named' => 'Delete Book :bookName', - 'books_delete_explain' => 'This will delete the book with the name \':bookName\', All pages and chapters will be removed.', + 'books_delete_explain' => 'This will delete the book with the name \':bookName\'. All pages and chapters will be removed.', 'books_delete_confirmation' => 'Are you sure you want to delete this book?', 'books_edit' => 'Edit Book', 'books_edit_named' => 'Edit Book :bookName', @@ -108,8 +110,7 @@ return [ 'chapters_create' => 'Create New Chapter', 'chapters_delete' => 'Delete Chapter', 'chapters_delete_named' => 'Delete Chapter :chapterName', - 'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\', All pages will be removed - and added directly to the parent book.', + 'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\'. All pages will be removed and added directly to the parent book.', 'chapters_delete_confirm' => 'Are you sure you want to delete this chapter?', 'chapters_edit' => 'Edit Chapter', 'chapters_edit_named' => 'Edit Chapter :chapterName', @@ -164,6 +165,7 @@ return [ 'pages_move_success' => 'Page moved to ":parentName"', 'pages_permissions' => 'Page Permissions', 'pages_permissions_success' => 'Page permissions updated', + 'pages_revision' => 'Revision', 'pages_revisions' => 'Page Revisions', 'pages_revisions_named' => 'Page Revisions for :pageName', 'pages_revision_named' => 'Page Revision for :pageName', diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index 0a7547a58..14b5371ff 100644 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -31,6 +31,9 @@ return [ 'app_logo_desc' => 'This image should be 43px in height.
Large images will be scaled down.', 'app_primary_color' => 'Application primary color', 'app_primary_color_desc' => 'This should be a hex value.
Leave empty to reset to the default color.', + 'app_homepage' => 'Application Homepage', + 'app_homepage_desc' => 'Select a page to show on the homepage instead of the default view. Page permissions are ignored for selected pages.', + 'app_homepage_default' => 'Default homepage view chosen', /** * Registration settings diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 706747b8b..dda733645 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -9,36 +9,38 @@ @section('content')
-
-

{{ title_case(trans('auth.log_in')) }}

+
+

{{ title_case(trans('auth.log_in')) }}

-
- {!! csrf_field() !!} +
+ + {!! csrf_field() !!} - @include('auth/forms/login/' . $authMethod) + @include('auth/forms/login/' . $authMethod) -
- - - -
+
+ + + +
-
- -
- +
+ +
+ - @if(count($socialDrivers) > 0) -
- @foreach($socialDrivers as $driver => $name) - - @icon($driver) - {{ trans('auth.log_in_with', ['socialDriver' => $name]) }} - - @endforeach - @endif + @if(count($socialDrivers) > 0) +
+ @foreach($socialDrivers as $driver => $name) + + @icon($driver) + {{ trans('auth.log_in_with', ['socialDriver' => $name]) }} + + @endforeach + @endif +
diff --git a/resources/views/auth/register-confirm.blade.php b/resources/views/auth/register-confirm.blade.php index 364df9266..5d945ef81 100644 --- a/resources/views/auth/register-confirm.blade.php +++ b/resources/views/auth/register-confirm.blade.php @@ -9,9 +9,11 @@ @section('content')
-
-

{{ trans('auth.register_thanks') }}

-

{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}

+
+

{{ trans('auth.register_thanks') }}

+
+

{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}

+
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index d5db4afa8..7b319d30c 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -7,41 +7,42 @@ @section('content')
-
-

{{ title_case(trans('auth.sign_up')) }}

+
+

{{ title_case(trans('auth.sign_up')) }}

+
+
+ {!! csrf_field() !!} - - {!! csrf_field() !!} +
+ + @include('form/text', ['name' => 'name']) +
-
- - @include('form/text', ['name' => 'name']) -
+
+ + @include('form/text', ['name' => 'email']) +
-
- - @include('form/text', ['name' => 'email']) -
+
+ + @include('form/password', ['name' => 'password', 'placeholder' => trans('auth.password_hint')]) +
-
- - @include('form/password', ['name' => 'password', 'placeholder' => trans('auth.password_hint')]) -
+
+ +
+
-
- -
- - - @if(count($socialDrivers) > 0) -
- @foreach($socialDrivers as $driver => $name) - - @icon($driver) - {{ trans('auth.sign_up_with', ['socialDriver' => $name]) }} - - @endforeach - @endif + @if(count($socialDrivers) > 0) +
+ @foreach($socialDrivers as $driver => $name) + + @icon($driver) + {{ trans('auth.sign_up_with', ['socialDriver' => $name]) }} + + @endforeach + @endif +
diff --git a/resources/views/auth/user-unconfirmed.blade.php b/resources/views/auth/user-unconfirmed.blade.php index 13567b412..22c26d92b 100644 --- a/resources/views/auth/user-unconfirmed.blade.php +++ b/resources/views/auth/user-unconfirmed.blade.php @@ -2,29 +2,33 @@ @section('content') -
-
-

{{ trans('auth.email_not_confirmed') }}

-

{{ trans('auth.email_not_confirmed_text') }}
- {{ trans('auth.email_not_confirmed_click_link') }}
- {{ trans('auth.email_not_confirmed_resend') }} -

-
-
- {!! csrf_field() !!} -
- - @if(auth()->check()) - @include('form/text', ['name' => 'email', 'model' => auth()->user()]) - @else - @include('form/text', ['name' => 'email']) - @endif -
-
- -
-
+
+

 

+
+

{{ trans('auth.email_not_confirmed') }}

+
+

{{ trans('auth.email_not_confirmed_text') }}
+ {{ trans('auth.email_not_confirmed_click_link') }}
+ {{ trans('auth.email_not_confirmed_resend') }} +

+
+
+ {!! csrf_field() !!} +
+ + @if(auth()->check()) + @include('form/text', ['name' => 'email', 'model' => auth()->user()]) + @else + @include('form/text', ['name' => 'email']) + @endif +
+
+ +
+
+
+
@stop diff --git a/resources/views/base.blade.php b/resources/views/base.blade.php index 1c972e4fb..edbd6a096 100644 --- a/resources/views/base.blade.php +++ b/resources/views/base.blade.php @@ -34,7 +34,7 @@ @include('partials/notifications')