Skip to content
Open

mian #26

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c0d684c
Merge pull request #15 from Lisly25/main
Lisly25 Oct 18, 2024
af7ad89
Made the banner in the background of user profile taller
Lisly25 Oct 18, 2024
91bb438
Merge pull request #16 from Lisly25/main
Lisly25 Oct 18, 2024
8cdf7c8
Removed not null requirement from email addresses for now
Lisly25 Oct 18, 2024
bb0cc75
Merge pull request #19 from Lisly25/main
Lisly25 Oct 18, 2024
16c55cc
Started implementing a page listing users. Currently working on: pagi…
Lisly25 Oct 18, 2024
2f9dd60
Pagination for users list is working - to be done still: search funct…
Lisly25 Oct 21, 2024
e88b31f
Added search box for users - does not do anything yet
Lisly25 Oct 21, 2024
838f120
Merge pull request #23 from Lisly25/main
Lisly25 Oct 21, 2024
ba39cf7
User list is now fetched from the backend (picture display is not wor…
Lisly25 Oct 21, 2024
f9978e1
Feat: added dynamic button for shuffle
LeonorTu Oct 21, 2024
f63b343
Started connecting frontend to backend: communitty page renders users…
Lisly25 Oct 21, 2024
d7b3c2e
Feat: add like and dislike functions in pokemon profile
LeonorTu Oct 21, 2024
d62db10
Rolled back on the users own profile page to a working version
Lisly25 Oct 21, 2024
eddc930
Merge pull request #24 from Lisly25/frontend_login_and_user_profiles
Lisly25 Oct 21, 2024
887e1c9
Feat: added unlike and undislike functions and styled the buttons for…
LeonorTu Oct 21, 2024
2b5f1d6
Fix: fixed weight and height to two decimal places
LeonorTu Oct 21, 2024
06ca65d
Merge remote-tracking branch 'origin/main' into frontend_like_pokemons
LeonorTu Oct 21, 2024
eb24fdd
Merge branch 'database' into user,-login,-reg-redirect-and-logout-navbar
janrau9 Oct 22, 2024
f9316cc
profile pic saving,holy loader, need to move profile pic to url in se…
janrau9 Oct 22, 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
3 changes: 2 additions & 1 deletion backend/controllers/profileController.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const updateProfile = async (req, res, next) => {
const updateProfilePic = async (req, res, next) => {
try {
const { id } = req.session.user;
const { profile_pic } = req.body;
// const { profile_pic } = req.body;
const profile_pic = req.file.buffer;
const profile = await profileService.updateProfilePic({
id,
profile_pic,
Expand Down
26 changes: 24 additions & 2 deletions backend/controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const userService = require('../services/userService');

const getLikedPokemonsByUserId = async (req, res, next) => {
const getLikedPokemonsByUser = async (req, res, next) => {
try {
const { id } = req.session.user;
const pokemons = await userService.getLikedPokemonsByUserId(id);
Expand All @@ -10,7 +10,7 @@ const getLikedPokemonsByUserId = async (req, res, next) => {
}
}

const getDislikedPokemonsByUserId = async (req, res, next) => {
const getDislikedPokemonsByUser = async (req, res, next) => {
try {
const { id } = req.session.user;
const pokemons = await userService.getDislikedPokemonsByUserId(id);
Expand All @@ -20,6 +20,26 @@ const getDislikedPokemonsByUserId = async (req, res, next) => {
}
}

const getLikedPokemonsByUserId = async (req, res, next) => {
try {
const { user_id } = req.params
const pokemons = await userService.getLikedPokemonsByUserId(user_id);
res.status(200).json(pokemons);
} catch (error) {
next(error);
}
}

const getDislikedPokemonsByUserId = async (req, res, next) => {
try {
const { user_id } = req.params;
const pokemons = await userService.getDislikedPokemonsByUserId(user_id);
res.status(200).json(pokemons);
} catch (error) {
next(error);
}
}

const searchUsers = async (req, res, next) => {
try {
const { username } = req.query;
Expand All @@ -31,6 +51,8 @@ const searchUsers = async (req, res, next) => {
}

module.exports = {
getLikedPokemonsByUser,
getDislikedPokemonsByUser,
getLikedPokemonsByUserId,
getDislikedPokemonsByUserId,
searchUsers,
Expand Down
2 changes: 1 addition & 1 deletion backend/database/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CREATE TYPE relationship_type AS ENUM ('like', 'dislike');
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE,
password VARCHAR(100) NOT NULL, -- Encrypted password
role VARCHAR(20) DEFAULT 'user', -- 'guest', 'user', 'admin'
created_at TIMESTAMP DEFAULT NOW(),
Expand Down
30 changes: 9 additions & 21 deletions backend/models/pokemonModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ const insertLikedPokemon = async (user_id, pokemon_id) => {
INSERT INTO user_pokemons (pokemon_id, user_id, relationship)
VALUES ($1, $2, 'like')
ON CONFLICT (pokemon_id, user_id)
DO UPDATE SET
relationship = CASE
WHEN user_pokemons.relationship = 'dislike' THEN 'like'
ELSE user_pokemons.relationship
DO UPDATE SET
relationship = CASE
WHEN user_pokemons.relationship = 'dislike' THEN 'like'
ELSE user_pokemons.relationship
END
RETURNING user_id, pokemon_id`;

const values = [pokemon_id, user_id];
const result = await db.query(text, values);
return result;
Expand All @@ -36,10 +36,10 @@ const insertDislikedPokemon = async (user_id, pokemon_id) => {
INSERT INTO user_pokemons (pokemon_id, user_id, relationship)
VALUES ($1, $2, 'dislike')
ON CONFLICT (pokemon_id, user_id)
DO UPDATE SET
relationship = CASE
WHEN user_pokemons.relationship = 'like' THEN 'dislike'
ELSE user_pokemons.relationship
DO UPDATE SET
relationship = CASE
WHEN user_pokemons.relationship = 'like' THEN 'dislike'
ELSE user_pokemons.relationship
END
RETURNING user_id, pokemon_id`;
const values = [pokemon_id, user_id];
Expand All @@ -50,9 +50,6 @@ const insertDislikedPokemon = async (user_id, pokemon_id) => {
const likedPokemon = async (user_id, pokemon_id, name) => {
await insertPokemon(pokemon_id, name);
const result = await insertLikedPokemon(user_id, pokemon_id);
/* if (result.rows.length === 0) {
throw new ValidationError("Pokemon already liked");
} */
return result.rows[0];
};

Expand All @@ -61,18 +58,12 @@ const unlikePokemon = async (user_id, pokemon_id) => {
"DELETE FROM user_pokemons WHERE user_id = $1 AND pokemon_id = $2 AND relationship = 'like' RETURNING user_id, pokemon_id";
const values = [user_id, pokemon_id];
const result = await db.query(text, values);
/* if (result.rows.length === 0) {
throw new ValidationError("Pokemon already unliked");
} */
return result.rows[0];
};

const dislikedPokemon = async (user_id, pokemon_id, name) => {
await insertPokemon(pokemon_id, name);
const result = await insertDislikedPokemon(user_id, pokemon_id);
/* if (result.rows.length === 0) {
throw new ValidationError("Pokemon already disliked");
} */
return result.rows[0];
};

Expand All @@ -81,9 +72,6 @@ const undislikePokemon = async (user_id, pokemon_id) => {
"DELETE FROM user_pokemons WHERE user_id = $1 AND pokemon_id = $2 AND relationship = 'dislike' RETURNING user_id, pokemon_id";
const values = [user_id, pokemon_id];
const result = await db.query(text, values);
/* if (result.rows.length === 0) {
throw new ValidationError("Pokemon already undisliked");
} */
return result.rows[0];
};

Expand Down
2 changes: 1 addition & 1 deletion backend/models/profileModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const updateProfile = async (id, name, bio, profile_pic) => {

const updateProfilePic = async (id, profile_pic) => {
const result = await db.query(
"UPDATE profiles SET profile_pic = $1, updated_at = NOW() WHERE _user_id = $2 RETURNING *",
"UPDATE profiles SET profile_pic = $1, updated_at = NOW() WHERE user_id = $2 RETURNING *",
[profile_pic, id]
);
if (result.rows.length === 0) {
Expand Down
2 changes: 1 addition & 1 deletion backend/models/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const getDislikedPokemonsByUserId = async (userId) => {
if (result.rows.length === 0) {
throw new NotFoundError("User not found");
}
return result.rows; // Return the array of disliked Pokémon
return result.rows[0]; // Return the array of disliked Pokémon
}

const searchUsers = async (query) => {
Expand Down
2 changes: 1 addition & 1 deletion backend/routes/profileRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ router.get("/:id", isAuthenticated, profileController.getProfileById);
profileController.createProfile
); */
router.put("/me/update", isAuthenticated, profileController.updateProfile);
router.patch(
router.post(
"/me/update/profile_pic",
upload.single("profile_pic"),
profileController.updateProfilePic
Expand Down
3 changes: 3 additions & 0 deletions backend/routes/userRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ router.get(
isAuthenticated,
userController.getDislikedPokemonsByUserId
);

router.get("/:user_id/liked_pokemons", isAuthenticated, userController.getLikedPokemonsByUserId);
router.get("/:user_id/disliked_pokemons", isAuthenticated, userController.getDislikedPokemonsByUserId);
router.get("/search", isAuthenticated, userController.searchUsers);

module.exports = router;
46 changes: 32 additions & 14 deletions backend/services/profileService.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const userModel = require("../models/profileModel");

const fs = require('fs');
const fs = require("fs");

// Read the default profile picture file
const defaultProfilePic = fs.readFileSync('./database/profile_pic.png');
const defaultProfilePic = fs.readFileSync("./database/profile_pic.png");

// Convert it to a binary format
const defaultProfilePicBinary = Buffer.from(defaultProfilePic);
Expand All @@ -12,8 +12,15 @@ const createProfile = async ({ user_id, name, bio }) => {
try {
console.log("creating profile");
console.log(user_id, name, bio, defaultProfilePicBinary);
const profile = await userModel.createProfile(user_id, name, bio, defaultProfilePicBinary);
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
const profile = await userModel.createProfile(
user_id,
name,
bio,
defaultProfilePicBinary
);
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
console.log("creating profile successful:", profile);
return profile;
Expand All @@ -28,11 +35,12 @@ const updateProfile = async ({ id, name, bio, profile_pic }) => {
console.log("updating profile");
console.log(id, name, bio, profile_pic);
const profile = await userModel.updateProfile(id, name, bio, profile_pic);
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
console.log("updating profile successful:", profile);
return profile;

} catch (error) {
console.log("error updating profile:", error.message);
throw error;
Expand All @@ -44,7 +52,9 @@ const updateProfilePic = async ({ id, profile_pic }) => {
console.log("updating profile pic");
console.log(id, profile_pic);
const profile = await userModel.updateProfilePic(id, profile_pic);
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
console.log("updating profile pic successful:", profile);
return profile;
Expand Down Expand Up @@ -85,7 +95,9 @@ const getProfileById = async (id) => {
console.log("fetching profile");
console.log(id);
const profile = await userModel.getProfileById(id);
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
console.log("fetching profile successful:", profile);
return profile;
Expand All @@ -99,8 +111,12 @@ const getProfiles = async () => {
try {
console.log("fetching profiles");
const profiles = await userModel.getProfiles();
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
profile.profile_pic = base64Image;
profiles.map((profile) => {
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
});
console.log("fetching profiles successful:", profiles);
return profiles;
} catch (error) {
Expand All @@ -113,16 +129,18 @@ const searchProfiles = async (name) => {
try {
console.log("searching profiles");
console.log(name);
const profiles = await userModel.searchProfiles(name);
const base64Image = profile.profile_pic ? profile.profile_pic.toString('base64') : null;
const profile = await userModel.searchProfiles(name);
const base64Image = profile.profile_pic
? profile.profile_pic.toString("base64")
: null;
profile.profile_pic = base64Image;
console.log("searching profiles successful:", profiles);
console.log("searching profiles successful:", profile);
return profiles;
} catch (error) {
console.log("error searching profiles:", error.message);
throw error;
}
}
};

module.exports = {
createProfile,
Expand Down
20 changes: 20 additions & 0 deletions frontend/pokedex_app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/pokedex_app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"proxy": "http://localhost:3000",
"dependencies": {
"@heroicons/react": "^2.1.5",
"holy-loader": "^2.3.8",
"lucide-react": "^0.453.0",
"prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
10 changes: 6 additions & 4 deletions frontend/pokedex_app/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import PrivacyPolicy from "./pages/PrivacyPolicy";
import TermsOfService from "./pages/TermsOfService";
import ErrorBoundary from "./ErrorBoundary";
import { AuthProvider } from "./AuthContext"; // Import AuthProvider
import Community from "./components/Community";

function App() {
return (
<AuthProvider>
<Router>
<Router>
<AuthProvider>
<div id="root">
<Navbar />
<main>
Expand All @@ -35,12 +36,13 @@ function App() {
<Route path="/pokemon/:name" element={<PokemonProfile />} />
<Route path="/privacy-policy" element={<PrivacyPolicy />} />
<Route path="/terms" element={<TermsOfService />} />
<Route path="/Community" element={<Community />} />
</Routes>
</main>
<Footer />
</div>
</Router>
</AuthProvider>
</AuthProvider>
</Router>
);
}

Expand Down
Loading