Add toast notifications
This commit is contained in:
14
app/components/toast.gjs
Normal file
14
app/components/toast.gjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import Component from '@glimmer/component';
|
||||||
|
import { service } from '@ember/service';
|
||||||
|
|
||||||
|
export default class ToastComponent extends Component {
|
||||||
|
@service toast;
|
||||||
|
|
||||||
|
<template>
|
||||||
|
{{#if this.toast.isVisible}}
|
||||||
|
<div class="toast-notification">
|
||||||
|
{{this.toast.message}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
}
|
||||||
21
app/services/toast.js
Normal file
21
app/services/toast.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import Service from '@ember/service';
|
||||||
|
import { tracked } from '@glimmer/tracking';
|
||||||
|
|
||||||
|
export default class ToastService extends Service {
|
||||||
|
@tracked message = null;
|
||||||
|
@tracked isVisible = false;
|
||||||
|
timeoutId = null;
|
||||||
|
|
||||||
|
show(message, duration = 3000) {
|
||||||
|
this.message = message;
|
||||||
|
this.isVisible = true;
|
||||||
|
|
||||||
|
if (this.timeoutId) {
|
||||||
|
clearTimeout(this.timeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.timeoutId = setTimeout(() => {
|
||||||
|
this.isVisible = false;
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1321,3 +1321,36 @@ button.create-place {
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Toast Notification */
|
||||||
|
.toast-notification {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 2rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: rgb(51 51 51 / 85%);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
color: white;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
z-index: 9999;
|
||||||
|
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
|
||||||
|
animation: fade-in-up 0.3s ease-out forwards;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 90%;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-up {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-50%, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { pageTitle } from 'ember-page-title';
|
|||||||
import Map from '#components/map';
|
import Map from '#components/map';
|
||||||
import AppHeader from '#components/app-header';
|
import AppHeader from '#components/app-header';
|
||||||
import AppMenu from '#components/app-menu/index';
|
import AppMenu from '#components/app-menu/index';
|
||||||
|
import Toast from '#components/toast';
|
||||||
import { service } from '@ember/service';
|
import { service } from '@ember/service';
|
||||||
import { tracked } from '@glimmer/tracking';
|
import { tracked } from '@glimmer/tracking';
|
||||||
import { action } from '@ember/object';
|
import { action } from '@ember/object';
|
||||||
@@ -89,6 +90,8 @@ export default class ApplicationComponent extends Component {
|
|||||||
<AppMenu @onClose={{this.closeAppMenu}} />
|
<AppMenu @onClose={{this.closeAppMenu}} />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<Toast />
|
||||||
|
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
</template>
|
</template>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user