React ag-grid date filter clearing second date filter when first one is cleared

I have implemented server side pagination with AG-Grid using React js.

Now I am having problems with the date filter on the grid. My filter has the “AND” “OR” conditions on them. By default only one date is shown (which is fine). But once you select a date the second date picker will show along side the “AND” “OR” condition.

The problem comes when you click on the first date picker and you select ‘Clear’, the second date disappears from the screen and the date filter is not applied to the grid. But when you add the first filter back again, the second filter which disappeared comes back with the old filter you put there back in.

You can see an example from the official documentation of the date filter picker working correctly (apply the date filter by selecting the three lines) https://codesandbox.io/s/f86lk4?file=/src/index.js

If you clear the first date it doesn’t clear the second date.

My filter params are defined like this:

var filterParams = {
  comparator: (filterLocalDateAtMidnight, cellValue) => {
    var dateAsString = cellValue;
    if (dateAsString == null) return -1;
    var dateParts = dateAsString.split('/');
    var cellDate = new Date(
      Number(dateParts[2]),
      Number(dateParts[1]) - 1,
      Number(dateParts[0])
    );
    if (filterLocalDateAtMidnight.getTime() === cellDate.getTime()) {
      return 0;
    }
    if (cellDate < filterLocalDateAtMidnight) {
      return -1;
    }
    if (cellDate > filterLocalDateAtMidnight) {
      return 1;
    }
    return 0;
  },
};

And my date column is defined like this:

  const [columnDefs, setColumnDefs] = useState([
    {
      field: 'date',
      filter: 'agDateColumnFilter',
      filterParams: filterParams,
    },
  ]);

and my default column definitions are defined like this:

  const defaultColDef = useMemo(() => {
    return {
      sortable: true,
      filter: true,
      wrapText: true,
      ensureDomOrder: true,
      enableCellTextSelection: true
    };
  }, []);

The code looks very similar to the example given by ag-grid but I have no idea why it works differently.

Does anyone have any ideas?

JavaScript Relation chart graph Best performance

I want to create a graph chart in my React app
but the data is very huge and If I use a library it crashes and has a lot of lags
How can I handle this with pure JS for better performance?
this is my code :

import React, { useEffect, useRef } from "react";

interface Node {
  id: string;
  x?: number;
  y?: number;
  count?: number;
}

interface Edge {
  source: string;
  target: string;
}

const GraphCanvas: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas: HTMLCanvasElement | null = canvasRef.current;
    if (canvas) {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      const ctx = canvas.getContext("2d");
      if (!ctx) return;

      const nodes: Node[] = [
        { id: "A", x: 100, y: 100, count: 50 },
        { id: "B", x: 200, y: 150, count: 200 },
        { id: "C", x: 300, y: 200, count: 400 },
        { id: "D", x: 200, y: 350, count: 500 },
        { id: "E", x: 200, y: 50, count: 1000 },
        { id: "F", x: 280, y: 100, count: 2000 },
        { id: "G", x: 300, y: 200, count: 3000 },
        { id: "H", x: 310, y: 300, count: 4000 },
        { id: "I", x: 250, y: 420, count: 5000 },
        { id: "J", x: 100, y: 450, count: 6000 },
        { id: "K", x: 100, y: 300, count: 7000 },
        { id: "L", x: 100, y: 300, count: 7000 },
        // Add more nodes as needed
      ];

      const edges: Edge[] = [
        { source: "A", target: "B" },
        { source: "B", target: "C" },
        { source: "B", target: "D" },
        { source: "B", target: "E" },
        { source: "G", target: "B" },
        { source: "F", target: "B" },
        { source: "C", target: "D" },
        { source: "K", target: "D" },
        { source: "H", target: "D" },
        { source: "I", target: "D" },
        { source: "J", target: "D" },
        { source: "K", target: "L" },
        // Define edges between nodes
      ];

      // Dynamically calculate initial positions based on canvas dimensions
      const centerX = canvas.width / 2;
      const centerY = canvas.height / 2;

      nodes.forEach((node, index) => {
        const angle = (index / nodes.length) * (2 * Math.PI);
        const radius = Math.min(centerX, centerY) * 0.8; // Adjust the radius as needed
        node.x = centerX + radius * Math.cos(angle);
        node.y = centerY + radius * Math.sin(angle);
      });

      // Visualization: Draw nodes and edges on canvas
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      edges.forEach((edge) => {
        const sourceNode = nodes.find((node) => node.id === edge.source);
        const targetNode = nodes.find((node) => node.id === edge.target);

        if (sourceNode && targetNode) {
          if (sourceNode.x && sourceNode.y && targetNode.x && targetNode.y) {
            ctx.beginPath();
            ctx.moveTo(sourceNode.x, sourceNode.y);
            ctx.lineTo(targetNode.x, targetNode.y);
            ctx.strokeStyle = "black";
            ctx.stroke();
          }
        }
      });

      nodes.forEach((node) => {
        if (node.x && node.y) {
          ctx.beginPath();
          ctx.arc(node.x, node.y, 20, 0, 2 * Math.PI);
          ctx.fillStyle = "white";
          ctx.fill();
          ctx.strokeStyle = "blue";
          ctx.stroke();
          ctx.font = "bold 14px Arial";
          ctx.fillStyle = "blue";
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";
          ctx.fillText(node.id, node.x, node.y);
        }
      });
    }
  }, []);

  return <canvas ref={canvasRef} width={400} height={300} />;
};

