What could be causing the JavaScript code to not execute in the process.php file, and how can I resolve this issue?

Description: I’m working on a PHP script that should automatically click an email link using JavaScript. The code works fine in a separate test.php file, but in process.php, the JavaScript doesn’t execute. Below is the relevant code:

<?php
include_once 'libs/load.php';
if (isset($_POST['command'])) {
    $command = trim($_POST['command']);
    handleCommand($command);
}

function handleCommand($command)
{
    switch ($command) {
        case 'email':
            $email = "[email protected]";
            echo "<html><body>";
            echo "<a id="emailLink" href="mailto:$email" style="color: rgb(5, 206, 145);">$email</a>";
            echo "<script type="text/javascript">
                    document.addEventListener('DOMContentLoaded', function() {
                        console.log('JavaScript is running');
                        alert('JavaScript is running');
                        document.getElementById('emailLink').click();
                    });
                  </script>";
            echo "</body></html>";
            break;
        default:
            echo "---n";
            echo "Unknown command: $commandn";
            echo "---";
            break;
    }
}
?>    

show/hide 2 divs with 2 buttons independently

I’m new to programming and would appreciate help from someone patient, because my I’m trying to improve my knowledge. I can easily learn by comparing code I wrote with an improved version, where I can see exactly where changes were made.

I create two divs (audiodescription-text and options-wrapper). I want to toggle their visibility independently. In other words, the visibility of one div doesn’t affect another one’s visibility. That’s why I created 2 buttons, one for each div.

However, with the following code, when you click in any button, the same div is hidden or shown.
(I posted the full code here, because it’s easier for testing, instead of posting a fragment of code that cannot generate a working webpage).

Can someone help me with the parts of the code that need to be changed for the divs to be shown or hidden independently?

<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sketchfab Configurator</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">

<body>
<div id="audiodescription-instructions"> 
    <button_audiodescription id="button_audiodescription" onclick="showHideButtonAudiodescription()">Exibir audiodescrição</button_audiodescription> 
    <div style="display:none"; id="audiodescription-text"><p>
        [AUDIODESCRIÇÃO: representação tridimensional colorida de uma célula eucariótica seccionada, ou seja, cortada ao meio para mostrar as principais estruturas constituintes.<br><br>
        
        Para facilitar a compreensão e considerando a posição inicial em que o modelo tridimensional é carregado, a apresentação e a descrição das estruturas são feitas da esquerda para a direita e de fora para dentro, ou seja, as mais externas primeiro e em seguida as mais internas. Inicialmente são descritas as estruturas em primeiro plano, para depois serem descritas as estruturas em planos mais ao fundo.<br><br>
        
        A célula eucariótica apresenta formato irregular, mais próximo do arredondado, sendo delimitada pela membrana plasmática com superfície é lisa. Internamente, apresenta citoplasma e organelas.<br><br>
        
        Em uma célula real as organelas não possuem posição fixa, podendo variar de localização. Neste modelo tridimensional, em primeiro plano e à esquerda, encontram-se lisossomos, pequenas organelas de formato arredondado. Mais à direita está o Complexo de Golgi formado por sacos achatados e empilhados, interconectados por vesículas. Um pouco mais atrás, e à esquerda do lisossomo, encontra-se um endossomo, com formato arredondado similar aos lisossomos, porém de maior diâmetro. Segue-se o retículo endoplasmático rugoso, rede de cisternas e túbulos interconectados que possuem ribossomos aderidos à sua face externa, os quais estão representados como pequenos grânulos arredondados. À direita do retículo endoplasmático rugoso, está uma mitocôndria, de formato alongado e cilíndrico e com cristas mitocondriais de formato ondulado em seu interior. Logo atrás está um proteassomo, estrutura pequena, de formato cilíndrico, cujas extremidades apresentam projeções. Do lado direito do proteassomo está o retículo endoplasmático liso, formado por tubos alongados interconectados. Do lado direito do retículo endoplasmático liso está o núcleo, grande esfera com superfície lisa, dotada de poros circulares. O núcleo está seccionado de forma a mostrar, em sua região central, o nucléolo de formato também esférico. Finalmente, ao fundo, no extremo esquerdo, encontram-se dois centríolos de formato cilíndrico e dispostos perpendicularmente um ao outro, e no extremo direito, dois peroxissomos, organelas de formato circular semelhante ao endossomo e ao lisossomo.<br><br>
        
        FIM DA AUDIODESCRIÇÃO.]</p>
    </div>
</div> 

<div class="sketchfab-container">
    <iframe
        src=""
        id="api-frame"
        allow="autoplay; fullscreen; xr-spatial-tracking"
        xr-spatial-tracking
        execution-while-out-of-viewport
        execution-while-not-rendered
        web-share
        allowfullscreen
        mozallowfullscreen="true"
        webkitallowfullscreen="true"
        height="1000"
        width="100%"
    ></iframe>
    
<div id="model-instructions">
    <p>Selecione a cor desejada para cada estrutura:</p>
    <button_model id="button_model" onclick="showHideButtonModel()">Exibir opções de cores</button_model>
    <div style="display:none"; id="options-wrapper">
    <div class="options" id="color-picker">
    </div>
    </div>
</body>

<script> 
    var div = document.getElementById('audiodescription-text');
           var display = 1;
           function showHideButtonAudiodescription()
           {
             if (display == 0)
             {
               div.style.display = 'none';
               display = 1;
               document.querySelector("button_audiodescription").innerHTML = "Exibir audiodescrição";
             }
             else
             {
               div.style.display = 'inherit';
               display = 0;
               document.querySelector("button_audiodescription").innerHTML = "Ocultar audiodescrição";
             }
             }
     
   </script>

