app/templates/footer.html

122 lines
No EOL
4.1 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: false,
showNotification: false,
},
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();
that.canLoadMore = json.more;
that.notifications = that.notifications.concat(json.notifications);
}
}
},
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.notifications;
that.loading = false;
that.canLoadMore = json.more
if (that.notifications.length > 0)
that.showNotification = true;
}
}
})
</script>