Feat: styles and session
This commit is contained in:
		
							
								
								
									
										24
									
								
								components/createroomform.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								components/createroomform.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| {{define "createform"}} | ||||
|  <div class="create-room-div"> | ||||
|             Create a room <br/> | ||||
|             or<br/> | ||||
|             @CustomBtn(templ.Attributes{"hx-get": "/room/hideform", "hx-target": ".create-room-div"}, "Hide Form") | ||||
|             <form hx-post="/room/create" hx-target="#ancestor"> | ||||
|                 <label For="room_name">Room Name</label><br/> | ||||
|                 <input type="text" id="room_name" name="room_name" class="text-center text-black" value={utils.MakeDefaultRoomName(utils.GetUsername(c))}/><br/> | ||||
|                 <label For="game_time">Game Time:</label><br/> | ||||
|                 <input type="number" id="game_time" name="game_time" class="text-center text-black" value="300"/><br/> | ||||
|                 <label For="minority_number">Minority Number:</label><br/> | ||||
|                 <input type="number" id="minority_number" name="minority_number" class="text-center text-black" value="1"/><br/> | ||||
|                 <label For="language">Language:</label><br/> | ||||
|                 /* <input type="text" id="language" name="language" class="text-center text-black" value="en"/><br/> */ | ||||
|                 @base.LangOption()<br/> | ||||
|                 <label For="password">Password:</label><br/> | ||||
|                 <input type="text" id="password" name="room_pass" class="text-center text-black" value="" placeholder="Leave empty for open room"/><br/> | ||||
|                 @CustomBtn(templ.Attributes{"type": "submit"}, "Create Room") | ||||
|             </form> | ||||
|         </div> | ||||
|         <div class="create-room-div"> | ||||
|             Hello, you should login. | ||||
|         </div> | ||||
| {{end}} | ||||
| @@ -2,14 +2,48 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
| 	<meta charset="UTF-8"> | ||||
| 	<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
| 	<title>Word Colors</title> | ||||
| 	<script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script> | ||||
| 	<script src="/assets/htmx.min.js"></script> | ||||
| 	<script src="/assets/htmx.sse.js"></script> | ||||
| 	<link rel="stylesheet" href="/assets/style.css"/> | ||||
| 	<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1"/> | ||||
| 	<link rel="icon" sizes="64x64" href="favicon.ico"/> | ||||
| 	<style type="text/css"> | ||||
| 		body{ | ||||
|             background-color: #0C1616FF; | ||||
|             color: #8896b2; | ||||
|             max-width: 800px; | ||||
|             min-width: 0; | ||||
|             margin: 2em auto !important; | ||||
|             margin-left: auto; | ||||
|             margin-right: auto; | ||||
|             line-height: 1.5; | ||||
|             font-size: 16px; | ||||
|             font-family: Open Sans,Arial; | ||||
|             text-align: center; | ||||
|             display: block; | ||||
|         } | ||||
|         a{ | ||||
|             color: #00a2e7; | ||||
|         } | ||||
|         a:visited{ | ||||
|             color: #ca1a70; | ||||
|         } | ||||
|         table { | ||||
|           border-collapse: separate !important; | ||||
|           border-spacing: 10px 10px; | ||||
|           border: 1px solid white; | ||||
|         } | ||||
|         tr{ | ||||
|             border: 1px solid white; | ||||
|         } | ||||
| 	</style> | ||||
| </head> | ||||
| <body> | ||||
| <div id=ancestor> | ||||
| 	{{template "login"}} | ||||
| 	    <button button id="create-form-btn" type="submit" class="justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" hx-get="/room/createform" hx-swap="outerHTML">SHOW ROOM CREATE FORM</button> | ||||
| 	<h1>Word Color Cards</h1> | ||||
| 	<div style="display: flex; gap: 1rem; flex-wrap: wrap; padding: 1rem;"> | ||||
| 		{{range $word, $color := .}} | ||||
|   | ||||
							
								
								
									
										10
									
								
								handlers/actions.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								handlers/actions.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"golias/models" | ||||
