Unexpected behaviour using Barba.js with BarbaCSS plugin

I have been following Petr Tichy’s fantastic courses, but I am running into a glitch I cannot fathom while attempting the cover transition (https://ihatetomatoes.net/module-1/bjs-06-css-cover-transition-703/)

In essence, Barba.js is changing the transform values on a covering div (.transition) — but unlike in Petr’s example, Barba does not KEEP the transform values on the covering div, at the end of the animation the cover zooms back up over the page, which is not what we want.

My Barba js

    import barba from '@barba/core';
    import barbaCss from '@barba/css';
    barba.use(barbaCss);
    barba.init(
    
    {
        transitions: [
            {
                name: 'with-cover',
                to: {
                    namespace: ['with-cover']
                },
                leave() {},
                enter() {}
            }       
        ]
    }
);  

and the corresponding css

.with-cover-leave-active,
.with-cover-enter-active,
.with-cover-leave-active .transition,
.with-cover-enter-active .transition {

    transition: transform 2s cubic-bezier(0.5, 0.7, 0.4, 1);
 
 }

/* cover slides down */

.with-cover-leave .transition {

   transform: translateY(-100%); 
}

.with-cover-leave-to .transition,
.with-cover-enter .transition {

    transform: translateY(0);

}

/* cover slides down and off the bottom of the screen */
 
 .with-cover-enter-to .transition {
 
     transform: translateY(100%) !important;
 
 }

I think the top classes are meant to KEEP the .transition transforms values in place, but what actually happens is the animation completes, then the transition dive shoots back up to Y -100!

Really stuck as to why this page test I built is NOT following the pattern of this demo page (click ‘Cover transition’) — https://ihatetomatoes.net/demos/barbajs/barbajs-css-transition/clip.html

heres the basic html structure too

<header data-barba="container" data-barba-namespace="with-cover" >
    <div class="transition">
      <h2>Cover Screen — is this really working?</h2>
    </div>
    <div class="content">
      <h1>This is cover content</h1> 
    </div>
</header>

Any advice much appreciated. I want sure if Barba was maybe handling css differently now?

thanks

Im getting ‘TypeError: Cannot read properties of undefined (reading ‘owner’)’ because component hasnt loaded an observable yet

Although the app works fine despite the error, I am receiving that error in my console because my component has not loaded the ‘post’ observable from the backend through the postService. My code is:

Component

export class PostComponent {
  post!: Post;

  constructor(
    activatedRoute: ActivatedRoute,
    private postService: PostService,
    private timeFormatService: TimeFormatService
  ) {
    activatedRoute.params.subscribe((params) => {
      if (params['id'])
        postService.getPostById(params['id']).subscribe((serverPost) => {
          this.post = serverPost;
        });
    });
  }
}

My html just displays post values such as {{post.owner}} or {{post.title}} in paragraphs or headings.

Im getting that error for each post value.
Ive figured i can fix this error by setting default values by changing post!:Post; to:

post:Post = {owner: '', title: ''}

And when the postService gets the real post details from the backend it updates the values. Im sort of new to coding, is this the correct way to do it?

How to animate bubble zone to zone using D3.js?

I have a svg file in which zones are market in red rectangle box, and i want to create a animated bubble visualization in which each bubble moves zone to zone as defined in csv.

My Csv looks like below:
this is house_csv.csv file i am using

device_id zone_name time
Kid Dinner 2024-01-01T00:00:00
Kid Family Room 2024-01-01T01:00:00
Kid Bedroom 2024-01-01T02:00:00
Friend1 Dinner 2024-01-01T00:00:00
Friend1 Family Room 2024-01-01T01:00:00
Friend1 Bedroom 2024-01-01T02:00:00
Pops Dinner 2024-01-01T00:00:00
Pops Garage Area 2024-01-01T01:00:00
Pops ,Bedroom 2024-01-01T02:00:00

Below is how my svg looks like, each red box is marked by an id which is same as zone_name:
its a house map where each read box is a room on which bubble should move

below is my code that i tried :

    <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Device Movement on Floorplan</title>
  <script src="https://d3js.org/d3.v7.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    #chart {
      width: 100%;
      height: 100%;
      max-width: 800px;
      max-height: 600px;
      margin: 0px auto;
      border: 1px solid #ccc;
      position: relative;
    }

    #playPauseButton {
      padding: 10px 20px;
      font-size: 16px;
      margin: 20px;
      cursor: pointer;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
    }

    #playPauseButton.paused {
      background-color: #f44336;
    }

    .bubble {
      fill-opacity: 0.8;
    }

    .object-label {
      font-size: 12px;
      font-weight: normal;
      fill: white;
      text-anchor: middle;
      pointer-events: none;
    }
  </style>
