@nualang/nualang-ui-components 0.1.1430 → 0.1.1432

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -135,12 +135,7 @@ function Bot({
135
135
  children: [/*#__PURE__*/_jsx(CardTop, {
136
136
  children: /*#__PURE__*/_jsx(Skeleton, {
137
137
  variant: "rectangular",
138
- sx: {
139
- ...classes.media,
140
- ...(compact ? {
141
- paddingTop: "40%"
142
- } : {})
143
- }
138
+ sx: classes.media
144
139
  })
145
140
  }), /*#__PURE__*/_jsx(CardHeader, {
146
141
  action: /*#__PURE__*/_jsx(IconButton, {
@@ -199,12 +194,7 @@ function Bot({
199
194
  onClick: selectBot,
200
195
  role: "link",
201
196
  children: [/*#__PURE__*/_jsx(ProgressiveCardMedia, {
202
- sx: {
203
- ...classes.media,
204
- ...(compact ? {
205
- paddingTop: "40%"
206
- } : {})
207
- },
197
+ sx: classes.media,
208
198
  highQualitySrc: visible || !pictureXs ? cardPicture || picture || PlaceholderImages.bot : null,
209
199
  lowQualitySrc: pictureXs,
210
200
  title: botName,
@@ -297,13 +297,7 @@ CourseDifficulty.propTypes = {
297
297
  difficulty: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
298
298
  compact: PropTypes.bool
299
299
  };
300
-
301
- // Keep compact cards' media at 16:9 even though it makes the card a little
302
- // taller than the old 40% (2.5:1) crop - matches how the picture actually
303
- // looks everywhere else it's shown.
304
- const COMPACT_MEDIA_ASPECT_RATIO = "56.25%";
305
300
  function CourseCardMedia({
306
- compact,
307
301
  visible,
308
302
  cardPicture,
309
303
  picture,
@@ -311,10 +305,7 @@ function CourseCardMedia({
311
305
  placeholderRef
312
306
  }) {
313
307
  return /*#__PURE__*/_jsx(ProgressiveCardMedia, {
314
- sx: compact ? {
315
- ...classes.media,
316
- paddingTop: COMPACT_MEDIA_ASPECT_RATIO
317
- } : classes.media,
308
+ sx: classes.media,
318
309
  highQualitySrc: visible || !pictureXs ? cardPicture || picture || PlaceholderImages.course : null,
319
310
  lowQualitySrc: pictureXs,
320
311
  placeholderRef: placeholderRef
@@ -373,10 +364,7 @@ function CompactCourseLoading() {
373
364
  children: [/*#__PURE__*/_jsx(CardTop, {
374
365
  children: /*#__PURE__*/_jsx(Skeleton, {
375
366
  variant: "rectangular",
376
- sx: {
377
- ...classes.media,
378
- paddingTop: COMPACT_MEDIA_ASPECT_RATIO
379
- }
367
+ sx: classes.media
380
368
  })
381
369
  }), /*#__PURE__*/_jsx(CardHeader, {
382
370
  title: /*#__PURE__*/_jsx(Skeleton, {
@@ -698,7 +686,6 @@ function CourseCard({
698
686
  role: "link",
699
687
  "aria-label": `${checked ? t("selected") : t("select")} ${courseName}`,
700
688
  children: /*#__PURE__*/_jsx(CourseCardMedia, {
701
- compact: true,
702
689
  visible: visible,
703
690
  cardPicture: cardPicture,
704
691
  picture: picture,
@@ -135,12 +135,7 @@ function Roleplay({
135
135
  children: [/*#__PURE__*/_jsx(CardTop, {
136
136
  children: /*#__PURE__*/_jsx(Skeleton, {
137
137
  variant: "rectangular",
138
- sx: {
139
- ...classes.media,
140
- ...(compact ? {
141
- paddingTop: "40%"
142
- } : {})
143
- }
138
+ sx: classes.media
144
139
  })
145
140
  }), /*#__PURE__*/_jsx(CardHeader, {
146
141
  action: /*#__PURE__*/_jsx(IconButton, {
@@ -199,12 +194,7 @@ function Roleplay({
199
194
  role: "link",
200
195
  "aria-label": "Card Image",
201
196
  children: [/*#__PURE__*/_jsx(ProgressiveCardMedia, {
202
- sx: {
203
- ...classes.media,
204
- ...(compact ? {
205
- paddingTop: "40%"
206
- } : {})
207
- },
197
+ sx: classes.media,
208
198
  highQualitySrc: visible || !pictureXs ? cardPicture || picture || PlaceholderImages.roleplay : null,
209
199
  lowQualitySrc: pictureXs,
210
200
  placeholderRef: placeholderRef,
@@ -38,12 +38,7 @@ function Topic({
38
38
  children: [/*#__PURE__*/_jsx(CardTop, {
39
39
  children: /*#__PURE__*/_jsx(Skeleton, {
40
40
  variant: "rectangular",
41
- sx: {
42
- ...classes.media,
43
- ...(compact ? {
44
- paddingTop: "40%"
45
- } : {})
46
- }
41
+ sx: classes.media
47
42
  })
48
43
  }), /*#__PURE__*/_jsx(CardHeader, {
49
44
  title: /*#__PURE__*/_jsx(Skeleton, {
@@ -94,12 +89,7 @@ function Topic({
94
89
  disabled: disableActions,
95
90
  role: "link",
96
91
  children: /*#__PURE__*/_jsx(ProgressiveCardMedia, {
97
- sx: {
98
- ...classes.media,
99
- ...(compact ? {
100
- paddingTop: "40%"
101
- } : {})
102
- },
92
+ sx: classes.media,
103
93
  highQualitySrc: visible || !pictureXs ? cardPicture || picture || PlaceholderImages.topic : null,
104
94
  lowQualitySrc: pictureXs,
105
95
  title: topicName,
@@ -16,7 +16,7 @@ import CloseIcon from "@mui/icons-material/Close";
16
16
  import AddIcon from "@mui/icons-material/Add";
17
17
  import Bots from "../../Lists/Bots/Bots";
18
18
  import PlaceholderImages from "../../utils/placeholder-images/index";
19
- import { SearchFilters, Transition } from "../SearchFilters/SearchFilters";
19
+ import { SearchFilters, Transition, applyFilters, useSearchFilters } from "../SearchFilters/SearchFilters";
20
20
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
21
21
  export default function FindChatbotDialog({
22
22
  open,
@@ -43,11 +43,11 @@ export default function FindChatbotDialog({
43
43
  // Restricted users are always kept on the library tab, regardless of state.
44
44
  const effectiveTab = isCommunityAccessRestricted ? 0 : tab;
45
45
  const [selectedBotIds, setSelectedBotIds] = useState([]);
46
- const [search, setSearch] = useState("");
47
- const [filters, setFilters] = useState({
48
- difficulty: "all",
49
- sort: "newest"
50
- });
46
+ const {
47
+ filters,
48
+ resetFilters,
49
+ filterProps
50
+ } = useSearchFilters();
51
51
  const allChatbots = [...libraryChatbots, ...communityChatbots];
52
52
  const selectedChatbots = allChatbots.filter(bot => selectedBotIds.includes(bot.botId)).filter((bot, index, arr) => arr.findIndex(b => b.botId === bot.botId) === index).map(bot => ({
53
53
  ...bot,
@@ -56,16 +56,6 @@ export default function FindChatbotDialog({
56
56
  const handleToggle = botId => {
57
57
  setSelectedBotIds(prev => prev.includes(botId) ? prev.filter(id => id !== botId) : [...prev, botId]);
58
58
  };
59
- const handleFilterChange = event => {
60
- const {
61
- name,
62
- value
63
- } = event.target;
64
- setFilters(prev => ({
65
- ...prev,
66
- [name]: value
67
- }));
68
- };
69
59
  const handleAdd = () => {
70
60
  onAddChatbots(selectedChatbots);
71
61
  reset();
@@ -73,11 +63,7 @@ export default function FindChatbotDialog({
73
63
  };
74
64
  const reset = () => {
75
65
  setSelectedBotIds([]);
76
- setSearch("");
77
- setFilters({
78
- difficulty: "all",
79
- sort: "newest"
80
- });
66
+ resetFilters();
81
67
  setTab(0);
82
68
  };
83
69
  const handleDialogClose = () => {
@@ -101,37 +87,14 @@ export default function FindChatbotDialog({
101
87
  const handleTabChange = (_, v) => {
102
88
  if (isCommunityAccessRestricted) return;
103
89
  setTab(v);
104
- setSearch("");
105
- setFilters({
106
- difficulty: "all",
107
- sort: "newest"
108
- });
90
+ resetFilters();
109
91
  if (scrollRef.current) scrollRef.current.scrollTop = 0;
110
92
  };
111
- const filterChatbots = chatbots => {
112
- if (!search.trim()) return chatbots;
113
- const q = search.toLowerCase();
114
- return chatbots.filter(bot => bot.botName?.toLowerCase().includes(q) || bot.description?.toLowerCase().includes(q) || bot.createdByName?.toLowerCase().includes(q));
115
- };
116
- const applyCommunityFilters = chatbots => {
117
- let result = filterChatbots(chatbots);
118
- if (filters.difficulty && filters.difficulty !== "all") {
119
- result = result.filter(bot => bot.difficulty === filters.difficulty);
120
- }
121
- if (filters.sort === "newest") {
122
- result = [...result].sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0));
123
- } else if (filters.sort === "oldest") {
124
- result = [...result].sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
125
- } else {
126
- result = [...result].sort((a, b) => (b.exerciseStartTotal || 0) - (a.exerciseStartTotal || 0));
127
- }
128
- return result;
129
- };
130
- const currentChatbots = effectiveTab === 0 ? filterChatbots(libraryChatbots) : applyCommunityFilters(communityChatbots);
93
+ const currentChatbots = applyFilters(effectiveTab === 0 ? libraryChatbots : communityChatbots, filters, "botName");
131
94
  const isLoading = effectiveTab === 0 ? isLoadingLibrary : isLoadingCommunity;
132
- const sectionLabel = effectiveTab === 0 ? t("add_own_exercise_message", {
95
+ const libraryLabel = t("add_own_exercise_message", {
133
96
  exerciseName: t("chatbots").toLowerCase()
134
- }) : t("or_select_a_community_template_desc");
97
+ });
135
98
  const addButtonLabel = selectedBotIds.length > 0 ? `${t("add_chatbots")} (${selectedBotIds.length})` : t("add_chatbots");
136
99
  return /*#__PURE__*/_jsxs(Dialog, {
137
100
  open: open,
@@ -190,24 +153,10 @@ export default function FindChatbotDialog({
190
153
  disabled: isCommunityAccessRestricted
191
154
  })]
192
155
  })
193
- }), effectiveTab === 1 && /*#__PURE__*/_jsx(Box, {
194
- sx: {
195
- px: 3,
196
- py: {
197
- xs: 0,
198
- md: 1.5
199
- },
200
- borderBottom: 1,
201
- borderColor: "divider"
202
- },
203
- children: /*#__PURE__*/_jsx(SearchFilters, {
204
- t: t,
205
- difficulty: filters.difficulty,
206
- handleFilterChange: handleFilterChange,
207
- sort: filters.sort,
208
- search: search,
209
- setSearch: setSearch
210
- })
156
+ }), /*#__PURE__*/_jsx(SearchFilters, {
157
+ t: t,
158
+ ...filterProps,
159
+ dataCyPrefix: "find-chatbots"
211
160
  }), /*#__PURE__*/_jsx(Box, {
212
161
  ref: scrollRef,
213
162
  sx: {
@@ -229,13 +178,13 @@ export default function FindChatbotDialog({
229
178
  children: t("no_chatbots_found") || "No chatbots found"
230
179
  })
231
180
  }) : /*#__PURE__*/_jsxs(_Fragment, {
232
- children: [/*#__PURE__*/_jsx(Typography, {
181
+ children: [effectiveTab === 0 && /*#__PURE__*/_jsx(Typography, {
233
182
  color: "text.secondary",
234
183
  sx: {
235
184
  display: "block",
236
185
  mb: 2
237
186
  },
238
- children: sectionLabel
187
+ children: libraryLabel
239
188
  }), /*#__PURE__*/_jsx(Bots, {
240
189
  t: t,
241
190
  bots: currentChatbots,
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useMemo, useRef, forwardRef } from "react";
1
+ import { useState, useEffect, useMemo, useRef } from "react";
2
2
  import { useInView } from "react-intersection-observer";
3
3
  import { courses as courseQuerys, ReactQuery } from "@nualang/nualang-api-and-queries/Queries";
4
4
  import { getCourses } from "@nualang/nualang-api-and-queries/APIs/Courses";
@@ -7,7 +7,6 @@ import AppBar from "@mui/material/AppBar";
7
7
  import Toolbar from "@mui/material/Toolbar";
8
8
  import IconButton from "@mui/material/IconButton";
9
9
  import Typography from "@mui/material/Typography";
10
- import Slide from "@mui/material/Slide";
11
10
  import Box from "@mui/material/Box";
12
11
  import Tabs from "@mui/material/Tabs";
13
12
  import Tab from "@mui/material/Tab";
@@ -26,6 +25,7 @@ import SortBySelector from "../../Forms/SortBySelector/SortBySelector";
26
25
  import useDebounce from "../../hooks/useDebounce";
27
26
  import useHorizontalScroll from "../../hooks/useHorizontalScroll";
28
27
  import PlaceholderImages from "../../utils/placeholder-images/index";
28
+ import { DIFFICULTIES, SORT_BY_OPTIONS, Transition, sortItems } from "../SearchFilters/SearchFilters";
29
29
 
30
30
  // The Community tab wraps into a grid, same as Topics.jsx's compact cards in
31
31
  // FindTopicsDialog. My library keeps horizontal scrolling rows (below) so
@@ -46,29 +46,47 @@ const courseGridSx = {
46
46
  const {
47
47
  useInfiniteQuery
48
48
  } = ReactQuery;
49
-
50
- // Same CEFR codes FindTopicsDialog's community difficulty filter uses.
51
- const DIFFICULTIES = ["A1", "A2", "B1", "B2", "C1", "C2"];
52
49
  const LIBRARY_PAGE_SIZE = 12;
53
50
  const nextLibraryPageParam = lastPage => lastPage.LastEvaluatedKey?.page || lastPage.LastEvaluatedKey?.courseId ? lastPage.LastEvaluatedKey : undefined;
54
- const SORT_BY_OPTIONS = {
55
- popular: "popular",
56
- newest: "newest",
57
- oldest: "oldest"
58
- };
59
51
  const DEFAULT_FILTERS = {
60
52
  learnLang: "all",
61
53
  forLang: "all",
62
54
  difficulty: "all",
63
55
  sort: "popular"
64
56
  };
65
- const Transition = /*#__PURE__*/forwardRef(function Transition(props, ref) {
66
- return /*#__PURE__*/_jsx(Slide, {
67
- direction: "up",
68
- ref: ref,
69
- ...props
57
+ const MY_LIBRARY_TAB = 0;
58
+ // My library lists the user's own courses, so newest first is more useful
59
+ // there than popularity. The Community tab keeps the "popular" default.
60
+ const MY_LIBRARY_DEFAULT_SORT = "newest";
61
+
62
+ // My library rows are fetched in full and filtered here, the same way the
63
+ // Courses screen does it, so search never goes through the global course search.
64
+ function filterLibraryCourses(courses, filters, search) {
65
+ const searchText = search.trim().toLowerCase();
66
+ const filtered = courses.filter(course => {
67
+ if (filters.learnLang !== "all" && course.learnLang !== filters.learnLang) {
68
+ return false;
69
+ }
70
+ if (filters.forLang !== "all" && course.forLang !== filters.forLang) {
71
+ return false;
72
+ }
73
+ if (filters.difficulty !== "all") {
74
+ const difficulties = Array.isArray(course.difficulty) ? course.difficulty : [course.difficulty];
75
+ if (!difficulties.includes(filters.difficulty)) {
76
+ return false;
77
+ }
78
+ }
79
+ if (searchText) {
80
+ const nameMatch = (course.courseName || "").toLowerCase().includes(searchText);
81
+ const descriptionMatch = (course.description || "").toLowerCase().includes(searchText);
82
+ if (!nameMatch && !descriptionMatch) {
83
+ return false;
84
+ }
85
+ }
86
+ return true;
70
87
  });
71
- });
88
+ return sortItems(filtered, filters.sort);
89
+ }
72
90
  function CourseFilters({
73
91
  t,
74
92
  search,
@@ -202,7 +220,7 @@ function CourseFilters({
202
220
  children: t("all") || "All"
203
221
  }), DIFFICULTIES.map(d => /*#__PURE__*/_jsx(MenuItem, {
204
222
  value: d,
205
- children: d
223
+ children: t(d) || d
206
224
  }, d))]
207
225
  }), /*#__PURE__*/_jsx(SortBySelector, {
208
226
  id: "course-sort",
@@ -383,6 +401,7 @@ export default function FindCoursesDialog({
383
401
  formatCourses,
384
402
  groupCourseIds = [],
385
403
  groupCoursesLimit = 100,
404
+ createdCoursesLimit = 1000,
386
405
  alreadyAddedCourseIds = [],
387
406
  isCommunityAccessRestricted = false,
388
407
  learnLangOptions = [],
@@ -397,16 +416,19 @@ export default function FindCoursesDialog({
397
416
  } = useInView({
398
417
  threshold: 0
399
418
  });
400
- const [tab, setTab] = useState(0);
401
- const effectiveTab = isCommunityAccessRestricted ? 0 : tab;
419
+ const [tab, setTab] = useState(MY_LIBRARY_TAB);
420
+ const effectiveTab = isCommunityAccessRestricted ? MY_LIBRARY_TAB : tab;
402
421
  const [selectedCourseIds, setSelectedCourseIds] = useState([]);
403
422
  const [search, setSearch] = useState("");
404
- const defaultFilters = {
423
+ const getDefaultFilters = tabIndex => ({
405
424
  ...DEFAULT_FILTERS,
406
425
  learnLang: defaultLearnLang,
407
- forLang: defaultForLang
408
- };
409
- const [filters, setFilters] = useState(defaultFilters);
426
+ forLang: defaultForLang,
427
+ ...(tabIndex === MY_LIBRARY_TAB && {
428
+ sort: MY_LIBRARY_DEFAULT_SORT
429
+ })
430
+ });
431
+ const [filters, setFilters] = useState(() => getDefaultFilters(MY_LIBRARY_TAB));
410
432
  // Every course object ever handed to this dialog, keyed by id. search/
411
433
  // difficulty/sort are now applied upstream (the caller only fetches
412
434
  // matching pages), so a course that's selected and then filtered out of
@@ -422,8 +444,8 @@ export default function FindCoursesDialog({
422
444
  const reset = () => {
423
445
  setSelectedCourseIds([]);
424
446
  setSearch("");
425
- setFilters(defaultFilters);
426
- setTab(0);
447
+ setFilters(getDefaultFilters(MY_LIBRARY_TAB));
448
+ setTab(MY_LIBRARY_TAB);
427
449
  setSearchResetKey(key => key + 1);
428
450
  setCourseCache(new Map());
429
451
  };
@@ -447,7 +469,7 @@ export default function FindCoursesDialog({
447
469
  if (isCommunityAccessRestricted) return;
448
470
  setTab(v);
449
471
  setSearch("");
450
- setFilters(defaultFilters);
472
+ setFilters(getDefaultFilters(v));
451
473
  setSearchResetKey(key => key + 1);
452
474
  };
453
475
  const handleFilterChange = event => {
@@ -465,28 +487,19 @@ export default function FindCoursesDialog({
465
487
  // every page load - so the carousels below know when a reorder is a real
466
488
  // reset versus just more of the same sort settling in as data grows.
467
489
  const librarySortResetKey = `${search}|${filters.learnLang}|${filters.forLang}|${filters.difficulty}|${filters.sort}`;
490
+
491
+ // Search/filters/sort are applied client-side in libraryCreatedCourses, so
492
+ // changing them doesn't refetch
468
493
  const teachCoursesQuery = useInfiniteQuery({
469
- queryKey: ["findCoursesDialog", "created", username, filters.learnLang, filters.forLang, filters.difficulty, search, filters.sort],
494
+ queryKey: ["findCoursesDialog", "created", username],
470
495
  queryFn: async ({
471
496
  pageParam = {}
472
497
  }) => {
473
498
  const response = await getCourses({
474
499
  createdBy: username,
475
500
  verbose: false,
476
- limit: LIBRARY_PAGE_SIZE,
477
- sort: filters.sort,
478
- ...(filters.learnLang !== "all" && {
479
- learnLang: filters.learnLang
480
- }),
481
- ...(filters.forLang !== "all" && {
482
- forLang: filters.forLang
483
- }),
484
- ...(filters.difficulty !== "all" && {
485
- difficulty: filters.difficulty
486
- }),
487
- ...(search && {
488
- search
489
- }),
501
+ // Get all using high limit, same as the Courses screen
502
+ limit: createdCoursesLimit,
490
503
  page: pageParam.page || 1,
491
504
  lastEvaluatedCourseId: pageParam.courseId || "",
492
505
  lastEvaluatedKey: pageParam.courseId || "",
@@ -503,6 +516,20 @@ export default function FindCoursesDialog({
503
516
  getNextPageParam: nextLibraryPageParam,
504
517
  enabled: !!username && open
505
518
  });
519
+ const {
520
+ hasNextPage: hasMoreCreated,
521
+ isFetchingNextPage: isFetchingMoreCreated,
522
+ isFetchNextPageError: isCreatedNextPageError
523
+ } = teachCoursesQuery;
524
+ useEffect(() => {
525
+ if (!open || !username || !hasMoreCreated || isFetchingMoreCreated || isCreatedNextPageError) {
526
+ return;
527
+ }
528
+ teachCoursesQuery.fetchNextPage({
529
+ cancelRefetch: false
530
+ });
531
+ // eslint-disable-next-line react-hooks/exhaustive-deps
532
+ }, [open, username, hasMoreCreated, isFetchingMoreCreated, isCreatedNextPageError]);
506
533
  const learnCoursesQuery = useInfiniteQuery({
507
534
  queryKey: ["findCoursesDialog", "joined", username],
508
535
  queryFn: async ({
@@ -545,32 +572,9 @@ export default function FindCoursesDialog({
545
572
  const groupCourses = groupCoursesQuery.isSuccess && Array.isArray(groupCoursesQuery.data) ? groupCoursesQuery.data : [];
546
573
  const combined = [...learnCourses, ...groupCourses];
547
574
  const deduped = combined.filter((course, index) => combined.findIndex(c => c.courseId === course.courseId) === index);
548
- const searchText = search.trim().toLowerCase();
549
- const filtered = deduped.filter(course => {
550
- if (filters.learnLang !== "all" && course.learnLang !== filters.learnLang) return false;
551
- if (filters.forLang !== "all" && course.forLang !== filters.forLang) return false;
552
- if (filters.difficulty !== "all") {
553
- const difficulties = Array.isArray(course.difficulty) ? course.difficulty : [course.difficulty];
554
- if (!difficulties.includes(filters.difficulty)) return false;
555
- }
556
- if (searchText) {
557
- const nameMatch = (course.courseName || "").toLowerCase().includes(searchText);
558
- const descriptionMatch = (course.description || "").toLowerCase().includes(searchText);
559
- if (!nameMatch && !descriptionMatch) return false;
560
- }
561
- return true;
562
- });
563
- const sorted = [...filtered];
564
- if (filters.sort === "newest") {
565
- sorted.sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0));
566
- } else if (filters.sort === "oldest") {
567
- sorted.sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
568
- } else {
569
- sorted.sort((a, b) => (b.exerciseStartTotal || 0) - (a.exerciseStartTotal || 0));
570
- }
571
- return sorted;
572
- }, [learnCoursesQuery.data, groupCoursesQuery.data, groupCoursesQuery.isSuccess, filters.learnLang, filters.forLang, filters.difficulty, search, filters.sort]);
573
- const libraryCreatedCourses = useMemo(() => (teachCoursesQuery.data?.pages || []).flatMap(page => page.Items || []), [teachCoursesQuery.data]);
575
+ return filterLibraryCourses(deduped, filters, search);
576
+ }, [learnCoursesQuery.data, groupCoursesQuery.data, groupCoursesQuery.isSuccess, filters, search]);
577
+ const libraryCreatedCourses = useMemo(() => filterLibraryCourses((teachCoursesQuery.data?.pages || []).flatMap(page => page.Items || []), filters, search), [teachCoursesQuery.data, filters, search]);
574
578
  const communityCoursesQuery = courseQuerys.useCommunityCourses(async queryFilters => {
575
579
  const response = await getCourses(queryFilters);
576
580
  const formattedCourses = await formatCourses(response.Items, authData);
@@ -807,18 +811,11 @@ export default function FindCoursesDialog({
807
811
  isLoadingMore: learnCoursesQuery.isFetchingNextPage,
808
812
  resetKey: librarySortResetKey
809
813
  })]
810
- }) : isLoadingCommunity ? /*#__PURE__*/_jsxs(Box, {
814
+ }) : isLoadingCommunity ? /*#__PURE__*/_jsx(Box, {
811
815
  sx: {
812
816
  p: 3
813
817
  },
814
- children: [/*#__PURE__*/_jsx(Skeleton, {
815
- variant: "text",
816
- width: 220,
817
- height: 28,
818
- sx: {
819
- mb: 2
820
- }
821
- }), /*#__PURE__*/_jsx(Box, {
818
+ children: /*#__PURE__*/_jsx(Box, {
822
819
  sx: courseGridSx,
823
820
  children: Array.from({
824
821
  length: 10
@@ -826,7 +823,7 @@ export default function FindCoursesDialog({
826
823
  t: t,
827
824
  compact: true
828
825
  }, i))
829
- })]
826
+ })
830
827
  }) : isCommunityEmpty ? /*#__PURE__*/_jsx(Box, {
831
828
  display: "flex",
832
829
  justifyContent: "center",
@@ -839,14 +836,7 @@ export default function FindCoursesDialog({
839
836
  sx: {
840
837
  p: 3
841
838
  },
842
- children: [/*#__PURE__*/_jsx(Typography, {
843
- variant: "body2",
844
- color: "text.secondary",
845
- sx: {
846
- mb: 2
847
- },
848
- children: t("courses_shared_by_other_teachers") || "Courses shared by other teachers"
849
- }), communityCourses.length === 0 ? /*#__PURE__*/_jsx(Typography, {
839
+ children: [communityCourses.length === 0 ? /*#__PURE__*/_jsx(Typography, {
850
840
  variant: "body2",
851
841
  color: "text.secondary",
852
842
  children: t("no_community_courses_match") || "No courses match these filters"