Javascript logic for Google Apps Script (Google Sheet) not working as intended

I have a google sheet that i am trying to search, match, and then auto-populate some data to.

Here is the google sheet layout
Here is the lookup table layout

I wrote some javascript code to try to search cell A2 for a keyword, match it to a value in the lookup table, grab the corresponding data, and then populate it 1 row down, and 1 column right of the keyword. It should repeat this checking every 7th cell in column A until there are no more. Currently, my code works for the first keyword, and then inputs the data incorrectly for the remaining keywords.

function FindItemAndPopulate() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Item Autofill");
  var keywordRange = sheet.getRange("A2:A");
  var keywords = keywordRange.getValues();
  var lastRowA = sheet.getLastRow();

  for (var i = 0; i < keywords.length; i += 7) { // Increment by 7 to check every 7th row
    var keyword = keywords[i][0];

    if (keyword !== "") {
      var searchData = sheet.getRange("M2:M" + lastRowA).getValues();
      var rowIndex = -1;

      for (var j = 0; j < searchData.length; j++) {
        if (searchData[j][0] === keyword) {
          rowIndex = j + 2; // Adjust index for row offset due to starting from row 2
          break;
        }
      }

      if (rowIndex !== -1) {
        var rowData = sheet.getRange(rowIndex, 14, 1, 5).getValues(); // Get data from columns N to R
        var valuesToPopulate = [];

        for (var k = 0; k < rowData[0].length; k++) {
          valuesToPopulate.push([rowData[0][k] !== "" ? rowData[0][k] : ""]);
        }

        sheet.getRange(rowIndex + 1, 2, 1, 5).setValues([valuesToPopulate]); // Populate data into the next row and 1 column right
      } else {
        sheet.getRange("B" + (i + 2) + ":F" + (i + 2)).clearContent(); // Clear corresponding row if no match found
      }
    } else {
      sheet.getRange("B" + (i + 2) + ":F" + (i + 2)).clearContent(); // Clear corresponding row if keyword is empty
    }
  }
}

I believe I made a mistake somewhere with the index of the keyword not being in the correct scope or not being properly updated, but I cannot figure out where. Any help would be appreciated.

Here is a photo of the result of the code

Thank you for your help and patience.

mui data grid with nextjs column definition error

I’m using mui data grid in a next.js app I’m building. The problem is when I try to do a more complex column definition I run into an error:

{
    field: 'home_address',
    valueGetter: (value, row) => {
        return (row.user.home_address);
    },
    headerName: 'Address' 
},

The error reads: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". {field: ..., valueGetter: function, headerName: ...}

I can hide this error by passing in use server to the closure like this:

{
    field: 'home_address',
    valueGetter: async (value, row) => {
        'use server'
        return (row.user.home_address);
    },
    headerName: 'Address' 
},

but then my address column renders:

[object Promise]

Is there a workaround for this, or a way to force the async closure to resolve before returning?

inside the useeffect , store update showing indefinite loading in react

i try to update the some data into store. When i try to use props.setReducerData(newData) in code, it is keeps updating the page and page keep loading and shwoing the message

” Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn’t have a dependency array, or one of the dependencies changes on every render”

 useEffect(() => {   
        let DataArray1 = props.DataArray1;  
         
        let DataArray2 = props.DataArray2;  
          
          let newData;
        if(DataArray1  && DataArray1 ?.length > 0 && 
          DataArray2 && DataArray2?.length > 0) 
          {  
              newData = DataArray1 && DataArray1.map(item => {
              const match = DataArray2.some(
                 DataObj => item.id ===  DataObj.id
              );       
              return {
              ...item,
              amount: match ? 0 : 100
              };
            });   
           
             props.setReducerData(newData); // update the new data into store 
         
        } else {
            newData = DataArray1 && DataArray1.map(item => { 
            return {
            ...item,
            amount: 100
            };
          });   
          
         props.setReducerData(newData); // update the new data into store 
         
        }  
       
      },[
        props.DataArray1,
        props.DataArray2
      ]); 

How to wait for API calls to finish before making another one when they are in their own functions?

I am a React noob and have a React component with a couple of functions that have API calls inside. I want to then call those functions from a separate onSubmit function and make another API call, but I don’t want to run the third API call until the first two have finished.

The code is set up like this:

function 1 (){
     fetch APIcall
     .then....
}

function 2 (){
     fetch APIcall
     .then....
}

function onSubmit(){
     function1()
     function2()
     fetch APIcall()     // don't want to run this until the other 2 calls are completed
     .then... 
}

I tried making function 1 and function2 async functions, but then I wasn’t sure how to await the promises in the onSubmit() function. Can this be done with async await, or is there a better way to handle this?

