article slider does not work twice on the same page

I have in my website a slider with articles. He has 9 cells.
But I need 9 more cells, and I want them below the first slide. But when I duplicate on index the second slider doesn’t work.

  <section class="slider">
    <div class="card">
        <div class="card-content slider-content">
            <img src="images/FotosDestaque/IMG1.png" alt="" class="card-img">
            <h1 class="card-title">Caixa Cartão Bolo Rei 28x28x7,5</h1>
            <div class="card-body">
                <p class="card-price">0,53€* / caixa</p>
            </div>
            <div class="card-footer slider-footer">
                <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG2.png" alt="" class="card-img">
            <h1 class="card-title">Guardanapo Natal PPP 40x40 Nova Era 24 maços </h1>
            <div class="card-body">
                <p class="card-price">19,93€* / caixa</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG3.png" alt="" class="card-img">
            <h1 class="card-title">Saco plástico alça Natal medida 50x55</h1>
            <div class="card-body">
                <p class="card-price">2,50€* / Kg</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG4.png" alt="" class="card-img">
            <h1 class="card-title">Saqueta Bolo Rei 26+8x42 c/ 500 sacos</h1>
            <div class="card-body">
                <p class="card-price">0,11€* / Saco</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG5.png" alt="" class="card-img">
            <h1 class="card-title">Lava Loiça Profissional Fairy 5 Lts Ultra</h1>
            <div class="card-body">
                <p class="card-price">8,99€* / uni</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG6.png" alt="" class="card-img">
            <h1 class="card-title">Esfregão Saponificado Favir c/6 Unds</h1>
            <div class="card-body">
                <p class="card-price">0,49€* / uni</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG8.png" alt="" class="card-img">
            <h1 class="card-title">Bloco Sanitário Senses 60 Grs</h1>
            <div class="card-body">
                <p class="card-price">0,48€* / uni</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
        <div class="card-content">
            <img src="images/FotosDestaque/IMG7.png" alt="" class="card-img">
            <h1 class="card-title">Toalha de mão 21x22 Amoos c/2800 fls</h1>
            <div class="card-body">
                <p class="card-price">10,46€* / caixa</p>
            </div>
            <div class="card-footer slider-footer">
              <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
            </div>
        </div>
    </div>
    <div class="card">
      <div class="card-content">
          <img src="images/FotosDestaque/IMG9.png" alt="" class="card-img">
          <h1 class="card-title">Tira Nódoas Fun Clorossan Roupa Branca/cor 800grs</h1>
          <div class="card-body">
              <p class="card-price">10,46€* / caixa</p>
          </div>
          <div class="card-footer slider-footer">
            <button onclick="window.location.href='catalogo.php'" class="btn btn-success button-slider">Comprar</button>
          </div>
      </div>
  </div>
    

    <span class="arrow left">&#129120;</span>
    <span class="arrow right">&#129122;</span>
  </section>

  <script src="js/scriptDestaques.js"></script>

This is the index, and when I do copy paste this section the second slider doesn’t work.

