How to render HTML from database in react?

I am working on making custom webpages with the help of Grapesjs. I want to render the html page in react js which has been been saved by the grapesjs editor in the database. Following is the format in which the data is being saved.

Right now I just able to get the html code in the inspect window, but how can i render it on the page?

import React from "react";
import axios from "axios";
// import {renderWebpage} from "../actions/webpage"

export const Page: React.FC = () => {
  const renderWebpage = axios
    .get("http://localhost:8080/61ea7fd2268f37443ca4d59a")
    .then((response) => {
      console.log("response", response);
      console.log(response.data, "data");
    });

  return <div>demo</div>;
};

Why does hit test seem to be calling my code in chrome devtools perf tab

I have a website I’m working on where there is an iframe which calls document.elementFromPoint in a loop in an event handler a bunch of times. I did a performance snapshot of the code and saw something strange.chrome dev tools perf tab, hit test is above event handler and element from point.
It seems like hit test, which is a internal browser thing, is calling my anonymous event handler which is calling element from point. But this doesn’t make any sense. It should be that my event handler is calling elementFromPoint which then should be calling hit test, assuming hit test is what is internally used in elementFromPoint. Also I don’t see why there seem to be gaps in the main thread.
Can anyone explain why this is happening?

Other details.

  • The Iframe has same origin
  • document.elementFromPoint is getting svg elements

What I have found.

  • When the loop is not so long the order is correct, my code calls elementfrompoint calls hit test.
  • Long loops seem to cause the issue

In React useEffect, how do you sneak state updates in between long running code?

I’m having trouble getting my loading status to appear before the longRunningCode executes. I tried making it async to no avail.

const [loadingStatus, setLoadingStatus] = useState(undefined);
const [myAction, setMyAction] = useState(undefined);

useEffect(async () => {
  if (myAction) {
    setLoadingStatus('Do the thing...')
    const result = await longRunningCode()
    // ...
    setLoadingStatus(undefined)
    setMyAction(undefined)
  }
}, [myAction])

//...

return <p>{loadingStatus}</p><button onClick={() => setMyAction({})} />

Refactor method chaining javascript

I call a function with bunch of nested method, i’m using web scraping tools called cheerio and i want to get the text out of it so i need to call a bunch of function. here’s my example code.

        var text = $(el)
          .children()
          .first()
          .children()
          .first()
          .children()
          .first()
          .text()
          .replace(/ss+/g, " ");

My question is, how can i simplify my function so I have the same result without chaining my function?

Data Context Object in Meteor-Blaze

I’m failing to understand what is a Data Context Object in Meteor-Blaze. Can someone explain what is a Data Context Object in Meteor-Blaze? I’ve searched in the internet yet I couldn’t find any proper answers. I’m new to Meteor Blaze please help me…Thanks in advance :).

select 2 ajax success only works once

i am using select2 value to populate other readonly field in the same form, my question is why the ajax success function populate the field only once but when i do something(solution) wrong it called the success function multiple time?

<script>
        $(document).ready(function () {
            $("#barang_id").select2({
                placeholder: "Cari...",
                allowClear: true,

                ajax: {
                    url: "/api/barang",
                    contentType: "application/json; charset=utf-8",
                    data: function (params) {

                        var query =
                        {
                            term: params.term,
                        };
                        return query;
                    },
                    headers: {
                        "RequestVerificationToken":
                            $('input[name="__RequestVerificationToken"]').val()
                    },
                    processResults: function (data) {
                        return {
                            results: $.map(data, function (item) {
                                return {
                                    id: item.id,
                                    text: item.kode + ' - ' + item.nama
                                }
                            })
                        }
                    },
                    success: function (data) {
                        $.map(data, function (item) {
                            $("#nama").val(item.nama);
                            $("#kode").val(item.kode);
                        })
                    }
                }

            });
        });
    </script>

how to prevent IDM (internet download manager) to download song, song link is given in anchor tag in HTML

I’m making audio player using wavesurfer.js. I have made an anchor tag and put the song link in anchor’s href attribute like this.

<a href="songs/song5.mp3" class="btn songlink songBtn"><i class="fa fa-play fa-lg playbtn"></i></a>

Everything is working fine but if I install [IDM]. It starts downloading the song and songs doesn’t play on the browser. So where should I put the song link in order to prevent the downloading.