<script> 
    var div = document.getElementById('options-wrapper');
            var display = 1;
            function showHideButtonModel()
            {
            if (display == 0)
            {
                div.style.display = 'none';
                display = 1;
                document.querySelector("button_model").innerHTML = "Exibir audiodescrição";
            }
            else
            {
         div.style.display = 'inherit';
         display = 0;
         document.querySelector("button_model").innerHTML = "Ocultar audiodescrição";
       }
       }
</script>

<script type="text/javascript" src="./assets/js/sketchfab-viewer-1.3.2.js"></script>
<script type="text/javascript" src="./assets/js/SketchfabConfigurator-1.0.6.js"></script>
<script type="text/javascript">
var config = { 
    
"model": "066fa44695014754ad13f0e69ddda1c3",
"params": {
    "camera": 0,
    "autoplay": 0,
    "preload": 1,
    "ui_controls": 0,
    "ui_infos": 0,
    "ui_watermark": 0
},
"config": [
    {
        "name": "01. Parede Celular",
        "type": "color",
        "material": "Parede",
        "default": "#b27e00",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688313518707
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688313518707
            },
            {
                "name": "Branco",
                "color": "#ffffff",
                "id": 1688313518707
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688313518707
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688313518707
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688313518707
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688313518707
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688313518707
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688313518707
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688313518707
            }
        ]
    },
    {
        "name": "02. Cílios",
        "type": "color",
        "material": "Cilios",
        "default": "#a9821b",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688313690276
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688313690276
            },
            {
                "name": "Branco",
                "color": "#ffffff",
                "id": 1688313690276
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688313690276
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688313690276
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688313690276
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688313690276
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688313690276
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688313690276
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688313690276
            }
        ]
    },
    {
        "name": "03. Membrana Plasmática",
        "type": "color",
        "material": "Membrana",
        "default": "#e7710c",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688313830703
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688313830703
            },
            {
                "name": "Branco",
                "color": "#ffffff",
                "id": 1688313830703
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688313830703
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688313830703
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688313830703
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688313830703
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688313830703
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688313830703
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688313830703
            }
        ]
    },
    {
        "name": "04.Citoplasma",
        "type": "color",
        "material": "Citoplasma",
        "default": "#e7e7e7",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688313956926
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688313956926
            },
            {
                "name": "Branco",
                "color": "#ffffff",
                "id": 1688313956926
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688313956926
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688313956926
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688313956926
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688313956926
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688313956926
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688313956926
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688313956926
            }
        ]
    },
    {
        "name": "05. Ribossomos",
        "type": "color",
        "material": "Ribossomos",
        "default": "#e300e7",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688314141902
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688314141902
            },
            {
                "name": "Branco",
                "color": "#FFFFFF",
                "id": 1688314141902
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688314141902
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688314141902
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688314141902
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688314141902
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688314141902
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688314141902
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688314141902
            }
        ]
    },
    {
        "name": "06. Material Genético",
        "type": "color",
        "material": "Material Genetico",
        "default": "#00c8e7",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688314249006
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688314249006
            },
            {
                "name": "Branco",
                "color": "#FFFFFF",
                "id": 1688314249006
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688314249006
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688314249006
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688314249006
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688314249006
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688314249006
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688314249006
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688314249006
            }
        ]
    },
    {
        "name": "07. Plasmídio",
        "type": "color",
        "material": "Plasmidio",
        "default": "#0011e7",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688314352195
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688314352195
            },
            {
                "name": "Branco",
                "color": "#FFFFFF",
                "id": 1688314352195
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688314352195
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688314352195
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688314352195
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688314352195
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688314352195
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688314352195
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688314352195
            }
        ]
    },
    {
        "name": "08. Flagelo",
        "type": "color",
        "material": "Flagelo",
        "default": "#834520",
        "options": [
            {
                "name": "Preto",
                "color": "#000000",
                "id": 1688314449619
            },
            {
                "name": "Cinza",
                "color": "#b3b3b3",
                "id": 1688314449619
            },
            {
                "name": "Branco",
                "color": "#FFFFFF",
                "id": 1688314449619
            },
            {
                "name": "Vermelho",
                "color": "#db2828",
                "id": 1688314449619
            },
            {
                "name": "Laranja",
                "color": "#f2711c",
                "id": 1688314449619
            },
            {
                "name": "Amarelo",
                "color": "#fbbd08",
                "id": 1688314449619
            },
            {
                "name": "Verde",
                "color": "#21ba45",
                "id": 1688314449619
            },
            {
                "name": "Azul",
                "color": "#2185d0",
                "id": 1688314449619
            },
            {
                "name": "Roxo",
                "color": "#a333c8",
                "id": 1688314449619
            },
            {
                "name": "Rosa",
                "color": "#e03997",
                "id": 1688314449619
            }
        ]
    }
].map((e) => {
    return {
      ...e,
      options: e.options.map((f) => ({
        color: f.color,
        id: f.id,
      })),
    };
  })
};
var iframeEl = document.getElementById('api-frame');
var optionsEl = document.querySelector('.options');
var configurator = new SketchfabConfigurator.Configurator(iframeEl, optionsEl, config);
</script>

Here is the styles.css

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  font-family: 'Quicksand', sans-serif;  /* Altere aqui a fonte e o tamanho da fonte */
  box-sizing: border-box;
  font-size: 12px;
}

#audiodescription-instructions {
  width: 100%;
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding-top: 10px;
}

button_audiodescription{ /* Altere aqui as configurações visuais do botão em estado normal*/
  padding: 6px 24px;
  text-align: center;
  font-family: 'Quicksand', sans-serif;
  color: #0d6efd;
  font-size: 14px;
  border: solid;
  border-width: 1px;
  border-color: #0d6efd;
  border-radius: 8px;
  cursor: pointer;
}

button_audiodescription:hover{ /* Altere aqui as configurações visuais do botão em estado normal*/
  color: white;
  background-color: #0d6efd;
}