:root {
  --primary: #ffffff;
  /* --primary: #fff; */
  --secondary: #13533A;
  --bg: #0e1523;
  /* --bg: #f5f5f5; */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body{
  /*background-color: var(--bg);*/
  overflow-x: hidden;
}

.slider {
  /*background-color: var(--bg);*/
  padding: 1rem;
  height: 100%;
  margin: 7rem auto;
  display: flex;
  /*display: grid;
  grid-template-columns: repeat(4, 1fr);
  place-items: center;
  grid-gap: 2rem;*/

 /* font: normal 1rem sans-serif;*/
}

.card {
  position: relative;
  left: 0;

  min-width: 17rem;
  height: 23rem;
  background-color:var(--primary);
  color: #fff;
  border-radius: 1rem;
  border: .1rem solid transparent;
  overflow: hidden;
  box-shadow: 0 .2rem .6rem #0003;
  transition: .5s ease-in-out;
}

@media screen and (max-width: 768px) {
  .card {
      min-width: 21rem;
  }
}

.card:not(:first-child){
  margin-left: 2rem;
  border: .1rem solid var(--secondary);
}

.card:first-child{
  margin-left: .4rem;
  border: .1rem solid var(--secondary);
}

.card:hover {
  border: .2rem solid var(--secondary);
  transform: scale(1.05);
}

.card .card-top-img{
  margin-top: 2rem;
}

.card::before, .card::after {
  position: absolute;
 /* content: "";
  background-color: var(--secondary);
  border-radius: 50%;
  transition: .5s ease-in-out;*/
  z-index: 100;
}

.card::before {
  top: -6%;
  right: -6%;
  width: 9rem;
  height: 9rem;
}

.card::after {
  bottom: -6%;
  left: -6%;
  width: 5rem;
  height: 5rem;
}

.card:hover::before {
  transform: scale(1.8);
}

.card:hover::after {
  transform: scale(0);
}

.card-content {
  position: absolute;
  top:0;
  left:0;
  width: 100%;
  height: 100%;

  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  z-index: 200;
}

.card-content img {
  margin-top: 2rem;
}

.card-img, 
.card-title {
  transform: translateY(4rem);
  transition: .5s ease-in-out;
  color: #13533A;
  font-size: 18px;
  text-align: center;
}

.card-img {
  width: auto;
  height: 9.5rem;
}

.card-title {
  text-transform: capitalize;
  transition-delay: .1s;
  color: #13533A;
    font-size: 18px;
}

.card-body, 
.card-footer {
  transform: translateY(10rem);
  padding: 0;
  transition: .5s ease-in-out;
}

.card-body {
  width: 100%;

  display: flex;
  justify-content: space-around;
  align-items: center;

  transition-delay: .2s;
}

.card:hover .card-img,
.card:hover .card-title,
.card:hover .card-body,
.card:hover .card-footer {
  transform: translateY(0);
}

.card-footer {
  transition-delay: .3s;
}

.button-slider {
  width: max-content;
  padding: 1rem 1rem;
  text-wrap: nowrap;
  font-size: 0.8rem;
}

.slider-footer {
  width: 100%;
  display: flex;
  justify-content: space-around;
}

.card-body p {
  margin-bottom: 0;
  color: #111;
}




.card-price {
  font: bolder 1.5rem sans-serif;
}

.btn {
  padding: 1rem 2rem;
  background-color: unset;
  border: none;
  outline: none;
  border-radius: 2rem;
  color: #fff;
  cursor: pointer;
}

.btn-success {
  background-color: var(--secondary);
}

.btn-border {
  border: .1rem solid var(--secondary);
}

.arrow{
  position: absolute;
  /* top: 50%; */
  align-self: center;
  /* transform: translateY(-50%); */

  width: 3rem;
  height: 3rem;
  background-color: #fff;
  color: #000;

  border-radius: 50%;
  font: 800 1.5rem sans-serif;
  text-align: center;
  line-height: 3rem;
  user-select: none;
  
  cursor: pointer;
  z-index: 300;
}

.arrow:active {
  background-color: #ddd;
}

.left{
  left: 1rem;
}

.right{
  right: 1rem;
}
const cards = document.querySelectorAll('.card');
const right_arrow = document.querySelector('.arrow.right');
const left_arrow = document.querySelector('.arrow.left');

let left = 0;
let card_size = 25.4;
let total_card_size = cards.length * card_size - card_size * 4;

if(window.matchMedia('(max-width: 768px)').matches){
    card_size = 52;
    total_card_size = cards.length * card_size - card_size * 2;
}

if(window.matchMedia('(max-width: 568px)').matches){
    card_size = 52;
    total_card_size = cards.length * card_size - card_size * 2;
}

left_arrow.onclick = () => {
    left -= card_size;

    if(left <= 0) left = 0;
    moveCards(left);
    checkArrowVisibility(left);
}

left_arrow.style.opacity = '0';


right_arrow.onclick = () => {
    left += card_size;

    if(left >= total_card_size) left = total_card_size;
    moveCards(left);
    checkArrowVisibility(left);
}

function moveCards(left) {
    for(card of cards) {
        card.style.left = -left + "%";
    }
}


function checkArrowVisibility(pos){
    if(pos == 0 ) {
        left_arrow.style.opacity = '0';
    }else {
        left_arrow.style.opacity = '1';
    }
    if(pos >= total_card_size ) {
        right_arrow.style.opacity = '0';
    }else {
        right_arrow.style.opacity = '1';
    }
}

And this is JavaScript.

I have other small thing’s on bootstrap too.

I try to copy paste the code on index.
I was expecting the code duplicate and work fine.

(REACT) Setting a default value to a Dropdown field

I am making a simple frontend to showcase CRUD RESTful API behavior. One of the requirements is, when the option “GET” is selected, to set as a default at the Dropdown field shown in the picture “Order-by” the value “Name”. However, for all the other options, the value should be default “None”.

This is how the specific part of the frontend looks.

const [selectedOrder, setSelectedOrder] = React.useState('');

const handleOrderChange = (event) => { setSelectedOrder(event.target.value); }

So far, the attribute “selected” doesn’t work because the state of the field changes. Setting the defaultValue to name also doesn’t work.

`

Order-by: &nbsp;

<select name="order-by" value={selectedOrder} onChange={handleOrderChange}>

    <option value="">None</option>

    <option value="name" disabled={!isOptionDisabled("GET")}>Name</option>

    <option value="iso" disabled={!isOptionDisabled("GET")}>ISO</option>

    <option value="year" disabled={!isOptionDisabled("GET", "GET emission")}>Year</option>

    <option value="population" disabled={!isOptionDisabled("GET energy per capita")}>Population</option>

</select>

`

(@walletconnect/ethereum-provider)You may need an appropriate loader to handle this file type, currently no loaders are configured to process

this is package.json file configuration

 "next": "9.5.5"
 "next-images": "^1.6.2",
 "next-videos": "^1.4.0",
 "webpack": "^4.42.0"
 "react-relay": "^10.1.2",

these versions are working properly but when I add an updated version of “@walletconnect/ethereum-provider”: from “2.8.5” to “^2.11.0”( Latest ),

it gives me unexpected token errors and does not use the appropriate loader error.

showing some file

tsconfig.js

{
  "compilerOptions": {
    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "module": "esnext",
    "moduleResolution": "node",
    "isolatedModules": true,
    "noImplicitAny": false,
    "jsx": "preserve",
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "include": [
    "next-env.d.ts",
    "./node_modules/web3-typescript-typings/index.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "**/__generated__/**",
    "**/*.graphql.ts",
  ]
}

next.config.js

const withImages = require("next-images");
const withVideos = require("next-videos");

module.exports = withVideos(
  withImages({
    fileExtensions: ["jpg", "jpeg", "png", "gif", "svg"],
    env: {},
    webpack(config, options) {
      if (!options.isServer) {
        config.resolve.alias["@sentry/node"] = "@sentry/browser";
      }
      if (!options.isServer) {
        config.node = {
          fs: "empty",
        };
      }
      config.module.rules.push({
        test: /node_modules[\/]@walletconnect/,
        loader: require.resolve('esbuild-loader'),
      });
      config.module.rules.push({
        test: /node_modules[\/]@metamask/,
        loader: require.resolve('esbuild-loader'),
      });
      config.module.rules.push({
        loader: require.resolve('babel-loader'),
        test: '/.(js|jsx|tsx)$/',
        exclude: /node_modules/,
      });
      return config;
    },
    pageExtensions: ['tsx', 'jsx', 'js']
  })
);

and in package.json added babel-loader also

 "babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      [
        "styled-components",
        {
          "ssr": true,
          "displayName": true,
          "preprocess": false
        }
      ],
      [
        "relay"
      ],
      [
        "@babel/plugin-transform-react-jsx",
        {
          "runtime": "automatic"
        }
      ]
    ]
  }

