Skip to content

Commit

Permalink
this is change for the targeted posting fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ktiuyi committed Jan 30, 2025
1 parent d9d379e commit aea2d89
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 85 deletions.
74 changes: 23 additions & 51 deletions backend/controllers/postController.js
Original file line number Diff line number Diff line change
Expand Up @@ -1266,23 +1266,15 @@ const sendNotificationEmail = async (recipientEmail, posterId, postId, posterUse

const createPost = async (req, res) => {
try {
const {
postedBy,
text,
targetYearGroups,
targetDepartments,
targetAudience,
} = req.body;
const { postedBy, text, targetYearGroups, targetDepartments, targetAudience } = req.body;
let { img } = req.body;

// Validate required fields
if (!postedBy || !text) {
return res
.status(400)
.json({ error: "PostedBy and text fields are required" });
return res.status(400).json({ error: "PostedBy and text fields are required" });
}

// Find the user who is posting
// Find and validate user
const user = await User.findById(postedBy);
if (!user) {
return res.status(404).json({ error: "User not found" });
Expand All @@ -1293,74 +1285,59 @@ const createPost = async (req, res) => {
return res.status(401).json({ error: "Unauthorized to create post" });
}

// Check if user is frozen
if (user.isFrozen) {
return res.status(403).json({ error: "Account is frozen" });
}

let postData = {
postedBy,
text,
img,
targetAudience: "all",
targetYearGroups: [],
targetDepartments: [],
targetAudience: "all" // Default value
reviewStatus: user.role === "student" ? "pending" : "approved"
};

// Role-specific post creation rules
// Role-specific validation and setup
switch (user.role) {
case "student":
// Students posts are always set to 'all'
// Students can only post to all
break;

case "teacher":
// Teachers must specify year groups
if (!targetYearGroups || targetYearGroups.length === 0) {
return res.status(400).json({
error: "Teachers must specify at least one year group to target",
});
if (!targetYearGroups?.length) {
return res.status(400).json({ error: "Teachers must specify year groups" });
}
postData.targetYearGroups = targetYearGroups;
// Set the first year group as the target audience
postData.targetAudience = targetYearGroups[0];
postData.targetAudience = "yearGroups";
break;

case "admin":
// Admins must specify either year groups or departments
if ((!targetYearGroups || targetYearGroups.length === 0) &&
(!targetDepartments || targetDepartments.length === 0)) {
return res.status(400).json({
error: "Admin must specify year groups or departments",
});
if (!targetYearGroups?.length && !targetDepartments?.length) {
return res.status(400).json({ error: "Admin must specify year groups or departments" });
}

postData.targetYearGroups = targetYearGroups || [];
postData.targetDepartments = targetDepartments || [];

// Set target audience based on what's specified
if (targetYearGroups?.length && targetDepartments?.length) {
postData.targetAudience = "all"; // Use "all" when targeting both
} else if (targetYearGroups?.length) {
postData.targetAudience = targetYearGroups[0]; // Use first year group
} else if (targetDepartments?.length) {
postData.targetAudience = targetDepartments[0]; // Use first department
}
postData.targetAudience = targetAudience; // Use the frontend-provided audience type
break;

default:
return res.status(403).json({ error: "Unauthorized role for creating posts" });
}

// Handle image upload if provided
// Handle image upload
if (img) {
const uploadedResponse = await cloudinary.uploader.upload(img);
postData.img = uploadedResponse.secure_url;
}

// Create the post with proper review status
const newPost = new Post({
...postData,
reviewStatus: user.role === "student" ? "pending" : "approved"
});

// Create and save the post
const newPost = new Post(postData);
await newPost.save();

// Only send notifications for non-student posts or approved student posts
// Send notifications for non-student posts or approved student posts
if (user.role !== "student") {
try {
const usersToNotify = await User.find({
Expand All @@ -1369,12 +1346,7 @@ const createPost = async (req, res) => {
});

const notificationPromises = usersToNotify.map(recipient =>
sendNotificationEmail(
recipient.email,
postedBy,
newPost._id,
user.username
)
sendNotificationEmail(recipient.email, postedBy, newPost._id, user.username)
);

await Promise.allSettled(notificationPromises);
Expand Down
2 changes: 1 addition & 1 deletion backend/models/postModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ const postSchema = mongoose.Schema(
"BTEC Art",
"Englich",
"tv",
"media",

],
default: "all",
},
Expand Down
1 change: 0 additions & 1 deletion backend/models/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ const userSchema = mongoose.Schema(
"BTEC Art",
"English",
"tv",
"media",
],
required: function () {
return this.role === "teacher";
Expand Down
62 changes: 30 additions & 32 deletions frontend/src/components/CreatePost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -556,50 +556,47 @@ const CreatePost = () => {
const handleCreatePost = async () => {
setIsLoading(true);
try {
// Base payload without audience info
// Base payload
const payload = {
postedBy: user._id,
text: postText,
targetAudience: "all", // Default value
targetYearGroups: [],
targetDepartments: []
};

// Handle image
// Add image if exists
if (imgUrl) payload.img = imgUrl;

// Student posts (default to all)
if (user.role === "student") {
payload.targetAudience = "all";
payload.targetYearGroups = [];
payload.targetDepartments = [];
}

// Teacher posts
// Handle role-specific targeting
if (user.role === "teacher") {
if (targetYearGroups.length === 0) {
showToast(t("Error"), t("Teachers must specify year groups"), "error");
setIsLoading(false);
return;
}
payload.targetAudience = "yearGroups";
payload.targetYearGroups = targetYearGroups;
payload.targetDepartments = [];
payload.targetAudience = "yearGroups";
}

// Admin posts
if (user.role === "admin") {
if (!targetYearGroups.length && !targetDepartments.length) {
showToast(t("Error"), t("Admins must specify target year groups or departments"), "error");
setIsLoading(false);
return;
}

// Determine audience type
payload.targetAudience =
targetYearGroups.length && targetDepartments.length ? "both" :
targetYearGroups.length ? "yearGroups" :
"departments";

payload.targetYearGroups = targetYearGroups;
payload.targetDepartments = targetDepartments;

// Set target audience based on what's being targeted
if (targetYearGroups.length && targetDepartments.length) {
payload.targetAudience = "all";
} else if (targetYearGroups.length) {
payload.targetAudience = "yearGroups";
} else {
payload.targetAudience = "departments";
}
}

const res = await fetch("/api/posts/create", {
Expand All @@ -610,26 +607,19 @@ const CreatePost = () => {

const data = await res.json();

if (data.error) {
showToast(t("Error"), data.error, "error");
if (!res.ok) {
showToast(t("Error"), data.error || "Failed to create post", "error");
return;
}

// Handle successful post creation
if (user.role === "student") {
setPostStatus('pending');
showToast(
t("Success"),
t("Your post has been submitted for review"),
"success"
);
showToast(t("Success"), t("Your post has been submitted for review"), "success");
} else {
setPostStatus('approved');
showToast(t("Success"), t("Post created successfully"), "success");
setPostText("");
setImgUrl("");
setTargetYearGroups([]);
setTargetDepartments([]);
onClose();
resetForm();
}
} catch (error) {
showToast(t("Error"), error.message, "error");
Expand All @@ -638,6 +628,15 @@ const CreatePost = () => {
}
};

const resetForm = () => {
setPostText("");
setImgUrl("");
setTargetYearGroups([]);
setTargetDepartments([]);
onClose();
};

// Return frozen account button if account is frozen
if (user?.isFrozen) {
return (
<Button
Expand Down Expand Up @@ -784,7 +783,6 @@ const CreatePost = () => {
<option value="BTEC Art">{t("BTEC Art")}</option>
<option value="English">{t("English")}</option>
<option value="tv">{t("tv")}</option>
<option value="media">{t("Pear media")}</option>
</Select>
</>
)}
Expand Down

0 comments on commit aea2d89

Please sign in to comment.