here is my jQuery code and html code is as given above

$(".player-playlist .songlink").click(function(){
                songLink = $(this).attr('href');
                wavesurfer = WaveSurfer.create({
                    container: '#playing-wave',
                    waveColor: '#CCCCCC',
                    progressColor: '#E64C51',
                    barWidth:1,
                    height:40,
                    barGap:0,
                    backgroundColor: 'transparent',
                    cursorColor: 'transparent',
                    plugins: [
                        WaveSurfer.minimap.create({
                            container: '#wave-minimap',
                            waveColor: '#CCCCCC',
                            progressColor: '#E64C51',
                            barWidth:1,
                            height:30,
                            barGap:0,
                            backgroundColor: 'transparent',
                            cursorColor: 'transparent',
                        })
                    ]
                });

});

JavaScript Array forEach function not working?

I tried to do some changes in the W33 school’s javascript code to learn about the difference
between forEach and map, is there anyone can please tell me why the output of this code is still:

45,4,9,16,25

instead of

90,8,18,32,50

Isn’t it forEach means call a function to every element in this array? I know I should not use return because the forEach does not return valid result.

const numbers = [45, 4, 9, 16, 25];

numbers.forEach(myFunction);
document.getElementById("demo").innerHTML = numbers;

function myFunction(value, index, array) {
  value * 2;
}
<!DOCTYPE html>
<html>

<body>

  <h2>JavaScript Array.forEach()</h2>
  <p>Calls a function once for each array element.</p>

  <p id="demo"></p>

</body>

</html>

Cannot read properties of undefined (reading ‘value’) from the field with options

I’m trying to display the value of the select field, however, this is what the error shows:

Cannot read properties of undefined (reading 'value')

enter image description here

This is the codesandbox link: https://codesandbox.io/s/basicselect-material-demo-forked-4g34r?file=/demo.js

Below are the codes:

import React, { useState, useEffect } from "react";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";

import { TextField, Button } from "@mui/material";

export default function BasicSelect() {
  const [prod, setProd] = useState("");
  const [qty, setQty] = useState(0);
  const [design, setDesign] = useState("");
  const [size, setSize] = useState("");

  const handleChange = (event) => {
    setProd(event.target.value);
  };

  const handleChangeSize = (event) => {
    setSize(event.target.value);
  };

  const handleChangeDesign = (event) => {
    setDesign(event.target.value);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    console.log(prod, qty, size, design);
  };

  const [sizeList, setSizeList] = useState([{ size: "" }]);
  console.log(sizeList);

  //helper method
  const handleAdd = () => {
    setSizeList([...sizeList, { size: "" }]);
  };

  const handleRemove = (index) => {
    const list = [...sizeList];
    list.splice(index, 1);
    setSizeList(list);
  };

  const handleSizeChange = (e, index) => {
    const { name, value } = e.tagret.value;
    const list = [...sizeList];
    list[index][name] = value;
    setSizeList(list);
  };

  return (
    <Box sx={{ minWidth: 120 }}>
      <form onSubmit={handleSubmit}>
        <FormControl fullWidth>
          <InputLabel id="demo-simple-select-label">Product</InputLabel>
          <Select
            labelId="demo-simple-select-label"
            id="demo-simple-select"
            value={prod}
            label="Product"
            onChange={handleChange}
          >
            <MenuItem value="Item1">Item1</MenuItem>
            <MenuItem value="Item2">Item2</MenuItem>
            <MenuItem value="Item3">Item3</MenuItem>
          </Select>
        </FormControl>
        <br />
        <br />
        {/* <TextField
          type="number"
          label="Quantity"
          variant="outlined"
          value={qty}
          onChange={(e) => setQty(e.target.value)}
          fullWidth
        /> */}

        <br />

        <br />
        {sizeList.map((singleSize, index) => (
          <div key={index}>
            <FormControl fullWidth>
              <InputLabel id="demo-simple-select-label">Size</InputLabel>
              <Select
                labelId="demo-simple-select-label"
                id="size"
                value={singleSize.size}
                label="Product"
                // onChange={handleChangeSize}
                onChange={(e) => handleSizeChange(e, index)}
              >
                <MenuItem value="S">Small</MenuItem>
                <MenuItem value="M">Medium</MenuItem>
                <MenuItem value="L">Large</MenuItem>
              </Select>
            </FormControl>

            <br />
            <br />
            {sizeList.length > 1 && (
              <Button
                onClick={() => handleRemove(index)}
                variant="contained"
                color="secondary"
              >
                Remove{" "}
              </Button>
            )}
            <br />
            <br />
            {sizeList.length - 1 === index && (
              <Button variant="contained" onClick={handleAdd}>
                {" "}
                Add Quantity
              </Button>
            )}
          </div>
        ))}

        <br />
        <br />
        <FormControl fullWidth>
          <InputLabel id="demo-simple-select-label">Choose Design</InputLabel>
          <Select
            labelId="demo-simple-select-label"
            id="demo-simple-select"
            value={design}
            label="Product"
            onChange={handleChangeDesign}
          >
            <MenuItem value="Design1">Design1</MenuItem>
            <MenuItem value="Design2">Design2</MenuItem>
            <MenuItem value="Design3">Design3</MenuItem>
          </Select>
        </FormControl>
        <br />
        <br />
        <Button type="submit">Submit </Button>
      </form>
      <Button>Add more Product </Button>
    </Box>
  );
}

