diff --git a/js/admin/Gulpfile.js b/js/admin/Gulpfile.js index c695c9a1e..51da8cfb4 100644 --- a/js/admin/Gulpfile.js +++ b/js/admin/Gulpfile.js @@ -1,22 +1,33 @@ var gulp = require('flarum-gulp'); +var nodeDir = 'node_modules'; +var bowerDir = '../bower_components'; + gulp({ files: [ - 'node_modules/babel-core/external-helpers.js', - '../bower_components/loader.js/loader.js', - '../bower_components/mithril/mithril.js', - '../bower_components/jquery/dist/jquery.js', - '../bower_components/moment/moment.js', - '../bower_components/bootstrap/dist/js/bootstrap.js', - '../bower_components/spin.js/spin.js', - '../bower_components/spin.js/jquery.spin.js' + nodeDir + '/babel-core/external-helpers.js', + + bowerDir + '/es6-micro-loader/dist/system-polyfill.js', + + bowerDir + '/mithril/mithril.js', + bowerDir + '/jquery/dist/jquery.js', + bowerDir + '/moment/moment.js', + + bowerDir + '/bootstrap/js/affix.js', + bowerDir + '/bootstrap/js/dropdown.js', + bowerDir + '/bootstrap/js/modal.js', + bowerDir + '/bootstrap/js/tooltip.js', + bowerDir + '/bootstrap/js/transition.js', + + bowerDir + '/spin.js/spin.js', + bowerDir + '/spin.js/jquery.spin.js' ], - moduleFiles: [ - 'src/**/*.js', - '../lib/**/*.js' - ], - bootstrapFiles: [], - modulePrefix: 'flarum', + modules: { + 'flarum': [ + 'src/**/*.js', + '../lib/**/*.js' + ] + }, externalHelpers: true, outputFile: 'dist/app.js' }); diff --git a/js/admin/src/app.js b/js/admin/src/app.js index 3176fa486..a479ada87 100644 --- a/js/admin/src/app.js +++ b/js/admin/src/app.js @@ -1,18 +1,15 @@ -import App from 'flarum/utils/app'; +import App from 'flarum/App'; import store from 'flarum/initializers/store'; import preload from 'flarum/initializers/preload'; -import session from 'flarum/initializers/session'; import routes from 'flarum/initializers/routes'; -import timestamps from 'flarum/initializers/timestamps'; import boot from 'flarum/initializers/boot'; -var app = new App(); +const app = new App(); app.initializers.add('store', store); -app.initializers.add('session', session); app.initializers.add('routes', routes); -app.initializers.add('timestamps', timestamps); -app.initializers.add('preload', preload, {last: true}); -app.initializers.add('boot', boot, {last: true}); +app.initializers.add('preload', preload, -100); + +app.initializers.add('boot', boot, -100); export default app; diff --git a/js/admin/src/components/AdminLinkButton.js b/js/admin/src/components/AdminLinkButton.js new file mode 100644 index 000000000..38a643bb4 --- /dev/null +++ b/js/admin/src/components/AdminLinkButton.js @@ -0,0 +1,15 @@ +import LinkButton from 'flarum/components/LinkButton'; + +export default class AdminLinkButton extends LinkButton { + getButtonContent() { + const content = super.getButtonContent(); + + content.push( +
+ {this.props.description} +
+ ); + + return content; + } +} diff --git a/js/admin/src/components/AdminNav.js b/js/admin/src/components/AdminNav.js new file mode 100644 index 000000000..41827fd01 --- /dev/null +++ b/js/admin/src/components/AdminNav.js @@ -0,0 +1,56 @@ +import Component from 'flarum/Component'; +import AdminLinkButton from 'flarum/components/AdminLinkButton'; +import SelectDropdown from 'flarum/components/SelectDropdown'; + +import ItemList from 'flarum/utils/ItemList'; + +export default class AdminNav extends Component { + view() { + return SelectDropdown.component({ + className: 'AdminNav App-titleControl', + buttonClassName: 'Button', + children: this.items().toArray() + }); + } + + items() { + const items = new ItemList(); + + items.add('dashboard', AdminLinkButton.component({ + href: app.route('dashboard'), + icon: 'bar-chart', + children: 'Dashboard', + description: 'Your forum at a glance.' + })); + + items.add('basics', AdminLinkButton.component({ + href: app.route('basics'), + icon: 'pencil', + children: 'Basics', + description: 'Set your forum title, language, and other basic settings.' + })); + + items.add('permissions', AdminLinkButton.component({ + href: app.route('permissions'), + icon: 'key', + children: 'Permissions', + description: 'Configure who can see and do what.' + })); + + items.add('appearance', AdminLinkButton.component({ + href: app.route('appearance'), + icon: 'paint-brush', + children: 'Appearance', + description: 'Customize your forum\'s colors, logos, and other variables.' + })); + + items.add('extensions', AdminLinkButton.component({ + href: app.route('extensions'), + icon: 'puzzle-piece', + children: 'Extensions', + description: 'Add extra functionality to your forum and make it your own.' + })); + + return items; + } +} diff --git a/js/admin/src/components/AppearancePage.js b/js/admin/src/components/AppearancePage.js new file mode 100644 index 000000000..448d9abba --- /dev/null +++ b/js/admin/src/components/AppearancePage.js @@ -0,0 +1,9 @@ +import Component from 'flarum/Component'; + +export default class AppearancePage extends Component { + view() { + return ( +
+ ); + } +} diff --git a/js/admin/src/components/DashboardPage.js b/js/admin/src/components/DashboardPage.js new file mode 100644 index 000000000..93534b5a3 --- /dev/null +++ b/js/admin/src/components/DashboardPage.js @@ -0,0 +1,16 @@ +import Component from 'flarum/Component'; + +export default class DashboardPage extends Component { + view() { + return ( +
+
+

Welcome to Flarum Beta

+

This is beta software; you shouldn't use it in production.

+

You're running version X

+

Get help on X. Report bugs here. Feedback here. Contribute here.

+
+
+ ); + } +} diff --git a/js/admin/src/components/ExtensionsPage.js b/js/admin/src/components/ExtensionsPage.js new file mode 100644 index 000000000..eb7101c3c --- /dev/null +++ b/js/admin/src/components/ExtensionsPage.js @@ -0,0 +1,9 @@ +import Component from 'flarum/Component'; + +export default class ExtensionsPage extends Component { + view() { + return ( +
+ ); + } +} diff --git a/js/admin/src/components/HeaderPrimary.js b/js/admin/src/components/HeaderPrimary.js new file mode 100644 index 000000000..34ffc203c --- /dev/null +++ b/js/admin/src/components/HeaderPrimary.js @@ -0,0 +1,26 @@ +import Component from 'flarum/Component'; +import ItemList from 'flarum/utils/ItemList'; +import listItems from 'flarum/helpers/listItems'; + +/** + * The `HeaderPrimary` component displays primary header controls. On the + * default skin, these are shown just to the right of the forum title. + */ +export default class HeaderPrimary extends Component { + view() { + return ( + + ); + } + + /** + * Build an item list for the controls. + * + * @return {ItemList} + */ + items() { + return new ItemList(); + } +} diff --git a/js/admin/src/components/HeaderSecondary.js b/js/admin/src/components/HeaderSecondary.js new file mode 100644 index 000000000..cc1f0b268 --- /dev/null +++ b/js/admin/src/components/HeaderSecondary.js @@ -0,0 +1,30 @@ +import Component from 'flarum/Component'; +import SessionDropdown from 'flarum/components/SessionDropdown'; +import ItemList from 'flarum/utils/ItemList'; +import listItems from 'flarum/helpers/listItems'; + +/** + * The `HeaderSecondary` component displays secondary header controls. + */ +export default class HeaderSecondary extends Component { + view() { + return ( + + ); + } + + /** + * Build an item list for the controls. + * + * @return {ItemList} + */ + items() { + const items = new ItemList(); + + items.add('session', SessionDropdown.component()); + + return items; + } +} diff --git a/js/admin/src/components/SessionDropdown.js b/js/admin/src/components/SessionDropdown.js new file mode 100644 index 000000000..f4a21f159 --- /dev/null +++ b/js/admin/src/components/SessionDropdown.js @@ -0,0 +1,54 @@ +import avatar from 'flarum/helpers/avatar'; +import username from 'flarum/helpers/username'; +import Dropdown from 'flarum/components/Dropdown'; +import Button from 'flarum/components/Button'; +import ItemList from 'flarum/utils/ItemList'; + +/** + * The `SessionDropdown` component shows a button with the current user's + * avatar/name, with a dropdown of session controls. + */ +export default class SessionDropdown extends Dropdown { + static initProps(props) { + super.initProps(props); + + props.className = 'SessionDropdown'; + props.buttonClassName = 'Button Button--user Button--flat'; + props.menuClassName = 'Dropdown-menu--right'; + } + + view() { + this.props.children = this.items().toArray(); + + return super.view(); + } + + getButtonContent() { + const user = app.session.user; + + return [ + avatar(user), ' ', + {username(user)} + ]; + } + + /** + * Build an item list for the contents of the dropdown menu. + * + * @return {ItemList} + */ + items() { + const items = new ItemList(); + + items.add('logOut', + Button.component({ + icon: 'sign-out', + children: app.trans('core.log_out'), + onclick: app.session.logout.bind(app.session) + }), + -100 + ); + + return items; + } +} diff --git a/js/admin/src/components/admin-nav-item.js b/js/admin/src/components/admin-nav-item.js deleted file mode 100644 index 2f05cab67..000000000 --- a/js/admin/src/components/admin-nav-item.js +++ /dev/null @@ -1,14 +0,0 @@ -import Component from 'flarum/component'; -import icon from 'flarum/helpers/icon'; -import NavItem from 'flarum/components/nav-item'; - -export default class AdminNavItem extends NavItem { - view() { - var active = this.constructor.active(this.props); - return m('li'+(active ? '.active' : ''), m('a', {href: this.props.href, config: m.route}, [ - icon(this.props.icon+' icon'), - m('span.label', this.props.label), - m('div.description', this.props.description) - ])) - } -} diff --git a/js/admin/src/components/admin-nav.js b/js/admin/src/components/admin-nav.js deleted file mode 100644 index bd9c042ee..000000000 --- a/js/admin/src/components/admin-nav.js +++ /dev/null @@ -1,54 +0,0 @@ -import Component from 'flarum/component'; -import UserDropdown from 'flarum/components/user-dropdown'; -import AdminNavItem from 'flarum/components/admin-nav-item'; -import DropdownSelect from 'flarum/components/dropdown-select'; - -import ItemList from 'flarum/utils/item-list'; -import listItems from 'flarum/helpers/list-items'; - -export default class AdminNav extends Component { - view() { - return DropdownSelect.component({ items: this.items().toArray() }); - } - - items() { - var items = new ItemList(); - - items.add('dashboard', AdminNavItem.component({ - href: app.route('dashboard'), - icon: 'bar-chart', - label: 'Dashboard', - description: 'Your forum at a glance.' - })); - - items.add('basics', AdminNavItem.component({ - href: app.route('basics'), - icon: 'pencil', - label: 'Basics', - description: 'Set your forum title, language, and other basic settings.' - })); - - items.add('permissions', AdminNavItem.component({ - href: app.route('permissions'), - icon: 'key', - label: 'Permissions', - description: 'Configure who can see and do what.' - })); - - items.add('appearance', AdminNavItem.component({ - href: app.route('appearance'), - icon: 'paint-brush', - label: 'Appearance', - description: 'Customize your forum\'s colors, logos, and other variables.' - })); - - items.add('extensions', AdminNavItem.component({ - href: app.route('extensions'), - icon: 'puzzle-piece', - label: 'Extensions', - description: 'Add extra functionality to your forum and make it your own.' - })); - - return items; - } -} diff --git a/js/admin/src/components/appearance-page.js b/js/admin/src/components/appearance-page.js deleted file mode 100644 index 5d1ddd2f1..000000000 --- a/js/admin/src/components/appearance-page.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from 'flarum/component'; - -export default class AppearancePage extends Component { - view() { - return m('div', 'appearance'); - } -}; diff --git a/js/admin/src/components/basics-page.js b/js/admin/src/components/basics-page.js deleted file mode 100644 index c5baf8a77..000000000 --- a/js/admin/src/components/basics-page.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from 'flarum/component'; - -export default class BasicsPage extends Component { - view() { - return m('div', 'basics'); - } -}; diff --git a/js/admin/src/components/dashboard-page.js b/js/admin/src/components/dashboard-page.js deleted file mode 100644 index d9dc00acb..000000000 --- a/js/admin/src/components/dashboard-page.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from 'flarum/component'; - -export default class DashboardPage extends Component { - view() { - return m('div', 'dashboard'); - } -}; diff --git a/js/admin/src/components/extensions-page.js b/js/admin/src/components/extensions-page.js deleted file mode 100644 index c1fe5e793..000000000 --- a/js/admin/src/components/extensions-page.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from 'flarum/component'; - -export default class ExtensionsPage extends Component { - view() { - return m('div', 'extensions'); - } -}; diff --git a/js/admin/src/components/header-primary.js b/js/admin/src/components/header-primary.js deleted file mode 100644 index 166a7b6cc..000000000 --- a/js/admin/src/components/header-primary.js +++ /dev/null @@ -1,15 +0,0 @@ -import Component from 'flarum/component'; -import ItemList from 'flarum/utils/item-list'; -import listItems from 'flarum/helpers/list-items'; - -export default class HeaderPrimary extends Component { - view() { - return m('ul.header-controls', listItems(this.items().toArray())); - } - - items() { - var items = new ItemList(); - - return items; - } -} diff --git a/js/admin/src/components/header-secondary.js b/js/admin/src/components/header-secondary.js deleted file mode 100644 index c48343c05..000000000 --- a/js/admin/src/components/header-secondary.js +++ /dev/null @@ -1,19 +0,0 @@ -import Component from 'flarum/component'; -import UserDropdown from 'flarum/components/user-dropdown'; - -import ItemList from 'flarum/utils/item-list'; -import listItems from 'flarum/helpers/list-items'; - -export default class HeaderSecondary extends Component { - view() { - return m('ul.header-controls', listItems(this.items().toArray())); - } - - items() { - var items = new ItemList(); - - items.add('user', UserDropdown.component({ user: app.session.user })); - - return items; - } -} diff --git a/js/admin/src/components/permissions-page.js b/js/admin/src/components/permissions-page.js deleted file mode 100644 index bc4c0ba4a..000000000 --- a/js/admin/src/components/permissions-page.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from 'flarum/component'; - -export default class PermissionsPage extends Component { - view() { - return m('div', 'permissions'); - } -}; diff --git a/js/admin/src/components/user-dropdown.js b/js/admin/src/components/user-dropdown.js deleted file mode 100644 index 1bbbc60f5..000000000 --- a/js/admin/src/components/user-dropdown.js +++ /dev/null @@ -1,35 +0,0 @@ -import Component from 'flarum/component'; -import avatar from 'flarum/helpers/avatar'; -import username from 'flarum/helpers/username'; -import DropdownButton from 'flarum/components/dropdown-button'; -import ActionButton from 'flarum/components/action-button'; -import ItemList from 'flarum/utils/item-list'; -import Separator from 'flarum/components/separator'; - -export default class UserDropdown extends Component { - view() { - var user = this.props.user; - - return DropdownButton.component({ - buttonClass: 'btn btn-default btn-naked btn-rounded btn-user', - menuClass: 'pull-right', - buttonContent: [avatar(user), ' ', m('span.label', username(user))], - items: this.items().toArray() - }); - } - - items() { - var items = new ItemList(); - var user = this.props.user; - - items.add('logOut', - ActionButton.component({ - icon: 'sign-out', - label: 'Log Out', - onclick: app.session.logout.bind(app.session) - }) - ); - - return items; - } -} diff --git a/js/admin/src/initializers/boot.js b/js/admin/src/initializers/boot.js index 52e4a4574..1463ed9d5 100644 --- a/js/admin/src/initializers/boot.js +++ b/js/admin/src/initializers/boot.js @@ -1,38 +1,54 @@ -import ScrollListener from 'flarum/utils/scroll-listener'; -import mapRoutes from 'flarum/utils/map-routes'; +/*global FastClick*/ -import BackButton from 'flarum/components/back-button'; -import HeaderPrimary from 'flarum/components/header-primary'; -import HeaderSecondary from 'flarum/components/header-secondary'; -import Modal from 'flarum/components/modal'; -import Alerts from 'flarum/components/alerts'; -import AdminNav from 'flarum/components/admin-nav'; +import ScrollListener from 'flarum/utils/ScrollListener'; +import Drawer from 'flarum/utils/Drawer'; +import mapRoutes from 'flarum/utils/mapRoutes'; -export default function(app) { - var id = id => document.getElementById(id); +import Navigation from 'flarum/components/Navigation'; +import HeaderPrimary from 'flarum/components/HeaderPrimary'; +import HeaderSecondary from 'flarum/components/HeaderSecondary'; +import AdminNav from 'flarum/components/AdminNav'; +import ModalManager from 'flarum/components/ModalManager'; +import AlertManager from 'flarum/components/AlertManager'; +/** + * The `boot` initializer boots up the admin app. It initializes some app + * globals, mounts components to the page, and begins routing. + * + * @param {ForumApp} app + */ +export default function boot(app) { + m.startComputation(); + + m.mount(document.getElementById('app-navigation'), Navigation.component({className: 'App-backControl', drawer: true})); + m.mount(document.getElementById('header-navigation'), Navigation.component()); + m.mount(document.getElementById('header-primary'), HeaderPrimary.component()); + m.mount(document.getElementById('header-secondary'), HeaderSecondary.component()); + m.mount(document.getElementById('admin-navigation'), AdminNav.component()); + + app.drawer = new Drawer(); + app.modal = m.mount(document.getElementById('modal'), ModalManager.component()); + app.alerts = m.mount(document.getElementById('alerts'), AlertManager.component()); app.history = { - back: function() { - window.location = 'http://flarum.dev'; - }, - canGoBack: function() { - return true; - } + canGoBack: () => true, + back: () => window.location = '/' }; - m.mount(id('back-control'), BackButton.component({ className: 'back-control', drawer: true })); - m.mount(id('back-button'), BackButton.component()); - - m.mount(id('header-primary'), HeaderPrimary.component()); - m.mount(id('header-secondary'), HeaderSecondary.component()); - - m.mount(id('admin-nav'), AdminNav.component()); - - app.modal = m.mount(id('modal'), Modal.component()); - app.alerts = m.mount(id('alerts'), Alerts.component()); - m.route.mode = 'hash'; - m.route(id('content'), '/', mapRoutes(app.routes)); + m.route(document.getElementById('content'), '/', mapRoutes(app.routes)); - new ScrollListener(top => $('body').toggleClass('scrolled', top > 0)).start(); + m.endComputation(); + + // Add a class to the body which indicates that the page has been scrolled + // down. + new ScrollListener(top => { + const $app = $('#app'); + const offset = $app.offset().top; + + $app + .toggleClass('affix', top >= offset) + .toggleClass('scrolled', top > offset); + }).start(); + + app.booted = true; } diff --git a/js/admin/src/initializers/routes.js b/js/admin/src/initializers/routes.js index d0519bf82..5a5a416ae 100644 --- a/js/admin/src/initializers/routes.js +++ b/js/admin/src/initializers/routes.js @@ -1,15 +1,20 @@ -import DashboardPage from 'flarum/components/dashboard-page'; -import BasicsPage from 'flarum/components/basics-page'; -import PermissionsPage from 'flarum/components/permissions-page'; -import AppearancePage from 'flarum/components/appearance-page'; -import ExtensionsPage from 'flarum/components/extensions-page'; +import DashboardPage from 'flarum/components/DashboardPage'; +import BasicsPage from 'flarum/components/BasicsPage'; +import PermissionsPage from 'flarum/components/PermissionsPage'; +import AppearancePage from 'flarum/components/AppearancePage'; +import ExtensionsPage from 'flarum/components/ExtensionsPage'; +/** + * The `routes` initializer defines the admin app's routes. + * + * @param {App} app + */ export default function(app) { app.routes = { - 'dashboard': ['/', DashboardPage.component()], - 'basics': ['/basics', BasicsPage.component()], - 'permissions': ['/permissions', PermissionsPage.component()], - 'appearance': ['/appearance', AppearancePage.component()], - 'extensions': ['/extensions', ExtensionsPage.component()] + 'dashboard': {path: '/', component: DashboardPage.component()}, + 'basics': {path: '/basics', component: BasicsPage.component()}, + 'permissions': {path: '/permissions', component: PermissionsPage.component()}, + 'appearance': {path: '/appearance', component: AppearancePage.component()}, + 'extensions': {path: '/extensions', component: ExtensionsPage.component()} }; } diff --git a/js/forum/src/components/HeaderSecondary.js b/js/forum/src/components/HeaderSecondary.js index a2cd4d5d8..1146e93a4 100644 --- a/js/forum/src/components/HeaderSecondary.js +++ b/js/forum/src/components/HeaderSecondary.js @@ -8,7 +8,7 @@ import ItemList from 'flarum/utils/ItemList'; import listItems from 'flarum/helpers/listItems'; /** - * The `HeaderSecondary` component displays secondary footer controls, such as + * The `HeaderSecondary` component displays secondary header controls, such as * the search box and the user menu. On the default skin, these are shown on the * right side of the header. */ diff --git a/js/forum/src/utils/Drawer.js b/js/lib/utils/Drawer.js similarity index 100% rename from js/forum/src/utils/Drawer.js rename to js/lib/utils/Drawer.js diff --git a/less/admin/layout.less b/less/admin/AdminNav.less similarity index 58% rename from less/admin/layout.less rename to less/admin/AdminNav.less index 55321b134..21736abe5 100644 --- a/less/admin/layout.less +++ b/less/admin/AdminNav.less @@ -1,75 +1,79 @@ @admin-pane-width: 300px; -.admin-nav { - & .description { - display: none; - } +.App { + padding-bottom: 0; } -.admin-content { +.AdminLinkButton-description { + display: none; +} +.AdminContent { padding: 20px 0; } +.App-content .sideNavOffset { + margin-top: 0; +} @media @desktop, @desktop-hd { - .admin-nav { + .App-nav { position: fixed; top: @header-height; bottom: 0; width: @admin-pane-width; - box-shadow: 0 2px 6px @shadow-color; + .box-shadow(2px 2px 6px -2px @shadow-color); background: @body-bg; border-top: 1px solid @control-bg; - - & .dropdown-select .dropdown-menu > li { - & > a { + z-index: @zindex-pane; + overflow: auto; + } + .App-content .sideNavOffset { + margin-left: @admin-pane-width; + } + .App-nav .AdminNav { + .Dropdown-menu > li { + > a { padding: 15px 15px 15px 45px; display: block; text-decoration: none; white-space: normal; } - & > a, & > a:hover, &.active > a { + > a, > a:hover, &.active > a { color: @muted-color; } + > a:hover { + background: @control-bg; + } &.active > a { background: @control-bg; font-weight: normal; - & .label, & .icon { + .Button-label, .Button-icon { color: @text-color; - } - & .label { font-weight: bold; } } - &:hover:not(.active) { - & .label { - text-decoration: underline; - } - } } - & .icon { + .Button-icon { float: left; margin-left: -30px; font-size: 14px; - margin-top: 2px; + margin-top: 4px !important; } - & .label { + .Button-label { display: block; font-size: 15px; font-weight: normal; margin: 0 0 5px; } - & .description { + .AdminLinkButton-description { display: block; font-size: 12px; } } - .admin-content { - margin-left: @admin-pane-width; - padding: 20px; - } .container { width: 100%; + padding: 0 30px; + margin: 0; - .global-content & { + .App-content > & { padding: 0; } } diff --git a/less/admin/DashboardPage.less b/less/admin/DashboardPage.less new file mode 100644 index 000000000..eacbbe62b --- /dev/null +++ b/less/admin/DashboardPage.less @@ -0,0 +1,9 @@ +.DashboardPage { + @media @desktop-up { + .container { + max-width: 600px; + padding: 30px; + margin: 0; + } + } +} diff --git a/less/admin/app.less b/less/admin/app.less index f853751ac..ba08c19e1 100644 --- a/less/admin/app.less +++ b/less/admin/app.less @@ -1,24 +1,6 @@ -@lib-path: "../lib"; +@import "../lib/lib.less"; -@import "@{lib-path}/bootstrap.less"; - -// We want to specify the @fa-font-path variable AFTER we import font awesome -// so that it overrides the default definition. -@import "@{lib-path}/font-awesome/font-awesome.less"; -@fa-font-path: "/assets/fonts"; - -@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700,300,600); - -// Finally, with our vendor CSS loaded, we can import Flarum-specific stuff. -@import "@{lib-path}/components.less"; -@import "@{lib-path}/buttons.less"; -@import "@{lib-path}/badges.less"; -@import "@{lib-path}/dropdowns.less"; -@import "@{lib-path}/avatars.less"; -@import "@{lib-path}/forms.less"; -@import "@{lib-path}/alerts.less"; -@import "@{lib-path}/modals.less"; -@import "@{lib-path}/layout.less"; -@import "@{lib-path}/side-nav.less"; - -@import "layout.less"; +@import "AdminNav.less"; +@import "DashboardPage.less"; +@import "BasicsPage.less"; +@import "PermissionsPage.less"; diff --git a/less/lib/FormControl.less b/less/lib/FormControl.less index 64e472650..66c09f2ac 100755 --- a/less/lib/FormControl.less +++ b/less/lib/FormControl.less @@ -40,3 +40,9 @@ height: auto; } } +.helpText { + font-size: 12px; + line-height: 1.5em; + margin-bottom: 10px; + color: @muted-color; +} diff --git a/less/lib/scaffolding.less b/less/lib/scaffolding.less index a48c0db1b..1ad846488 100755 --- a/less/lib/scaffolding.less +++ b/less/lib/scaffolding.less @@ -93,55 +93,19 @@ input[type="search"] { -webkit-appearance: none; } -// Checkboxes and radios -// -// Indent the labels to position radios/checkboxes as hanging controls. +.checkbox { + display: block; + padding-left: 20px; + margin-bottom: 5px; + cursor: pointer; -// .radio, -// .checkbox { -// position: relative; -// display: block; -// margin-top: 10px; -// margin-bottom: 10px; - -// label { -// min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text -// padding-left: 20px; -// margin-bottom: 0; -// font-weight: normal; -// cursor: pointer; -// } -// } -// .radio input[type="radio"], -// .radio-inline input[type="radio"], -// .checkbox input[type="checkbox"], -// .checkbox-inline input[type="checkbox"] { -// position: absolute; -// margin-left: -20px; -// margin-top: 4px \9; -// } - -// .radio + .radio, -// .checkbox + .checkbox { -// margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing -// } - -// // Radios and checkboxes on same line -// .radio-inline, -// .checkbox-inline { -// position: relative; -// display: inline-block; -// padding-left: 20px; -// margin-bottom: 0; -// vertical-align: middle; -// font-weight: normal; -// cursor: pointer; -// } -// .radio-inline + .radio-inline, -// .checkbox-inline + .checkbox-inline { -// margin-top: 0; -// margin-left: 10px; // space out consecutive inline controls -// } + input[type=checkbox], + input[type=radio] { + margin-left: -20px; + margin-top: 2px; + float: left; + } +} .fade { opacity: 0; diff --git a/src/Admin/Actions/ClientAction.php b/src/Admin/Actions/ClientAction.php new file mode 100644 index 000000000..fa72b8d67 --- /dev/null +++ b/src/Admin/Actions/ClientAction.php @@ -0,0 +1,23 @@ +apiClient = $apiClient; - $this->actor = $actor; - } - - protected function render(Request $request, $routeParams = []) - { - $config = app('db')->table('config')->whereIn('key', ['base_url', 'api_url', 'forum_title', 'welcome_title', 'welcome_message'])->lists('value', 'key'); - $data = []; - $session = []; - - if (($user = $this->actor->getUser()) && $user->exists) { - $session = [ - 'userId' => $user->id, - 'token' => FigRequestCookies::get($request, 'flarum_remember'), - ]; - - $response = $this->apiClient->send('Flarum\Api\Actions\Users\ShowAction', ['id' => $user->id]); - - $data = [$response->data]; - if (isset($response->included)) { - $data = array_merge($data, $response->included); - } - } - - $view = view('flarum.admin::index') - ->with('title', 'Administration - '.Core::config('forum_title')) - ->with('config', $config) - ->with('layout', 'flarum.admin::admin') - ->with('data', $data) - ->with('session', $session); - - $assetManager = app('flarum.admin.assetManager'); - $root = __DIR__.'/../../..'; - $assetManager->addFile([ - $root.'/js/admin/dist/app.js', - $root.'/less/admin/app.less' - ]); - - // event(new RenderView($view, $assetManager, $this)); - - return $view - ->with('styles', $assetManager->getCSSFiles()) - ->with('scripts', $assetManager->getJSFiles()); - } -} diff --git a/src/Admin/AdminServiceProvider.php b/src/Admin/AdminServiceProvider.php index 9e4e5af21..be60a09d3 100644 --- a/src/Admin/AdminServiceProvider.php +++ b/src/Admin/AdminServiceProvider.php @@ -4,6 +4,7 @@ use Flarum\Http\RouteCollection; use Flarum\Http\UrlGenerator; use Illuminate\Support\ServiceProvider; use Psr\Http\Message\ServerRequestInterface; +use Zend\Diactoros\Response\RedirectResponse; class AdminServiceProvider extends ServiceProvider { @@ -47,7 +48,7 @@ class AdminServiceProvider extends ServiceProvider $routes->get( '/', 'flarum.admin.index', - $this->action('Flarum\Admin\Actions\IndexAction') + $this->action('Flarum\Admin\Actions\ClientAction') ); } diff --git a/src/Admin/Middleware/LoginWithCookieAndCheckAdmin.php b/src/Admin/Middleware/LoginWithCookieAndCheckAdmin.php index 2cf71d4b8..8871607ea 100644 --- a/src/Admin/Middleware/LoginWithCookieAndCheckAdmin.php +++ b/src/Admin/Middleware/LoginWithCookieAndCheckAdmin.php @@ -1,7 +1,7 @@ actor = $actor; + $this->app = $app; } /** @@ -23,15 +26,13 @@ class LoginWithCookieAndCheckAdmin implements MiddlewareInterface */ public function __invoke(Request $request, Response $response, callable $out = null) { - $cookies = $request->getCookieParams(); - - if (($token = $cookies['flarum_remember']) && + if (($token = array_get($request->getCookieParams(), 'flarum_remember')) && ($accessToken = AccessToken::where('id', $token)->first()) && $accessToken->user->isAdmin() ) { - $this->actor->setUser($accessToken->user); + $this->app->instance('flarum.actor', $accessToken->user); } else { - die('ur not an admin'); + die('Access Denied'); } return $out ? $out($request, $response) : $response; diff --git a/src/Http/RouterMiddleware.php b/src/Http/RouterMiddleware.php index 0e76744df..4bf6c200f 100644 --- a/src/Http/RouterMiddleware.php +++ b/src/Http/RouterMiddleware.php @@ -41,7 +41,7 @@ class RouterMiddleware public function __invoke(Request $request, Response $response, callable $out = null) { $method = $request->getMethod(); - $uri = $request->getUri()->getPath(); + $uri = $request->getUri()->getPath() ?: '/'; $routeInfo = $this->getDispatcher()->dispatch($method, $uri); diff --git a/views/admin.blade.php b/views/admin.blade.php index 28d39eb23..6a76c8e43 100644 --- a/views/admin.blade.php +++ b/views/admin.blade.php @@ -1,17 +1,30 @@ -
-
-
-