Include user information
This commit is contained in:
parent
9e8848379f
commit
8d3b522ff0
9 changed files with 117 additions and 83 deletions
|
@ -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
40
components/user.templ
Normal 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>
|
||||
}
|
|
@ -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>
|
||||
}
|
||||
|
|
35
compose.yml
35
compose.yml
|
@ -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]
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
3
main.go
3
main.go
|
@ -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)
|
||||
|
|
|
@ -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">
|
||||
<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>
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue