Skip to content

Commit

Permalink
Edit Users Model: add avatar, phone, gender, address
Browse files Browse the repository at this point in the history
  • Loading branch information
RobyYasirAmri committed Jun 10, 2024
1 parent 70d4f02 commit 5740115
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 70 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@babel/preset-env": "^7.24.6"
},
"dependencies": {
"@google-cloud/storage": "^7.11.1",
"@google-cloud/storage": "^7.11.2",
"@prisma/client": "^5.14.0",
"@tensorflow/tfjs-node": "^4.19.0",
"axios": "^1.7.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE `Users` ADD COLUMN `address` VARCHAR(191) NULL,
ADD COLUMN `avatar` VARCHAR(191) NULL,
ADD COLUMN `gender` VARCHAR(191) NULL,
ADD COLUMN `phoneNumber` VARCHAR(191) NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Warnings:
- You are about to drop the column `phoneNumber` on the `Users` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE `Users` DROP COLUMN `phoneNumber`,
ADD COLUMN `phone` VARCHAR(191) NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE `Users` ADD COLUMN `address_lat` DOUBLE NULL,
ADD COLUMN `address_lng` DOUBLE NULL;
6 changes: 6 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ model Users {
updated_at DateTime @updatedAt
isVerified Boolean @default(false)
isDeleted Boolean @default(false)
avatar String?
gender String?
address String?
address_lat Float?
address_lng Float?
phone String?
tenants Tenants[]
bookings Booking[]
Expand Down
158 changes: 90 additions & 68 deletions src/controllers/UsersControllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { text } from "express";
import nodemailer from "nodemailer";
const fs = require("fs");
const path = require("path");
// const TokensBlacklistModels = require("../models/Models").tokenblacklist;
import { Storage } from "@google-cloud/storage";
import axios from "axios";

// import { transporter } from "../middlewares/NodeMailerConfig";

env.config();

Expand All @@ -27,6 +27,37 @@ const transporter = nodemailer.createTransport({
pass: process.env.ZOHO_PASSWORD,
},
});

// GOOGLE CLOUD STORAGE TO UPLOAD AVATAR

const storage = new Storage();

const bucketName = process.env.GCS_BUCKET_NAME;

const uploadImageToGCS = async (file, folderName) => {
const bucket = storage.bucket(bucketName);
const fileName = `${folderName}/${crypto.randomBytes(16).toString("hex")}-${file.originalname}`;
const blob = bucket.file(fileName);

return new Promise((resolve, reject) => {
const blobStream = blob.createWriteStream({
resumable: false,
contentType: file.mimetype,
});

blobStream.on("finish", () => {
const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
resolve(publicUrl);
});

blobStream.on("error", (err) => {
reject(err);
});

blobStream.end(file.buffer);
});
};

// CREATE USERS

export const UsersCreate = async (req, res) => {
Expand Down Expand Up @@ -457,6 +488,15 @@ export const UsersRead = async (req, res) => {
take: parseInt(limit),
orderBy: { id: "desc" },
where: filter,
select: {
id: true,
email: true,
username: true,
avatar: true,
phone: true,
gender: true,
address: true,
},
});

const conn = await UsersModels.count();
Expand All @@ -477,13 +517,33 @@ export const UsersRead = async (req, res) => {
}
};

// Fetch location data from Google Maps API

const getFormattedAddress = async (address) => {
const apiKey = process.env.GOOGLE_MAPS_API_KEY;
const response = await axios.get(
`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${apiKey}`
);

if (response.data.status !== 'OK') {
throw new Error('Error fetching address from Google Maps API');
}

const result = response.data.results[0];
return {
formattedAddress: result.formatted_address,
lat: result.geometry.location.lat,
lng: result.geometry.location.lng,
};
};

// USERS UPDATE

