TopBar.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /** @jsx h */
  2. import { h } from "preact";
  3. import { useEffect, useState } from "preact/hooks";
  4. import { EditorMode } from "./Editor.tsx";
  5. interface TopBarProps {
  6. allowMode: EditorMode;
  7. isLogined: boolean;
  8. }
  9. export default function TopBar(props: TopBarProps) {
  10. const [mode, setMode] = useState(props.allowMode);
  11. // Event listener
  12. const modeChangeListener = (e: CustomEvent) => {
  13. if (
  14. e.detail &&
  15. (props.allowMode === e.detail || props.allowMode === EditorMode.Both)
  16. ) {
  17. setMode(e.detail);
  18. }
  19. };
  20. // Event dispatcher
  21. const modeChangeDispatcher = (mode: EditorMode) => {
  22. dispatchEvent(new CustomEvent("ModeChange", { detail: mode }));
  23. };
  24. const doLogout = async () => {
  25. const resp = await fetch("/api/user/logout");
  26. const respJson = await resp.json();
  27. if (respJson.success) {
  28. location.href = "/login";
  29. return true;
  30. }
  31. return false;
  32. };
  33. const goHome = () => {
  34. location.href = "/";
  35. };
  36. // Init event listeners
  37. useEffect(() => {
  38. addEventListener("ModeChange", modeChangeListener);
  39. return () => {
  40. removeEventListener("ModeChange", modeChangeListener);
  41. };
  42. }, []);
  43. return (
  44. <div className="pd-top-bar">
  45. <div className="pd-top-bar-mode-switcher">
  46. <button
  47. className={`pd-top-bar-btn${
  48. mode === EditorMode.Edit ? " active" : ""
  49. }${props.allowMode === EditorMode.Read ? " disabled" : ""}`}
  50. id="edit"
  51. type="button"
  52. onClick={() => {
  53. modeChangeDispatcher(EditorMode.Edit);
  54. }}
  55. >
  56. Edit
  57. </button>
  58. <button
  59. className={`pd-top-bar-btn${
  60. mode === EditorMode.Read ? " active" : ""
  61. }${props.allowMode === EditorMode.Edit ? " disabled" : ""}`}
  62. id="read"
  63. type="button"
  64. onClick={() => {
  65. modeChangeDispatcher(EditorMode.Read);
  66. }}
  67. >
  68. Read
  69. </button>
  70. <button
  71. className={`pd-top-bar-btn${
  72. mode === EditorMode.Both ? " active" : ""
  73. }${props.allowMode !== EditorMode.Both ? " disabled" : ""}`}
  74. id="both"
  75. type="button"
  76. onClick={() => {
  77. modeChangeDispatcher(EditorMode.Both);
  78. }}
  79. >
  80. Both
  81. </button>
  82. </div>
  83. {props.isLogined ? (
  84. <div className="pd-top-bar-tool-icons">
  85. <i className="bi bi-box-arrow-left" onClick={doLogout} />
  86. <i className="bi bi-house-door" onClick={goHome} />
  87. <i className="bi bi-share" />
  88. <i className="bi bi-gear" />
  89. </div>
  90. ) : null}
  91. </div>
  92. );
  93. }