diff --git a/Project/backend/java-server/app/src/main/java/org/server/LoginRoutes.java b/Project/backend/java-server/app/src/main/java/org/server/LoginRoutes.java index 7f86020..18c5782 100644 --- a/Project/backend/java-server/app/src/main/java/org/server/LoginRoutes.java +++ b/Project/backend/java-server/app/src/main/java/org/server/LoginRoutes.java @@ -4,8 +4,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ExecutionException; import org.springframework.http.ResponseEntity; @@ -76,23 +74,40 @@ public ResponseEntity login(@RequestBody String code) } } - @PostMapping(path = "/api/v1/matching") - public ResponseEntity> matching(@RequestParam int minAge, @RequestParam int maxAge, @RequestParam String[] ranks, @RequestParam String[] roles) throws IOException { - Matching matcher = new Matching(); - boolean success = matcher.fillMatches(minAge, maxAge, ranks, roles); - if (success) { - List matches = matcher.getMatchList(); - return ResponseEntity.ok(matches); - } else { - return ResponseEntity.ok(new ArrayList<>()); + public class matchUpdate { + private String sessionToken; + private String matchedId; + + public matchUpdate(String sessionToken, String matchedId) { + this.sessionToken = sessionToken; + this.matchedId = matchedId; + } + + public String getMatchedId() { + return matchedId; + } + + public void setMatchedId(String matchedId) { + this.matchedId = matchedId; + } + + public String getSessionToken() { + return sessionToken; + } + + public void setSessionToken(String sessionToken) { + this.sessionToken = sessionToken; } } @PostMapping(path = "/api/v1/update_matches") - public ResponseEntity updateMatches(@RequestParam String userId, @RequestParam String matchedId) { + public ResponseEntity updateMatches(@RequestBody matchUpdate matchUpdate) { OneAndTwoWayMatches oneAndTwoWayMatches = new OneAndTwoWayMatches(); - boolean success = oneAndTwoWayMatches.updateMatches(userId, matchedId); - return ResponseEntity.ok(new ReturnValue(success, "")); + PostgreSQLController pgController = new PostgreSQLController(); + boolean success = + oneAndTwoWayMatches.updateMatches( + pgController.getDiscordId(matchUpdate.getSessionToken()), + pgController.getDiscordIdfromRiot(matchUpdate.getMatchedId())); + return ResponseEntity.ok(success); } - } diff --git a/Project/backend/java-server/app/src/main/java/org/server/Matching.java b/Project/backend/java-server/app/src/main/java/org/server/Matching.java index 632d7ae..a049419 100644 --- a/Project/backend/java-server/app/src/main/java/org/server/Matching.java +++ b/Project/backend/java-server/app/src/main/java/org/server/Matching.java @@ -6,12 +6,12 @@ public class Matching { private List matchList = new ArrayList<>(); + private String sessionToken; public Matching(String sessionToken) { this.sessionToken = sessionToken; } - public void newFillMatchList() { matchList.clear(); PostgreSQLController pgController = new PostgreSQLController(); diff --git a/Project/backend/java-server/app/src/main/java/org/server/MatchingRoutes.java b/Project/backend/java-server/app/src/main/java/org/server/MatchingRoutes.java index f73258f..a8eaed8 100644 --- a/Project/backend/java-server/app/src/main/java/org/server/MatchingRoutes.java +++ b/Project/backend/java-server/app/src/main/java/org/server/MatchingRoutes.java @@ -1,9 +1,7 @@ package org.server; import com.google.gson.JsonObject; -import org.checkerframework.checker.units.qual.A; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -11,6 +9,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.concurrent.ExecutionException; @RestController @@ -60,22 +59,76 @@ public ResponseEntity nextUser(@RequestBody JsonObject token) { PostgreSQLController pgController = new PostgreSQLController(); String sessionToken = token.get("session_token").getAsString(); String discordId = pgController.getDiscordId(sessionToken); - pgController.resetSeen(discordId); if (pgController.hasUserBeenCreated(discordId)) { try { Matching matching = new Matching(sessionToken); matching.newFillMatchList(); List matchList = matching.getMatchList(); if (matchList.isEmpty()) { + pgController.resetSeen(discordId); matching.newFillMatchList(); matchList = matching.getMatchList(); if (matchList.isEmpty()) { return ResponseEntity.ok().build(); } - return ResponseEntity.ok(new UserOutput(matchList.getFirst())); + Random rand = new Random(); + return ResponseEntity.ok(new UserOutput(matchList.get(rand.nextInt(matchList.size())))); } pgController.addUserToSeen(discordId, matchList.getFirst().getPrivateUser().getDiscordId()); - return ResponseEntity.ok(new UserOutput(matchList.getFirst())); + Random rand = new Random(); + return ResponseEntity.ok(new UserOutput(matchList.get(rand.nextInt(matchList.size())))); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } + } + return ResponseEntity.notFound().build(); + } + + public class MatchResponse { + private String name; + private String discordId; + + public MatchResponse(String name, String discordId) { + this.name = name; + this.discordId = discordId; + } + + public String getDiscordId() { + return discordId; + } + + public void setDiscordId(String discordId) { + this.discordId = discordId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + @PostMapping(path = "/api/v1/get_matches") + public ResponseEntity> getMatches(@RequestBody JsonObject token) { + PostgreSQLController pgController = new PostgreSQLController(); + String sessionToken = token.get("session_token").getAsString(); + String discordId = pgController.getDiscordId(sessionToken); + if (pgController.hasUserBeenCreated(discordId)) { + try { + List outputList = pgController.getTwoWayMatched(discordId); + List outputFinal = new ArrayList<>(); + DiscordOps discordOps = new DiscordOps(); + for (String user : outputList) { + outputFinal.add( + new MatchResponse( + pgController.getUser(user).getPublicUser().getFirstName() + + " " + + pgController.getUser(user).getPublicUser().getLastName(), + discordOps.getUsername(user))); + } + return ResponseEntity.ok(outputFinal); } catch (Exception e) { return ResponseEntity.badRequest().build(); } diff --git a/Project/backend/java-server/app/src/main/java/org/server/OneAndTwoWayMatches.java b/Project/backend/java-server/app/src/main/java/org/server/OneAndTwoWayMatches.java index 1fe2df2..0d9b407 100644 --- a/Project/backend/java-server/app/src/main/java/org/server/OneAndTwoWayMatches.java +++ b/Project/backend/java-server/app/src/main/java/org/server/OneAndTwoWayMatches.java @@ -2,24 +2,33 @@ public class OneAndTwoWayMatches { - public boolean updateMatches(String discordId, String matchedId) { - PostgreSQLController pgController = new PostgreSQLController(); - boolean exists = pgController.existsInOneWay(discordId, matchedId); - if (exists) { - boolean deleted = pgController.deleteOneWayMatched(discordId, matchedId); - if (!deleted) { - return false; - } - boolean added_to_two_way = pgController.updateTwoWayMatched(discordId, matchedId); - if (!added_to_two_way) { - return false; - } - } else { - boolean added = pgController.updateOneWayMatched(discordId, matchedId); - if (!added) { - return false; - } + public boolean updateMatches(String discordId, String matchedId) { + PostgreSQLController pgController = new PostgreSQLController(); + boolean exists = pgController.existsInOneWay(matchedId, discordId); + if (pgController.containsTwoWayMatched(discordId, matchedId)) { + return false; + } + boolean wasAddedToTwoWay = false; + if (exists) { + boolean deleted = pgController.deleteOneWayMatched(matchedId, discordId); + if (!deleted) { + return false; + } + boolean added_to_two_way = pgController.updateTwoWayMatched(discordId, matchedId); + if (added_to_two_way) { + wasAddedToTwoWay = true; + } + } else { + boolean existsInOneWay = pgController.existsInOneWay(matchedId, discordId); + if (!existsInOneWay) { + boolean added = pgController.updateOneWayMatched(discordId, matchedId); + if (!added) { + return wasAddedToTwoWay; } - return true; + } else { + return false; + } } + return wasAddedToTwoWay; + } } diff --git a/Project/backend/java-server/app/src/main/java/org/server/PostgreSQLController.java b/Project/backend/java-server/app/src/main/java/org/server/PostgreSQLController.java index 79f6c53..7a3aef3 100644 --- a/Project/backend/java-server/app/src/main/java/org/server/PostgreSQLController.java +++ b/Project/backend/java-server/app/src/main/java/org/server/PostgreSQLController.java @@ -9,10 +9,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.UUID; +import java.util.*; /** * This class is responsible for controlling the PostgreSQL database. It can deal with user data. @@ -368,17 +365,37 @@ public List getUsers() throws SQLException { } public boolean existsInOneWay(String discordId, String matchedId) { - Connection connection = null; + Connection connection = null; try { connection = DriverManager.getConnection(url, props); connection.setAutoCommit(false); - String sql = "SELECT * FROM private WHERE ? = ANY(one_way_matched) AND discord_id = ?"; + String sql = "SELECT * FROM private WHERE ? = ANY(one_way_matched) AND discord_id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { - stmt.setString(1, discordId); - stmt.setString(2, matchedId); + stmt.setString(1, matchedId); + stmt.setString(2, discordId); ResultSet rs = stmt.executeQuery(); if (rs.next()) { return true; + } + connection.commit(); + } catch (SQLException e) { + connection.rollback(); + throw e; + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } + } + return false; + } + public void updateUserPreferences(UserPrefs prefs) { Connection connection = null; try { @@ -408,7 +425,6 @@ public void updateUserPreferences(UserPrefs prefs) { connection.rollback(); throw e; } - } connection.commit(); } catch (SQLException e) { @@ -426,8 +442,6 @@ public void updateUserPreferences(UserPrefs prefs) { System.err.println(e.getMessage()); } } - return false; - } public boolean updateOneWayMatched(String discordId, String matchedId) { @@ -435,7 +449,8 @@ public boolean updateOneWayMatched(String discordId, String matchedId) { try { connection = DriverManager.getConnection(url, props); connection.setAutoCommit(false); - String sql = "UPDATE private SET one_way_matched = one_way_matched || ARRAY[?] WHERE discord_id = ?"; + String sql = + "UPDATE private SET one_way_matched = one_way_matched || ARRAY[?] WHERE discord_id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, matchedId); stmt.setString(2, discordId); @@ -460,15 +475,47 @@ public boolean updateOneWayMatched(String discordId, String matchedId) { return true; } - public boolean deleteOneWayMatched(String discordId, String matchedId) { + public List getTwoWayMatched(String discordId) { Connection connection = null; try { connection = DriverManager.getConnection(url, props); connection.setAutoCommit(false); - String sql = "UPDATE private SET one_way_matched = array_remove(one_way_matched, ?) WHERE discord_id = ?"; + String sql = "SELECT two_way_matched FROM private WHERE discord_id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, discordId); - stmt.setString(2, matchedId); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return Arrays.asList((String[]) rs.getArray("two_way_matched").getArray()); + } + connection.commit(); + } catch (SQLException e) { + connection.rollback(); + throw e; + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } + } + return new ArrayList<>(); + } + + public boolean deleteOneWayMatched(String discordId, String matchedId) { + Connection connection = null; + try { + connection = DriverManager.getConnection(url, props); + connection.setAutoCommit(false); + String sql = + "UPDATE private SET one_way_matched = array_remove(one_way_matched, ?) WHERE discord_id = ?"; + try (PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, matchedId); + stmt.setString(2, discordId); stmt.executeUpdate(); connection.commit(); } catch (SQLException e) { @@ -490,15 +537,80 @@ public boolean deleteOneWayMatched(String discordId, String matchedId) { return true; } + public String getDiscordIdfromRiot(String riotId) { + Connection connection = null; + try { + connection = DriverManager.getConnection(url, props); + connection.setAutoCommit(false); + String sql = "SELECT discord_id FROM public WHERE riot_id = ?"; + try (PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, riotId); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getString("discord_id"); + } + connection.commit(); + } catch (SQLException e) { + connection.rollback(); + throw e; + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } + } + return null; + } + + public boolean containsTwoWayMatched(String target, String match) { + Connection connection = null; + try { + connection = DriverManager.getConnection(url, props); + connection.setAutoCommit(false); + String sql = "SELECT * FROM private WHERE ? = ANY(two_way_matched) AND discord_id = ?"; + try (PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, target); + stmt.setString(2, match); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return true; + } + connection.commit(); + } catch (SQLException e) { + connection.rollback(); + throw e; + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + System.err.println(e.getMessage()); + } + } + return false; + } + public boolean updateTwoWayMatched(String discordId, String matchedId) { Connection connection = null; try { connection = DriverManager.getConnection(url, props); connection.setAutoCommit(false); - String sql1 = "UPDATE private SET two_way_matched = two_way_matched || ARRAY[?] WHERE discord_id = ?"; - String sql2 = "UPDATE private SET two_way_matched = two_way_matched || ARRAY[?] WHERE discord_id = ?"; + String sql1 = + "UPDATE private SET two_way_matched = two_way_matched || ARRAY[?] WHERE discord_id = ?"; + String sql2 = + "UPDATE private SET two_way_matched = two_way_matched || ARRAY[?] WHERE discord_id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql1); - PreparedStatement stmt2 = connection.prepareStatement(sql2)) { + PreparedStatement stmt2 = connection.prepareStatement(sql2)) { stmt.setString(1, matchedId); stmt.setString(2, discordId); stmt2.setString(1, discordId); @@ -523,7 +635,6 @@ public boolean updateTwoWayMatched(String discordId, String matchedId) { } } return true; - } /** diff --git a/Project/frontend/app/matches/components/MatchCard.tsx b/Project/frontend/app/matches/components/MatchCard.tsx new file mode 100644 index 0000000..b4b380b --- /dev/null +++ b/Project/frontend/app/matches/components/MatchCard.tsx @@ -0,0 +1,28 @@ +// app/matches/components/MatchCard.tsx +'use client'; + +import React from 'react'; +import classes from '../matches.module.css'; + +interface MatchCardProps { + match: { + name: string; + discordId: string; + }; + isMutual: boolean; +} + +const MatchCard: React.FC = ({ match, isMutual }) => { + return ( +
+
+

{match.name}

+
+

Discord: {match.discordId}

+
+
+
+ ); +}; + +export default MatchCard; diff --git a/Project/frontend/app/matches/matches.module.css b/Project/frontend/app/matches/matches.module.css new file mode 100644 index 0000000..14d6449 --- /dev/null +++ b/Project/frontend/app/matches/matches.module.css @@ -0,0 +1,141 @@ +/* app/matches/matches.module.css */ +.matchesContainer { + padding: 2rem; + max-width: 1200px; + margin: 0 auto; + background: linear-gradient(to bottom, rgba(73, 141, 224, 0.874), rgba(170, 63, 118, 0.4)); + min-height: calc(100vh - 64px); +} + +.matchesSection { + margin-bottom: 3rem; +} + +.sectionTitle { + color: white; + font-size: 2rem; + margin-bottom: 1.5rem; + border-bottom: 2px solid rgba(255, 255, 255, 0.2); + padding-bottom: 0.5rem; +} + +.matchesGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1.5rem; +} + +.matchCard { + background: white; + border-radius: 12px; + overflow: hidden; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + transition: transform 0.2s ease; +} + +.matchCard:hover { + transform: translateY(-4px); +} + +.mutualMatch { + border: 2px solid #4CAF50; +} + +.oneWayMatch { + border: 2px solid #2196F3; +} + +.matchImageContainer { + position: relative; + width: 100%; + height: 200px; +} + +.matchImage { + width: 100%; + height: 100%; + object-fit: cover; +} + +.mutualBadge { + position: absolute; + top: 10px; + right: 10px; + background: #4CAF50; + color: white; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.875rem; +} + +.matchInfo { + padding: 1rem; +} + +.matchName { + font-size: 1.5rem; + margin: 0 0 0.5rem 0; +} + +.matchAge { + color: #666; + margin: 0 0 0.5rem 0; +} + +.matchRank { + font-weight: bold; + color: #333; + margin: 0 0 0.5rem 0; +} + +.matchRoles { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 0.5rem; +} + +.roleTag { + background: #f0f0f0; + padding: 4px 8px; + border-radius: 4px; + font-size: 0.875rem; +} + +.matchIds { + font-size: 0.875rem; + color: #666; + margin-bottom: 0.5rem; +} + +.matchBio { + font-size: 0.875rem; + color: #444; + line-height: 1.4; +} + +.loading { + text-align: center; + padding: 2rem; + color: white; + font-size: 1.25rem; +} + +.error { + text-align: center; + padding: 2rem; + color: #ff4444; + font-size: 1.25rem; + background: rgba(255, 68, 68, 0.1); + border-radius: 8px; + margin: 2rem; +} + +.noMatches { + text-align: center; + color: white; + font-size: 1.125rem; + padding: 2rem; + background: rgba(255, 255, 255, 0.1); + border-radius: 8px; +} diff --git a/Project/frontend/app/matches/page.tsx b/Project/frontend/app/matches/page.tsx new file mode 100644 index 0000000..400f864 --- /dev/null +++ b/Project/frontend/app/matches/page.tsx @@ -0,0 +1,79 @@ +// app/matches/page.tsx +'use client'; + +import React, { useState, useEffect } from 'react'; +import { HeaderSimple } from '../header'; +import MatchCard from './components/MatchCard'; +import classes from './matches.module.css'; + +interface Match { + name: string; + discordId: string; +} + +const MatchesPage = () => { + const [matches, setMatches] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchMatches = async () => { + try { + const response = await fetch('http://10.195.197.251:8080/api/v1/get_matches', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + session_token: localStorage.getItem('sessionToken') + }) + }); + + if (!response.ok) { + throw new Error('Failed to fetch matches'); + } + + const data = await response.json(); + setMatches(data); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to fetch matches'); + } finally { + setLoading(false); + } + }; + + fetchMatches(); + }, []); + + //const twoWayMatches = matches.filter(match => match.isMutual); + const twoWayMatches = matches + console.log(twoWayMatches); + + if (loading) return
Loading matches...
; + if (error) return
{error}
; + + return ( +
+
+
+

Two-Way Matches

+
+ {twoWayMatches.length > 0 ? ( + twoWayMatches.map((match) => ( + + )) + ) : ( +

No mutual matches yet!

+ )} +
+
+
+
+ ); +}; + +export default MatchesPage; diff --git a/Project/frontend/app/preferences/style.module.css b/Project/frontend/app/preferences/style.module.css index 2746275..ee63abf 100644 --- a/Project/frontend/app/preferences/style.module.css +++ b/Project/frontend/app/preferences/style.module.css @@ -6,7 +6,7 @@ flex-direction: column; align-items: center; justify-content: center; - min-height: 100vh; + height: 100vh; } .homepageTitle { @@ -19,4 +19,4 @@ padding: 20px; Optional: Adds padding inside the section display: flex; flex-direction: column; -justify-content: center; Center content vertically if desired */ \ No newline at end of file +justify-content: center; Center content vertically if desired */ diff --git a/Project/frontend/components/SwipeCard.module.css b/Project/frontend/components/SwipeCard.module.css index 5e8f705..56c9bef 100644 --- a/Project/frontend/components/SwipeCard.module.css +++ b/Project/frontend/components/SwipeCard.module.css @@ -27,7 +27,7 @@ } .swipe-card p { - margin: 15px; + margin: 5px; color: #666; font-size: 16px; line-height: 1.6; diff --git a/Project/frontend/components/SwipeCard.tsx b/Project/frontend/components/SwipeCard.tsx index 307a63e..b605e87 100644 --- a/Project/frontend/components/SwipeCard.tsx +++ b/Project/frontend/components/SwipeCard.tsx @@ -5,7 +5,8 @@ import {Container, Button, Card, Image, Text, Badge, Group} from '@mantine/core' import styles from './SwipeCard.module.css'; interface User { - discord_id: string; + riotId: string, + discordId: string, name: string; pronouns: string[]; bio: string; @@ -16,7 +17,16 @@ interface User { } export default function SwipeCard() { - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); + const [riotId, setRiotId] = useState(null); + const [discordId, setDiscordId] = useState(null); + const [name, setName] = useState(null); + const [pronouns, setPronouns] = useState(null); + const [bio, setBio] = useState(null); + const [roles, setRoles] = useState(null); + const [rank, setRank] = useState(null); + const [image, setImage] = useState(null); + const [age, setAge] = useState(null); const [swipeDirection, setSwipeDirection] = useState(null); const fetchNextUser = () => { @@ -30,6 +40,15 @@ export default function SwipeCard() { .then((res) => res.json()) .then((data) => { setUser(data); + setRiotId(data.riotId); + setDiscordId(data.discordId); + setName(data.name); + setPronouns(data.pronouns); + setBio(data.bio); + setRoles(data.roles); + setRank(data.rank); + setImage(data.image); + setAge(data.age); setSwipeDirection(null); // Reset swipe direction }) .catch((err) => { @@ -41,7 +60,28 @@ export default function SwipeCard() { fetchNextUser(); }, []); + const preferences = () => { + window.location.href = '/preferences'; + } + const handleSwipe = (direction: 'left' | 'right') => { + if (direction == 'right') { + fetch('http://10.195.197.251:8080/api/v1/update_matches', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({sessionToken: localStorage.getItem("sessionToken"), matchedId: riotId}) + }) + .then((res) => res.json()) + .then((data) => { + setUser(data); + setSwipeDirection(null); // Reset swipe direction + }) + .catch((err) => { + console.error(err); + }); + } setSwipeDirection(direction); setTimeout(() => { setUser(null); // Remove the card from the DOM @@ -88,28 +128,31 @@ export default function SwipeCard() { > - {`${user.name}`}/ + {`${name}`}/ - {user.name} - {user.age} + {name} + {age} + {riotId} + {discordId} - - {user.bio} + + {bio} - {user.rank} + {rank} - {user.pronouns.map((pronoun) => ( - - {pronoun} + {console.log(pronouns)} + {pronouns.map((pronouns) => ( + + {pronouns} ))} - {user.roles.map((role) => ( + {roles.map((role) => ( {role} @@ -130,6 +173,11 @@ export default function SwipeCard() { Swipe Right + + ); }