mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-06 00:47:09 +00:00
add Notifications
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { fade } from "svelte/transition";
|
||||||
|
import Button from "./Button.svelte";
|
||||||
|
import { X } from "lucide-svelte";
|
||||||
|
import { notifications } from "../ts/stores/notification";
|
||||||
|
import { get_shifted_color } from "../ts/stores/ui_behavior";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="fixed flex flex-col gap-2 {true ? "top-[41%]": "top-2"} right-2 left-2 md:top-auto md:left-auto md:bottom-2 md:w-100 z-50">
|
||||||
|
{#each $notifications as n (n.id)}
|
||||||
|
<div
|
||||||
|
transition:fade={{ duration: 200 }}
|
||||||
|
class="p-2 pl-4 pb-3 rounded-lg shadow-xl/30 text-white flex flex-col gap-2 overflow-hidden relative border-1 border-black/20 {n.className}"
|
||||||
|
class:bg-red-900={n.type === "error"}
|
||||||
|
class:bg-green-900={n.type === "success"}
|
||||||
|
class:bg-sky-900={n.type === "info"}
|
||||||
|
style="--dur: {n.duration}ms"
|
||||||
|
>
|
||||||
|
<div class="flex flex-row justify-between">
|
||||||
|
<span class="text-xl font-bold flex items-center">{n.title}</span>
|
||||||
|
<Button click_function={() => notifications.remove(n.id)} className="p-2" bg="bg-stone-900/50" hover_bg="bg-stone-600/70" active_bg="bg-stone-500/80"><X/></Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span>{n.message}</span>
|
||||||
|
|
||||||
|
<div class="absolute inset-x-0 bottom-0 h-1 bg-white/25">
|
||||||
|
<div
|
||||||
|
class="block h-full w-full bg-white/80 origin-left animate-progress-bar"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@keyframes progress {
|
||||||
|
from {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animate-progress-bar {
|
||||||
|
animation: progress var(--dur) linear forwards;
|
||||||
|
transform-origin: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
import Notification from '../components/Notification.svelte';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|
||||||
|
<Notification />
|
||||||
@@ -213,5 +213,8 @@ module.exports = {
|
|||||||
|
|
||||||
'hover:bg-red-400',
|
'hover:bg-red-400',
|
||||||
'active:bg-red-500',
|
'active:bg-red-500',
|
||||||
|
|
||||||
|
'hover:bg-stone-600/70',
|
||||||
|
'active:bg-stone-500/80',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { get, writable } from "svelte/store";
|
||||||
|
|
||||||
|
export type Notification = {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
message: string;
|
||||||
|
duration: number;
|
||||||
|
className: string;
|
||||||
|
type?: "error" | "success" | "info";
|
||||||
|
};
|
||||||
|
|
||||||
|
function createNotifications() {
|
||||||
|
const { subscribe, update } = writable<Notification[]>([]);
|
||||||
|
|
||||||
|
function push(type: "error" | "success" | "info", title: string, message: string = "", className: string = "") {
|
||||||
|
const id = Date.now();
|
||||||
|
const duration = type === "error" ? 8000 : 4000;
|
||||||
|
update((n) => [...n, { id, title, message, duration, className, type }]);
|
||||||
|
setTimeout(() => {
|
||||||
|
update((n) => n.filter((x) => x.id !== id));
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
const remove = (id: number) => update(n => n.filter(x => x.id !== id));
|
||||||
|
|
||||||
|
return { subscribe, push, remove };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const notifications = createNotifications();
|
||||||
Reference in New Issue
Block a user