aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dashboard/src/App.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dashboard/src/App.vue')
-rw-r--r--apps/dashboard/src/App.vue126
1 files changed, 126 insertions, 0 deletions
diff --git a/apps/dashboard/src/App.vue b/apps/dashboard/src/App.vue
new file mode 100644
index 00000000000..87c76a603b4
--- /dev/null
+++ b/apps/dashboard/src/App.vue
@@ -0,0 +1,126 @@
+<template>
+ <div id="app-dashboard">
+ <h2>{{ greeting.icon }} {{ greeting.text }}</h2>
+
+ <div class="panels">
+ <div v-for="panel in panels" :key="panel.id" class="panel">
+ <a :href="panel.url">
+ <h3 :class="panel.iconClass">
+ {{ panel.title }}
+ </h3>
+ </a>
+ <div :ref="panel.id" :data-id="panel.id" />
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import { loadState } from '@nextcloud/initial-state'
+import { getCurrentUser } from '@nextcloud/auth'
+
+const panels = loadState('dashboard', 'panels')
+
+export default {
+ name: 'App',
+ data() {
+ return {
+ timer: new Date(),
+ callbacks: {},
+ panels,
+ name: getCurrentUser()?.displayName,
+ }
+ },
+ computed: {
+ greeting() {
+ const time = this.timer.getHours()
+
+ if (time > 18) {
+ return { icon: '🌙', text: t('dashboard', 'Good evening, {name}', { name: this.name }) }
+ }
+ if (time > 12) {
+ return { icon: '☀', text: t('dashboard', 'Good afternoon, {name}', { name: this.name }) }
+ }
+ if (time === 12) {
+ return { icon: '🍽', text: t('dashboard', 'Time for lunch, {name}', { name: this.name }) }
+ }
+ if (time > 5) {
+ return { icon: '🌄', text: t('dashboard', 'Good morning, {name}', { name: this.name }) }
+ }
+ return { icon: '🦉', text: t('dashboard', 'Have a night owl, {name}', { name: this.name }) }
+ },
+ },
+ watch: {
+ callbacks() {
+ for (const app in this.callbacks) {
+ const element = this.$refs[app]
+ if (this.panels[app].mounted) {
+ continue
+ }
+
+ if (element) {
+ this.callbacks[app](element[0])
+ Vue.set(this.panels[app], 'mounted', true)
+ } else {
+ console.error('Failed to register panel in the frontend as no backend data was provided for ' + app)
+ }
+ }
+ },
+ },
+ mounted() {
+ setInterval(() => {
+ this.timer = new Date()
+ }, 30000)
+ },
+ methods: {
+ register(app, callback) {
+ Vue.set(this.callbacks, app, callback)
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+ #app-dashboard {
+ width: 100%;
+ }
+ h2 {
+ text-align: center;
+ font-size: 32px;
+ line-height: 130%;
+ padding: 80px 16px 32px;
+ }
+
+ .panels {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ flex-direction: row;
+ align-items: flex-start;
+ flex-wrap: wrap;
+ }
+
+ .panel {
+ width: 250px;
+ margin: 16px;
+
+ & > a {
+ position: sticky;
+ top: 50px;
+ display: block;
+ background: linear-gradient(var(--color-main-background-translucent), var(--color-main-background-translucent) 80%, rgba(255, 255, 255, 0));
+ backdrop-filter: blur(4px);
+
+ h3 {
+ margin: 0;
+ font-size: 20px;
+ font-weight: bold;
+ background-size: 32px;
+ background-position: 10px 10px;
+ padding: 16px 8px 16px 52px;
+ }
+ }
+ }
+
+</style>