✨ Added custom alert-component
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<!--
|
||||
By Flowbite, but changed: https://flowbite.com/docs/components/modal/#default-modal
|
||||
-->
|
||||
<script lang="ts">
|
||||
export let title: string;
|
||||
export let body: string;
|
||||
export let open: boolean;
|
||||
console.log(open, title, body);
|
||||
open = true;
|
||||
</script>
|
||||
|
||||
<!-- Main modal -->
|
||||
{#if open}
|
||||
<div tabindex="-1" class="overflow-y-auto overflow-x-hidden md:inset-0 lg:w-2/6 w-5/6">
|
||||
<div class="relative p-4 w-full max-w-2xl h-full md:h-auto">
|
||||
<!-- Modal content -->
|
||||
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
||||
<!-- Modal header -->
|
||||
<div
|
||||
class="flex justify-between items-start p-4 rounded-t border-b dark:border-gray-600"
|
||||
>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
|
||||
{title}
|
||||
</h3>
|
||||
<button
|
||||
type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
on:click={() => {
|
||||
open = false;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Modal body -->
|
||||
<div class="p-6 space-y-6">
|
||||
<p class="text-base leading-relaxed text-gray-500 dark:text-gray-400">
|
||||
{body}
|
||||
</p>
|
||||
</div>
|
||||
<!-- Modal footer -->
|
||||
<div
|
||||
class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600"
|
||||
>
|
||||
<button
|
||||
data-modal-toggle="defaultModal"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
open = false;
|
||||
}}
|
||||
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -42,7 +42,7 @@
|
||||
</script>
|
||||
|
||||
<nav
|
||||
class="w-screen px-4 lg:px-10 py-2 flex flex-col lg:flex-row lg:items-center fixed backdrop-blur-2xl bg-white/70 shadow-md z-50 top-0"
|
||||
class="w-screen px-4 lg:px-10 py-2 flex flex-col lg:flex-row lg:items-center fixed backdrop-blur-2xl bg-white/70 shadow-md z-30 top-0"
|
||||
>
|
||||
<section class="w-full lg:w-max flex justify-between">
|
||||
<a href="/" class="font-black tracking-tight text-xl text-black marck-script link-hover"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { browser } from '$app/env';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { alertModal } from '../stores';
|
||||
|
||||
export let game_pin: string;
|
||||
|
||||
@@ -50,12 +51,20 @@
|
||||
captcha_enabled = (await res.json()).enabled;
|
||||
}
|
||||
if (res.status === 404) {
|
||||
alert('Game not found');
|
||||
alertModal.set({
|
||||
open: true,
|
||||
title: 'Game not found',
|
||||
body: 'The game pin you entered seems invalid.'
|
||||
});
|
||||
game_pin = '';
|
||||
return;
|
||||
}
|
||||
if (res.status !== 200) {
|
||||
alert('Unknown error!');
|
||||
alertModal.set({
|
||||
open: true,
|
||||
body: `Unknown error with response-code ${res.status}`,
|
||||
title: 'Unknown Error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -69,8 +78,16 @@
|
||||
if (import.meta.env.VITE_SENTRY !== null) {
|
||||
Sentry.captureException(e);
|
||||
}
|
||||
alert('Captcha failed, reloading the page probably helps!');
|
||||
window.location.reload();
|
||||
alertModal.set({
|
||||
open: true,
|
||||
body: "The captcha failed, which is normal, but most of the time it's fixed by reloading!",
|
||||
title: 'Captcha failed'
|
||||
});
|
||||
alertModal.subscribe((data) => {
|
||||
if (!data.open) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
socket.emit('join_game', {
|
||||
|
||||
@@ -3,3 +3,5 @@ import { writable } from 'svelte/store';
|
||||
export const navbarVisible = writable(true);
|
||||
export const signedIn = writable(false);
|
||||
export const pathname = writable('/');
|
||||
|
||||
export const alertModal = writable({ open: false, title: '', body: '' });
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
<script>
|
||||
import '../app.css';
|
||||
import Navbar from '$lib/navbar.svelte';
|
||||
import { navbarVisible, pathname } from '$lib/stores';
|
||||
import { navbarVisible, pathname, alertModal } from '$lib/stores';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { BrowserTracing } from '@sentry/tracing';
|
||||
import { initLocalizationContext } from '$lib/i18n';
|
||||
import { browser } from '$app/env';
|
||||
import Alert from '$lib/modals/alert.svelte';
|
||||
|
||||
if (browser) {
|
||||
pathname.set(window.location.pathname);
|
||||
@@ -64,6 +65,17 @@
|
||||
{:else}
|
||||
<slot />
|
||||
{/if}
|
||||
{#if $alertModal.open}
|
||||
<div
|
||||
class="fixed inset-0 h-screen w-screen bg-black z-30 bg-opacity-60 flex items-center justify-center content-center"
|
||||
>
|
||||
<Alert
|
||||
bind:title={$alertModal.title}
|
||||
bind:body={$alertModal.body}
|
||||
bind:open={$alertModal.open}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
:global(html:not(.dark)) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { getLocalization } from '$lib/i18n';
|
||||
import { navbarVisible } from '$lib/stores';
|
||||
import { navbarVisible, alertModal } from '$lib/stores';
|
||||
|
||||
navbarVisible.set(true);
|
||||
|
||||
@@ -50,9 +50,17 @@
|
||||
if (res.status === 200) {
|
||||
window.location.href = '/overview';
|
||||
} else if (res.status === 400) {
|
||||
alert("This quiz isn't (yet) supported!");
|
||||
alertModal.set({
|
||||
open: true,
|
||||
title: 'Import failed',
|
||||
body: "This quiz isn't (yet) supported!"
|
||||
});
|
||||
} else {
|
||||
alert('Error importing quiz');
|
||||
alertModal.set({
|
||||
open: true,
|
||||
title: 'Import failed',
|
||||
body: 'Unknown error while importing the quiz!'
|
||||
});
|
||||
}
|
||||
is_loading = false;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { DateTime } from 'luxon';
|
||||
import { getLocalization } from '$lib/i18n';
|
||||
import Footer from '$lib/footer.svelte';
|
||||
import { navbarVisible, signedIn } from '$lib/stores';
|
||||
import { alertModal, navbarVisible, signedIn } from '$lib/stores';
|
||||
|
||||
interface QuizData {
|
||||
id: string;
|
||||
@@ -60,9 +60,14 @@
|
||||
}
|
||||
|
||||
if (res.status !== 200) {
|
||||
alert('Failed to start game!');
|
||||
console.error(`Failed to start game, ${await res.text()}`);
|
||||
window.location.replace('/account/login?returnTo=/overview');
|
||||
alertModal.set({
|
||||
open: true,
|
||||
title: 'Start failed',
|
||||
body: `Failed to start game, ${await res.text()}`
|
||||
});
|
||||
alertModal.subscribe((_) => {
|
||||
window.location.replace('/account/login?returnTo=/overview');
|
||||
});
|
||||
}
|
||||
const data = await res.json();
|
||||
// eslint-disable-next-line no-undef
|
||||
|
||||
Reference in New Issue
Block a user