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

Dev #133

Merged
merged 44 commits into from
Feb 5, 2024
Merged

Dev #133

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
77fd29b
continue upload front
cassiopeelaurie Jan 30, 2024
7d78be4
update getUser
FredD27 Jan 30, 2024
ff1949f
route upload by id
cassiopeelaurie Feb 2, 2024
cb3d952
Merge pull request #121 from WildCodeSchool/user_update
Hepsox Feb 3, 2024
a214653
Remove unused route from main.jsx
Hepsox Feb 3, 2024
60159fa
Merge branch 'dev' of github.com:WildCodeSchool/2023-09-JS-BDX-P3-La_…
Hepsox Feb 3, 2024
d1f025a
Refactor profile page and loaders
Hepsox Feb 3, 2024
66663c2
Refactor fetchCvId to use dynamic user id
Hepsox Feb 3, 2024
9eb190b
Add isWorking prop to CardExperience component
Hepsox Feb 3, 2024
6a241b2
Fix dateEnd prop in CardExperience component
Hepsox Feb 3, 2024
0f89a49
Add react-router-dom and navigate to dashboard after successful offer…
Hepsox Feb 3, 2024
d06feae
Add options for "stage" and "alternance" in AddOffer and EditOffer
Hepsox Feb 3, 2024
c65df05
Fix typos in French messages
Hepsox Feb 3, 2024
0f40c6c
Refactor competence switch to display selected competences
Hepsox Feb 3, 2024
1c6414d
Add deleteId method to OfferManager
Hepsox Feb 3, 2024
1a39baf
Add deleteId method to UserManager class
Hepsox Feb 3, 2024
613cc05
Fix button text in Dashboard and Offer pages
Hepsox Feb 3, 2024
62cd5c4
route uploadById + allUpload + create en cours
cassiopeelaurie Feb 3, 2024
e7ec868
Merge pull request #124 from WildCodeSchool/newBugs
FredD27 Feb 4, 2024
2bea3f9
Update CSS styles and class names
Hepsox Feb 4, 2024
a13f4da
Add styling and update profile layout
Hepsox Feb 4, 2024
2c5271c
Add modal component for job application
Hepsox Feb 4, 2024
194587b
add update skills
FredD27 Feb 4, 2024
e93d8a5
Merge pull request #125 from WildCodeSchool/newBugs
FredD27 Feb 4, 2024
95fa8a4
Merge branch 'dev' of github.com:WildCodeSchool/2023-09-JS-BDX-P3-La_…
FredD27 Feb 4, 2024
c9f6ec2
Merge pull request #126 from WildCodeSchool/user_update
Hepsox Feb 4, 2024
1c198d7
Fix user navigation bug in EditUser component
Hepsox Feb 4, 2024
5b5006f
add editprofil button
FredD27 Feb 4, 2024
c560f8e
Add error handling and redirect to profile page if data retrieval fails
Hepsox Feb 4, 2024
290a6a5
modify timeout
FredD27 Feb 4, 2024
f290a11
Merge pull request #127 from WildCodeSchool/newBugs
FredD27 Feb 4, 2024
1e56e05
Merge branch 'dev' of github.com:WildCodeSchool/2023-09-JS-BDX-P3-La_…
FredD27 Feb 4, 2024
55ceb72
Merge pull request #128 from WildCodeSchool/user_update
Hepsox Feb 4, 2024
b50828b
commit
cassiopeelaurie Feb 4, 2024
7043f22
Merge branch 'dev' of github.com:WildCodeSchool/2023-09-JS-BDX-P3-La_…
cassiopeelaurie Feb 4, 2024
1dd8d88
Fix onClick function in UserProfileModel.jsx
Hepsox Feb 4, 2024
9fee972
Merge pull request #129 from WildCodeSchool/final
FredD27 Feb 4, 2024
3dbb311
bug fixed skills
cassiopeelaurie Feb 4, 2024
1a81fa1
Merge pull request #130 from WildCodeSchool/upload_test
Hepsox Feb 4, 2024
bcaad64
uplaod is workingg
cassiopeelaurie Feb 4, 2024
78a9bba
fix url
cassiopeelaurie Feb 4, 2024
bbe334e
Merge pull request #131 from WildCodeSchool/upload_test
Hepsox Feb 4, 2024
db8ee2f
new db update
cassiopeelaurie Feb 4, 2024
1298761
Merge pull request #132 from WildCodeSchool/upload_test
Hepsox Feb 4, 2024
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
442 changes: 177 additions & 265 deletions backend/database/database.sql

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const router = require("./router");
// Mount the API routes under the "/api" endpoint
app.use("/api", router);