export default GraphCanvas;

But I have some problems
I want to show this graph in a tree-shape
that the children won’t have confluence with other nodes

is there someone who has experience in implementing graphs with Js?

WebAR project in playcanvas

I want to access webcam in my playcanvas project.And also want to use the face detection API for my project.Now how should I write code for this? Can anyone help me to make a project in playcanvas? Is there any professional who works with webAR in playcanvas?

Quill Bold format

By default Quill use tag to make text bold.
How replace Quill tag with which has inline style ‘font-weight: 700’.

My workaround is here. But it is does not work when we use IPhone text formatting.

    class CustomBold extends Inline {
        static blotName = 'bold';
        static tagName = 'SPAN';
        static create(value: string) {
            const node = super.create(value) as HTMLSpanElement;
            node.style.fontWeight = '700';
            return node;
        }
        static formats(domNode: HTMLSpanElement) {
            return domNode.style.fontWeight === '700' ? true : false;
        }

        format(name: string, value: boolean) {
            if (name === 'bold') {
                this.domNode.style.fontWeight = value ? '700' : '400';
            } else {
                super.format(name, value);
            }
        }
        formats() {
            let formats = super.formats();
            formats['bold'] = CustomBold.formats(this.domNode);
            return formats;
        }
    } 

I’m not able to play songs from my playlist stored in local storage in my react music player

I cannot play songs from my ceated playList stored in local storage.
awhat it actually does is that it palys the songs from my All songs
list whenever I click any song in my play list. The playlist is made
by clicking the + icon on the song, and by doing this the song is
added to the playlist and storef in local storage

main App.js code

  const songs = data;
  const [isPlaying, setIsPlaying] = useState(false);
  const [volume, setVolume] = useState(0.5);
  const  = useState(() => {
    const savedPlaylist = JSON.parse(localStorage.getItem("playlist"));

    return savedPlaylist || [];
  });
  const [playlistName, setPlaylistName] = useState(() => {
    const savedPlaylistName = localStorage.getItem("playlistName");
    return savedPlaylistName || "My Playlist";
  });
  const [isEditingName, setIsEditingName] = useState(false);
  const [currentSongIndex, setCurrentSongIndex] = useState(0);
  const [songProgress, setSongProgress] = useState(0);
  const audioRef = useRef(new Audio());

  useEffect(() => {
    // Save the updated playlist to local storage
    localStorage.setItem("playlist", JSON.stringify(playlist));
  }, );

  const handlePlaylistNameChange = (e) => {
    setPlaylistName(e.target.value);
  };

  const playFromPlaylist = (index) => {
    setCurrentSongIndex(index);

    setIsPlaying(true);
  };

  const startEditingName = () => {
    setIsEditingName(true);
  };

  const finishEditingName = () => {
    setIsEditingName(false);
    localStorage.setItem("playlistName", playlistName);
  };

  const onProgressChange = (e) => {
    const value = e.target.value;
    setSongProgress(value);
    const duration = audioRef.current.duration;
    audioRef.current.currentTime = (value * duration) / 100;
  };

  const playNewSong = () => {
    setSongProgress(0);
    if (audioRef.current) {
      audioRef.current.src = songs[currentSongIndex]?.audio;
      audioRef.current.currentTime = 0;
      audioRef.current.play();
    }
  };

  useEffect(() => {
    if (audioRef.current) {
      audioRef.current.volume = volume;
    }
  }, [volume]);

  const timeUpdateHandler = (e) => {
    if (audioRef.current) {
      const current = e.target.currentTime;
      const duration = e.target.duration;
      const roundedCurrent = Math.round(current);
      const roundedDuration = Math.round(duration);
      const animation = Math.round((roundedCurrent / roundedDuration) * 100);
      setSongProgress(animation);
    }
  };

  useEffect(() => {
    if (audioRef.current) {
      audioRef.current.addEventListener("timeupdate", timeUpdateHandler);
      return () => {
        audioRef.current.removeEventListener("timeupdate", timeUpdateHandler);
      };
    }
  }, [audioRef, timeUpdateHandler]);

  useEffect(() => {
    if (isPlaying && audioRef.current) {
      audioRef.current.play();
    } else if (audioRef.current) {
      audioRef.current.pause();
    }
  }, [isPlaying]);

  useEffect(() => {
    if (isPlaying) {
      playNewSong();
    } else if (audioRef.current) {
      audioRef.current.pause();
    }
  }, [currentSongIndex, isPlaying]);


