create new bot flow

This commit is contained in:
Ilion Beyst 2022-07-24 18:05:20 +02:00
parent 99987f8444
commit 90dfc3dec4
4 changed files with 140 additions and 4 deletions

View file

@ -134,17 +134,25 @@ pub struct BotParams {
name: String,
}
// TODO: can we unify this with save_bot?
pub async fn create_bot(
conn: DatabaseConnection,
user: User,
params: Json<BotParams>,
) -> (StatusCode, Json<Bot>) {
) -> Result<(StatusCode, Json<Bot>), SaveBotError> {
validate_bot_name(&params.name)?;
let existing_bot = bots::find_bot_by_name(&params.name, &conn)
.optional()
.expect("could not run query");
if existing_bot.is_some() {
return Err(SaveBotError::BotNameTaken);
}
let bot_params = bots::NewBot {
owner_id: Some(user.id),
name: &params.name,
};
let bot = bots::create_bot(&bot_params, &conn).unwrap();
(StatusCode::CREATED, Json(bot))
Ok((StatusCode::CREATED, Json(bot)))
}
// TODO: handle errors

View file

@ -0,0 +1,98 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { get_session_token } from "$lib/auth";
import { currentUser } from "$lib/stores/current_user";
import { onMount } from "svelte";
let botName: string | undefined = undefined;
let saveErrors: string[] = [];
onMount(() => {
// ensure user is logged in
if (!$currentUser) {
goto("/login");
}
});
async function createBot() {
saveErrors = [];
let response = await fetch("/api/bots", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${get_session_token()}`,
},
body: JSON.stringify({
name: botName,
}),
});
let responseData = await response.json();
if (response.ok) {
let bot = responseData;
goto(`/bots/${bot["name"]}`);
} else {
const error = responseData["error"];
if (error["type"] === "validation_failed") {
saveErrors = error["validation_errors"];
} else if (error["type"] === "bot_name_taken") {
saveErrors = ["Bot name is already taken"];
} else {
// unexpected error
throw responseData;
}
}
}
</script>
<div class="container">
<div class="create-bot-form">
<h4>Create new bot</h4>
<input type="text" class="bot-name-input" placeholder="bot name" bind:value={botName} />
{#if saveErrors.length > 0}
<ul>
{#each saveErrors as errorText}
<li class="error-text">{errorText}</li>
{/each}
</ul>
{/if}
<button class="submit-button save-button" on:click={createBot}>Save</button>
</div>
</div>
<style lang="scss">
.container {
width: 400px;
max-width: 80%;
margin: 50px auto;
}
.create-bot-form h4 {
margin-bottom: 0.3em;
}
.error-text {
color: red;
}
.submit-button {
padding: 6px 16px;
border-radius: 4px;
border: 0;
font-size: 18pt;
display: block;
margin: 10px auto;
background-color: lightgreen;
cursor: pointer;
}
.bot-name-input {
width: 100%;
font-size: 16px;
padding: 8px 16px;
box-sizing: border-box;
margin: 10px 0;
border: 1px solid rgb(216, 219, 223);
border-radius: 3px;
}
</style>

View file

@ -1,6 +1,5 @@
<script lang="ts" context="module">
import { get_session_token } from "$lib/auth";
import { mount_component } from "svelte/internal";
export async function load({ page }) {
const token = get_session_token();

View file

@ -17,6 +17,8 @@
</script>
<script lang="ts">
import { currentUser } from "$lib/stores/current_user";
export let userName: string;
export let bots: object[];
</script>
@ -25,7 +27,13 @@
<div class="header">
<h1 class="user-name">{userName}</h1>
</div>
<h2>Bots</h2>
<div class="bot-list-header">
<h2 class="bot-list-header-title">Bots</h2>
{#if $currentUser && $currentUser.username == userName}
<a href="/bots/new" class="btn-new-bot"> New bot </a>
{/if}
</div>
<ul class="bot-list">
{#each bots as bot}
<li class="bot">
@ -51,6 +59,29 @@
margin-bottom: 0.5em;
}
.bot-list-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.bot-list-header-title {
margin-bottom: 0px;
}
.btn-new-bot {
padding: 8px 12px;
border-radius: 4px;
border: 0;
display: block;
color: white;
background-color: rgb(40, 167, 69);
font-weight: 500;
text-decoration: none;
font-size: 11pt;
cursor: pointer;
}
.bot-list {
list-style: none;
padding: 0;