GIF89a php
Current File : /home/viralhoga/app_viralhoga/src/modules/user/user.controller.js
import Auth from "../../models/auth.model.js";
import Category from "../../models/category.model.js";
import User from "../../models/user.model.js";
import ApiError from "../../utils/ApiErrorHandler.js";
import ApiResponse from "../../utils/ApiRespinseHandler.js";
import AsyncHandler from "../../utils/AsyncHandler.js";
import path from 'path'
import { roleContaints } from "../../validators/constaints.js";
import Content from "../../models/content.model.js";

export const getProfile = AsyncHandler(async (req, res) => {
    const queryObj = {};

    // If ?userId= is passed (admin fetching someone else), use it; else fetch own profile
    if (req.query.userId) {
        queryObj._id = req.query.userId;
    } else {
        queryObj.authId = req.userId;
    }

    const user = await User.findOne(queryObj)
        .populate({
            path: 'authId',
            select: 'mobile email'
        });

    if (!user) {
        throw new ApiError(404, 'User not found');
    }

    res.status(200).json(
        new ApiResponse(200, 'Profile fetched successfully', user)
    );
});

// export const updateProfile = AsyncHandler(async (req, res) => {
//     const { fullName, location } = req.body;
//     const userId = req.userId;

//     const user = await User.findOne({
//         authId: userId
//     });

//     if (!user) {
//         throw new ApiError(401, "Unauthorized user");
//     }

//     const avatar = req.file?.path;

//     if (avatar) {
//         user.avatar = `uploads/${path.basename(avatar)}`;
//     }

//     user.fullName = fullName ?? user.fullName;
//     user.location = location ?? user.location;

//     await user.save();

//     res.status(200).json(
//         new ApiResponse(200, "Profile updated successfully", user)
//     );
// });

export const updateProfile = AsyncHandler(async (req, res) => {
    const { firstName, lastName, location } = req.body;
    const userId = req.userId;

    const user = await User.findOne({
        authId: userId
    });

    if (!user) {
        throw new ApiError(401, "Unauthorized user");
    }

    const avatar = req.file?.path;

    if (avatar) {
        user.avatar = `uploads/${path.basename(avatar)}`;
    }

    user.firstName = firstName ?? user.firstName;
    user.lastName = lastName ?? user.lastName;
    user.location = location ?? user.location;

    await user.save();

    res.status(200).json(
        new ApiResponse(200, "Profile updated successfully", user)
    );
});

export const updateAvatar = AsyncHandler(async (req, res) => {

});

export const getAllUsers = AsyncHandler(async (req, res) => {
    const queryObj = {};
    const reqQuery = req.query.userType
    const roleInUpperCase = reqQuery?.toUpperCase()

    if (req.query.userType) {
        queryObj.role = roleInUpperCase
    }


    const users = await User.find(queryObj)
        .populate({
            path: 'authId',
            select: 'email'
        });

    res.status(200).json(
        new ApiResponse(200, 'Users fetched successfully', users)
    );
});

export const updateUserStatus = AsyncHandler(async (req, res) => {
    const { id } = req.params;
    const { status } = req.body;

    if (!['active', 'inactive'].includes(status)) {
        throw new ApiError(400, 'Invalid status value');
    }

    const user = await User.findByIdAndUpdate(
        id,
        { status },
        { new: true }
    );

    if (!user) {
        throw new ApiError(404, 'User not found');
    }

    res.status(200).json(
        new ApiResponse(200, 'User status updated successfully', user)
    );
});

//==================

// export const artistRegistration = AsyncHandler(async (req, res) => {
//     const {
//         fullName,
//         email,
//         dob,
//         role,
//         experties,
//         socialLinks,
//         termsAndConditions,
//         services,
//         profession,
//         location,
//         about
//     } = req.body;

//     const userId = req.userId;

//     // ==========================
//     // Category Validation
//     // ==========================

//     let categoryIds = req.body.categoryIds;

//     if (!categoryIds) {
//         throw new ApiError(400, "At least one category is required");
//     }

//     // Handle JSON string from form-data
//     if (typeof categoryIds === "string") {
//         try {
//             categoryIds = JSON.parse(categoryIds);
//         } catch (error) {
//             categoryIds = [categoryIds];
//         }
//     }

//     const categoryIdsArray = Array.isArray(categoryIds)
//         ? categoryIds
//         : [categoryIds];

//     if (categoryIdsArray.length === 0) {
//         throw new ApiError(400, "At least one category is required");
//     }

//     const categories = await Category.find({
//         _id: { $in: categoryIdsArray }
//     });

