Include user information

This commit is contained in:
Florian Hoss 2024-03-25 20:31:51 +01:00
parent 9e8848379f
commit 8d3b522ff0
9 changed files with 117 additions and 83 deletions

View file

@ -58,3 +58,42 @@ templ Uptime(extraInfo string, id string, uptime services.Uptime) {
</div>
</div>
}
templ SystemScript() {
<script>
let systemSSESource = null;
addEventListener('beforeunload', () => {
systemSSESource && systemSSESource.close();
});
systemSSESource = new EventSource('/sse?stream=system');
systemSSESource.onmessage = (e) => {
const parsed = JSON.parse(e.data);
replaceSystem(parsed);
};
// system elements
const systemCpuPercentage = document.getElementById('systemCpuPercentage');
const systemRamPercentage = document.getElementById('systemRamPercentage');
const systemRamValue = document.getElementById('systemRamValue');
const systemDiskPercentage = document.getElementById('systemDiskPercentage');
const systemDiskValue = document.getElementById('systemDiskValue');
const systemUptimePercentage = document.getElementById('systemUptimePercentage');
const uptimeDays = document.getElementById('uptimeDays');
const uptimeHours = document.getElementById('uptimeHours');
const uptimeMinutes = document.getElementById('uptimeMinutes');
const uptimeSeconds = document.getElementById('uptimeSeconds');
function replaceSystem(parsed) {
systemCpuPercentage.style = 'width:' + parsed.cpu + '%';
systemRamPercentage.style = 'width:' + parsed.ram.percentage + '%';
systemRamValue.innerText = parsed.ram.value;
systemDiskPercentage.style = 'width:' + parsed.disk.percentage + '%';
systemDiskValue.innerText = parsed.disk.value;
systemUptimePercentage.style = 'width:' + parsed.uptime.percentage + '%';
uptimeDays.style = '--value:' + parsed.uptime.days;
uptimeHours.style = '--value:' + parsed.uptime.hours;
uptimeMinutes.style = '--value:' + parsed.uptime.minutes;
uptimeSeconds.style = '--value:' + parsed.uptime.seconds;
}
</script>
}

40
components/user.templ Normal file
View file

@ -0,0 +1,40 @@
package components
import (
"github.com/logto-io/go/core"
)
templ User(user *core.UserInfoResponse) {
<div
x-data="{
open: false,
toggle() {
if (this.open) return this.close();
this.open = true;
},
close(focusAfter) {
if (! this.open) return;
this.open = false;
}
}"
class="relative"
>
<button x-on:click="toggle()" class="avatar" type="button">
<div class="w-10 h-10 rounded-xl">
<img src={ user.Picture }/>
</div>
</button>
<ul
x-show="open"
x-transition.origin.top.right
x-on:click.outside="close($refs.button)"
style="display: none;"
class="z-50 absolute right-0 mt-2 menu bg-base-200 rounded-box"
>
<li class="menu-title whitespace-nowrap">{ user.Name }</li>
<li>
<a href="/sign-out"><span class="icon-[bi--box-arrow-left]"></span> Logout</a>
</li>
</ul>
</div>
}

View file

