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
+
+
+ | Product ID |
+ Name |
+ Price |
+ Action |
+
+ {{range .Products}}
+
+ | {{.ID}} |
+ {{.Name}} |
+ {{.Price}} |
+
+ Edit |
+ Delete
+ |
+
+ {{end}}
+
+
+ Add a New Product
+
+
+ Cart
+
+
+ | Product ID |
+ Quantity |
+
+ {{range .Cart}}
+
+ | {{.ProductID}} |
+ {{.Quantity}} |
+
+ {{end}}
+
+
+
+ `)
+ 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))
+}