aboutsummaryrefslogtreecommitdiffstats
path: root/apps/portal/src/app/pages
diff options
context:
space:
mode:
Diffstat (limited to 'apps/portal/src/app/pages')
-rw-r--r--apps/portal/src/app/pages/_layout.svelte62
-rw-r--r--apps/portal/src/app/pages/_layout@loggedin.svelte75
-rw-r--r--apps/portal/src/app/pages/admin/index.svelte18
-rw-r--r--apps/portal/src/app/pages/forgot.svelte102
-rw-r--r--apps/portal/src/app/pages/home.svelte103
-rw-r--r--apps/portal/src/app/pages/login.svelte142
-rw-r--r--apps/portal/src/app/pages/profile/index.svelte167
-rw-r--r--apps/portal/src/app/pages/reset-password.svelte138
-rw-r--r--apps/portal/src/app/pages/sign-up.svelte131
9 files changed, 0 insertions, 938 deletions
diff --git a/apps/portal/src/app/pages/_layout.svelte b/apps/portal/src/app/pages/_layout.svelte
deleted file mode 100644
index 8c75cb9..0000000
--- a/apps/portal/src/app/pages/_layout.svelte
+++ /dev/null
@@ -1,62 +0,0 @@
-<script>
- import BlowoutToolbelt from "$shared/components/blowout-toolbelt.svelte";
-</script>
-
-<style>
- #decoration {
- position: absolute;
- top: 0;
- left: 0;
- pointer-events: none;
- width: 100%;
- height: 100%;
- overflow: hidden;
- z-index: 1;
- }
-
- #decoration svg {
- position: absolute;
- top: 0;
- left: 50%;
- -webkit-transform: translateX(-50%);
- transform: translateX(-50%);
- width: 134%;
- min-width: 1280px;
- max-width: 1920px;
- height: auto;
- }
-</style>
-<BlowoutToolbelt/>
-
-<main class="container-fluid padding-x-xs padding-x-xxl@xs padding-y-md padding-y-lg@md max-width-sm">
- <div class="z-index-2 position-relative">
- <slot/>
- </div>
-
- <figure id="decoration"
- class="z-index-1"
- aria-hidden="true">
- <svg class="color-contrast-higher opacity-10%"
- viewBox="0 0 1920 450"
- fill="none">
- <g stroke="currentColor"
- stroke-width="2"
- stroke-linejoin="round"
- stroke-linecap="round">
- <path d="M1449 94.9993V3L1354 48.9995L1259 3V94.9993L1354 140.999L1449 94.9993Z"/>
- <path d="M1639 94.9993V3L1544 48.9995L1449 3V94.9993L1544 140.999L1639 94.9993Z"/>
- <path d="M1354 49.0002V141"/>
- <path d="M1544 49.0002V141"/>
- <path d="M1449 94.9995L1544 140.999L1449 186.999L1354 140.999L1449 94.9995Z"/>
- <path d="M1544 141V232.999L1449 278.999L1354 232.999V141"/>
- <path d="M1449 187V279"/>
- <path d="M1544 264L1639 310L1544 355.999L1449 310L1544 264Z"/>
- <path d="M1639 310V402L1544 447.999L1449 402V310"/>
- <path d="M1544 356.001V448"/>
- <path d="M1639 94.9995L1734 140.999L1639 186.999L1544 140.999L1639 94.9995Z"/>
- <path d="M1734 141V232.999L1639 278.999L1544 232.999V141"/>
- <path d="M1639 187V279"/>
- </g>
- </svg>
- </figure>
-</main>
diff --git a/apps/portal/src/app/pages/_layout@loggedin.svelte b/apps/portal/src/app/pages/_layout@loggedin.svelte
deleted file mode 100644
index 44e2e4a..0000000
--- a/apps/portal/src/app/pages/_layout@loggedin.svelte
+++ /dev/null
@@ -1,75 +0,0 @@
-<script>
- import BlowoutToolbelt from "$shared/components/blowout-toolbelt.svelte";
- import {end_session, get_session_data} from "$shared/lib/session";
- import {replace} from "svelte-spa-router";
-
- const session = get_session_data();
-</script>
-
-<style>
- #decoration {
- position: absolute;
- top: 0;
- left: 0;
- pointer-events: none;
- width: 100%;
- height: 100%;
- overflow: hidden;
- z-index: 1;
- }
-
- #decoration svg {
- position: absolute;
- top: 0;
- left: 50%;
- -webkit-transform: translateX(-50%);
- transform: translateX(-50%);
- width: 134%;
- min-width: 1280px;
- max-width: 1920px;
- height: auto;
- }
-</style>
-<BlowoutToolbelt/>
-<main class="container max-width-xl padding-x-xs padding-x-xxl@xs padding-y-md padding-y-lg@md">
- <div class="z-index-2 position-relative">
- <slot/>
- </div>
-
- <div class="flex flex-row gap-xs position-fixed left-0 top-0 margin-md z-index-2">
- <span on:click={async () => {
- if (confirm("Are you sure?")) await end_session(() => {
- replace("/login");
- })
- }} class="btn btn--sm">
- Logout
- </span>
- </div>
-
- <figure id="decoration"
- class="z-index-1"
- aria-hidden="true">
- <svg class="color-contrast-higher opacity-10%"
- viewBox="0 0 1920 450"
- fill="none">
- <g stroke="currentColor"
- stroke-width="2"
- stroke-linejoin="round"
- stroke-linecap="round">
- <path d="M1449 94.9993V3L1354 48.9995L1259 3V94.9993L1354 140.999L1449 94.9993Z"/>
- <path d="M1639 94.9993V3L1544 48.9995L1449 3V94.9993L1544 140.999L1639 94.9993Z"/>
- <path d="M1354 49.0002V141"/>
- <path d="M1544 49.0002V141"/>
- <path d="M1449 94.9995L1544 140.999L1449 186.999L1354 140.999L1449 94.9995Z"/>
- <path d="M1544 141V232.999L1449 278.999L1354 232.999V141"/>
- <path d="M1449 187V279"/>
- <path d="M1544 264L1639 310L1544 355.999L1449 310L1544 264Z"/>
- <path d="M1639 310V402L1544 447.999L1449 402V310"/>
- <path d="M1544 356.001V448"/>
- <path d="M1639 94.9995L1734 140.999L1639 186.999L1544 140.999L1639 94.9995Z"/>
- <path d="M1734 141V232.999L1639 278.999L1544 232.999V141"/>
- <path d="M1639 187V279"/>
- </g>
- </svg>
- </figure>
-</main>
diff --git a/apps/portal/src/app/pages/admin/index.svelte b/apps/portal/src/app/pages/admin/index.svelte
deleted file mode 100644
index f9b91d2..0000000
--- a/apps/portal/src/app/pages/admin/index.svelte
+++ /dev/null
@@ -1,18 +0,0 @@
-<script>
- import Layout from "../_layout@loggedin.svelte";
- import {Bread, Crumb} from "$shared/components/breadcrumb";
- import {push} from "svelte-spa-router";
-
-</script>
-
-<Layout>
- <Bread>
- <Crumb name="Home"
- withArrow="true"
- isLink="true"
- on:click={() => push("/")}/>
- <Crumb name="Organisation"/>
- </Bread>
-
- <main class="max-width-sm"></main>
-</Layout>
diff --git a/apps/portal/src/app/pages/forgot.svelte b/apps/portal/src/app/pages/forgot.svelte
deleted file mode 100644
index 156deab..0000000
--- a/apps/portal/src/app/pages/forgot.svelte
+++ /dev/null
@@ -1,102 +0,0 @@
-<script>
- import {onMount} from "svelte";
- import {link} from "svelte-spa-router";
- import {create_forgot_password_request} from "$shared/lib/api/user";
- import {is_email} from "$shared/lib/helpers";
- import Alert from "$shared/components/alert.svelte";
- import Button from "$shared/components/button.svelte";
- import Tile from "$shared/components/tile.svelte";
- import Layout from "./_layout.svelte";
-
- let isLoading = false;
- let username;
-
- const alert = {
- title: "",
- type: "",
- message: "",
- isVisible: false,
- show(type, obj) {
- alert.title = obj.title;
- alert.message = obj.text;
- alert.type = type;
- alert.isVisible = true;
- isLoading = false;
- },
- hide() {
- alert.isVisible = false;
- alert.title = "";
- alert.message = "";
- alert.type = "";
- isLoading = false;
- },
- };
-
- function is_valid() {
- return is_email(username);
- }
-
- async function submit_form() {
- if (isLoading) {
- return;
- }
- if (is_valid()) {
- isLoading = true;
- const response = await create_forgot_password_request(username);
- if (response.ok) {
- alert.show("success", {
- title: "Request is sent",
- text: "If we find an account associated with this email address, you will receive an email with a reset link very soon.",
- });
- } else {
- console.error(response.data);
- alert.show("error", {
- title: response.data?.title ?? "An error occured",
- text: response.data?.text ?? "Please try again soon",
- });
- }
- }
- }
-
- onMount(() => {
- document.addEventListener("DOMContentLoaded", () => {
- document.getElementById("email-address").focus();
- });
- });
-</script>
-
-<Layout>
- <Tile>
- <form on:submit|preventDefault={submit_form}
- class="max-width-xxs">
- <fieldset>
- <legend class="form-legend">
- <span class="margin-bottom-xs text-xl">Send reset link</span> <br/>
- <span class="text-sm">... or <a href="/login"
- use:link>log in</a></span>
- </legend>
- <div class="margin-bottom-xs">
- <p>Provide your email address, and we'll send you a link to set your new password.</p>
- </div>
- <div class="margin-bottom-xxs max-width-xxs">
- <Alert visible={alert.isVisible}
- title={alert.title}
- message={alert.message}
- type={alert.type}/>
- </div>
- <div class="margin-bottom-xs">
- <input type="email"
- id="email-address"
- placeholder="Email address"
- class="form-control width-100%"
- bind:value={username}/>
- </div>
- <div class="flex justify-end">
- <Button text="Send reset link"
- type="primary"
- loading={isLoading}/>
- </div>
- </fieldset>
- </form>
- </Tile>
-</Layout>
diff --git a/apps/portal/src/app/pages/home.svelte b/apps/portal/src/app/pages/home.svelte
deleted file mode 100644
index 0e325ee..0000000
--- a/apps/portal/src/app/pages/home.svelte
+++ /dev/null
@@ -1,103 +0,0 @@
-<script>
- import {projects_base} from "$shared/lib/configuration";
- import {get_session_data} from "$shared/lib/session";
- import {push} from "svelte-spa-router";
- import Layout from "./_layout@loggedin.svelte";
- import LinkCard from "$shared/components/link-card.svelte";
- import Alert from "$shared/components/alert.svelte";
- import {UserIcon, UsersIcon, WatchIcon, SendIcon, ListIcon} from "svelte-feather-icons";
-
- let showUsers = true;
- const session = get_session_data();
-</script>
-
-<Layout>
- <div class="grid gap-md">
- <div class="row">
- <Alert closeable="true"
- closeableCooldown="~"
- id="welcome-note"
- title="Hello {session.profile?.username}"
- message="This is your portal to Greatoffice, here you will find all your great apps and management options."/>
- </div>
- <div class="row">
- <h2 class="margin-bottom-xs">Apps</h2>
- <div class="grid-auto-md gap-sm">
- <LinkCard name="Projects"
- description="The home for your projects"
- text="Open in a new tab"
- title="Open Projects"
- href="{projects_base()}">
- <figure slot="icon">
- <div class="bg-primary bg-opacity-10% padding-xs border-left border-primary border-2">
- <WatchIcon size="42"
- class="color-primary"
- strokeWidth="1.2"/>
- </div>
- </figure>
- </LinkCard>
- <LinkCard name="Tickets"
- description="The home for your tickets"
- class="c-disabled user-select-none"
- text="Coming soon"
- title="Open Tickets"
- href="{projects_base()}">
- <figure slot="icon">
- <div class="bg-primary bg-opacity-10% padding-xs border-left border-primary border-2">
- <SendIcon size="42"
- class="color-primary"
- strokeWidth="1.2"/>
- </div>
- </figure>
- </LinkCard>
- <LinkCard name="Todo"
- description="The home for your todos"
- class="c-disabled user-select-none"
- text="Coming soon"
- title="Open Todo"
- href="{projects_base()}">
- <figure slot="icon">
- <div class="bg-primary bg-opacity-10% padding-xs border-left border-primary border-2">
- <ListIcon size="42"
- class="color-primary"
- strokeWidth="1.2"/>
- </div>
- </figure>
- </LinkCard>
- </div>
- </div>
- <div class="row">
- <h2 class="margin-bottom-xs">Manage</h2>
- <div class="grid-auto-md gap-sm">
- <LinkCard name="Profile"
- description="Manage your profile"
- text="Open"
- title="Go to your profile management page"
- on:click={() => push("/profile")}>
- <figure slot="icon">
- <div class="bg-primary bg-opacity-10% padding-xs border-left border-primary border-2">
- <UserIcon size="42"
- class="color-primary"
- strokeWidth="1.2"/>
- </div>
- </figure>
- </LinkCard>
- {#if showUsers}
- <LinkCard name="Organisation"
- description="Manage your organisation"
- title="Go to your organisations management page"
- text="Open"
- on:click={() => push("/admin")}>
- <figure slot="icon">
- <div class="bg-primary bg-opacity-10% padding-xs border-left border-primary border-2">
- <UsersIcon size="42"
- class="color-primary"
- strokeWidth="1.2"/>
- </div>
- </figure>
- </LinkCard>
- {/if}
- </div>
- </div>
- </div>
-</Layout>
diff --git a/apps/portal/src/app/pages/login.svelte b/apps/portal/src/app/pages/login.svelte
deleted file mode 100644
index 1ca6b61..0000000
--- a/apps/portal/src/app/pages/login.svelte
+++ /dev/null
@@ -1,142 +0,0 @@
-<script>
- import {onMount} from "svelte";
- import {link, replace, querystring} from "svelte-spa-router";
- import {api_base, IconNames, frontpage_base} from "$shared/lib/configuration";
- import Button from "$shared/components/button.svelte";
- import Alert from "$shared/components/alert.svelte";
- import Tile from "$shared/components/tile.svelte";
- import {login} from "$shared/lib/api/user";
- import {is_email} from "$shared/lib/helpers";
- import Layout from "./_layout.svelte";
-
- const loginForm = {
- loading: false,
- values: {
- username: "",
- password: "",
- persist: true
- },
- alert: {
- title: "",
- type: "",
- message: "",
- isVisible: false,
- show(type, obj) {
- loginForm.alert.title = obj.title;
- loginForm.alert.message = obj.text;
- loginForm.alert.type = type;
- loginForm.alert.isVisible = true;
- loginForm.loading = false;
- },
- hide() {
- loginForm.alert.isVisible = false;
- loginForm.alert.title = "";
- loginForm.alert.message = "";
- loginForm.alert.type = "";
- },
- },
- is_valid() {
- return is_email(loginForm.values.username) && loginForm.values.password.length > 0;
- },
- async submit_form() {
- if (loginForm.loading) {
- return;
- }
- if (loginForm.is_valid()) {
- loginForm.alert.hide();
- loginForm.loading = true;
- try {
- const response = await login(loginForm.values);
- if (response.ok) {
- await replace("#/home");
- } else {
- if (response.data.title || response.data.text) {
- loginForm.alert.show("error", {
- title: response.data.title ?? "",
- text: response.data.text ?? "",
- });
- } else {
- loginForm.alert.show("error", {
- title: "An unknown error occured",
- text: "Try again soon",
- });
- }
- }
- } catch (e) {
- loginForm.alert.show("error", {
- title: "An error occured",
- text: "Could not connect to server, please check your internet connection",
- });
- }
- } else {
- loginForm.alert.show("error", {
- title: "Invalid form",
- });
- }
- },
- };
-
- onMount(() => {
- if ($querystring === "deleted") {
- loginForm.alert.show("info", {
- title: "Account deleted",
- text: "Your account and all its data was successfully deleted.",
- });
- }
- if ($querystring === "expired") {
- loginForm.alert.show("info", {
- title: "Session expired",
- text: "Your session has expired, feel free to log in again.",
- });
- }
- });
-</script>
-
-<Layout>
- <a href="{frontpage_base()}" class="block margin-bottom-xs">Go to {frontpage_base()}</a>
- <Tile>
- <form on:submit|preventDefault={loginForm.submit_form}
- class="max-width-xxs">
- <fieldset>
- <legend class="form-legend">
- <span class="margin-bottom-xs text-xl">Log into your account</span>
- <br/>
- <span class="text-sm">... or <a href="/signup"
- use:link>create a new one</a></span>
- </legend>
- <div class="margin-bottom-xxs max-width-xxs">
- <Alert visible={loginForm.alert.isVisible}
- title={loginForm.alert.title}
- message={loginForm.alert.message}
- type={loginForm.alert.type}/>
- </div>
- <div class="margin-bottom-xxs">
- <input type="email"
- placeholder="Email address"
- class="form-control width-100%"
- id="username"
- bind:value={loginForm.values.username}/>
- </div>
- <div class="margin-bottom-xxs">
- <input type="password"
- placeholder="Password"
- id="password"
- class="form-control width-100%"
- bind:value={loginForm.values.password}/>
- <div class="flex justify-end">
- <a tabindex="-1"
- class="text-sm"
- href="/forgot"
- use:link>Reset password</a>
- </div>
- </div>
- <div class="flex justify-between">
- <Button text="Login"
- type="submit"
- variant="primary"
- loading={loginForm.loading}/>
- </div>
- </fieldset>
- </form>
- </Tile>
-</Layout>
diff --git a/apps/portal/src/app/pages/profile/index.svelte b/apps/portal/src/app/pages/profile/index.svelte
deleted file mode 100644
index a7291d6..0000000
--- a/apps/portal/src/app/pages/profile/index.svelte
+++ /dev/null
@@ -1,167 +0,0 @@
-<script>
- import {push} from "svelte-spa-router";
- import {Bread, Crumb} from "$shared/components/breadcrumb/index";
- import Layout from "$app/pages/_layout@loggedin.svelte";
- import {update_profile} from "$shared/lib/api/user";
- import Alert from "$shared/components/alert.svelte";
- import Button from "$shared/components/button.svelte";
- import {is_email} from "$shared/lib/helpers";
- import {api_base} from "$shared/lib/configuration";
- import {get_session_data} from "$shared/lib/session";
-
- const archiveLink = api_base("_/account/archive");
-
- let modal;
- let understands = false;
-
- let formIsLoading = false;
- let formError;
-
- let username = get_session_data()?.profile.username;
- let usernameFieldMessage;
- let usernameFieldMessageClass = "color-error";
-
- let password;
- let passwordFieldMessage;
- let passwordFieldMessageClass = "color-error";
-
- async function submit_form(e) {
- e.preventDefault();
- if (!username && !password) {
- console.error("Not submitting because both values is empty");
- return;
- }
-
- usernameFieldMessage = "";
- passwordFieldMessage = "";
-
- if (username && !is_email(username)) {
- usernameFieldMessage = "Username has to be a valid email";
- return;
- }
-
- if (password && password?.length < 6) {
- passwordFieldMessage = "The new password must contain at least 6 characters";
- return;
- }
-
- formIsLoading = true;
-
- const response = await update_profile({
- username,
- password,
- });
-
- formIsLoading = false;
-
- if (response.ok) {
- if (password) {
- passwordFieldMessage = "Successfully updated";
- passwordFieldMessageClass = "color-success";
- password = "";
- }
- if (username) {
- usernameFieldMessage = "Successfully updated";
- usernameFieldMessageClass = "color-success";
- password = "";
- }
- } else {
- formError = response.data.title ?? "An unknown error occured";
- }
- }
-
- async function handle_delete_account_button_click() {
- alert("Not implemented");
- return;
- if (understands && confirm("Are you absolutely sure that you want to delete your account?")) {
- }
- }
-
- export const functions = {
- open() {
- modal.open();
- },
- close() {
- // modal.close();
- },
- };
-</script>
-
-<Layout>
- <Bread>
- <Crumb name="Home"
- withArrow="true"
- isLink="true"
- on:click={() => push("/")}/>
- <Crumb name="Profile"/>
- </Bread>
-
- <main class="max-width-sm">
- <section class="margin-bottom-md">
- <p class="text-md margin-bottom-sm">Update your information</p>
- <form on:submit={submit_form}
- autocomplete="new-password">
- {#if formError}
- <small class="color-danger">{formError}</small>
- {/if}
- <div class="margin-bottom-sm">
- <label for="email"
- class="form-label margin-bottom-xxs">New username</label>
- <input type="email"
- class="form-control width-100%"
- id="email"
- placeholder={username}
- bind:value={username}/>
- {#if usernameFieldMessage}
- <small class={usernameFieldMessageClass}>{usernameFieldMessage}</small>
- {/if}
- </div>
- <div class="margin-bottom-sm">
- <label for="password"
- class="form-label margin-bottom-xxs">New password</label>
- <input type="password"
- class="form-control width-100%"
- id="password"
- bind:value={password}/>
- {#if passwordFieldMessage}
- <small class={passwordFieldMessageClass}>{passwordFieldMessage}</small>
- {/if}
- </div>
- <div class="flex justify-end">
- <Button text="Save"
- on:click={submit_form}
- variant="primary"
- loading={formIsLoading}/>
- </div>
- </form>
- </section>
- <section class="margin-bottom-md">
- <p class="text-md margin-bottom-sm">Download your data</p>
- <a class="btn btn--subtle"
- href={archiveLink}
- download>Click here to download your data</a>
- </section>
- <section>
- <p class="text-md margin-bottom-sm">Delete account</p>
- <div class="margin-bottom-sm">
- <Alert
- message="Deleting your account and data means that all of your data (entries, categories, etc.) will be unrecoverable forever.<br>You should probably download your data before continuing."
- type="info"
- />
- </div>
- <div class="form-check margin-bottom-sm">
- <input type="checkbox"
- class="checkbox"
- id="the-consequences"
- bind:checked={understands}/>
- <label for="the-consequences">I understand the consequences of deleting my account and data.</label>
- </div>
- <div class="flex justify-end">
- <Button text="Delete everything"
- variant="accent"
- disabled={!understands}
- on:click={handle_delete_account_button_click}/>
- </div>
- </section>
- </main>
-</Layout>
diff --git a/apps/portal/src/app/pages/reset-password.svelte b/apps/portal/src/app/pages/reset-password.svelte
deleted file mode 100644
index dabf5c9..0000000
--- a/apps/portal/src/app/pages/reset-password.svelte
+++ /dev/null
@@ -1,138 +0,0 @@
-<script>
- import {querystring, link} from "svelte-spa-router";
- import {check_forgot_password_request, fulfill_forgot_password_request} from "$shared/lib/api/user";
- import Alert from "$shared/components/alert.svelte";
- import Button from "$shared/components/button.svelte";
- import Tile from "$shared/components/tile.svelte";
- import Layout from "./_layout.svelte";
-
- const requestId = new URLSearchParams($querystring).get("id");
- let isLoading = false;
- let newPassword;
- let newPasswordError;
- let alert = {
- title: "",
- type: "",
- message: "",
- isVisible: false,
- show(type, obj) {
- alert.title = obj.title;
- alert.message = obj.text;
- alert.type = type;
- alert.isVisible = true;
- isLoading = false;
- },
- hide() {
- alert.isVisible = false;
- alert.title = "";
- alert.message = "";
- alert.type = "";
- isLoading = false;
- },
- };
-
- function is_valid() {
- let isValid = true;
- if (!newPassword.length > 5) {
- newPasswordError = "The new password must be at least 5 characters";
- isValid = false;
- }
- return isValid;
- }
-
- async function submit() {
- if (isLoading) {
- return;
- }
- if (is_valid()) {
- isLoading = true;
- const response = await fulfill_forgot_password_request(requestId, newPassword);
- if (response.ok) {
- alert.show("success", {
- title: "Your new password is set",
- text: "<a href='/#/login'>Click here to log in</a>",
- });
- } else {
- console.error(response.data);
- alert.show("error", {
- title: response.data?.title ?? "An error occured",
- text: response.data?.text ?? "Please try again soon",
- });
- }
- }
- }
-
- async function is_valid_password_reset_request() {
- const response = await check_forgot_password_request(requestId);
- if (response.ok) {
- return response.data === true;
- }
- return false;
- }
-</script>
-
-<Layout>
- <Tile>
- <form on:submit|preventDefault={submit}
- class="max-width-xxs {isLoading ? 'c-disabled loading' : ''}">
- {#if requestId}
- {#await is_valid_password_reset_request()}
- <p>Checking your request...</p>
- <a href="/login"
- use:link>cancel</a>
- {:then isActive}
- {#if isActive === true}
- <fieldset>
- <legend class="form-legend">
- <span class="margin-bottom-xs text-xl">Set your new password</span> <br/>
- <span class="text-sm">
- ... or
- <a href="/login"
- use:link> log in </a>
- </span>
- </legend>
- <div class="margin-bottom-xxs max-width-xxs">
- <Alert visible={alert.isVisible}
- title={alert.title}
- message={alert.message}
- type={alert.type}/>
- </div>
- <div class="margin-bottom-xs">
- <input
- type="password"
- id="new-password"
- placeholder="New password"
- class="form-control width-100%"
- bind:value={newPassword}
- />
- {#if newPasswordError}
- <small class="color-danger">{newPasswordError}</small>
- {/if}
- </div>
- <div class="flex justify-end">
- <Button text="Set new password"
- type="primary"
- loading={isLoading}
- on:click={submit}/>
- </div>
- </fieldset>
- {:else}
- <Alert title="This request is expired"
- message="Please submit the forgot password form again"
- type="warning"/>
- <div class="flex justify-between width-100% margin-y-sm">
- <a href="/forgot"
- use:link>Go to forgot form</a>
- <a href="/login"
- use:link>Go to login form</a>
- </div>
- {/if}
- {:catch _}
- <Alert title="An error occured"
- message="Please try again soon"
- type="error"/>
- {/await}
- {/if}
- </form>
- </Tile>
-</Layout>
diff --git a/apps/portal/src/app/pages/sign-up.svelte b/apps/portal/src/app/pages/sign-up.svelte
deleted file mode 100644
index 3bcab6d..0000000
--- a/apps/portal/src/app/pages/sign-up.svelte
+++ /dev/null
@@ -1,131 +0,0 @@
-<script>
- import {create_account} from "$shared/lib/api/user";
- import {frontpage_base} from "$shared/lib/configuration";
- import {is_email} from "$shared/lib/helpers";
- import Alert from "$shared/components/alert.svelte";
- import Button from "$shared/components/button.svelte";
- import Tile from "$shared/components/tile.svelte";
- import {link} from "svelte-spa-router";
- import Layout from "./_layout.svelte";
-
- const signupForm = {
- loading: false,
- values: {
- username: "",
- password: "",
- },
- alert: {
- title: "",
- type: "",
- message: "",
- isVisible: false,
- show(type, obj) {
- signupForm.alert.title = obj.title;
- signupForm.alert.message = obj.text;
- signupForm.alert.type = type;
- signupForm.alert.isVisible = true;
- signupForm.loading = false;
- },
- hide() {
- signupForm.alert.isVisible = false;
- signupForm.alert.title = "";
- signupForm.alert.message = "";
- signupForm.alert.type = "";
- },
- },
- is_valid() {
- return (
- is_email(signupForm.values.username) &&
- signupForm.values.password.length > 0
- );
- },
- async submit_form() {
- if (signupForm.loading) {
- return;
- }
- if (signupForm.is_valid()) {
- signupForm.alert.hide();
- signupForm.loading = true;
- try {
- const response = await create_account(signupForm.values);
- if (response.ok) {
- location.reload();
- } else {
- if (response.data.title || response.data.text) {
- signupForm.alert.show("error", {
- title: response.data.title ?? "",
- text: response.data.text ?? "",
- });
- } else {
- signupForm.alert.show("error", {
- title: "An unknown error occured",
- text: "Try again soon",
- });
- }
- }
- } catch (e) {
- console.error(e);
- signupForm.alert.show("error", {
- title: "An error occured",
- text: "Could not connect to server, please check your internet connection",
- });
- }
- } else {
- signupForm.alert.show("error", {
- title: "Invalid form",
- });
- }
- },
- };
-</script>
-
-<Layout>
- <a href="{frontpage_base()}"
- class="block margin-bottom-xs">Go to {frontpage_base()}</a>
- <Tile>
- <form on:submit|preventDefault={signupForm.submit_form}
- class="max-width-xxs">
- <fieldset>
- <legend class="form-legend">
- <span class="margin-bottom-xs text-xl">Create your account</span> <br/>
- <span class="text-sm"
- >... or <a href="/login"
- use:link>log in</a></span
- >
- </legend>
- <div class="margin-bottom-xs">
- <p>Provide an email and password to get immediate access to your new environment (30 days full access, no billing details required, no promotion emails).</p>
- </div>
- <div class="margin-bottom-xxs max-width-xxs">
- <Alert visible={signupForm.alert.isVisible}
- title={signupForm.alert.title}
- message={signupForm.alert.message}
- type={signupForm.alert.type}
- />
- </div>
- <div class="margin-bottom-xxs">
- <input type="email"
- placeholder="Email address"
- class="form-control width-100%"
- id="email-address"
- bind:value={signupForm.values.username}
- />
- </div>
- <div class="margin-bottom-xxs">
- <input type="password"
- placeholder="Password"
- class="form-control width-100%"
- bind:value={signupForm.values.password}
- />
- </div>
- <div class="flex justify-end">
- <Button class="margin-bottom-xs"
- text="Create account"
- type="primary"
- loading={signupForm.loading}
- />
- </div>
- </fieldset>
- </form>
- </Tile>
-</Layout>