diff options
-rw-r--r-- | planetwars-server/src/db/users.rs | 4 | ||||
-rw-r--r-- | planetwars-server/src/lib.rs | 2 | ||||
-rw-r--r-- | planetwars-server/src/routes/bots.rs | 9 | ||||
-rw-r--r-- | planetwars-server/src/routes/users.rs | 2 | ||||
-rw-r--r-- | web/pw-server/src/lib/components/Leaderboard.svelte | 8 | ||||
-rw-r--r-- | web/pw-server/src/lib/components/navbar/UserControls.svelte | 7 | ||||
-rw-r--r-- | web/pw-server/src/routes/users/[user_name].svelte | 84 |
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 |