Get the contents of a table cell for all selected rows

I have a table of user info. When you click the button, I want to get the email address from each selected row, output into a comma-separated string.

<table>
   <tr>
      <td><input type="checkbox" class="selector"></td>
      <td class="name">John Doe</td>
      <td class="country">Australia</td>
      <td class="email">[email protected]</td>
    </tr>
    <tr>
      <td><input type="checkbox" class="selector"></td>
      <td class="name">Jane Smith</td>
      <td class="country">Canada</td>
      <td class="email">[email protected]</td>
    </tr>
</table>

<button onclick="tableToEmail()">Get Emails</button>

I got it to work with the following code, but I’m a novice with JS so I assume it must be inefficient:

function tableToEmail() {

  var recipients = [];
  $('input.selector:checked').each(function(){
      var email = $(this).closest('tr').find('.email');
      recipients.push(email.text());
  });
  console.log(recipients.join(','));

}

Is there a better way to achieve this, preferably with vanilla JS if jQuery is not needed?

Thank you!

Value is not changing on onChange react-hook-form in nested array

I am want to handle nested array using react hook from that’s my task. I am able to do everything but the state is not setting on onChange while I am getting all the correct value.
This is how my array looks like

  const { register, handleSubmit, setValue, getValues } = useForm({
defaultValues: {
  quizData: [{
    pId: 1,
    questions: [{ que: 'QUESTION 1', options: ['option 1', 'option 2'], correctAnswer: 0, selectedAnswer: -1 }, { que: 'QUESTION 2', options: ['option 1', 'option 2'], correctAnswer: 0, selectedAnswer: -1 }]
  }]
}
});

Selected answer is not been updated below is link for codesandbox you can run the app over there.

Code Sandbox link

how to quickly download audio from YouTube [closed]

I was able to get audio from a YouTube video. When I try to download it using js, it starts downloading after a minute. When I try to download a sound using the download button (On the sound page), the download continues the same way after a minute. How can I get around this limitation?

I didn’t miss anything because I didn’t find any information

Problem with asynchronous work of javascript

This is my code right now:

//#region

let targetElementSelector =
  "[class='xi81zsa x1lkfr7t xkjl1po x1mzt3pk xh8yej3 x13faqbe']";
let defaultTimeOut = 10;
let action = Click(targetElementSelector);

function ActIfElementReady(elementSelector, action, timeOut) {
  let abortController = new AbortController();

  let actIfElementReadyAsync = async (
    elementSelector,
    action,
    abortController,
    abortSignal,
  ) => {
    return new Promise((resolve, reject) => {
      let observer = new MutationObserver((mutationsList, observer) => {
        // Look through all mutations that just occured
        for (let mutation of mutationsList) {
          // If the addedNodes property has one or more nodes
          if (mutation.addedNodes.length) {
            let element = document.querySelector(elementSelector);
            if (element) {
              action();
              observer.disconnect(); // Stop observing
              abortController.abort(); // Cancel the other task
              resolve("Element is ready and action has been executed");
            }
          }
        }
      });

      // Start observing the document with the configured parameters
      observer.observe(document.body, { childList: true, subtree: true });

      // Listen for the 'abort' event on the signal
      abortSignal.addEventListener("abort", () => {
        observer.disconnect(); // Stop observing
        reject("Task was cancelled");
      });
    });
  };

  let waitUntilTimeRunOutAsync = async (
    timeOut,
    abortController,
    abortSignal,
  ) => {
    DelayTime(timeOut);
    abortController.abort();
  };

  let actIfElementReadyTask = actIfElementReadyAsync(
    targetElementSelector,
    action,
    abortController,
    abortController.signal,
  );
  let waitUntilTimeRunOutTask = waitUntilTimeRunOutAsync(
    defaultTimeOut,
    abortController,
    abortController.signal,
  );

  let result;
  Promise.allSettled([actIfElementReadyTask, waitUntilTimeRunOutTask]).then(
    (results) => {
      let [actIfElementReadyResult, waitUntilTimeRunOutResult] = results;

      if (actIfElementReadyResult.status === "fulfilled") {
        // return 'Everything worked as expected:' + actIfElementReadyResult.value
        result = true;
      } else if (
        actIfElementReadyResult.status === "rejected" &&
        waitUntilTimeRunOutResult.status === "fulfilled"
      ) {
        // return 'The time has run out:'+ actIfElementReadyResult.reason
        result = false;
      }
    },
  );
  return result;
}

ActIfElementReady(targetElementSelector, action, defaultTimeOut);

var paragraph = "People of cave!!!!";
var imagePath = "C:\1.png";