playlist  component in App component

 <div className="col-span-1 mt-4">
        <PlaylistName
          name={playlistName}
          isEditing={isEditingName}
          onNameChange={handlePlaylistNameChange}
          onStartEditing={startEditingName}
          onFinishEditing={finishEditingName}
        />

        {playlist.length > 0 && (
          <Playlist
            songs={playlist}
            onPlayPlaylist={playFromPlaylist}
            onRemoveFromPlaylist={(index) => {
              const newPlaylist = [...playlist];
              newPlaylist.splice(index, 1);
              setPlaylist(newPlaylist);
            }}
          />
        )}
      </div>

Main playList component

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTimes } from "@fortawesome/free-solid-svg-icons";

const Playlist = ({ songs, onPlayPlaylist, onRemoveFromPlaylist }) => {
  return (
    <ul>
      {songs.map((song, index) => (
        <li key={song.id} className="flex items-center justify-between p-2">
          <div className="flex items-center space-x-2">
            <img
              src={song.cover}
              alt={`${song.name} Cover`}
              className="w-8 h-8 object-cover rounded-md"
            />
            <p onClick={() => onPlayPlaylist(index)} className="cursor-pointer">
              {song.name}
            </p>
          </div>
          <button
            onClick={() => onRemoveFromPlaylist(index)}
            className="hover:text-red-500"
            title="Remove from Playlist"
          >
            <FontAwesomeIcon icon={faTimes} />
          </button>
        </li>
      ))}
    </ul>
  );
};

export default Playlist;

converting bootstrap template into next js

i am trying to convert bootstrap template into next js which is using owl.carousel.js library its only showing image in carousel for like 1 sec
reference video => https://streamable.com/h0c9o2
github => https://github.com/AnonymousDEV001/nextJs-carasol

in github code its just carousel so u don’t waste your time finding the right page

I had hydration issue i fixed that and now i don’t have any errors and now its not showing carousel image at all not even for a sec

electron – Having trouble with showOpenDialog

Developing an electron app right now.
I need the feature to upload files locally, I was experimenting with showOpenDialog(). Clicking on the button to upload, opens the file chooser as intended, but an error shows up in the terminal:

[4801:0205/172224.193666:ERROR:browser_main_loop.cc(276)] GLib-GObject: invalid cast from ‘GtkFileChooserNative’ to ‘GtkWidget’

Choosing a file throws another error:

[4801:0205/172226.571068:ERROR:browser_main_loop.cc(276)] GLib-GObject: ../glib/gobject/gsignal.c:2777: instance ‘0x12b000ac7bf0’ has no handler with id ‘3139’

Here’s the code in my main.js:

ipcMain.handle('gallery-add-files', (e) => {
    var files = dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
        properties:[
            'openFile',
            'multiSelections'
        ]
    }, function(files){
        console.log(files)
    });
})

I’m using arch and I think that’s relevant because previously there were a couple more errors showing with this one but installing ‘xdg-desktop-portal’ and ‘xdg-desktop-portal-gtk’ solved them.

Why is Bootstrap Multiselect not working?

I am trying to get Bootstrap Multiselect running but it just doesn’t want to function. I already tried everything and just cannot find the issue.
My index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Minimal Bootstrap Multiselect Example</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-multiselect.css">
</head>
<body>

    <select id="minimal-multiselect" multiple="multiple">
        <option value="cheese">Cheese</option>
        <option value="tomatoes">Tomatoes</option>
        <option value="mozarella">Mozzarella</option>
        <option value="mushrooms">Mushrooms</option>
        <option value="pepperoni">Pepperoni</option>
        <option value="onions">Onions</option>
    </select>

    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap-multiselect.js"></script>
    <script>
        $(document).ready(function() {
            $('#minimal-multiselect').multiselect();
        });
    </script>

</body>
</html>

This actually loads the multiselect correctly and the css is also working on it. But when i click on it the dropdown just doesn’t open. There is also no errors in the console.

I expected the dropdown to open

Anonymous access to google drive from javascript in browser

I have a bunch of public images in a google drive that I’d like to display on a website. There is no server-side programming access on the website; I have to do all programming in javascript on the browser. What I’d like to do is get a listing of the files in the public folder and then I can make the appropriate HTML.

But I cannot figure out a reasonable way to get the list of files. I have found lots of discussion about how to do this with server-side APIs — drive app, google’s REST API — but none seem suitable for browser javascript, just node.js. The REST API in particular seems either to require oauth 2.0 or an API key. Clearly the oauth credentials cannot live in a browser-based javascript, and I’m a little leery about putting the API key there, even if the API key is highly restricted. I’ve also found a few old stackoverflow answers with pointers to APIs that promise anonymous access, but those all seem to point to dead links; the APIs have apparently been withdrawn.