#audiodescription-text {/* Criar aqui uma classe para conter a interface de seleção de cores */
  margin: 20px;
  padding-left: 15px;
  padding-right: 15px;
  padding-bottom: 15px;
  border-width: 1px;
  border-style: solid;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
  letter-spacing: 0.12px;
  border-width: 1px;
  border-style: solid;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
}

.sketchfab-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 900px;
  overflow: hidden; /* Oculte aqui a barra de rolagem */
}

iframe {
  width: 100%;
  height: 70%;
  margin-bottom: 0px; /* Oculte aqui a borda */
  border: none;
}

#model-instructions { /* Criar aqui uma classe para exibir texto com instrução de seleção de cores. Este será o elemento-pai */
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding-top: 10px;
}

button_model{ /* Altere aqui as configurações visuais do botão em estado normal*/
  padding: 6px 24px;
  text-align: center;
  font-family: 'Quicksand', sans-serif;
  color: #0d6efd;
  font-size: 14px;
  border: solid;
  border-width: 1px;
  border-color: #0d6efd;
  border-radius: 8px;
  cursor: pointer;
}

button_model:hover{ /* Altere aqui as configurações visuais do botão em estado normal*/
  color: white;
  background-color: #0d6efd;
}

#options-wrapper {/* Criar aqui uma classe para conter a interface de seleção de cores */
  width: 100%;
  display: flex;
  flex-direction:row;
  justify-content: center;
  margin: 20px
}

.options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 0 50px;
}

.option {
  display: flex;
  flex-direction: column;
  gap: 4px; /* Altere aqui o espaçamento entre o nome da estrutura e os quadrados de cores. O espaçamento original é 8px */
  padding: 12px 0; /* Altere aqui o espaçamento geral entre as linhas. O espaçamento original é 16px */
}

.color {
  display: flex;
  align-items: center;
  padding: 1px 0; /* Altere aqui o espaçamento entre as linhas no menu de seleção de cores. O espaçamento original é 4px */
}

.color input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.option__control {
  display: flex; /* Altere aqui o espaçamento horizontal entre os quadrados de cores. O espaçamento original é 8px */
  gap: 3px;
}

.color__swatch {
  display: inline-block;
  width: 24px;
  height: 24px; /* Altere aqui a curvatura da borda do quadrado de cores. A curvatura orginal é 8px */
  border-radius: 4px; /* Altere aqui o tamanho do quadrado de cores. O tamanho original é 25px */
  width: 20px;
  height: 20px;
  border: 1px solid rgba(0, 0, 0, 0.5);
  margin-right: 4px;
}

.color input:checked + .color__swatch { /* Altere aqui a borda da cor atualmente atribuída a determinada estrutura. A cor original é #000 */
  box-shadow: 0 0 0 2px #fff;
}

.color:hover .color__swatch {
  box-shadow: 0 0 0 2px #999;
}

.texture {
  display: block;
  position: relative;
  margin-bottom: 10px;
}

.texture input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.texture__preview {
  display: block;
}

.texture__preview img {
  display: block;
  max-width: 100%;
  height: auto;
}

.texture input:checked + .texture__preview > img {
  box-shadow: 0 0 0 2px #000;
}

.texture__name {
  display: block;
  margin-top: 4px;
} /* Aqui termina o conteúdo do arquvo styles.css */

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  font-family: 'Quicksand', sans-serif;  /* Altere aqui a fonte e o tamanho da fonte */
  box-sizing: border-box;
  font-size: 12px;
}

#audiodescription-instructions {
  width: 100%;
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding-top: 10px;
}

button_audiodescription{ /* Altere aqui as configurações visuais do botão em estado normal*/
  padding: 6px 24px;
  text-align: center;
  font-family: 'Quicksand', sans-serif;
  color: #0d6efd;
  font-size: 14px;
  border: solid;
  border-width: 1px;
  border-color: #0d6efd;
  border-radius: 8px;
  cursor: pointer;
}

button_audiodescription:hover{ /* Altere aqui as configurações visuais do botão em estado normal*/
  color: white;
  background-color: #0d6efd;
}

#audiodescription-text {/* Criar aqui uma classe para conter a interface de seleção de cores */
  margin: 20px;
  padding-left: 15px;
  padding-right: 15px;
  padding-bottom: 15px;
  border-width: 1px;
  border-style: solid;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
  letter-spacing: 0.12px;
  border-width: 1px;
  border-style: solid;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
}

.sketchfab-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 900px;
  overflow: hidden; /* Oculte aqui a barra de rolagem */
}

iframe {
  width: 100%;
  height: 70%;
  margin-bottom: 0px; /* Oculte aqui a borda */
  border: none;
}

#model-instructions { /* Criar aqui uma classe para exibir texto com instrução de seleção de cores. Este será o elemento-pai */
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding-top: 10px;
}

button_model{ /* Altere aqui as configurações visuais do botão em estado normal*/
  padding: 6px 24px;
  text-align: center;
  font-family: 'Quicksand', sans-serif;
  color: #0d6efd;
  font-size: 14px;
  border: solid;
  border-width: 1px;
  border-color: #0d6efd;
  border-radius: 8px;
  cursor: pointer;
}

button_model:hover{ /* Altere aqui as configurações visuais do botão em estado normal*/
  color: white;
  background-color: #0d6efd;
}

#options-wrapper {/* Criar aqui uma classe para conter a interface de seleção de cores */
  width: 100%;
  display: flex;
  flex-direction:row;
  justify-content: center;
  margin: 20px
}

.options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 0 50px;
}

.option {
  display: flex;
  flex-direction: column;
  gap: 4px; /* Altere aqui o espaçamento entre o nome da estrutura e os quadrados de cores. O espaçamento original é 8px */
  padding: 12px 0; /* Altere aqui o espaçamento geral entre as linhas. O espaçamento original é 16px */
}

