aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--planetwars-server/src/db/users.rs4
-rw-r--r--planetwars-server/src/lib.rs2
-rw-r--r--planetwars-server/src/routes/bots.rs9
-rw-r--r--planetwars-server/src/routes/users.rs2
-rw-r--r--web/pw-server/src/lib/components/Leaderboard.svelte8
-rw-r--r--web/pw-server/src/lib/components/navbar/UserControls.svelte7
-rw-r--r--web/pw-server/src/routes/users/[user_name].svelte84
7 files changed, 105 insertions, 11 deletions
diff --git a/planetwars-server/src/db/users.rs b/planetwars-server/src/db/users.rs
index 3a74c53..1098204 100644
--- a/planetwars-server/src/db/users.rs
+++ b/planetwars-server/src/db/users.rs
@@ -57,14 +57,14 @@ pub fn create_user(credentials: &Credentials, conn: &PgConnection) -> QueryResul
.get_result::<User>(conn)
}
-pub fn find_user(username: &str, db_conn: &PgConnection) -> QueryResult<User> {
+pub fn find_user_by_name(username: &str, db_conn: &PgConnection) -> QueryResult<User> {
users::table
.filter(users::username.eq(username))
.first::<User>(db_conn)
}
pub fn authenticate_user(credentials: &Credentials, db_conn: &PgConnection) -> Option<User> {
- find_user(credentials.username, db_conn)
+ find_user_by_name(credentials.username, db_conn)
.optional()
.unwrap()
.and_then(|user| {
diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs
index 050048c..ccf7cfc 100644
--- a/planetwars-server/src/lib.rs
+++ b/planetwars-server/src/lib.rs
@@ -119,11 +119,11 @@ pub fn api() -> Router {
.route("/register", post(routes::users::register))
.route("/login", post(routes::users::login))
.route("/users/me", get(routes::users::current_user))
+ .route("/users/:user/bots", get(routes::bots::get_user_bots))
.route(
"/bots",
get(routes::bots::list_bots).post(routes::bots::create_bot),
)
- .route("/bots/my_bots", get(routes::bots::get_my_bots))
.route("/bots/:bot_id", get(routes::bots::get_bot))
.route(
"/bots/:bot_id/upload",
diff --git a/planetwars-server/src/routes/bots.rs b/planetwars-server/src/routes/bots.rs
index fc180d8..896359c 100644
--- a/planetwars-server/src/routes/bots.rs
+++ b/planetwars-server/src/routes/bots.rs
@@ -12,6 +12,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use thiserror;
+use crate::db;
use crate::db::bots::{self, BotVersion};
use crate::db::ratings::{self, RankedBot};
use crate::db::users::User;
@@ -158,11 +159,13 @@ pub async fn get_bot(
})))
}
-pub async fn get_my_bots(
+pub async fn get_user_bots(
conn: DatabaseConnection,
- user: User,
+ Path(user_name): Path<String>,
) -> Result<Json<Vec<Bot>>, StatusCode> {
- bots::find_bots_by_owner(user.id, &conn)
+ let user =
+ db::users::find_user_by_name(&user_name, &conn).map_err(|_| StatusCode::NOT_FOUND)?;
+ db::bots::find_bots_by_owner(user.id, &conn)
.map(Json)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
}
diff --git a/planetwars-server/src/routes/users.rs b/planetwars-server/src/routes/users.rs
index 1989904..faad1d1 100644
--- a/planetwars-server/src/routes/users.rs
+++ b/planetwars-server/src/routes/users.rs
@@ -89,7 +89,7 @@ impl RegistrationParams {
errors.push("password must be at least 8 characters".to_string());
}
- if users::find_user(&self.username, &conn).is_ok() {
+ if users::find_user_by_name(&self.username, &conn).is_ok() {
errors.push("username is already taken".to_string());
}
diff --git a/web/pw-server/src/lib/components/Leaderboard.svelte b/web/pw-server/src/lib/components/Leaderboard.svelte
index 75e4807..8582198 100644
--- a/web/pw-server/src/lib/components/Leaderboard.svelte
+++ b/web/pw-server/src/lib/components/Leaderboard.svelte
@@ -44,7 +44,8 @@
<td class="leaderboard-bot">{entry["bot"]["name"]}</td>
<td class="leaderboard-author">
{#if entry["author"]}
- {entry["author"]["username"]}
+ <!-- TODO: remove duplication -->
+ <a href="/users/{entry["author"]["username"]}">{entry["author"]["username"]}</a>
{/if}
</td>
</tr>
@@ -69,4 +70,9 @@
.leaderboard-rank {
color: #333;
}
+
+ .leaderboard-author a{
+ text-decoration: none;
+ color: black;
+ }
</style>
diff --git a/web/pw-server/src/lib/components/navbar/UserControls.svelte b/web/pw-server/src/lib/components/navbar/UserControls.svelte
index 0b8413d..a9bd87b 100644
--- a/web/pw-server/src/lib/components/navbar/UserControls.svelte
+++ b/web/pw-server/src/lib/components/navbar/UserControls.svelte
@@ -36,9 +36,9 @@
<div class="user-controls">
{#if $currentUser}
- <div class="current-user-name">
- {$currentUser["username"]}
- </div>
+ <a class="current-user-name" href="/users/{$currentUser["username"]}">
+ {$currentUser["username"]}
+ </a>
<div class="sign-out" on:click={signOut}>Sign out</div>
{:else}
<a class="account-href" href="login">Sign in</a>
@@ -61,6 +61,7 @@
.current-user-name {
@include navbar-item;
+ text-decoration: none;
color: #fff;
}
diff --git a/web/pw-server/src/routes/users/[user_name].svelte b/web/pw-server/src/routes/users/[user_name].svelte
new file mode 100644
index 0000000..fab3a96
--- /dev/null
+++ b/web/pw-server/src/routes/users/[user_name].svelte
@@ -0,0 +1,84 @@
+<script lang="ts" context="module">
+ function fetchJson(url: string): Promise<Response> {
+ return fetch(url, {
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ }
+
+ export async function load({ params, fetch }) {
+ const userName = params["user_name"];
+ const userBotsResponse = await fetch(`/api/users/${userName}/bots`);
+ return {
+ props: {
+ userName,
+ bots: await userBotsResponse.json(),
+ },
+ };
+
+ // return {
+ // status: matchDataResponse.status,
+ // error: new Error("failed to load match"),
+ // };
+ }
+</script>
+
+<script lang="ts">
+ export let userName: string;
+ export let bots: object[];
+</script>
+
+<div class="container">
+ <div class="header">
+ <h1 class="user-name">{userName}</h1>
+ </div>
+ <h2>Bots</h2>
+ <ul class="bot-list">
+ {#each bots as bot}
+ <li class="bot">
+ <span class="bot-name">{bot['name']}</span>
+ </li>
+ {/each}
+ </ul>
+</div>
+
+<style lang="scss">
+ .container {
+ min-width: 600px;
+ max-width: 800px;
+ margin: 50px auto;
+ }
+
+ .header {
+ margin-bottom: 60px;
+ border-bottom: 1px solid black;
+ }
+
+ .user-name {
+ margin-bottom: .5em;
+ }
+
+ .bot-list {
+ list-style: none;
+ padding: 0;
+ }
+
+ $border-color: #d0d7de;
+
+ .bot {
+ display: block;
+ padding: 24px 0;
+ border-bottom: 1px solid $border-color;
+ }
+
+ .bot-name {
+ font-size: 20px;
+ font-weight: 400;
+ }
+
+ .bot:first-child {
+ border-top: 1px solid $border-color;
+ }
+
+</style> \ No newline at end of file