prototype bots pages
This commit is contained in:
parent
c6ca7cf2d1
commit
f5e8b4093a
6 changed files with 127 additions and 3 deletions
|
@ -28,6 +28,12 @@ pub fn find_bot(id: i32, conn: &PgConnection) -> QueryResult<Bot> {
|
||||||
bots::table.find(id).first(conn)
|
bots::table.find(id).first(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_bots_by_owner(owner_id: i32, conn: &PgConnection) -> QueryResult<Vec<Bot>> {
|
||||||
|
bots::table
|
||||||
|
.filter(bots::owner_id.eq(owner_id))
|
||||||
|
.get_results(conn)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable)]
|
||||||
#[table_name = "code_bundles"]
|
#[table_name = "code_bundles"]
|
||||||
pub struct NewCodeBundle<'a> {
|
pub struct NewCodeBundle<'a> {
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub async fn api() -> Router {
|
||||||
.route("/login", post(routes::users::login))
|
.route("/login", post(routes::users::login))
|
||||||
.route("/users/me", get(routes::users::current_user))
|
.route("/users/me", get(routes::users::current_user))
|
||||||
.route("/bots", post(routes::bots::create_bot))
|
.route("/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", get(routes::bots::get_bot))
|
||||||
.route("/bots/:bot_id/upload", post(routes::bots::upload_bot_code))
|
.route("/bots/:bot_id/upload", post(routes::bots::upload_bot_code))
|
||||||
.layer(AddExtensionLayer::new(pool));
|
.layer(AddExtensionLayer::new(pool));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use axum::extract::{Path, RawBody};
|
use axum::extract::{Path, RawBody};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -30,9 +31,19 @@ pub async fn create_bot(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle errors
|
// TODO: handle errors
|
||||||
pub async fn get_bot(conn: DatabaseConnection, Path(bot_id): Path<i32>) -> Json<Bot> {
|
pub async fn get_bot(conn: DatabaseConnection, Path(bot_id): Path<i32>) -> impl IntoResponse {
|
||||||
let bot = bots::find_bot(bot_id, &conn).unwrap();
|
bots::find_bot(bot_id, &conn)
|
||||||
Json(bot)
|
.map(Json)
|
||||||
|
.map_err(|_| StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_my_bots(
|
||||||
|
conn: DatabaseConnection,
|
||||||
|
user: User,
|
||||||
|
) -> Result<Json<Vec<Bot>>, StatusCode> {
|
||||||
|
bots::find_bots_by_owner(user.id, &conn)
|
||||||
|
.map(Json)
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: proper error handling
|
// TODO: proper error handling
|
||||||
|
|
|
@ -19,6 +19,7 @@ where
|
||||||
|
|
||||||
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||||
let conn = DatabaseConnection::from_request(req).await?;
|
let conn = DatabaseConnection::from_request(req).await?;
|
||||||
|
|
||||||
let TypedHeader(Authorization(bearer)) = AuthorizationHeader::from_request(req)
|
let TypedHeader(Authorization(bearer)) = AuthorizationHeader::from_request(req)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| (StatusCode::UNAUTHORIZED, "".to_string()))?;
|
.map_err(|_| (StatusCode::UNAUTHORIZED, "".to_string()))?;
|
||||||
|
|
34
web/pw-server/src/routes/bots/[bot_id].svelte
Normal file
34
web/pw-server/src/routes/bots/[bot_id].svelte
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script lang="ts" context="module">
|
||||||
|
import { get_session_token } from "$lib/auth";
|
||||||
|
|
||||||
|
export async function load({ page }) {
|
||||||
|
const token = get_session_token();
|
||||||
|
const res = await fetch(`/api/bots/${page.params["bot_id"]}`, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
bot: await res.json(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: res.status,
|
||||||
|
error: new Error("Could not load bot"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export let bot: object;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{bot["name"]}
|
||||||
|
</div>
|
71
web/pw-server/src/routes/bots/index.svelte
Normal file
71
web/pw-server/src/routes/bots/index.svelte
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<script lang="ts" context="module">
|
||||||
|
import { get_session_token } from '$lib/auth';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Load} */
|
||||||
|
export async function load({ params, fetch, session, stuff }) {
|
||||||
|
const token = get_session_token();
|
||||||
|
const res = await fetch('/api/bots/my_bots', {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
bots: await res.json()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: res.status,
|
||||||
|
error: new Error('Could not load bots')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
|
export let bots: object[];
|
||||||
|
let name: string | undefined;
|
||||||
|
|
||||||
|
async function createBot() {
|
||||||
|
const token = get_session_token();
|
||||||
|
const res = await fetch('/api/bots', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
let bot = await res.json();
|
||||||
|
goto(`/bots/${bot['id']}`);
|
||||||
|
} else {
|
||||||
|
new Error('creation failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form on:submit|preventDefault={createBot}>
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<input name="name" bind:value={name}/>
|
||||||
|
<button type="submit">Create</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{#each bots as bot}
|
||||||
|
<li>
|
||||||
|
<a target="_blank" href={`bots/${bot['id']}`}>
|
||||||
|
{bot['name']}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
Loading…
Reference in a new issue