How to bind an new event after an ajax success

I’m uploading different images sending the form with ajax, and if the image is uploaded successfully, the button to launch the modal to upload the images changes the data-target attribute to launch a different modal to delete the images and vice versa, but after the image is uploaded and the text in the button changes as well as the data-target attribute (I can see it in the browser inspector that it changed), it is not working (I guess it has to do with the dom, because the form that is bound with the event is the form that uploads the image, not the one that deletes it. How can I do that? Any help will be appreciated. Thanks

$('body').on('submit','form[id="image-form"]', function(e) {
                e.preventDefault();
                    $("#upmsg").html('<div class="alert alert-info"><i class="fa fa-spin fa-spinner"></i> Please wait...!</div>');
                    $.ajax({
                        type: "POST",
                        url: "dir_programs_img_upload.php",
                        data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                        contentType: false, // The content type used when sending data to the server.
                        cache: false, // To unable request pages to be cached
                        processData: false, // To send DOMDocument or non processed data file it is set to false
                        dataType:"json",
                        success: function(data) {
                            if (data.status == 1 || parseInt(data.status) == 1) {
                                if (data.target == "thumb") {
                                    $("#img-thumb").attr("src","../img/prog_thumbs/" + data.name);
                                    $("#action-thumb").attr("data-target", "mod-img-del");
                                    $("#action-thumb").html("Remove Image");
                                } else if (data.target == "slide1") {
                                    $("#img-slide1").attr("src","../img/prog_carousel/" + data.name);
                                    $("#action-slide1").attr("data-target", "mod-img-del");
                                    $("#action-slide1").html("Remove Image");
                                } else if (data.target == "slide2") {
                                    $("#img-slide2").attr("src","../img/prog_carousel/" + data.name);
                                    $("#action-slide2").attr("data-target", "mod-img-del");
                                    $("#action-slide2").html("Remove Image");
                                } else if (data.target == "slide3") {
                                    $("#img-slide3").attr("src","../img/prog_carousel/" + data.name);
                                    $("#action-slide3").attr("data-target", "mod-img-del");
                                    $("#action-slide3").html("Remove Image");
                                } else if (data.target == "slide4") {
                                    $("#img-slide4").attr("src","../img/prog_carousel/" + data.name);
                                    $("#action-slide4").attr("data-target", "mod-img-del");
                                    $("#action-slide4").html("Remove Image");
                                } else if (data.target == "map") {
                                    $("#img-map").attr("src","../img/prog_maps/" + data.name);
                                    $("#action-map").attr("data-target", "mod-img-del");
                                    $("#action-map").html("Remove Image");
                                }
                                $("#upmsg").html("");
                                $('#image-form')[0].reset();
                                $("#preview").attr("src","img/img12.jpg");
                                $('#mod-upload').modal('hide');  
                            } else {
                                $("#upmsg").html('<div class="alert alert-info"><i class="fa fa-exclamation-triangle"></i> ' + data.msg + '</div>');
                            }
                        },
                        error: function(data) {
                            $("#upmsg").html('<div class="alert alert-danger"><i class="fa fa-exclamation-triangle"></i> There is some thing wrong.</div>');
                        }
                    });
                });

What is a Google Apps Script to Calculate the Probability of Independent Events?

I am trying to create a script that calculates the probability of 0-20 wins in a 20-game season, with the results going in Column F of this spreadsheet.
enter image description here

Finding the probability of 0 and 20 wins is simple and quick, because there is only one way to achieve each. Calculating the probability of 1:19 wins is simple but takes much longer, because there are 1,048,576(2^20-2) different ways that can play out. There is an awesome VBA/Excel solution for this problem here, but I would like to use GAS.

VBA that works in Excel:

Sub CountEm() Dim i As Long, j As Long, str1 As String, wk As Double Dim probs As Variant, outprobs(0 To 20, 1 To 1) As Double, ctr As Long Dim ix(20) As Byte

For i = 0 To 2 ^ 20 - 1
    ctr = 0
    wk = 1
    ctr = 0
    For j = 1 To 20
        If ix(j) = 1 Then
            wk = wk * probs(j, 1)
            ctr = ctr + 1
        Else
            wk = wk * probs(j, 2)
        End If
    Next j
    outprobs(ctr, 1) = outprobs(ctr, 1) + wk

    For j = 1 To 20
        ix(j) = ix(j) + 1
        If ix(j) = 1 Then Exit For
        ix(j) = 0
    Next j
Next i
Range("F2:F22").Value = outprobs, End Sub

This is the my GAS attempt:

function multiplyArrays2() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sht = ss.getSheetByName("Script ProbWin");  
var probs = sht.getRange("B3:C22").getValues();  
    for (var i = 0; i < 2^20-1; i++) { //2^20=total combinations
       var ctr = 0; //I deleted the duplicate of this exact line below var wk and VBA ran
       var wk = 1; //Added "var" for GAS
        for (var j; i < 20; i++) {
             if ix[j] = 1 {  //this is the first line GAS underlines red. I don't know how to deal with the "x"
                wk = wk * probs[j, 1] //changed () to [] to deal with array
                ctr = ctr + 1
              } else {
                wk = wk * probs[j, 2]
              }
        }     
      var outprobs[ctr, 1] = outprobs[ctr, 1] + wk;  //added "var"
        for (var j; i < 20; i++) {
            ix[j] = ix[j] + 1 //again, I don't know how to deal with the "x"
            if ix[j] = 1 {
            ix[j] = 0
        }
        }   
   } 
  sht.getRange("F2:F22").setValues(outprobs);
};

