Added rooms!

This commit is contained in:
Atridad Lahiji 2024-06-28 14:23:35 -06:00
parent bf62a62978
commit 7cc7226dee
No known key found for this signature in database
8 changed files with 231 additions and 6 deletions

45
api/createroom.go Normal file
View file

@ -0,0 +1,45 @@
package api
import (
"fmt"
"net/http"
"pollo/lib"
"github.com/labstack/echo/v4"
)
// CreateRoomHandler handles the creation of a new room and returns an updated list of rooms.
func CreateRoomHandler(c echo.Context) error {
currentSession, err := lib.GetSessionCookie(c.Request(), "session")
if err != nil {
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
}
roomName := c.FormValue("roomName")
if roomName == "" {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "room name is required"})
}
_, err = lib.CreateRoom(lib.GetDBPool(), currentSession.UserID, roomName)
if err != nil {
println("Error creating room: ", err.Error())
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to create room"})
}
// Retrieve the updated list of rooms for the user
rooms, err := lib.GetRoomsByUserID(lib.GetDBPool(), currentSession.UserID)
if err != nil {
println("Error retrieving rooms: ", err.Error())
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to retrieve rooms"})
}
// Start building the HTML content for the updated list of rooms
htmlContent := "<div id='room-list'>"
for _, room := range rooms {
htmlContent += fmt.Sprintf("<div class='room-name'>%s</div>", room.RoomName)
}
htmlContent += "</div>"
// Return the dynamically generated HTML content
return c.HTML(http.StatusOK, htmlContent)
}

23
api/deleteroom.go Normal file
View file

@ -0,0 +1,23 @@
package api
import (
"net/http"
"pollo/lib"
"github.com/labstack/echo/v4"
)
// DeleteRoomHandler handles the deletion of a room by ID.
func DeleteRoomHandler(c echo.Context) error {
roomID := c.Param("id")
if roomID == "" {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "room ID is required"})
}
err := lib.DeleteRoom(lib.GetDBPool(), roomID)
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to delete room"})
}
return c.NoContent(http.StatusNoContent)
}

36
api/getroomlist.go Normal file
View file

@ -0,0 +1,36 @@
package api
import (
"fmt"
"net/http"
"pollo/lib"
"github.com/labstack/echo/v4"
)
// GetAllRoomsHandler handles the request to get all rooms for a user.
func GetAllRoomsHandler(c echo.Context) error {
currentSession, err := lib.GetSessionCookie(c.Request(), "session")
if err != nil {
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
}
rooms, err := lib.GetRoomsByUserID(lib.GetDBPool(), currentSession.UserID)
if err != nil {
// Log the error and return an internal server error response
println("Error retrieving rooms: ", err.Error())
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to retrieve rooms"})
}
// Start building the HTML content
htmlContent := "<div id='room-list'>"
for _, room := range rooms {
// For each room, append an HTML element to htmlContent
// Customize this HTML structure as needed to match your desired appearance
htmlContent += fmt.Sprintf("<div class='room-name'>%s</div>", room.RoomName)
}
htmlContent += "</div>"
// Return the dynamically generated HTML content
return c.HTML(http.StatusOK, htmlContent)
}

View file

@ -29,7 +29,17 @@ func InitializeSchema(dbPool *pgxpool.Pool) error {
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
);`
);
CREATE TABLE IF NOT EXISTS rooms (
id TEXT NOT NULL PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
userId TEXT NOT NULL,
roomName TEXT,
topicName TEXT,
visible BOOLEAN NOT NULL DEFAULT false,
scale TEXT NOT NULL DEFAULT '0.5,1,2,3,5'
);
`
// TODO: Add more tables to the schema
_, err := dbPool.Exec(context.Background(), schemaSQL)

99
lib/room.go Normal file
View file