Of course I can just access the page via a regular URL, but the HTML data that comes back is a pretty complicated script, and parsing the information out of that would be difficult (not to mention pretty fragile when the display changes).

Am I missing some API? Or am I overthinking the security aspects about putting the API key into a public script?

I’m trying to get information in an HTML message

in the head part within the html, there are 4 pieces of information that I wanted to get using cheerio, but I tried everything and it is always returning an invalid value, in this case returning NOTHING
in the javascript code it has the 4 options that I am trying to get from the html, if possible someone can help I would appreciate it
enter image description here

my code

    const axios = require("axios");
const cheerio = require('cheerio');

const headers = {
    'Cache-Control': 'max-age=0',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': 'PHPSESSID=0cpr6cn0mdqhab6v6vvdi0ifbm',
    'Host': 'sistemas.viareal.net',
    'Origin': 'https://sistemas.viareal.net',
    'Referer': 'https://sistemas.viareal.net/utp-dev/index.php?ti=pl',
    'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
};

const minhaFuncaoAssincrona = async () => {
    try {
        const response = await axios.post('https://sistemas.viareal.net/utp-dev/index.php?s=pl', {
            cep: '93285310',
            numcasa: '85'
        }, { headers, timeout: 160000 });

        const extrairInformacoes = (html) => {
            const $ = cheerio.load(html);

            const viabilidade = $('font:contains("Rede disponível no endereço pesquisado")').length > 0;

            if (viabilidade) {
                console.log('Há viabilidade no endereço pesquisado.');

                const enderecoProspectado = $('td:contains("Endereço prospectado:")').next().find('b').text().trim();
                const ctoPreferencial = $('b:contains("CTO Preferencial:")').closest('td').next().text().trim();
                const ctoAlternativa1 = $('b:contains("CTO Alternativa 1:")').closest('td').next().text().trim();
                const ctoAlternativa2 = $('b:contains("CTO Alternativa 2:")').closest('td').next().text().trim();

                console.log('Endereço Prospectado:', enderecoProspectado);
                console.log('CTO Preferencial:', ctoPreferencial);
                console.log('CTO Alternativa 1:', ctoAlternativa1);
                console.log('CTO Alternativa 2:', ctoAlternativa2);

            } else {
                console.log('Não há viabilidade no endereço pesquisado.');
            }
        };

        extrairInformacoes(response.data);

    } catch (error) {
        console.error('Erro na solicitação:', error.message);
    }
};

minhaFuncaoAssincrona();

html response

