Skip to content

Commit 52cbcf2

Browse files
refactor(ui): improve Home page text and styling
1 parent 9884845 commit 52cbcf2

File tree

3 files changed

+285
-95
lines changed

3 files changed

+285
-95
lines changed

ui/src/views/Home.vue

Lines changed: 145 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,146 @@
11
<template>
2-
<v-row v-if="!hasStatus">
3-
<v-col cols="12" md="4" class="pt-0" v-for="(item, index) in items" :key="index">
4-
<div data-test="home-card">
5-
<StatCard
6-
:title="item.title"
7-
:content="item.content"
8-
:icon="item.icon"
9-
:buttonLabel="item.buttonLabel"
10-
:path="item.path"
11-
:stat="item.stat"
12-
/>
13-
</div>
14-
</v-col>
15-
</v-row>
2+
<div v-if="!hasStatus">
3+
<!-- Namespace Info Card -->
4+
<v-row>
5+
<v-col cols="12">
6+
<v-card class="bg-transparent mb-6" elevation="0" rounded="0">
7+
<v-row>
8+
<v-col cols="12" md="6">
9+
<div class="d-flex align-start">
10+
<v-avatar color="primary" size="48" class="mr-4">
11+
<v-icon size="32">mdi-home</v-icon>
12+
</v-avatar>
13+
<div>
14+
<div class="text-overline text-medium-emphasis mb-1">Home</div>
15+
<div class="text-h5 font-weight-bold mb-2">{{ namespace.name }}</div>
16+
<div class="text-body-2 text-medium-emphasis">
17+
This is your active namespace. All devices, sessions and configurations are isolated within this namespace.
18+
</div>
19+
</div>
20+
</div>
21+
</v-col>
22+
<v-col cols="12" md="6">
23+
<v-card class="pa-4" variant="tonal">
24+
<div class="text-overline text-medium-emphasis mb-2">TENANT ID</div>
25+
<div class="d-flex align-center justify-space-between">
26+
<code class="text-primary">{{ namespace.tenant_id }}</code>
27+
<CopyWarning :copied-item="'Tenant ID'">
28+
<template #default="{ copyText }">
29+
<v-btn
30+
@click="copyText(namespace.tenant_id)"
31+
color="primary"
32+
variant="elevated"
33+
size="small"
34+
prepend-icon="mdi-content-copy"
35+
>
36+
Copy
37+
</v-btn>
38+
</template>
39+
</CopyWarning>
40+
</div>
41+
<div class="text-caption text-medium-emphasis mt-2">
42+
Use this ID to register new devices to this namespace
43+
</div>
44+
</v-card>
45+
</v-col>
46+
</v-row>
47+
</v-card>
48+
</v-col>
49+
</v-row>
50+
51+
<!-- Devices Section -->
52+
<v-row>
53+
<v-col cols="12" class="d-flex align-center mb-2">
54+
<v-icon class="mr-2">mdi-devices</v-icon>
55+
<h2 class="text-h6">Devices</h2>
56+
</v-col>
57+
</v-row>
58+
59+
<v-row>
60+
<!-- Accepted Devices Card -->
61+
<v-col cols="12" md="3">
62+
<v-card class="pa-6 bg-v-theme-surface text-center h-100" border>
63+
<v-avatar color="primary" size="64" class="mb-4">
64+
<v-icon size="40">mdi-check</v-icon>
65+
</v-avatar>
66+
67+
<div class="text-overline text-medium-emphasis mb-2">ACCEPTED DEVICES</div>
68+
<div class="text-h2 font-weight-bold mb-4">{{ stats.registered_devices || 0 }}</div>
69+
70+
<v-btn
71+
variant="text"
72+
color="primary"
73+
size="small"
74+
:to="'/devices'"
75+
block
76+
>
77+
View all devices
78+
</v-btn>
79+
</v-card>
80+
</v-col>
81+
82+
<!-- Online Devices Card -->
83+
<v-col cols="12" md="3">
84+
<v-card class="pa-6 bg-v-theme-surface text-center h-100" border>
85+
<v-avatar color="primary" size="64" class="mb-4">
86+
<v-icon size="40">mdi-lan-connect</v-icon>
87+
</v-avatar>
88+
89+
<div class="text-overline text-medium-emphasis mb-2">ONLINE DEVICES</div>
90+
<div class="text-h2 font-weight-bold mb-4">{{ stats.online_devices || 0 }}</div>
91+
92+
<v-btn
93+
variant="text"
94+
color="primary"
95+
size="small"
96+
:to="'/devices'"
97+
block
98+
>
99+
View Online Devices
100+
</v-btn>
101+
</v-card>
102+
</v-col>
103+
104+
<!-- Pending Devices Card -->
105+
<v-col cols="12" md="3">
106+
<v-card class="pa-6 bg-v-theme-surface text-center h-100" border>
107+
<v-avatar color="primary" size="64" class="mb-4">
108+
<v-icon size="40">mdi-clock-outline</v-icon>
109+
</v-avatar>
110+
111+
<div class="text-overline text-medium-emphasis mb-2">PENDING DEVICES</div>
112+
<div class="text-h2 font-weight-bold mb-4">{{ stats.pending_devices || 0 }}</div>
113+
114+
<v-btn
115+
variant="text"
116+
color="primary"
117+
size="small"
118+
:to="'/devices/pending'"
119+
block
120+
>
121+
Approve Devices
122+
</v-btn>
123+
</v-card>
124+
</v-col>
125+
126+
<!-- Connect Device Card -->
127+
<v-col cols="12" md="3">
128+
<v-card class="pa-6 bg-transparent text-center h-100 border border-dashed">
129+
<v-avatar color="surface-variant" size="64" class="mb-4" theme="dark">
130+
<v-icon size="40" color="primary">mdi-developer-board</v-icon>
131+
</v-avatar>
132+
133+
<div class="text-h6 font-weight-bold mb-2">Add a new device</div>
134+
<div class="text-body-2 text-medium-emphasis mb-4">
135+
Register new devices to this namespace and start managing remote connections
136+
</div>
137+
138+
<DeviceAdd />
139+
</v-card>
140+
</v-col>
141+
</v-row>
142+
143+
</div>
16144
<v-card data-test="home-failed" class="mt-2 pa-4 bg-v-theme-surface" v-else>
17145
<p class="text-center">Something is wrong, try again !</p>
18146
</v-card>
@@ -21,47 +149,21 @@
21149
<script setup lang="ts">
22150
import { computed, onMounted, ref } from "vue";
23151
import axios, { AxiosError } from "axios";
24-
import { StatCardItem } from "@/interfaces/IStats";
25-
import StatCard from "@/components/StatCard.vue";
26152
import handleError from "@/utils/handleError";
27153
import useSnackbar from "@/helpers/snackbar";
28154
import useNamespacesStore from "@/store/modules/namespaces";
29155
import useStatsStore from "@/store/modules/stats";
156+
import DeviceAdd from "@/components/Devices/DeviceAdd.vue";
157+
import CopyWarning from "@/components/User/CopyWarning.vue";
30158
31159
const namespacesStore = useNamespacesStore();
32160
const statsStore = useStatsStore();
33161
const snackbar = useSnackbar();
34162
const hasStatus = ref(false);
35163
const stats = computed(() => statsStore.stats);
164+
const namespace = computed(() => namespacesStore.currentNamespace);
36165
const hasNamespace = computed(() => namespacesStore.namespaceList.length !== 0);
37166
38-
const items = computed<StatCardItem[]>(() => [
39-
{
40-
title: "Registered Devices",
41-
content: "Registered devices into the tenancy account",
42-
icon: "mdi-developer-board",
43-
buttonLabel: "Add Device",
44-
path: "devices",
45-
stat: stats.value.registered_devices || 0,
46-
},
47-
{
48-
title: "Online Devices",
49-
content: "Devices are online and ready for connecting",
50-
icon: "mdi-developer-board",
51-
buttonLabel: "View all Devices",
52-
path: "devices",
53-
stat: stats.value.online_devices || 0,
54-
},
55-
{
56-
title: "Active Sessions",
57-
content: "Active SSH Sessions opened by users",
58-
icon: "mdi-developer-board",
59-
buttonLabel: "View all Sessions",
60-
path: "sessions",
61-
stat: stats.value.active_sessions || 0,
62-
},
63-
]);
64-
65167
onMounted(async () => {
66168
if (!hasNamespace.value) return;
67169

ui/tests/views/Home.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ describe("Home", () => {
7777
});
7878

7979
it("Renders the template with data", async () => {
80-
expect(wrapper.find('[data-test="home-card"]').exists()).toBe(true);
80+
expect(wrapper.text()).toContain("ACCEPTED DEVICES");
81+
expect(wrapper.text()).toContain("ONLINE DEVICES");
82+
expect(wrapper.text()).toContain("PENDING DEVICES");
8183
wrapper.vm.hasStatus = true; // Set the conditional validation to true so it can show the error card.
8284
await nextTick();
8385
expect(wrapper.find('[data-test="home-failed"]').exists()).toBe(true);

0 commit comments

Comments
 (0)