.color {
  display: flex;
  align-items: center;
  padding: 1px 0; /* Altere aqui o espaçamento entre as linhas no menu de seleção de cores. O espaçamento original é 4px */
}

.color input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.option__control {
  display: flex; /* Altere aqui o espaçamento horizontal entre os quadrados de cores. O espaçamento original é 8px */
  gap: 3px;
}

.color__swatch {
  display: inline-block;
  width: 24px;
  height: 24px; /* Altere aqui a curvatura da borda do quadrado de cores. A curvatura orginal é 8px */
  border-radius: 4px; /* Altere aqui o tamanho do quadrado de cores. O tamanho original é 25px */
  width: 20px;
  height: 20px;
  border: 1px solid rgba(0, 0, 0, 0.5);
  margin-right: 4px;
}

.color input:checked + .color__swatch { /* Altere aqui a borda da cor atualmente atribuída a determinada estrutura. A cor original é #000 */
  box-shadow: 0 0 0 2px #fff;
}

.color:hover .color__swatch {
  box-shadow: 0 0 0 2px #999;
}

.texture {
  display: block;
  position: relative;
  margin-bottom: 10px;
}

.texture input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.texture__preview {
  display: block;
}

.texture__preview img {
  display: block;
  max-width: 100%;
  height: auto;
}

.texture input:checked + .texture__preview > img {
  box-shadow: 0 0 0 2px #000;
}

.texture__name {
  display: block;
  margin-top: 4px;
} /* Aqui termina o conteúdo do arquvo styles.css */

Google sheets function using in Voiceflow

I’m using a function made in JavaScript in a platform called voiceflow. It has an input variable known as range which only fetches a specified sheet name data. I want to modify the function to fetch data from all sheets in the Google spreadsheet.