@ -0,0 +1,99 @@
package lib
import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"time"
"github.com/jackc/pgx/v4/pgxpool"
)
type Room struct {
ID string
CreatedAt time.Time
UserID string
RoomName string
TopicName string
Visible bool
Scale string
}
// GenerateNewID generates a new room ID with the format "room_randomstring".
func GenerateNewID() string {
randomBytes := make([]byte, 16)
if _, err := rand.Read(randomBytes); err != nil {
panic(err)
}
return fmt.Sprintf("room_%s", hex.EncodeToString(randomBytes))
}
// CreateRoom creates a new room in the database.
func CreateRoom(dbPool *pgxpool.Pool, userID, roomName string) (*Room, error) {
if dbPool == nil {
return nil, errors.New("database connection pool is not initialized")
}
// Generate a new ID for the room
newRoomID := GenerateNewID()
// Insert the new room into the database
_, err := dbPool.Exec(context.Background(), "INSERT INTO rooms (id, userid, roomname, topicname, visible, scale) VALUES ($1, $2, $3, $4, $5, $6)", newRoomID, userID, roomName, "My First Topic", false, "0.5,1,2,3,5")
if err != nil {
return nil, err
}
return &Room{
ID: newRoomID,
UserID: userID,
RoomName: roomName,
TopicName: "My First Topic",
Visible: false, // Default visibility
Scale: "0.5,1,2,3,5", // Default scale
}, nil
}
// DeleteRoom deletes a room from the database by its ID.
func DeleteRoom(dbPool *pgxpool.Pool, roomID string) error {
if dbPool == nil {
return errors.New("database connection pool is not initialized")
}
_, err := dbPool.Exec(context.Background(), "DELETE FROM rooms WHERE id = $1", roomID)
if err != nil {
return err
}
return nil
}
// GetRoomsByUserID retrieves all rooms for a given userID.
func GetRoomsByUserID(dbPool *pgxpool.Pool, userID string) ([]Room, error) {
if dbPool == nil {
return nil, errors.New("database connection pool is not initialized")
}
var rooms []Room
rows, err := dbPool.Query(context.Background(), "SELECT id, created_at, userid, roomname, topicname, visible, scale FROM rooms WHERE userid = $1", userID)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var room Room
err := rows.Scan(&room.ID, &room.CreatedAt, &room.UserID, &room.RoomName, &room.TopicName, &room.Visible, &room.Scale)
if err != nil {
return nil, err
}
rooms = append(rooms, room)
}
if err = rows.Err(); err != nil {
return nil, err
}
return rooms, nil
}

View file

@ -89,6 +89,10 @@ func main() {
apiGroup.POST("/register", api.RegisterUserHandler)
apiGroup.POST("/signin", api.SignInUserHandler)
apiGroup.POST("/signout", api.SignOutUserHandler)
// Rooms routes
apiGroup.POST("/room/create", api.CreateRoomHandler)
apiGroup.GET("/room/list", api.GetAllRoomsHandler)
apiGroup.POST("/room/delete", api.DeleteRoomHandler)
// Webhook Routes:
webhookGroup := e.Group("/webhook")

View file

@ -15,10 +15,18 @@ Pollo // Dashboard
<h1 class="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-4xl font-bold">
Hi, {{.Name}}!
</h1>
<label htmlFor="new-room-modal" class="btn btn-primary">
New Room
</label>
<!-- Form to create a new room -->
<form method="POST" hx-post="/api/room/create" hx-target="#room-list" hx-swap="outerHTML">
<input type="text" name="roomName" placeholder="Room Name" required>
<button type="submit" class="btn btn-primary">Create Room</button>
</form>
<!-- Section to list rooms -->
<div class="flex flex-col gap-2" id="room-list" hx-get="/api/room/list" hx-trigger="load">
<!-- Example of how rooms might be loaded -->
<!-- <div class="room-name">Room 1</div>
<div class="room-name">Room 2</div> -->
<!-- Rooms will be loaded here -->
</div>
</div>
{{end}}

File diff suppressed because one or more lines are too long