Any help is greatly appreciated.

Binary Search Tree & “Cannot read properties of null”

I have a generic binary search tree that uses a comparator function to evaluate which value is bigger. This is my remove method:

remove(data) {
        const removeHelper = (node, data) => {
            if (!node) return null;
            if (this.#comparator(data, node.data) === 0) {
                if (!node.left && !node.right) return null;
                if (!node.left) return node.right;
                if (!node.right) return node.left;
                let tmp = node.right;
                while (!tmp.left) {
                    tmp = tmp.left;
                }
                node.data = tmp.data;
                node.right = removeHelper(node.right, tmp.data);
            } else if (this.#comparator(data, node.data) === -1) {
                node.left = removeHelper(node.left, data);
                return node;
            } else {
                node.right = removeHelper(node.right, data);
                return node;
            }
        };
        this.root = removeHelper(this.root, data);
        return data;
    }

I keep getting the error: TypeError: Cannot read properties of null (reading 'left') reffering to this line: (while (!tmp.left) )

How is my remove method not supposed to read property types of null if thats what the entire method functions off of

Error: connect ETIMEDOUT xxx.xx.xxx.xxx:587 Nodemailer script stopped working with outlook throws

A few months ago I created this script to help me send multiple mails at once instead of sending them one by one, and it was working perfectly till now.

