135 lines
3.0 KiB
Go
135 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/gorilla/handlers"
|
|
"github.com/gorilla/mux"
|
|
"github.com/joho/godotenv"
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
type CartItem struct {
|
|
ID int `json:"id"`
|
|
Title string `json:"title"`
|
|
Price float64 `json:"price"`
|
|
Quantity int `json:"quantity"`
|
|
}
|
|
|
|
var db *sql.DB
|
|
|
|
func main() {
|
|
// Load environment variables
|
|
err := godotenv.Load()
|
|
if err != nil {
|
|
log.Fatal("Error loading .env file")
|
|
}
|
|
|
|
// Connect to the database
|
|
connStr := os.Getenv("DATABASE_URL")
|
|
db, err = sql.Open("postgres", connStr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Create the cart table if it doesn't exist
|
|
_, err = db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS cart_items (
|
|
id SERIAL PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
price DECIMAL(10, 2) NOT NULL,
|
|
quantity INTEGER NOT NULL
|
|
)
|
|
`)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
r := mux.NewRouter()
|
|
|
|
r.HandleFunc("/cart", getCart).Methods("GET")
|
|
r.HandleFunc("/cart", saveCart).Methods("POST")
|
|
r.HandleFunc("/cart", clearCart).Methods("DELETE")
|
|
|
|
// Add CORS middleware
|
|
corsHandler := handlers.CORS(
|
|
handlers.AllowedOrigins([]string{"http://localhost:3000"}),
|
|
handlers.AllowedMethods([]string{"GET", "POST", "DELETE", "OPTIONS"}),
|
|
handlers.AllowedHeaders([]string{"Content-Type"}),
|
|
)
|
|
|
|
log.Println("Server starting on :8080")
|
|
log.Fatal(http.ListenAndServe(":8080", corsHandler(r)))
|
|
}
|
|
|
|
func getCart(w http.ResponseWriter, r *http.Request) {
|
|
rows, err := db.Query("SELECT id, title, price, quantity FROM cart_items")
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
var cart []CartItem
|
|
for rows.Next() {
|
|
var item CartItem
|
|
err := rows.Scan(&item.ID, &item.Title, &item.Price, &item.Quantity)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
cart = append(cart, item)
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(cart)
|
|
}
|
|
|
|
func saveCart(w http.ResponseWriter, r *http.Request) {
|
|
cookie, err := r.Cookie("cart")
|
|
if err != nil {
|
|
http.Error(w, "Cart not found in cookies", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var newCart []CartItem
|
|
err = json.Unmarshal([]byte(cookie.Value), &newCart)
|
|
if err != nil {
|
|
http.Error(w, "Invalid cart data", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Clear the existing cart
|
|
_, err = db.Exec("DELETE FROM cart_items")
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Insert new items
|
|
for _, item := range newCart {
|
|
_, err = db.Exec("INSERT INTO cart_items (title, price, quantity) VALUES ($1, $2, $3)",
|
|
item.Title, item.Price, item.Quantity)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func clearCart(w http.ResponseWriter, r *http.Request) {
|
|
_, err := db.Exec("DELETE FROM cart_items")
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|