Implement chargepoint list route

This commit is contained in:
Oliver Traber 2025-04-27 13:56:20 +00:00 committed by BluemediaDev
parent 8e42205301
commit 1c810e6293
Signed by: Bluemedia
GPG key ID: C0674B105057136C
5 changed files with 178 additions and 0 deletions

View file

@ -0,0 +1,19 @@
export type ChargePoint = {
identity: string;
is_active: boolean;
price: number;
id: string;
last_seen: string;
vendor_name: string;
model: string;
serial_number: string,
firmware_version: string;
connectors: [
{
id: string;
evse: number;
index: number;
status: 'Available' | 'Occupied' | 'Reserved' | 'Unavailable' | 'Faulted'
}
]
}

View file

@ -8,3 +8,22 @@ export const currentDaytime = function(): string {
}
return 'evening'
}
export function relativeTimeFromDate(date: Date): {val: number, range: Intl.RelativeTimeFormatUnit} | undefined {
const units: {unit: Intl.RelativeTimeFormatUnit; ms: number}[] = [
{unit: "year", ms: 31536000000},
{unit: "month", ms: 2628000000},
{unit: "day", ms: 86400000},
{unit: "hour", ms: 3600000},
{unit: "minute", ms: 60000},
{unit: "second", ms: 1000},
];
const elapsed = date.getTime() - new Date().getTime();
for (const {unit, ms} of units) {
if (Math.abs(elapsed) >= ms || unit === "second") {
return {val: Math.round(elapsed / ms), range: unit};
}
}
return undefined;
}

View file

@ -0,0 +1,106 @@
<script lang="ts">
import axios from '$lib/axios.svelte'
import i18n from '$lib/i18n'
import type { ChargePoint } from '$lib/types/chargepoint'
import { relativeTimeFromDate } from '$lib/util'
import { onMount } from 'svelte'
$i18n.loadNamespaces('chargepoint')
let chargepoints: ChargePoint[] = $state([])
const pageSize = 25
let page: number = $state(1)
const urlParams = new URLSearchParams(window.location.search)
if (urlParams.has('page')) {
page = Number.parseInt(urlParams.get('page')!)
}
function load() {
axios
.get('/chargepoints', { params: { skip: (page - 1) * pageSize, limit: pageSize } })
.then((res) => {
chargepoints = res.data
})
}
function nextPage() {
++page
load()
}
function previousPage() {
--page
load()
}
onMount(() => {
load()
})
</script>
<div class="w-full h-full mt-4 flex flex-col">
<p class="w-full text-2xl font-bold">
{$i18n.t('chargepoint:header')}
</p>
<div class="overflow-x-auto mt-8 bg-base-100 rounded-md">
<table class="table">
<thead>
<tr>
<th>{$i18n.t('chargepoint:tableHeader.name')}</th>
<th>{$i18n.t('chargepoint:tableHeader.active')}</th>
<th>{$i18n.t('chargepoint:tableHeader.lastSeen')}</th>
<th>{$i18n.t('chargepoint:tableHeader.price')}</th>
<th></th>
</tr>
</thead>
<tbody>
{#if chargepoints.length > 0}
{#each chargepoints as chargepoint}
<tr>
<td>
{chargepoint.identity}
</td>
<td>
{#if chargepoint.is_active}
{$i18n.t('chargepoint:state.enabled')}
{:else}
{$i18n.t('chargepoint:state.disabled')}
{/if}
</td>
<td>
{$i18n.t(
'chargepoint:tableFormatting.lastSeen',
relativeTimeFromDate(new Date(chargepoint.last_seen))!
)}
</td>
<td>{chargepoint.price}</td>
<th>
<a href="/chargepoint/{chargepoint.id}" class="btn btn-sm btn-primary">
{$i18n.t('common:transactionTable.detailButton')}
<i class="bi bi-arrow-right"></i>
</a>
</th>
</tr>
{/each}
{/if}
</tbody>
</table>
{#if chargepoints.length === 0}
<p class="w-full mt-15 mb-15 text-center text-xl font-bold">
{$i18n.t('chargepoint:noChargepoints')}
</p>
{/if}
</div>
<div class="join mt-4">
<button onclick={previousPage} disabled={page === 1 || null} class="join-item btn bg-base-100"
</button
>
<button class="join-item btn bg-base-100">Page {page}</button>
<button
onclick={nextPage}
disabled={chargepoints.length < pageSize || null}
class="join-item btn bg-base-100">»</button
>
</div>
</div>

View file

@ -0,0 +1,17 @@
{
"header": "Ladepunkte",
"tableHeader": {
"name": "Name",
"active": "Aktiv",
"price": "Preis",
"lastSeen": "Zuletzt gesehen"
},
"tableFormatting": {
"lastSeen": "{{val, relativetime}}"
},
"state": {
"enabled": "Aktiv",
"disabled": "Deaktiviert"
},
"noChargepoints": "Noch keine Ladepunkte vorhanden."
}

View file

@ -0,0 +1,17 @@
{
"header": "Chargepoints",
"tableHeader": {
"name": "Name",
"active": "Active",
"price": "Price",
"lastSeen": "Last seen"
},
"tableFormatting": {
"lastSeen": "{{val, relativetime}}"
},
"state": {
"enabled": "Active",
"disabled": "Disabled"
},
"noChargepoints": "There are no chargepoints yet."
}