mirror of
https://github.com/flarum/framework.git
synced 2024-11-25 17:50:38 +08:00
Added Appearance page
This commit is contained in:
parent
e9ad848530
commit
ea880632e1
|
@ -60,12 +60,15 @@ export default class AdminNav<T> extends Component<T> {
|
|||
})
|
||||
);
|
||||
|
||||
// items.add('appearance', AdminLinkButton.component({
|
||||
// href: app.route('appearance'),
|
||||
// icon: 'fas fa-paint-brush',
|
||||
// children: app.translator.trans('core.admin.nav.appearance_button'),
|
||||
// description: app.translator.trans('core.admin.nav.appearance_text')
|
||||
// }));
|
||||
items.add(
|
||||
'appearance',
|
||||
AdminLinkButton.component({
|
||||
href: app.route('appearance'),
|
||||
icon: 'fas fa-paint-brush',
|
||||
children: app.translator.trans('core.admin.nav.appearance_button'),
|
||||
description: app.translator.trans('core.admin.nav.appearance_text'),
|
||||
})
|
||||
);
|
||||
|
||||
// items.add('extensions', AdminLinkButton.component({
|
||||
// href: app.route('extensions'),
|
||||
|
|
131
js/src/admin/components/AppearancePage.tsx
Normal file
131
js/src/admin/components/AppearancePage.tsx
Normal file
|
@ -0,0 +1,131 @@
|
|||
import app from '../app';
|
||||
|
||||
import Page from './Page';
|
||||
import Button from '../../common/components/Button';
|
||||
import Switch from '../../common/components/Switch';
|
||||
import EditCustomCssModal from './EditCustomCssModal';
|
||||
import EditCustomHeaderModal from './EditCustomHeaderModal';
|
||||
import EditCustomFooterModal from './EditCustomFooterModal';
|
||||
import UploadImageButton from './UploadImageButton';
|
||||
import saveSettings from '../utils/saveSettings';
|
||||
|
||||
export default class AppearancePage extends Page {
|
||||
loading = false;
|
||||
primaryColor = m.prop(app.data.settings.theme_primary_color);
|
||||
secondaryColor = m.prop(app.data.settings.theme_secondary_color);
|
||||
darkMode = m.prop(app.data.settings.theme_dark_mode === '1');
|
||||
coloredHeader = m.prop(app.data.settings.theme_colored_header === '1');
|
||||
|
||||
view() {
|
||||
return (
|
||||
<div className="AppearancePage">
|
||||
<div className="container">
|
||||
<form onsubmit={this.onsubmit.bind(this)}>
|
||||
<fieldset className="AppearancePage-colors">
|
||||
<legend>{app.translator.trans('core.admin.appearance.colors_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.colors_text')}</div>
|
||||
|
||||
<div className="AppearancePage-colors-input">
|
||||
<input
|
||||
className="FormControl"
|
||||
type="text"
|
||||
placeholder="#aaaaaa"
|
||||
value={this.primaryColor()}
|
||||
onchange={m.withAttr('value', this.primaryColor)}
|
||||
/>
|
||||
<input
|
||||
className="FormControl"
|
||||
type="text"
|
||||
placeholder="#aaaaaa"
|
||||
value={this.secondaryColor()}
|
||||
onchange={m.withAttr('value', this.secondaryColor)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{Switch.component({
|
||||
state: this.darkMode(),
|
||||
children: app.translator.trans('core.admin.appearance.dark_mode_label'),
|
||||
onchange: this.darkMode,
|
||||
})}
|
||||
|
||||
{Switch.component({
|
||||
state: this.coloredHeader(),
|
||||
children: app.translator.trans('core.admin.appearance.colored_header_label'),
|
||||
onchange: this.coloredHeader,
|
||||
})}
|
||||
|
||||
{Button.component({
|
||||
className: 'Button Button--primary',
|
||||
type: 'submit',
|
||||
children: app.translator.trans('core.admin.appearance.submit_button'),
|
||||
loading: this.loading,
|
||||
})}
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<fieldset>
|
||||
<legend>{app.translator.trans('core.admin.appearance.logo_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.logo_text')}</div>
|
||||
<UploadImageButton name="logo" />
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{app.translator.trans('core.admin.appearance.favicon_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.favicon_text')}</div>
|
||||
<UploadImageButton name="favicon" />
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{app.translator.trans('core.admin.appearance.custom_header_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_header_text')}</div>
|
||||
{Button.component({
|
||||
className: 'Button',
|
||||
children: app.translator.trans('core.admin.appearance.edit_header_button'),
|
||||
onclick: () => app.modal.show(EditCustomHeaderModal),
|
||||
})}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{app.translator.trans('core.admin.appearance.custom_footer_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_footer_text')}</div>
|
||||
{Button.component({
|
||||
className: 'Button',
|
||||
children: app.translator.trans('core.admin.appearance.edit_footer_button'),
|
||||
onclick: () => app.modal.show(EditCustomFooterModal),
|
||||
})}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{app.translator.trans('core.admin.appearance.custom_styles_heading')}</legend>
|
||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_styles_text')}</div>
|
||||
{Button.component({
|
||||
className: 'Button',
|
||||
children: app.translator.trans('core.admin.appearance.edit_css_button'),
|
||||
onclick: () => app.modal.show(EditCustomCssModal),
|
||||
})}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onsubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const hex = /^#[0-9a-f]{3}([0-9a-f]{3})?$/i;
|
||||
|
||||
if (!hex.test(this.primaryColor()) || !hex.test(this.secondaryColor())) {
|
||||
alert(app.translator.trans('core.admin.appearance.enter_hex_message'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
saveSettings({
|
||||
theme_primary_color: this.primaryColor(),
|
||||
theme_secondary_color: this.secondaryColor(),
|
||||
theme_dark_mode: this.darkMode(),
|
||||
theme_colored_header: this.coloredHeader(),
|
||||
}).then(() => window.location.reload());
|
||||
}
|
||||
}
|
28
js/src/admin/components/EditCustomCssModal.tsx
Normal file
28
js/src/admin/components/EditCustomCssModal.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import SettingsModal from './SettingsModal';
|
||||
|
||||
export default class EditCustomCssModal extends SettingsModal {
|
||||
className() {
|
||||
return 'EditCustomCssModal Modal--large';
|
||||
}
|
||||
|
||||
title() {
|
||||
return app.translator.trans('core.admin.edit_css.title');
|
||||
}
|
||||
|
||||
form() {
|
||||
return [
|
||||
<p>
|
||||
{app.translator.trans('core.admin.edit_css.customize_text', {
|
||||
a: <a href="https://github.com/flarum/core/tree/master/less" target="_blank" />,
|
||||
})}
|
||||
</p>,
|
||||
<div className="Form-group">
|
||||
<textarea className="FormControl" rows="30" bidi={this.setting('custom_less')} />
|
||||
</div>,
|
||||
];
|
||||
}
|
||||
|
||||
onsaved() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
24
js/src/admin/components/EditCustomFooterModal.tsx
Normal file
24
js/src/admin/components/EditCustomFooterModal.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import SettingsModal from './SettingsModal';
|
||||
|
||||
export default class EditCustomFooterModal extends SettingsModal {
|
||||
className() {
|
||||
return 'EditCustomFooterModal Modal--large';
|
||||
}
|
||||
|
||||
title() {
|
||||
return app.translator.trans('core.admin.edit_footer.title');
|
||||
}
|
||||
|
||||
form() {
|
||||
return [
|
||||
<p>{app.translator.trans('core.admin.edit_footer.customize_text')}</p>,
|
||||
<div className="Form-group">
|
||||
<textarea className="FormControl" rows="30" bidi={this.setting('custom_footer')} />
|
||||
</div>,
|
||||
];
|
||||
}
|
||||
|
||||
onsaved() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
24
js/src/admin/components/EditCustomHeaderModal.tsx
Normal file
24
js/src/admin/components/EditCustomHeaderModal.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import SettingsModal from './SettingsModal';
|
||||
|
||||
export default class EditCustomHeaderModal extends SettingsModal {
|
||||
className() {
|
||||
return 'EditCustomHeaderModal Modal--large';
|
||||
}
|
||||
|
||||
title() {
|
||||
return app.translator.trans('core.admin.edit_header.title');
|
||||
}
|
||||
|
||||
form() {
|
||||
return [
|
||||
<p>{app.translator.trans('core.admin.edit_header.customize_text')}</p>,
|
||||
<div className="Form-group">
|
||||
<textarea className="FormControl" rows="30" bidi={this.setting('custom_header')} />
|
||||
</div>,
|
||||
];
|
||||
}
|
||||
|
||||
onsaved() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ export default class UploadImageButton<T extends ButtonProps = ButtonProps> exte
|
|||
upload() {
|
||||
if (this.loading) return;
|
||||
|
||||
const $input = this.$('<input type="file">');
|
||||
const $input = $('<input type="file">');
|
||||
|
||||
$input
|
||||
.appendTo('body')
|
||||
|
@ -52,7 +52,7 @@ export default class UploadImageButton<T extends ButtonProps = ButtonProps> exte
|
|||
method: 'POST',
|
||||
url: this.resourceUrl(),
|
||||
serialize: (raw) => raw,
|
||||
data,
|
||||
body: data,
|
||||
}).then(this.success.bind(this), this.failure.bind(this));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import BasicsPage from './components/BasicsPage';
|
|||
import DashboardPage from './components/DashboardPage';
|
||||
import MailPage from './components/MailPage';
|
||||
import PermissionsPage from './components/PermissionsPage';
|
||||
import AppearancePage from './components/AppearancePage';
|
||||
|
||||
export default (app) => {
|
||||
app.routes = {
|
||||
|
@ -9,5 +10,6 @@ export default (app) => {
|
|||
basics: { path: '/basics', component: BasicsPage },
|
||||
mail: { path: '/mail', component: MailPage },
|
||||
permissions: { path: '/permissions', component: PermissionsPage },
|
||||
appearance: { path: '/appearance', component: AppearancePage },
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user