Introduce toasts

This commit is contained in:
Fred Boniface 2024-06-13 21:59:01 +01:00
parent 0d0875f893
commit c93f36102e
11 changed files with 2993 additions and 2861 deletions

39
package-lock.json generated
View File

@ -22,6 +22,7 @@
"prettier-plugin-svelte": "^2.8.1", "prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0", "svelte": "^3.54.0",
"svelte-check": "^3.0.1", "svelte-check": "^3.0.1",
"svelte-french-toast": "^1.2.0",
"svelte-sitemap": "^2.6.0", "svelte-sitemap": "^2.6.0",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^4.3.0" "vite": "^4.3.0"
@ -850,12 +851,12 @@
} }
}, },
"node_modules/braces": { "node_modules/braces": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.1.1"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@ -1395,9 +1396,9 @@
} }
}, },
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
@ -2507,6 +2508,18 @@
} }
} }
}, },
"node_modules/svelte-french-toast": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/svelte-french-toast/-/svelte-french-toast-1.2.0.tgz",
"integrity": "sha512-5PW+6RFX3xQPbR44CngYAP1Sd9oCq9P2FOox4FZffzJuZI2mHOB7q5gJBVnOiLF5y3moVGZ7u2bYt7+yPAgcEQ==",
"dev": true,
"dependencies": {
"svelte-writable-derived": "^3.1.0"
},
"peerDependencies": {
"svelte": "^3.57.0 || ^4.0.0"
}
},
"node_modules/svelte-hmr": { "node_modules/svelte-hmr": {
"version": "0.15.3", "version": "0.15.3",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz",
@ -2598,6 +2611,18 @@
"node": ">= 14.17.0" "node": ">= 14.17.0"
} }
}, },
"node_modules/svelte-writable-derived": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.1.tgz",
"integrity": "sha512-w4LR6/bYZEuCs7SGr+M54oipk/UQKtiMadyOhW0PTwAtJ/Ai12QS77sLngEcfBx2q4H8ZBQucc9ktSA5sUGZWw==",
"dev": true,
"funding": {
"url": "https://ko-fi.com/pixievoltno1"
},
"peerDependencies": {
"svelte": "^3.2.1 || ^4.0.0-next.1 || ^5.0.0-next.94"
}
},
"node_modules/text-table": { "node_modules/text-table": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",

View File

@ -24,6 +24,7 @@
"prettier-plugin-svelte": "^2.8.1", "prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0", "svelte": "^3.54.0",
"svelte-check": "^3.0.1", "svelte-check": "^3.0.1",
"svelte-french-toast": "^1.2.0",
"svelte-sitemap": "^2.6.0", "svelte-sitemap": "^2.6.0",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^4.3.0" "vite": "^4.3.0"

View File

@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Island from "$lib/islands/island.svelte"; import Island from "$lib/islands/island.svelte";
import { ql } from "$lib/stores/quick-links"; import { ql } from "$lib/stores/quick-links";
import toast from "svelte-french-toast";
export let variables = { export let variables = {
title: "Quick Links", title: "Quick Links",
}; };
@ -17,6 +18,17 @@
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }
function save() {
toast.promise(
saveQl(),
{
loading: 'Saving...',
success: "Quick Links saved!",
error: "Failed to save."
}
);
}
async function saveQl() { async function saveQl() {
// Fetch the content of all text entries within the island then run ql.set([ARRAY OF INPUT CONTENT]) // Fetch the content of all text entries within the island then run ql.set([ARRAY OF INPUT CONTENT])
const inputs = document.getElementsByClassName("qlInput"); const inputs = document.getElementsByClassName("qlInput");
@ -29,14 +41,14 @@
} }
console.log(inputLinks); console.log(inputLinks);
ql.set(inputLinks); ql.set(inputLinks);
saveButton = "&#10004;"; await timeout(1000);
await timeout(3000);
saveButton = "Saved"; saveButton = "Saved";
} }
function clearQl() { function clearQl() {
ql.set([]); ql.set([]);
saveButton = "Saved"; saveButton = "Saved";
toast.success("Cleared Quick Links.")
} }
function addQlBox() { function addQlBox() {
@ -64,7 +76,7 @@
{/each} {/each}
<button on:click={addQlBox} id="qlAdd">+</button> <button on:click={addQlBox} id="qlAdd">+</button>
</div> </div>
<button on:click={saveQl}>{@html saveButton}</button> <button on:click={save}>{@html saveButton}</button>
<button on:click={clearQl}>Clear</button> <button on:click={clearQl}>Clear</button>
</Island> </Island>

View File

@ -0,0 +1,27 @@
<script lang="ts">
import { stop_propagation } from "svelte/internal";
export let showModal: boolean
let dialog: HTMLDialogElement
$: if (dialog && showModal) dialog.showModal();
</script>
<dialog
bind:this={dialog}
on:close={() => (showModal = false)}
on:click|self={() => dialog.close()}
>
<div on:click|stop_propagation>
<slot name="header" />
<hr />
<slot />
<hr />
<button autofocus on:click{() => dialog.close()}>Close</button>
</div>
</dialog>
<style>
</style>

View File

@ -0,0 +1,9 @@
<script lang="ts">
</script>
<style>
</style>

View File

@ -1,3 +1,3 @@
export const version: string = "2024.04.5"; export const version: string = "2024.06.1";
export const versionTag: string = ""; export const versionTag: string = "";
export const showWelcome: boolean = false; export const showWelcome: boolean = false;

View File

@ -4,6 +4,7 @@
import { dev } from "$app/environment"; import { dev } from "$app/environment";
import DevBanner from "$lib/DevBanner.svelte"; import DevBanner from "$lib/DevBanner.svelte";
import { page } from "$app/stores"; import { page } from "$app/stores";
import { Toaster } from 'svelte-french-toast'
</script> </script>
<svelte:head> <svelte:head>
@ -30,6 +31,7 @@
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<title>OwlBoard</title> <title>OwlBoard</title>
</svelte:head> </svelte:head>
<Toaster />
{#if dev} {#if dev}
<DevBanner /> <DevBanner />
{/if} {/if}

View File

@ -1,4 +1,4 @@
<script> <script lang="ts">
import Header from "$lib/navigation/header.svelte"; import Header from "$lib/navigation/header.svelte";
import Nav from "$lib/navigation/nav.svelte"; import Nav from "$lib/navigation/nav.svelte";
import InputIsland from "$lib/islands/input-island-form.svelte"; import InputIsland from "$lib/islands/input-island-form.svelte";
@ -6,6 +6,8 @@
import Welcome from "$lib/overlays/welcome.svelte"; import Welcome from "$lib/overlays/welcome.svelte";
import { welcome } from "$lib/stores/welcome"; import { welcome } from "$lib/stores/welcome";
import { version, showWelcome } from "$lib/stores/version"; import { version, showWelcome } from "$lib/stores/version";
import { onMount } from "svelte";
import toast from "svelte-french-toast";
const title = "OwlBoard"; const title = "OwlBoard";
const inputIslands = [ const inputIslands = [
@ -22,6 +24,16 @@
queryName: "headcode", queryName: "headcode",
}, },
]; ];
onMount(() => {
toast(
"Registration soon required for some features.\n\nClick 'Register' in the menu.",
{
duration: 3000,
}
)
})
</script> </script>
{#if showWelcome && ($welcome === "null" || !$welcome || parseInt($welcome.replace(/\./g, "")) < parseInt(version.replace(/\./g, "")))} {#if showWelcome && ($welcome === "null" || !$welcome || parseInt($welcome.replace(/\./g, "")) < parseInt(version.replace(/\./g, "")))}

View File

@ -6,6 +6,7 @@
import { checkAuth } from "$lib/libauth"; import { checkAuth } from "$lib/libauth";
import LogoutButton from "$lib/navigation/LogoutButton.svelte"; import LogoutButton from "$lib/navigation/LogoutButton.svelte";
import { getApiUrl } from "$lib/scripts/upstream"; import { getApiUrl } from "$lib/scripts/upstream";
import toast from "svelte-french-toast";
const title = "Register"; const title = "Register";
@ -40,6 +41,17 @@
isLoading = false; isLoading = false;
} }
function send() {
toast.promise(
request(),
{
loading: "Contacting Server...",
success: "Request Answered.",
error: "Unable to contact server."
}
)
}
onMount(async () => { onMount(async () => {
const auth = await checkAuth(); const auth = await checkAuth();
if (auth.uuidPresent === false) { if (auth.uuidPresent === false) {
@ -59,7 +71,7 @@
{:else if state == "unreg"} {:else if state == "unreg"}
<p>To register, you will need to enter a work email address to receive a confirmation email</p> <p>To register, you will need to enter a work email address to receive a confirmation email</p>
<p class="bold">Already have a registration code? <a href="/more/reg/submit">enter it here</a></p> <p class="bold">Already have a registration code? <a href="/more/reg/submit">enter it here</a></p>
<form on:submit={request}> <form on:submit={send}>
<input type="text" autocomplete="email" placeholder="Enter work email" bind:value={inputValue} on:input={handleInput} /><br /> <input type="text" autocomplete="email" placeholder="Enter work email" bind:value={inputValue} on:input={handleInput} /><br />
<label for="checkbox"> <label for="checkbox">
I have read and accept the terms of the <a href="/more/privacy">Privacy Policy</a><br /> I have read and accept the terms of the <a href="/more/privacy">Privacy Policy</a><br />

View File

@ -1,4 +1,4 @@
<script> <script lang="ts">
import Header from "$lib/navigation/header.svelte"; import Header from "$lib/navigation/header.svelte";
import Nav from "$lib/navigation/nav.svelte"; import Nav from "$lib/navigation/nav.svelte";
import Island from "$lib/islands/island.svelte"; import Island from "$lib/islands/island.svelte";
@ -6,6 +6,8 @@
import { uuid } from "$lib/stores/uuid"; import { uuid } from "$lib/stores/uuid";
import StylesToc from "$lib/train/styles-toc.svelte"; import StylesToc from "$lib/train/styles-toc.svelte";
import { getApiUrl } from "$lib/scripts/upstream"; import { getApiUrl } from "$lib/scripts/upstream";
import toast from "svelte-french-toast";
import { onMount } from "svelte";
const title = "PIS Finder"; const title = "PIS Finder";
const variables = { title: "Results" }; const variables = { title: "Results" };
@ -24,14 +26,16 @@
isLoading = false; isLoading = false;
} }
/* Temporarily Disabled
async function findByPis() { async function findByPis() {
isLoading = true; isLoading = true;
const url = `${getApiUrl()}/api/v2/pis/byCode/${entryPIS}`; const url = `${getApiUrl()}/api/v2/pis/byCode/${entryPIS}`;
await fetchData(url); await fetchData(url);
isLoading = false; isLoading = false;
} }
*/
async function fetchData(url) { async function fetchData(url: string) {
const options = { const options = {
method: "GET", method: "GET",
headers: { headers: {
@ -41,20 +45,29 @@
const res = await fetch(url, options); // Enable Auth const res = await fetch(url, options); // Enable Auth
if (res.status == 401) { if (res.status == 401) {
errMsg = "You must be logged in to the staff version"; errMsg = "You must be logged in to the staff version";
toast.error("You must be registered")
error = true; error = true;
return false; return false;
} else if (res.status == 500) { } else if (res.status == 500) {
errMsg = "Server Error, try again later"; errMsg = "Server Error, try again later";
toast.error("Server Error.", {duration: 7500})
error = true; error = true;
return false; return false;
} }
const jsonData = await res.json(); const jsonData = await res.json();
if (jsonData.ERROR == "offline") { if (jsonData.ERROR == "offline") {
errMsg = "Connection error, check your internet connection and try again"; errMsg = "Connection error, check your internet connection and try again";
toast.error("You are offline.")
error = true; error = true;
return false; return false;
} }
data = jsonData; data = jsonData;
let count = data.length
if (!count) {
toast.error("No PIS Codes found.")
} else {
toast.success(`${count} PIS Codes found`)
}
} }
async function reset() { async function reset() {
@ -63,7 +76,18 @@
entryPIS = ""; entryPIS = "";
entryStartCRS = ""; entryStartCRS = "";
entryEndCRS = ""; entryEndCRS = "";
toast.success("Form reset")
} }
onMount(() => {
toast(
"Registration soon required for PIS features.\n\nClick 'Register' in the menu.",
{
duration: 3000,
}
)
})
</script> </script>
<Header {title} /> <Header {title} />

View File

@ -8,6 +8,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import TrainDetail from "$lib/train/train-detail.svelte"; import TrainDetail from "$lib/train/train-detail.svelte";
import { getApiUrl } from "$lib/scripts/upstream"; import { getApiUrl } from "$lib/scripts/upstream";
import toast from "svelte-french-toast";
let title = "Timetable Results"; let title = "Timetable Results";
let id = ""; let id = "";
@ -40,6 +41,13 @@
} }
} }
isLoading = false; isLoading = false;
toast(
"Registration soon required for timetable features.\n\nClick 'Register' in the menu.",
{
duration: 3000,
}
)
}); });
async function fetchData(id = "") { async function fetchData(id = "") {