function AutoPost(message, imagePath) {
  let writePostRangeSelector =
    "[class='xi81zsa x1lkfr7t xkjl1po x1mzt3pk xh8yej3 x13faqbe']";
  var addImageButtonSelector =
    'img[class="x1b0d499 xl1xv1r"][src="https://static.xx.fbcdn.net/rsrc.php/v3/y7/r/Ivw7nhRtXyo.png"]';
  let imageInputSelector = '[role="dialog"] input[type="file"]';
  let messageSelector =
    "[class='xzsf02u x1a2a7pz x1n2onr6 x14wi4xw x9f619 x1lliihq x5yr21d xh8yej3 notranslate']";
  let postButtonSelector =
    '[class="x1n2onr6 x1ja2u2z x78zum5 x2lah0s xl56j7k x6s0dn4 xozqiw3 x1q0g3np xi112ho x17zwfj4 x585lrc x1403ito x972fbf xcfux6l x1qhh985 xm0m39n x9f619 xn6708d x1ye3gou xtvsq51 x1r1pt67"]';

  if (
    !ActIfElementReady(
      writePostRangeSelector,
      Click(writePostRangeSelector),
      10,
    )
  )
    return "Cannot click the write post section";
  if (!ActIfElementReady(imageInputSelector, Click(addImageButtonSelector), 10))
    return "Cannot click the add image button";
  if (
    !ActIfElementReady(
      imageInputSelector,
      SendKeys(imageInputSelector, imagePath),
      10,
    )
  )
    return "Cannot send the image to image input";
  if (
    !ActIfElementReady(messageSelector, SendKeys(messageSelector, message), 10)
  )
    return "Cannot send message to message section";

  DelayTime(7);
  if (!Click(postButtonSelector)) return "Cannot click post button";

  return "sucessful";
}

AutoPost(paragraph, imagePath);

//#endregion

//Điều hướng trang web
function GotoUrl(url: string) {} //Điều hướng đến url
function Refresh() {} //Load lại trang
function Back(count: number) {} //Quay lại trang trước

function GetUrl(): string {
  return "";
} //Lấy url hiện tại
function GetPageSource(): string {
  return "";
} //Lấy source code trang hiện tại

//Tương tác với cookies
function AddCookies(cookie: string, domain: string): boolean {
  return true;
} //Thêm cookie
function GetCookies(domain: string): string {
  return "";
} //Lấy cookie
function DeleteCookie(name: string): boolean {
  return true;
} //Xóa cookie theo tên
function DeleteAllCookies(): boolean {
  return true;
} //Xóa tất cả cookie

//Tương tác với element
function ExistElement(selector: string, timeout: number): boolean {
  return true;
} //kiểm tra xem element có tồn tại không
function ExistElements(timeout: number, arrSelector: string[]): string {
  return "";
} //kiểm tra xem các element có tồn tại không
function WaitElementHide(selector: string, timeout: number): boolean {
  return true;
} //Đợi element ẩn đi
function CountElement(selector: string): number {
  return 0;
} //Đếm số lượng element
function RemoveElement(selector: string): boolean {
  return true;
} //Xóa element
function IsElementVisible(selector: string): boolean {
  return true;
} //Kiểm tra xem element có hiển thị không
function IsElementOnScreen(selector: string, timeout: number): boolean {
  return true;
} //Kiểm tra xem element có hiển thị trên màn hình không

function ExecuteJS(script: string): string {
  return "";
} //Thực thi đoạn code javascript

function GetElementAttr(selector: string, attributeName: string): string {
  return "";
} //Lấy giá trị thuộc tính của element
function GetElementInnerText(selector: string): string {
  return "";
} //Lấy innerText của element
function GetElementValue(selector: string): string {
  return "";
} //Lấy giá trị của element (thẻ input)
function SetElementValue(selector: string, value: string): string {
  return "";
} //Thay đổi giá trị của element (thẻ input)

function Click(selector: string): boolean {
  return true;
} //Click vào element
function ClickJS(selector: string): boolean {
  return true;
} //Click vào element bằng javascript
function SendKeys(selector: string, content: string): boolean {
  return true;
} //Nhập text vào element
function ClearText(selector: string): boolean {
  return true;
} //Xóa text của element
function SelectText(selector: string): boolean {
  return true;
} //Chọn text của element
function SendEnter(selector: string): boolean {
  return true;
} //Gửi phím enter
function Select(selector: string, value: string): boolean {
  return true;
} //Chọn option của element (thẻ select)

//Scroll
function Scroll(selector: string): boolean {
  return true;
} //Cuộn đến element
function ScrollAndWait(selector: string, timeout: number): boolean {
  return true;
} //Cuộn đến element và đợi
function ScrollAndClick(selector: string): boolean {
  return true;
} //Cuộn đến element và click
function ScrollDistance(distance: number): boolean {
  return true;
} //Cuộn theo khoảng cách
function ScrollIfNotOnScreen(selector: string): boolean {
  return true;
} //Cuộn nếu element không hiển thị trên màn hình

//Tương tác với cửa sổ trình duyệt
function GetSize(): string {
  return "";
} //Lấy kích thước cửa sổ trình duyệt
function SetSize(width: number, height: number): boolean {
  return true;
} //Thay đổi kích thước cửa sổ trình duyệt
function RetoreSize(): boolean {
  return true;
} //Phục hồi kích thước cửa sổ trình duyệt trước đó

function GetPosition(): string {
  return "";
} //Lấy vị trí cửa sổ trình duyệt
function SetPosition(x: number, y: number): boolean {
  return true;
} //Thay đổi vị trí cửa sổ trình duyệt
function RetorePosition(): boolean {
  return true;
} //Phục hồi vị trí cửa sổ trình duyệt trước đó

function Screenshot(filePath: string): boolean {
  return true;
} //Chụp ảnh màn hình

//Đợi trình duyệt chuyển qua url mới
function SetUrl() {}
function CheckUrlChanged(timeout: number): boolean {
  return true;
}

//Khác
function DelayTime(seconds: number) {} //Đợi một khoảng thời gian
function DelayRandom(min: number, max: number) {} //Đợi một khoảng thời gian ngẫu nhiên
function Random(max: number): number {
  return 0;
} //Lấy số ngẫu nhiên từ 0 đến max
function RandomInt(min: number, max: number): number {
  return 0;
} //Lấy số ngẫu nhiên từ min đến max
function RandomString(length: number, typeRandom: string): string {
  return "";
} //Lấy chuỗi ngẫu nhiên
function GetTotp(fa2: string): string {
  return "";
} //Lấy mã bảo mật từ 2fa
function CheckGetnada(email: string): boolean {
  return true;
} //kiểm tra xem email có phải của getnada không
function GetOtpGetnada(email: string, timeout: number): string {
  return "";
} //Lấy mã otp từ getnada
function LogJS(content: string) {} //Ghi log javascript

//Một số hàm hỗ trợ Facebook
function SetFbLanguage(language: string) {} //Thay đổi ngôn ngữ facebook
function GetFbWeb(url: string): string {
  return "";
} //Check web facebook: 1-www, 2-mobile (mfb), 3-mbasic
function SwitchToMfb(url: string) {} //Chuyển sang web facebook dạng mobile
function GetDomainFb(url: string): string {
  return "";
} //Lấy domain facebook hiện tại
function GetLinkFromId(idOrLink: string, domainFb: string): string {
  return "";
} //Lấy link từ id (hoặc link)
function GetUid(): string {
  return "";
} //Lấy uid facebook hiện tại
function CheckFbBlock(): boolean {
  return true;
} //Kiểm tra xem nick facebook có bị block tính năng không

//Nâng cao
function RequestGet(url: string): string {
  return "";
} //Gửi request get
function RequestPost(url: string, data: string): string {
  return "";
} //Gửi request post

All my code from ActIfElementReady and AutoPost. The issue is if the everything work as expected, I will make a post in facebook automately, but instead of that only the section that allow user to write post is popup, which mean something wrong. This is a video about the test:
https://www.dropbox.com/scl/fi/yz5fxpsg5noosqs927sss/bug.mp4?rlkey=nsbz6wt7n0jqlzrn34zf1660i&st=wjco2n6u&dl=0

I expect someone be able to tell me what I’m wrong with async/await of js. I come from C#, so it is even better if someone can tell what difference those two things work. Or even better, should I ever touch to async/await of js again or not. Of course, a method that how should my code be fix to run as my expected.

epub.js always empty in web page

I’m struggling trying to get a epub file to display in a web page using epub.js. I’ve seen all the examples, and documentation but I can’t get an epub to appear. I have this HTML:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Test</title>
  <style>
    #area {
      box-sizing: border-box;
      position: absolute;
      left: 50px;
      top: 10px;
      width: 600px;
      height: 400px;
      border: 1px dotted red;
    }
  </style>
  <script src="epub.js"></script>
  <script src="jszip.min.js"></script>
  <script>
    window.onload = function () {
      let book = ePub('epub/house.epub'),
          rendition = book.renderTo('area',
            {
              openAs: 'epub',
              method: 'default',
              width:  '100%',
              height: 400
            }
          ),
          displayed = rendition.display();
    };
  </script>
</head>

<body>
  <div id="area"></div>
</body>

</html>

and running it in a browser from VS Code I get this in the network panel:

