CustomizeSidebarSetting.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import React, { type JSX, useCallback } from 'react';
  2. import { LoadingSpinner } from '@growi/ui/dist/components';
  3. import { useTranslation } from 'next-i18next';
  4. import { Card, CardBody } from 'reactstrap';
  5. import { toastError, toastSuccess } from '~/client/util/toastr';
  6. import { useSWRxSidebarConfig } from '~/stores/admin/sidebar-config';
  7. import { useNextThemes } from '~/stores-universal/use-next-themes';
  8. const CustomizeSidebarsetting = (): JSX.Element => {
  9. const { t } = useTranslation(['admin', 'commons']);
  10. const { data, update, setIsSidebarCollapsedMode } = useSWRxSidebarConfig();
  11. const { resolvedTheme } = useNextThemes();
  12. const collapsedIconFileName = `/images/customize-settings/collapsed-${resolvedTheme}.svg`;
  13. const dockIconFileName = `/images/customize-settings/dock-${resolvedTheme}.svg`;
  14. const onClickSubmit = useCallback(async () => {
  15. try {
  16. await update();
  17. toastSuccess(
  18. t('toaster.update_successed', {
  19. target: t('customize_settings.default_sidebar_mode.title'),
  20. ns: 'commons',
  21. }),
  22. );
  23. } catch (err) {
  24. toastError(err);
  25. }
  26. }, [t, update]);
  27. if (data == null) {
  28. return <LoadingSpinner />;
  29. }
  30. const { isSidebarCollapsedMode } = data;
  31. return (
  32. <React.Fragment>
  33. <div className="row">
  34. <div className="col-12">
  35. <h2 className="admin-setting-header">
  36. {t('customize_settings.default_sidebar_mode.title')}
  37. </h2>
  38. <Card className="card custom-card bg-body-tertiary my-3">
  39. <CardBody className="px-0 py-2">
  40. {t('customize_settings.default_sidebar_mode.desc')}
  41. </CardBody>
  42. </Card>
  43. <div className="d-flex justify-content-around mt-5">
  44. <div className="row row-cols-2">
  45. <div className="col">
  46. <button
  47. type="button"
  48. className={`card border border-4 ${isSidebarCollapsedMode ? 'border-primary' : ''}`}
  49. onClick={() => setIsSidebarCollapsedMode(true)}
  50. aria-pressed={isSidebarCollapsedMode}
  51. >
  52. {/* eslint-disable-next-line @next/next/no-img-element */}
  53. <img src={collapsedIconFileName} alt="Collapsed Mode" />
  54. <div className="card-body text-center">Collapsed Mode</div>
  55. </button>
  56. </div>
  57. <div className="col">
  58. <button
  59. type="button"
  60. className={`card border border-4 ${!isSidebarCollapsedMode ? 'border-primary' : ''}`}
  61. onClick={() => setIsSidebarCollapsedMode(false)}
  62. aria-pressed={!isSidebarCollapsedMode}
  63. >
  64. {/* eslint-disable-next-line @next/next/no-img-element */}
  65. <img src={dockIconFileName} alt="Dock Mode" />
  66. <div className="card-body text-center">Dock Mode</div>
  67. </button>
  68. </div>
  69. </div>
  70. </div>
  71. <div className="row my-3">
  72. <div className="mx-auto">
  73. <button
  74. type="button"
  75. onClick={onClickSubmit}
  76. className="btn btn-primary"
  77. >
  78. {t('Update')}
  79. </button>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. </React.Fragment>
  85. );
  86. };
  87. export default CustomizeSidebarsetting;