React and Tailwind – Closing a sidemenu when clicking outside the menu

I’m not sure why I always have problems with this, my code seems to close the menu the fraction of a second I click the button to open the menu and I can’t figure out how to stop it.

    const MobileMenu = () => {
  const { open, setOpen } = useContext(DataContext);
  const menuItems = ["Login", "Store", "Community", "About", "Support"];

  window.addEventListener("click", function (e) {
    if (open && !this.document.getElementById("menu").contains(e.target)) {
      e.stopPropagation();
      setOpen(false);
    }
  });

  return (
    <div className="absolute z-30">
      <div
        id="menu"
        className={`bg-very-dark-blue shadow-[0_0px_7px_0px_rgba(0,0,0,0.75)] top-0 left-0 bottom-0 fixed w-[280px] text-[#bdbdbd] ${
          open ? "translate-x-0 block" : "-translate-x-full"
        } transition-all delay-75 duration-500 ease-in-out`}
      >
        <ul className="flex flex-col ">
          {menuItems.map((item) => (
            <li className="text-3xl px-3 py-5 border-t-[1px] border-[#2f3138] border-b-[1px] border-b-black">
              {item}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

If I comment out the window.addEventListener block I can open the menu just fine. Bringing the code block back in stops the menu from opening at all though. It’s set so that if the open state is True and you click outside the menu, then it will set the open state to false. But it seems to think when the open state is false and I click the button to open the menu, that it’s true and sets it back to false.

I thought e.stopPropagation() would prevent that, but no luck.

How to patch or extend PivotGroupByMenu (module not found error)

I’m currently upgrading a custom module from Odoo 17 to Odoo 18. In Odoo 17, I had the following code to patch the PivotGroupByMenu in order to filter pivot fields dynamically:

/** @odoo-module **/

import { PivotGroupByMenu } from "@web/views/pivot/pivot_group_by_menu";
import { patch } from "@web/core/utils/patch";
import { useService } from "@web/core/utils/hooks";
import { onWillStart } from "@odoo/owl";

patch(PivotGroupByMenu.prototype, {
    setup() {
        super.setup(...arguments);
        this.orm = useService("orm");

        onWillStart(async () => {
            const res = await this.orm.call("access.management", "get_hidden_field", [
                this?.env?.searchModel?.resModel,
            ]);
            this.fields = this.fields.filter((ele) => res.includes(ele.name));
        });
    },
});

After upgrading to Odoo 18, I’m getting the following error in the browser console:

The following modules are needed by other modules but have not been defined, they may not be present in the correct asset bundle:

["@web/core/network/rpc_service", "@web/views/pivot/pivot_renderer"]

The following modules could not be loaded because they have unmet dependencies:
[“@simplify_access_management/js/hide_chatter”, “@simplify_access_management/js/pivot_grp_menu”]
It seems that @web/views/pivot/pivot_group_by_menu no longer exists in Odoo 18.

My questions:

  • What is the new way to patch or extend the pivot “Group By” menu in Odoo 18?
  • Has PivotGroupByMenu been removed or renamed in Odoo 18?
  • Is there an official or recommended way to dynamically filter available pivot fields in this version?

How can I create a smooth rotating linear-gradient border animation in CSS? [duplicate]

I’m trying to create an animated rotating border effect using a linear-gradient — where the gradient appears to rotate around an element like a dynamic glowing border.

However, I’ve found that animating the angle of linear-gradient() in CSS using @keyframes doesn’t work — the gradient snaps or doesn’t interpolate between angles. Here’s what I tried:

.myElement {
  background: linear-gradient(0deg, #FFC600 40%, transparent 60%);
  animation: rotateGradient 5s infinite linear;
}

@keyframes rotateGradient {
  0% { background: linear-gradient(0deg, #FFC600 40%, transparent 60%); }
  100% { background: linear-gradient(360deg, #FFC600 40%, transparent 60%); }
}

Here’s a screen recording showing the effect I want to achieve:
video

I am trying to send a video in a formdata using reactjs. When I submit, getting videoUrl in response as null

I am working on vote-form. When I am creating a vote and sending video with formData using reactjs it gets submitted successfully but in response videoUrl is null. Now when I click on edit the same vote, getVoteById api is called and in response I can see the videoUrl is present and also prepopulate the video which proves that yes video is getting saved. But the main problem starts here is Now when I update the vote it gets saved successfully but again videoUrl is null and at this time when I click on edit, at this time my videoUrl is empty and preview is also not showing.
Note: At every stage video hasn’t been changed…

This is how I am handling the submit:
const handleSubmit = async (e, activeStatus = formData.isActive) => {
if (e) e.preventDefault();

// Validate required fields
if (!formData.title.trim()) {
  toast.error("Title is required");
  return;
}

if (!formData.description.trim()) {
  toast.error("Description is required");
  return;
}

if (!questionType.trim()) {
  toast.error("Option type is required");
  return;
}
if (!priority) {
  toast.error("Set Priority is required");
  return;
}

const userId = Cookies.get("userId");
const token = Cookies.get("token");

if (!userId || !token) {
  toast.error("Missing credentials");
  return;
}

const dataToSubmit = new FormData();
dataToSubmit.append("UserId", userId);
dataToSubmit.append("Title", formData.title);
dataToSubmit.append("Description", formData.description);
dataToSubmit.append("OptionType", questionType);
// dataToSubmit.append("isActive", formData.isActive);
dataToSubmit.append("isActive", activeStatus);
dataToSubmit.append("Priority", formData.priority);

let optionsArray = [];
if (questionType === "custom options") {
  optionsArray = mcqOptions.filter((opt) => opt.trim() !== "");
} else if (questionType === "Yes/No") {
  optionsArray = ["Yes", "No", "I don't know"];
} else if (questionType === "True/False") {
  optionsArray = ["True", "False", "I don't know"];
}

optionsArray.forEach((opt) => dataToSubmit.append("Options", opt));

if (formData.image) {
  dataToSubmit.append("Images", formData.image);
}

if (formData.video) {
  dataToSubmit.append("video", formData.video);
} else if (videoUrl) {
  dataToSubmit.append("videoUrl", videoUrl);
}

let imageUrlsToSend = imageUrl;

// Handle potential double-stringification or dirty strings
if (typeof imageUrlsToSend === "string") {
  try {
    // Attempt to parse stringified array
    const parsed = JSON.parse(imageUrlsToSend);
    if (Array.isArray(parsed)) {
      imageUrlsToSend = parsed;
    } else {
      imageUrlsToSend = [parsed];
    }
  } catch (e) {
    // Fallback: extract URL from string using regex
    const urlMatch = imageUrlsToSend.match(/https?://[^s"]+/g);
    imageUrlsToSend = urlMatch ? urlMatch : [imageUrlsToSend];
  }
} else if (!Array.isArray(imageUrlsToSend)) {
  imageUrlsToSend = [imageUrlsToSend];
}

if (voteId) dataToSubmit.append("VoteId", voteId);

try {
  const response = await axios({
    method: voteId ? "put" : "post",
    url: voteId
      ? `${VOTE_URL}/Votes/update-vote`
      : `${VOTE_URL}/Votes/create-vote`,
    data: dataToSubmit,
    headers: {
      "Content-Type": "multipart/form-data",
      Authorization: `Bearer ${token}`,
    },
  });

  console.log("Response after vote is created: ", response.data);

  toast.success(
    voteId
      ? "Vote updated successfully!"
      : "Congrats! Your Vote is created successfully!"
  );

  setQuestionType("");
  setMcqOptions([]);
  setImageUrl("");
  setVideoUrl("");
  setIsActive(isActive);
  setPriority(null);
  setFormData({
    title: "",
    description: "",
    image: null,
    video: null,
    questionType: "",
    yesNoOrTrueFalse: null,
    mcqOptions: [],
    priority: null,
  });
} catch (error) {
  console.error("Submit error:", error.response?.data || error.message);
  toast.error("Something went wrong!");
}

};

How can I build a secure backend to track Emirates ID status using Node.js? [closed]

I’m working on a web app that allows users to track Emirates ID status — commonly used in the UAE for residency and identification purposes.

While this project is just a simulation (not tied to any government API), I want to make sure the backend logic is set up securely and efficiently. Here’s what I’ve done so far:

Frontend: HTML form to collect a 15-digit Emirates ID

Backend: Express route that accepts the ID and returns a mock status (e.g., “In Process”, “Printed”, etc.)

Input is validated using a regex: /^784-d{4}-d{7}-d{1}$/

My Question:
What are the best practices to:

Prevent abuse (e.g., spamming fake Emirates ID checks)?

Handle rate-limiting in Express to avoid DoS risks?

Log requests without storing personal Emirates ID data?

(Bonus) If I ever wanted to integrate with a real API, what steps should I take to ensure compliance and security?

How to declare and use compound indexes in indexeddb?

With given values of this shape:

interface Entity {
  id: number
  created_at: Date
  updated_at: Date
  title: string
}

And this storage and its indexes:

const store = database.createObjectStore("entities", {
  keyPath: "id",
  autoIncrement: true,
});

store.createIndex("index_by_creation_date", ["created_at", "id"], {
  unique: true,
});
store.createIndex("index_by_update_date", ["updated_at", "id"], {
  unique: true,
});

I assumed I could get different sorting order by just opening cursors on different indexes:

interface Props {
  transaction: IDBTransaction,
  index_name: "index_by_creation_date" | "index_by_update_date",
  offset?: number,
  limit?: number
}

function getEntityIDs(
  {
    transaction,
    index_name,
    offset = 0,
    limit = 20
  }: Props,
  onSuccess: (results: Entity["id"][]) => void
) {
  const objectStore = transaction.objectStore("entities");
  const index = objectStore.index(index_name);
  const results: Entity["id"][] = [];
  let isAdvancing = offset !== 0;

  const cursorRequest = index.openKeyCursor();
  
  cursorRequest.onsuccess = (event) => {
    const cursor = (event.target as typeof cursorRequest).result;

    if (cursor && results.length < limit) {
      if (isAdvancing === true) {
        cursor.advance(offset);
        isAdvancing = false;

        return;
      }

      const id = cursor.primaryKey as Entity["id"];

      results.push(id);
      cursor.continue();
    } else {
      onSuccess(results);
    }
  } 
  
}

But both indexes iterate in the same order. They have to be compound because the timestamps are generated at transaction creation time for related operations and creation/update are implemented as batch operations, so entities created/updated in the same transaction will have exact the same timestamp.

TypeError: bs58.decode is not a function

I’m working on a meme coin trading bot using Node.js and Solana’s web3.js library. When I run my script, I get the following error:

‘TypeError: bs58.decode is not a function
at Object. (C:Userscharlmeme-coin-botmeme-coin-botbot.js:15:24)
at Module._compile (node:internal/modules/cjs/loader:1730:14)
at Object..js (node:internal/modules/cjs/loader:1895:10)
at Module.load (node:internal/modules/cjs/loader:1465:32)
at Function._load (node:internal/modules/cjs/loader:1282:12)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
at node:internal/main/run_main_module:36:49’

The error happens at this line:

‘const secretKey = bs58.decode(secretKeyBase58);’

My script prompts the user to enter a wallet secret key in Base58 format. I’ve installed bs58 using npm install bs58, and I’m importing it like this

const bs58 = require('bs58')

I’m not sure what I’m doing wrong. Could someone help me figure out why bs58.decode isn’t recognized as a function?

Thanks in advance!

What I tried:

I installed the bs58 package using npm install bs58.
In my code, I imported it with:

const bs58 = require('bs58');

Then I used:

`const secretKey = bs58.decode(secretKeyBase58);’

What I expected:
I expected bs58.decode() to decode a Base58 string (my wallet secret key) into a Uint8Array that I could use to generate a Solana Keypair like this:

const keypair = web3.Keypair.fromSecretKey(secretKey);
What actually happened:

I got this error
TypeError: bs58.decode is not a function at Object.<anonymous> (C:Userscharlmeme-coin-botmeme-coin-botbot.js:15:24) at Module._compile (node:internal/modules/cjs/loader:1730:14) at Object..js (node:internal/modules/cjs/loader:1895:10) at Module.load (node:internal/modules/cjs/loader:1465:32) at Function._load (node:internal/modules/cjs/loader:1282:12) at TracingChannel.traceSync (node:diagnostics_channel:322:14) at wrapModuleLoad (node:internal/modules/cjs/loader:235:24) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5) at node:internal/main/run_main_module:36:49
`

type ‘string’ is not assignable to parameter of type ‘keyof StaticContentData

I am trying to pass the contenttype into my hook:

const useIndicativeImageSheetContent = (
  contentType = 'IndicativeVehicleImageText',
) => {
  const { data } = useStaticContent(contentType);

However I get the error:

Argument of type ‘string’ is not assignable to parameter of type ‘keyof StaticContentData’.

My staticContentData is:

export type StaticContentData = {
....
  IndicativeVehicleImageText: MobileApiContract.Models.CMSEnrichmentModels.IndicativeVehicleImageText;
  vehicleValuation: MobileApiContract.Models.CMSEnrichmentModels.VehicleValuationBottomSheet;
  AutoUpdateBottomSheet: MobileApiContract.Models.CMSEnrichmentModels.AutoUpdateBottomSheet;
};
export type KnownStaticContentKeys = keyof StaticContentData;

How can I get rid of the TS error?

Remove emoji from text in react [closed]

I have an input that adds text to a list and returns the checked text in the placeholder. I want to trim the emoji in the input’s placeholder. I tried to replace it, but it didn’t work.
the code

  <input
      className="input-field"
      type="text"
      placeholder={
        itemArray
          .filter((item) => item.isChecked)
          .map((item) => item.label)
          .join(" | ") ||
        "Nothing Selected".replace(
          /([u2700-u27BF]|[uE000-uF8FF]|uD83C[uDC00-uDFFF]|uD83D[uDC00-uDFFF]|[u2011-u26FF]|uD83E[uDD10-uDDFF])/g,
          ""
        )
      }

but my input still show the emoji

How to stop browser from closing in playwright after popup throws window.close() in javascript

I’m currently trying to automate an application that does the following:

  • in order to fill in a form there’s a button that opens a popup window
  • within the popup window I can search and select from a list
  • as soon as the selection is made, I press a button: the popup window closes and the selected value is inserted in my main window.

The issue: Whenever I run this in playwright, the popup window closes and so does my main browser window, halting the entire test.

I can see that the custom.js runs a script that ends in window.close();.
How can I prevent my entire context from closing when one window is forced to close?

Edit: the window.close() is part of the application. It’s how it closes the popup. When I manually run through the application it works as intended: popup closes and I can continue in the main window. In playwright it closes the entire context, so that includes the popup AND the main window (the browser in general).

Tell tablesorter plugin to not use ‘and’ and ‘or’ as logical operators in filtering

tablesorter’s column filtering is behaving erratically because it is treating ‘and’ and ‘or’ as logical operators rather than just plain text. I’ve been reading the docs here and can’t see how to tell it to not do that, and just treat everything as a simple text match (still taking the other options to do with case insensitivity and coping with accented characters).

These are the options I’m using at the moment:

  options = {
    "sortInitialOrder":"asc",
    "sortRestart":true,
    "sortList":[[1,0],[5,0]],
    "textExtraction":"basic",
    "sortLocaleCompare":true,
    "debug":"core filter", // => core and filter widget debugging
    "widgets":["filter"],
    "widgetOptions":{
      "filter_childRows":true,
      "filter_cssFilter":"tablesorter-filter",
      "filter_ignoreCase":true
    }
  }
  $('#works-table').tablesorter(options);

Does anyone know how to tell it to just treat ‘and’ and ‘or’ as regular text rather the operators?

Setting the dimensions on the image doesn’t help to remove the CLS

I’m experiencing Cumulative Layout Shift (CLS) issues with images in my Nuxt 3 project using Tailwind CSS. Despite implementing aspect ratio containers and proper image dimensions, my images still cause layout shifts during loading.

Images flicker during page load

Layout shifts occur even with aspect-ratio and explicit dimensions

Both desktop and mobile versions exhibit this behavior

<div class="relative max-w-[605px]">
  <!-- Desktop Image -->
  <div class="hidden md:block w-full max-w-[605px] aspect-[1222/1008]">
    <NuxtImg 
      src="/terminal.webp" 
      width="1222"
      height="1008"
      class="w-full h-full object-contain"
    />
  </div>
  
  <!-- Mobile Image -->
  <div class="block md:hidden aspect-[696/704]">
    <NuxtImg 
      src="/terminal-mobile.webp"
      width="696"
      height="704"
      class="w-full h-full object-contain"
    />
  </div>
</div>

Space isn’t reserved for images before they load so it makes the content shift. Is there a missing CSS containment property or a Nuxt-specific hydration behavior causing this? I’ve read mau guides but didn’t find any advice except setting dimensions. Using Nuxt 3.17.1 with @nuxt/image 1.10.0. Thank you

Formik Field component FieldInputProps not working properly with ShadCN Input OTP component

I have tried with children method and with component method, but in both cases onChange={field.onChange} or {…field} doesnt update the field on input.

<Field
 name={"otp"}
 component={({ field, ...props }: { field: FieldInputProps<string> }) => (
       <InputOTP
        maxLength={6}
        pattern={REGEXP_ONLY_DIGITS}
        {...field}
        {...props}
       >
         <InputOTPGroup>
         <InputOTPSlot index={0} />
         <InputOTPSlot index={1} />
         <InputOTPSlot index={2} />
         </InputOTPGroup>
         <InputOTPSeparator />
         <InputOTPGroup>
         <InputOTPSlot index={3} />
         <InputOTPSlot index={4} />
         <InputOTPSlot index={5} />
         </InputOTPGroup>
        </InputOTP>
 )}
/>

I expected the onChange or custom React children of the ShadCN Input OTP to be controlled by formik. But upon closer inspection the value is registered by the Input OTPs onChange prop but not being registered by the field.onChange prop. Hence the value never changes.

Firebase cloud function taking very long to return a result to the client

I have a firebase cloud function that executes on the server and the cloud logs reflects the function as successfully completed within a few seconds. However the client side takes very long to receive the returned value of the cloud function.

Here’s a sample of the cloud function code in Node js;

    exports.UploadData = functions
      .runWith({
        // Ensure the function has enough memory and time
        // to process large files
        timeoutSeconds: 540,
        memory: "8GB",
      })
      .region("us-central1")
      .https.onCall(async (data, context) => {
        const db = admin.database();
    
        var UserData = [];
      
    
        return await db
          .ref("DATA/")
          .once(
            "value",
            async (snapshot) => {
              dataFields = await snapshot.val();
    
              for (let id in dataFields) {
                UserData.push({ id, ...dataFields[id] });
              }
            },
            (errorObject) => {
              console.log("Database read failed ", errorObject);
            }
          )
    
          .then(async () => {
            
            let UserID = [
              await UserData.filter((el) => el.id).find(
                (el1) => el1.id
              ),
            ]
              .map((el) => el.id)
              .toString();
           
          
            if (context.auth.uid) {
              const addDataRef = db.ref(
                `/User/${UserID}`
              );
              let CSVData = await data.NameAccount1;
              let NameAccount1 = await JSON.parse(CSVData);
    
             
    
           
              let promises = [];
              const DatabaseSend = async (el) => {
             
    
                if (
                  true // conditions
                ) {
                  if (
                   true // conditions
                  ) {
                   
                    for (
                      let i = 0;
                      i < (NameAccount1 && NameAccount1.length);
                      i++
                    ) {
                     
    
                      if (
                        NameAccount1
                      ) {
                        if (NameAccount1.date>"2020-12-31" // example condition
                        ) {
                        
    
                          let promise0 = await addDataRef.push(
                            {
                              
                              date:
                                (NameAccount1.date),
                            
                             
                            },
                            (error) => {
                              if (error) {
                                console.log(error);
                              } else {
                                console.log("Updated 0");
                              }
                            }
                          );
                          promises.push(promise0);
                         
                        } else {
                          let promise1 = await addDataRef.push(
                            {
                           
                              dateNewer:
                                (NameAccount1.date)
                            },
                            (error) => {
                              if (error) {
                                console.log(error);
                              } else {
                                console.log("Updated");
                              }
                            }
                          );
                          promises.push(promise1);
                        }
                       
                      } 
                      
                    }
                   
                  }
                }
              
    
                return await Promise.all(promises);
              };
             
    
              return await DatabaseSend().then(() => {
                console.log("server complete");
                return "SUCCESS";
              });
            } else {
              console.log("ERROR");
              return "ERROR";
            }
          });
       
      });

Here’s a sample of the client side code in React js;

      async function handleData() {
        
    
      
        var UploadData = functions.httpsCallable("UploadData", {
          timeout: 300000,
       
        });
     
    
      
        return await UploadData({
          id: userID,
          NameAccount1: JSON.stringify(NameAccount1), // data state
       
    
       
        })
          .then(async (result) => {
            let dataReceived = await result.data;
            console.log(dataReceived);
         
            return; 
          })
          .catch((error) => {
            // Getting the Error details.
            var code = error.code;
            var message = error.message;
            var details = error.details;
            console.log(code, message, details);
            if (error) {
        
              console.log("ERROR");
              return error;
            }
    
            return;
            // ...
          });
      }

I’ve tried the same function with a smaller payload of data and it works fast, however with a larger data payload, it takes very long, although the cloud logs shows the function as completed successfully many seconds before the client side receives the returned response from the cloud function.

Is there some error with the above code?