Network panel

So while everything appears to load, and no errors display in the console, I keep getting an empty #area.

What am I missing? Or is there a basic example I can download that does work that I can check?

Can’t get other input value on live time change on mobile

I want to make two input for calculate function but it doesn’t work on moblie

<input type="number" id="input1" placeholder="Enter number 1">
<input type="number" id="input2" placeholder="Enter number 2">
<button id="calculateButton">Calculate</button>
<div id="result"></div>
$('#calculateButton').click(function(){
      // Get the values from the input fields
      var num1 = parseFloat($('#input1').val());
      var num2 = parseFloat($('#input2').val());
      
      // Perform the calculation
      var result = num1 + num2;
      
      // Display the result
      $('#result').text('Result: ' + result);
    });

On desktop working as expect but only on mobile not working

Using IPC renderer in angular component

Im currently in the process of create an electron application using angular and hit a bit of a road block.

The whole idea is that the user uses the electron app to input a “Name” and an “Event” and I use playwright to emulate the browser initiating going to a webpage and getting all the name data for that event

At the moment I have a form that takes a first name and event

Name.component.html

<form (ngSubmit)="submitForm()" #nameForm>
  <label for="firstName">First Name:</label>
  <input type="text" id="firstName" name="firstName" [(ngModel)]="firstName"><br><br>
  <label for="event">Event:</label>
  <input type="text" id="event" name="event" [(ngModel)]="event"><br><br>
  <button type="submit">Submit</button>
</form>

name.component.ts

import { Component } from '@angular/core';
import { ipcRenderer } from 'electron';

@Component({
  selector: 'app-name',
  templateUrl: './name.component.html',
  styleUrl: './name.component.css'
})

export class nameComponent {

  barcode: string = '';
  event: string = '';

  submitForm() {
    const name = this.name;
    const event = this.event;
    
    console.log('Barcode:', this.name);
    console.log('Event:', this.event);

    
    ipcRenderer.send('checkName', { name, event });
  }


}

this is what I have going on in main.js

Main.js

// main.js

// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const url = require("url");
const { chromium } = require('playwright');

const createWindow = () => {
    // Create the browser window.
    const mainWindow = new BrowserWindow({
        width: 1000,
        height: 800,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            nodeIntegration: true,
            contextIsolation: false
        }
    })

    // and load the index.html of the app.
    mainWindow.loadURL(
        url.format({
          pathname: path.join(__dirname, '/dist/eventName/browser/index.html'),
          protocol: "file:",
          slashes: true
        })
      );

    // Open the DevTools.
    // mainWindow.webContents.openDevTools()
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
    createWindow()

    app.on('activate', () => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})
// Listen for the 'checkNames' event from the renderer process
ipcMain.on('checkNames', async (event, data) => {
    console.log('Barcode:', data.Name);
    console.log('Event:', data.event);
    try {
        const result = await getNameData(data.Name, data.event, true, true);
        console.log(result);

    } catch (error) {
        console.error('Error fetching Name data:', error);

    }
});

preload.js

// preload.js

const { ipcRenderer } = require('electron');

window.ipcRenderer = ipcRenderer;
window.ipcMain = ipcRenderer;

// All the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener('DOMContentLoaded', () => {
    const replaceText = (selector, text) => {
        const element = document.getElementById(selector)
        if (element) element.innerText = text
    }

    for (const dependency of ['chrome', 'node', 'electron']) {
        replaceText(`${dependency}-version`, process.versions[dependency])
    }
})

The issue im having now is that when I compile using npm start

 [ERROR] Could not resolve "fs"

    node_modules/electron/index.js:1:19:
      1 │ const fs = require('fs');
        ╵                    ~~~~

  The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.


X [ERROR] Could not resolve "path"

    node_modules/electron/index.js:2:21:
      2 │ const path = require('path');
        ╵                      ~~~~~~

  The package "path" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

Any ideas what what I can do to resolve the issue? It compiles successfully when I have the renderer being called in a separate renderer.js file but the issues lies when I’m calling it from the component directly. I’m just not sure how to call the renderer.js from within the component itself, that is why I tried using it from the component directly.

Why my websites load bugget on iphones, even tho it works fine on androids?

I developed a calculator using react and it works fine on my pc, so i uploaded it to github pages. The page in my both friend’s phone works fine, and they use android, but for some reason on my iphone it looks bugged.
the webpage on my iphone

Here is my .html file

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <link rel="icon" href="./src/assets/171352_calculator_icon2.png"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Calculator</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

And here is my .css file. I am using vite and react, so i am not sure if i made it right, but it worked on android phones. I send it to 4 differents friends with android and 2 iphones, and only the iphones were bugged.