</head>
<body>
  <h1>Device Movement on Floorplan</h1>
  <div id="chart"></div>
  <button id="playPauseButton">Play</button>

  <script>
    window.onload = function() {
      // Load and parse the CSV file
      Papa.parse('house_csv.csv', {
        download: true,
        header: true,
        dynamicTyping: true,
        complete: function(results) {
          const filteredData = results.data.filter(row => row.time && row.time !== 'undefined');
          if (filteredData.length > 0) {
            createBubbleChart(filteredData);
          } else {
            console.error('No valid data found in the CSV');
          }
        },
        error: function(error) {
          console.error("CSV Parse Error: ", error);
        }
      });
    };

    function createBubbleChart(data) {
      const floorplanWidth = 627.89801;
      const floorplanHeight = 354.04199;

      const svg = d3.select("#chart").append("svg")
        .attr("width", "100%")
        .attr("height", "100%")
        .attr("viewBox", `0 0 ${floorplanWidth} ${floorplanHeight}`)
        .attr("preserveAspectRatio", "xMidYMid meet");

      d3.xml("HouseMap.svg").then(function(xml) {
        const importedNode = document.importNode(xml.documentElement, true);
        svg.node().appendChild(importedNode);

        const containerWidth = document.getElementById("chart").offsetWidth;
        const containerHeight = document.getElementById("chart").offsetHeight;

        const scaleX = containerWidth / floorplanWidth;
        const scaleY = containerHeight / floorplanHeight;

        console.log(`ScaleX: ${scaleX}, ScaleY: ${scaleY}`);

        // Create a map of zone names to positions (center of <rect> elements)
        const zonePositions = {};

        svg.selectAll("rect")
          .each(function() {
            const rectElement = d3.select(this);
            const zoneId = rectElement.attr("id");

            const bbox = rectElement.node().getBBox();
            const centerX = (bbox.x + bbox.width / 2) * scaleX;
            const centerY = (bbox.y + bbox.height / 2) * scaleY;

            zonePositions[zoneId] = { x: centerX, y: centerY };
          });

        console.log("Zone Positions: ", zonePositions);  // Debugging log to check mapping

        // Create a color scale for different device IDs
        const colorScale = d3.scaleOrdinal(d3.schemeCategory10);

        // Create initial bubbles for each device_id
        const bubbles = svg.selectAll(".bubble")
          .data([...new Set(data.map(d => d.device_id))])
          .enter().append("circle")
          .attr("class", "bubble")
          .attr("r", 10)  // Set initial radius
          .attr("cx", 0)  // Initial X position
          .attr("cy", 0)  // Initial Y position
          .attr("opacity", 0)
          .style("fill", d => colorScale(d)) // Assign color to each device
          .transition()
          .duration(2000)
          .attr("opacity", 1);  // Fade in the bubbles

        // Group data by device_id and zone_name
        const groupedData = d3.nest()
          .key(d => d.device_id)
          .key(d => d.zone_name)
          .entries(data);

        // Create a path for each device_id based on zone names
        const devicePaths = {};
        groupedData.forEach(device => {
          const deviceId = device.key;
          const path = device.values.map(d => zonePositions[d.key]);  // Get the corresponding zone position for each zone_name
          devicePaths[deviceId] = path;
        });

        console.log("Device Paths: ", devicePaths); // Debugging log to check paths

        let currentIndex = 0;
        let isPlaying = false;

        // Animate the bubbles across the floorplan
        function animateBubbles() {
          if (!isPlaying) return;

          // Loop through each device and move its bubble
          Object.keys(devicePaths).forEach(deviceId => {
            const devicePath = devicePaths[deviceId];
            const deviceBubble = svg.select(`circle[fill="${colorScale(deviceId)}"]`);
            if (!deviceBubble.empty()) {
              deviceBubble.transition()
                .duration(1000)  // Adjust duration for smooth transition
                .ease(d3.easeLinear)
                .attr("cx", devicePath[currentIndex].x)
                .attr("cy", devicePath[currentIndex].y);
            }
          });

          // Move to the next index in the data
          currentIndex++;
          if (currentIndex < data.length) {
            setTimeout(animateBubbles, 1000); // Adjust the timeout for better pacing
          } else {
            currentIndex = 0;  // Reset to the beginning for loop
          }
        }

        // Play/Pause button functionality
        d3.select("#playPauseButton").on("click", function() {
          isPlaying = !isPlaying;
          if (isPlaying) {
            d3.select("#playPauseButton").text("Pause");
            animateBubbles();  // Start the animation
          } else {
            d3.select("#playPauseButton").text("Play");
            currentIndex = 0;  // Reset index when paused
          }
        });
      });
    }
  </script>
</body>
</html>

this is what my output look likes :
my output here

My code is not displaying id names (from svg file) as label name correctly neither bubbles are moving, Can anyone help me in moving bubble zone to zone.

React -accessing properties of an object which is itself retrieved using a dynamic key of an outer object

I am having a problem accessing a property of an object which itself is a property of another object. I have reviewed the answers on here and researched the issue, but have not found an answer.

In brief, I have an object, data, that has a dynamic key that is a variable policyNumber, the value of which is an object. That object has a key loanFinancialInformation, the value of which is an object. I have data[policyNumber] saved as policyLoanDetails, and it shows the LoanFinanicalInformation object in the console.log. But when I do policyLoanDetails.loanFinancialInformation, or policyLoanDetails[loanFinancialInformation], or policyLoanDetails[‘loanFinancialInformation], I get TypeError: Cannot read properties of undefined (reading ‘loanFinancialInformation’)

This is a React project. First, I have a model component called PolcyLoanModel. It is pretty long, so I am trimming out some of the properties. The model is as follows:

export interface PolcyLoanModel {
    success: boolean;
    loanFinancialInformation: LoanFinancialInformation;
}

export interface LoanFinancialInformation {
    grossCashValue: GrossCashValue;
    maximumLoanInterest: MaximumLoanInterest;
    loanInterestRate: LoanInterestRate;
    loanInterestRateType: string;
    loanInterestRateDesc: LoanInterestRateDesc;
    loanPayoffDate: string;
}

export interface GrossCashValue {
    amount: number;
    currencyCode: string;
}

export interface MaximumLoanInterest {
    amount: number;
    currencyCode: string;
}

export interface LoanInterestRate {
    amount: number;
    currencyCode: string;
}

export interface LoanInterestRateDesc {
    code: string;
    shortName: string;
    longName: string;
    codeText: string;
}

Next I have a component called Policy. In that component, I do a callout for the loan information. The callout works fine, so I won’t post it here. I store the callout response in a variable called policyLoanDetails. This component also has the policy number I’m working with. That part is working fine also. I then have in my component return a component called LoanInfo. The line for the LoanInfo component passing the props is this:

<LoanInfo data={policyLoanDetails} policyNumber={policyNumber} />

In the LoanInfo component itself, I import the PolcyLoanModel. I then have the following code. Please note that I have trimmed out much of the code that is irrelevent due to length.

