1 | import styles from "./Maps.module.css";
|
---|
2 | import "react-tiles-dnd/esm/index.css";
|
---|
3 | import { TilesContainer } from "react-tiles-dnd";
|
---|
4 | import { Link } from "react-router-dom";
|
---|
5 | import card from "../../assets/card-map.png";
|
---|
6 | import star_icon from "../../assets/star_icon.png"; // Unfilled star icon
|
---|
7 | import star_filled_icon from "../../assets/star_filled_icon.png"; // Filled star icon
|
---|
8 | import { useEffect, useState } from "react";
|
---|
9 | import HttpService from "../../scripts/net/HttpService.js";
|
---|
10 | import Logo from "../../components/Logo/Logo.jsx";
|
---|
11 | import Profile from "../../components/Profile/Profile.jsx";
|
---|
12 | import config from "../../scripts/net/netconfig.js";
|
---|
13 | import { useAppContext } from "../../components/AppContext/AppContext.jsx";
|
---|
14 |
|
---|
15 | let loadedTiles = [];
|
---|
16 |
|
---|
17 | const renderTile = ({ data, isDragging, toggleFavorite }) => (
|
---|
18 | <div style={{ padding: "1rem", width: "100%", position: "relative" }}>
|
---|
19 | <Link to={`/Maps/${data.text}/View`} className={styles.linkStyle}>
|
---|
20 | <div
|
---|
21 | className={`${styles.tile} ${isDragging ? styles.dragging : ""}`}
|
---|
22 | style={{ width: "100%", height: "100%" }}
|
---|
23 | >
|
---|
24 | <img src={card} className={styles.imgStyle} alt="Map Thumbnail" />
|
---|
25 | <div style={{ fontFamily: "exo" }}>
|
---|
26 | {data.text} {isDragging ? "DRAGGING" : null}
|
---|
27 | </div>
|
---|
28 | </div>
|
---|
29 | </Link>
|
---|
30 | <div className={styles.favorite} onClick={() => toggleFavorite(data.text, data.isFavorite)}>
|
---|
31 | <img
|
---|
32 | src={data.isFavorite ? star_filled_icon : star_icon}
|
---|
33 | alt="Favorite Icon"
|
---|
34 | style={{ width: "20px", height: "20px" }}
|
---|
35 | />
|
---|
36 | </div>
|
---|
37 | </div>
|
---|
38 | );
|
---|
39 |
|
---|
40 | const tileSize = (tile) => ({
|
---|
41 | colSpan: tile.cols,
|
---|
42 | rowSpan: tile.rows,
|
---|
43 | });
|
---|
44 |
|
---|
45 | export default function BrowseMaps() {
|
---|
46 | const [searchTerm, setSearchTerm] = useState("");
|
---|
47 | const [tiles, setTiles] = useState([]);
|
---|
48 | const { username, isAuthenticated } = useAppContext();
|
---|
49 |
|
---|
50 | useEffect(() => {
|
---|
51 | const loadMaps = async () => {
|
---|
52 | const httpService = new HttpService();
|
---|
53 | let mapTiles = [];
|
---|
54 |
|
---|
55 | if (isAuthenticated) {
|
---|
56 | // :D
|
---|
57 | const favResp = await httpService.get(`${config.favourites.display}?username=${username}`);
|
---|
58 | console.log("RESPONSE FAVORITE MAPS", favResp);
|
---|
59 |
|
---|
60 | const favMapTiles = favResp.map((elem) => ({
|
---|
61 | text: elem.mapName,
|
---|
62 | cols: 1,
|
---|
63 | rows: 1,
|
---|
64 | isFavorite: true,
|
---|
65 | }));
|
---|
66 |
|
---|
67 | // Load all maps
|
---|
68 | const allResp = await httpService.get(config.view_maps.display);
|
---|
69 | console.log("RESPONSE MAPS PUBLIC", allResp);
|
---|
70 |
|
---|
71 | const nonFavMapTiles = allResp
|
---|
72 | .filter((elem) => !favMapTiles.some((fav) => fav.text === elem.mapName))
|
---|
73 | .map((elem) => ({
|
---|
74 | text: elem.mapName,
|
---|
75 | cols: 1,
|
---|
76 | rows: 1,
|
---|
77 | isFavorite: false,
|
---|
78 | }));
|
---|
79 |
|
---|
80 | mapTiles = [...favMapTiles, ...nonFavMapTiles];
|
---|
81 | } else {
|
---|
82 | const allResp = await httpService.get(config.view_maps.display);
|
---|
83 | console.log("RESPONSE MAPS PUBLIC", allResp);
|
---|
84 |
|
---|
85 | mapTiles = allResp.map((elem) => ({
|
---|
86 | text: elem.mapName,
|
---|
87 | cols: 1,
|
---|
88 | rows: 1,
|
---|
89 | isFavorite: false,
|
---|
90 | }));
|
---|
91 | }
|
---|
92 |
|
---|
93 | loadedTiles = [...mapTiles];
|
---|
94 | sortTiles(mapTiles);
|
---|
95 | setTiles(mapTiles);
|
---|
96 | };
|
---|
97 | loadMaps();
|
---|
98 | }, [isAuthenticated, username]);
|
---|
99 |
|
---|
100 | const toggleFavorite = async (tileName, isFavorite) => {
|
---|
101 | const httpService = new HttpService();
|
---|
102 | const url = isFavorite
|
---|
103 | ? `${config.favourites.delete}?username=${username}&mapName=${encodeURIComponent(tileName)}`
|
---|
104 | : `${config.favourites.add}?username=${username}&mapName=${encodeURIComponent(tileName)}`;
|
---|
105 |
|
---|
106 | console.log("Request URL:", url);
|
---|
107 | let response;
|
---|
108 | if (isFavorite) {
|
---|
109 | response = await httpService.delete(url);
|
---|
110 | } else {
|
---|
111 | response = await httpService.post(url);
|
---|
112 | }
|
---|
113 | console.log("Response received:", response);
|
---|
114 |
|
---|
115 | const updatedTiles = tiles.map((tile) =>
|
---|
116 | tile.text === tileName ? { ...tile, isFavorite: !tile.isFavorite } : tile
|
---|
117 | );
|
---|
118 |
|
---|
119 | loadedTiles = [...updatedTiles];
|
---|
120 | sortTiles(updatedTiles);
|
---|
121 | setTiles(updatedTiles);
|
---|
122 | };
|
---|
123 |
|
---|
124 | const handleSearchChange = (e) => {
|
---|
125 | const value = e.target.value.toLowerCase();
|
---|
126 | setSearchTerm(value);
|
---|
127 |
|
---|
128 | const filteredTiles = loadedTiles.filter((tile) =>
|
---|
129 | tile.text.toLowerCase().includes(value)
|
---|
130 | );
|
---|
131 | sortTiles(filteredTiles);
|
---|
132 | setTiles(filteredTiles);
|
---|
133 | };
|
---|
134 |
|
---|
135 | const sortTiles = (tilesToSort) => {
|
---|
136 | tilesToSort.sort((a, b) => {
|
---|
137 | if (a.isFavorite === b.isFavorite) return a.text.localeCompare(b.text);
|
---|
138 | return a.isFavorite ? -1 : 1;
|
---|
139 | });
|
---|
140 | };
|
---|
141 |
|
---|
142 | return (
|
---|
143 | <div className={styles.container}>
|
---|
144 | <h1>Explore Maps</h1>
|
---|
145 | <Logo></Logo>
|
---|
146 | <Profile></Profile>
|
---|
147 | <div className={styles.searchBar}>
|
---|
148 | <input
|
---|
149 | type="text"
|
---|
150 | placeholder="Search for maps..."
|
---|
151 | value={searchTerm}
|
---|
152 | onChange={handleSearchChange}
|
---|
153 | />
|
---|
154 | </div>
|
---|
155 |
|
---|
156 | <TilesContainer
|
---|
157 | data={tiles}
|
---|
158 | renderTile={(props) => renderTile({ ...props, toggleFavorite })}
|
---|
159 | tileSize={tileSize}
|
---|
160 | forceTileWidth={150}
|
---|
161 | forceTileHeight={170}
|
---|
162 | />
|
---|
163 | </div>
|
---|
164 | );
|
---|
165 | }
|
---|