#calculator{
    margin: auto;
    margin-top: 100px;
    overflow: hidden;
    background-color: #1C1C1C;
    max-width: 400px;
    border-radius: 10px;
}

#keys{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    padding: 20px;
    margin-bottom: -10px;
}

#display{
    margin-left: 25px;
    margin-right: 20px;
    background-color: #1C1C1C;
    color:white;
    border: none;
    width: 340px;
    height: 70px;
    margin-bottom: px;
    margin-top: 20px;
    padding-bottom: 0px;
    text-align: end;
    font-size: 70px;

}

#keys-after-zero{
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    padding-left: 20px;
    margin-bottom: 20px;
}

#zero-button{
    border-radius: 80px;
    width: 179px;
    text-align: start;
    padding-left: 34px;
}

button{
    background-color: hsl(0, 0%, 31%);
    border-radius: 50%;
    width: 80px;
    height: 80px;
    border: none;
    cursor: pointer;
    color: white;
    font-size: 35px;
}

button:active {
    background-color: hsl(0, 0%, 41%);
}

.orange{
    background-color: hsl(35, 100%, 50%);
}

.orange:active{
    background-color: hsl(35, 100%, 40%);
}

.light-gray{
    color: #1C1C1C;
    background-color: hsl(60, 2%, 63%);
}

.light-gray:active{
    background-color: hsl(60, 2%, 53%);
}


@media screen and (max-width: 600px){
    #calculator{
        max-width: 280px;
    }

    button{
        width: 50px;
        height: 50px;
        font-size: 27px;
        -webkit-appearance: none;
        appearance: none;
    }

    #zero-button{
        width: 118px;
        padding-left: 34px;
    }

    #display {
        width: 225px;
        font-size: 55px;
        height: 60px;
    }
}

@media (device-height: 568px) and (-webkit-min-device-pixel-ratio: 2) {
    #calculator{
        max-width: 280px;
    }

    button{
        width: 50px;
        height: 50px;
        font-size: 27px;
    }

    #zero-button{
        width: 118px;
        padding-left: 34px;
    }

    #display {
        width: 225px;
        font-size: 55px;
        height: 60px;
    }
}

I tried change the css file, and i already made an @media in css to be different in cellphones and tried to add -webkit-appearance: none;, but it didn’t work

If anyone wants to open the site and see how it looks, here is the link: https://edd-estevam.github.io/Calculator-react/

The repository is updated with the latest changes that i made: https://github.com/Edd-Estevam/Calculator-react

I tried to add some lines in css that i found in the internet, like @media (device-height: 568px) and (-webkit-min-device-pixel-ratio: 2){}, but it didn’t work.

I want to add a push notification based on the user selection at the schedule to any device that logged on to the account

i would like to ask a question, i want to add a push notification at my TypeScript Next.js 14.2 for every selection at Penjadwalan (translate: Schedule), like i want it to send a push notification for 1 time in a day and much more based on the user select, can i get a recommendation or solving for this?

"use client";
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { FieldValues, SubmitHandler, useForm } from "react-hook-form";
import { useSupabaseClient } from "@supabase/auth-helpers-react";
import { useRouter } from "next/navigation";
import { useUser } from "@/hooks/useUser";

const svg = {
  userDarken: require("@/shared/icons/user-darken.svg"),
  pillDarken: require("@/shared/icons/pill-darken.svg"),
  calendarPlusDarken: require("@/shared/icons/calendar-plus-darken.svg"),
  vaccineBottleDarken: require("@/shared/icons/vaccine-bottle-darken.svg"),
  bellPlusDarken: require("@/shared/icons/bell-plus-darken.svg"),
  checkupListDarken: require("@/shared/icons/checkup-list-darken.svg"),
  plusSecondary: require("@/shared/icons/plus-secondary.svg"),
  xSecondary: require("@/shared/icons/x-secondary.svg"),
};

interface AddProviderProps {
  className: string;
  onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
}