| ) | ||||
|  | ||||
| func createRoom(ctx context.Context, req *models.RoomReq) (*models.RoomPublic, error) { | ||||
| 	return nil, nil | ||||
| } | ||||
| @@ -1,10 +1,12 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"golias/models" | ||||
| 	"golias/utils" | ||||
| 	"html/template" | ||||
| @@ -112,3 +114,12 @@ func cacheSetSession(key string, session *models.Session) error { | ||||
| 	memcache.Expire(key, 10*60) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func updateRoomInSession(ctx context.Context, roomID string) (context.Context, error) { | ||||
| 	s, ok := ctx.Value("session").(models.Session) | ||||
| 	if !ok { | ||||
| 		return context.TODO(), errors.New("failed to extract session from ctx") | ||||
| 	} | ||||
| 	s.CurrentRoom = roomID | ||||
| 	return context.WithValue(ctx, "session", s), nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										15
									
								
								handlers/elements.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								handlers/elements.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| func HandleShowCreateForm(w http.ResponseWriter, r *http.Request) { | ||||
| 	tmpl, err := template.ParseGlob("components/*.html") | ||||
| 	if err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	tmpl.ExecuteTemplate(w, "createform", nil) | ||||
| } | ||||
							
								
								
									
										44
									
								
								handlers/game.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								handlers/game.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"golias/models" | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { | ||||
| 	// parse payload | ||||
| 	payload := &models.RoomReq{ | ||||
| 		RoomPass: r.PostFormValue("room_pass"), | ||||
| 		RoomName: r.PostFormValue("room_name"), | ||||
| 	} | ||||
| 	// create a room | ||||
| 	room, err := createRoom(r.Context(), payload) | ||||
| 	if err != nil { | ||||
| 		msg := "failed to create a room" | ||||
| 		log.Error(msg, "error", err) | ||||
| 		abortWithError(w, msg) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx := context.WithValue(r.Context(), "current_room", room.ID) | ||||
| 	ctx, err = updateRoomInSession(ctx, room.ID) | ||||
| 	if err != nil { | ||||
| 		msg := "failed to set current room to session" | ||||
| 		log.Error(msg, "error", err) | ||||
| 		abortWithError(w, msg) | ||||
| 		return | ||||
| 	} | ||||
| 	// send msg of created room | ||||
| 	// h.Broker.Notifier <- broker.NotificationEvent{ | ||||
| 	// 	EventName: models.MsgRoomListUpdate, | ||||
| 	// 	Payload:   fmt.Sprintf("%s created a room named %s", r.CreatorName, r.RoomName), | ||||
| 	// } | ||||
| 	// return html | ||||
| 	tmpl, err := template.ParseGlob("components/*.html") | ||||
| 	if err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	tmpl.ExecuteTemplate(w, "main", nil) | ||||
| } | ||||
| @@ -1,19 +1,27 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"golias/config" | ||||
| 	"golias/pkg/cache" | ||||
| 	"html/template" | ||||
| 	"log/slog" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| var log *slog.Logger | ||||
| var ( | ||||
| 	log      *slog.Logger | ||||
| 	cfg      *config.Config | ||||
| 	memcache cache.Cache | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ | ||||
| 		Level:     slog.LevelDebug, | ||||
| 		AddSource: true, | ||||
| 	})) | ||||
| 	memcache = cache.MemCache | ||||
| 	cfg = config.LoadConfigOrDefault("") | ||||
| } | ||||
|  | ||||
| var roundWords = map[string]string{ | ||||
|   | ||||
| @@ -6,17 +6,10 @@ import ( | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"golias/config" | ||||
| 	"golias/pkg/cache" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	cfg      config.Config | ||||
| 	memcache cache.Cache | ||||
| ) | ||||
|  | ||||
| // responseWriterWrapper wraps http.ResponseWriter to capture status code | ||||
| type responseWriterWrapper struct { | ||||
| 	http.ResponseWriter | ||||
| @@ -99,6 +92,8 @@ func GetSession(next http.Handler) http.Handler { | ||||
| 		} | ||||
| 		ctx := context.WithValue(r.Context(), | ||||
| 			"username", userSession.Username) | ||||
| 		ctx = context.WithValue(r.Context(), | ||||
| 			"session", userSession) | ||||
| 		if err := cacheSetSession(sessionToken, | ||||
| 			userSession); err != nil { | ||||
| 			msg := "failed to marshal user session" | ||||
|   | ||||
							
								
								
									
										7
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"golias/handlers" | ||||
| 	"log/slog" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
| @@ -22,13 +22,14 @@ func ListenToRequests(port string) error { | ||||
|  | ||||
| 	mux.HandleFunc("GET /ping", handlers.HandlePing) | ||||
| 	mux.HandleFunc("GET /", handlers.HandleHome) | ||||
| 	fmt.Println("Listening", "addr", port) | ||||
| 	mux.HandleFunc("POST /login", handlers.HandleFrontLogin) | ||||
| 	mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm) | ||||
| 	slog.Info("Listening", "addr", port) | ||||
| 	return server.ListenAndServe() | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	port := ":3000" | ||||
| 	fmt.Printf("Starting server on %s\n", port) | ||||
| 	err := ListenToRequests(port) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
|   | ||||
| @@ -67,3 +67,12 @@ type GameSettings struct { | ||||
| 	ProgressPct uint32 `json:"progress_pct"` | ||||
| 	IsOver      bool | ||||
| } | ||||
|  | ||||
| // ===== | ||||
|  | ||||
| type RoomReq struct { | ||||
| 	// is not user or not unique | ||||
| 	RoomPass string `json:"room_pass" form:"room_pass"` | ||||
| 	RoomName string `json:"room_name" form:"room_name"` | ||||
| 	// GameSettings | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder