diff --git a/apps/forum/src/components/App.tsx b/apps/forum/src/components/App.tsx
index 7e41f4a0c..e04651147 100644
--- a/apps/forum/src/components/App.tsx
+++ b/apps/forum/src/components/App.tsx
@@ -11,7 +11,7 @@ import SearchTags from "./SearchTags";
import FeedBackBox from "./FeedBackBox";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { API } from "@aws-amplify/api";
-import { getUserAttr, getIdToken } from "wasedatime-ui";
+import { getUserAttr, getIdToken, LoadingSpinner } from "wasedatime-ui";
const App = () => {
return (
@@ -25,6 +25,14 @@ const App = () => {
export default App;
+const NotFound = () => {
+ const { theme } = React.useContext(ThemeContext);
+ const navigate = useNavigate();
+ useEffect(() => navigate("/"));
+
+ return ;
+};
+
const InnerApp = () => {
const { t, i18n } = useTranslation();
@@ -108,6 +116,7 @@ const InnerApp = () => {
path="forum/:boardSlug"
/>
} path="forum/:boardSlug/:threadUuid" />
+ } path="*" />
diff --git a/apps/forum/src/components/Comment.tsx b/apps/forum/src/components/Comment.tsx
index af9e1e7ae..afe2daa8a 100644
--- a/apps/forum/src/components/Comment.tsx
+++ b/apps/forum/src/components/Comment.tsx
@@ -7,6 +7,7 @@ import { ConfirmModal } from "@app/components/form/ConfirmModal";
import API from "@aws-amplify/api";
import { getIdToken } from "wasedatime-ui";
import ThreadType from "@app/types/thread";
+import { timeFormatter } from "../utils/timeFormatter";
type Props = {
comment: CommentType;
@@ -18,7 +19,7 @@ type Props = {
const convertUrlsToLinks = (text: string) => {
if (!text) return null;
- const urlRegex = /https?:\/\/[^\s]+/g;
+ const urlRegex: RegExp = /https?:\/\/[^\s]+/g;
const parts = text.split(urlRegex);
const matches = text.match(urlRegex);
@@ -100,8 +101,6 @@ const Comment = ({ comment, thread, setComments, setThread }: Props) => {
}
);
- console.log(res);
-
const action = "update_decr";
await API.patch(
"wasedatime-dev",
@@ -129,12 +128,15 @@ const Comment = ({ comment, thread, setComments, setThread }: Props) => {
}
};
+ const time = timeFormatter(comment);
+ console.log(comment);
+
return (
{convertUrlsToLinks(comment.body)}
-
+ Posted at {time}
{comment.mod === true && (
diff --git a/apps/forum/src/components/CommentForm.tsx b/apps/forum/src/components/CommentForm.tsx
index 1871b6011..d470eff1c 100644
--- a/apps/forum/src/components/CommentForm.tsx
+++ b/apps/forum/src/components/CommentForm.tsx
@@ -66,6 +66,7 @@ const CommentForm: React.FC
= ({
);
const newComment: CommentType = response.data;
+
onNewComment(newComment);
setComment("");
@@ -105,12 +106,12 @@ const CommentForm: React.FC = ({
}
} catch (error) {
console.error("An error occurred:", error);
- } finally {
}
};
return (
+ {/*
Posted at ${time}
*/}
= ({
>
- {isSignInModalOpen && (
-
setSignInModalOpen(false)}
- t={t}
- />
- )}
+ setSignInModalOpen(false)}
+ t={t}
+ />
);
};
diff --git a/apps/forum/src/components/CreateThread.tsx b/apps/forum/src/components/CreateThread.tsx
index a2a9c980c..eecad3972 100644
--- a/apps/forum/src/components/CreateThread.tsx
+++ b/apps/forum/src/components/CreateThread.tsx
@@ -9,6 +9,8 @@ import SchoolFilterForm from "./common/SchoolFilter";
import { Menu, Transition } from "@headlessui/react";
import ThreadType from "@app/types/thread";
import TagType from "@app/types/tag";
+import ImageIcon from "@mui/icons-material/Image";
+import threadPayload from "@app/types/threadPayload";
interface CreateThreadProps {
onNewThread: (newThread: ThreadType) => void;
@@ -29,6 +31,9 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
const [selectedBoard, setSelectedBoard] = useState("");
const [selectedTag, setSelectedTag] = useState(null);
const [selectedSchool, setSelectedSchool] = useState("");
+ const [fileName, setFileName] = useState(null);
+ const [selectedFile, setSelectedFile] = useState(null);
+ const [fileType, setFileType] = useState(null);
// Tags and Group buttons might be best moved to their respective components but this is how I will leave it for now.
const { boardSlug } = useParams();
@@ -81,6 +86,20 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
setSelectedTag(tag);
};
+ const handleImageChange = (e: ChangeEvent) => {
+ const file = e.target.files ? e.target.files[0] : null;
+ if (file) {
+ const reader = new FileReader();
+ reader.readAsDataURL(file);
+ reader.onloadend = () => {
+ const base64data = reader.result as string;
+ setSelectedFile(base64data); // Store the base64-encoded image
+ setFileType(file.type); // Store the MIME type of the file
+ };
+ setFileName(file.name); // Store the name of the selected file
+ }
+ };
+
const handleSubmit = async () => {
// Require a Board
// If current board isn't chosen, then output this
@@ -125,18 +144,26 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
}
try {
+ const payload: threadPayload = {
+ body: textContent,
+ title: "default",
+ tag_id: "default",
+ group_id: selectedSchool,
+ univ_id: "1",
+ board_id: selectedBoard,
+ };
+
+ if (selectedFile) {
+ payload.image = selectedFile;
+ payload.contentType = fileType || "";
+ payload.fileName = fileName || "image";
+ }
const response = await API.post(
"wasedatime-dev",
`/forum/${selectedBoard}`,
{
body: {
- data: {
- body: textContent,
- title: "default",
- tag_id: "default",
- group_id: selectedSchool,
- univ_id: "1",
- },
+ data: payload,
},
headers: {
"Content-Type": "application/json",
@@ -158,6 +185,10 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
setTitleContent("");
setTextContent("");
setSelectedBoard("");
+ setSelectedSchool("");
+ setSelectedFile(null);
+ setFileType(null);
+ setFileName(null);
setSelectedTag(null);
} catch (error) {
console.log(error);
@@ -308,6 +339,22 @@ const CreateThread = ({ onNewThread }: CreateThreadProps) => {
) : null}
{selectedSchool ? selectedSchool : "School"}
+
+
+
+