mirror of
https://github.com/simple-login/app.git
synced 2024-11-18 06:31:27 +08:00
118 lines
No EOL
3.9 KiB
HTML
118 lines
No EOL
3.9 KiB
HTML
<footer class="footer">
|
|
<div class="container">
|
|
<div class="row align-items-center flex-row-reverse">
|
|
<div class="col-auto ml-lg-auto">
|
|
<div class="row align-items-center">
|
|
<div class="col-auto">
|
|
<ul class="list-inline list-inline-dots mb-0">
|
|
<li class="list-inline-item"><a href="https://simplelogin.io" target="_blank">
|
|
Website <i class="fe fe-external-link"></i>
|
|
</a></li>
|
|
<li class="list-inline-item"><a href="https://trello.com/b/4d6A69I4/open-roadmap" target="_blank">
|
|
Feature Requests <i class="fe fe-external-link"></i>
|
|
</a></li>
|
|
<li class="list-inline-item"><a href="https://docs.simplelogin.io" target="_blank">
|
|
Dev Documentation <i class="fe fe-external-link"></i>
|
|
</a></li>
|
|
<li class="list-inline-item"><a href="https://status.simplelogin.io" target="_blank">
|
|
Uptime <i class="fe fe-external-link"></i>
|
|
</a></li>
|
|
<li class="list-inline-item"><a href="mailto:hi@simplelogin.io">Contact Us
|
|
<i class="fe fe-external-link"></i></a></li>
|
|
<li class="list-inline-item intro-step-0">
|
|
<a onclick="startIntro()"
|
|
data-intro="Welcome to SimpleLogin! <br><br>
|
|
It seems that this is the first time you are here,
|
|
let's walk through some SimpleLogin features together! <br><br>
|
|
You can always show this tutorial again any time by clicking on this <i class='fe fe-help-circle'></i> icon below 👇"
|
|
data-step="1"
|
|
><i class="fe fe-help-circle"></i></a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center">
|
|
Copyright © {{ YEAR }}
|
|
<a href="https://simplelogin.io" target="_blank">SimpleLogin</a>.
|
|
All rights reserved.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
function startIntro() {
|
|
introJs().setOption('showProgress', true).start();
|
|
introJs().start();
|
|
}
|
|
</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> |