redo of frontend style part 1

This commit is contained in:
“Niklas” 2024-10-10 12:01:08 +02:00
parent 4faf14c518
commit 2e2437660b
5 changed files with 312 additions and 100 deletions

View file

@ -29,5 +29,6 @@
"vite": "^5.1.5",
"vite-plugin-vuetify": "^2.0.3",
"vue-tsc": "^2.0.6"
}
},
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
}

View file

@ -1,12 +1,15 @@
<template>
<v-app>
<v-main>
<!-- <div v-if="store.token === null">
<!--
<div v-if="store.token === null">
<loginPage />
</div>
<div v-else> -->
<div v-else>
<MainPage />
<!--</div>-->
</div>
-->
<MainPage />
</v-main>
</v-app>
</template>
@ -21,6 +24,6 @@ import { store } from "./store";
html,
body,
main {
background-color: #e3e3e3;
background-color: #2B3037;
}
</style>

View file

@ -1,95 +1,67 @@
<template>
<div>
<HeaderBar />
<div class="ma-8">
<div v-if="isPending">Loading...</div>
<ul v-else-if="data">
<li v-for="nodeGroup in data" :key="nodeGroup.groupId">
<CategoryContainer :nodeGroup="nodeGroup" />
</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import HeaderBar from "./HeaderBar.vue";
import CategoryContainer from "./CategoryContainer.vue";
import { useQuery } from "@tanstack/vue-query";
import { axiosInstance } from "@/client";
import { NodeGroup } from "@/types";
import { search, key } from "@/store";
import MiniSearch from "minisearch";
import { computed, provide } from "vue";
const mockNodeGroups: NodeGroup[] = [
{
groupId: "group-1",
name: "Test Node Group 1",
nodes: [
{
uuid: "123e4567-e89b-12d3-a456-426614174000",
name: "Sensor Node A1",
status: 502,
coordla: 52.5200,
coordlong: 13.4050,
temperature: 22.5,
battery: 85,
runtime: 120,
},
{
uuid: "223e4567-e89b-12d3-a456-426614174001",
name: "Sensor Node A2",
status: 200,
coordla: 48.8566,
coordlong: 2.3522,
temperature: 20.0,
battery: 90,
runtime: 100,
},
]
},
];
const { isPending, isError, data, error } = useQuery({
queryKey: ["nodeGroups"],
queryFn: async () => {
//hier der API-Call für die Daten
return mockNodeGroups;
},
refetchInterval: 1 * 1,
});
const searchEngine = computed(() => {
const minisearch = new MiniSearch({
fields: ["name", "groupId"],
searchOptions: {
boost: { name: 2 },
prefix: true,
},
});
if (data.value) {
minisearch.addAll(data.value);
}
return minisearch;
});
const searching = computed(() => search.value !== "");
const visibleIds = computed(() => {
return searching.value ? searchEngine.value.search(search.value).map(result => result.groupId) : [];
});
provide(key, {
visibleIds,
searching,
});
</script>
<style scoped>
li,
ul {
list-style-type: none;
}
</style>
<template>
<div>
<HeaderBar />
<div style="margin: 15px">
<TableCategory></TableCategory>
</div>
</div>
</template>
<script setup lang="ts">
import HeaderBar from "./HeaderBar.vue";
import CategoryContainer from "./CategoryContainer.vue";
import { useQuery } from "@tanstack/vue-query";
import { axiosInstance } from "@/client";
import { LicenseGroup, License } from "@/types";
import { search, key } from "@/store";
import MiniSearch from "minisearch";
import { computed, provide } from "vue";
import TableCategory from "./TableCategory.vue";
const { isPending, isError, data, error } = useQuery({
queryKey: ["licenses"],
queryFn: async () => {
const res = await axiosInstance.get<LicenseGroup[]>("/licenses");
console.log(res.data);
return res.data;
},
refetchInterval: 60 * 1000,
});
const searchEngine = computed(() => {
let minisearch = new MiniSearch({
fields: ["name", "description", "id"],
searchOptions: {
boost: { name: 2 },
prefix: true,
},
});
let licenses: License[] = [];
data.value?.forEach((group) => {
group.licenses.forEach((license) => licenses.push(license));
});
console.log(licenses);
minisearch.addAll(licenses);
return minisearch;
});
const searching = computed(() => search.value !== "");
const visibleIds = computed(() => {
return searchEngine.value.search(search.value).map((searchResult) => {
return searchResult.id;
});
});
provide(key, {
visibleIds,
searching,
});
</script>
<style scoped>
li,
ul {
list-style-type: none;
}
</style>

View file

