mirror of
https://github.com/flarum/framework.git
synced 2024-11-23 06:31:41 +08:00
Get admin area working again
This commit is contained in:
parent
d8d9cac7c3
commit
e863bd53d3
|
@ -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'
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
15
js/admin/src/components/AdminLinkButton.js
Normal file
15
js/admin/src/components/AdminLinkButton.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import LinkButton from 'flarum/components/LinkButton';
|
||||
|
||||
export default class AdminLinkButton extends LinkButton {
|
||||
getButtonContent() {
|
||||
const content = super.getButtonContent();
|
||||
|
||||
content.push(
|
||||
<div className="AdminLinkButton-description">
|
||||
{this.props.description}
|
||||
</div>
|
||||
);
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
56
js/admin/src/components/AdminNav.js
Normal file
56
js/admin/src/components/AdminNav.js
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
9
js/admin/src/components/AppearancePage.js
Normal file
9
js/admin/src/components/AppearancePage.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Component from 'flarum/Component';
|
||||
|
||||
export default class AppearancePage extends Component {
|
||||
view() {
|
||||
return (
|
||||
<div className="AppearancePage"/>
|
||||
);
|
||||
}
|
||||
}
|
16
js/admin/src/components/DashboardPage.js
Normal file
16
js/admin/src/components/DashboardPage.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Component from 'flarum/Component';
|
||||
|
||||
export default class DashboardPage extends Component {
|
||||
view() {
|
||||
return (
|
||||
<div className="DashboardPage">
|
||||
<div className="container">
|
||||
<h2>Welcome to Flarum Beta</h2>
|
||||
<p>This is beta software; you shouldn't use it in production.</p>
|
||||
<p>You're running version X</p>
|
||||
<p>Get help on X. Report bugs here. Feedback here. Contribute here.</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
9
js/admin/src/components/ExtensionsPage.js
Normal file
9
js/admin/src/components/ExtensionsPage.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Component from 'flarum/Component';
|
||||
|
||||
export default class ExtensionsPage extends Component {
|
||||
view() {
|
||||
return (
|
||||
<div className="ExtensionsPage"/>
|
||||
);
|
||||
}
|
||||
}
|
26
js/admin/src/components/HeaderPrimary.js
Normal file
26
js/admin/src/components/HeaderPrimary.js
Normal file
|
@ -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 (
|
||||
<ul className="Header-controls">
|
||||
{listItems(this.items().toArray())}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an item list for the controls.
|
||||
*
|
||||
* @return {ItemList}
|
||||
*/
|
||||
items() {
|
||||
return new ItemList();
|
||||
}
|
||||
}
|
30
js/admin/src/components/HeaderSecondary.js
Normal file
30
js/admin/src/components/HeaderSecondary.js
Normal file
|
@ -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 (
|
||||
<ul className="Header-controls">
|
||||
{listItems(this.items().toArray())}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an item list for the controls.
|
||||
*
|
||||
* @return {ItemList}
|
||||
*/
|
||||
items() {
|
||||
const items = new ItemList();
|
||||
|
||||
items.add('session', SessionDropdown.component());
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
54
js/admin/src/components/SessionDropdown.js
Normal file
54
js/admin/src/components/SessionDropdown.js
Normal file
|
@ -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), ' ',
|
||||
<span className="Button-label">{username(user)}</span>
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
]))
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import Component from 'flarum/component';
|
||||
|
||||
export default class AppearancePage extends Component {
|
||||
view() {
|
||||
return m('div', 'appearance');
|
||||
}
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
import Component from 'flarum/component';
|
||||
|
||||
export default class BasicsPage extends Component {
|
||||
view() {
|
||||
return m('div', 'basics');
|
||||
}
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
import Component from 'flarum/component';
|
||||
|
||||
export default class DashboardPage extends Component {
|
||||
view() {
|
||||
return m('div', 'dashboard');
|
||||
}
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
import Component from 'flarum/component';
|
||||
|
||||
export default class ExtensionsPage extends Component {
|
||||
view() {
|
||||
return m('div', 'extensions');
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import Component from 'flarum/component';
|
||||
|
||||
export default class PermissionsPage extends Component {
|
||||
view() {
|
||||
return m('div', 'permissions');
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
9
less/admin/DashboardPage.less
Normal file
9
less/admin/DashboardPage.less
Normal file
|
@ -0,0 +1,9 @@
|
|||
.DashboardPage {
|
||||
@media @desktop-up {
|
||||
.container {
|
||||
max-width: 600px;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
|
|
|
@ -40,3 +40,9 @@
|
|||
height: auto;
|
||||
}
|
||||
}
|
||||
.helpText {
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
margin-bottom: 10px;
|
||||
color: @muted-color;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
23
src/Admin/Actions/ClientAction.php
Normal file
23
src/Admin/Actions/ClientAction.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php namespace Flarum\Admin\Actions;
|
||||
|
||||
use Flarum\Support\ClientAction as BaseClientAction;
|
||||
|
||||
class ClientAction extends BaseClientAction
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $clientName = 'admin';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $layout = __DIR__.'/../../../views/admin.blade.php';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $translationKeys = [
|
||||
|
||||
];
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php namespace Flarum\Admin\Actions;
|
||||
|
||||
use Dflydev\FigCookies\FigRequestCookies;
|
||||
use Flarum\Api\Client;
|
||||
use Flarum\Support\Actor;
|
||||
use Flarum\Support\HtmlAction;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Flarum\Core;
|
||||
|
||||
class IndexAction extends HtmlAction
|
||||
{
|
||||
protected $apiClient;
|
||||
|
||||
protected $actor;
|
||||
|
||||
public function __construct(Client $apiClient, Actor $actor)
|
||||
{
|
||||
$this->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());
|
||||
}
|
||||
}
|
|
@ -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')
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php namespace Flarum\Admin\Middleware;
|
||||
|
||||
use Flarum\Support\Actor;
|
||||
use Flarum\Core\Models\AccessToken;
|
||||
use Flarum\Api\AccessToken;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Zend\Stratigility\MiddlewareInterface;
|
||||
|
@ -9,13 +9,16 @@ use Zend\Stratigility\MiddlewareInterface;
|
|||
class LoginWithCookieAndCheckAdmin implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @var Actor
|
||||
* @var Container
|
||||
*/
|
||||
protected $actor;
|
||||
protected $app;
|
||||
|
||||
public function __construct(Actor $actor)
|
||||
/**
|
||||
* @param Container $app
|
||||
*/
|
||||
public function __construct(Container $app)
|
||||
{
|
||||
$this->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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
<div class="global-page" id="page">
|
||||
<div id="back-control"></div>
|
||||
<div class="global-drawer">
|
||||
<header class="global-header" id="header">
|
||||
<div id="back-button"></div>
|
||||
<div id="app" class="App">
|
||||
|
||||
<div id="app-navigation" class="App-navigation"></div>
|
||||
|
||||
<div id="drawer" class="App-drawer">
|
||||
|
||||
<header id="header" class="App-header">
|
||||
<div id="header-navigation" class="Header-navigation"></div>
|
||||
<div class="container">
|
||||
<h1 class="header-title"><a href="#" onclick="app.history.home()">Flarum Demo Forum</a></h1>
|
||||
<div id="header-primary" class="header-primary"></div>
|
||||
<div id="header-secondary" class="header-secondary"></div>
|
||||
<h1 class="Header-title">
|
||||
<a href="{{ $forum->attributes->baseUrl }}">
|
||||
{{ $forum->attributes->title }}
|
||||
</a>
|
||||
</h1>
|
||||
<div id="header-primary" class="Header-primary"></div>
|
||||
<div id="header-secondary" class="Header-secondary"></div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
</div>
|
||||
<main class="global-content">
|
||||
<div class="side-nav admin-nav title-control" id="admin-nav"></div>
|
||||
<div class="admin-content" id="content"></div>
|
||||
|
||||
<main class="App-content">
|
||||
<div class="container">
|
||||
<div id="admin-navigation" class="App-nav sideNav"></div>
|
||||
</div>
|
||||
|
||||
<div id="content" class="sideNavOffset"></div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user