For this script, I’ve used dotenv, nodemailer, and nodemon (only in development, when I finished it I started using npm run start to run it)

    (function main() {

    const { contacts } = contacts_list;

    try {

        const { MAIL_ACCOUNT, MAIL_PASSWORD } = process.env;

        const transport = nodemailer.createTransport({

            // Uses 'pool' attribute: The same connection is used to send up to 100 mails before being disposed.
            pool: true,
            // Sets the number of max connections per transport. Microsoft accepts up to 1 parallel connection for the same client.
            maxConnections: 1,
            logger: true,
            debug: true,
            service: "hotmail",
            auth: {
                user: MAIL_ACCOUNT,
                pass: MAIL_PASSWORD
            },
            tls: { rejectUnauthorized: false }

        })

        // Change mail parameters such as subject, recipients, content, etc
        const mailParams = {
            from: `test <${MAIL_ACCOUNT}>`,
            to: '',
            attachments: [],
            subject: `test`,
            text: `test`,
            html: `<h1>test</h1>`
        }

        // Mail every contact once at a time with its corresponding attachments
        contacts.forEach(async (contact) => {

            mailParams.to = contact.email;
            mailParams.attachments = [...contact.attachments];

            await transport.sendMail(mailParams);

        })


    } catch (err) {
        
        console.error(err);

    }

})();

I’ve already scanned for blocked ports, disabled firewall when trying to use it and antivirus as well. None of these approaches worked.

It throws the following error:

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

Error: connect ETIMEDOUT xxx.xx.xxx.xxx:587
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16) {
  errno: -4039,
  code: 'ESOCKET',
  syscall: 'connect',
  address: 'xxx.xx.xxx.xxx',
  port: 587,
  command: 'CONN'
}

Logger prints the following lines:

[2022-02-03 01:39:22] DEBUG Creating transport: nodemailer (6.7.2; +https://nodemailer.com/; SMTP (pool)/6.7.2[client:6.7.2])
[2022-02-03 01:39:22] DEBUG Sending mail using SMTP (pool)/6.7.2[client:6.7.2]
[2022-02-03 01:39:22] DEBUG Sending mail using SMTP (pool)/6.7.2[client:6.7.2]
[2022-02-03 01:39:22] INFO  [#1] Created new pool resource #1
[2022-02-03 01:39:22] DEBUG [#1] Assigned message <[email protected]> to #1 (1)
[2022-02-03 01:39:22] DEBUG [nHXJGQWMbA] Resolved smtp.live.com as xxx.xx.xxx.xxx [cache miss]
[2022-02-03 01:39:43] ERROR [nHXJGQWMbA] connect ETIMEDOUT xxx.xx.xxx.xxx:587
[2022-02-03 01:39:43] ERROR [#1] Pool Error for #1: connect ETIMEDOUT xxx.xx.xxx.xxx:587
[2022-02-03 01:39:43] ERROR Send Error: connect ETIMEDOUT xxx.xx.xxx.xxx:587
[2022-02-03 01:39:43] DEBUG [nHXJGQWMbA] Closing connection to the server using "destroy"
[2022-02-03 01:39:43] INFO  [#1] Connection #1 was closed

If you know how to solve it, i’ll be very grateful if you lend me a hand!

How do I get my etch-a-sketch program to “listen” to this dropdown menu instead of the buttons?

I’m new to Stack Overflow. I hope that I’m doing this correctly. ❤

I’m working on an old Etch-a-Sketch JavaScript project from months ago and decided to rework the ‘mobile’ form of the project because I hadn’t bothered to do so at the time. At first, I tried just moving the buttons to the top horizontally, but I didn’t like any of the variations I tried. So I decided I’d be better off with a dropdown menu instead that would appear when the screen is 500px or smaller, replacing the buttons.

The dropdown menu is supposed to do exactly what the buttons do – when a certain mode is selected, that’s the mode that the program is supposed to switch to. For example, when the “Party mode” button is clicked, the program switches to “party mode”. I want the dropdown menu to behave similarly – when the “party mode” option is selected, the program should switch to “party mode”.

My logic was that I needed a function that grabbed the value of the dropdown menu, and then an “if” condition would run that pretty much says “If the value is x, x mode should run; else if the value is y, y mode should run”, and so on. I added the function to the existing window.onload function so it would run upon the window loading. This didn’t work.

Note that the dropdown menu will, in the future, only appear when the screen size is 500px or less. In addition, I still have the buttons on the screen for all sizes, just for testing/debugging purposes. When I’m done and have this figured out, the buttons will have “display = ‘none'” and be hidden for the “mobile size”.

Anyway, so yeah, the program is still just listening to the buttons, and not the dropdown menu. That leads me to believe that I need to somehow turn “off” the button mode? If that’s the case, how do I do that? If that’s not the case, what am I supposed to do here? Any help or insight would be greatly appreciated. Thanks!

const defaultMode = 'default';
const defaultSize = 30;
const defaultColor = '#0b478b';
let currentMode = defaultMode;
let currentSize = defaultSize;
let currentColor = defaultColor;

// Sets the program's current mode
function setCurrentMode(newMode) {
  activeButton(newMode);
  currentMode = newMode;
}

// Sets the grid's size
function setCurrentSize(newSize) {
  currentSize = newSize;
}

// Sets the color of the square (if in default mode)
function setCurrentColor(newColor) {
  currentColor = newColor;
}

// Links the various HTML elements to this script
const sizeValue = document.querySelector('#sizevalue');
const sizeSlider = document.querySelector('#sizeslider');
const colorPicker = document.querySelector('#colorpicker');
const defaultBtn = document.querySelector('#default');
const partyBtn = document.querySelector('#party');
const grayBtn = document.querySelector('#grayscale');
const eraserBtn = document.querySelector('#eraser');
const clearBtn = document.querySelector('#clear');
const grid = document.querySelector('#maincontainer');

// DOM manipulations for buttons, color picker, and size slider
colorPicker.onchange = (e) => setCurrentColor(e.target.value);
defaultBtn.onclick = () => setCurrentMode('default');
partyBtn.onclick = () => setCurrentMode('party');
grayBtn.onclick = () => setCurrentMode('gray');
eraserBtn.onclick = () => setCurrentMode('eraser');
clearBtn.onclick = () => reloadGrid();
sizeSlider.onmousemove = (e) => updateSizeValue(e.target.value);
sizeSlider.onchange = (e) => changeSize(e.target.value);

// When the size is changed, we set the grid size, update the size value (text), and reload the grid.
function changeSize(num) {
  setCurrentSize(num);
  updateSizeValue(num);
  reloadGrid();
}

// When we update the size value, the text changes to reflect the value. (It's a square, so the value is always the same for length and width).
function updateSizeValue(num) {
  sizeValue.innerHTML = `${num} x ${num}`;
}

// When we reload the grid (which happens when "Clear grid" is pressed), we ensure that we clear the grid and that the size is still the current size.
function reloadGrid() {
  clearGrid()
  makeGrid(currentSize)
}

// When we clear the grid, it clears the grid.
function clearGrid() {
  grid.innerHTML = ''
}

// Creates the base grid and includes the code that says "when the mouse goes over the squares, draw."
function makeGrid(size) {
  grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
  grid.style.gridTemplateRows = `repeat(${size}, 1fr)`;
  for (i = 0; i < size * size; i++) {
    let square = document.createElement('div');
    square.addEventListener('mouseover', changeColor);
    grid.appendChild(square);
  }
}

// These are the conditions to set the color of the "pen" (squares)
function changeColor(e) {
  if (currentMode === 'party') {
    const randomR = Math.floor(Math.random() * 256);
    const randomG = Math.floor(Math.random() * 256);
    const randomB = Math.floor(Math.random() * 256);
    e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
  } else if (currentMode === 'default') {
    e.target.style.backgroundColor = currentColor;
  } else if (currentMode === 'gray') {
    e.target.style.backgroundColor = calculateGray(e);
  } else if (currentMode === 'eraser') {
    e.target.style.backgroundColor = 'white';
  }
}

// Shading mode code
function calculateGray(e) {
  let clr = returnRGB(e.target.style.backgroundColor);
  if (!clr || clr[1] !== clr[2] || clr[1] !== clr[3]) {
    return `rgb(255, 255, 255)`;
  }
  return clr[1] <= 0 ? `rgb(255, 255, 255)` : `rgb(${clr[1]-25}, ${clr[1]-25}, ${clr[1]-25})`;
}

function returnRGB(num) {
  return num.match(/rgb(([0-9]*), ([0-9]*), ([0-9]*))/);
}

// Changes the button styling to indicate which mode is the active mode
function activeButton(newMode) {
  if (currentMode === 'party') {
    partyBtn.classList.remove('active');
  } else if (currentMode === 'default') {
    defaultBtn.classList.remove('active');
  } else if (currentMode === 'gray') {
    grayBtn.classList.remove('active');
  } else if (currentMode === 'eraser') {
    eraserBtn.classList.remove('active');
  }

  if (newMode === 'party') {
    partyBtn.classList.add('active');
  } else if (newMode === 'default') {
    defaultBtn.classList.add('active');
  } else if (newMode === 'gray') {
    grayBtn.classList.add('active');
  } else if (newMode === 'eraser') {
    eraserBtn.classList.add('active');
  }
}

// Ensures that, when we load the page, we make the grid and activate the correct mode (default).
window.onload = () => {
  makeGrid(defaultSize);
  activeButton(defaultMode);
  dropdownModeThing(document.getElementById('dropdown-mode').value);
}

// Code for the dropdown menu
function dropdownModeThing(val) {
  if (val === 'default') {
    setCurrentMode('default');
  } else if (val === 'party') {
    setCurrentMode('party');
  } else if (val === 'shading') {
    setCurrentMode('gray');
  } else if (val === 'eraser') {
    setCurrentMode('eraser');
  } else if (val === 'clear') {
    reloadGrid();
  }
}
body,
html {
  min-height: 100vh;
  height: 100%;
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  margin: 0;
  padding: 0;
  background-color: white;
  overflow-x: hidden;
}

header {
  text-align: center;
  margin: 0;
  border-bottom: 1px solid black;
  background-color: #0b478b;
  color: white;
  padding: 10px;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}

p {
  margin: 0;
}

h1 {
  text-align: center;
  margin: 0;
  font-size: 2.5rem;
  padding: 0;
}

#maincontainer {
  background-color: white;
  margin: 20px auto 10px auto;
  display: grid;
  border: 1px solid black;
  width: 45vw;
  height: 45vw;
  min-height: 300px;
  min-width: 300px;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}

.testing {
  padding-top: 100%;
  color: hsla(0, 0%, 68%, 0.596);
}

#btncontainer {
  padding-top: 20px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

a {
  color: #2aa5a1;
  text-decoration: none;
}

a:hover {
  color: white;
}

button {
  background-color: #2aa5a1;
  color: white;
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  border: 1px solid black;
  margin: 10px 15px;
  padding: 8px 10px;
  font-size: .9em;
  transition: 0.3s;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}

button:active {
  background-color: #3F86D8;
  color: white;
  border: 1px solid black;
}

.active {
  background-color: #3F86D8;
  transition: 0.3s;
  color: white;
  border: 1px solid black;
}

button:hover {
  background-color: #0b478b;
  color: white;
  border: 1px solid black;
  opacity: 1;
}

#rightside {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  text-align: center;
  min-height: 500px;
  padding: 0;
  margin: 0;
}

#sizevalue {
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  margin-bottom: 0;
}

input[type=range] {
  background-color: white;
  height: 28px;
  -webkit-appearance: none;
  margin: 0;
  margin-bottom: 35px;
  width: 250px;
  padding: 0;
}

input[type=range]:focus {}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 11px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000;
  background: #3F86D8;
  border-radius: 13px;
  border: 0px solid #010101;
}

input[type=range]::-webkit-slider-thumb {
  box-shadow: 1px 1px 2px #000031;
  border: 1px solid #00001E;
  height: 20px;
  width: 20px;
  border-radius: 15px;
  background: #FFFFFF;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -5px;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #3F86D8;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 11px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000;
  background: #3F86D8;
  border-radius: 13px;
  border: 0px solid #010101;
}

input[type=range]::-moz-range-thumb {
  box-shadow: 1px 1px 2px #000031;
  border: 1px solid #00001E;
  height: 20px;
  width: 20px;
  border-radius: 15px;
  background: #F3EEED;
  cursor: pointer;
}

input[type=range]::-ms-track {
  width: 100%;
  height: 11px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  color: transparent;
}

input[type=range]::-ms-fill-lower {
  background: #3F86D8;
  border: 0px solid #010101;
  border-radius: 26px;
  box-shadow: 1px 1px 1px #000000;
}

input[type=range]::-ms-fill-upper {
  background: #3F86D8;
  border: 0px solid #010101;
  border-radius: 26px;
  box-shadow: 1px 1px 1px #000000;
}

input[type=range]::-ms-thumb {
  margin-top: 1px;
  box-shadow: 1px 1px 2px #000031;
  border: 1px solid #00001E;
  height: 20px;
  width: 20px;
  border-radius: 15px;
  background: #F3EEED;
  cursor: pointer;
}

input[type=range]:focus::-ms-fill-lower {
  background: #3F86D8;
}

input[type=range]:focus::-ms-fill-upper {
  background: #3F86D8;
}

main {
  display: flex;
  justify-content: center;
  margin: 0;
  margin-bottom: 20px;
  padding: 0;
}

#colorpicker {
  -webkit-appearance: none;
  border-radius: 100vw;
  width: 50px;
  height: 50px;
  padding: 0;
  margin: 0 auto 10px auto;
  overflow: hidden;
  border: 1px solid black;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}