const ComponentAddProvider: React.FC<AddProviderProps> = ({
  className,
  onClick,
}) => {
  const [controlExpand, setControlExpand] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const supabaseClient = useSupabaseClient();
  const router = useRouter();
  const { user } = useUser();

  useEffect(() => {
    const controlExpandBreakpoint = window.innerWidth < 1024;
    setControlExpand(!controlExpandBreakpoint);
  }, []);

  const { register, handleSubmit, reset } = useForm<FieldValues>({
    defaultValues: {
      date_added: new Date().toISOString().split("T")[0],
      patient: "",
      medicine: "",
      dosage: "",
      dosage_unit: "Pilih Dosis",
      schedule: "Pilih Penjadwalan",
      notes: "",
    },
  });

  const eventSubmit: SubmitHandler<FieldValues> = async (values) => {
    try {
      setIsLoading(true);

      const { error: supabaseError } = await supabaseClient
        .from("reminders")
        .insert({
          user_id: user?.id,
          date_added: values.date_added,
          patient: values.patient,
          medicine: values.medicine,
          dosage: values.dosage,
          dosage_unit: values.dosage_unit,
          schedule: values.schedule,
          notes: values.notes,
        });

      if (supabaseError) {
        setIsLoading(false);
        console.log(supabaseError.message);
      }

      router.refresh();
      reset();
    } catch (error) {
      console.log(error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <form
      onSubmit={handleSubmit(eventSubmit)}
      className={`bg-[hsl(210,17%,98%)] ${className} z-10 w-full lg:w-[480px] px-6 py-0 lg:p-8 rounded-3xl`}
    >
      <div
        className={`${
          controlExpand ? "mt-0 mb-4 lg:mb-8" : "m-0"
        } flex flex-col lg:flex-row items-start justify-between w-full h-auto`}
      >
        <div className="z-10 flex flex-col items-center lg:items-start justify-center lg:justify-start w-full lg:w-auto h-auto">
          <p className="text-[hsl(0,0%,13%)] font-medium text-sm text-start mt-0 mb-0">
            Tambahkan Pengingat
          </p>
          <p className="text-[hsl(0,0%,53%)] font-light text-xs text-start mt-0 mb-0">
            Buat Penjadwalan Sekarang
          </p>
        </div>
        <div className="flex flex-row gap-4 lg:gap-2 items-center justify-center lg:justify-end w-full lg:w-auto h-auto mt-4 lg:mt-0">
          <button
            type="submit"
            className="bg-[hsl(0,0%,13%)] opacity-100 transition-all hover:opacity-80 flex flex-row gap-2 items-center justify-center w-full lg:w-fit p-4 lg:px-4 lg:py-2 rounded-2xl"
          >
            <Image
              src={svg.plusSecondary}
              width="14"
              height="14"
              alt="plusSecondary"
            />
            <p className="text-[hsl(210,17%,98%)] font-medium text-xs">
              Tambah
            </p>
          </button>
          <button
            onClick={onClick}
            className="bg-[hsl(0,0%,13%)] opacity-100 transition-all hover:opacity-80 flex flex-row gap-2 items-center justify-center w-full lg:w-fit p-4 lg:px-4 lg:py-2 rounded-2xl"
          >
            <Image
              src={svg.xSecondary}
              width="14"
              height="14"
              alt="xSecondary"
            />
            <p className="text-[hsl(210,17%,98%)] font-medium text-xs">
              Keluar
            </p>
          </button>
        </div>
      </div>
      <div className="flex flex-col w-full h-auto gap-4 mt-4 lg:mt-8">
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.calendarPlusDarken}
              width="16"
              height="16"
              alt="calendarPlusDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Ditambahkan Pada
            </p>
          </div>
          <input
            id="date_added"
            {...register("date_added", { required: true })}
            disabled={isLoading}
            type="date"
            placeholder="Masukkan Nama Obat .."
            className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
          />
        </div>
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.userDarken}
              width="16"
              height="16"
              alt="userDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Nama Pasien
            </p>
          </div>
          <input
            id="patient"
            {...register("patient", { required: true })}
            disabled={isLoading}
            type="text"
            placeholder="Masukkan Nama Pasien .."
            className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
          />
        </div>
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.pillDarken}
              width="16"
              height="16"
              alt="pillDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Obat
            </p>
          </div>
          <input
            id="medicine"
            {...register("medicine", { required: true })}
            disabled={isLoading}
            type="text"
            placeholder="Masukkan Nama Obat .."
            className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
          />
        </div>
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.vaccineBottleDarken}
              width="16"
              height="16"
              alt="vaccineBottleDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Dosis
            </p>
          </div>
          <div className="flex flex-row gap-2 items-center justify-start w-full h-auto">
            <input
              id="dosage"
              {...register("dosage", { required: true })}
              disabled={isLoading}
              type="number"
              placeholder="Masukkan Dosis .."
              className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
            />
            <select
              id="dosage_unit"
              {...register("dosage_unit", { required: true })}
              disabled={isLoading}
              className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
            >
              <option>Pilih Satuan</option>
              <option id="miligram">Miligram (mg)</option>
              <option id="mikrogram">Mikrogram (µg)</option>
              <option id="milliliter">
                Milliliter (ml) atau Cubic Centimeter (cc)
              </option>
              <option id="unit">Unit (U)</option>
              <option id="gram">Gram (g)</option>
              <option id="international_unit">International Unit (IU)</option>
            </select>
          </div>
        </div>
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.bellPlusDarken}
              width="16"
              height="16"
              alt="bellPlusDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Penjadwalan
            </p>
          </div>
          <select
            id="schedule"
            {...register("schedule", { required: true })}
            disabled={isLoading}
            className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
          >
            <option>Pilih Penjadwalan</option>
            <option id="one_time_in_a_day">1x Sehari</option>
            <option id="two_time_in_a_day">2x Sehari</option>
            <option id="three_time_in_a_day">3x Sehari</option>
            <option id="one_time_in_a_week">1x Seminggu</option>
            <option id="one_time_in_a_week">2x Seminggu</option>
            <option id="one_time_in_a_week">3x Seminggu</option>
          </select>
        </div>
        <div className="flex flex-col lg:flex-row items-center justify-center gap-2 w-full h-auto">
          <div className="flex flex-row gap-2 items-center justify-start w-full lg:w-[60%] h-auto p-0 mt-0">
            <Image
              src={svg.checkupListDarken}
              width="16"
              height="16"
              alt="checkupListDarken"
            />
            <p className="text-[hsl(0,0%,13%)] font-medium text-xs text-start mt-0">
              Keterangan
            </p>
          </div>
          <input
            id="notes"
            {...register("notes", { required: false })}
            disabled={isLoading}
            type="text"
            placeholder="(Opsional) Masukkan Keterangan .."
            className="outline-none bg-transparent text-[hsl(0,0%,13%)] placeholder:text-[hsl(0,0%,13%)]/60 w-full font-light text-xs"
          />
        </div>
      </div>
    </form>
  );
};