here is webpack.config.js file

{
  module: {
    rules: [
      {
        test: /.scss$/,
        uese: {
          loader: "sass-loader",
          options: {
            includePaths: [
              path.resolve("../node_modules"), 
            ],
          },
        },
      },
      {
        test: require.resolve('jquery/dist/jquery.slim'),
        use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },{
          loader: 'expose-loader',
          options: '$'
        }]
      }
    ];
  }
}

I am building a predictive model web app for heart disease and i need help addressing these issues

So as I ran localhost 127.0.0.1:5000 I encountered these errors:

127.0.0.1 – – [26/Dec/2023 12:13:46] “POST / HTTP/1.1” 500 –

127.0.0.1 – – [26/Dec/2023 12:13:46] “GET /static/css/soft-ui-dashboard.css HTTP/1.1” 404 –

127.0.0.1 – – [26/Dec/2023 12:13:46] “GET /static/js/api.js HTTP/1.1” 404 –

127.0.0.1 – – [26/Dec/2023 12:13:46] “GET /static/js/soft-ui-dashboard.js HTTP/1.1” 404 –

127.0.0.1 – – [26/Dec/2023 12:13:46] “GET /static/img/ivancik.jpg HTTP/1.1” 404 –

I checked all that needs to be checked and im expecting a user interface where patient’s data can be inputed for predictions