<!DOCTYPE html><html>   <head>      <link rel='SHORTCUT ICON' href='knife.png'/>        <style>            /* Set the size of the div element that contains the map */            #map {                height: 500px;  /* The height is 400 pixels */                width: 700px;  /* The width is the width of the web page */            }        .blink {
    animation: blinker 0.8s linear infinite;
    color: #cc0000;
    font-size: 12px;
    font-weight: bold;
    font-family: sans-serif;
}
@keyframes blinker {
    0% {
    opacity: 0;
   }
}        </style>       <Title>UTP - Pinga Lote</title><style type="text/css">
body {color: #737373; font-size: 10px; font-family: verdana;}

textarea,input,select {
background-color: #FDFBFB;
border: 1px solid #BBBBBB;
padding: 2px;
margin: 1px;
font-size: 14px;
color: #808080;
}

a, a:link, a:visited, a:active { color: #1212FF; text-decoration: none; font-size: 14px; }
a:hover { border-bottom: 1px dotted #c1c1c1; color: #AAAAAA; }
img {border: none;}
td { font-size: 14px; color: #7A7A7A; }
</style>


</head>    <body><table border=0 width=100%><tr><td><center><table border=0 bgcolor=#eeeeee width=100%><tr><td valign=center colspan=14 bgcolor=#FF0D5D><font color=white><center>UTP - Versão 0.23 - Bem vindo [email protected]. <a href=index.php?s=logout><font color=white>Deslogar.</a></td></tr><tr><td height=80 valign=center width=200><center><a href=index.php?ti=pl><img src=pingalote.png><br><font face='Arial' color='black' size='2'>Pinga Lote</a></td><td height=80 valign=center width=200><center><a href=index.php?s=ctoProx><img src=ctoprox.png><br><font face='Arial' color='black' size='2'>CTO Próxima</a></td><td height=80 valign=center width=200><center><a href=index.php?ti=ts><img src=timesheet.png><br><font face='Arial' color='black' size='2'>TimeSheet</a></td><td height=80 valign=center width=200><center><a href=index.php?s=valid1><img src=valida.png><br><font face='Arial' color='black' size='2'>Valida CTO</a></td></td></tr></table>        <style>            /* Set the size of the div element that contains the map */            #map {                height: 400px;  /* The height is 400 pixels */                width: 600px;  /* The width is the width of the web page */            }        </style><center><table border=0 bgcolor=#eeeeee width=100%><tr><td colspan=2 bgcolor=#FF0D5D><font color=white><center>Informações de Viabilidade</td><tr><td valign=top><center><center><table border=0 bgcolor=#eeeeee><tr><td bgcolor=#cccccc><center><font face='arial' color='black' size='2'>Dados da pesquisa</td></tr><tr><td><br><font face='arial' color='black' size='2'>Endereço prospectado:<br> <b>Rua Bandeirantes, 85 Liberdade Esteio/RS</b> <br><br><font color=green><b><center>Rede disponível no endereço pesquisado<br><br></b></font><b>CTO Preferencial:</b> [EIO-024-2-2/C:16/O:0/D:16]<b> GPON</b> FTTH <br><font color=black>Distância em linha reta: 44 m  <font color=black> <font color=black>Pelo arruamento: 37 m <font color=black><br>R. Bandeirantes, 48 - Liberdade, Esteio - RS, 93285-310, Brazil<br><br><b>CTO Alternativa 1:</b> [EIO-024-2-3/C:16/O:0/D:16]<b> GPON</b>  FTTH <br><font color=black>Distância em linha reta: 74 m   <font color=black> <font color=black>Pelo arruamento: 206 m  <font color=black><br>Rua 7 de Setembro, 122 - Liberdade, Esteio - RS, 93285-280, Brazil<br><br><b>CTO Alternativa 2:</b> [EIO-024-2-4/C:16/O:0/D:16]<b> GPON</b>  FTTH <br><font color=black>Distância em linha reta: 119 m   <font color=black> <font color=black>Pelo arruamento: 191 m  <font color=black><br>R. Império, 245 - Liberdade, Esteio - RS, 93285-300, Brazil<br><br><a href=index.php?s=pl&oc=true&lat=-29.8570493&lng=-51.1626037>Fazer essa pesquisa novamente considerando ocupação de portas.</a></td></tr></table></td><td width=60%>    <!--The div element for the map -->    <div id='map'></div>    <script>        function initMap() {var prospect = {lat: -29.8570493, lng: -51.1626037};
var ctoProx = {lat: -29.85685456114, lng: -51.16300520971};
var ctoProx2 = {lat: -29.85759455392, lng: -51.16303747274};
var ctoProx3 = {lat: -29.85617002886, lng: -51.16190663742};
var ctoProx4 = {lat: -29.85797213144, lng: -51.16421839478};
var ctoProx5 = {lat: -29.85522027068, lng: -51.16365481213};
var cto = {lat: -29.76780141496, lng: -51.15253019817};
var map = new google.maps.Map(document.getElementById('map'), {zoom: 17, center: prospect, mapTypeId: 'hybrid', styles:  [
{
"elementType": "geometry",
"stylers": [
{
"color": "#ebe3cd"
}
]
},
{
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#523735"
}
]
},
{
"elementType": "labels.text.stroke",
"stylers": [
{
"color": "#f5f1e6"
}
]
},
{
"featureType": "administrative",
"elementType": "geometry",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "administrative",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#c9b2a6"
}
]
},
{
"featureType": "administrative.land_parcel",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#dcd2be"
}
]
},
{
"featureType": "administrative.land_parcel",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#ae9e90"
}
]
},
{
"featureType": "landscape.natural",
"elementType": "geometry",
"stylers": [
{
"color": "#dfd2ae"
}
]
},
{
"featureType": "poi",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "poi",
"elementType": "geometry",
"stylers": [
{
"color": "#dfd2ae"
}
]
},
{
"featureType": "poi",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#93817c"
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#a5b076"
}
]
},
{
"featureType": "poi.park",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#447530"
}
]
},
{
"featureType": "road",
"elementType": "geometry",
"stylers": [
{
"color": "#f5f1e6"
}
]
},
{
"featureType": "road",
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry",
"stylers": [
{
"color": "#fdfcf8"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry",
"stylers": [
{
"color": "#f8c967"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#e9bc62"
}
]
},
{
"featureType": "road.highway.controlled_access",
"elementType": "geometry",
"stylers": [
{
"color": "#e98d58"
}
]
},
{
"featureType": "road.highway.controlled_access",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#db8555"
}
]
},
{
"featureType": "road.local",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#806b63"
}
]
},
{
"featureType": "transit",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "transit.line",
"elementType": "geometry",
"stylers": [
{
"color": "#dfd2ae"
}
]
},
{
"featureType": "transit.line",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#8f7d77"
}
]
},
{
"featureType": "transit.line",
"elementType": "labels.text.stroke",
"stylers": [
{
"color": "#ebe3cd"
}
]
},
{
"featureType": "transit.station",
"elementType": "geometry",
"stylers": [
{
"color": "#dfd2ae"
}
]
},
{
"featureType": "water",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#b9d3c2"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#92998d"
}
]
}
]
});
var infoWindow = new google.maps.InfoWindow({content: '', position: prospect});var prospectIcon = {  url: 'pin18-yellow.png',labelOrigin:  new google.maps.Point(9, -2), size: new google.maps.Size(18, 26),origin: new google.maps.Point(0, 0),anchor: new google.maps.Point(9, 26)};
var ctopIcon = {  url: 'selecionado.png',labelOrigin:  new google.maps.Point(0, -4), size: new google.maps.Size(20, 20),origin: new google.maps.Point(0, 0),anchor: new google.maps.Point(20, 20)};
var marker0 = new google.maps.Marker({position: prospect, map: map, label: 'Cliente', draggable:true, icon: prospectIcon});
function handleEvent(event) {
infoWindow = new google.maps.InfoWindow({position: event.latLng});
var NovoP = '<a href=index.php?s=pl&latP=' +  event.latLng.lat() + '&lngP=' +  event.latLng.lng() + '>Nova busca aqui</a>';                                 
infoWindow.setContent(NovoP);
infoWindow.open(map);
}marker0.addListener('dragend', handleEvent);var marker1 = new google.maps.Marker({position: ctoProx, map: map, icon: ctopIcon, label: 'CTO Preferencial[16/16]'});
var marker2 = new google.maps.Marker({position: ctoProx2, map: map, icon: ctopIcon, label: 'CTO Alternativa 1[16/16]'});
var marker3 = new google.maps.Marker({position: ctoProx3, map: map, icon: ctopIcon, label: 'CTO Alternativa 2[16/16]'});
var cto = {lat: -29.85685456114, lng: -51.16300520971};
var ctoCircle = new google.maps.Circle({
                  strokeColor: '#ff0000',
                  strokeOpacity: 0.2,
                  strokeWeight: 0.2,
                  fillColor: '#FF0000',
                  fillOpacity: 0.25,
                  map: map,
                  center: cto,
                  radius: 150,
                  zIndex: 5
              });
