diff --git a/js/src/admin/components/AdminNav.tsx b/js/src/admin/components/AdminNav.tsx index c814c8189..badf2b4d5 100644 --- a/js/src/admin/components/AdminNav.tsx +++ b/js/src/admin/components/AdminNav.tsx @@ -60,12 +60,15 @@ export default class AdminNav extends Component { }) ); - // 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'), diff --git a/js/src/admin/components/AppearancePage.tsx b/js/src/admin/components/AppearancePage.tsx new file mode 100644 index 000000000..774a39055 --- /dev/null +++ b/js/src/admin/components/AppearancePage.tsx @@ -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 ( +
+
+
+
+ {app.translator.trans('core.admin.appearance.colors_heading')} +
{app.translator.trans('core.admin.appearance.colors_text')}
+ +
+ + +
+ + {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, + })} +
+
+ +
+ {app.translator.trans('core.admin.appearance.logo_heading')} +
{app.translator.trans('core.admin.appearance.logo_text')}
+ +
+ +
+ {app.translator.trans('core.admin.appearance.favicon_heading')} +
{app.translator.trans('core.admin.appearance.favicon_text')}
+ +
+ +
+ {app.translator.trans('core.admin.appearance.custom_header_heading')} +
{app.translator.trans('core.admin.appearance.custom_header_text')}
+ {Button.component({ + className: 'Button', + children: app.translator.trans('core.admin.appearance.edit_header_button'), + onclick: () => app.modal.show(EditCustomHeaderModal), + })} +
+ +
+ {app.translator.trans('core.admin.appearance.custom_footer_heading')} +
{app.translator.trans('core.admin.appearance.custom_footer_text')}
+ {Button.component({ + className: 'Button', + children: app.translator.trans('core.admin.appearance.edit_footer_button'), + onclick: () => app.modal.show(EditCustomFooterModal), + })} +
+ +
+ {app.translator.trans('core.admin.appearance.custom_styles_heading')} +
{app.translator.trans('core.admin.appearance.custom_styles_text')}
+ {Button.component({ + className: 'Button', + children: app.translator.trans('core.admin.appearance.edit_css_button'), + onclick: () => app.modal.show(EditCustomCssModal), + })} +
+
+
+ ); + } + + 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()); + } +} diff --git a/js/src/admin/components/EditCustomCssModal.tsx b/js/src/admin/components/EditCustomCssModal.tsx new file mode 100644 index 000000000..c7686b085 --- /dev/null +++ b/js/src/admin/components/EditCustomCssModal.tsx @@ -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 [ +

+ {app.translator.trans('core.admin.edit_css.customize_text', { + a: , + })} +

, +
+