style updates, split aside components, add get town by coords
This commit is contained in:
parent
58fe999675
commit
574bde5f28
@ -46,6 +46,15 @@ section#game {
|
|||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
border-top: 2px solid #000;
|
border-top: 2px solid #000;
|
||||||
|
|
||||||
|
& > aside > section:not(:last-child) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > aside > section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
& > aside#left {
|
& > aside#left {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
border-right: 2px solid #000;
|
border-right: 2px solid #000;
|
||||||
@ -86,7 +95,7 @@ a {
|
|||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
div.title {
|
||||||
border: solid 1px black;
|
border: solid 1px black;
|
||||||
background-color: #eeeeee;
|
background-color: #eeeeee;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -106,3 +115,51 @@ footer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.unstyled {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
form#move-compass {
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-image: url('/assets/images/compass.webp');
|
||||||
|
margin: 0.5rem auto;
|
||||||
|
|
||||||
|
& > div.mid {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
color: transparent; /* Hide the text */
|
||||||
|
background-size: cover; /* Ensure the background image fills the button */
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(225, 16, 16, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&#north {
|
||||||
|
width: 128px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&#west {
|
||||||
|
width: 63px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&#east {
|
||||||
|
width: 63px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&#south {
|
||||||
|
width: 128px;
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -43,32 +43,7 @@ func Start(port string) error {
|
|||||||
// Setup route handlers
|
// Setup route handlers
|
||||||
routes.RegisterAuthRoutes(r)
|
routes.RegisterAuthRoutes(r)
|
||||||
|
|
||||||
// Dashboard (protected route)
|
|
||||||
r.WithMiddleware(middleware.RequireAuth("/login")).Get("/dashboard", func(ctx router.Ctx, params []string) {
|
|
||||||
currentUser := middleware.GetCurrentUser(ctx)
|
|
||||||
totalSessions, activeSessions := auth.Manager.SessionStats()
|
|
||||||
|
|
||||||
pageData := components.NewPageData(
|
|
||||||
"Dashboard - Dragon Knight",
|
|
||||||
fmt.Sprintf("Welcome back, %s!", currentUser.Username),
|
|
||||||
)
|
|
||||||
|
|
||||||
additionalData := map[string]any{
|
|
||||||
"total_sessions": totalSessions,
|
|
||||||
"active_sessions": activeSessions,
|
|
||||||
"authenticated": true,
|
|
||||||
"username": currentUser.Username,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := components.RenderPage(ctx, pageData, additionalData); err != nil {
|
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
|
||||||
fmt.Fprintf(ctx, "Template error: %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Hello world endpoint (public)
|
|
||||||
r.Get("/", func(ctx router.Ctx, params []string) {
|
r.Get("/", func(ctx router.Ctx, params []string) {
|
||||||
// Get current user if authenticated
|
|
||||||
currentUser := middleware.GetCurrentUser(ctx)
|
currentUser := middleware.GetCurrentUser(ctx)
|
||||||
var username string
|
var username string
|
||||||
if currentUser != nil {
|
if currentUser != nil {
|
||||||
@ -77,21 +52,12 @@ func Start(port string) error {
|
|||||||
username = "Guest"
|
username = "Guest"
|
||||||
}
|
}
|
||||||
|
|
||||||
totalSessions, activeSessions := auth.Manager.SessionStats()
|
|
||||||
|
|
||||||
pageData := components.NewPageData(
|
pageData := components.NewPageData(
|
||||||
"Dragon Knight",
|
"Dragon Knight",
|
||||||
fmt.Sprintf("Hello %s!", username),
|
fmt.Sprintf("Hello %s!", username),
|
||||||
)
|
)
|
||||||
|
|
||||||
additionalData := map[string]any{
|
if err := components.RenderPage(ctx, pageData, nil); err != nil {
|
||||||
"total_sessions": totalSessions,
|
|
||||||
"active_sessions": activeSessions,
|
|
||||||
"authenticated": currentUser != nil,
|
|
||||||
"username": username,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := components.RenderPage(ctx, pageData, additionalData); err != nil {
|
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
fmt.Fprintf(ctx, "Template error: %v", err)
|
fmt.Fprintf(ctx, "Template error: %v", err)
|
||||||
return
|
return
|
||||||
|
91
internal/template/components/asides.go
Normal file
91
internal/template/components/asides.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dk/internal/middleware"
|
||||||
|
"dk/internal/router"
|
||||||
|
"dk/internal/template"
|
||||||
|
"dk/internal/towns"
|
||||||
|
"dk/internal/users"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LeftAside generates the left sidebar content
|
||||||
|
func LeftAside(ctx router.Ctx) string {
|
||||||
|
if !middleware.IsAuthenticated(ctx) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
leftSideTmpl, err := template.Cache.Load("leftside.html")
|
||||||
|
if err != nil {
|
||||||
|
return "leftside failed to load?"
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUser := middleware.GetCurrentUser(ctx)
|
||||||
|
if currentUser == nil {
|
||||||
|
return "no currentUser?"
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := users.Find(currentUser.ID)
|
||||||
|
if err != nil {
|
||||||
|
return "user not found?"
|
||||||
|
}
|
||||||
|
|
||||||
|
cardinalX := "E"
|
||||||
|
if user.X < 0 {
|
||||||
|
cardinalX = "W"
|
||||||
|
}
|
||||||
|
|
||||||
|
cardinalY := "S"
|
||||||
|
if user.Y < 0 {
|
||||||
|
cardinalY = "N"
|
||||||
|
}
|
||||||
|
|
||||||
|
townname := ""
|
||||||
|
if user.Currently == "In Town" {
|
||||||
|
town, err := towns.ByCoords(user.X, user.Y)
|
||||||
|
if err != nil {
|
||||||
|
townname = "error finding town"
|
||||||
|
}
|
||||||
|
townname = "<b>In " + town.Name + "</b>"
|
||||||
|
}
|
||||||
|
|
||||||
|
leftSideData := map[string]any{
|
||||||
|
"user": user.ToMap(),
|
||||||
|
"cardinalX": cardinalX,
|
||||||
|
"cardinalY": cardinalY,
|
||||||
|
"townname": townname,
|
||||||
|
"townlist": "@TODO",
|
||||||
|
}
|
||||||
|
|
||||||
|
return leftSideTmpl.RenderNamed(leftSideData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RightAside generates the right sidebar content
|
||||||
|
func RightAside(ctx router.Ctx) string {
|
||||||
|
if !middleware.IsAuthenticated(ctx) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load and render the rightside template with user data
|
||||||
|
rightSideTmpl, err := template.Cache.Load("rightside.html")
|
||||||
|
if err != nil {
|
||||||
|
return "" // Silently fail - sidebar is optional
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current user from session
|
||||||
|
currentUser := middleware.GetCurrentUser(ctx)
|
||||||
|
if currentUser == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := users.Find(currentUser.ID)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass the user object directly to the template
|
||||||
|
rightSideData := map[string]any{
|
||||||
|
"user": user.ToMap(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return rightSideTmpl.RenderNamed(rightSideData)
|
||||||
|
}
|
@ -9,7 +9,6 @@ import (
|
|||||||
"dk/internal/middleware"
|
"dk/internal/middleware"
|
||||||
"dk/internal/router"
|
"dk/internal/router"
|
||||||
"dk/internal/template"
|
"dk/internal/template"
|
||||||
"dk/internal/users"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerateTopNav generates the top navigation HTML based on authentication status
|
// GenerateTopNav generates the top navigation HTML based on authentication status
|
||||||
@ -28,68 +27,6 @@ func GenerateTopNav(ctx router.Ctx) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateLeftSide generates the left sidebar content for authenticated users
|
|
||||||
func GenerateLeftSide(ctx router.Ctx) string {
|
|
||||||
if !middleware.IsAuthenticated(ctx) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load and render the leftside template with user data
|
|
||||||
leftSideTmpl, err := template.Cache.Load("leftside.html")
|
|
||||||
if err != nil {
|
|
||||||
return "" // Silently fail - sidebar is optional
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current user from session
|
|
||||||
currentUser := middleware.GetCurrentUser(ctx)
|
|
||||||
if currentUser == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := users.Find(currentUser.ID)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass the user object directly to the template
|
|
||||||
leftSideData := map[string]any{
|
|
||||||
"user": user.ToMap(),
|
|
||||||
}
|
|
||||||
|
|
||||||
return leftSideTmpl.RenderNamed(leftSideData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateRightSide generates the right sidebar content for authenticated users
|
|
||||||
func GenerateRightSide(ctx router.Ctx) string {
|
|
||||||
if !middleware.IsAuthenticated(ctx) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load and render the rightside template with user data
|
|
||||||
rightSideTmpl, err := template.Cache.Load("rightside.html")
|
|
||||||
if err != nil {
|
|
||||||
return "" // Silently fail - sidebar is optional
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current user from session
|
|
||||||
currentUser := middleware.GetCurrentUser(ctx)
|
|
||||||
if currentUser == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := users.Find(currentUser.ID)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass the user object directly to the template
|
|
||||||
rightSideData := map[string]any{
|
|
||||||
"user": user.ToMap(),
|
|
||||||
}
|
|
||||||
|
|
||||||
return rightSideTmpl.RenderNamed(rightSideData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageData holds common page template data
|
// PageData holds common page template data
|
||||||
type PageData struct {
|
type PageData struct {
|
||||||
Title string
|
Title string
|
||||||
@ -106,7 +43,7 @@ type PageData struct {
|
|||||||
// RenderPage renders a page using the layout template with common data and additional custom data
|
// RenderPage renders a page using the layout template with common data and additional custom data
|
||||||
func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any) error {
|
func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any) error {
|
||||||
if template.Cache == nil || auth.Manager == nil {
|
if template.Cache == nil || auth.Manager == nil {
|
||||||
return fmt.Errorf("singleton template.Cache or auth.Manager not initialized")
|
return fmt.Errorf("template.Cache or auth.Manager not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutTmpl, err := template.Cache.Load("layout.html")
|
layoutTmpl, err := template.Cache.Load("layout.html")
|
||||||
@ -132,10 +69,10 @@ func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any
|
|||||||
|
|
||||||
// Set defaults for empty fields
|
// Set defaults for empty fields
|
||||||
if data["leftside"] == "" {
|
if data["leftside"] == "" {
|
||||||
data["leftside"] = GenerateLeftSide(ctx)
|
data["leftside"] = LeftAside(ctx)
|
||||||
}
|
}
|
||||||
if data["rightside"] == "" {
|
if data["rightside"] == "" {
|
||||||
data["rightside"] = GenerateRightSide(ctx)
|
data["rightside"] = RightAside(ctx)
|
||||||
}
|
}
|
||||||
if data["numqueries"] == "" {
|
if data["numqueries"] == "" {
|
||||||
data["numqueries"] = "0"
|
data["numqueries"] = "0"
|
||||||
|
@ -158,6 +158,31 @@ func ByMaxTPCost(maxCost int) ([]*Town, error) {
|
|||||||
return towns, nil
|
return towns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByCoords retrieves a town by its x, y coordinates
|
||||||
|
func ByCoords(x, y int) (*Town, error) {
|
||||||
|
town := &Town{}
|
||||||
|
|
||||||
|
query := `SELECT id, name, x, y, inn_cost, map_cost, tp_cost, shop_list
|
||||||
|
FROM towns WHERE x = ? AND y = ? LIMIT 1`
|
||||||
|
err := database.Query(query, func(stmt *sqlite.Stmt) error {
|
||||||
|
town.ID = stmt.ColumnInt(0)
|
||||||
|
town.Name = stmt.ColumnText(1)
|
||||||
|
town.X = stmt.ColumnInt(2)
|
||||||
|
town.Y = stmt.ColumnInt(3)
|
||||||
|
town.InnCost = stmt.ColumnInt(4)
|
||||||
|
town.MapCost = stmt.ColumnInt(5)
|
||||||
|
town.TPCost = stmt.ColumnInt(6)
|
||||||
|
town.ShopList = stmt.ColumnText(7)
|
||||||
|
return nil
|
||||||
|
}, x, y)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to retrieve towns by distance: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return town, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ByDistance retrieves towns within a certain distance from a point
|
// ByDistance retrieves towns within a certain distance from a point
|
||||||
func ByDistance(fromX, fromY, maxDistance int) ([]*Town, error) {
|
func ByDistance(fromX, fromY, maxDistance int) ([]*Town, error) {
|
||||||
var towns []*Town
|
var towns []*Town
|
||||||
|
@ -1,46 +1,32 @@
|
|||||||
<table width="100%">
|
<section>
|
||||||
<tr>
|
<div class="title"><img src="/assets/images/button_location.gif" alt="Location" title="Location"></div>
|
||||||
<td class="title"><img src="/assets/images/button_location.gif" alt="Location" title="Location"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Currently: {user.Currently}<br>
|
|
||||||
Longitude: {user.X}<br>
|
|
||||||
Latitude: {user.Y}<br>
|
|
||||||
<a href="javascript:openmappopup()">View Map</a>
|
|
||||||
<br><br>
|
|
||||||
<form action="/move" method="post">
|
|
||||||
<center>
|
|
||||||
<input name="north" type="submit" value="North"><br>
|
|
||||||
<input name="west" type="submit" value="West"><input name="east" type="submit" value="East"><br>
|
|
||||||
<input name="south" type="submit" value="South">
|
|
||||||
</center>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
<div><b>{user.Currently}</b></div>
|
||||||
|
<div>{user.X}{cardinalX}, {user.Y}{cardinalY}</div>
|
||||||
|
|
||||||
|
<a href="javascript:openmappopup()">View Map</a>
|
||||||
|
|
||||||
<table width="100%">
|
<form id="move-compass" action="/move" method="post" >
|
||||||
<tr><td class="title"><img src="/assets/images/button_towns.gif" alt="Towns" title="Towns"></td></tr>
|
<button id="north" name="direction" value="north">North</button>
|
||||||
<tr>
|
<div class="mid">
|
||||||
<td>
|
<button id="west" name="direction" value="west">West</button>
|
||||||
{townname}
|
<button id="east" name="direction" value="east">East</button>
|
||||||
{townlist}
|
</div>
|
||||||
</td>
|
<button id="south" name="direction" value="south">South</button>
|
||||||
</tr>
|
</form>
|
||||||
</table>
|
</section>
|
||||||
|
|
||||||
<br>
|
<section>
|
||||||
|
<div class="title"><img src="/assets/images/button_towns.gif" alt="Towns" title="Towns"></div>
|
||||||
|
<div>{townname}</div>
|
||||||
|
<div>{townlist}</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<table width="100%">
|
<section id="functions">
|
||||||
<tr><td class="title"><img src="/assets/images/button_functions.gif" alt="Functions" title="Functions"></td></tr>
|
<div class="title"><img src="/assets/images/button_functions.gif" alt="Functions" title="Functions"></div>
|
||||||
<tr><td>
|
<a href="/">Home</a>
|
||||||
<a href="/">Home</a><br>
|
|
||||||
<a href="/forum">Forum</a>
|
<a href="/forum">Forum</a>
|
||||||
<a href="/change-password">Change Password</a><br>
|
<a href="/change-password">Change Password</a>
|
||||||
<a href="#">Log Out</a><br>
|
<a href="#">Log Out</a>
|
||||||
<a href="/help">Help</a>
|
<a href="/help">Help</a>
|
||||||
</td></tr>
|
</section>
|
||||||
</table>
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user