//     if (categories.length !== categoryIdsArray.length) {
//         throw new ApiError(400, "One or more category IDs are invalid");
//     }

//     // ==========================
//     // User Validation
//     // ==========================

//     const user = await User.findOne({
//         authId: userId
//     });

//     if (!user) {
//         throw new ApiError(401, "Unauthorized user");
//     }

//     const auth = await Auth.findById(userId);

//     if (!auth) {
//         throw new ApiError(401, "Auth user not found");
//     }

//     // ==========================
//     // Files
//     // ==========================

//     const avatar = req.files?.avatar?.[0];
//     const aadhaarFront = req.files?.aadhaarFront?.[0];
//     const aadhaarBack = req.files?.aadhaarBack?.[0];
//     const shortVideo = req.files?.shortVideo?.[0];
//     const studioImage = req.files?.studioImage

//     if (!user.aadhaarFront && !aadhaarFront) {
//         throw new ApiError(400, "Aadhaar front image is required");
//     }

//     if (!user.aadhaarBack && !aadhaarBack) {
//         throw new ApiError(400, "Aadhaar back image is required");
//     }

//     if (shortVideo) {
//         user.shortVideo = `uploads/${path.basename(shortVideo.path)}`
//     }

//     if (avatar) {
//         user.avatar = `uploads/${path.basename(avatar.path)}`;
//     }

//     if (aadhaarFront) {
//         user.aadhaarFront = `uploads/${path.basename(aadhaarFront.path)}`;
//     }

//     if (aadhaarBack) {
//         user.aadhaarBack = `uploads/${path.basename(aadhaarBack.path)}`;
//     }

//     if (studioImage) {
//         user.studio = studioImage.map((file) => ({
//             url: `uploads/${path.basename(studioImage.path)}`
//         }))
//     }

//     // ==========================
//     // Role Validation
//     // ==========================

//     const roleInUpperCase = role?.toUpperCase();

//     if (!Object.values(roleContaints).includes(roleInUpperCase)) {
//         throw new ApiError(400, "Invalid role");
//     }

//     // ==========================
//     // Expertise
//     // ==========================

//     let expertiesData = user.experties || [];

//     if (experties) {
//         expertiesData = Array.isArray(experties)
//             ? experties
//             : experties
//                 .split(",")
//                 .map(item => item.trim())
//                 .filter(Boolean);
//     }

//     // ==========================
//     // Social Links
//     // ==========================

//     let parsedSocialLinks = user.socialLinks;

//     if (socialLinks) {
//         try {
//             parsedSocialLinks =
//                 typeof socialLinks === "string"
//                     ? JSON.parse(socialLinks)
//                     : socialLinks;
//         } catch (error) {
//             throw new ApiError(400, "Invalid socialLinks format");
//         }
//     }

//     // ==========================
//     // Update User
//     // ==========================

//     user.categories = categoryIdsArray;
//     user.fullName = fullName ?? user.fullName;
//     user.dob = dob ?? user.dob;
//     user.role = roleInUpperCase ?? user.role;
//     user.experties = expertiesData;
//     user.socialLinks = parsedSocialLinks;
//     user.termsAndConditions =
//         termsAndConditions ?? user.termsAndConditions;
//     user.services = services ?? user.services
//     user.profession = profession ?? user.role;
//     user.location = location ?? user.location,
//     user.about = about ?? user.about

//     // ==========================
//     // Update Auth
//     // ==========================

//     auth.email = email ?? auth.email;

//     await auth.save();
//     await user.save();

//     return res.status(200).json(
//         new ApiResponse(
//             200,
//             "Artist registration completed successfully",
//             user
//         )
//     );
// });