var cto = {lat: -29.85759455392, lng: -51.16303747274};
var ctoCircle = new google.maps.Circle({
                  strokeColor: '#ff0000',
                  strokeOpacity: 0.2,
                  strokeWeight: 0.2,
                  fillColor: '#FF0000',
                  fillOpacity: 0.25,
                  map: map,
                  center: cto,
                  radius: 150,
                  zIndex: 5
              });
var cto = {lat: -29.85617002886, lng: -51.16190663742};
var ctoCircle = new google.maps.Circle({
                  strokeColor: '#ff0000',
                  strokeOpacity: 0.2,
                  strokeWeight: 0.2,
                  fillColor: '#FF0000',
                  fillOpacity: 0.25,
                  map: map,
                  center: cto,
                  radius: 150,
                  zIndex: 5
              });
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD-D6oUG0QtWftzZ6ZOLfcKA6_zz3kQjhs&callback=initMap&libraries=visualization">        </script></td></tr></table>    </body>
</html>

Unable to loop clicking next page button

I am trying to scrape a website (https://rca.cnc.fr/rca.frontoffice/#) using puppeteer and NestJS.

So far I’m able to use a form but the data is returned as a table with multiple pages. I was able to make puppeteer click the next page button once, scrape the content, narrow it down to the data I need on page 1, page 2 loads, but it won’t scrape, extract and click and repeat.

import { Injectable } from '@nestjs/common';

import puppeteer from 'puppeteer';

@Injectable()
export class AppService {
  async getOeuvres(): Promise<string[]> {
    // Launch the browser and open a new blank page
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();

    // Navigate the page to a URL
    await page.goto('https://rca.cnc.fr/rca.frontoffice/recherche');

    await page.waitForSelector("mat-select[name='typeRecherche']");
    // Then click on the mat-select element with name 'typeRecherche'
    await page.click("mat-select[name='typeRecherche']");

    // Wait for the mat-option with id 'mat-option-167' that contains the text "Oeuvre" to appear in the DOM
    await page.waitForSelector('#mat-option-0 ');

    // Then click on the mat-option with id 'mat-option-167' that contains the text "Oeuvre"
    await page.click('#mat-option-0');

    // Wait for the mat-radio-button element containing the "Registre public" text to appear in the DOM
    await page.waitForSelector('#mat-radio-2');
    await page.click('#mat-radio-2');

    // Wait for the button with text 'Plus de critères' to appear in the DOM
    await page.waitForSelector(
      '#main > div > div:nth-child(2) > div > div.ng-star-inserted > mat-card > mat-card-content > div > button:nth-child(2)',
    );
    // Then click on the button with text 'Plus de critères'
    await page.click(
      '#main > div > div:nth-child(2) > div > div.ng-star-inserted > mat-card > mat-card-content > div > button:nth-child(2)',
    );

    // Wait for the mat-select element with formcontrolname 'format' to appear in the DOM
    await page.waitForSelector('#mat-select-6');
    // Then click on the mat-select element with formcontrolname 'format'
    await page.click('#mat-select-6');

    // Wait for the mat-option element containing the "Long métrage" text to appear in the DOM
    await page.waitForSelector('#mat-option-5');
    await page.click('#mat-option-5');

    // Click on the mat-select with formcontrolname 'typeDuree' to open the dropdown
    await page.waitForSelector('#mat-select-8');
    await page.click('#mat-select-8');

    // Wait for the mat-option element containing the "Cinématographique" text to appear in the DOM
    await page.waitForSelector('#mat-option-18');
    await page.click('#mat-option-18');

    // Wait for the button element containing the "Rechercher" text to appear in the DOM
    await page.waitForSelector(
      '#main > div > div:nth-child(2) > div > div.ng-star-inserted > mat-card > mat-card-content > div > button.mat-focus-indicator.mat-raised-button.mat-button-base.mat-primary',
    );
    await page.click(
      '#main > div > div:nth-child(2) > div > div.ng-star-inserted > mat-card > mat-card-content > div > button.mat-focus-indicator.mat-raised-button.mat-button-base.mat-primary',
    );
    await page.waitForSelector('#mat-select-16');
    await page.click('#mat-select-16');

    await page.waitForSelector('#mat-option-59');
    await page.click('#mat-option-59');

    // Initialize an array to store the results from all pages
    let allResults = [];
    let isDisabled = false;

    do {
      const payloadPromise = new Promise<any>((resolve) => {
        page.on('response', async (response) => {
          const request = response.request();
          if (
            request.url().includes('/rca.frontoffice/api/search/searchOeuvre') &&
            request.method() === 'POST'
          ) {
            const payload = await response.json();
            resolve(payload);
          }
        });
      });

      const payload = await payloadPromise;
      const extractedData = payload.resultatsRecherche.map((item) => ({
        id: item.id,
        numeroImmatriculation: item.numeroImmatriculation,
        dateImmat: item.dateImmat,
        titre: item.titre,
        refId: item.refId,
      }));

      allResults = allResults.concat(extractedData);
      console.log(allResults);

      isDisabled = await page.evaluate(() => {
        const nextButton = document.querySelector('.mat-icon-button[aria-label="Page suivante"]');
        if (nextButton && !nextButton.hasAttribute('disabled')) {
          (nextButton as HTMLElement).click();
          return false;
        }
        return true;
      });

      if (!isDisabled) {
        // Wait for the click to be processed before waiting for navigation
        await page.waitForTimeout(1000);
        await page.waitForNavigation({ waitUntil: 'networkidle0' });
      }
      await page.screenshot({ path: `screenshot${Date.now()}.png` });
    } while (!isDisabled);

    await browser.close();

    return allResults;
  }
}

The do…while runs once since i allResults console logged but the screenshot is not taken and the code won’t loop.

I have tried switching the selector or the selecting method ($/evaluate/xPath) but nothing works.

On page 2, the button is identical, it is only modified on the last page with disabled tag.

complexity is x it is time to do something…, visual studio code

I am using vscode for a react native app. And I am wondering if the message:

complexity is x it is time to do something… is always usefull.

Because for example I have this function:

import { API_URL } from "@env";
import { retrieveToken } from "../authentication/token";
export const fetchCategoryData = async () => {
    const token = await retrieveToken();
    try {
        if (token) {
            const response = await fetch(`${API_URL}/api/categories/main_groups/`, {
                method: "GET",
                headers: {
                    Authorization: `Token ${token}`,
                    "Content-Type": "application/json",
                },
            });
            return await response.json();
        } else {
            throw new Error(token);
        }
    } catch (error) {
        Error("can't retreive data");
    }
}

And vscode says:

complexity is 6 it is time to do something…

retrieveToken:

import AsyncStorage from "@react-native-async-storage/async-storage";

export const retrieveToken = async () => {
    try {
        const token = await AsyncStorage.getItem("Token");

        return token;
    } catch (error) {
        return null;
    }
};

Quesiton: How to improve the function where the message says: complexity is 6 it is time to do something…?

Display authenticated image

I have two servers – one handling images and the other serving the main webpage. The main page needs to access images from the image server, including some private ones that require authentication. I am facing a challenge in figuring out how to send a request from the main server to the image server along with the authentication token.

The problem arises from the Cross-Origin Resource Sharing (CORS) policy because the request are restricted from including headers and cookies. Due to this, I am unable to include the authentication code in the request headers.

The image handling looks something like this, and it is working well. (Tested with Postman)

app.get("/:file", async (req, res) => {
  const filename = req.params.file
  const authorization = req.headers.authorization

  if (public.includes(filename)) {
    streamFile(res, `public/${filename}`)
  } else if (private.includes(filename) && authorization) {
    const valid = somethingThatCheckAuthorization(authorization)

    if (valid) {
        streamFile(res, `private/${filename}`)
    } else {
      return res.sendStatus(400)
    }
  } else {
    return res.sendStatus(400)
  }
})

How can I get an authenticated image to appear on a webpage?

JS Slider made with swiper.js crashes on changing site pages in prod mode

I’m new in frontend and got some problems with swiper.js on my website [https://awaketensei.ru/]. When i changing page from “services” or “work” on any page without slider, it crashes down in a column. But it crashes only when deployed (“npm start” on the localhost or on ubuntu server), “npm run dev” mode works fine.

Project stack: JS + Tailwind (PCSS) + React + next.js

ServiceSlider.js

import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/free-mode';
import 'swiper/css/pagination';

// icons
import {
  RxCrop,
  RxDesktop,
  RxReader,
  RxRocket,
  RxArrowTopRight,
} from 'react-icons/rx';

import { FreeMode, Pagination } from 'swiper';

// data
const serviceData = [
  {
    icon: <RxDesktop />,
    title: 'Development',
    description: 'Script and web development, bug-fixing',
  },
  {
    icon: <RxCrop />,
    title: 'Design',
    description: 'Some kind of web-design, AI art generation',
  },
  {
    icon: <RxRocket />,
    title: 'PC Buiding',
    description: 'Servrer or personal PC building',
  },
  {
    icon: <RxReader />,
    title: 'Translation',
    description: 'Professional RU-ENG/ENG-RU translation',
  },
];

const ServiceSlider = () => {
  return ( 
    <Swiper 
      breakpoints={{
        320: {
          slidesPerView: 1,
          spaceBetween: 15,
        },

        640: {
          slidesPerView: 3,
          spaceBetween: 15,
        },
      }}
     freeMode={true}
      pagination={{
        clickable: true,
      }}
      modules={[FreeMode, Pagination]}
      className='h-[240px] sm:h-[340px]'
    >
      {
      serviceData.map((item, index) => {
          return (
            <SwiperSlide key={index}>
              <div className='bg-[rgba(65,47,123,0.15)] h-max rounded-lg px-6 py-8 flex
              sm:flex-col gap-x-6 sm:gap-x-0 group cursor-pointer hover:bg-[rgba(89,65,169,0.15)]
              transition-all duration-300'>
                {/* icon */}
                <div className='text-4xl text-accent mb-4'>
                  {item.icon}
                </div>
                {/* title & desc */}
                <div className='mb-8'>
                  <div className='mb-2 text-lg'>
                    {item.title}
                  </div>
                    <p className='max-w-[350px] leading-normal'>
                      {item.description}
                    </p>
                </div>
                {/* arrow */}
                <div className='text-3xl'>
                  <RxArrowTopRight className='group-hover:rotate-45
                  group-hover:text-accent transition-all duration-300'/>
                </div>
              </div>
            </SwiperSlide>
          );
        })}
    </Swiper>
  );
};
export default ServiceSlider;

Page where slider integrated:

import ServiceSlider from '../../components/ServiceSlider';
import Bulb from '../../components/Bulb';
import Circles from '../../components/Circles';

// framer-motion
import { motion } from 'framer-motion';
import { fadeIn } from '../../variants';

const Services = () => {
  return ( 
    <div className='h-full bg-primary/30 py-36 flex items-center'>
      <Circles />
      <div className='container mx-auto'>
        <div className='flex flex-col xl:flex-row gap-x-8'>
          {/* text */}
          <div className='text-center flex xl:w-[30vw] flex-col lg:text-left 
          mb-4 xl:mb-0'>
              <motion.h2 
                variants={fadeIn('up, 0.3')} 
                initial="hidden" 
                animate="show"
                exit="hidden" 
                className='h2 xl:mt-8'
              >
              My Services <span className='text-accent'>.</span>
              </motion.h2>
              <motion.p 
                variants={fadeIn('up, 0.4')} 
                initial="hidden" 
                animate="show"
                exit="hidden" 
                className='mb-4 max-w-[400px] mx-auto lg:mx-0'>
                Thanks for visiting my website!
              </motion.p>
          </div>

          {/* Slider */}
          <motion.div 
            variants={fadeIn('down, 0.6')} 
            initial="hidden" 
            animate="show"
            exit="hidden" 
            className='w-full xl:max-w-[65%]'
          > 
            <ServiceSlider />
          </motion.div>
        </div>
      </div>
      <Bulb />
    </div>
  );
};
export default Services;

I’ve researched Internet for several days, but it was useless for me. Tried to found vulnerabilities issues, used edge dev console to check some issues, but I haven’t found any problems.

Thanks in advance for your time and answers.