diff --git a/package.json b/package.json index dc736a1..bc10ed1 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "dependencies": { "@tanstack/svelte-query": "^4.35.0", "axios": "^1.5.0", + "svelte-french-toast": "^1.2.0", "svelte-local-storage-store": "^0.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b97405d..67c01be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ dependencies: axios: specifier: ^1.5.0 version: 1.5.0 + svelte-french-toast: + specifier: ^1.2.0 + version: 1.2.0(svelte@4.2.0) svelte-local-storage-store: specifier: ^0.6.0 version: 0.6.0(svelte@4.2.0) @@ -2061,6 +2064,15 @@ packages: svelte: 4.2.0 dev: true + /svelte-french-toast@1.2.0(svelte@4.2.0): + resolution: {integrity: sha512-5PW+6RFX3xQPbR44CngYAP1Sd9oCq9P2FOox4FZffzJuZI2mHOB7q5gJBVnOiLF5y3moVGZ7u2bYt7+yPAgcEQ==} + peerDependencies: + svelte: ^3.57.0 || ^4.0.0 + dependencies: + svelte: 4.2.0 + svelte-writable-derived: 3.1.0(svelte@4.2.0) + dev: false + /svelte-hmr@0.15.3(svelte@4.2.0): resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==} engines: {node: ^12.20 || ^14.13.1 || >= 16} @@ -2127,6 +2139,14 @@ packages: typescript: 5.2.2 dev: true + /svelte-writable-derived@3.1.0(svelte@4.2.0): + resolution: {integrity: sha512-cTvaVFNIJ036vSDIyPxJYivKC7ZLtcFOPm1Iq6qWBDo1fOHzfk6ZSbwaKrxhjgy52Rbl5IHzRcWgos6Zqn9/rg==} + peerDependencies: + svelte: ^3.2.1 || ^4.0.0-next.1 + dependencies: + svelte: 4.2.0 + dev: false + /svelte@4.2.0: resolution: {integrity: sha512-kVsdPjDbLrv74SmLSUzAsBGquMs4MPgWGkGLpH+PjOYnFOziAvENVzgJmyOCV2gntxE32aNm8/sqNKD6LbIpeQ==} engines: {node: '>=16'} diff --git a/src/components/DeleteConfirm.svelte b/src/components/DeleteConfirm.svelte new file mode 100644 index 0000000..e9ca684 --- /dev/null +++ b/src/components/DeleteConfirm.svelte @@ -0,0 +1,43 @@ + + + + Are you sure you want to, Delete "{props.cmd.name}" {typeToName(props.cmd.type)} Interaction? + +
+ + +
+
diff --git a/src/components/commandList.svelte b/src/components/commandList.svelte index 15824db..66c4cc3 100644 --- a/src/components/commandList.svelte +++ b/src/components/commandList.svelte @@ -2,15 +2,17 @@ import { base } from '$app/paths'; import { fetchAPI } from '$lib/api'; import { typeToName, type DiscordInteraction } from '$lib/constants'; - import { createQuery, useQueryClient } from '@tanstack/svelte-query'; + import { createQuery } from '@tanstack/svelte-query'; + import toast from 'svelte-french-toast'; + import DeleteConfirm from './DeleteConfirm.svelte'; + import { goto } from '$app/navigation'; + // headers for the table let headers: string[] = ['Name', 'Type', 'Description']; // get basePath since same component can be used to get guild commands export let basePath = ''; export let id = 'global'; - const queryClient = useQueryClient(); - $: queryKey = ['app.commands', id]; $: commandList = createQuery({ @@ -25,17 +27,13 @@ $: rows = $commandList.data || []; async function deleteCommand(cmd: DiscordInteraction) { - if (confirm(`Do you want to delete command "${cmd.name}"?"`)) { - try { - await fetchAPI(`${basePath}/${cmd.id}`, { method: 'DELETE' }); - queryClient.invalidateQueries({ queryKey }); - alert(`Command: "${cmd.name}" was successfully deleted.`); - } catch (err) { - alert(`Error deleting command "${cmd.name}" [${err}]`); - console.log(`#DeleteCommandError`, err); - } - } + //@ts-ignore props are allowed in toasts + toast(DeleteConfirm, { props: { cmd, basePath, queryKey, duration: 6000, } }); } + + + + @@ -50,22 +48,22 @@ {/each} @@ -80,15 +78,25 @@ {:else if error} {:else} - - {#each rows as row (row.id)} + {#if rows.length == 0} + + + + {:else} + + {#each rows as row (row.id)} @@ -128,7 +136,8 @@ - {/each} + {/each} + {/if} {/if} @@ -150,7 +159,7 @@ d="M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2" /> - {:else if !loading} + {:else if !loading && !error} -
+ +
+

Site unsupported!

+

+ You appear to be using a mobile device or browser with a minimized screen size + unfortunately we do not support this screen size. + + Please use a desktop to access this site. +

+ Github for issues +
\ No newline at end of file diff --git a/src/routes/add/+page.svelte b/src/routes/add/+page.svelte new file mode 100644 index 0000000..37bc481 --- /dev/null +++ b/src/routes/add/+page.svelte @@ -0,0 +1,9 @@ + + +
+

Add

+
\ No newline at end of file diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte index cc89bfc..2972886 100644 --- a/src/routes/dashboard/+page.svelte +++ b/src/routes/dashboard/+page.svelte @@ -7,11 +7,12 @@ import { goto } from '$app/navigation'; import {browser} from "$app/environment"; import { base } from '$app/paths'; + import toast from 'svelte-french-toast'; const appInfo = get(applicationInfo); $: searchParams = browser && $page.url.searchParams - $: guildId = searchParams && searchParams.get('guildId') || ''; + $: guildId = searchParams && searchParams.get('guildId') || "global"; $: basePath = guildId && discordIdRegex.test(guildId) ? `/applications/${appInfo.id}/guilds/${guildId}/commands` @@ -20,10 +21,15 @@ let guildInput = ''; function viewGuildCommands() { - if (!discordIdRegex.test(guildInput)) return alert(`Invalid guild id`); - guildId = guildInput + if (!discordIdRegex.test(guildInput)) return toast.error(`The guild id is invalid, try again`) + toast(`Viewing guild "${guildInput}"`, { + icon: '🌏' + }) + guildId = guildInput goto(`?guildId=${guildInput}`); } + +
@@ -36,7 +42,7 @@

-
+
{#if guildId && discordIdRegex.test(guildId)}

View Global List

@@ -50,7 +56,7 @@

View Guild commands

You are currently viewing the global list. - Enter a guild id (you bot must be invited to it) + Enter a guild id (your bot must be invited to it) and click the button to manage guild specific interactions

View guild commandsView Guild Interaction {/if}
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte index 1c66207..8ca57be 100644 --- a/src/routes/login/+page.svelte +++ b/src/routes/login/+page.svelte @@ -7,6 +7,7 @@ import { discordIdRegex } from '$lib/constants'; import { getAccessToken } from '$lib/api'; import { base } from '$app/paths'; + import toast from 'svelte-french-toast'; let auth = get(authStore); @@ -19,7 +20,9 @@ async function login() { if(loginBlocked) return; - if(!discordIdRegex.test(clientId)) return alert(`Id is invalid.`) + if(!discordIdRegex.test(clientId)) { + throw new Error(`Client ID is invalid`) + } loggingIn = true; authStore.update((p) => ({ ...p, clientId, clientSecret })) try { @@ -35,15 +38,24 @@ id }); - goto(`${base}/dashboard`) + loggingIn = false; + return goto(`${base}/dashboard`) } catch(err) { console.log('Error while verifying', err) authStore.update((p) => ({ ...p, accessToken: '' })) - alert('Verification failed, try again (check your credentials)') + loggingIn = false; + throw new Error('Failed to login') + // alert('Verification failed, try again (check your credentials)') } + } - loggingIn = false; + async function LoginWrapper() { + toast.promise(login(), { + loading: 'Logging in...', + success: 'Logged in, please wait...', + error: 'Could not log in, check your credentials', + }) } onMount(() => { @@ -65,7 +77,6 @@

Get your application credentials from here discord.com/developers/applications

- - {#if loggingIn}

Please wait..., verifying credentials

{/if} +
\ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index 1e2e03f..e8b4e4a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -17,15 +17,16 @@ export default { 900: '#050507', }, blurple: { - 100: '#8D95FF', - 200: '#7E8FFC', - 300: '#6F89F9', - 400: '#6073F6', - 500: '#5865F2', // Original Color - 600: '#515BEF', - 700: '#4851EC', - 800: '#4047E9', - 900: '#333CE6', + "50": "#eef0fe", + "100": "#dee0fc", + "200": "#bcc1fa", + "300": "#9ba3f7", + "400": "#7984f5", + "500": "#5865f2", + "600": "#4651c2", + "700": "#353d91", + "800": "#232861", + "900": "#121430" }, } }
- +
-
-

(╯°□°)╯︵ ┻━┻

+
+

(╯°□°)╯︵ ┻━┻

Oops! Something went wrong.
+
+

¯\_(ツ)_/¯

+ Nothing to display here. +
+
{row.name} {typeToName(row.type)}