Add custom CSS (#264)

This commit is contained in:
Riccardo Graziosi
2024-01-23 18:50:42 +01:00
committed by GitHub
parent 653e139a9e
commit d7e7db9f72
40 changed files with 421 additions and 54 deletions

View File

@@ -168,7 +168,7 @@ class NewPost extends React.Component<Props, State> {
}
</Button>
:
<a href="/users/sign_in" className="btn btn-dark">
<a href="/users/sign_in" className="btn btnPrimary">
{I18n.t('board.new_post.login_button')}
</a>
}

View File

@@ -0,0 +1,118 @@
import * as React from 'react';
import { useEffect } from 'react';
import I18n from 'i18n-js';
import Box from '../../common/Box';
import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox';
import Button from '../../common/Button';
import HttpStatus from '../../../constants/http_status';
import { getLabel } from '../../../helpers/formUtils';
import { SubmitHandler, useForm } from 'react-hook-form';
import ActionLink from '../../common/ActionLink';
import { LearnMoreIcon } from '../../common/Icons';
export interface ISiteSettingsAppearanceForm {
customCss: string;
}
interface Props {
originForm: ISiteSettingsAppearanceForm;
authenticityToken: string;
areUpdating: boolean;
error: string;
updateTenant(
customCss: string,
authenticityToken: string
): Promise<any>;
}
const AppearanceSiteSettingsP = ({
originForm,
authenticityToken,
areUpdating,
error,
updateTenant,
}: Props) => {
const {
register,
handleSubmit,
formState: { isDirty, isSubmitSuccessful },
watch,
} = useForm<ISiteSettingsAppearanceForm>({
defaultValues: {
customCss: originForm.customCss,
},
});
const customCss = watch('customCss');
const onSubmit: SubmitHandler<ISiteSettingsAppearanceForm> = data => {
updateTenant(
data.customCss,
authenticityToken
).then(res => {
if (res?.status !== HttpStatus.OK) return;
window.location.reload();
});
};
useEffect(() => {
const style = document.createElement('style');
style.innerHTML = customCss;
document.body.appendChild(style);
// Clean up function
return () => {
document.body.removeChild(style);
};
}, [customCss]);
return (
<>
<Box>
<h2>{ I18n.t('site_settings.appearance.title') }</h2>
<p style={{textAlign: 'left'}}>
<ActionLink
onClick={() => window.open('https://docs.astuto.io/category/appearance-customization/', '_blank')}
icon={<LearnMoreIcon />}
>
{I18n.t('site_settings.appearance.learn_more')}
</ActionLink>
</p>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="formRow">
<div className="formGroup customCssForm col-12">
<h4>{ getLabel('tenant_setting', 'custom_css') }</h4>
<textarea
{...register('customCss')}
maxLength={32000}
id="customCss"
className="formControl"
onKeyDown={e => e.key === 'Tab' && e.preventDefault()}
/>
</div>
</div>
<Button onClick={() => null} disabled={!isDirty}>
{I18n.t('common.buttons.update')}
</Button>
</form>
</Box>
<SiteSettingsInfoBox
areUpdating={areUpdating}
error={error}
areDirty={isDirty && !isSubmitSuccessful}
/>
</>
);
}
export default AppearanceSiteSettingsP;

View File

@@ -0,0 +1,36 @@
import * as React from 'react';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import AppearanceSiteSettings from '../../../containers/AppearanceSiteSettings';
import createStoreHelper from '../../../helpers/createStore';
import { State } from '../../../reducers/rootReducer';
import { ISiteSettingsAppearanceForm } from './AppearanceSiteSettingsP';
interface Props {
originForm: ISiteSettingsAppearanceForm;
authenticityToken: string;
}
class AppearanceSiteSettingsRoot extends React.Component<Props> {
store: Store<State, any>;
constructor(props: Props) {
super(props);
this.store = createStoreHelper();
}
render() {
return (
<Provider store={this.store}>
<AppearanceSiteSettings
originForm={this.props.originForm}
authenticityToken={this.props.authenticityToken}
/>
</Provider>
);
}
}
export default AppearanceSiteSettingsRoot;

View File

@@ -6,6 +6,8 @@ import OAuthProvidersList from './OAuthProvidersList';
import { AuthenticationPages } from './AuthenticationSiteSettingsP';
import { OAuthsState } from '../../../reducers/oAuthsReducer';
import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox';
import ActionLink from '../../common/ActionLink';
import { LearnMoreIcon } from '../../common/Icons';
interface Props {
oAuths: OAuthsState;
@@ -34,6 +36,15 @@ const AuthenticationIndexPage = ({
<Box customClass="authenticationIndexPage">
<h2>{ I18n.t('site_settings.authentication.title') }</h2>
<p style={{textAlign: 'left'}}>
<ActionLink
onClick={() => window.open('https://docs.astuto.io/category/oauth-configuration/', '_blank')}
icon={<LearnMoreIcon />}
>
{I18n.t('site_settings.authentication.learn_more')}
</ActionLink>
</p>
<OAuthProvidersList
oAuths={oAuths.items}
handleToggleEnabledOAuth={handleToggleEnabledOAuth}

View File

@@ -11,7 +11,7 @@ interface Props {
const Button = ({ children, onClick, className = '', outline = false, disabled = false}: Props) => (
<button
onClick={onClick}
className={`${className} btn btn-${outline ? 'outline-' : ''}dark`}
className={`${className} btn${outline ? 'Outline' : ''}Primary`}
disabled={disabled}
>
{children}

View File

@@ -6,6 +6,7 @@ import { ImCancelCircle } from 'react-icons/im';
import { TbLock, TbLockOpen } from 'react-icons/tb';
import { MdContentCopy, MdDone, MdOutlineArrowBack } from 'react-icons/md';
import { GrTest } from 'react-icons/gr';
import { MdOutlineLibraryBooks } from "react-icons/md";
export const EditIcon = () => <FiEdit />;
@@ -25,4 +26,6 @@ export const DoneIcon = () => <MdDone />;
export const BackIcon = () => <MdOutlineArrowBack />;
export const ReplyIcon = () => <BsReply />;
export const ReplyIcon = () => <BsReply />;
export const LearnMoreIcon = () => <MdOutlineLibraryBooks />;