How to keep a loggedin session continued across all the pages of my react app?

I am using firebase email and password as authorization please help!!

This is my App.js. I have tried with navigate but this only works in a single page have but i want to add multiple pages for different classes and there whenever a user is logged in it will redirect me to my home page instead of redirecting to the page of i intended to go to…
I would appreciate that if you can suggest me any other method than using navigate() for home page.
I want to continue my login session across my whole app

App.js code snippet 1
App.js code snippet 2

Data is not updated in react when used useState

I am new to ReactJs .I’m trying to use the useState hook in react function base component but the value of the state is not getting updated when I am calling the function. When receiving data via websocket, it is not possible to update the data on the line graph using the construct useState and useEffect.

client receives data via websocket:

const myWs = new WebSocket('ws://localhost:8000');
// обработчик проинформирует в консоль когда соединение установится
myWs.onopen = function () {
    console.log('подключился');
};

// обработчик сообщений от сервера
myWs.onmessage = function (message) {
    const jsonParse = JSON.parse(message.data);      
    try {   
      
      let temp = {x:setInterval((counter) =>{
        if(mockLineData[0].data.length >= 50){
          mockLineData[0].data.shift();
          counter++
        }
        else{
          counter++
        }
      }, 3000), y:jsonParse[0]['value_state']};
      mockLineData[0].data.push(temp);
      console.log(mockLineData[0].data);

    } catch (error) {
        console.log('Error: ', error);
    }
};




export const mockLineData = [
  {
    id: "ИБП Uвх",
    color: tokens("dark").redAccent[200],
    data: [
      {
        x: 0,
        y: 0
      },
      
    ],
  },
];

Next I’m trying to update data in a table using the construct useState and useEffect

const LineChart = ({ isCustomLineColors = false, isDashboard = false }) => {
  const theme = useTheme();
  const colors = tokens(theme.palette.mode);
  const [state, setState] = useState();
  
  useEffect(() => {
    setInterval(()=>{
      setState(data);
    },1000)
  }, []);


  return (
    <ResponsiveLine
      data={state}
      theme={{
        axis: {
          domain: {
            line: {
              stroke: colors.grey[100],
            },
          },
          legend: {
            text: {
              fill: colors.grey[100],
            },
          },
          ticks: {
            line: {
              stroke: colors.grey[100],
              strokeWidth: 1,
            },
            text: {
              fill: colors.grey[100],
            },
          },
        },
        legends: {
          text: {
            fill: colors.grey[100],
          },
        },
        tooltip: {
          container: {
            color: colors.primary[500],
          },
        },
      }}
      colors={isDashboard ? { datum: "color" } : { scheme: "nivo" }} // added
      margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
      enableGridX={false}
      enableGridY={false}
      pointSize={8}
      pointColor={{ theme: "background" }}
      pointBorderWidth={2}
      pointBorderColor={{ from: "serieColor" }}
      pointLabelYOffset={-12}
      useMesh={true}
      legends={[
        {
          anchor: "bottom-right",
          direction: "column",
          justify: false,
          translateX: 100,
          translateY: 0,
          itemsSpacing: 0,
          itemDirection: "left-to-right",
          itemWidth: 80,
          itemHeight: 20,
          itemOpacity: 0.75,
          symbolSize: 12,
          symbolShape: "circle",
          symbolBorderColor: "rgba(0, 0, 0, .5)",
          effects: [
            {
              on: "hover", //hover
              style: {
                itemBackground: "rgba(0, 0, 0, .03)",
                itemOpacity: 1,
              },
            },
          ],
        },
      ]}
    />
  );
};