app.use(express.static("public"));

/* ************************************************************************* */

// Production-ready setup: What is it for, and when should I enable it?
Expand Down
46 changes: 37 additions & 9 deletions backend/src/controllers/uploadControllers.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
const models = require("../models");

const getList = async (req, res) => {
const getUploadById = async (req, res) => {
try {
const [result] = await models.upload.findAll();
return res.send(result);
const [item] = await models.upload.findId(req.params.id);
if (item[0] != null) {
res.json(item[0]);
} else {
res.sendStatus(404);
}
} catch (err) {
return res.status(400).send({ message: err.message });
res.status(500).send({ message: err.message });
}
};

const create = async (req, res) => {
const getAllUploads = async (req, res) => {
try {
const result = await models.upload.create(req.file);
const [item] = await models.upload.findAll(req.body);
if (item) {
res.json(item);
} else {
res.sendStatus(404);
}
} catch (err) {
res.status(500).send({ message: err.message });
}
};

await models.user.addAvatar(req.user.id, result.id);
return res.status(201).send({ ...req.user, avatar: result });
const createUpload = async (req, res) => {
try {
const { id } = req.params;
const result = await models.upload.create(req.file);
await models.user.updateUser(id, {
upload_url: result.url,
});
return res.status(201).send({ avatar: result });
} catch (err) {
return res.status(400).send({ message: err.message });
}
};

module.exports = { getList, create };
// const updateUpload = async (req, res) => {
// try {
// const [result] = await models.user.findAll();
// return res.send(result);
// } catch (err) {
// return res.status(400).send({ message: err.message });
// }
// };

module.exports = { getUploadById, getAllUploads, createUpload };
35 changes: 33 additions & 2 deletions backend/src/controllers/userControllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ const getUsers = async (_, res) => {
}
};

const setSkills = async (req, res) => {
const id = +req.params.id;

try {
await models.userCompetence.setUserCompetencesList(id, req.body);
res.status(201).send({});
} catch (err) {
console.error(err);
res.status(500).send({ error: err.message });
}
};

const getUserById = async (req, res) => {
const id = +req.params.id;
try {
Expand All @@ -24,6 +36,7 @@ const getUserById = async (req, res) => {
}
const user = result[0];
delete user.password;
user.competences = await models.userCompetence.getUserCompetences(user.id);
return res.send(user);
} catch (error) {
return res.status(422).send({ error: error.message });
Expand All @@ -32,9 +45,9 @@ const getUserById = async (req, res) => {

const postUser = async (req, res) => {
try {
const rows = await models.user.create(req.body);
const { rows } = await models.user.create(req.body);
res.send({
id: rows.insertId,
insertId: rows.insertId,
firstname: req.body.firstname,
lastname: req.body.lastname,
phone: req.body.phone,
Expand Down Expand Up @@ -115,6 +128,23 @@ const postLogin = async (req, res) => {
}
};

// const updateUser = async (req, res) => {
// try {
// const id = parseInt(req.params.id, 10);
// if (!id) {
// res.sendStatus(500);
// }
// const result = await models.user.updateUser(id, req.body);
// if (result.affectedRows.length === 0) {
// res.sendStatus(500);
// }
// res.sendStatus(200);
// } catch (error) {
// console.error(error);
// res.status(422).send({ error: error.message });
// }
// };

const getProfile = async (req, res) => {
delete req.user.password;
req.user.competences = await models.userCompetence.getUserCompetences(
Expand Down Expand Up @@ -231,5 +261,6 @@ module.exports = {
postSkills,
getSkills,
addSkills,
setSkills,
getMatchingOffers,
};
26 changes: 26 additions & 0 deletions backend/src/middlewares/multerMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require("fs");

function renameFile(req, res, next) {
const proxyHost = req.headers["x-forwarded-host"];

const host = proxyHost ?? req.headers.host;

if (req.file && req.file.destination) {
const { originalname, filename } = req.file;
const relativePath = `uploads/${Date.now()}_${originalname}`;
const newPath = `./public/${relativePath}`;
const fullPath = `${req.protocol}://${host}/${relativePath}`;

fs.rename(`./public/uploads/${filename}`, newPath, (err) => {
if (err) {
return;
}
req.newPath = fullPath;
req.relativePath = relativePath;
next();
});
} else {
next(new Error("La destination du fichier est indéfinie."));
}
}
module.exports = { renameFile };
8 changes: 8 additions & 0 deletions backend/src/models/OfferManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ class OfferManager extends AbstractManager {

return result;
}

async deleteId(id) {
await this.database.query(
`DELETE FROM offer_competence WHERE offer_id = ?`,
[id]
);
return this.database.query(`DELETE FROM ${this.table} WHERE id = ?`, [id]);
}
}

module.exports = OfferManager;
15 changes: 12 additions & 3 deletions backend/src/models/UploadManager.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
const fs = require("fs");

const AbstractManager = require("./AbstractManager");

class UploadManager extends AbstractManager {
constructor() {
super({ table: "upload" });
}

// async getUpload(uploadId) {
// const [upload] = await this.database.query(
// `SELECT * FROM ${this.table} WHERE id = ?`,
// [uploadId]
// );
// return upload;
// }

create(data) {
const filename = `${data.path}.${data.originalname.split(".").slice(-1)}`;
let filename = data.destination.replace("public/", "");
filename += `${data.filename}.`;
filename += data.originalname.split(".").slice(-1);

return new Promise((resolve, reject) => {
fs.rename(`${data.path}`, filename, async (err) => {
fs.rename(`${data.path}`, `public/${filename}`, async (err) => {
if (err) {
reject(err);
}
Expand Down
24 changes: 24 additions & 0 deletions backend/src/models/UserCompetenceManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ class UserCompetenceManager extends AbstractManager {
super({ table: "user_competence" });
}

async setUserCompetencesList(userId, body) {
try {
await this.database.query(
`DELETE FROM ${this.table} WHERE user_id = ${userId}`
);

const competences = body.competences ?? [];

let sql = `INSERT INTO ${this.table} (user_id, competence_id) VALUES`;

const sqlValues = [];
competences.forEach((competenceId) => {
sql += `${sqlValues.length > 0 ? "," : ""} (?,?)`;
sqlValues.push(userId);
sqlValues.push(competenceId);
});
const [result] = await this.database.query(sql, sqlValues);
return result;
} catch (e) {
console.error(e);
return null;
}
}

async addUserCompetences(userId, body) {
const uniqValues = new Set(body.competences ?? []);
const [userCompetences] = await this.database.query(
Expand Down
63 changes: 51 additions & 12 deletions backend/src/models/UserManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class UserManager extends AbstractManager {
create(user) {
return UserManager.hashPassword(user.password).then(async (hash) => {
const [rows] = await this.database.query(
`INSERT INTO user (firstname, lastname, phone, address, email, password, is_admin) VALUES (?, ?, ?, ?, ?, ?, ?)`,
`INSERT INTO user (firstname, lastname, phone, address, email, password, is_admin, upload_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[
user.firstname,
user.lastname,
Expand All @@ -18,6 +18,7 @@ class UserManager extends AbstractManager {
user.email,
hash,
0,
user.upload_url ?? "",
]
);
// const userId = rows.insertId;
Expand All @@ -44,20 +45,12 @@ class UserManager extends AbstractManager {
}

async update(id, user) {
// const { firstname, lastname, phone, email, address } = user;
const { firstname, lastname, phone, email, address } = user;

try {
const [result] = await this.database.query(
`UPDATE ${this.table} SET is_admin = ?, firstname = ?, lastname = ?, phone = ?, email = ?, address = ? WHERE id = ?`,
[
user.is_admin,
user.firstname,
user.lastname,
user.phone,
user.email,
user.address,
id,
]
`UPDATE ${this.table} SET firstname = ?, lastname = ?, phone = ?, email = ?, address = ? WHERE id = ?`,
[firstname, lastname, phone, email, address, id]
);

return result;
Expand All @@ -67,6 +60,45 @@ class UserManager extends AbstractManager {
}
}

// async updateUser(id, user) {
// // const { firstname, lastname, phone, email, address } = user;

// try {
// const [result] = await this.database.query(
// `UPDATE ${this.table} SET is_admin = ?, firstname = ?, lastname = ?, phone = ?, email = ?, address = ?, upload_url = ? WHERE id = ?`,
// [
// user.is_admin,
// user.firstname,
// user.lastname,
// user.phone,
// user.email,
// user.address,
// user.upload_url,
// id,
// ]
// );

// return result;
// } catch (err) {
// console.error(err);
// return null;
// }
// }

async updateUser(id, structure) {
let sql = "UPDATE user set";
const sqlValues = [];
for (const [key, value] of Object.entries(structure)) {
sql += `${sqlValues.length ? "," : ""} ${key} = ?`;

sqlValues.push(value);
}
sql += " where id = ?";
sqlValues.push(id);
const [res] = await this.database.query(sql, sqlValues);
return res;
}

async login(user) {
const { email, password } = user;
const [rows] = await this.database.query(
Expand Down Expand Up @@ -98,6 +130,13 @@ class UserManager extends AbstractManager {
static hashPassword(password, workFactor = 5) {
return bcrypt.hash(password, workFactor);
}

async deleteId(id) {
await this.database.query(`DELETE FROM user_competence WHERE user_id = ?`, [
id,
]);
return this.database.query(`DELETE FROM ${this.table} WHERE id = ?`, [id]);
}
}

module.exports = UserManager;
2 changes: 1 addition & 1 deletion backend/src/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ models.offer.setDatabase(pool);
models.experience.setDatabase(pool);
models.course.setDatabase(pool);
models.cv.setDatabase(pool);
models.upload.setDatabase(pool);
models.userCompetence.setDatabase(pool);
models.offerCompetence.setDatabase(pool);
models.competence.setDatabase(pool);
models.upload.setDatabase(pool);
// bonus: use a proxy to personalize error message,
// when asking for a non existing model
const handler = {
Expand Down
14 changes: 10 additions & 4 deletions backend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ router.post(
authMiddleware,
userControllers.addSkills
);
router.post("/users/:id([0-9]+)/set/skills", userControllers.setSkills);
router.get(
"/users/me/get-matching-offers",
authMiddleware,
Expand All @@ -46,7 +47,6 @@ router.put(
);

// FOR ADMIN. */
router.get("/users/:id([0-9]+)", authMiddleware, userControllers.getUserById);
router.delete(
"/admin/users/:id([0-9]+)",
authMiddleware,
Expand Down Expand Up @@ -169,15 +169,21 @@ router.delete(
authMiddleware,
courseControllers.deleteCourseById
);

// UPLOADS
router.get("/uploads", authMiddleware, uploadController.getList);
router.get("/upload/:id", authMiddleware, uploadController.getUploadById);

router.get("/uploads", uploadController.getAllUploads);

router.post(
"/uploads",
"/uploads/:id",
authMiddleware,
upload.single("avatar"),
uploadController.create
uploadController.createUpload
);

// router.put("/uploads", authMiddleware, uploadController.updateUpload);

/* CV. */
router.post("/cvs", authMiddleware, cvControllers.postCv);

Expand Down
Loading
Loading