export default async function main(args) {
const { google_sheets_api_key, spreadsheet_link, range } = 
args.inputVars;

if (!google_sheets_api_key || !spreadsheet_link || !range) {
return {
  next: { path: 'error' },
  trace: [{ type: "debug", payload: { message: "Missing required input variables for Google Sheets API function" } }]
};
}

const spreadsheetIdRegex = //d/([a-zA-Z0-9-_]+)/;
const match = spreadsheetIdRegex.exec(spreadsheet_link);
if (!match) {
return {
  next: { path: 'error' },
  trace: [{ type: "debug", payload: { message: "Invalid Google Sheets URL" } }]
};
}
const spreadsheet_id = match[1];

const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheet_id}/values/${range}?key=${google_sheets_api_key}`;

try {
const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json' } });
const responseBody = response.json;

if (!responseBody || typeof responseBody !== 'object') {
  return {
    next: { path: 'error' },
    trace: [{ type: "debug", payload: { message: "Invalid or missing response body from Google Sheets API" } }]
  };
}

// Simplifying the return object for testing
return {
  outputVars: { sheetData: JSON.stringify(responseBody) }, // Temporarily return the response as a string
  next: { path: 'success' },
  trace: [{ type: "debug", payload: { message: "Response Body: " + JSON.stringify(responseBody) } }]
};
} catch (error) {
return {
  next: { path: 'error' },
  trace: [{ type: "debug", payload: { message: "Error fetching data from Google Sheets: " + error.message } }]
};
}
}

I have tried the app script, but it truncates the data due to large data output. I need help to modify the function to fetch data from all the sheets present in the spreadsheet.
I have tried a lot of different modified functions but all of them have the same error which response.json is not a function.

in my ubuntu pc i cant connect blutooth becuz default controller not present how to install

i installed gnome in my pd my mistake so got it reformmatted it to get back it normal but now there is no default controller in it so i m unable to connect my bluetooth headphones can i install it myself or i need to call for expert help. and ya my computer have ubuntu not windows

i have tried some solutions on web but no result and i have no experience in ubuntu also so i do not even know basics but tried few codes they did not help
i really need to fix this so someone please help i tried instally bluez and other softwares to but it came out that those were already installed

Converted Model Using TensorFlow.JS Converter Not Working

I was following the TFJS WebML YT Course from Jason Mayes and following along to the TFJS Converter video, here’s my notebook:
Google Colab Notebook

Basically it is an exact replica from the video and with a few extra warnings here and there, the model files were generated:
MobileNetV2.zip

On my site, I used TFJS with tf.loadLayersModel(‘URL OF MODEL.JSON’) but an error was given saying an InputLayer should have been passed either a batchInputShape or an inputShape. There is a batch_shape in the model.json though. TFJS is up to date, no clue whats going on.

I am trying to convert a MobileNetV3-Large actually but the same thing happened too and I was left with this (using same notebook as earlier but replacing tf.keras.applications.MobileNetV2 with tf.keras.applications.MobileNetV3Large, but got same results as earlier):
MobileNetV3-Large.zip

Any help appreciated! This is probably just me stupid as I’m learning TF/TFJS and ML in general, so sorry in advance!

Thanks, and have a good one!

Ploting the coinbase API in stream line chartjs

I have coinbase websocket where I am trying to consume the realtime data level2_bactch and plot it into the stream line chart js.

I have restructured the data acccordingly but not able to print it.

https://codesandbox.io/p/sandbox/dazzling-neumann-qjw7yv
https://docs.cdp.coinbase.com/exchange/docs/websocket-channels/#level2-channel

  • I have this in my local where, I have the websocket inside my component and in the example i am trying insde a custom hook

Update/PUT doesnt work using Redux toolkit. data from frontend to slice goes as undefined. Check the picture

Let me tell you that my create(POST) and view(GET) works fine, but PUT or update doesn’t work.

FrontEnd: send Invoice VIN number to modify/Update using PUT using Redux-Toolkit:

import Navigation from "../Auth/Navigation";
import Box from "@mui/material/Box";
import { useUpdateSavedInvoiceByIdMutation } from "../../../redux/api/invoiceApiSlice";

import { useParams } from "react-router-dom";
import { toast } from "react-toastify";
import { useState } from "react";

const SingleSavedInvoice = () => {
  const { id: invoiceID } = useParams();

  const [vinNumber, setVinNumber] = useState("12344024124474484");

  const [
    updateSavedInvoiceById,
    error,
    isLoading,
    isFetching,
    isError,
    isSuccess,
  ] = useUpdateSavedInvoiceByIdMutation();

  console.log(error, isLoading, isError, isSuccess, isFetching);

  const handleFormSubmit = async (e) => {
    e.preventDefault();
    try {
      const data = await updateSavedInvoiceById({
        vinNumber,
        invoiceID,
      });
      if (data?.error) {
        toast.error(data.error, {
          position: toast.POSITION.TOP_RIGHT,
          autoClose: 2000,
        });
      } else {
        toast.success(`VIN successfully updated`, {
          position: toast.POSITION.TOP_RIGHT,
          autoClose: 2000,
        });
      }
    } catch (err) {
      toast.error(err.data || err.error);
    }
  };

  return (
    <>
      <Box sx={{ display: "flex" }}>
        <Navigation />
        <Box component="main" sx={{ flexGrow: 1, p: 3 }}>
          <h2 className="text-center text-success h3">Edit Saved Invoice</h2>
          <hr className="mb-3" />
          <form onSubmit={handleFormSubmit}>
            <div className="container-fluid border mb-3">
              <div className="row mt-3 mb-3">
                <b className="h5 text-primary">Car Details</b>
                <div className="col-md-3">
                  <label htmlFor="name block">VIN # </label>
                  <input
                    type="text"
                    name="vinNumber"
                    className="p-4 mb-3 w-[30rem] border rounded-lg bg-[#101011] text-white "
                    value={vinNumber}
                    onChange={(e) => setVinNumber(e.target.value)}
                  />
                </div>
              </div>
            </div>
            <div className="container-fluid border mb-3 ">
              <div className="row mt-3 mb-3">
                <b className="h5 text-primary">Description</b>

                <div className="col-md-12">
                  <div className="form-group"></div>
                </div>
              </div>
            </div>
            <div className="button-box col-lg-12">
              <div className="row mt-4">
                <div className="col-md-3"></div>
                <div className="col-md-3">
                  <button
                    type="submit"
             
                    className="button-box btn btn-success  col-md-4 mt-3"
                  >
                    Submit Invoice
                  </button>
                </div>
              
              </div>
            </div>
          </form>
        </Box>
      </Box>
    </>
  );
};

export default SingleSavedInvoice;

InvoiceApiSlice below:

import { apiSlice } from "../../redux/api/apiSlice";
import { USERS_URL } from "../constants";

export const invoiceApiSlice = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    updateSavedInvoiceById: builder.mutation({
      query: ({ data, invoiceID }) => ({
        a: console.log(
          "I m in invoiceApiSlice at updateSavedInvoiceById",
          data,
          invoiceID
        ),
        url: `${USERS_URL}/invoice/savedInvoice/edit/${invoiceID}`,
        // url: `${EXPENSE_URL}/create-expense`,
        method: "PUT",
        body: data,
        // headers: { "Content-Type": "application/json" },
        // mode: "no-cors", 
        // credentials: "include", 
      }),
    }),

  }),
});

export const {
  useUpdateSavedInvoiceByIdMutation
} = invoiceApiSlice;

enter image description here

enter image description here

apiSlice:

import { fetchBaseQuery, createApi } from "@reduxjs/toolkit/query/react";
import { BASE_URL } from "../constants";

const baseQuery = fetchBaseQuery({ baseUrl: BASE_URL });

export const apiSlice = createApi({
  baseQuery,
  endpoints: () => ({}),
});

store:

export const store = configureStore({
  reducer: {
    auth: authReducer,
    [apiSlice.reducerPath]: apiSlice.reducer,
    [invoiceApiSlice.reducerPath]: invoiceApiSlice.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(
      apiSlice.middleware,
      invoiceApiSlice.middleware
    ),
  devTools: true,
});

setupListeners(store.dispatch);

export default store;

Invoice Controller:

static updateSavedInvoiceById = asyncHandler(async (req, res) => {
  try {
    const invoice = await Invoice.findById(req.params.id);
    const user = await UserModel.findById(_id);
    if (!invoice) {
      return res.status(404).json({ error: "invoice not found" });
    }
    if (invoice) {
      invoice.vinNumber = req.body.vinNumber;
      const latestInvoice = await invoice.save();
      user.invoiceCreatedByThisUser.push(latestInvoice);
      user.save();    
    } else {
      res.status(404);
      throw new Error("invoice not found");
    }
  } catch (error) {
    console.error(error);
    res.status(404).json({ error: " invoice not found" });
  }
});

Invoice Model:

import mongoose from "mongoose";
const { ObjectId } = mongoose.Schema;

const invoiceSchema = mongoose.Schema(
  {
    vinNumber: {
      type: Number,
      trim: true,
    },
  },
  { timestamps: true }
);

const Invoice = mongoose.model("invoice", invoiceSchema);

export default Invoice;

Invoice Routes:

router.put(
  "/savedInvoice/edit/:id",
  InvoiceController.updateSavedInvoiceById
);

I want to create an html popup that take variable input

I have instructions with pictures that get displayed when a user clicks a link.
I know how to create a “static” popup – one that has a static image. I’d like to create a single parameterized popup that would display the image I tell it to.

I want to do something like this :

I am writing some instructions about how to use the <a href="javascript:alert('dishwasher.jpg');">dishwasher </a>
and the <a href="javascript:alert('washing machine.jpg');">washing machine</a>, etc.
<script>
function alert(image) {
  var popup = document.getElementById("myPopup");
<!--   somehow tell the popup to show image -->
  popup.classList.toggle("show");

}</script>
<div class="popup" onclick="myFunction()">Click me!
  <span class="popuptext" id="myPopup">Popup text...</span>
</div> 

This is based on https://www.w3schools.com/howto/howto_js_popup.asp

Compound bodies in Phaser.js/matter.js

I have a player object (Matter/Sprite) and i want to add a bottom-sensor body in order to detect if the player hit the ground or a brick (enable jump for example).

i prepare the player body:

private preparePhysicsBody() {

    const bodyPlayer = this.scene.matter.bodies.rectangle(
      this.displayWidth / 2, this.displayHeight / 2,
      this.displayWidth, this.displayHeight);
    bodyPlayer.collisionFilter.category = PhysicsBodyCategories.PLAYER;
    bodyPlayer.collisionFilter.mask = PhysicsBodyCategories.WORLD;

    const bodyPlayerBottomSensor = this.scene.matter.bodies.rectangle(
      bodyPlayer.position.x, bodyPlayer.position.y + (this.displayHeight / 2),
      this.displayWidth - 6, 1, {
        isSensor: true
      });
    bodyPlayer.collisionFilter.category = PhysicsBodyCategories.PLAYER_BOTTOM;
    bodyPlayer.collisionFilter.mask = PhysicsBodyCategories.WORLD | PhysicsBodyCategories.BRICK;

    const body = this.scene.matter.body.create({
      parts: [
        bodyPlayerBottomSensor,
        bodyPlayer
      ]
    });
    this.setExistingBody(body);
    this.setFixedRotation();


    //on collisions
    this.setOnCollide((obj: MatterCollisionData) => {
      console.log(obj.bodyA.collisionFilter.category)
      console.log(obj.bodyB.collisionFilter.category)
    });

and a few bricks (also Matter/Sprite) in different positions:

class Brick extends Sprite {

  constructor(scene: Scene, x: number, y: number) {

    super(scene.matter.world, x, y, "brick", undefined, {
      isStatic: true
    });
    this.setPosition(x, y);
    this.setFriction(0.01)
    this.setDisplaySize(100, 10)
    this.setCollisionCategory(PhysicsBodyCategories.BRICK)

The first problem is, that the playerBody still collides with the bricks even though there is only the WORLD assigned to mask.

The second problem is, that setOnCollide doesn´t fire.

I tried also with the initial generated body of the playerObject and set the same values for category and mask and it worked, collision detection fired too.

conditional rendering a table in next js

I have a table of values with varying values of location. I am trying to filter the rows in the database by matching the location value. The code is

'use client';
import { useState, useEffect } from 'react';
import { io } from 'socket.io-client';

const styles = {
  container: {
    width: '100%',
    height: '100vh',
    display: 'flex',
    flexDirection: 'column',
    backgroundColor: '#fff',
    overflow: 'hidden',
  },
  header: {
    width: '100%',
    padding: '1rem',
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    borderBottom: '1px solid #eaeaea',
    boxSizing: 'border-box',
  },
  createButton: {
    padding: '0.5rem 1rem',
    backgroundColor: '#0070f3',
    color: 'white',
    border: 'none',
    borderRadius: '5px',
    cursor: 'pointer',
    fontSize: '1rem',
  },
  headerText: {
    flex: 1,
    textAlign: 'center',
    fontSize: '1.25rem',
    color: '#333',
  },
  logOutButton: {
    padding: '0.4rem 1rem',
    backgroundColor: '#FF999C',
    color: 'white',
    border: '0.5px',
    borderRadius: '5px',
    cursor: 'pointer',
    fontSize: '1rem',
  },
  contentWrapper: {
    flex: 1,
    padding: '1rem',
    overflowY: 'auto',
  },
  main: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    width: '100%',
  },
  table: {
    width: '100%',
    borderCollapse: 'collapse',
    borderRadius: '10px',
    overflow: 'hidden',
    border: '1px solid #000',
    boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
  },
  th: {
    border: '1px solid #000',
    padding: '8px',
    paddingLeft: '10px',
    backgroundColor: '#334',
    color: '#fff',
    textAlign: 'center',
  },
  td: {
    border: '1px solid #000',
    padding: '8px',
    textAlign: 'center',
    backgroundColor: '#FAF9F6',
    color: '#000',
  },
  footer: {
    padding: '0.5rem',
    borderTop: '2px solid #eaeaea',
    display: 'flex',
    justifyContent: 'center',
    backgroundColor: 'white',
    color: 'black',
    boxSizing: 'border-box',
  },
  modalOverlay: {
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1000,
  },
  modalContent: {
    backgroundColor: 'white',
    padding: '2rem',
    borderRadius: '10px',
    width: '90%',
    maxWidth: '600px',
    boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
  },
  input: {
    width: '100%',
    padding: '0.5rem',
    marginBottom: '0.5rem',
    color: 'black',
    borderRadius: '5px',
    border: '1px solid #ccc',
    fontSize: '1rem',
  },
  modalButtons: {
    display: 'flex',
    justifyContent: 'space-between',
  },
  addButton: {
    padding: '0.5rem 1rem',
    backgroundColor: '#0070f3',
    color: 'white',
    border: 'none',
    borderRadius: '5px',
    cursor: 'pointer',
    fontSize: '1rem',
  },
  cancelButton: {
    padding: '0.5rem 1rem',
    backgroundColor: '#E97451',
    color: 'white',
    border: 'none',
    borderRadius: '5px',
    cursor: 'pointer',
    fontSize: '1rem',
  },
  deleteButton: {
    padding: '0.1rem 1rem',
    backgroundColor: '#E97451',
    color: 'white',
    border: 'none',
    borderRadius: '5px',
    cursor: 'pointer',
    fontSize: '0.8rem',
  },
  '@media (max-width: 1024px)': {
    container: {
      padding: '0.5rem',
    },
    headerText: {
      fontSize: '1rem',
    },
    createButton: {
      padding: '0.3rem 0.6rem',
      fontSize: '0.875rem',
    },
    table: {
      width: '100%',
    },
    modalContent: {
      width: '80%',
    },
  },
  '@media (max-width: 768px)': {
    container: {
      padding: '0.5rem',
    },
    headerText: {
      fontSize: '1rem',
    },
    createButton: {
      padding: '0.3rem 0.6rem',
      fontSize: '0.875rem',
    },
    table: {
      width: '100%',
    },
    modalContent: {
      width: '90%',
    },
  },
  '@media (max-width: 480px)': {
    container: {
      padding: '0.25rem',
    },
    header: {
      flexDirection: 'column',
      alignItems: 'flex-start',
    },
    createButton: {
      padding: '0.3rem 0.5rem',
      fontSize: '0.75rem',
    },
    headerText: {
      fontSize: '0.875rem',
    },
    table: {
      fontSize: '0.875rem',
    },
    modalContent: {
      width: '95%',
    },
  },
};


const Dashboard = () => {
  const [streetLights, setStreetLights] = useState([]);
  const [filter, setFilter] = useState({ location: '' });
  const [selectedLocation, setSelectedLocation] = useState('');
  const [newLight, setNewLight] = useState({
    id: '',
    dateOfFixing: '',
    intensity: '',
    workingCondition: '',
    location: '',
  });
  const [editingLight, setEditingLight] = useState(null);
  const [isModalOpen, setIsModalOpen] = useState(false);

  // Fetch street lights when the filter changes
  useEffect(() => {
    const fetchStreetLights = async () => {
      const query = new URLSearchParams(filter).toString();  // Convert filter to query string
      const res = await fetch(`/api/streetlights?${query}`); // Append query string to the API endpoint
      const data = await res.json();
      setStreetLights(data); // Update state with filtered data
    };
  
    fetchStreetLights();
  }, [filter]); // Re-run the effect when the filter changes
  

  
  useEffect(() => {
    const interval = setInterval(() => {
      const fetchStreetLights = async () => {
        const query = new URLSearchParams(filter).toString();
        const res = await fetch(`/api/streetlights?${query}`);
        const data = await res.json();
        setStreetLights(data);
      };

      fetchStreetLights();
    }, 100);

    return () => clearInterval(interval);
  }, [filter]);

  // Socket connection for real-time updates
  useEffect(() => {
    const socket = io('http://localhost:3001');

    socket.on('streetLightsData', (data) => {
      setStreetLights(data);
    });

    return () => {
      socket.disconnect();
    };
  }, []);

  const handleFilterChange = (e) => {
    setFilter({ ...filter, [e.target.name]: e.target.value });  // Update the filter state
  };
  

  const handleDelete = async (id) => {
    const res = await fetch(`/api/streetlights/${id}`, {
      method: 'DELETE',
    });

    if (res.ok) {
      setStreetLights((prev) => prev.filter((light) => light.id !== id));
    } else {
      console.error('Failed to delete street light');
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setNewLight((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const res = await fetch('/api/streetlights', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(newLight),
    });

    if (res.ok) {
      const newLight = await res.json();
      setStreetLights((prev) => [...prev, newLight]);
      setNewLight({
        id: '',
        dateOfFixing: '',
        intensity: '',
        workingCondition: true,
        location: '',
      });
    }
  };

  const startEditing = (light) => {
    setEditingLight(light);
    setIsModalOpen(true);
  };

  const handleEditChange = (e) => {
    const { name, value } = e.target;
    setEditingLight((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const handleOpenModal = () => {
    setIsModalOpen(true);
  };

  const handleCloseModal = () => {
    setIsModalOpen(false);
  };

  const handleLogout = () => {
    window.location.href = '/api/auth/logout';
  };

  return (
    <div style={styles.container}>
      <header style={styles.header}>
        <button style={styles.createButton} onClick={handleOpenModal}>
          Create Light
        </button>
        <div style={styles.headerText}>Street Lights Dashboard</div>
        <button style={styles.logOutButton} onClick={handleLogout}>
          Log out
        </button>
      </header>
      <header style={styles.header}>
        <div>
          <select
            name="location"
            value={filter.location}
            onChange={handleFilterChange}
            style={styles.input}
          >
            <option value="">All Locations</option>
            <option value="Sriperumbudur">Sriperumbudur</option>
            <option value="Location2">Location 2</option>
            <option value="Location3">Location 3</option>
          </select>
        </div>
        <div style={styles.headerText}>Street Lights Dashboard</div>
      </header>

      <div style={styles.contentWrapper}>
        <main style={styles.main}>
          <table style={styles.table}>
            <thead>
              <tr>
                <th style={styles.th}>ID</th>
                <th style={styles.th}>Date of Fixing</th>
                <th style={styles.th}>Intensity</th>
                <th style={styles.th}>Status</th>
                <th style={styles.th}>Location</th>
                <th style={styles.th}>Actions</th>
              </tr>
            </thead>
            <tbody>
            {streetLights.length > 0 ? (
              streetLights.map((light) => (
                <tr key={light.id}>
                  <td style={styles.td}>{light.id}</td>
                  <td style={styles.td}>{light.dateOfFixing}</td>
                  <td style={styles.td}>{light.intensity}</td>
                  <td style={styles.td}>{light.workingCondition}</td>
                  <td style={styles.td}>{light.location}</td>
                  <td style={styles.td}>
                    <button style={styles.deleteButton} onClick={() => handleDelete(light.id)}>
                      Delete
                    </button>
                  </td>
                </tr>
              ))
            ) : (
              <tr>
                <td style={styles.td} colSpan="6">No street lights found for this location.</td>
              </tr>
            )}
          </tbody>
          </table>
        </main>
      </div>
      <footer style={styles.footer}>
        <p>Street Light Management System</p>
      </footer>
    </div>
  );
};

export default Dashboard;

It still doesn’t filter the values by location. How do I do that?

Tried to print the lights with the location selected from the drop down menu but end up getting all the lights

Dynamically expand a 12 col grid

I have 2 rows consisting of 12 cols
and a test button which should expand the first col of first row after each click.

HTML and CSS:

<div class="row">
  <div class="col"></div>
  <!-- 12 times -->
</div>
<div class="row">
  <div class="col"></div>
  <!-- 12 times -->
</div>

.row {
  display: flex;
  margin: 20px;
}

.col {
  display: flex;
  flex: 1 1 calc((100% / 12);
  position: relative;
  border: 1px dashed darkgray;
  border-right: 0;
  padding: 10px;
}

This is how I am expanding the column (when clicking the button):

const minColWidthPercentage = (1 / 12) * 100;

expandCol(col) {
  const colStyle = window.getComputedStyle(col);
  const flexBasis = parseFloat(colStyle.flexBasis) + minColWidthPercentage;
  col.style.setProperty("flex", `1 1 calc(${flexBasis}%)`);
}

As soon as I comment out the ‘padding: 10px;’ from col’s css, everything works fine.
The right border of the expanded column correctly aligns with the border of the column below from the second row.
But if I keep the padding, the alignment breaks.

Without padding after expanding 4 times:
enter image description here

With padding after expanding 4 times:
enter image description here

I already tried 1 1 calc(${flexBasis}%+${padding*n}px) approach.
But this does not solve the problem.
I think I should include the padding somehow in the percentage calculation, but how exactly?

PS: Note that, while expanding I am removing the neighbour column in another function.

Cache a Shopify Storefront Api Response with Workbox

Shopify exposes a storefront api to query data for headless e-commerce sites. The api is graphql based and every query in graphql is a POST request.

If the following url exists to query the storefront api:

https://some-store.myshopify.com/api/2024-01/graphql.json

A sample usage for a single product query would look like this

fetch('https://some-store.myshopify.com/api/2024-01/graphql.json', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Shopify-Storefront-Access-Token': '84178bc7c741a43bcg7c64308dbc6691'
  },
  body: JSON.stringify({
    query: `{
      product(id: "1") {
        title
        price
      }
    }`

  })
})

I have a setup with workbox like this, note the third argument 'POST'. According to the worbox docs for routing

All routes by default are assumed to be for GET requests.
If you would like to route other requests, like a POST request, you need to define the method when registering the route, like so:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\.json'), handlerCb, 'POST');

I have the RegExp route setup and included the third parameter and I get an error in the console anyways attempt-to-cache-non-get-request: Unable to cache ‘https://some-store.myshopify.com/api/2024-01/graphql.json’ because it is a ‘POST’ request and only ‘GET’ requests can be cached

import { registerRoute } from 'workbox-routing'

registerRoute(
  /^https://headless-test-dev.myshopify.com/api/2024-01/graphql.json/,
  new NetworkFirst({
    cacheName: 'storefront-api'
  }),
  'POST'
)

If anyone can explain what I am doing wrong here it would be great.

How do I get the modal dialog box to display customized with two different buttons?

So I am working on the TicTacToe game for the Odin Project. I have two different create Player buttons that I want to open the same modal dialog box so I can enter in two different parameters and have one save across both.When I put X as the marker for one player I want it to be (required?) inaccessible for the other player, so that the other player has to pick O.How do I do this?

HTML

<body>
    <header> TIC-TAC-TOE</header>
    <section id="large-container">
        <article class="Players" id="1">
            Player1
            <button id="1">
                Enter Player
            </button>
        </article>
        <div class="container">
            <div class="item"><button id="0">0</button></div>
            <div class="item"><button id ="1">1</button></div>
            <div class="item"><button id="2">2</button></div>
            <div class="item"><button id="3">3</button></div>
            <div class="item"><button id="4">4</button></div>
            <div class="item"><button id="5">5</button></div>
            <div class="item"><button id="6">6</button></div>
            <div class="item"><button id="7">7</button></div>
            <div class="item"><button id="8">8</button></div>
        </div>
        <article class="Players" id="2">
            Player2
            <button id="2">
                Enter Player
            </button>
        </article>
        <dialog class="PlayerDialog">
            <form>
                <p>
                    <label for="playerName">What is the Player's Name</label>
                    <input type="text" id="PName" name="PName">

                    <label for="playerMarker">What is the Players marker?
                        <select>
                            <option value="X" id="X" name="Marker">X</option>
                            <option value="O" id="O" name="Marker">O</option>
                        </select>
                    </label>
                </p>
                <button value="cancel" formmethod="dialog">Cancel</button>
                <button id="Confirm" value="default">Confirm</button>
            </form>
        </dialog>
    </section>
    <script src="Main3.js"></script>
</body>

JS

const playerCreationButtons = document.querySelectorAll(".Players > button")
const playerCreation = document.querySelector(".PlayerDialog")
const PlayerDisplay = document.querySelector("article.Players")
const confirmBtn = document.querySelector("#Confirm")
const playerName = document.getElementById("#PName")
const playerMarkerX = document.getElementById("X")
playerCreationButtons.forEach((button)=>{
    button.addEventListener("click", ()=>{
         /// (Some code here to alter the modal for each player before it's shown)///
        playerCreation.showModal()
        console.log(`${button.id}`)
    })
})