export default ComponentAddProvider;

I just dont know what kind of npm modules to use, or if there’s anybody can help me to solve it?

Openlayer // Animations when moving the coordinates of a marker

I put gps on my car and mark it as a marker on the map.

Problem is, gps data comes in every 1 minute cycle. This can’t be fixed…

As an alternative, I think the movement of the marker should be smooth.

I found an animation that moves along the polyline as a way to move the marker.

https://openlayers.org/en/latest/examples/feature-move-animation.html

But it seems like this has to have polyline.

Using this method is bound to be a cumbersome way to create and move polylines every minute.

How can I give an animation like transition of css

    function moveLeft() {
      let coordinates = markerLayer.getSource().getFeatures()[0].getGeometry().getCoordinates();
      let newCoordinates = [coordinates[0], coordinates[1] + 15]
      markerLayer.getSource().getFeatures()[0].getGeometry().setCoordinates(newCoordinates);

      // this is not animation..
    }

Is my form submission being prevented by SWR? [duplicate]

I am using nextjs and incorporating SWR for some client side data rendering for an edit page. I can get the data through the fetcher but for some reason my values wont update or setState unless I click on the form submission twice. The code as follows:

export default function Edit({ params }) {
  let [title, setTitle] = useState();
  let [body, setBody] = useState();
  const router = useRouter();

  const fetcher = (...args) => fetch(...args).then((res) => res.json());

  const sumbitForm = async (e) => {
    e.preventDefault();

    if (!title) {
      setTitle(data.title);
    }
    console.log(title);

    if (!body) {
      setTags(data.body);
    }
    console.log(body);
  };

  const id = params.forumId;
  const { data, error } = useSWR(
    `http://localhost:3000/api/forum/${id}`,
    fetcher,
  );

  if (error) {
    return <div>failed to load</div>;
  }
  if (!data) {
    return <div>loading...</div>;
  }
  if (data) {
    return (
      <>
        <div className="grid items-center min-h-screen px-4 space-y-4 md:px-6">
          <div className="space-y-2">
            <label className="form-label" htmlFor="title">
              Title
            </label>
            <Input
              id="title"
              onChange={(e) => setTitle(e.target.value)}
              defaultValue={data.title}
              required
            />
          </div>
          <div className="space-y-2">
            <label className="form-label" htmlFor="body">
              Body
            </label>
            <Textarea
              id="body"
              required
              onChange={(e) => setBody(e.target.value)}
              defaultValue={data.body}
              rows={10}
            />
          </div>
          <div className="space-y-2">
            <Button id="submitBtn" type="submit" onClick={sumbitForm}>
              Submit Button
            </Button>
          </div>
        </div>
      </>
    );
  }
}

my console logs just look like this {title: 'edited title', body: undefined}. it isn’t until I click on the submit button again that the console log is able to pick up the fields from the swr fetcher on the state of the remaining field: {title: 'edited title', body: 'The body of the original post'}. Any ideas why it takes 2 clicks to get the loaded data to associate to the value of the state?