input[type='color']:hover {
  transform: scale(1.05);
}

input[type='color']::-webkit-color-swatch-wrapper {
  padding: 0;
}

input[type='color']::-webkit-color-swatch {
  border: none;
  border-radius: 50px;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}


/* Tooltip container */

.tooltip {
  position: relative;
  display: inline-block;
  border-bottom: 1px dotted black;
  /* If you want dots under the hoverable text */
}


/* Tooltip text */

.tooltip .tooltiptext {
  visibility: hidden;
  width: 120px;
  background-color: black;
  color: #fff;
  text-align: center;
  padding: 5px 0;
  border-radius: 6px;
  /* Position the tooltip text - see examples below! */
  position: absolute;
  z-index: 1;
}


/* Show the tooltip text when you mouse over the tooltip container */

.tooltip:hover .tooltiptext {
  visibility: visible;
}

.tooltip .tooltiptext::after {
  content: " ";
  position: absolute;
  top: 50%;
  right: 100%;
  /* To the left of the tooltip */
  margin-top: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent black transparent transparent;
}

footer {
  color: white;
  text-align: center;
  background-color: #0b478b;
  position: fixed;
  bottom: 0;
  width: 100%;
  margin: 0;
  padding-top: 10px;
  padding-bottom: 15px;
}