export default LineChart;

but the data is not updated

React Native: Issue with State Update – Component Not Re-rendering

I’m currently facing an issue in my React Native project related to state updates and component re-rendering. Even though I’m updating the state, the component doesn’t re-render as expected. Here’s a simplified version of my code:

import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';

export default function MyComponent() {
  const [count, setCount] = useState(0);

  const handleIncrement = () => {
    setCount(count + 1);
    console.log('Count:', count); // Logs the correct incremented value
  };

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={handleIncrement} />
    </View>
  );
}

Although the setCount function updates the state correctly, the component doesn’t re-render immediately, and the logged count value remains the same. I’ve tried using useEffect, but it doesn’t resolve the issue.

Can someone please provide guidance on how to troubleshoot and resolve this problem with state updates not triggering an immediate re-render of the component? Any help or insights would be appreciated. Thank you!

Is there a way of inserting data to database with manay to many relantionship in Prisma?

**These are my models:**
model Category {
  id      Int       @id @default(autoincrement())
  name    String    @unique @db.VarChar(50)
  product Product[]

  @@map("categories")
}

model Product {
  id         Int         @id @default(autoincrement())
  name       String      @unique @db.VarChar(35)
  barcode    String      @unique @db.VarChar(35)
  sell  Decimal     @db.Decimal(12, 2)
  shop Decimal     @db.Decimal(12, 2)
  quantity Int
  expiresIn String
  createdAt  DateTime    @default(now())
  updatedAt  DateTime    @updatedAt
  categoryId Int
  category   Category    @relation(fields: [categoryId], references: [id], onDelete: Cascade, onUpdate: Cascade)
  sales      SaleOrder[]
  purchases PurchaseProduct[]
  
  @@map("products")
}

model PurchaseProduct{
  name  String    @db.VarChar(50)
  sell  Decimal       @db.Decimal(12, 2)
  shop Decimal        @db.Decimal(12, 2)
  quantity Int
  expiresIn String
  purchaseId Int
  purchase   Purchase    @relation(fields: [purchaseId], references: [id], onDelete: Cascade, onUpdate: Cascade)
  productId Int
  product   Product    @relation(fields: [productId], references: [id], onDelete: Cascade, onUpdate: Cascade)

  @@id([purchaseId, productId])

  @@map("purchaseProducts")
}


model Purchase{
   id   Int     @id @default(autoincrement())
  supplierId Int
  supplier   Supplier    @relation(fields: [supplierId], references: [id], onDelete: Cascade, onUpdate: Cascade)
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  purchases PurchaseProduct[]
  @@map("purchases")
}

model Supplier {
  id          Int       @id @default(autoincrement())
  name        String    @unique @db.VarChar(35)
  email       String?   @unique @db.VarChar(35)`your text`
  contact String?   @unique @db.VarChar(10)
  products    Purchase[]

  @@map("suppliers")
}

