Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CHE-65] Create CreateThread Component #78

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions client/src/components/Forums/CreateThread/CreateThread.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import React, { useState, ChangeEvent, FormEvent } from "react";
import axios from "axios";

interface CreateThreadProps {
forumId: string;
onClose: () => void;
}

const CreateThread: React.FC<CreateThreadProps> = ({ forumId, onClose }) => {
const [formData, setFormData] = useState<{ title: string; content: string }>({
title: "",
content: "",
});

const { title, content } = formData;

const handleChange = (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const response = await axios.post(
`/api/forums/${forumId}/threads`,
formData,
{
withCredentials: true,
}
);
console.log("Thread created:", response.data);
onClose();
} catch (error) {
console.error("Failed to create thread:", error);
//TODO userfeedback with errors
}
};

return (
<div className="w-full max-w-lg">
<form
className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
onSubmit={handleSubmit}
>
<div className="mb-4">
<label
className="block text-gray-700 text-sm font-bold mb-2"
htmlFor="title"
>
Title
</label>
<input
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="title"
name="title"
type="text"
placeholder="Thread Title"
value={title}
onChange={handleChange}
required
/>
</div>
<div className="mb-6">
<label
className="block text-gray-700 text-sm font-bold mb-2"
htmlFor="content"
>
Content
</label>
<textarea
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="content"
name="content"
rows={4}
placeholder="Write something..."
value={content}
onChange={handleChange}
required
/>
</div>
<div className="flex items-center justify-between">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="submit"
>
Create Thread
</button>
</div>
</form>
</div>
);
};

export default CreateThread;
20 changes: 19 additions & 1 deletion client/src/components/Forums/ThreadsDisplay/ThreadsDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import CreateThread from "../CreateThread/CreateThread";
import { Thread, IForum } from "../../../../types/forums";

interface ThreadsDisplayProps {
Expand All @@ -15,6 +16,7 @@ const ThreadsDisplay: React.FC<ThreadsDisplayProps> = ({
const [forum, setForum] = useState<IForum | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [creatingThread, setCreatingThread] = useState(false);

useEffect(() => {
const fetchForumAndThreads = async () => {
Expand Down Expand Up @@ -42,7 +44,11 @@ const ThreadsDisplay: React.FC<ThreadsDisplayProps> = ({
};

fetchForumAndThreads();
}, [forumId]);
}, [forumId, creatingThread]);

const toggleCreateThread = () => {
setCreatingThread(!creatingThread);
};

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
Expand All @@ -52,6 +58,18 @@ const ThreadsDisplay: React.FC<ThreadsDisplayProps> = ({
<h3 className="text-xl font-bold mb-4">
{forum ? `Showing threads for ${forum.title}` : "Showing all threads"}
</h3>
{forumId && (
<button
onClick={toggleCreateThread}
className="mb-4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
{creatingThread ? "Cancel" : "Create New Thread"}
</button>
)}
{creatingThread && forumId ? (
<CreateThread forumId={forumId} onClose={toggleCreateThread} />
) : null}

<ul>
{threads.map((thread) => (
<li
Expand Down
1 change: 1 addition & 0 deletions server/controllers/threadController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const createThread = async (
res: Response,
next: NextFunction
) => {
console.log("TEST!");
const { forumId } = req.params;
const { title, content } = req.body;

Expand Down
Loading