1
0
Fork 0
mirror of synced 2024-09-21 11:53:49 +12:00
budibase/packages/builder/src/components/start/CreateAppModal.svelte

198 lines
4.4 KiB
Svelte
Raw Normal View History

2020-05-27 02:25:37 +12:00
<script>
2020-05-27 22:54:53 +12:00
import Spinner from "components/common/Spinner.svelte"
2020-07-31 20:46:23 +12:00
import { API, Info, User } from "./Steps"
import Indicator from "./Indicator.svelte"
2020-05-27 03:37:11 +12:00
import { Input, TextArea, Button } from "@budibase/bbui"
2020-05-27 22:54:53 +12:00
import { goto } from "@sveltech/routify"
2020-05-27 02:25:37 +12:00
import { AppsIcon, InfoIcon, CloseIcon } from "components/common/Icons/"
import { getContext } from "svelte"
2020-05-27 22:54:53 +12:00
import { fade } from "svelte/transition"
import { post } from "builderStore/api"
import analytics from "../../analytics"
2020-05-27 22:54:53 +12:00
2020-07-31 20:46:23 +12:00
export let hasAPIKey = false
2020-05-27 22:54:53 +12:00
const { open, close } = getContext("simple-modal")
2020-05-27 02:25:37 +12:00
2020-05-27 21:44:15 +12:00
let name = ""
let description = ""
2020-05-27 22:54:53 +12:00
let loading = false
2020-05-27 23:48:38 +12:00
let error = {}
2020-05-27 22:54:53 +12:00
2020-05-27 21:44:15 +12:00
const createNewApp = async () => {
2020-05-27 23:48:38 +12:00
if ((name.length > 100 || name.length < 1) && description.length < 1) {
error = {
name: true,
description: true,
}
} else if (description.length < 1) {
error = {
name: false,
description: true,
}
} else if (name.length > 100 || name.length < 1) {
error = {
name: true,
}
} else {
error = {}
const data = { name, description }
loading = true
try {
const response = await post("/api/applications", data)
2020-05-27 22:54:53 +12:00
2020-05-27 23:48:38 +12:00
const res = await response.json()
2020-05-27 22:54:53 +12:00
analytics.captureEvent("web_app_created", {
name,
description,
2020-07-16 04:27:33 +12:00
appId: res._id,
})
2020-05-27 23:48:38 +12:00
$goto(`./${res._id}`)
} catch (error) {
console.error(error)
}
2020-05-27 21:44:15 +12:00
}
}
2020-05-27 02:25:37 +12:00
let value
let onChange = () => {}
function _onCancel() {
close()
}
2020-05-27 21:44:15 +12:00
async function _onOkay() {
await createNewApp()
2020-05-27 02:25:37 +12:00
}
2020-07-31 20:46:23 +12:00
let currentStep = 0
let steps = [
{ title: "Setup your API Key" },
{ title: "Create your first web app" },
{ title: "Create new user" },
]
2020-05-27 02:25:37 +12:00
</script>
<div class="container">
2020-07-31 20:46:23 +12:00
<div class="sidebar">
{#each steps as { active, done }, i}
<Indicator
active={currentStep === i}
done={i < currentStep}
step={i + 1} />
{/each}
</div>
2020-05-27 02:25:37 +12:00
<div class="body">
<div class="heading">
2020-07-31 20:46:23 +12:00
<h3 class="header">Get Started with Budibase</h3>
</div>
<div class="step">
<Input
error={error.name}
name="name"
label="Name"
placeholder="Enter application name"
on:change={e => (name = e.target.value)}
on:input={e => (name = e.target.value)} />
<TextArea
bind:value={description}
name="description"
label="Description"
placeholder="Describe your application" />
{#if error.description}
<span class="error">
Please enter a short description of your application
</span>
{/if}
</div>
<div class="footer">
{#if currentStep !== 0}
<Button primary thin on:click={_onOkay}>Back</Button>
{/if}
<Button primary thin on:click={_onOkay}>Next</Button>
{#if currentStep + 1 === steps.length}
<Button primary thin on:click={_onOkay}>Launch</Button>
{/if}
2020-05-27 02:25:37 +12:00
</div>
2020-05-27 22:54:53 +12:00
</div>
<div class="close-button" on:click={_onCancel}>
<CloseIcon />
2020-05-27 02:25:37 +12:00
</div>
2020-05-27 22:54:53 +12:00
{#if loading}
<div in:fade class="spinner-container">
<Spinner />
<span class="spinner-text">Creating your app...</span>
</div>
{/if}
2020-05-27 02:25:37 +12:00
</div>
<style>
2020-05-27 22:54:53 +12:00
.container {
2020-07-31 20:46:23 +12:00
display: grid;
grid-template-columns: 80px 1fr;
2020-05-27 22:54:53 +12:00
position: relative;
}
2020-07-31 20:46:23 +12:00
.sidebar {
display: grid;
border-bottom-left-radius: 0.5rem;
border-top-left-radius: 0.5rem;
grid-gap: 30px;
align-content: center;
background: #f5f5f5;
}
2020-05-27 02:25:37 +12:00
.close-button {
cursor: pointer;
position: absolute;
top: 20px;
right: 20px;
}
.close-button :global(svg) {
width: 24px;
height: 24px;
}
.heading {
display: flex;
flex-direction: row;
align-items: center;
2020-05-27 03:37:11 +12:00
margin-bottom: 20px;
2020-05-27 02:25:37 +12:00
}
.header {
2020-05-27 02:25:37 +12:00
margin: 0;
font-size: 24px;
font-weight: 600;
2020-05-27 02:25:37 +12:00
}
.body {
2020-07-31 20:46:23 +12:00
padding: 40px 60px 60px 60px;
2020-05-27 02:25:37 +12:00
display: grid;
2020-07-31 20:46:23 +12:00
grid-template-rows: auto 1fr auto;
2020-05-27 02:25:37 +12:00
}
.footer {
display: grid;
2020-07-31 20:46:23 +12:00
grid-gap: 15px;
grid-template-columns: auto auto;
justify-content: end;
2020-05-27 02:25:37 +12:00
}
2020-05-27 22:54:53 +12:00
.spinner-container {
background: white;
position: absolute;
border-radius: 5px;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: grid;
justify-items: center;
align-content: center;
grid-gap: 50px;
}
.spinner-text {
font-size: 2em;
}
2020-05-27 23:48:38 +12:00
.error {
color: var(--red);
2020-05-27 23:48:38 +12:00
font-weight: bold;
font-size: 0.8em;
}
2020-05-27 02:25:37 +12:00
</style>