const LoanInfo = ({data, policyNumber}:{data:any, policyNumber:string}) => {
    console.log(`Loan Info component - data = ${JSON.stringify(data)}`);
    const policyLoanDetails: PolcyLoanModel = data[policyNumber];
    console.log(`policyLoanDetails - ${JSON.stringify(policyLoanDetails)}`);

For the callout, I am using a policy number which we will say is R302301 (fake for purposes of privacy). For the first console log, I get back the following:

{
    "N830000026":{
        "success": true,
        "loanFinancialInformation": {
            "grossCashValue": {
                "amount": 3021.21,
                "currencyCode": "USD"
            },
            "maximumLoanInterest": {
                "amount": 52.97,
                "currencyCode": "USD"
            },
            "loanInterestRate": {
                "amount": 7.4,
                "currencyCode": "USD"
            },
            "loanInterestRateType": "Fixed",
            "loanInterestRateDesc": {
                "code": "A",
                "shortName": "Advance",
                "longName": "Interest Billed in Advance",
                "codeText": ""
            },
            "loanPayoffDate": "2024-11-11"
        }
    }
}

For the second console.log, data[policyNumber], I get the following return:

{
    "success": true,
    "loanFinancialInformation": {
        "grossCashValue": {
            "amount": 3021.21,
            "currencyCode": "USD"
        },
        ...
        "loanPayoffDate": "2024-11-11",
    }
}

I am trying to access the properties of loanFinancialInformation in a table with the following lines of code:

const policyLoanInfo = policyLoanDetails.loanFinancialInformation;

<TableCell id="loan-info-cash-val-value">${policyLoanInfo.grossCashValue.amount} <span className="redText"><strong>(Don&apos;t Quote)</strong></span></TableCell>

The error is occurring on the line with const policyLoanInfo = . Like I said at the beginning, it occurs whether I use dot notation or bracket notation.

Any help is appreciated.

Dependency Array of useCallback is not working

I have a useCallback function and a snackbar state, each time deleteRow function called, snackbar state will be updated, but setSnackbar function not update the first value that we pass, so when we log from snackbar, snackbar doesn’t have the all value that we pass into it

const deleteRow = useCallback(async (item: ICheckoutItem, ppid: number, isLastOne = false) => {
        let newItems = [...checkoutItems];
        newItems = newItems.map(((item) => {
            item.properties = item.properties.filter((property) => property.id !== ppid);
            return item;
        }));

        newItems = newItems.filter((item) => item.properties.length > 0);

        setCheckoutItems(newItems);

        await server_axios.delete(endpoints.orderProductProperties.delete(ppid) + (orderId ? `?order_id=${orderId}` : ''));

        await new Promise((resolve) => setTimeout(resolve, 500));

        if (isLastOne && type === 'edit') {
            enqueueSnackbar(
                `تمامی کالاهای پروفیل ${item.product.name} با موفقیت حذف شدند.nهمچنین وضعیت سفارش شما به «حذف‌شده» تغییر داده شد.`,
                {
                    variant: 'multiline',
                    color: 'info',
                }
            );
            console.log(snackbar)
            snackbar.forEach((id) => {
                closeSnackbar(id)
            })
            setSnackbar([])
        } else if (!isLastOne) {
            const esId: SnackbarKey = enqueueSnackbar('کالای مورد نظر با موفقیت حذف شد.', {
                color: 'info',
                variant: 'myCustomVariant',
                showTimer: true,
                showButton: true,
                autoHideDuration: 10 * 1000,
                onClick: async () => {
                    await server_axios.patch(endpoints.orderProductProperties.cancel_delete(ppid))
                    if (onRefresh) onRefresh();
                }
            })
            setSnackbar(currentSnackbar => {
                console.log('Previous snackbar state:', currentSnackbar);
                console.log('New snackbar ID:', esId);
                const newState = [...currentSnackbar, esId];
                console.log('New snackbar state:', newState);
                return newState;
            });
            // updateSnack(esId)
            // console.log(esId)
            // let newSnackbar = snackbar.length ? [...snackbar, esId] : [esId]
            // console.log(newSnackbar)
            // setSnackbar([...newSnackbar])
        }

        if (afterUpdate) afterUpdate((newItems.length === 0));

    }, [checkoutItems, orderId, type, snackbar]);

I am user React Big Calendar and getting a depracation warning that says use javascript default parameters instead of defaultProps and cant solve it

I am having a little problem with setting up a calendar. The Calendar works, but I have been struggling a little bit with understanding a warning I have been trying to solve for a at least a couple of weeks.

I thought I have set appropriate javascript default parameters for every component related to the Calendarpage, but apprentley I dont understand the issue.

I have been reading several forums about this issue but could get it solved. It seems simple but still overlooking something.

here is my Calendar page.

Calendar PAge:

import {useState, useEffect, useMemo, useRef } from 'react'
import MainContentWrap from '../components/wraps/client/MainContentWrap' 
import CalendarInterface from '../components/interface/CalendarInterface.jsx'

import CalendarModal from '../components/modal/CalendarModal.jsx'
import { dataProvider } from '../dataProvider/main/DataProvider.jsx'
import { useGetIdentity } from 'react-admin'
import { useNotify } from 'react-admin'
import { useAuthenticated } from 'react-admin'

const dummyPlannedEvent = { 
    id: 1,
    title: 'title',
    start: 0,
    end: 0,
    resource : 1
  }

export default function CalendarPage(){
    useAuthenticated()
    const {data: userIdentity, isPending, error} = useGetIdentity()
    const notify = useNotify()
    const wrapName = 'Calendar'
    const dialog = useRef()
    
    const [plannedEvents, setPlannedEvents] = useState([dummyPlannedEvent])
    const [userSelectedEvents, setUserSelectedEvents] = useState([dummyPlannedEvent])
    const [responseRequest, setResponseRequest] = useState(null)
    const [showInModal, setShowInModal] = useState({
        title: 'test',
        startDateTime: 'xx-xx-xxx',
        endTime: 'xx-xx-xxxx',
    })
    const handleSelectEvent = useMemo(() => 
        (event) =>  { 
            const options = { month: 'short', day: 'numeric' }
            const selectedDate = new Date(event.start).toLocaleDateString('en-us', options)
            
            if(event.start < new Date()){
                let text = `This ${event.title} on ${selectedDate} has already passed!nPlease selected one of the upcoming available dates`
                window.alert(text)
                return
            }
            
            dialog.current.open()
            const extractStartTimeEvent = new Date(event.start)
            const extractEventTimeEnd = new Date(event.end)
            
            const extractDay = extractStartTimeEvent.toDateString()
            const extractStartTimeHours = extractStartTimeEvent.getHours()
            const extractStartTimeMin = extractStartTimeEvent.getMinutes()
            const startTimeEvent = extractStartTimeHours + ':' + extractStartTimeMin
            
            const extractEndTimeHours = extractEventTimeEnd.getHours()
            const extractEndTimeMin = extractEventTimeEnd.getMinutes()
            const endTimeEvent = extractEndTimeHours + ':' + extractEndTimeMin

            const allReadySelected = userSelectedEvents.find((eventId) => eventId === event.id)
            
            setShowInModal(() => ({
                    id: event.id,
                    title: event.title,
                    description: event.description,
                    day: extractDay,
                    start: startTimeEvent,
                    end: endTimeEvent,
                    allReadySelected: !!allReadySelected,
                })
            )
        }
    )

    useEffect(() => {
        dataProvider.allBlackDragonEvents('subscribe', userIdentity?.email).then((blackDragonEvents) =>{
             setUserSelectedEvents(blackDragonEvents?.userSelectedEvents)
             setPlannedEvents(blackDragonEvents?.events)
        }).catch(error => notify(`${error}`, {type: 'error'}))
    }, [])

    const standardSyle = 'p-4 mb-8 rounded-md text-center'

    console.log('plannedDragonEvents', plannedEvents)
    console.log('blackDragonEvents',userSelectedEvents)

    return(
        <>
            <CalendarModal ref={dialog} setResponseRequest={setResponseRequest}  {...showInModal} />
            <MainContentWrap name={wrapName}>
                <div className='flex-col'>
                    {responseRequest?.message != null && 
                        <section className={responseRequest.status >= 399 ? `bg-red-300 border border-red-400 text-red-700 ${standardSyle}` :`bg-green-300 border border-green-400 text-green-700 ${standardSyle}`}>
                            {responseRequest.message}
                        </section>
                    }
                    <CalendarInterface
                        getPlannedEvents={plannedEvents}
                        userSelectedEvents={userSelectedEvents}
                        clickHandle={handleSelectEvent} 
                        />
                </div>    
            </MainContentWrap>
        </>
    )
 }

CalendarInterface:

import React, {useState} from 'react'
import { Calendar, dateFnsLocalizer} from 'react-big-calendar'

import IconBxCheck from '../../assets/IconBxCheck'

import format from 'date-fns/format'
import parse from 'date-fns/parse'
import startOfWeek from 'date-fns/startOfWeek'
import getDay from 'date-fns/getDay'
import enUS from 'date-fns/locale/en-US'
import moment from 'moment/moment'

import "react-big-calendar/lib/css/react-big-calendar.css"
import "./CalendarInterface.css"

const locales = {
  'en-US': enUS,
}

const localizer = dateFnsLocalizer({
  format,
  parse,
  startOfWeek,
  getDay,
  locales,
})

const defaultPlannedEvents = [
  {
    id: 0,
    title: 'training',
    start: 0,
    end: 0,
    resource : 1
 },
 {
    id: 1,
    title: 'training',
    start: 0,
    end: 0,
    resource : 1
   }
]

const CalendarInterface = ({getPlannedEvents = defaultPlannedEvents, userSelectedEvents = [{id: 0}], clickHandle = () => {}}) => {    
    
  const components = {
    event: ({ event }) => {
      const {id, title: typeEvent} = event
  
      if(userSelectedEvents.includes(id)) {
        return ( <div style={{ display: 'inline-flex', justifyContent: 'center' ,backgroundColor: '#a6a6a6', color: '#004e00', fontWeight: 500, fontSize: 18, width: '100%' }}>{<IconBxCheck />} {typeEvent}</div>)
      }
  
      switch(typeEvent){
        case 'special':
          return( <div style={{ backgroundColor: '#d73052', color: 'white' }}>{typeEvent}</div>)
        case 'training':
          return( <div style={{ backgroundColor: '#ffb732', color: '#444444' }}>{typeEvent}</div>)
        case 'expeditie':
          return( <div style={{ backgroundColor: '#00ffa5', color: '#674ea7' }}>{typeEvent}</div>)
        default: 
          return ( <div style={{ backgroundColor: '#f0f8ff', color: 'f0f8ff' }}>{typeEvent}</div>)
      }
    }
  }

  return (<Calendar
      localizer={localizer}
      events={getPlannedEvents}
      startAccessor="start"
      endAccessor="end"
      components={components}
      onSelectEvent={clickHandle}
      defaultView={'agenda'}
      views={['agenda', 'week']}
      style={{ height: 500 }}
    />)
}


export default CalendarInterface

I hope someone can help me solve this single issue/ error

Issue with looping animation in anime.js

I am trying to run animation of floating effect inside an animation that is called with another animation and it completely ignores the loop: true

import anime from "/static/js/lib/animejs/lib/anime.es.js";


export const initAnimation = () => {
    const XOplatform = anime.timeline({
        targets: '.XOplatform',
        autoplay: false,
        begin: function () {
            smallXandO.play();
        }
    }).add({
        duration: 400,
        easing: 'easeInOutExpo',
        scaleX: [1, 1],
        scaleY: [0, 1],
        perspective: '500px',
    }).add({
        duration: 800,
        rotateY: '-15deg',
        rotateX: '8deg',
        rotateZ: '-1deg'
    });

    const smallXandO = anime.timeline({
        targets: '.cross-box-1, .circle-box-1',
        autoplay: false,
    }).add({
        duration: 400,
        easing: 'easeInOutExpo',
        scaleX: [0.05, 0.05],
        scaleY: [0, 1],
        perspective: '500px',
    }).add({
        duration: 400,
        easing: 'easeInOutExpo',
        scaleX: 1
    }).add({
        duration: 800,
        rotateZ: '20deg'
    }).add({
        keyframes: [
            { translateY: -10 },
            { translateY: 0 },
        ],
        duration: 6000,
        easing: 'easeInOutSine',
        direction: 'alternate',
        loop: true
    });

    const initFce = () => {
        setTimeout(function () {
            XOplatform.play();
        }, 600);
    };

    initFce();
};

I tried to restart it once it is complete but it didn’t work

.add({
        keyframes: [
            { translateY: -10 },
            { translateY: 0 },
        ],
        duration: 6000,
        easing: 'easeInOutSine',
        direction: 'alternate',
        loop: true,
        complete: function () {
             smallXandO.restart();
        }
    });

Dependency Array of useCallback is not working and not set new value to array state

i have a delete function that when called, it shows a snackbar, and every snackbar has a unique id, and in the delete function, I save these snackbar ids in an state,

const deleteRow = useCallback(async (item: ICheckoutItem, ppid: number, isLastOne = false) => {
        let newItems = [...checkoutItems];
        newItems = newItems.map(((item) => {
            item.properties = item.properties.filter((property) => property.id !== ppid);
            return item;
        }));

        newItems = newItems.filter((item) => item.properties.length > 0);

        setCheckoutItems(newItems);

        await server_axios.delete(endpoints.orderProductProperties.delete(ppid) + (orderId ? `?order_id=${orderId}` : ''));

        await new Promise((resolve) => setTimeout(resolve, 500));

        if (isLastOne && type === 'edit') {
            enqueueSnackbar(
                `تمامی کالاهای پروفیل ${item.product.name} با موفقیت حذف شدند.nهمچنین وضعیت سفارش شما به «حذف‌شده» تغییر داده شد.`,
                {
                    variant: 'multiline',
                    color: 'info',
                }
            );
            console.log(snackbar)
            snackbar.forEach((id) => {
                closeSnackbar(id)
            })
            setSnackbar([])
        } else if (!isLastOne) {
            const esId: SnackbarKey = enqueueSnackbar('کالای مورد نظر با موفقیت حذف شد.', {
                color: 'info',
                variant: 'myCustomVariant',
                showTimer: true,
                showButton: true,
                autoHideDuration: 10 * 1000,
                onClick: async () => {
                    await server_axios.patch(endpoints.orderProductProperties.cancel_delete(ppid))
                    if (onRefresh) onRefresh();
                }
            })
            setSnackbar(currentSnackbar => {
                console.log('Previous snackbar state:', currentSnackbar);
                console.log('New snackbar ID:', esId);
                const newState = [...currentSnackbar, esId];
                console.log('New snackbar state:', newState);
                return newState;
            });
        }

        if (afterUpdate) afterUpdate((newItems.length === 0));

    }, [checkoutItems, orderId, type, snackbar]);

i ask difference AI and no one can help me to fix this,

the problem is when is call setSnackbar for the first time, the snackbar Id will not save in the snackbar state!!!
but when call setSnackbar for the second time، the value will save!!
and when i call delete function to delete the last record and close all of the snackbar ids, snackbar states has just the last snackbar id value!!

this is my all code


export default function ShoppingCartList({ items, type, isMini, afterUpdate, orderId, onRefresh }: Props) {
    const checkout = useCheckoutContext();

    const [checkoutItems, setCheckoutItems] = useState<ICheckoutItem[]>(items);
    const [checkoutItem, setCheckoutItem] = useState<ICheckoutItem>();
    const [propertyId, setPropertyId] = useState<number>();
    const [property, setProperty] = useState<ICheckoutItemPropertyPrice>();
    const [list, setList] = useState<ICheckoutItemPropertyPrice[]>();
    const [snackbar, setSnackbar] = useState<SnackbarKey[]>([]);
    // const [is, setIs] = useState<boolean>(true);
    // const snackbarRef = useRef<any[]>([]);

    const cartDialog = useBoolean();

    const { enqueueSnackbar, closeSnackbar } = useSnackbar();

    const deleteRow = useCallback(async (item: ICheckoutItem, ppid: number, isLastOne = false) => {
        let newItems = [...checkoutItems];
        newItems = newItems.map(((item) => {
            item.properties = item.properties.filter((property) => property.id !== ppid);
            return item;
        }));

        newItems = newItems.filter((item) => item.properties.length > 0);

        setCheckoutItems(newItems);

        await server_axios.delete(endpoints.orderProductProperties.delete(ppid) + (orderId ? `?order_id=${orderId}` : ''));

        await new Promise((resolve) => setTimeout(resolve, 500));

        if (isLastOne && type === 'edit') {
            enqueueSnackbar(
                `تمامی کالاهای پروفیل ${item.product.name} با موفقیت حذف شدند.nهمچنین وضعیت سفارش شما به «حذف‌شده» تغییر داده شد.`,
                {
                    variant: 'multiline',
                    color: 'info',
                }
            );
            console.log(snackbar)
            snackbar.forEach((id) => {
                closeSnackbar(id)
            })
            setSnackbar([])
        } else if (!isLastOne) {
            const esId: SnackbarKey = enqueueSnackbar('کالای مورد نظر با موفقیت حذف شد.', {
                color: 'info',
                variant: 'myCustomVariant',
                showTimer: true,
                showButton: true,
                autoHideDuration: 10 * 1000,
                onClick: async () => {
                    await server_axios.patch(endpoints.orderProductProperties.cancel_delete(ppid))
                    if (onRefresh) onRefresh();
                }
            })
            setSnackbar(currentSnackbar => {
                console.log('Previous snackbar state:', currentSnackbar);
                console.log('New snackbar ID:', esId);
                const newState = [...currentSnackbar, esId];
                console.log('New snackbar state:', newState);
                return newState;
            });
            // updateSnack(esId)
            // console.log(esId)
            // let newSnackbar = snackbar.length ? [...snackbar, esId] : [esId]
            // console.log(newSnackbar)
            // setSnackbar([...newSnackbar])
        }

        if (afterUpdate) afterUpdate((newItems.length === 0));

    }, [checkoutItems, orderId, type, snackbar]);

    return (
        <Box>
            {checkoutItem && (
                <CartDialog
                    dialog={cartDialog}
                    order_form_id={checkoutItem.product.order_form_options.id}
                    product_name={checkoutItem.product.name}
                    pId={checkoutItem.id}
                    listId={propertyId}
                    listData={list}
                    onAddCart={handleAddCart}
                    onDelete={(ppid: number) => deleteRow(checkoutItem, ppid)}
                    handleUpdateRow={handleUpdateRow}
                    currentData={property}
                    type={type}
                />
            )}

Dependency Array of useCallback is not working and not set new array value to state

i have a delete function that when called, it shows a snackbar, and every snackbar has a unique id, and in the delete function, I save these snackbar ids in an state,

const deleteRow = useCallback(async (item: ICheckoutItem, ppid: number, isLastOne = false) => {
        let newItems = [...checkoutItems];
        newItems = newItems.map(((item) => {
            item.properties = item.properties.filter((property) => property.id !== ppid);
            return item;
        }));

        newItems = newItems.filter((item) => item.properties.length > 0);

        setCheckoutItems(newItems);

        await server_axios.delete(endpoints.orderProductProperties.delete(ppid) + (orderId ? `?order_id=${orderId}` : ''));

        await new Promise((resolve) => setTimeout(resolve, 500));

        if (isLastOne && type === 'edit') {
            enqueueSnackbar(
                `تمامی کالاهای پروفیل ${item.product.name} با موفقیت حذف شدند.nهمچنین وضعیت سفارش شما به «حذف‌شده» تغییر داده شد.`,
                {
                    variant: 'multiline',
                    color: 'info',
                }
            );
            console.log(snackbar)
            snackbar.forEach((id) => {
                closeSnackbar(id)
            })
            setSnackbar([])
        } else if (!isLastOne) {
            const esId: SnackbarKey = enqueueSnackbar('کالای مورد نظر با موفقیت حذف شد.', {
                color: 'info',
                variant: 'myCustomVariant',
                showTimer: true,
                showButton: true,
                autoHideDuration: 10 * 1000,
                onClick: async () => {
                    await server_axios.patch(endpoints.orderProductProperties.cancel_delete(ppid))
                    if (onRefresh) onRefresh();
                }
            })
            setSnackbar(currentSnackbar => {
                console.log('Previous snackbar state:', currentSnackbar);
                console.log('New snackbar ID:', esId);
                const newState = [...currentSnackbar, esId];
                console.log('New snackbar state:', newState);
                return newState;
            });
        }

        if (afterUpdate) afterUpdate((newItems.length === 0));

    }, [checkoutItems, orderId, type, snackbar]);

i ask difference AI and no one can help me to fix this,

the problem is when is call setSnackbar for the first time, the snackbar Id will not save in the snackbard state!!!
but the id of the second snackbard will save!!
and when i call delete function to delete the last record and close all of the snackbar ids, snackbar states has just the last snackbar id!!

this is my all code


export default function ShoppingCartList({ items, type, isMini, afterUpdate, orderId, onRefresh }: Props) {
    const checkout = useCheckoutContext();

    const [checkoutItems, setCheckoutItems] = useState<ICheckoutItem[]>(items);
    const [checkoutItem, setCheckoutItem] = useState<ICheckoutItem>();
    const [propertyId, setPropertyId] = useState<number>();
    const [property, setProperty] = useState<ICheckoutItemPropertyPrice>();
    const [list, setList] = useState<ICheckoutItemPropertyPrice[]>();
    const [snackbar, setSnackbar] = useState<SnackbarKey[]>([]);
    // const [is, setIs] = useState<boolean>(true);
    // const snackbarRef = useRef<any[]>([]);

    const cartDialog = useBoolean();

    const { enqueueSnackbar, closeSnackbar } = useSnackbar();

    const deleteRow = useCallback(async (item: ICheckoutItem, ppid: number, isLastOne = false) => {
        let newItems = [...checkoutItems];
        newItems = newItems.map(((item) => {
            item.properties = item.properties.filter((property) => property.id !== ppid);
            return item;
        }));

        newItems = newItems.filter((item) => item.properties.length > 0);

        setCheckoutItems(newItems);

        await server_axios.delete(endpoints.orderProductProperties.delete(ppid) + (orderId ? `?order_id=${orderId}` : ''));

        await new Promise((resolve) => setTimeout(resolve, 500));

        if (isLastOne && type === 'edit') {
            enqueueSnackbar(
                `تمامی کالاهای پروفیل ${item.product.name} با موفقیت حذف شدند.nهمچنین وضعیت سفارش شما به «حذف‌شده» تغییر داده شد.`,
                {
                    variant: 'multiline',
                    color: 'info',
                }
            );
            console.log(snackbar)
            snackbar.forEach((id) => {
                closeSnackbar(id)
            })
            setSnackbar([])
        } else if (!isLastOne) {
            const esId: SnackbarKey = enqueueSnackbar('کالای مورد نظر با موفقیت حذف شد.', {
                color: 'info',
                variant: 'myCustomVariant',
                showTimer: true,
                showButton: true,
                autoHideDuration: 10 * 1000,
                onClick: async () => {
                    await server_axios.patch(endpoints.orderProductProperties.cancel_delete(ppid))
                    if (onRefresh) onRefresh();
                }
            })
            setSnackbar(currentSnackbar => {
                console.log('Previous snackbar state:', currentSnackbar);
                console.log('New snackbar ID:', esId);
                const newState = [...currentSnackbar, esId];
                console.log('New snackbar state:', newState);
                return newState;
            });
            // updateSnack(esId)
            // console.log(esId)
            // let newSnackbar = snackbar.length ? [...snackbar, esId] : [esId]
            // console.log(newSnackbar)
            // setSnackbar([...newSnackbar])
        }

        if (afterUpdate) afterUpdate((newItems.length === 0));

    }, [checkoutItems, orderId, type, snackbar]);

    return (
        <Box>
            {checkoutItem && (
                <CartDialog
                    dialog={cartDialog}
                    order_form_id={checkoutItem.product.order_form_options.id}
                    product_name={checkoutItem.product.name}
                    pId={checkoutItem.id}
                    listId={propertyId}
                    listData={list}
                    onAddCart={handleAddCart}
                    onDelete={(ppid: number) => deleteRow(checkoutItem, ppid)}
                    handleUpdateRow={handleUpdateRow}
                    currentData={property}
                    type={type}
                />
            )}

Nextjs Typescript Error deconstructing params in api route

I Have a next project when I build it, it works fine localy but on vercel keeps throwing this error no matter what I try

Type error: Route "[action]/route.ts" has an invalid "POST" export:
  Type "NextResponse<unknown>" is not a valid type for the function's second argument.
Error: Command "npm run build" exited with 1

This is my current code and I’ve tried many variation of it but it wont let me build

declare module "next/server" {
  interface NextResponse {
    params: { action: string }; // Add your custom property here
  }
}
export const POST = async (req: NextRequest, res: NextResponse) => {
  const { params } = await res;

  if (!params || !params.action)
    return NextResponse.json({ success: false, message: "Incorrect usage" });

  const action = params.action;

  
  ...

Also tried expanding

interface MyResponse extends NextResponse {
  params: { action: string }; // Add your custom property here
}
export const POST = async (req: NextRequest, res: MyResponse) => {

Any help would be much appreciated

Interdependent numeric fields

I am using Datatables Editor and have 3 numeric fields which are interdependent:

  1. when I input a numeric data in the first one, the value of the second one must adjust to be equal to the value of the third one (if present) less the value of the first one, multiplied by ten thousand –> 2 = (3-1)*10000
  2. when I input a numeric data in the second one, the value of the third one must adjust to be equal to the value of the first one plus the value of the second one divided by ten thousand –> 3 = 1 +2/10000
  3. when I input a numeric data in the third one, the value of the second one must adjust to be equal to the value of the third one less the value of the first one multiplied by ten thousand –> 2 = (3 -1)/10000

The 3rd part works fine with the following code:

    editor.dependent( 'tms_ft_financialtransaction.RateDeal', function ( val, data, callback ) {
        if (editor.field('tms_ft_financialtransaction.RateSpot').val() ) {
            editor.field('tms_ft_financialtransaction.RateMargin').val((parseFloat(editor.field('tms_ft_financialtransaction.RateDeal').val()) - parseFloat(editor.field('tms_ft_financialtransaction.RateSpot').val()) )*10000);
        }
        callback(true);
    } );

I have 2 problems:

  1. Although 20 is stored in the database, the second field is recalculated when opening the editor and shows decimals
    See example
  2. When I replicate the same code for the second part, I guess due to the first problem, when amending the second field, the third field is recalculated, which recalculates the third, which recalculates the second one, etc.
    Does anybody know how I can fix that?

How to filter values in a map in jsx?

I have a React function that handles user selections from a dropdown. The function is meant to handle two features:

Feature 1: When the user selects a key (from ourMap), the corresponding mGIds should be selected.

Feature 2: When the user selects specific mGIds, the corresponding key(s) from ourMap should be selected.

However, I’m facing an issue with Feature 2, where I need to filter the mGIds from the ourMap based on the selected values in mGDropdown. Specifically, if a user selects mGIds that match part of a key’s values in ourMap, the corresponding key should be selected—even if the user hasn’t selected all the mGIds for that key.

Problem Description:

In the handleOnChange function, I have a map ourMap with the following type:

interface ConfigurationMap {
  configurationName: string | null;
  mGIds: number[];  // List of mGIds associated with the key
}

The structure is such that ourMap’s key represents an ID, and the value is an array of mGIds (e.g., mGIds: [500, 300]).

When a user selects a key, the corresponding mGIds are retrieved, and I want to filter those mGIds against mGDropdown, which contains the mGIds that the user is allowed to see.

for example, please consider the below data

ourMap = new Map([
  [1, { configurationName: 'Key 1', mGIds: [500, 300] }],
  [2, { configurationName: 'Key 2', mGIds: [200, 350, 450] }]
]);

this.props.mGDropdown = [
  { value: 500 }, { value: 300 }, { value: 200 }, { value: 350 }
];

Feature 1: If the user selects key 1, the mGIds 500 and 300 should be selected.

Feature 2: If the user selects 200 and 350 from mGDropdown, key 2 should be selected, even though 450 is part of key 2’s mGIds but not in the mGDropdown.
The issue is that when a user selects 200 and 350, the current logic does not select key 2 because 450 is also part of key 2’s mGIds. The requirement is that 450 should be filtered out and key 2 should be selected because 200 and 350 are in mGDropdown.

code block:

handleOnChange = (selection, e) => {
    const { qaFilters, edit, ourMap } = this.props;
    const { name: filterName } = e;
    if (filterName === 'MapFilters') {
      const selectedKeys = selection.map((item) => item.label);
      const selectedMGIds = selectedKeys.reduce((acc, key) => {
        const mgIds = ourMap.get(key)?.mgIds || [];
        return acc.concat(mgIds);
      }, []);

      const selectedMGs = this.props.mGDropdown.filter(
        (group) => selectedMGIds.includes(group.value)
      );
      const updatedFilters = {
        ...qaFilters,
        mGFilters: selectedMGs,
      };
      ...
    } 
  };
  
  
  render(){
    const selectedPSs = this.getSelectedPSs(
      mGFilters,
      ourMap,
      pSOptions
    );
    const pSFilters = [...selectedPSs];
  }
  
  
  getSelectedPSs(
    mGFilters,
    ourMap,
    pSOptions
  ) {
    const selectMGIds = mGFilters
      ? mGFilters.map((item) => item.value)
      : [];

    const allMGMatch = (mGIds) => {
      return mGIds.every((id) =>
        selectMGIds.includes(id)
      );
    };

    const pSEntries = Array.from(ourMap.entries());

    const filteredEntries = pSEntries.filter(
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      ([_, { mGIds }]) => {
        const match = allMGMatch(mGIds);
        return match;
      }
    );

    const matchingCIds = filteredEntries.map(([key]) => {
      return key;
    });

    return pSOptions.filter((group) =>
      matchingCIds.includes(group.value)
    );
  }

What I Need:
I need to filter out mGIds from ourMap that are not present in this.props.mGDropdown. For example, if 450 is in the mGIds of a key (like key 2), but it is not part of the mGDropdown, it should be excluded.
Key 2 should still be selected if the user selects 200 and 350, even though 450 exists in ourMap for key 2.

Question:
How can I modify the logic in handleOnChange to filter out mGIds from ourMap that are not part of this.props.mGDropdown, so that feature 2 works as expected?

Is there a way to bind event in dynamically rendered components in angular using templates?

I am using below code to render my components dynamically –

    @for(item of list(); track $index){
    <!-- dynamic rendering using ng-container -->
    <ng-container *ngComponentOutlet="componentToRender(); inputs: item;" />
}

Is there a way to bind events using any property of ng-container similar to input?
I have alreay searched the internet and those solutions suggesting to use @ViewChild but I want to know if any solution exists which uses only templates for event binding.

Chrome extension, tailwind css and youtube issue

I am working on a Chrome extension that inserts some HTML into a shadow DOM. Everything works as expected, but on YouTube, the content seems zoomed out. I have also tried setting important: '#modal-root', on my tailwind.config.js, but that doesn’t solve the issue.

I also noticed that when I inspect the text in my extension HTML and look at the computed font size on youtube it shows 10px and on other websites it shows 20px.

I am using React for my Chrome extension with tailwind CSS.

This is how it should look like

enter image description here

And this is how it looks on youtube.com
enter image description here

Here is how I append the shadow dom:

import Modal from './src/components/Content/Modal.jsx';
import { createRoot } from 'react-dom/client';

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.action === 'showInputPopup') {
        const elementName = 'my-extension';
        const wrapperContainer = document.querySelector(elementName);
        if (wrapperContainer) {
            wrapperContainer.remove();
        }
        const modalContainer = document.createElement(elementName);
        const shadowRoot = modalContainer.attachShadow({ mode: 'open' });

        // Load Tailwind CSS into Shadow DOM
        const styleLink = document.createElement('link');
        styleLink.setAttribute('rel', 'stylesheet');
        styleLink.setAttribute('href', chrome.runtime.getURL('assets/tailwind-generate.css')); // Update this path to your generated CSS file
        shadowRoot.appendChild(styleLink);

        // Create an inner div for React to render into
        const reactRootDiv = document.createElement('div');
        reactRootDiv.id = 'modal-root';
        shadowRoot.appendChild(reactRootDiv);
        document.body.appendChild(modalContainer);

        createRoot(reactRootDiv).render(<Modal />);
    }
});

And here is my tailwind.config.js

/** @type {import('tailwindcss').Config} */
import forms from "@tailwindcss/forms";

export default {
  important: '#modal-root',
  content: [
    'index.html',
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [
      forms
  ],
}

When I click on the login text, I am not directed to the “/login” page

<li>
  <ion-icon name="person-outline" class="nav-icon"></ion-icon>
  <a class="main-nav-link show-modal" href="/login">Giriş</a>
</li>

<div class="giris gizle">
  <button class="giris-kapat">&times;</button>
  <h1 class="giris-name">Giriş</h1>
  <div>
    <form action="/login" method="POST">
      <ul class="giris-list">
        <li class="giris-item">
          <p class="giris-text">Kullanıcı Adı:</p>
          <input type="text" name="username" />
        </li>
        <li class="giris-item">
          <p class="giris-text">Şifre:</p>
          <input type="password" name="password" />
        </li>
      </ul>
      <button type="submit" class="giris-btn">Giriş</button>
    </form>
  </div>
</div>

router.get("/login", async (req, res) => {});

router.post("/login", async (req, res) => {
const { username, password } = req.body; // Formdan gelen veriyi al

try {
const request = new sql.Request();
const result = await request
  .input("username", sql.VarChar, username) // Kullanıcı adını parametre olarak ver
  .input("password", sql.VarChar, password) // Şifreyi parametre olarak ver
  .query(
    "SELECT * FROM Kullanicilar WHERE kullaniciAdi = @username AND kullaniciSifre = @password"
  ); // Sorgu

if (result.recordset.length > 0) {
  // Kullanıcı bulunduysa giriş başarılı
  console.log("giriş başarılı");
  res.render("user-page");
} else {
  // Kullanıcı bulunamadıysa hata mesajı
  console.log("Geçersiz kullanıcı adı veya şifre");
}
} catch (err) {
console.error("Giriş işlemi sırasında hata oluştu:", err);
res.status(500).send("Giriş sırasında bir hata oluştu.");}});

When you click on “Login” on the Home Page, a login window opens in the middle of the screen, but there is no redirection to “/login”. Why?
When you click on the login text on the homepage, I want the login window to open and be directed to /login. If the login is correct, I will redirect to another page, if it is incorrect, I will send an error message.