@media (max-width: 500px) {
  main {
    flex-direction: column;
  }
  #btncontainer {
    margin: 0 auto;
    padding: 20px 10px 5px 10px;
    flex-wrap: wrap;
    flex-direction: row;
    justify-content: center;
  }
  #btncontainer button {
    margin: 0 3px;
    height: 35px;
  }
  #colorpicker {
    -webkit-appearance: none;
    border-radius: 100px;
    width: 35px;
    height: 35px;
    padding: 0;
    margin: 0 auto 10px auto;
    overflow: hidden;
    border: 1px solid black;
    box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- CSS spreadsheet -->
  <link href="styles.css" rel="stylesheet">

  <title>Etch-a-Sketch</title>
</head>

<body>
  <!-- Note that this is set up in various divs so
that we can use Flex to create our wanted layout. -->

  <div id="entirepage">
    <header>
      <h1>Etch-a-Sketch</h1>
      <p title="Testing">Select a color or a different mode, then select your size, and get drawing!</p>
    </header>
    <main>
      <div id="btncontainer">
        <select id="dropdown-mode">
          <option value="default">Default mode</option>
          <option value="party">Party mode</option>
          <option value="shading">Shading</option>
          <option value="eraser">Eraser mode</option>
          <option value="clear">Clear grid</option>
        </select>
        <input type="color" id="colorpicker" value="#0b478b">
        <button id="default">Default mode</button>
        <button id="party">Party mode</button>
        <button id="grayscale">Shading</button>
        <button id="eraser">Eraser mode</button>
        <button id="clear">Clear grid</button>
      </div>
      <div id="rightside">
        <div id="maincontainer">
        </div>
        <label for="sizeslider" id="sizevalue">30 x 30</label>
        <input type="range" min="1" max="100" value="30" id="sizeslider">
      </div>
    </main>
    <footer>
      <p>Created by Sara Dunlop (<a href="https://www.github.com/Risclover" target="_blank">RiscloverYT</a>)</p>
    </footer>
  </div>

  <!-- JavaScript script -->
  <script src="script.js"></script>

</body>

</html>

how to create context for theme with reactjs?

I need to create a context to apply dark or light theme in repositories. There will be no change of themes by button or something like that, I’ll just set the theme and that’s it

for now, I have context like this

import { createContext } from "react";
import { light } from './themes';

export const ThemeContext = createContext(light);

export default ThemeContext;

and my app

import { light, dark } from './themes';


<ThemeContext.Provider value={light}> // or dark, depending on the project
   <App />   
 </ThemeContext.Provider> 
);

that way is not working, how can I apply the theme?