2
0

TextBook.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // ─────────────────────────────────────────────
  2. // Props
  3. // ─────────────────────────────────────────────
  4. import type { ArticleMode, ArticleType } from "../../api/article";
  5. import type { ISearchParams } from "../../components/article/TypePali";
  6. import type { TTarget } from "../../types";
  7. import AnthologyTocTree from "../../components/anthology/AnthologyTocTree";
  8. import TypeCourse from "../../components/article/TypeCourse";
  9. import { useCourse } from "../../components/course/hooks/useCourse";
  10. import Editor from "../../components/editor";
  11. export interface ArticleEditorProps {
  12. articleId?: string;
  13. courseId?: string;
  14. mode?: ArticleMode;
  15. channelId?: string | null;
  16. // ── 路由事件回调(由 page 层处理导航)──
  17. /** 点击目录树中的文章时触发 */
  18. onArticleClick?: (
  19. anthologyId: string,
  20. articleId: string,
  21. target?: string
  22. ) => void;
  23. /** 选择了新的 anthology 时触发 */
  24. onAnthologySelect?: (anthologyId: string) => void;
  25. /** 文章内部触发跳转(type: 'article' | 'anthology' 等) */
  26. onArticleChange?: (
  27. type: ArticleType,
  28. id: string,
  29. target?: TTarget,
  30. param?: ISearchParams[]
  31. ) => void;
  32. }
  33. // ─────────────────────────────────────────────
  34. // Component
  35. // ─────────────────────────────────────────────
  36. export default function TextBookEditor({
  37. articleId,
  38. courseId,
  39. mode = "read",
  40. channelId,
  41. onArticleClick,
  42. onArticleChange,
  43. }: ArticleEditorProps) {
  44. const channels = channelId ? channelId.split("_") : undefined;
  45. const { data, loading } = useCourse(courseId);
  46. return (
  47. <Editor
  48. sidebarTitle="table of content"
  49. sidebar={
  50. loading ? (
  51. <>loading</>
  52. ) : (
  53. <AnthologyTocTree
  54. anthologyId={data?.anthology_id}
  55. articleId={articleId}
  56. channels={channels}
  57. onClick={(tocAnthology, article, target) => {
  58. onArticleClick?.(tocAnthology, article, target);
  59. }}
  60. />
  61. )
  62. }
  63. articleId={articleId}
  64. anthologyId={data?.anthology_id}
  65. channelId={channelId}
  66. >
  67. {({ expandButton }) => (
  68. <TypeCourse
  69. articleId={articleId}
  70. mode={mode}
  71. courseId={courseId}
  72. channelId={channelId}
  73. headerExtra={expandButton}
  74. onArticleChange={onArticleChange}
  75. />
  76. )}
  77. </Editor>
  78. );
  79. }