CustomizeLayoutSetting.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import React, {
  2. useCallback, useEffect, useState,
  3. } from 'react';
  4. import { useTranslation } from 'next-i18next';
  5. import { toastSuccess, toastError } from '~/client/util/toastr';
  6. import { LoadingSpinner } from '~/components/LoadingSpinner';
  7. import { useSWRxLayoutSetting } from '~/stores/admin/customize';
  8. import { useNextThemes } from '~/stores/use-next-themes';
  9. const useIsContainerFluid = () => {
  10. const { data: layoutSetting, update: updateLayoutSetting } = useSWRxLayoutSetting();
  11. const [isContainerFluid, setIsContainerFluid] = useState<boolean>();
  12. useEffect(() => {
  13. setIsContainerFluid(layoutSetting?.isContainerFluid);
  14. }, [layoutSetting?.isContainerFluid]);
  15. return {
  16. isContainerFluid,
  17. setIsContainerFluid,
  18. updateLayoutSetting,
  19. };
  20. };
  21. const CustomizeLayoutSetting = (): JSX.Element => {
  22. const { t } = useTranslation('admin');
  23. const { resolvedTheme } = useNextThemes();
  24. const { isContainerFluid, setIsContainerFluid, updateLayoutSetting } = useIsContainerFluid();
  25. const [retrieveError, setRetrieveError] = useState<any>();
  26. const onClickSubmit = useCallback(async() => {
  27. if (isContainerFluid == null) { return }
  28. try {
  29. await updateLayoutSetting({ isContainerFluid });
  30. toastSuccess(t('toaster.update_successed', { target: t('customize_settings.layout'), ns: 'commons' }));
  31. }
  32. catch (err) {
  33. toastError(err);
  34. }
  35. }, [isContainerFluid, updateLayoutSetting, t]);
  36. if (isContainerFluid == null) {
  37. return (
  38. <div className="text-muted text-center fs-3">
  39. <LoadingSpinner />
  40. </div>
  41. );
  42. }
  43. return (
  44. <React.Fragment>
  45. <div className="row">
  46. <div className="col-12">
  47. <h2 className="admin-setting-header">{t('customize_settings.layout')}</h2>
  48. <div className="d-flex justify-content-around mt-5">
  49. <div id="layoutOptions" className="row row-cols-2">
  50. <div className="col">
  51. <div
  52. className={`card customize-layout-card ${!isContainerFluid ? 'border-active' : ''}`}
  53. onClick={() => setIsContainerFluid(false)}
  54. role="button"
  55. >
  56. <img src={`/images/customize-settings/default-${resolvedTheme}.svg`} />
  57. <div className="card-body text-center">
  58. {t('customize_settings.layout_options.default')}
  59. </div>
  60. </div>
  61. </div>
  62. <div className="col">
  63. <div
  64. className={`card customize-layout-card ${isContainerFluid ? 'border-active' : ''}`}
  65. onClick={() => setIsContainerFluid(true)}
  66. role="button"
  67. >
  68. <img src={`/images/customize-settings/fluid-${resolvedTheme}.svg`} />
  69. <div className="card-body text-center">
  70. {t('customize_settings.layout_options.expanded')}
  71. </div>
  72. </div>
  73. </div>
  74. </div>
  75. </div>
  76. <div className="row my-3">
  77. <div className="mx-auto">
  78. <button type="button" className="btn btn-primary" onClick={onClickSubmit} disabled={retrieveError != null}>{ t('Update') }</button>
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. </React.Fragment>
  84. );
  85. };
  86. export default CustomizeLayoutSetting;