**What I have tried:**
export async function create(formData: Purchase){
  const purchase = await db.purchase.create({
    data:   {
      name: formData.name,
      sell: formData.sell,
      shop: formData.shop,
      quantity: formData.quantity,
      supplier: {
                  connectOrCreate:{
                    where:{name: formData.supplierName},
                    create:{name: formData.supplierName, contact: formData.phone, email: formData.email}
                }
              },
      product:{
                connectOrCreate:{where:{name:formData.name}, 
                create:{
                      name: FormData.name,
                      barcode: formData.barcode,
                      sell:formData.sell,
                      shop: formData.shop,
                      quantity: formData.quantity,
                      expiresIn: formData.expiresIn,
                      categoryId: formData.categoryId
                    }}
                }}
              })
              
  return purchase;
}

I have tried using connect and connectOrCreate but it did not work, because for each insertion of purchase it may have many products, so my idea is to insert many products of each purchase.
For example, for each purchase there will have product 1, product 2, product 3 and etc. I want to pass array of data/json containg these products and then insert int the three tables at once.

how to loop adding data the same information as before

const ObjectData =[
    { "foo": "baz", "y": "13" },
    { "foo": "baz", "y": "14" },
    { "foo": "baz", "y": "15" },
    { "foo": "baz", "y": "16" },
    { "foo": "baz", "y": "17" }
    ];
  var list = "";
  for (i = 0; i <= ObjectData.length; i++){
     list += ObjectData[i];
  }

how to loop adding data the same information as before
same information as before

Swiper Slider UI Breaks on Page Reload

When initializing the slider in Vue3 and attempting to simulate an API failure with Network request blocking in Chrome DevTools, I encountered an issue where the Swiper UI breaks.

Scenario: API failure → Attempt to reload → UI breaks

enter image description here

Expected Result

enter image description here

Actual Result

enter image description here

Below is a code snippet for your reference:

export default {
  name: 'FixedQR',

  mounted() {
    this.getData()
    this.swiper = new Swiper(this.$refs.swiper, {
      slidesPerView: 'auto',
      watchSlidesProgress: true,
      centeredSlides: true,
      spaceBetween: 40,
      // Disable preloading of all images
      preloadImages: false,
      // Enable lazy loading
      lazy: true,
      observer: true,
      observeParents: true,

      on: {
        slideChange: () => {
          // Prefetch data when scrolling to last 3 objects in array
          if (this.swiper.realIndex === this.qrCodes.length - 3) {
            this.getMoreQR()
          }
        },
      },
    })
  },

Has anyone else experienced a similar situation and can provide a solution? Thanks!

Some issues regarding CSS/JS/toolchain learning [closed]

I have learned about the knowledge of front-end architecture during the front-end development process, which is very novel to me. I searched for the keyword CSS tool chain on YouTube and found that there is very little related content. Therefore, I would like to inquire if there is a similar website that I can learn from, as I am still a student. Thank you!

I tried to query some information keywords on youtube ,it doesn’t fills me.

How to fix this image inside column and have 20px margin from top, left and right?

I have this row of three columns where I want an image in each column and for this image to take 20px margin from top, left and right. margin-right rule is having no effect on image, margin-left makes it move towards right and overlap the other column.

HTML
<div class="row">
  <div class="column">
  <p class="title">News</p>
  <img src="https://circleyoga.com/wp-content/uploads/2023/12/Gift-Box-v2-500x300-1.jpg" alt="">
</div>

CSS 
.row{
 display: flex;
 max-width: 1060px;
 align-items: center;
 justify-content: center;
 margin: 0 auto;
 margin-top: 30px;
 box-sizing: border-box;
}
.column{
 display: inline-block;
 min-height: 500px;
 width: 33.33%;
 border: 5px solid #F8F8F8;
 box-sizing: border-box;
}

.title{
 font-family: 'Nunito Sans', sans-serif;
 font-size: 30px;
 font-weight: 100;
 border-left-style: solid;
 border-left-width: 5px;
 border-color: #d54126;
 padding-left: 13px;
 margin: 10px 0px;
}

.column img{
 display: block;
 max-width: 100%;
 height: auto;
 margin: 20px 20px 0 20px;
}