fix(all) Добавил раздачу картинок через бекенд
@@ -18,6 +18,7 @@ FROM alpine:latest
|
|||||||
WORKDIR /root/
|
WORKDIR /root/
|
||||||
|
|
||||||
COPY --from=builder /app/main .
|
COPY --from=builder /app/main .
|
||||||
|
COPY --from=builder /app/uploads ./uploads
|
||||||
|
|
||||||
EXPOSE 8090
|
EXPOSE 8090
|
||||||
CMD ["./main"]
|
CMD ["./main"]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -19,6 +20,12 @@ func GetItem(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if item.AvatarURL != "" {
|
||||||
|
item.AvatarURL = fmt.Sprintf("/static/items/%s", item.AvatarURL)
|
||||||
|
} else {
|
||||||
|
item.AvatarURL = fmt.Sprintf("/static/items/background.png")
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, item)
|
c.JSON(http.StatusOK, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +37,14 @@ func GetAllItems(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range items {
|
||||||
|
if items[i].AvatarURL != "" {
|
||||||
|
items[i].AvatarURL = fmt.Sprintf("/static/items/%s", items[i].AvatarURL)
|
||||||
|
} else {
|
||||||
|
items[i].AvatarURL = fmt.Sprintf("/static/items/background.png")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, items)
|
c.JSON(http.StatusOK, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ func main() {
|
|||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
|
r.Static("/static", "./uploads")
|
||||||
|
|
||||||
err := godotenv.Load()
|
err := godotenv.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Файл .env не был найден в папке backend, использую системные переменные")
|
log.Println("Файл .env не был найден в папке backend, использую системные переменные")
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
Unit string `json:"unit"`
|
Unit string `json:"unit"`
|
||||||
Price int `json:"price"`
|
Price int `json:"price"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
|
Stock float64 `gorm:"default:0" json:"stock"`
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 9.8 MiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 741 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 328 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -21,6 +21,10 @@ server {
|
|||||||
proxy_pass http://backend:8081;
|
proxy_pass http://backend:8081;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
proxy_pass http://backend:8081;
|
||||||
|
}
|
||||||
|
|
||||||
# Сама статика React
|
# Сама статика React
|
||||||
location / {
|
location / {
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
|||||||
@@ -20,22 +20,7 @@ export default function CardItem({ item, onAddToCart }) {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col text-white w-full">
|
<div className="flex flex-col text-white w-full">
|
||||||
<div className="w-full rounded-md overflow-hidden bg-slate-800/60 flex flex-col h-100 items-center justify-center border border-slate-700/50 select-none">
|
<div className="w-full rounded-md overflow-hidden bg-slate-800/60 flex flex-col h-100 items-center justify-center border border-slate-700/50 select-none">
|
||||||
<svg
|
<img src={item.avatar_url} alt={item.name} className="object-cover" />
|
||||||
className="w-12 h-12 text-slate-600 mb-2"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth={1.5}
|
|
||||||
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 002-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<span className="text-xs text-slate-500 font-medium uppercase tracking-wider">
|
|
||||||
Изображение товара
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Блок с информацией о товаре */}
|
{/* Блок с информацией о товаре */}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export default function Shop() {
|
|||||||
return (
|
return (
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
<main className="px-6 md:px-16 grow w-full mb-6">
|
<main className="px-6 md:px-16 grow w-full mb-6">
|
||||||
<div className="flex flex-col text-white text-2xl font-medium ">
|
<div className="flex flex-col text-white text-2xl font-medium">
|
||||||
<div className="uppercase text-2xl md:text-4xl md:mt-10">
|
<div className="uppercase text-2xl md:text-4xl md:mt-10">
|
||||||
fish fish
|
fish fish
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ export default function Contact() {
|
|||||||
return (
|
return (
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
<main className="px-6 md:px-16 grow w-full mb-6">
|
<main className="px-6 md:px-16 grow w-full mb-6">
|
||||||
<div className="w-full overflow-hidden rounded shadow-md ">
|
<div>
|
||||||
<iframe
|
<div className="text-2xl text-white">Контакты</div>
|
||||||
src="https://yandex.ru/map-widget/v1/?um=constructor%3Aaee46827fd51e482587f99245635b92b3d473b8d2aef2b4e36f83ddfaaf77cb9&source=constructor"
|
<div className="w-full overflow-hidden rounded shadow-md ">
|
||||||
className="w-full h-127.5 border-0 "
|
<iframe
|
||||||
title="Yandex Map"
|
src="https://yandex.ru/map-widget/v1/?um=constructor%3Aaee46827fd51e482587f99245635b92b3d473b8d2aef2b4e36f83ddfaaf77cb9&source=constructor"
|
||||||
/>
|
className="w-full h-127.5 md:h-[340px] border-0"
|
||||||
|
title="Yandex Map"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
|
|||||||