export const artistRegistration = AsyncHandler(async (req, res) => {
    const {
        firstName,
        lastName,
        email,
        dob,
        role,
        experties,
        socialLinks,
        termsAndConditions,
        services,
        profession,
        location,
        about
    } = req.body;

    const userId = req.userId;

    // ==========================
    // Category Validation
    // ==========================

    let categoryIds = req.body.categoryIds;

    if (!categoryIds) {
        throw new ApiError(400, "At least one category is required");
    }

    // Handle JSON string from form-data
    if (typeof categoryIds === "string") {
        try {
            categoryIds = JSON.parse(categoryIds);
        } catch (error) {
            categoryIds = [categoryIds];
        }
    }

    const categoryIdsArray = Array.isArray(categoryIds)
        ? categoryIds
        : [categoryIds];

    if (categoryIdsArray.length === 0) {
        throw new ApiError(400, "At least one category is required");
    }

    const categories = await Category.find({
        _id: { $in: categoryIdsArray }
    });

    if (categories.length !== categoryIdsArray.length) {
        throw new ApiError(400, "One or more category IDs are invalid");
    }

    // ==========================
    // User Validation
    // ==========================

    const user = await User.findOne({
        authId: userId
    });

    if (!user) {
        throw new ApiError(401, "Unauthorized user");
    }

    const auth = await Auth.findById(userId);

    if (!auth) {
        throw new ApiError(401, "Auth user not found");
    }

    // ==========================
    // Files
    // ==========================

    const avatar = req.files?.avatar?.[0];
    const aadhaarFront = req.files?.aadhaarFront?.[0];
    const aadhaarBack = req.files?.aadhaarBack?.[0];
    const shortVideo = req.files?.shortVideo?.[0];
    const studioImage = req.files?.studioImage

    if (!user.aadhaarFront && !aadhaarFront) {
        throw new ApiError(400, "Aadhaar front image is required");
    }

    if (!user.aadhaarBack && !aadhaarBack) {
        throw new ApiError(400, "Aadhaar back image is required");
    }

    if (shortVideo) {
        user.shortVideo = `uploads/${path.basename(shortVideo.path)}`
    }

    if (avatar) {
        user.avatar = `uploads/${path.basename(avatar.path)}`;
    }

    if (aadhaarFront) {
        user.aadhaarFront = `uploads/${path.basename(aadhaarFront.path)}`;
    }

    if (aadhaarBack) {
        user.aadhaarBack = `uploads/${path.basename(aadhaarBack.path)}`;
    }

    if (studioImage) {
        user.studio = studioImage.map((file) => ({
            url: `uploads/${path.basename(studioImage.path)}`
        }))
    }

    // ==========================
    // Role Validation
    // ==========================

    const roleInUpperCase = role?.toUpperCase();

    if (!Object.values(roleContaints).includes(roleInUpperCase)) {
        throw new ApiError(400, "Invalid role");
    }

    // ==========================
    // Expertise
    // ==========================

    let expertiesData = user.experties || [];

    if (experties) {
        expertiesData = Array.isArray(experties)
            ? experties
            : experties
                .split(",")
                .map(item => item.trim())
                .filter(Boolean);
    }

    // ==========================
    // Social Links
    // ==========================

    let parsedSocialLinks = user.socialLinks;

    if (socialLinks) {
        try {
            parsedSocialLinks =
                typeof socialLinks === "string"
                    ? JSON.parse(socialLinks)
                    : socialLinks;
        } catch (error) {
            throw new ApiError(400, "Invalid socialLinks format");
        }
    }

    // ==========================
    // Update User
    // ==========================

    user.categories = categoryIdsArray;
    user.firstName = firstName ?? user.firstName;
    user.lastName = lastName ?? user.lastName;
    user.dob = dob ?? user.dob;
    user.role = roleInUpperCase ?? user.role;
    user.experties = expertiesData;
    user.socialLinks = parsedSocialLinks;
    user.termsAndConditions =
        termsAndConditions ?? user.termsAndConditions;
    user.services = services ?? user.services;
    user.profession = profession ?? user.role;
    user.location = location ?? user.location;
    user.about = about ?? user.about

    // ==========================
    // Update Auth
    // ==========================

    auth.email = email ?? auth.email;

    await auth.save();
    await user.save();

    return res.status(200).json(
        new ApiResponse(
            200,
            "Artist registration completed successfully",
            user
        )
    );
});

export const getAllUsersWithoutAuth = AsyncHandler(async (req, res) => {
    const queryObj = {};
    const reqQuery = req.query.userType
    const roleInUpperCase = reqQuery?.toUpperCase()

    if (req.query.userId) {
        queryObj._id = req.query.userId
    }

    if (req.query.userType) {
        queryObj.role = roleInUpperCase
    }
    if (req.query.categoryId) {
        queryObj.categories = req.query.categoryId
    }
    if (req.query.isVarifiedAsArtist) {
        queryObj.isVarifiedAsArtist = req.query.isVarifiedAsArtist
    }

    // console.log('query', queryObj)


    const users = await User.find(queryObj)
        .populate({
            path: 'authId',
            select: 'email mobile'
        }).lean(); // Use lean for performance and to easily add fields

    // Fetch one content for each user
    const usersWithContent = await Promise.all(users.map(async (user) => {
        const content = await Content.findOne({ contentOf: user._id })
            .select("title images videos youtubeVideos status contentAccessType ")
            .sort({ createdAt: -1 });
        return { ...user, content };
    }));

    res.status(200).json(
        new ApiResponse(200, 'Users fetched successfully', usersWithContent)
    );
});