Added searching for all relevant data types
This commit is contained in:
parent
4df0a804b3
commit
a8cf583569
39 changed files with 1159 additions and 233 deletions
|
@ -11,14 +11,10 @@ const promptly = require('promptly');
|
|||
|
||||
const config = require('./config.js').load(process.argv[2]);
|
||||
|
||||
if (config.build === 'debug') {
|
||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
|
||||
}
|
||||
|
||||
console.log(`Running server at '${config.hosts.frontend}'`);
|
||||
|
||||
passport.use(new SteamStrategy({
|
||||
returnURL: `${config.hosts.frontend}/profile/steam`,
|
||||
returnURL: `${config.hosts.frontend}/user/steam`,
|
||||
realm: `${config.hosts.frontend}`,
|
||||
profile: false,
|
||||
}));
|
||||
|
@ -41,8 +37,11 @@ app.get("/users", (req, res) => {
|
|||
app.get("/games", (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/webpage/search_games.html"));
|
||||
});
|
||||
app.get("/profile/:id", (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/webpage/profile.html"));
|
||||
app.get("/achievement/:id", (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/webpage/achievement.html"));
|
||||
});
|
||||
app.get("/user/:id", (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/webpage/user.html"));
|
||||
});
|
||||
app.get("/auth/steam", passport.authenticate('steam'), (req, res) => {});
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<div id="search-achievements-page" class="search page">
|
||||
<div class="page-subsection">
|
||||
<div class="page-header">
|
||||
<p class="page-header-text">Search Achievements</p>
|
||||
<p class="page-header-text">Achievement Search</p>
|
||||
<div class="page-header-separator"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -35,7 +35,7 @@
|
|||
<div id="search-wrapper" class="page-subsection-wrapper">
|
||||
<div id="list-page-search-pair" class="list-page-search page-subsection-chunk">
|
||||
<label id="achievement-search-button" for="achievement-search">Search</label>
|
||||
<input id="achievement-search-field" type="text" placeholder="Name" name="achievement-search"/>
|
||||
<input id="achievement-search-field" type="text" placeholder="Game Name, Achievement Name" name="achievement-search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filter-dropdown-wrapper" class="page-subsection-wrapper">
|
||||
|
@ -46,16 +46,16 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="list-page-filters-flex">
|
||||
<div class="list-page-filter-section page-subsection-wrapper">
|
||||
<div id="personal-filters" class="list-page-filter-section page-subsection-wrapper">
|
||||
<div class="page-subheader">
|
||||
<p class="page-subheader-text">Me</p>
|
||||
<p class="page-subheader-text">Personal</p>
|
||||
<div class="page-subheader-separator"></div>
|
||||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="completed-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Completed</p>
|
||||
<p class="list-page-filter-name">Completed By Me</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,19 +68,19 @@
|
|||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Completion</p>
|
||||
<p class="list-page-filter-label">Min. Completion</p>
|
||||
<input id="min-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Completion</p>
|
||||
<p class="list-page-filter-label">Max. Completion</p>
|
||||
<input id="max-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Difficulty</p>
|
||||
<p class="list-page-filter-label">Min. Difficulty</p>
|
||||
<input id="min-difficulty-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Difficulty</p>
|
||||
<p class="list-page-filter-label">Max. Difficulty</p>
|
||||
<input id="max-difficulty-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -94,11 +94,11 @@
|
|||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Quality</p>
|
||||
<p class="list-page-filter-label">Min. Quality</p>
|
||||
<input id="min-quality-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Quality</p>
|
||||
<p class="list-page-filter-label">Max. Quality</p>
|
||||
<input id="max-quality-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -112,15 +112,15 @@
|
|||
<div class="list-page-list">
|
||||
<div class="list-page-header">
|
||||
<p class="list-page-entry-icon"></p>
|
||||
<p class="list-page-entry-text achievement-game-name">Game</p>
|
||||
<p class="list-page-entry-text achievement-name">Name</p>
|
||||
<p class="list-page-entry-text achievement-completion">Completion Rate</p>
|
||||
<p class="list-page-entry-text achievement-difficulty">Difficulty</p>
|
||||
<p class="list-page-entry-text achievement-quality">Quality</p>
|
||||
<p id="achievement-header-game" class="list-page-entry-text achievement-game-name">Game</p>
|
||||
<p id="achievement-header-name" class="list-page-entry-text achievement-name">Name</p>
|
||||
<p id="achievement-header-completion" class="list-page-entry-text achievement-completion">Completion Rate</p>
|
||||
<p id="achievement-header-difficulty" class="list-page-entry-text achievement-difficulty">Difficulty</p>
|
||||
<p id="achievement-header-quality" class="list-page-entry-text achievement-quality">Quality</p>
|
||||
</div>
|
||||
<template id="achievement-list-template" data-template="achievements-page-list: List<Basic>">
|
||||
<div class="list-page-entry">
|
||||
<img class="list-page-entry-icon lazy-img" data-src="/api/achievement/${achievement_id}/image" alt="Achievement Thumbnail"></img>
|
||||
<div id="achievement-entry-${achievement_id}" class="list-page-entry achievement">
|
||||
<img class="list-page-entry-icon lazy-img" data-src="/api/achievement/${achievement_id}/image" alt="Achievement Icon"></img>
|
||||
<p class="list-page-entry-text achievement-game-name">${game_name}</p>
|
||||
<p class="list-page-entry-text achievement-name">${achievement_name}</p>
|
||||
<p class="list-page-entry-text achievement-completion">${completion}</p>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<div id="search-games-page" class="search page">
|
||||
<div class="page-subsection">
|
||||
<div class="page-header">
|
||||
<p class="page-header-text">Search Games</p>
|
||||
<p class="page-header-text">Game Search</p>
|
||||
<div class="page-header-separator"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,8 +34,8 @@
|
|||
<div id="list-page-search-dropdown">
|
||||
<div id="search-wrapper" class="page-subsection-wrapper">
|
||||
<div id="list-page-search-pair" class="list-page-search page-subsection-chunk">
|
||||
<label for="achievement-search">Search</label>
|
||||
<input id="achievement-search" type="text" placeholder="Name" name="achievement-search"/>
|
||||
<label id="game-search-button" for="game-search">Search</label>
|
||||
<input id="game-search-field" type="text" placeholder="Name" name="game-search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filter-dropdown-wrapper" class="page-subsection-wrapper">
|
||||
|
@ -48,14 +48,14 @@
|
|||
<div id="list-page-filters-flex">
|
||||
<div class="list-page-filter-section page-subsection-wrapper">
|
||||
<div class="page-subheader">
|
||||
<p class="page-subheader-text">Games</p>
|
||||
<p class="page-subheader-text">Me</p>
|
||||
<div class="page-subheader-separator"></div>
|
||||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="games-owned-filter" class="list-page-filter">
|
||||
<div id="owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Games Owned</p>
|
||||
<p class="list-page-filter-name">Owned By Me</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -67,31 +67,39 @@
|
|||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="from-games-owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">My Games</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Avg. Completion</p>
|
||||
<input id="min-avg-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div id="in-progress-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">In Progress</p>
|
||||
</div>
|
||||
<div id="completed-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Completed</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Avg. Completion</p>
|
||||
<input id="max-avg-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-page-filter-section page-subsection-wrapper">
|
||||
<div class="page-subheader">
|
||||
<p class="page-subheader-text">Platforms</p>
|
||||
<p class="page-subheader-text">Users</p>
|
||||
<div class="page-subheader-separator"></div>
|
||||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="games-owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Games Owned</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Num Owners</p>
|
||||
<input id="min-num-owners-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Num Owners</p>
|
||||
<input id="max-num-owners-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Num Perfects</p>
|
||||
<input id="min-num-perfects-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Num Perfects</p>
|
||||
<input id="max-num-perfects-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -103,25 +111,28 @@
|
|||
<div class="page-subsection-chunk">
|
||||
<div class="list-page-list">
|
||||
<div class="list-page-header">
|
||||
<p class="list-page-entry-icon"></p>
|
||||
<p class="list-page-entry-text achievement-name">Name</p>
|
||||
<p class="list-page-entry-text achievement-description">Description</p>
|
||||
<p class="list-page-entry-text achievement-stages">Stages</p>
|
||||
<p class="list-page-entry-icon game"></p>
|
||||
<p class="list-page-entry-text game-name">Game</p>
|
||||
<p class="list-page-entry-text game-achievement-count">Achievement Count</p>
|
||||
<p class="list-page-entry-text game-avg-completion">Avg. Completion</p>
|
||||
<p class="list-page-entry-text game-num-owners">Num Owners</p>
|
||||
<p class="list-page-entry-text game-num-perfects">Num Perfects</p>
|
||||
</div>
|
||||
<template data-template="achievements-page-list: List<Basic>">
|
||||
<template id="game-list-template" data-template="games-page-list: List<Basic>">
|
||||
<div class="list-page-entry">
|
||||
<img class="list-page-entry-icon" src="/static/res/dummy_achievement.png" alt="Achievement Thumbnail"></img>
|
||||
<div class="list-page-entry-text-section">
|
||||
<p class="list-page-entry-text achievement-name">${achievement-name}</p>
|
||||
<p class="list-page-entry-text achievement-description">${achievement-description}</p>
|
||||
<p class="list-page-entry-text achievement-stages">${stages}</p>
|
||||
</div>
|
||||
<img class="list-page-entry-icon lazy-img game" data-src="/api/game/${game_id}/image" alt="Game Thumbnail"></img>
|
||||
<p class="list-page-entry-text game-name">${game_name}</p>
|
||||
<p class="list-page-entry-text game-achievement-count">${achievement_count}</p>
|
||||
<p class="list-page-entry-text game-avg-completion">${avg_completion}</p>
|
||||
<p class="list-page-entry-text game-num-owners">${num_owners}</p>
|
||||
<p class="list-page-entry-text game-num-perfects">${num_perfects}</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img id="loading-results" class="ap-loading" src="/static/res/loading.svg" alt="Loading Symbol" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<div id="search-users-page" class="search page">
|
||||
<div class="page-subsection">
|
||||
<div class="page-header">
|
||||
<p class="page-header-text">Search Users</p>
|
||||
<p class="page-header-text">User Search</p>
|
||||
<div class="page-header-separator"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,8 +34,8 @@
|
|||
<div id="list-page-search-dropdown">
|
||||
<div id="search-wrapper" class="page-subsection-wrapper">
|
||||
<div id="list-page-search-pair" class="list-page-search page-subsection-chunk">
|
||||
<label for="achievement-search">Search</label>
|
||||
<input id="achievement-search" type="text" placeholder="Name" name="achievement-search"/>
|
||||
<label id="user-search-button" for="user-search">Search</label>
|
||||
<input id="user-search-field" type="text" placeholder="Name" name="user-search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filter-dropdown-wrapper" class="page-subsection-wrapper">
|
||||
|
@ -53,45 +53,39 @@
|
|||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="games-owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Games Owned</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Owned</p>
|
||||
<input id="min-owned-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Owned</p>
|
||||
<input id="max-owned-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-page-filter-section page-subsection-wrapper">
|
||||
<div class="page-subheader">
|
||||
<p class="page-subheader-text">General</p>
|
||||
<p class="page-subheader-text">Achievements</p>
|
||||
<div class="page-subheader-separator"></div>
|
||||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="from-games-owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">From My Games</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Completed</p>
|
||||
<input id="min-completed-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div id="completed-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Completed</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Completed</p>
|
||||
<input id="max-completed-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
<div id="completed-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Completed</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Min Avg. Completion</p>
|
||||
<input id="min-avg-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-page-filter-section page-subsection-wrapper">
|
||||
<div class="page-subheader">
|
||||
<p class="page-subheader-text">Platforms</p>
|
||||
<div class="page-subheader-separator"></div>
|
||||
</div>
|
||||
<div class="list-page-filter-chunk page-subsection-chunk">
|
||||
<div class="page-subsection-wrapper">
|
||||
<div id="games-owned-filter" class="list-page-filter">
|
||||
<div class="list-page-filter-checkbox"></div>
|
||||
<p class="list-page-filter-name">Games Owned</p>
|
||||
<div class="list-page-filter">
|
||||
<p class="list-page-filter-label">Max Avg. Completion</p>
|
||||
<input id="max-avg-completion-filter" type="text" class="list-page-filter-param"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,24 +98,27 @@
|
|||
<div class="list-page-list">
|
||||
<div class="list-page-header">
|
||||
<p class="list-page-entry-icon"></p>
|
||||
<p class="list-page-entry-text achievement-name">Name</p>
|
||||
<p class="list-page-entry-text achievement-description">Description</p>
|
||||
<p class="list-page-entry-text achievement-stages">Stages</p>
|
||||
<p class="list-page-entry-text user-username">Username</p>
|
||||
<p class="list-page-entry-text user-game-count">Game Count</p>
|
||||
<p class="list-page-entry-text user-achievement-count">Achievement Count</p>
|
||||
<p class="list-page-entry-text user-avg-completion">Avg. Completion</p>
|
||||
<p class="list-page-entry-text user-perfect-games">Perfect Games</p>
|
||||
</div>
|
||||
<template data-template="achievements-page-list: List<Basic>">
|
||||
<div class="list-page-entry">
|
||||
<img class="list-page-entry-icon" src="/static/res/dummy_achievement.png" alt="Achievement Thumbnail"></img>
|
||||
<div class="list-page-entry-text-section">
|
||||
<p class="list-page-entry-text achievement-name">${achievement-name}</p>
|
||||
<p class="list-page-entry-text achievement-description">${achievement-description}</p>
|
||||
<p class="list-page-entry-text achievement-stages">${stages}</p>
|
||||
</div>
|
||||
<template id="user-list-template" data-template="user-page-list: List<Basic>">
|
||||
<div class="list-page-entry user" data-id="${user_id}">
|
||||
<img class="list-page-entry-icon lazy-img" data-src="/api/user/${user_id}/image" alt="User Image"></img>
|
||||
<p class="list-page-entry-text user-username">${username}</p>
|
||||
<p class="list-page-entry-text user-game-count">${game_count}</p>
|
||||
<p class="list-page-entry-text user-achievement-count">${achievement_count}</p>
|
||||
<p class="list-page-entry-text user-avg-completion">${avg_completion}</p>
|
||||
<p class="list-page-entry-text user-perfect-games">${perfect_games}</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img id="loading-results" class="ap-loading" src="/static/res/loading.svg" alt="Loading Symbol" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -63,7 +63,7 @@ const commonTemplates = async () => {
|
|||
]);
|
||||
} else {
|
||||
template.apply("navbar-section-right").values([
|
||||
{ item: "login", title: "Login" }
|
||||
{ item: "login", title: "Login / Create Account" }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ const connectNavbar = () => {
|
|||
window.location.href = "/login";
|
||||
});
|
||||
} else if (item.dataset.pageName === "profile") {
|
||||
item.addEventListener("click", (clickEvent) => window.location.href = `/profile/${session.id}`);
|
||||
item.addEventListener("click", (clickEvent) => window.location.href = `/user/${session.id}`);
|
||||
} else {
|
||||
item.addEventListener("click", (clickEvent) => window.location.href = `/${item.dataset.pageName}`);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ window.addEventListener("load", async (loadEvent) => {
|
|||
const data = response.data;
|
||||
if (response.status === 201) {
|
||||
session = data;
|
||||
window.location.href = "/";
|
||||
window.location.href = `/user/${session.id}`;
|
||||
} else if (response.status === 500) {
|
||||
raiseError([], "Internal server error :(");
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,10 @@ const saveTemplate = () => {
|
|||
const loadAchievementSearch = () => {
|
||||
const loading = document.querySelector("#loading-results");
|
||||
|
||||
const personal = document.querySelector("#personal-filters");
|
||||
if (!session) {
|
||||
personal.style.display = 'none';
|
||||
}
|
||||
|
||||
const searchButton = document.querySelector("#achievement-search-button");
|
||||
const searchField = document.querySelector("#achievement-search-field" );
|
||||
|
@ -22,23 +26,26 @@ const loadAchievementSearch = () => {
|
|||
const minQuality = document.querySelector("#min-quality-filter" );
|
||||
const maxQuality = document.querySelector("#max-quality-filter" );
|
||||
|
||||
let ordering = 'name';
|
||||
let direction = true;
|
||||
let canSearch = true;
|
||||
const loadList = async () => {
|
||||
if (canSearch) {
|
||||
canSearch = false;
|
||||
|
||||
const body = {
|
||||
searchTerm: searchField.value,
|
||||
userId: completed.classList.contains('active') ? session.id : null,
|
||||
completed: completed.classList.contains('active'),
|
||||
minCompletion: minCompletion.value === '' ? null : Number(minCompletion.value),
|
||||
maxCompletion: maxCompletion.value === '' ? null : Number(maxCompletion.value),
|
||||
minDifficulty: minDifficulty.value === '' ? null : Number(minDifficulty.value),
|
||||
maxDifficulty: maxDifficulty.value === '' ? null : Number(maxDifficulty.value),
|
||||
minQuality: minQuality.value === '' ? null : Number(minQuality.value ),
|
||||
maxQuality: maxQuality.value === '' ? null : Number(maxQuality.value ),
|
||||
searchTerm: searchField.value,
|
||||
userId: completed.classList.contains('selected') ? session.id : null,
|
||||
completed: completed.classList.contains('selected') ? true : null,
|
||||
minCompletion: minCompletion.value === '' ? null : Number(minCompletion.value),
|
||||
maxCompletion: maxCompletion.value === '' ? null : Number(maxCompletion.value),
|
||||
minDifficulty: minDifficulty.value === '' ? null : Number(minDifficulty.value),
|
||||
maxDifficulty: maxDifficulty.value === '' ? null : Number(maxDifficulty.value),
|
||||
minQuality: minQuality.value === '' ? null : Number(minQuality.value ),
|
||||
maxQuality: maxQuality.value === '' ? null : Number(maxQuality.value ),
|
||||
ordering: ordering,
|
||||
orderDirection: direction ? 'ASC' : 'DESC',
|
||||
};
|
||||
console.log(body);
|
||||
let successful = true;
|
||||
if (Number.isNaN(body.minCompletion)) { successful = false; minCompletion.style.backgroundColor = 'var(--error)'; } else { minCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxCompletion)) { successful = false; maxCompletion.style.backgroundColor = 'var(--error)'; } else { maxCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
|
@ -72,9 +79,9 @@ const loadAchievementSearch = () => {
|
|||
achievement_id: item.ID,
|
||||
achievement_name: item.name,
|
||||
game_name: item.game,
|
||||
completion: item.completion == null ? 'N/A' : item.completion + '%',
|
||||
difficulty: item.difficulty == null ? 'N/A' : item.difficulty + ' / 10',
|
||||
quality: item.quality == null ? 'N/A' : item.quality + ' / 10'
|
||||
completion: item.completion == null ? 'N/A' : `${item.completion}%`,
|
||||
difficulty: item.difficulty == null ? 'N/A' : `${item.difficulty} / 10`,
|
||||
quality: item.quality == null ? 'N/A' : `${item.quality} / 10`
|
||||
}))));
|
||||
await template.expand();
|
||||
data.then(data => {
|
||||
|
@ -82,6 +89,25 @@ const loadAchievementSearch = () => {
|
|||
canSearch = true;
|
||||
loadLazyImages();
|
||||
});
|
||||
|
||||
const headers = {
|
||||
game: document.querySelector(".list-page-header > .achievement-game-name" ),
|
||||
name: document.querySelector(".list-page-header > .achievement-name" ),
|
||||
completion: document.querySelector(".list-page-header > .achievement-completion"),
|
||||
difficulty: document.querySelector(".list-page-header > .achievement-difficulty"),
|
||||
quality: document.querySelector(".list-page-header > .achievement-quality" ),
|
||||
}
|
||||
for (const header in headers) {
|
||||
headers[header].addEventListener("click", (clickEvent) => {
|
||||
if (ordering === header) {
|
||||
direction = !direction;
|
||||
} else {
|
||||
ordering = header;
|
||||
direction = true;
|
||||
}
|
||||
loadList();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
135
frontend/webpage/static/scripts/search_games.js
Normal file
135
frontend/webpage/static/scripts/search_games.js
Normal file
|
@ -0,0 +1,135 @@
|
|||
let templateList = null;
|
||||
let templateText = null;
|
||||
const saveTemplate = () => {
|
||||
const templateElement = document.querySelector("#game-list-template");
|
||||
templateList = templateElement.parentElement;
|
||||
templateText = templateElement.outerHTML;
|
||||
templateElement.remove();
|
||||
};
|
||||
|
||||
const loadGameSearch = () => {
|
||||
const loading = document.querySelector("#loading-results");
|
||||
|
||||
const personal = document.querySelector("#personal-filters");
|
||||
if (!session) {
|
||||
personal.style.display = 'none';
|
||||
}
|
||||
|
||||
const searchButton = document.querySelector("#game-search-button");
|
||||
const searchField = document.querySelector("#game-search-field" );
|
||||
|
||||
const owned = document.querySelector("#owned-filter" );
|
||||
const minAvgCompletion = document.querySelector("#min-avg-completion-filter");
|
||||
const maxAvgCompletion = document.querySelector("#max-avg-completion-filter");
|
||||
const minNumOwners = document.querySelector("#min-num-owners-filter" );
|
||||
const maxNumOwners = document.querySelector("#max-num-owners-filter" );
|
||||
const minNumPerfects = document.querySelector("#min-num-perfects-filter" );
|
||||
const maxNumPerfects = document.querySelector("#max-num-perfects-filter" );
|
||||
|
||||
let ordering = 'name';
|
||||
let direction = true;
|
||||
let canSearch = true;
|
||||
const loadList = async () => {
|
||||
if (canSearch) {
|
||||
canSearch = false;
|
||||
|
||||
const body = {
|
||||
searchTerm: searchField.value,
|
||||
userId: owned.classList.contains('selected') ? session.id : null,
|
||||
owned: owned.classList.contains('selected') ? true : null,
|
||||
minAvgCompletion: minAvgCompletion.value === '' ? null : Number(minAvgCompletion.value),
|
||||
maxAvgCompletion: maxAvgCompletion.value === '' ? null : Number(maxAvgCompletion.value),
|
||||
minNumOwners: minNumOwners.value === '' ? null : Number(minNumOwners.value ),
|
||||
maxNumOwners: maxNumOwners.value === '' ? null : Number(maxNumOwners.value ),
|
||||
minNumPerfects: minNumPerfects.value === '' ? null : Number(minNumPerfects.value ),
|
||||
maxNumPerfects: maxNumPerfects.value === '' ? null : Number(maxNumPerfects.value ),
|
||||
ordering: ordering,
|
||||
orderDirection: direction ? 'ASC' : 'DESC',
|
||||
};
|
||||
let successful = true;
|
||||
if (Number.isNaN(body.minAvgCompletion)) { successful = false; minAvgCompletion.style.backgroundColor = 'var(--error)'; } else { minAvgCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxAvgCompletion)) { successful = false; maxAvgCompletion.style.backgroundColor = 'var(--error)'; } else { maxAvgCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.minNumOwners)) { successful = false; minNumOwners.style.backgroundColor = 'var(--error)'; } else { minNumOwners.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxNumOwners)) { successful = false; maxNumOwners.style.backgroundColor = 'var(--error)'; } else { maxNumOwners.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.minNumPerfects)) { successful = false; minNumPerfects.style.backgroundColor = 'var(--error)'; } else { minNumPerfects.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxNumPerfects)) { successful = false; maxNumPerfects.style.backgroundColor = 'var(--error)'; } else { maxNumPerfects.style.backgroundColor = 'var(--foreground)'; }
|
||||
|
||||
if (!successful) {
|
||||
canSearch = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of templateList.querySelectorAll(".list-page-entry")) {
|
||||
entry.remove();
|
||||
}
|
||||
templateList.innerHTML += templateText;
|
||||
loading.style.display = 'block';
|
||||
|
||||
const data = fetch("/api/games", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
})
|
||||
.then(response => response.json())
|
||||
|
||||
template.clear();
|
||||
template.apply('games-page-list').promise(data.then(data => data.map(item => ({
|
||||
game_id: item.ID,
|
||||
game_name: item.name,
|
||||
achievement_count: item.achievement_count,
|
||||
avg_completion: item.avg_completion == null ? 'N/A' : `${item.avg_completion}%`,
|
||||
num_owners: item.num_owners,
|
||||
num_perfects: item.num_perfects,
|
||||
}))));
|
||||
await template.expand();
|
||||
data.then(data => {
|
||||
console.log(data);
|
||||
loading.style.display = 'none';
|
||||
canSearch = true;
|
||||
loadLazyImages();
|
||||
});
|
||||
|
||||
const headers = {
|
||||
game: document.querySelector(".list-page-header > .game-name" ),
|
||||
achievement_count: document.querySelector(".list-page-header > .game-achievement-count"),
|
||||
avg_completion: document.querySelector(".list-page-header > .game-avg-completion" ),
|
||||
num_owners: document.querySelector(".list-page-header > .game-num-owners" ),
|
||||
num_perfects: document.querySelector(".list-page-header > .game-num-perfects" ),
|
||||
}
|
||||
for (const header in headers) {
|
||||
headers[header].addEventListener("click", (clickEvent) => {
|
||||
if (ordering === header) {
|
||||
direction = !direction;
|
||||
} else {
|
||||
ordering = header;
|
||||
direction = true;
|
||||
}
|
||||
loadList();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
searchButton.addEventListener("click", loadList);
|
||||
searchField.addEventListener("keydown", (keyEvent) => {
|
||||
if (keyEvent.key === 'Enter') {
|
||||
loadList();
|
||||
}
|
||||
});
|
||||
|
||||
loadList();
|
||||
};
|
||||
|
||||
window.addEventListener("load", async (loadEvent) => {
|
||||
await loadCommonSearch();
|
||||
|
||||
saveTemplate();
|
||||
await template.expand();
|
||||
|
||||
connectNavbar();
|
||||
loadFilters();
|
||||
|
||||
await loadGameSearch();
|
||||
});
|
132
frontend/webpage/static/scripts/search_users.js
Normal file
132
frontend/webpage/static/scripts/search_users.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
let templateList = null;
|
||||
let templateText = null;
|
||||
const saveTemplate = () => {
|
||||
const templateElement = document.querySelector("#user-list-template");
|
||||
templateList = templateElement.parentElement;
|
||||
templateText = templateElement.outerHTML;
|
||||
templateElement.remove();
|
||||
};
|
||||
|
||||
const loadUserSearch = () => {
|
||||
const loading = document.querySelector("#loading-results");
|
||||
|
||||
|
||||
const searchButton = document.querySelector("#user-search-button");
|
||||
const searchField = document.querySelector("#user-search-field" );
|
||||
|
||||
const minOwned = document.querySelector("#min-owned-filter" );
|
||||
const maxOwned = document.querySelector("#max-owned-filter" );
|
||||
const minCompleted = document.querySelector("#min-completed-filter" );
|
||||
const maxCompleted = document.querySelector("#max-completed-filter" );
|
||||
const minAvgCompletion = document.querySelector("#min-avg-completion-filter");
|
||||
const maxAvgCompletion = document.querySelector("#max-avg-completion-filter");
|
||||
|
||||
let ordering = 'name';
|
||||
let direction = true;
|
||||
let canSearch = true;
|
||||
const loadList = async () => {
|
||||
if (canSearch) {
|
||||
canSearch = false;
|
||||
|
||||
const body = {
|
||||
searchTerm: searchField.value,
|
||||
minOwned: minOwned.value === '' ? null : Number(minOwned.value ),
|
||||
maxOwned: maxOwned.value === '' ? null : Number(maxOwned.value ),
|
||||
minCompleted: minCompleted.value === '' ? null : Number(minCompleted.value ),
|
||||
maxCompleted: maxCompleted.value === '' ? null : Number(maxCompleted.value ),
|
||||
minAvgCompletion: minAvgCompletion.value === '' ? null : Number(minAvgCompletion.value),
|
||||
maxAvgCompletion: maxAvgCompletion.value === '' ? null : Number(maxAvgCompletion.value),
|
||||
};
|
||||
let successful = true;
|
||||
if (Number.isNaN(body.minOwned )) { successful = false; minOwned.style.backgroundColor = 'var(--error)'; } else { minOwned.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxOwned )) { successful = false; maxOwned.style.backgroundColor = 'var(--error)'; } else { maxOwned.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.minCompleted )) { successful = false; minCompleted.style.backgroundColor = 'var(--error)'; } else { minCompleted.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxCompleted )) { successful = false; maxCompleted.style.backgroundColor = 'var(--error)'; } else { maxCompleted.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.minAvgCompletion)) { successful = false; minAvgCompletion.style.backgroundColor = 'var(--error)'; } else { minAvgCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
if (Number.isNaN(body.maxAvgCompletion)) { successful = false; maxAvgCompletion.style.backgroundColor = 'var(--error)'; } else { maxAvgCompletion.style.backgroundColor = 'var(--foreground)'; }
|
||||
|
||||
if (!successful) {
|
||||
canSearch = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of templateList.querySelectorAll(".list-page-entry")) {
|
||||
entry.remove();
|
||||
}
|
||||
templateList.innerHTML += templateText;
|
||||
loading.style.display = 'block';
|
||||
|
||||
const data = fetch("/api/users", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
})
|
||||
.then(response => response.json())
|
||||
|
||||
template.clear();
|
||||
template.apply('user-page-list').promise(data.then(data => data.map(item => ({
|
||||
user_id: item.id,
|
||||
username: item.username,
|
||||
game_count: item.game_count,
|
||||
achievement_count: item.achievement_count,
|
||||
avg_completion: item.avg_completion == null ? 'N/A' : `${item.avg_completion}%`,
|
||||
perfect_games: item.perfect_games
|
||||
}))));
|
||||
await template.expand();
|
||||
data.then(data => {
|
||||
loading.style.display = 'none';
|
||||
canSearch = true;
|
||||
loadLazyImages();
|
||||
|
||||
const entries = document.querySelectorAll(".list-page-entry.user");
|
||||
for (const entry of entries) {
|
||||
entry.addEventListener("click", (clickEvent) => {
|
||||
window.location.href = `/user/${entry.dataset.id}`;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const headers = {
|
||||
username: document.querySelector(".list-page-header > .user-username" ),
|
||||
game_count: document.querySelector(".list-page-header > .user-game-count" ),
|
||||
achievement_count: document.querySelector(".list-page-header > .user-achievement-count"),
|
||||
avg_completion: document.querySelector(".list-page-header > .user-avg-completion" ),
|
||||
perfect_games: document.querySelector(".list-page-header > .user-perfect-games" ),
|
||||
}
|
||||
for (const header in headers) {
|
||||
headers[header].addEventListener("click", (clickEvent) => {
|
||||
if (ordering === header) {
|
||||
direction = !direction;
|
||||
} else {
|
||||
ordering = header;
|
||||
direction = true;
|
||||
}
|
||||
loadList();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
searchButton.addEventListener("click", loadList);
|
||||
searchField.addEventListener("keydown", (keyEvent) => {
|
||||
if (keyEvent.key === 'Enter') {
|
||||
loadList();
|
||||
}
|
||||
});
|
||||
|
||||
loadList();
|
||||
};
|
||||
|
||||
window.addEventListener("load", async (loadEvent) => {
|
||||
await loadCommonSearch();
|
||||
|
||||
saveTemplate();
|
||||
await template.expand();
|
||||
|
||||
connectNavbar();
|
||||
loadFilters();
|
||||
|
||||
await loadUserSearch();
|
||||
});
|
|
@ -160,8 +160,11 @@ const loadProfile = () => {
|
|||
document.querySelector("#platform-0"),
|
||||
];
|
||||
|
||||
let allowSteamImport = true;
|
||||
steamButtons[0].addEventListener("click", (clickEvent) => {
|
||||
window.location.href = "/auth/steam";
|
||||
if (allowSteamImport) {
|
||||
window.location.href = "/auth/steam";
|
||||
}
|
||||
});
|
||||
steamButtons[1].addEventListener("click", (clickEvent) => {
|
||||
fetch(`/api/user/${profileId}/platforms/remove`, {
|
||||
|
@ -170,7 +173,10 @@ const loadProfile = () => {
|
|||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ sessionKey: session.key, platformId: 0 })
|
||||
}).then(() => {
|
||||
allowSteamImport = true;
|
||||
});
|
||||
allowSteamImport = false;
|
||||
steamButtons[1].parentElement.classList.remove("connected");
|
||||
});
|
||||
|
|
@ -289,6 +289,9 @@
|
|||
|
||||
color: var(--foreground);
|
||||
font-size: 24px;
|
||||
|
||||
transition-property: background-color;
|
||||
transition-duration: 0.15s;
|
||||
}
|
||||
|
||||
.list-page-entry-icon {
|
||||
|
@ -309,6 +312,8 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.list-page-entry > .list-page-entry-text {
|
||||
|
@ -318,6 +323,17 @@
|
|||
|
||||
.list-page-header > .list-page-entry-text {
|
||||
border-left: 1px solid var(--accent-value0);
|
||||
|
||||
transition-property: background-color;
|
||||
transition-duration: 0.15s;
|
||||
}
|
||||
|
||||
.list-page-header > .list-page-entry-text:hover {
|
||||
background-color: var(--accent-value1);
|
||||
}
|
||||
|
||||
.list-page-header > .list-page-entry-text:active {
|
||||
background-color: var(--accent-value0);
|
||||
}
|
||||
|
||||
#loading-results {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
.list-page-entry.achievement:hover {
|
||||
background-color: var(--background-light);
|
||||
}
|
||||
|
||||
.list-page-entry-text.achievement-game-name { flex-grow: 1.75; }
|
||||
.list-page-entry-text.achievement-name { flex-grow: 2; }
|
||||
.list-page-entry-text.achievement-completion { flex-grow: 1; }
|
||||
|
|
9
frontend/webpage/static/styles/search_games.css
Normal file
9
frontend/webpage/static/styles/search_games.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.list-page-entry-icon.game {
|
||||
width: 137px;
|
||||
}
|
||||
|
||||
.list-page-entry-text.game-name { flex-grow: 2.5; }
|
||||
.list-page-entry-text.game-achievement-count { flex-grow: 1; }
|
||||
.list-page-entry-text.game-avg-completion { flex-grow: 1; }
|
||||
.list-page-entry-text.game-num-owners { flex-grow: 1; }
|
||||
.list-page-entry-text.game-num-perfects { flex-grow: 1; }
|
9
frontend/webpage/static/styles/search_users.css
Normal file
9
frontend/webpage/static/styles/search_users.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.list-page-entry.user:hover {
|
||||
background-color: var(--background-light);
|
||||
}
|
||||
|
||||
.list-page-entry-text.user-username { flex-grow: 1.5; }
|
||||
.list-page-entry-text.user-game-count { flex-grow: 1; }
|
||||
.list-page-entry-text.user-achievement-count { flex-grow: 1; }
|
||||
.list-page-entry-text.user-avg-completion { flex-grow: 1; }
|
||||
.list-page-entry-text.user-perfect-games { flex-grow: 1; }
|
|
@ -1,10 +1,11 @@
|
|||
:root {
|
||||
--background-dark: #111117;
|
||||
--background: #22222A;
|
||||
--background-light: #33333B;
|
||||
--distinction: #44444C;
|
||||
--foreground-disabled: #77777D;
|
||||
--foreground-dark: #AAAAAA;
|
||||
--foreground: #EEEEEE;
|
||||
--distinction: #44444C;
|
||||
|
||||
--accent-hue: 0;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<link rel="stylesheet" href="/static/styles/theme.css" />
|
||||
<link rel="stylesheet" href="/static/styles/common.css" />
|
||||
<link rel="stylesheet" href="/static/styles/profile.css" />
|
||||
<link rel="stylesheet" href="/static/styles/user.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="navbar">
|
||||
|
@ -137,6 +137,6 @@
|
|||
</div>
|
||||
<script src="/static/scripts/template.js"></script>
|
||||
<script src="/static/scripts/common.js"></script>
|
||||
<script src="/static/scripts/profile.js"></script>
|
||||
<script src="/static/scripts/user.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue