diff --git a/apps/forum/src/components/APIs.tsx b/apps/forum/src/components/APIs.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/apps/forum/src/components/Board.tsx b/apps/forum/src/components/Board.tsx index bbe1c4d37..941a2e52a 100644 --- a/apps/forum/src/components/Board.tsx +++ b/apps/forum/src/components/Board.tsx @@ -5,8 +5,8 @@ import CreateThread from "./CreateThread"; import ThreadBlock from "./ThreadBlock"; import boards from "@app/constants/boards.json"; import localForage from "localforage"; -import { currentGroupsState, currentTagsState } from "@app/recoil/atoms"; -import { filterThreadsByTags, filterThreadsByGroups } from "@app/utils/filter"; +import { currentSchoolState, currentTagsState } from "@app/recoil/atoms"; +import { filterThreadsByTags, filterThreadsBySchool } from "@app/utils/filter"; import { API } from "@aws-amplify/api"; import Thread from "@app/types/thread"; import { getUserAttr } from "wasedatime-ui"; @@ -18,7 +18,7 @@ const Board = () => { const { boardSlug } = useParams(); const currentTags = useRecoilValue(currentTagsState); - const currentGroups = useRecoilValue(currentGroupsState); + const currentSchools = useRecoilValue(currentSchoolState); const [boardId, setBoardId] = useState( boards.find((board) => board.slug === boardSlug)?.slug || "academic" @@ -65,7 +65,10 @@ const Board = () => { console.log(threads); var filteredThreads = filterThreadsByTags(threads, currentTags); - filteredThreads = filterThreadsByGroups(filteredThreads, currentGroups); + filteredThreads = filterThreadsBySchool( + filteredThreads, + currentSchools + ); if (filteredThreads.length > threadCountPerPage * page) filteredThreads = filteredThreads.slice(0, threadCountPerPage * page); setFilteredThreads(filteredThreads); @@ -77,16 +80,16 @@ const Board = () => { }); }; - // when currentTags or currentGroups change, filter the threads + // when currentTags or currentSchools change, filter the threads useEffect(() => { var filteredThreads = filterThreadsByTags(boardThreads, currentTags); - filteredThreads = filterThreadsByGroups(filteredThreads, currentGroups); + filteredThreads = filterThreadsBySchool(filteredThreads, currentSchools); if (filteredThreads.length > threadCountPerPage * page) filteredThreads = filteredThreads.slice(0, threadCountPerPage * page); if (filteredThreads.length > threadCountPerPage * page) filteredThreads = filteredThreads.slice(0, threadCountPerPage * page); setFilteredThreads(filteredThreads); - }, [currentTags, currentGroups]); + }, [currentTags, currentSchools]); const displayMoreThread = () => { setTimeout(() => { @@ -94,7 +97,7 @@ const Board = () => { const nextPage = page + 1; setPage(nextPage); var threads = filterThreadsByTags(boardThreads, currentTags); - threads = filterThreadsByGroups(threads, currentGroups); + threads = filterThreadsBySchool(threads, currentSchools); threads = threads.slice(0, threadCountPerPage * nextPage); setFilteredThreads(threads); }, 1000); diff --git a/apps/forum/src/components/FilterMenu.tsx b/apps/forum/src/components/FilterMenu.tsx index 112e36e58..c482be3ce 100644 --- a/apps/forum/src/components/FilterMenu.tsx +++ b/apps/forum/src/components/FilterMenu.tsx @@ -1,30 +1,29 @@ import React, { useState, useEffect } from "react"; import { useRecoilState } from "recoil"; import { useNavigate } from "react-router-dom"; -import groups from "@app/constants/groups.json"; -import CheckList from "@app/components/form/CheckList"; import SchoolFilterForm from "@app/components/SchoolFilterForm"; -import { currentGroupsState } from "@app/recoil/atoms"; +import { currentSchoolState } from "@app/recoil/atoms"; const FilterMenu = () => { - const [currentGroups, setCurrentGroups] = useRecoilState(currentGroupsState); + const [currentSchools, setCurrentSchools] = + useRecoilState(currentSchoolState); const [openSchoolModal, setOpenSchoolModal] = useState(false); const navigate = useNavigate(); const toggleGroup = (group: string) => { - if (currentGroups.includes(group)) { - var groups = [...currentGroups]; + if (currentSchools.includes(group)) { + var groups = [...currentSchools]; const index = groups.indexOf(group); if (index > -1) { groups.splice(index, 1); } - setCurrentGroups(groups); + setCurrentSchools(groups); } else { - setCurrentGroups([...currentGroups, group]); + setCurrentSchools([...currentSchools, group]); } }; - const isGroupChecked = (group: string) => currentGroups.includes(group); + const isGroupChecked = (group: string) => currentSchools.includes(group); const toggleSchoolFilter = () => { setOpenSchoolModal(!openSchoolModal); diff --git a/apps/forum/src/components/Home.tsx b/apps/forum/src/components/Home.tsx index 3c66fb939..5b46e714f 100644 --- a/apps/forum/src/components/Home.tsx +++ b/apps/forum/src/components/Home.tsx @@ -5,8 +5,8 @@ import CreateThread from "./CreateThread"; import ThreadBlock from "./ThreadBlock"; import boards from "@app/constants/boards.json"; import localForage from "localforage"; -import { currentGroupsState, currentTagsState } from "@app/recoil/atoms"; -import { filterThreadsByTags, filterThreadsByGroups } from "@app/utils/filter"; +import { currentSchoolState, currentTagsState } from "@app/recoil/atoms"; +import { filterThreadsByTags, filterThreadsBySchool } from "@app/utils/filter"; import { API } from "@aws-amplify/api"; import Thread from "@app/types/thread"; import { getUserAttr } from "wasedatime-ui"; @@ -16,17 +16,13 @@ const threadCountPerPage = 3; // 10 const Home = () => { const currentTags = useRecoilValue(currentTagsState); - const currentGroups = useRecoilValue(currentGroupsState); + const currentSchools = useRecoilValue(currentSchoolState); const [allThreads, setAllThreads] = useState([]); const [filteredThreads, setFilteredThreads] = useState([]); const [userToken, setUserToken] = useState(""); const [page, setPage] = useState(1); - const boardStorage = localForage.createInstance({ - name: "BoardData", - }); - // fetching the all thread data useEffect(() => { const fetchData = async () => { @@ -65,11 +61,12 @@ const Home = () => { useEffect(() => { var filteredThreads = filterThreadsByTags(allThreads, currentTags); - filteredThreads = filterThreadsByGroups(filteredThreads, currentGroups); + filteredThreads = filterThreadsBySchool(filteredThreads, currentSchools); if (filteredThreads.length > threadCountPerPage * page) filteredThreads = filteredThreads.slice(0, threadCountPerPage * page); setFilteredThreads(filteredThreads); - }, [currentTags, currentGroups]); + displayMoreThread(); + }, [currentTags, currentSchools]); const displayMoreThread = () => { console.log("displayMoreThread called"); // Debugging @@ -82,11 +79,12 @@ const Home = () => { "page:", page ); // Debugging + if (allThreads.length < threadCountPerPage * page) return; const nextPage = page + 1; setPage(nextPage); var threads = filterThreadsByTags(allThreads, currentTags); - threads = filterThreadsByGroups(threads, currentGroups); + threads = filterThreadsBySchool(threads, currentSchools); threads = threads.slice(0, threadCountPerPage * nextPage); console.log("Setting filteredThreads:", threads); // Debugging setFilteredThreads(threads); @@ -106,10 +104,10 @@ const Home = () => { style={{ overflowY: "hidden" }} > {/* {this.state.items.map((i, index) => ( -
- div - #{index} -
- ))} */} +
+ div - #{index} +
+ ))} */} {filteredThreads.map((thread, i) => ( ))} @@ -120,3 +118,8 @@ const Home = () => { }; export default Home; + +// 1 when you first enter) fetch posts (useEffect) -> display posts +// 2 filtering by "groups" -> state that manages groups ("") -> group is selected then setGroup(selected group) +// 3) [posts, setPosts] = useState([]) -> entering the page: setState([post1, post2..... post9]) +// 4) displayMore is triggered [...post9] + [additional 10 posts] = [20 posts] diff --git a/apps/forum/src/components/SchoolFilterForm.tsx b/apps/forum/src/components/SchoolFilterForm.tsx index 215b7407a..fa4ea8066 100644 --- a/apps/forum/src/components/SchoolFilterForm.tsx +++ b/apps/forum/src/components/SchoolFilterForm.tsx @@ -7,7 +7,7 @@ import { } from "@app/constants/schools"; import { School } from "@app/constants/schools"; import getSchoolIconPath from "@app/utils/get-school-icon-path"; -import { currentGroupsState } from "@app/recoil/atoms"; +import { currentSchoolState } from "@app/recoil/atoms"; const schoolsByCategory = [ { @@ -73,26 +73,27 @@ const TabItem = ({ title, isActive, onClick }: TabItemProps) => ( const SchoolFilterForm = ({ isOpen, setOpen }: SchoolFilterFormProps) => { const [schoolsCategoryId, setSchoolsCategoryId] = useState(0); - const [currentGroups, setCurrentGroups] = useRecoilState(currentGroupsState); + const [currentSchools, setCurrentSchools] = + useRecoilState(currentSchoolState); - const toggleGroup = (group: string) => { - console.log(group); - if (currentGroups.includes(group)) { - var groups = [...currentGroups]; - const index = groups.indexOf(group); + const toggleGroup = (school: string) => { + console.log(school); + if (currentSchools.includes(school)) { + var schools = [...currentSchools]; + const index = schools.indexOf(school); if (index > -1) { - groups.splice(index, 1); + schools.splice(index, 1); } - setCurrentGroups(groups); + setCurrentSchools(schools); } else { - setCurrentGroups([...currentGroups, group]); + setCurrentSchools([...currentSchools, school]); } }; const SchoolBlock = ({ school }: SchoolBlockProps) => (
{ + if (!text) return null; + + const urlRegex = /https?:\/\/[^\s]+/g; + const parts = text.split(urlRegex); + const matches = text.match(urlRegex); + + return ( +
+ {parts.map((part, index) => ( + + {part} + {matches && matches[index] ? ( + + {matches[index]} + + ) : null} + + ))} +
+ ); +}; + const ThreadBlock = ({ isPreview, thread }: Props) => { const [userToken, setUserToken] = useState(""); const [editModalOpen, setEditModalOpen] = useState(false); const [deleteModalOpen, setDeleteModalOpen] = useState(false); - const convertUrlsToLinks = (text: string) => { - if (!text) return null; - - const urlRegex = /https?:\/\/[^\s]+/g; - const parts = text.split(urlRegex); - const matches = text.match(urlRegex); - - return ( -
- {parts.map((part, index) => ( - <> - {part} - {matches && matches[index] ? ( - - {matches[index]} - - ) : null} - - ))} -
- ); - }; - useEffect(() => { const updateLoginStatus = async () => { const idToken = await getIdToken(); diff --git a/apps/forum/src/recoil/atoms.ts b/apps/forum/src/recoil/atoms.ts index 810ba47ab..a577a365b 100644 --- a/apps/forum/src/recoil/atoms.ts +++ b/apps/forum/src/recoil/atoms.ts @@ -10,7 +10,7 @@ export const currentTagsState = atom({ default: [], }); -export const currentGroupsState = atom({ - key: "currentGroups", +export const currentSchoolState = atom({ + key: "currentSchools", default: [], }); diff --git a/apps/forum/src/utils/filter.ts b/apps/forum/src/utils/filter.ts index 290c315c5..72f90a878 100644 --- a/apps/forum/src/utils/filter.ts +++ b/apps/forum/src/utils/filter.ts @@ -5,7 +5,7 @@ export const filterThreadsByTags = (threads: Thread[], tags: string[]) => ? threads.filter((thread) => tags.includes(thread.tag_id)) : threads; -export const filterThreadsByGroups = (threads: Thread[], groups: string[]) => +export const filterThreadsBySchool = (threads: Thread[], groups: string[]) => groups.length > 0 ? threads.filter((thread) => groups.includes(thread.group_id)) : threads;