style updates, split aside components, add get town by coords

This commit is contained in:
Sky Johnson 2025-08-09 21:29:12 -05:00
parent 58fe999675
commit 574bde5f28
6 changed files with 204 additions and 142 deletions

View File

@ -46,6 +46,15 @@ section#game {
margin: 1rem 0;
border-top: 2px solid #000;
& > aside > section:not(:last-child) {
margin-bottom: 1rem;
}
& > aside > section {
display: flex;
flex-direction: column;
}
& > aside#left {
grid-column: 1;
border-right: 2px solid #000;
@ -86,7 +95,7 @@ a {
color: #999999;
}
.title {
div.title {
border: solid 1px black;
background-color: #eeeeee;
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;
}
}
}

View File

@ -43,32 +43,7 @@ func Start(port string) error {
// Setup route handlers
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) {
// Get current user if authenticated
currentUser := middleware.GetCurrentUser(ctx)
var username string
if currentUser != nil {
@ -77,21 +52,12 @@ func Start(port string) error {
username = "Guest"
}
totalSessions, activeSessions := auth.Manager.SessionStats()
pageData := components.NewPageData(
"Dragon Knight",
fmt.Sprintf("Hello %s!", username),
)
additionalData := map[string]any{
"total_sessions": totalSessions,
"active_sessions": activeSessions,
"authenticated": currentUser != nil,
"username": username,
}
if err := components.RenderPage(ctx, pageData, additionalData); err != nil {
if err := components.RenderPage(ctx, pageData, nil); err != nil {
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
fmt.Fprintf(ctx, "Template error: %v", err)
return

View 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)
}

View File

@ -9,7 +9,6 @@ import (
"dk/internal/middleware"
"dk/internal/router"
"dk/internal/template"
"dk/internal/users"
)
// 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
type PageData struct {
Title string
@ -106,7 +43,7 @@ type PageData struct {
// 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 {
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")
@ -132,10 +69,10 @@ func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any
// Set defaults for empty fields
if data["leftside"] == "" {
data["leftside"] = GenerateLeftSide(ctx)
data["leftside"] = LeftAside(ctx)
}
if data["rightside"] == "" {
data["rightside"] = GenerateRightSide(ctx)
data["rightside"] = RightAside(ctx)
}
if data["numqueries"] == "" {
data["numqueries"] = "0"

View File

@ -158,6 +158,31 @@ func ByMaxTPCost(maxCost int) ([]*Town, error) {
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
func ByDistance(fromX, fromY, maxDistance int) ([]*Town, error) {
var towns []*Town

View File

@ -1,46 +1,32 @@
<table width="100%">
<tr>
<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>
<section>
<div class="title"><img src="/assets/images/button_location.gif" alt="Location" title="Location"></div>
<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%">
<tr><td class="title"><img src="/assets/images/button_towns.gif" alt="Towns" title="Towns"></td></tr>
<tr>
<td>
{townname}
{townlist}
</td>
</tr>
</table>
<form id="move-compass" action="/move" method="post" >
<button id="north" name="direction" value="north">North</button>
<div class="mid">
<button id="west" name="direction" value="west">West</button>
<button id="east" name="direction" value="east">East</button>
</div>
<button id="south" name="direction" value="south">South</button>
</form>
</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%">
<tr><td class="title"><img src="/assets/images/button_functions.gif" alt="Functions" title="Functions"></td></tr>
<tr><td>
<a href="/">Home</a><br>
<section id="functions">
<div class="title"><img src="/assets/images/button_functions.gif" alt="Functions" title="Functions"></div>
<a href="/">Home</a>
<a href="/forum">Forum</a>
<a href="/change-password">Change Password</a><br>
<a href="#">Log Out</a><br>
<a href="/change-password">Change Password</a>
<a href="#">Log Out</a>
<a href="/help">Help</a>
</td></tr>
</table>
</section>