export const UsersUpdate = async (req, res) => {
try {
const data = req.body;
const { id } = req.params;

// CHECK UNIQUE ID
const checkUniqueId = await UsersModels.findUnique({
where: {
Expand All @@ -509,6 +569,27 @@ export const UsersUpdate = async (req, res) => {
updatedData.password = hashedPassword;
}

if (req.file) {
const folderName = `avatars/${checkUniqueId.username}`;
const avatarUrl = await uploadImageToGCS(req.file, folderName);
updatedData.avatar = avatarUrl;
}

if (data.phone) {
updatedData.phone = data.phone;
}

if (data.gender) {
updatedData.gender = data.gender;
}

if (data.address) {
const addressData = await getFormattedAddress(data.address);
updatedData.address = addressData.formattedAddress;
updatedData.address_lat = addressData.lat;
updatedData.address_lng = addressData.lng;
}

const result = await UsersModels.update({
where: {
id: parseInt(id),
Expand All @@ -523,6 +604,12 @@ export const UsersUpdate = async (req, res) => {
id: result.id,
email: result.email,
username: result.username,
avatar: result.avatar,
phone: result.phone,
gender: result.gender,
address: result.address,
address_lat: result.address_lat,
address_lng: result.address_lng,
},
});
} catch (error) {
Expand Down Expand Up @@ -605,71 +692,6 @@ export const UsersDelete = async (req, res) => {
}
};

// // USER Authorization

// export const UsersAuth = async (req, res) => {
// try {
// const token = await req.headers.authorization;

// if (!token) {
// res.status(401).json({
// success: "false",
// message: "Login first to get tokens ?",
// });
// return res.status(401).json({
// success: "false",
// message: "Token not found",
// });
// }

// const baerer = await token.split(" ")[1];
// const decToken = await CryptoJS.AES.decrypt(baerer, process.env.API_SECRET).toString(CryptoJS.enc.Utf8);

// const verify = await jwt.verify(decToken, process.env.API_SECRET);

// if (!verify) {
// res.status(401).json({
// success: "false",
// message: "Login first to get tokens ?",
// });
// return res.status(401).json({
// success: "false",
// error: "Error token",
// });
// }

// if (verify.exp < Date.now() / 1000) {
// res.status(401).json({
// success: "false",
// message: "Token expired",
// });
// return res.status(401).json({
// success: "false",
// message: "Token expired",
// });
// }

// const getUserData = await UsersModels.findUnique({
// where: {
// id: parseInt(verify.id),
// },
// });

// const removePass = delete getUserData.password;

// return res.status(200).json({
// success: "true",
// message: "User data",
// query: getUserData,
// });
// } catch (error) {
// res.status(500).json({
// success: "false",
// message: error.message,
// });
// }
// };

// USERS RESET/FORGOT PASSWORD

export const requestPasswordReset = async (req, res) => {
Expand Down
20 changes: 19 additions & 1 deletion src/routes/UsersRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import express from "express";
import { UsersCreate, UsersLogin, UsersLogout, UsersRead, UsersUpdate, UsersDelete, UsersAuth, UsersVerifyEmail, UsersResendVerificationEmail, requestPasswordReset, resetPassword } from "../controllers/UsersControllers";
const CheckBlacklist = require("../middlewares/CheckBlacklist");
const authCheck = require("../middlewares/AuthCheck");
import multer from "multer";


const users_controllers = express.Router();

Expand All @@ -14,13 +16,29 @@ const LimitLogin = rateLimit({
message: "Too much pressing the screen, please wait a little longer up to 15 minutes !!",
});

// Filter file untuk memastikan hanya gambar yang diizinkan
const imageFilter = (req, file, cb) => {
if (!file.mimetype.match(/^image\/(jpeg|png|gif|webp)$/)) {
console.error("Only image files are allowed!");
return cb(new Error("Only image files are allowed!"), false);
}
cb(null, true);
};

// Mengijinkan upload gambar dengan batasan 5MB
const upload = multer({
storage: multer.memoryStorage(),
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
fileFilter: imageFilter,
});

// CREATE USER ROUTES

users_controllers.post("/users/create", UsersCreate);
users_controllers.post("/users/login", LimitLogin, UsersLogin);
//users_controllers.post("/users/logout", authCheck, UsersLogout);
users_controllers.post("/users/read", authCheck, UsersRead);
users_controllers.patch("/users/update/:id", authCheck, CheckBlacklist, UsersUpdate);
users_controllers.patch("/users/update/:id", authCheck, CheckBlacklist, upload.single('avatar'), UsersUpdate);
users_controllers.delete("/users/delete/:id", authCheck, CheckBlacklist, UsersDelete);
// users_controllers.get("/users/auth", UsersAuth);

Expand Down

0 comments on commit 5740115

Please sign in to comment.