@ -63,17 +63,10 @@ templ Weather(weather *services.OpenWeather) {
templ WeatherScript() {
<script>
let systemSSESource = null;
let weatherSSESource = null;
addEventListener('beforeunload', () => {
systemSSESource && systemSSESource.close();
weatherSSESource && weatherSSESource.close();
});
systemSSESource = new EventSource('/sse?stream=system');
systemSSESource.onmessage = (e) => {
const parsed = JSON.parse(e.data);
replaceSystem(parsed);
};
weatherSSESource = new EventSource('/sse?stream=weather');
weatherSSESource.onmessage = (e) => {
const parsed = JSON.parse(e.data);
@ -89,18 +82,6 @@ templ WeatherScript() {
const weatherSunrise = document.getElementById('weatherSunrise');
const weatherSunset = document.getElementById('weatherSunset');
// system elements
const systemCpuPercentage = document.getElementById('systemCpuPercentage');
const systemRamPercentage = document.getElementById('systemRamPercentage');
const systemRamValue = document.getElementById('systemRamValue');
const systemDiskPercentage = document.getElementById('systemDiskPercentage');
const systemDiskValue = document.getElementById('systemDiskValue');
const systemUptimePercentage = document.getElementById('systemUptimePercentage');
const uptimeDays = document.getElementById('uptimeDays');
const uptimeHours = document.getElementById('uptimeHours');
const uptimeMinutes = document.getElementById('uptimeMinutes');
const uptimeSeconds = document.getElementById('uptimeSeconds');
function weatherClass(icon){
switch (icon) {
case "01d":
@ -143,18 +124,5 @@ templ WeatherScript() {
weatherSunrise.innerText = parsed.sunrise;
weatherSunset.innerText = parsed.sunset;
}
function replaceSystem(parsed) {
systemCpuPercentage.style = 'width:' + parsed.cpu + '%';
systemRamPercentage.style = 'width:' + parsed.ram.percentage + '%';
systemRamValue.innerText = parsed.ram.value;
systemDiskPercentage.style = 'width:' + parsed.disk.percentage + '%';
systemDiskValue.innerText = parsed.disk.value;
systemUptimePercentage.style = 'width:' + parsed.uptime.percentage + '%';
uptimeDays.style = '--value:' + parsed.uptime.days;
uptimeHours.style = '--value:' + parsed.uptime.hours;
uptimeMinutes.style = '--value:' + parsed.uptime.minutes;
uptimeSeconds.style = '--value:' + parsed.uptime.seconds;
}
</script>
}

View file

@ -1,40 +1,8 @@
networks:
net:
external: false
proxy:
external: false
services:
logto:
depends_on:
logto-db:
condition: service_healthy
image: svhd/logto:${V_LOGTO}
entrypoint: ['sh', '-c', 'npm run cli db seed -- --swe && npm start']
ports:
- 3001:3001
- 3002:3002
environment:
- TRUST_PROXY_HEADER=1
- DB_URL=postgres://postgres:p0stgr3s@logto-db:5432/logto
- ENDPOINT=http://0.0.0.0:3001
networks:
- net
- proxy
logto-db:
image: postgres:${V_POSTGRES}-alpine
user: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: p0stgr3s
healthcheck:
test: ['CMD-SHELL', 'pg_isready']
interval: 10s
timeout: 5s
retries: 5
networks:
- net
backend:
build:
@ -63,6 +31,7 @@ services:
- TITLE=DEV
- APP_VERSION=v0.0.1-DEV
- WEATHER_KEY=${WEATHER_KEY}
- LOGTO_ENDPOINT=${LOGTO_ENDPOINT}
- LOGTO_APP_ID=${LOGTO_APP_ID}
- LOGTO_APP_SECRET=${LOGTO_APP_SECRET}
- SESSION_KEY=super-secure
@ -70,8 +39,6 @@ services:
- .:/app/
ports:
- 4000:4000
networks:
- proxy
templ:
profiles: [dev]

View file

@ -20,30 +20,32 @@ type WeatherService interface {
GetCurrentWeather() *services.OpenWeather
}
func NewAppHandler(env *env.Config, s SystemService, w WeatherService, b BookmarkService) *AppHandler {
func NewAppHandler(env *env.Config, authHandler *AuthHandler, s SystemService, w WeatherService, b BookmarkService) *AppHandler {
return &AppHandler{
env: env,
SystemService: s,
WeatherService: w,
BookmarkService: b,
authHandler: authHandler,
systemService: s,
weatherService: w,
bookmarkService: b,
}
}
type AppHandler struct {
env *env.Config
SystemService SystemService
WeatherService WeatherService
BookmarkService BookmarkService
authHandler *AuthHandler
systemService SystemService
weatherService WeatherService
bookmarkService BookmarkService
}
func (bh *AppHandler) appHandler(c echo.Context) error {
bookmarks := bh.BookmarkService.GetAllBookmarks()
staticSystem := bh.SystemService.GetStaticInformation()
liveSystem := bh.SystemService.GetLiveInformation()
weather := bh.WeatherService.GetCurrentWeather()
bookmarks := bh.bookmarkService.GetAllBookmarks()
staticSystem := bh.systemService.GetStaticInformation()
liveSystem := bh.systemService.GetLiveInformation()
weather := bh.weatherService.GetCurrentWeather()
user := bh.authHandler.GetUserInfo()
titlePage := bh.env.Title
return renderView(c, home.HomeIndex(titlePage, bh.env.Version, home.Home(titlePage, bookmarks, staticSystem, liveSystem, weather)))
return renderView(c, home.HomeIndex(titlePage, bh.env.Version, home.Home(titlePage, user, bookmarks, staticSystem, liveSystem, weather)))
}

View file

@ -6,6 +6,7 @@ import (
"github.com/labstack/echo/v4"
"github.com/logto-io/go/client"
"github.com/logto-io/go/core"
"gitlab.unjx.de/flohoss/godash/internal/env"
)
@ -23,6 +24,11 @@ func NewAuthHandler(env *env.Config) *AuthHandler {
type AuthHandler struct {
env *env.Config
logtoConfig *client.LogtoConfig
userInfo *core.UserInfoResponse
}
func (authHandler *AuthHandler) GetUserInfo() *core.UserInfoResponse {
return authHandler.userInfo
}
func (authHandler *AuthHandler) logtoMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
@ -34,6 +40,13 @@ func (authHandler *AuthHandler) logtoMiddleware(next echo.HandlerFunc) echo.Hand
if !logtoClient.IsAuthenticated() {
return c.Redirect(http.StatusTemporaryRedirect, "/sign-in")
}
if authHandler.userInfo == nil {
info, err := logtoClient.FetchUserInfo()
if err != nil {
return echo.ErrInternalServerError
}
authHandler.userInfo = &info
}
return next(c)
}
}

View file

@ -29,7 +29,6 @@ func main() {
e.HidePort = true
e.Use(middleware.Recover())
e.Use(middleware.Logger())
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
Skipper: func(c echo.Context) bool {
return strings.Contains(c.Path(), "sse") || strings.Contains(c.Path(), "sign")
@ -46,8 +45,8 @@ func main() {
w := services.NewWeatherService(sse, env)
b := services.NewBookmarkService()
appHandler := handlers.NewAppHandler(env, s, w, b)
authHandler := handlers.NewAuthHandler(env)
appHandler := handlers.NewAppHandler(env, authHandler, s, w, b)
handlers.SetupRoutes(e, sse, appHandler, authHandler)
slog.Info("starting server", "url", env.PublicUrl)

View file

@ -5,11 +5,15 @@ import (
"gitlab.unjx.de/flohoss/godash/views/layout"
"fmt"
"gitlab.unjx.de/flohoss/godash/components"
"github.com/logto-io/go/core"
)
templ Home(title string, bookmarks *services.Bookmarks, static *services.StaticInformation, live *services.LiveInformation, weather *services.OpenWeather) {
templ Home(title string, user *core.UserInfoResponse, bookmarks *services.Bookmarks, static *services.StaticInformation, live *services.LiveInformation, weather *services.OpenWeather) {
<section class="grid gap-10">
@components.Weather(weather)
<div class="flex w-full justify-between items-center">
@components.Weather(weather)
@components.User(user)
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-3 select-none">
@components.System("icon-[bi--cpu]",static.CPU.Name,"",static.CPU.Threads,"systemCpuPercentage","",live.CPU)
@components.System("icon-[bi--nvme]",live.Disk.Value,fmt.Sprintf(" | %s", static.Disk.Total),static.Disk.Partitions,"systemDiskPercentage","systemDiskValue",live.Disk.Percentage)
@ -45,6 +49,7 @@ templ Home(title string, bookmarks *services.Bookmarks, static *services.StaticI
}
</div>
@components.WeatherScript()
@components.SystemScript()
</section>
}

View file

@ -18,6 +18,7 @@ templ Base(title, version string) {
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png"/>
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png"/>
<link rel="manifest" href="/favicon/site.webmanifest"/>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.7/dist/cdn.min.js"></script>
<style>
.bookmark-link:hover .img {
opacity: 1;