From 56b851aba661f5e10a24bb7a1c69121928fc2933 Mon Sep 17 00:00:00 2001 From: User Date: Fri, 3 Jan 2025 21:34:48 +0300 Subject: [PATCH] saved --- cmd/server/main.go | 329 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 cmd/server/main.go diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 0000000..f6c655d --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,329 @@ +package main + +import ( + "encoding/json" + "fmt" + "html/template" + "log" + "net/http" + "strconv" + "sync" +) + +type Product struct { + ID int `json:"id"` + Name string `json:"name"` + Price float64 `json:"price"` +} + +var ( + products []Product + mu sync.Mutex // Для безопасного доступа к списку продуктов + nextID int = 1 // Для автоматической генерации ID +) + +// Структура для передачи данных в шаблон +type PageData struct { + Products []Product + Cart []CartItem +} + +type CartItem struct { + ProductID int `json:"product_id"` + UserID int `json:"user_id"` + Quantity int `json:"quantity"` + CreatedID int `json:"created_id"` +} + +// Получение корзины из cookies +func GetCartFromCookie(r *http.Request) ([]CartItem, error) { + // Read the cookie + cookie, err := r.Cookie("cart") + if err != nil { + if err == http.ErrNoCookie { + // If no cookie, return an empty cart + return []CartItem{}, nil + } + return nil, fmt.Errorf("failed to read cart cookie: %w", err) + } + + // Check if the cookie value looks like JSON + var cart []CartItem + err = json.Unmarshal([]byte(cookie.Value), &cart) + if err != nil { + log.Println("Invalid cart cookie value, resetting cart.") + return []CartItem{}, nil // Reset to an empty cart on error + } + + return cart, nil +} + +// Сохранение корзины в cookies +func SetCartCookie(w http.ResponseWriter, cart []CartItem) error { + cartJSON, err := json.Marshal(cart) + if err != nil { + return fmt.Errorf("failed to serialize cart: %w", err) + } + + // Устанавливаем cookie с корзиной + http.SetCookie(w, &http.Cookie{ + Name: "cart", + Value: string(cartJSON), + Path: "/", + }) + return nil +} +func renderTemplate(w http.ResponseWriter, r *http.Request, cart []CartItem) { + tmpl, err := template.New("index").Parse(` + + + + + + Products + + + +

Products

+ + + + + + + + {{range .Products}} + + + + + + + {{end}} +
Product IDNamePriceAction
{{.ID}}{{.Name}}{{.Price}} + Edit | + Delete +
+ +

Add a New Product

+
+ +

+ + +

+ + +
+ +

Cart

+ + + + + + {{range .Cart}} + + + + + {{end}} +
Product IDQuantity
{{.ProductID}}{{.Quantity}}
+ + + `) + if err != nil { + log.Println("Error parsing template:", err) + http.Error(w, "Error parsing template", http.StatusInternalServerError) + return + } + + // Передаем данные продукта и корзины в шаблон + data := PageData{ + Products: products, + Cart: cart, + } + + err = tmpl.Execute(w, data) + if err != nil { + log.Println("Error executing template:", err) + http.Error(w, "Error executing template", http.StatusInternalServerError) + return + } +} + +func AddProduct(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodPost { + // Получаем данные из формы + name := r.FormValue("name") + price := r.FormValue("price") + + // Преобразуем цену в float + var priceFloat float64 + _, err := fmt.Sscanf(price, "%f", &priceFloat) + if err != nil { + http.Error(w, "Invalid price", http.StatusBadRequest) + return + } + + // Создаем новый продукт + mu.Lock() + product := Product{ + ID: nextID, + Name: name, + Price: priceFloat, + } + nextID++ + products = append(products, product) + mu.Unlock() + + // Перенаправляем пользователя на главную страницу после добавления продукта + http.Redirect(w, r, "/", http.StatusFound) + return + } + + // Получаем корзину из cookies + cart, err := GetCartFromCookie(r) + if err != nil { + http.Error(w, fmt.Sprintf("Error reading cart: %v", err), http.StatusInternalServerError) + return + } + + // Отображаем шаблон с обновленным списком продуктов и корзиной + renderTemplate(w, r, cart) +} + +func EditProduct(w http.ResponseWriter, r *http.Request) { + idStr := r.URL.Path[len("/edit/"):] + + id, err := strconv.Atoi(idStr) + if err != nil { + http.Error(w, "Invalid product ID", http.StatusBadRequest) + return + } + + // Ищем продукт по ID + var product *Product + for i := range products { + if products[i].ID == id { + product = &products[i] + break + } + } + + if product == nil { + http.Error(w, "Product not found", http.StatusNotFound) + return + } + + if r.Method == http.MethodPost { + // Обновляем детали продукта + product.Name = r.FormValue("name") + price := r.FormValue("price") + var priceFloat float64 + _, err := fmt.Sscanf(price, "%f", &priceFloat) + if err != nil { + http.Error(w, "Invalid price", http.StatusBadRequest) + return + } + product.Price = priceFloat + + // Перенаправляем на главную страницу + http.Redirect(w, r, "/", http.StatusFound) + return + } + + // Получаем корзину из cookies + // cart, err := GetCartFromCookie(r) + // if err != nil { + // http.Error(w, fmt.Sprintf("Error reading cart: %v", err), http.StatusInternalServerError) + // return + // } + + // Отображаем форму редактирования продукта + tmpl := ` +

Edit Product

+
+ +

+ + +

+ + +
+ ` + + tmplParsed, err := template.New("edit").Parse(tmpl) + if err != nil { + http.Error(w, "Error parsing template", http.StatusInternalServerError) + return + } + + // Передаем данные продукта в шаблон + tmplParsed.Execute(w, product) +} + +func DeleteProduct(w http.ResponseWriter, r *http.Request) { + idStr := r.URL.Path[len("/delete/"):] + + id, err := strconv.Atoi(idStr) + if err != nil { + http.Error(w, "Invalid product ID", http.StatusBadRequest) + return + } + + // Находим индекс продукта для удаления + mu.Lock() + defer mu.Unlock() + for i, product := range products { + if product.ID == id { + // Удаляем продукт из списка + products = append(products[:i], products[i+1:]...) + break + } + } + + // Получаем корзину из cookies + cart, err := GetCartFromCookie(r) + if err != nil { + http.Error(w, fmt.Sprintf("Error reading cart: %v", err), http.StatusInternalServerError) + return + } + + // Сохраняем обновленную корзину в cookies (если необходимо) + err = SetCartCookie(w, cart) + if err != nil { + http.Error(w, fmt.Sprintf("Error setting cart cookie: %v", err), http.StatusInternalServerError) + return + } + + // Перенаправляем на главную страницу + http.Redirect(w, r, "/", http.StatusFound) +} + +func main() { + // Обработчики маршрутов + http.HandleFunc("/add", AddProduct) + http.HandleFunc("/edit/", EditProduct) + http.HandleFunc("/delete/", DeleteProduct) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Получаем корзину из cookies + cart, err := GetCartFromCookie(r) + if err != nil { + http.Error(w, fmt.Sprintf("Error reading cart: %v", err), http.StatusInternalServerError) + return + } + + // Отображаем шаблон с корзиной + renderTemplate(w, r, cart) + }) + + log.Println("Server is running on http://localhost:8080") + log.Fatal(http.ListenAndServe(":8080", nil)) +}