mirror of
https://github.com/simple-login/app.git
synced 2025-10-06 05:17:41 +08:00
display notifications. user can mark a notification as read.
This commit is contained in:
parent
95c5cb8452
commit
b01c91423f
3 changed files with 102 additions and 1 deletions
|
@ -710,7 +710,6 @@
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='node_modules/vue/dist/vue.min.js') }}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
el: '#filter-app',
|
el: '#filter-app',
|
||||||
|
|
|
@ -46,3 +46,73 @@
|
||||||
introJs().start();
|
introJs().start();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="{{ url_for('static', filename='node_modules/vue/dist/vue.min.js') }}"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#notification-app',
|
||||||
|
delimiters: ["[[", "]]"], // necessary to avoid conflict with jinja
|
||||||
|
data: {
|
||||||
|
notifications: [],
|
||||||
|
page: 0,
|
||||||
|
loading: true,
|
||||||
|
canLoadMore: true
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
has_non_read_notification: function () {
|
||||||
|
for (let i = 0; i < this.notifications.length; i++) {
|
||||||
|
if (!this.notifications[i].read) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
markAsRead: async function (notification) {
|
||||||
|
notification.read = true;
|
||||||
|
let res = await fetch(`/api/notifications/${notification.id}/read`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMore: async function () {
|
||||||
|
let that = this;
|
||||||
|
that.page += 1;
|
||||||
|
|
||||||
|
let res = await fetch(`/api/notifications?page=${that.page}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
let json = await res.json();
|
||||||
|
if (json.length == 0) that.canLoadMore = false;
|
||||||
|
that.notifications = that.notifications.concat(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
let that = this;
|
||||||
|
let res = await fetch(`/api/notifications?page=${that.page}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
let json = await res.json();
|
||||||
|
that.notifications = json;
|
||||||
|
that.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -15,6 +15,38 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<div id="notification-app" class="dropdown d-none d-md-flex">
|
||||||
|
<a class="nav-link icon" data-toggle="collapse" href="#notifications" style="height: 100%">
|
||||||
|
<i class="fe fe-bell"></i>
|
||||||
|
<span v-if="has_non_read_notification" class="nav-unread"></span>
|
||||||
|
<span v-else class="nav-read"></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow collapse" id="notifications">
|
||||||
|
<div v-if="loading">Loading ...</div>
|
||||||
|
<div class="dropdown-item d-flex" v-for="notification in notifications">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div v-html="notification.message"
|
||||||
|
style="width: 40em; word-wrap:break-word; white-space: normal"></div>
|
||||||
|
<div class="small text-muted">
|
||||||
|
[[notification.created_at]]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!notification.read">
|
||||||
|
<i class="fe fe-check"
|
||||||
|
@click="markAsRead(notification)"
|
||||||
|
data-toggle="tooltip" title="mark as read"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button v-if="canLoadMore" @click="loadMore()" class="btn btn-link">Load more</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<a href="#" class="nav-link pr-0 leading-none" data-toggle="dropdown">
|
<a href="#" class="nav-link pr-0 leading-none" data-toggle="dropdown">
|
||||||
{% if current_user.profile_picture_id %}
|
{% if current_user.profile_picture_id %}
|
||||||
|
|
Loading…
Add table
Reference in a new issue