Add full project files

This commit is contained in:
root
2026-07-04 19:24:56 +03:30
parent d54f5441a3
commit b245e7b71a
835 changed files with 30149 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
/* eslint-disable camelcase */
const PostModel = require('../../../models/PostModel');
const jwt = require('jsonwebtoken');
const UserModel = require('../../../models/UserModel');
const LikeModel = require('../../../models/LikeModel');
const toggleLike = async (req, res, next) => {
try {
const { postId } = req.body;
const token = req.header('Authorization')?.split(' ')[1];
if (!token) {
return res.status(401).json({ message: 'توکن ارائه نشده است' });
}
let userId;
try {
const decodedToken = jwt.verify(token, process.env.APP_SECRET);
userId = decodedToken.id;
} catch (err) {
return res.status(401).json({ message: 'توکن نامعتبر است' });
}
if (!postId) {
return res.status(400).json({ message: 'شناسه پست الزامی است' });
}
const post = await PostModel.findById(postId);
if (!post) {
return res.status(404).json({ message: 'پست مورد نظر یافت نشد' });
}
const isLiked = post.likes.includes(userId);
if (isLiked) {
// unlike
post.likes.pull(userId);
await post.save();
await LikeModel.findOneAndDelete({ postId, userId });
return res.status(200).json({
message: 'لایک با موفقیت حذف شد',
is_liked: false,
likesCount: post.likes.length,
});
} else {
// like
post.likes.push(userId);
await post.save();
await LikeModel.create({ postId, userId });
return res.status(200).json({
message: 'پست با موفقیت لایک شد',
is_liked: true,
likesCount: post.likes.length,
});
}
} catch (error) {
console.error('خطا در toggleLike:', error);
res.status(500).json({ message: 'خطا در سرور' });
next(error);
}
};
module.exports = { toggleLike };

View File

@@ -0,0 +1,182 @@
/* eslint-disable camelcase */
const PostModel = require('../../../models/PostModel');
const UserModel = require('../../../models/UserModel');
const { check, validationResult } = require('express-validator');
const jwt = require('jsonwebtoken');
const path = require('path');
const { default: mongoose } = require('mongoose');
const createPostValidationRules = () => {
console.log(4);
return [
check('caption')
.notEmpty().withMessage('توضیحات نمی‌تواند خالی باشد'),
];
};
const createPost = async (req, res) => {
try {
console.log('DEBUG: createPost called');
console.log('DEBUG: req.files:', req.files);
console.log('DEBUG: req.body:', req.body);
const { caption } = req.body;
const files = req.files || [];
const userId = req.user.id; // از میدل‌ویر auth
if (!files || files.length === 0) {
console.log('DEBUG: No files provided');
return res.status(400).json({ error: true, message: 'هیچ فایلی آپلود نشده است' });
}
if (!caption) {
console.log('DEBUG: No caption provided');
return res.status(400).json({ error: true, message: 'کپشن الزامی است' });
}
const filePaths = files.map((file) => ({
path: file.path,
type: file.mimetype.startsWith('video/') ? 'video' : 'image',
}));
console.log('DEBUG: Saving post to MongoDB, filePaths:', filePaths);
const post = new PostModel({
user_id: userId,
caption,
files: filePaths,
type: files[0].mimetype.startsWith('video/') ? 'video' : 'image', // اضافه کردن فیلد type
createdAt: new Date(),
});
await post.save();
console.log('DEBUG: Post saved:', post._id);
res.status(201).json({ message: 'پست با موفقیت ایجاد شد', postId: post._id });
} catch (err) {
console.error('DEBUG: createPost error:', err.message);
res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` });
}
};
const getUserPosts = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const user_id = req.query.user_id
// eslint-disable-next-line no-unused-vars
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userReqId = decodedToken.id
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const response = {}
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
if (user_id.toString() === userReqId.toString()) {
// کاربر خودش است، همه پست‌هایش را بررسی می‌کند
const posts = await PostModel.paginate(
{ user_id: user._id, status: { $in: ['pending', 'accept'] } }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.posts = posts.docs
response.postsCount = posts.totalDocs
response.totalPages = posts.totalPages // ارسال تعداد کل صفحات
response.totalItems = posts.totalDocs
} else {
// دیگران، فقط پست‌هایی که وضعیتشان "accept" است را ببینند
const posts = await PostModel.paginate(
{ user_id: user._id, status: 'accept' }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.posts = posts.docs
response.postsCount = posts.totalDocs
response.totalPages = posts.totalPages // ارسال تعداد کل صفحات
response.totalItems = posts.totalDocs
}
return res.status(200).json({ data: response })
} catch (error) {
next(error)
}
}
const getUserPostsWeb = async (req, res, next) => {
try {
let userReqId = null
// دریافت توکن و بررسی معتبر بودنش (اگر وجود داشت)
const authHeader = req.header('Authorization')
if (authHeader) {
const token = authHeader.split(' ')[1]
try {
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
userReqId = decodedToken.id
} catch (err) {
console.warn('توکن نامعتبر است، ادامه بدون احراز هویت') // فقط هشدار، نه ارور
}
}
const user_id = req.query.user_id
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const data = {}
const options = {
page: req.query.page || 1,
limit: req.query.limit || 10,
sort: { createdAt: -1 }
}
if (userReqId && user_id.toString() === userReqId.toString()) {
// اگر کاربر لاگین کرده و درخواست برای خودش است، همه پست‌هایش را ببیند
const posts = await PostModel.paginate(
{ user_id: user._id, status: { $in: ['pending', 'accept'] } },
options
)
data.posts = posts.docs
data.postsCount = posts.totalDocs
data.totalPages = posts.totalPages
data.totalItems = posts.totalDocs
} else {
// برای بقیه، فقط پست‌هایی که وضعیتشان "accept" است نمایش داده شود
const posts = await PostModel.paginate(
{ user_id: user._id, status: 'accept' },
options
)
data.posts = posts.docs
data.postsCount = posts.totalDocs
data.totalPages = posts.totalPages
data.totalItems = posts.totalDocs
}
return res.status(200).json(data)
} catch (error) {
next(error)
}
}
module.exports = {
createPostValidationRules,
createPost,
getUserPosts,
getUserPostsWeb
}