@ -0,0 +1,141 @@
<template>
<div class="table-container">
<table class="responsive-table">
<thead>
<tr>
<th>Node/Name</th>
<th>Status</th>
<th>Latitude</th> <!-- Separate column for Latitude -->
<th>Longitude</th> <!-- Separate column for Longitude -->
<th>Battery</th>
<th>Gemessene - Temperatur</th>
<th>Laufzeit</th>
</tr>
</thead>
<tbody>
<tr v-for="(node, index) in tableData" :key="index">
<td>{{ node.name }}</td>
<td>
<span :class="node.status === 'ONLINE' ? 'status-online' : 'status-offline'">
{{ node.status }}
</span>
</td>
<td>{{ node.position.lat }}</td>
<td>{{ node.position.lng }}</td>
<td>{{ node.battery }}%</td>
<td>{{ node.temperature }}°C</td>
<td>{{ node.runtime }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "ONLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 98,
temperature: 100,
runtime: "12h 30m 12s",
},
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "OFFLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 19,
temperature: 100,
runtime: "30m",
},
{
name: "Localnode-3",
status: "ONLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 66,
temperature: 100,
runtime: "12h 30m 12s",
},
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "ONLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 79,
temperature: 100,
runtime: "12h 30m 12s",
},
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "ONLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 10,
temperature: 100,
runtime: "12h 30m 12s",
},
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "OFFLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 0,
temperature: 100,
runtime: "12h 30m 12s",
},
{
name: "XXXX-XXXX-XXXX-XXXX",
status: "ONLINE",
position: { lat: 40.7128, lng: 74.0012 },
battery: 56,
temperature: 100,
runtime: "12h 30m 12s",
},
],
};
},
};
</script>
<style scoped>
.table-container {
background-color: white;
padding: 0.5rem 1rem; /* Reduce top padding to 0.5rem */
margin: 0 auto; /* Remove margin at the top, keep it centered horizontally */
width: 100%; /* Full width of parent */
overflow-x: auto; /* Allow horizontal scroll if necessary */
}
.responsive-table {
width: 100%; /* Full width */
border-collapse: collapse; /* Ensure tight borders */
margin: 0; /* Remove margin at the top of the table */
table-layout: auto; /* Auto layout for slimmer columns */
}
.responsive-table th,
.responsive-table td {
padding: 0.5rem; /* Maintain slim padding */
text-align: center; /* Center text */
border-bottom: 1px solid #ddd;
}
.responsive-table th {
font-weight: bold;
}
.responsive-table tr:nth-child(even) {
background-color: #f9f9f9; /* Striped rows */
}
.status-online {
color: green;
font-weight: bold;
}
.status-offline {
color: red;
font-weight: bold;
}
</style>

View file

@ -0,0 +1,95 @@
<template>
<div>
<HeaderBar />
<div class="ma-8">
<div v-if="isPending">Loading...</div>
<ul v-else-if="data">
<li v-for="nodeGroup in data" :key="nodeGroup.groupId">
<CategoryContainer :nodeGroup="nodeGroup" />
</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import HeaderBar from "./HeaderBar.vue";
import CategoryContainer from "./CategoryContainer.vue";
import { useQuery } from "@tanstack/vue-query";
import { axiosInstance } from "@/client";
import { NodeGroup } from "@/types";
import { search, key } from "@/store";
import MiniSearch from "minisearch";
import { computed, provide } from "vue";
const mockNodeGroups: NodeGroup[] = [
{
groupId: "group-1",
name: "Test Node Group 1",
nodes: [
{
uuid: "123e4567-e89b-12d3-a456-426614174000",
name: "Sensor Node A1",
status: 502,
coordla: 52.5200,
coordlong: 13.4050,
temperature: 22.5,
battery: 85,
runtime: 120,
},
{
uuid: "223e4567-e89b-12d3-a456-426614174001",
name: "Sensor Node A2",
status: 200,
coordla: 48.8566,
coordlong: 2.3522,
temperature: 20.0,
battery: 90,
runtime: 100,
},
]
},
];
const { isPending, isError, data, error } = useQuery({
queryKey: ["nodeGroups"],
queryFn: async () => {
//hier der API-Call für die Daten
return mockNodeGroups;
},
refetchInterval: 1 * 1,
});
const searchEngine = computed(() => {
const minisearch = new MiniSearch({
fields: ["name", "groupId"],
searchOptions: {
boost: { name: 2 },
prefix: true,
},
});
if (data.value) {
minisearch.addAll(data.value);
}
return minisearch;
});
const searching = computed(() => search.value !== "");
const visibleIds = computed(() => {
return searching.value ? searchEngine.value.search(search.value).map(result => result.groupId) : [];
});
provide(key, {
visibleIds,
searching,
});
</script>
<style scoped>
li,
ul {
list-style-type: none;
}
</style>