Sorting Issue with AngularJS

when I click on a column header, sorting happens as expected while keeping null values at the bottom for both ascending and descending cases. It is working this way for all my columns except for the ones with date values where all null values are being placed on the top or bottom. Is this expected with AngularJS or am I doing something wrong?

Here is my JS code for sorting that is called using ng-click on a column header:

  $scope.Data = $scope.Data.sort(function (a, b)
       {
           var firstValue = getDisplayValue(a, $scope.TableSorting.SortedByColumn);
           var secondValue = getDisplayValue(b, $scope.TableSorting.SortedByColumn);

           if (firstValue === null)
           {
               return 1;
           }
           else if (secondValue === null)
           {
               return -1;
           }

           if (isDate(firstValue) && isDate(secondValue))
           {
               firstValue = new Date(firstValue);
               secondValue = new Date(secondValue);
           }

           if (typeof firstValue === 'string' && typeof secondValue === 'string')
           {
               firstValue = firstValue.toLowerCase();
               secondValue = secondValue.toLowerCase();
           }

           if (firstValue < secondValue)
           {
               return $scope.TableSorting.SortInReverseOrder ? 1 : -1;
           }

           if (firstValue > secondValue)
           {
               return $scope.TableSorting.SortInReverseOrder ? -1 : 1;
           }

           return 0;
       });
   };

    getDisplayValue = function (data, columnName) {
        if (columnName == 'PreviousCallIsInbound') 
        {
            return data.PreviousConferenceId ? (data.PreviousCallDate ? 'Yes' : 'No') : null;
        }

        if (columnName == 'NextCallIsInbound') {
            return data.NextConferenceId ? (data.NextCallDate ? 'Yes' : 'No') : null;
        }

        return data[columnName];
    };

this is the cshtml code that calls the function:

                            <table class="table table-hover table-special table-striped" id="tblMainTable" style="table-layout: fixed; width: 100%;">
                            <thead>
                                <tr>
                                    <th style="width: 100px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'UserName',
                                           'sorting_desc': TableSorting.SortedByColumn === 'UserName' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'UserName' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('UserName')">User</th>

                                    <th style="width: 100px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'UserActionDate',
                                           'sorting_desc': TableSorting.SortedByColumn === 'UserActionDate' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'UserActionDate' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('UserActionDate')">Action Date</th>

                                    <th style="width: 150px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'UserActionName',
                                           'sorting_desc': TableSorting.SortedByColumn === 'UserActionName' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'UserActionName' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('UserActionName')">Action</th>

                                    <th style="width: 100px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'OfferId',
                                           'sorting_desc': TableSorting.SortedByColumn === 'OfferId' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'OfferId' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('OfferId')">OfferId</th>

                                    <th style="width: 200px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'PreviousConferenceId',
                                           'sorting_desc': TableSorting.SortedByColumn === 'PreviousConferenceId' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'PreviousConferenceId' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('PreviousConferenceId')">Previous Conf Id</th>

                                    <th style="width: 100px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'PreviousCallDate',
                                           'sorting_desc': TableSorting.SortedByColumn === 'PreviousCallDate' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'PreviousCallDate' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('PreviousCallDate')">Previous Call Date</th>                                        
                                          
                                    <th style="width: 70px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'PreviousCallIsInbound',
                                           'sorting_desc': TableSorting.SortedByColumn === 'PreviousCallIsInbound' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'PreviousCallIsInbound' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('PreviousCallIsInbound')">Previous Call Is Inbound</th>     
                                          
                                    <th style="width: 200px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'NextConferenceId',
                                           'sorting_desc': TableSorting.SortedByColumn === 'NextConferenceId' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'NextConferenceId' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('NextConferenceId')">Next Conf Id</th>                                        
                                          
                                    <th style="width: 100px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'NextCallDate',
                                           'sorting_desc': TableSorting.SortedByColumn === 'NextCallDate' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'NextCallDate' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('NextCallDate')">Next Call Date</th>

                                    <th style="width: 70px;" ng-class="{'sorting': TableSorting.SortedByColumn !== 'NextCallIsInbound',
                                           'sorting_desc': TableSorting.SortedByColumn === 'NextCallIsInbound' && TableSorting.SortInReverseOrder,
                                           'sorting_asc': TableSorting.SortedByColumn === 'NextCallIsInbound' && !TableSorting.SortInReverseOrder
                                          }" ng-click="sortByColumn('NextCallIsInbound')">Next Is Inbound</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr ng-repeat="userActionReport in Data | filter : Paginate">
                                    <td style="overflow-wrap: break-word;">
                                        <span style="margin-top: 5px;">{{ userActionReport.UserName }}</span>
                                    </td>                                        
                                    <td>
                                        <span style="margin-top: 5px;">{{ userActionReport.UserActionDate }}</span>
                                    </td>                                        
                                    <td>
                                        <span style="margin-top: 5px;">{{ userActionReport.UserActionName }}</span>
                                    </td>
                                    <td>
                                        <a ng-click="openOffer(userActionReport.OfferId, userActionReport.OfferUniqueKey)">
                                            <span style="margin-top: 5px;">{{ userActionReport.OfferId }}</span>
                                        </a>
                                    </td>
                                    <td style="overflow-wrap: break-word;">
                                        <a ng-click="openConference(userActionReport.PreviousConferenceId)">
                                            <span style="margin-top: 5px;">
                                                {{ userActionReport.PreviousConferenceId }}
                                            </span>
                                        </a>
                                    </td>
                                    <td>
                                        <span style="margin-top: 5px;">{{ userActionReport.PreviousCallDate }}</span>
                                    </td>
                                    <td>
                                        <span style="margin-top: 5px;">
                                            {{ userActionReport.PreviousConferenceId ? (userActionReport.PreviousCallDate ? 'Yes' : 'No') : ' ' }}
                                        </span>
                                    </td>
                                    <td style="overflow-wrap: break-word;">
                                        <a ng-click="openConference(userActionReport.NextConferenceId)">
                                            <span style="margin-top: 5px;">{{ userActionReport.NextConferenceId }}</span>
                                        </a>
                                    </td>
                                    <td>
                                        <span style="margin-top: 5px;">{{ userActionReport.NextCallDate }}</span>
                                    </td>
                                    <td>
                                        <span style="margin-top: 5px;">
                                            {{ userActionReport.NextConferenceId ? (userActionReport.NextCallDate ? 'Yes' : 'No') : ' ' }}
                                        </span>
                                    </td>
                                </tr>
                            </tbody>
                        </table>

I tried including checks for undefined. Any help is appreciated!

Cant save my changes to a source map on an external site

Im trying to mess with some of the js on an external site and whenever I try to edit the source map (or its assocciated files) I get the “Changes to this file were not saved to the file system”. I don’t know if this is the reason why the changes wont affect the page, but either way I can’t make any difference on what actually happens.
Thanks!

How to resolve ‘App not active’ error in Facebook Login with React Native while in development mode?

Facebook Developer Console

here is my error enter image description here

Pls help i try all things but not working

I’m working on integrating Facebook Login into my React Native app using the react-native-fbsdk-next library. However, when trying to log in, I encounter the above error

Context:
My app is currently in development mode on the Facebook Developer platform.
I want to keep the app in development mode, as it’s still in the testing phase.
What I Need Help With:

Is it possible to resolve this error without switching the app to live mode?
Are there any specific configurations or settings I need to adjust in the Facebook Developer Console to allow testing while in development mode?
Has anyone else encountered this issue while in development mode, and how did you overcome it?
What I’ve Tried:

I’ve checked the Facebook Developer Console and confirmed that the app is in development mode.
I’ve added test users under App-Roles > Roles but still face the same issue.

D3.js and Livewire Integration: Points Not Appearing on Zoomed Region

I’m working on a project that integrates D3.js with Livewire (v3.4) in a Laravel application. I aim to display points (schools) on a map when a region (polygon) is clicked and zoomed in. The points should load dynamically based on the region’s desa_code using a Livewire method.

The issue I’m facing is that while the map is zoomed and the popup with region information displays correctly, the points do not appear on the canvas, and the regions sometimes disappear.

Here’s a summary of my process:

  1. Map and regions (polygons) load correctly from a GeoJSON file.
  2. On clicking a region, it zooms in and calls the Livewire method to load the corresponding points (schools).
  3. Points should be drawn on the map after the region is zoomed in, but they don’t appear.

Code Overview:

1. Livewire Component (PHP)

#[On('loadPoints')]
public function loadPoints($desaCode)
{
    $this->points = AppModelsMapHistory::getSekolahsWithinDesa($desaCode);
    $this->dispatchBrowserEvent('pointsLoaded', ['points' => $this->points]);
}

2. JavaScript (D3 and Livewire Integration)

function clicked(event, d) {
    event.stopPropagation();

    if (active === this) { 
        return reset();
    }

    active = this;

    features.transition().duration(500)
        .style("opacity", function() {
            return this === active ? 1 : 0;
        });

    const [[x0, y0], [x1, y1]] = path.bounds(d);
    svg.transition().duration(1000).call(
        zoom.transform,
        d3.zoomIdentity.translate(width / 2, height / 2)
        .scale(Math.min(8, 0.9 / Math.max((x1 - x0) / width, (y1 - y0) / height)))
        .translate(-(x0 + x1) / 2, -(y0 + y1) / 2)
    );

    // Load points (schools) based on desaCode
    Livewire.emit('loadPoints', d.properties.desa_code);
}

Livewire.on('pointsLoaded', (event) => {
    var points = JSON.parse(event.points);
    var pointsLayer = d3.select("#map").select("svg").append("g");

    pointsLayer.selectAll("circle").remove();
    pointsLayer.selectAll("circle")
        .data(points.features)
        .enter().append("circle")
        .attr("cx", function(d) {
            return projection([d.geometry.coordinates[0], d.geometry.coordinates[1]])[0];
        })
        .attr("cy", function(d) {
            return projection([d.geometry.coordinates[0], d.geometry.coordinates[1]])[1];
        })
        .attr("r", 5)
        .attr("fill", "blue")
        .on("click", function(d) {
            alert(`Sekolah: ${d.properties.name}nBentuk: ${d.properties.bentuk}nPegawai: ${d.properties.pegawai_count}`);
        });
});

3. Complete Code

Here’s the complete code it works fine when I zoom the region, but I would like the points to appear inside the zoomed region.

function showInfoPopup(event, properties) {
    d3.select("#info-popup").remove();

    var popup = d3.select("body").append("div")
        .attr("id", "info-popup")
        .style("position", "absolute")
        .style("background", "white")
        .style("border", "1px solid #ccc")
        .style("padding", "10px")
        .style("left", (event.pageX + 10) + "px")
        .style("top", (event.pageY + 10) + "px");

    // Add close button
    popup.append("button")
        .text("Close")
        .on("click", function () {
            d3.select("#info-popup").remove();
        });

    popup.append("h4").text("Informasi Wilayah");
    popup.append("p").text(`Desa: ${properties.desa_name}`);
    popup.append("p").text(`Kecamatan: ${properties.kecamatan_name}`);
}

Issue:

  1. Regions sometimes disappear on Zoom, and points do not appear on the canvas.
  2. The pointsLoaded event returns the correct data (checked with console.log(points)), but the points aren’t rendered.
  3. I suspect there may be an issue with how the points are layered or attached to the canvas after Zoom.

What I’ve Tried:

  • Verified that points are returned correctly from Livewire.
  • Used D3’s .data() to bind the points data to circle elements.
  • Tried different projection methods and cx/cy calculations.

Any help on how to correctly render the points and maintain the regions on Zoom would be greatly appreciated!

Hello, I’ve created a personal web site

Hello, I’ve created a personal webpage, and I’m wondering if it’s okay to share the URL to my webpage and GitHub repository to get feedback?

I understand that Stack Overflow is mainly for questions and answers about code errors and programming. Is it appropriate to ask for feedback by sharing my personal webpage and GitHub repository here?

If it’s not allowed, I’ll stop immediately and delete this question as well.

How can I show an updated header component with a user’s info in Next.js?

I am currently building my first web application using the Next.js App Router. Unfortunately, I’ve hit a roadblock in trying to display the user’s info (like a username) in the page’s header. When the status of the user’s session changes, the header does not update to reflect the new status. For instance, if a user signs in, they are redirected to their dashboard, but the header still shows the placeholder “Sign In” instead of a username:

Dashboard page shown immediately after sign-in. Header says 'sign in.'

When I reload the page, however, the header updates to reflect the new information:

Dashboard page upon refreshing. Header says 'Cloud Strife', the user's name.

This leads me to believe that there is an issue with the header not re-rendering upon navigation.

Currently, I have placed the header in the root template.tsx file:

import Header from "@/components/Header/Header";
import { PropsWithChildren } from "react";

export default function RootTemplate({ children }: PropsWithChildren) {
    return (
        <>
            <Header />
            <main>
                {children}
            </main>
        </>
    )
}

(The Header component logic is not included here because I have ensured that it properly fetches the account information at render time. I don’t believe that the Header component is the issue here.)

According to the Next.js documentation, template.tsx files differ from layout.tsx files in that their children do not persist upon navigation (at least, from what I understand):

Templates are similar to layouts in that they wrap a child layout or page. Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the child is mounted, DOM elements are recreated, state is not preserved in Client Components, and effects are re-synchronized.

Thus, when I placed my Header component in template.tsx, I thought it would be re-rendered on the server with updated information and sent to the client upon navigation. However, that doesn’t appear to be happening (maybe because it’s a Server Component)?

To get around this, I tried to convert the Header component into a Client Component that retrieves the user’s name upon rendering with a Server Action, but there was a noticeable delay in the header updating due to the latency of fetching account and session information from the database. Is there a way to make the Header component re-render to show consistently updated user information without a delay?

component is re-rendering Infinitely

const Survey: React.FC = () => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const [currentStep, setCurrentStep] = useState(0);
  const [stepsArray, setStepsArray] = useState<JSX.Element[]>([]);
  const [capturedPicture, setCapturePicture] = useState<string>('');
  const [showPopup, setShowPopup] = useState(false);
  const [popup, setPopup] = useState(false)
  const [loading, setLoading] = useState(false)
  const [enableGeolocation, setEnableGeolocation] = useState(false)
  const [locationFetched, setLocationFetched] = useState(false)
  const [isOnline, setIsOnline] = useState(navigator.onLine);
  const currentDate = getCurrentTimeStampOfEndMarket()
  const [selectDate, setselectDate] = useState(currentDate)

  const employeeDetails = useSelector((state: RootState) => state.jwtToken.jwtTokenData?.UserData);
  const imageCaptureLimit = 8;
  const newOutlet = useSelector((state: RootState) => state.newOutletSurvey.data);
  const surveyJson: SurveyDetail[] = newOutlet ? JSON.parse(newOutlet?.content!) : [];
  const memoizedSurveyJson = useMemo(() => surveyJson, [surveyJson]);

  const capturedImages = useSelector((state: RootState) =>
    state?.photo.data.filter(image => image.source !== 'Survey') ?? []
  );
  const [surveyResponses, setSurveyResponses] = useState<LocalSurveyResponse[]>([]);

  const [validationErrors, setValidationErrors] = useState<{ key: string; errorMessage: string; type: string; }[]>([]);

  useEffect(() => {
    return () => {
      dispatch(clearImage())
      setCapturePicture('');
    }
  }, []);

  useEffect(() => {
    if (capturedImages.length > 0) {
      setCapturePicture(capturedImages[capturedImages.length - 1].images);
    }
  }, [capturedImages]);

  useEffect(() => {
    if (memoizedSurveyJson) {
      setSteps(memoizedSurveyJson);
    }
  }, [memoizedSurveyJson]);

  const handleCapture = (imgSrc: string) => {
    const base64Image = imgSrc.replace(/^data:image/(png|jpeg);base64,/, '');
    setCapturePicture(base64Image);
    const data: PhotoModel = {
      source: "newOutletSurvey",
      images: base64Image
    };
    dispatch(addPhoto(data));
    setShowPopup(false); // Close the popup after capturing
  };

  const handleClick = () => {
    setShowPopup(true);
  };

  const closePopup = () => {
    setShowPopup(false);
  };

  const onRemoveClick = (index: number) => {
    dispatch(deleteImage(index));
  };

  const updateSurveyResponse = (questionId: string, response: LocalSurveyResponse) => {
    setSurveyResponses(prevState => {
      const existingIndex = prevState.findIndex(item => item.questionId === questionId);
      if (existingIndex !== -1) {
        return prevState.map((item, i) => (i === existingIndex ? response : item));
      } else {
        return [...prevState, response];
      }
    });
  };

  const handleSelectedDate = (date: { day: string; month: string; year: string }) => {
    const formattedDate = `${date.year}-${date.month}-${date.day}`;
    setselectDate(formattedDate);
  }

  const setSteps = (surveyData: SurveyDetail[]) => {
    const updatedSteps = surveyData.map((data, index) => {
      const questionId = `${data.type}_${index}`;
      switch (data.type) {
        case 'text':
          return (
            <div key={questionId}>
              <TextBox
                label={data.Label}
                placeholder={data.Placeholder}
                onPageChange={(text) => {
                  const newResponse: LocalSurveyResponse = {
                    questionId,
                    question: data.Label,
                    response: [text],
                    type: data.type,
                  };
                  updateSurveyResponse(questionId, newResponse);
                }}
              />
            </div>
          );
        case 'checkbox':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>
                <div className="flex flex-wrap gap-2 overflow-y-scroll no-scrollbar">
                  {data.options && data.options.map((option, optionIndex) => (
                    <div key={optionIndex}>
                      <ButtonWithText
                        isEnabled={surveyResponses.find(r => r.questionId === questionId)?.response.includes(option)}
                        // isSelected={surveyResponses.find(r => r.questionId === questionId)?.response.includes(option)}
                        label={option}
                        onClick={() => {
                          const currentResponse = surveyResponses.find(r => r.questionId === questionId)?.response || [];
                          const newResponse: LocalSurveyResponse = {
                            questionId,
                            question: data.Label,
                            response: currentResponse.includes(option)
                              ? currentResponse.filter(item => item !== option)
                              : [...currentResponse, option],
                            type: data.type,
                          };
                          updateSurveyResponse(questionId, newResponse);
                        }}
                        type={'mini'}
                      />
                    </div>
                  ))}
                </div>
              </Label>
            </div>
          );
        case 'capture':
          return (
            <div className="w-full " key={questionId}>
              <Label Label={t("Upload")}>
                {capturedImages.length === 0 && (
                  <div
                    className="font-poppins-bold rounded-lg flex items-center justify-center w-full h-24"
                    onClick={() => handleClick()}
                    style={{ backgroundImage: "url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='8' ry='8' stroke='black' stroke-width='2' stroke-dasharray='10' stroke-dashoffset='10' stroke-linecap='butt'/%3e%3c/svg%3e")" }}
                  >
                    <Icons.CAMERA_PLUS size={32} />
                  </div>
                )}
                <div className="w-full flex flex-wrap justify-space gap-3">
                  {capturedImages.length > 0 && capturedImages.length < imageCaptureLimit && (
                    <div
                      className="font-poppins-bold rounded-lg flex items-center justify-center bg-white w-24 h-24"
                      onClick={() => handleClick()}
                    >
                      <Icons.CAMERA_PLUS size={32} />
                    </div>
                  )}
                  {capturedImages.map((img: PhotoModel, i: number) => {
                    const newResponse: LocalSurveyResponse = {
                      questionId,
                      question: data.Label,
                      response: capturedImages.map(img => img.images),
                      type: data.type,
                    };
                    updateSurveyResponse(questionId, newResponse);
                    return (
                      <ButtonWithImage
                        onRemoveClick={() => onRemoveClick(i)}
                        imageUrl={`data:image//(png|jpeg|jpg);base64,${img.images}`}
                        alt={`Image ${i}`}
                        enableCloseButton={true}
                        key={i}
                      />
                    )
                  })}
                </div>
              </Label>
            </div>
          )
        case 'date':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>

                 <CalendarPicker
                  dateFormat="dd-mm-yyyy"
                  initialValue={currentDate}
                  onDateChange={(date) => {
                    handleSelectedDate(date);
                    const formattedDate = `${date.year}-${date.month}-${date.day}`;
                    const newResponse: LocalSurveyResponse = {
                      questionId,
                      question: data.Label,
                      response: [formattedDate],
                      type: data.type,
                    };
                    updateSurveyResponse(questionId, newResponse);
                  }}
                />
              </Label>
            </div>
          );
          ); default:
          return null;
      }
    });

    setStepsArray(updatedSteps.filter((step) => step !== null) as JSX.Element[]);
  };

  const handleNextClick = async () => {
    if (!newOutlet) {
      navigate('/home');
    } else {
      const currentSurveyItem = surveyJson[currentStep];
      const questionId = `${currentSurveyItem.type}_${currentStep}`;
      const currentResponse = surveyResponses.find(r => r.questionId === questionId);

      let isValid = true;
      let errorMessage = '';

      switch (currentSurveyItem.type) {
        case 'text':
          if (!currentResponse?.response[0]?.trim()) {
            isValid = false;
            errorMessage = 'The field should not be empty.';
          }
          break;
        case 'checkbox':
          if (!currentResponse?.response.length) {
            isValid = false;
            errorMessage = 'Please select at least one option.';
          }
          break;
        case 'capture':
          if (!capturedImages.length) {
            isValid = false;
            errorMessage = 'Please capture/upload a picture.';
          }
          break;
        case 'date':
          if (!currentResponse?.response[0]) {
            isValid = false;
            errorMessage = 'Please select a date.';
          }
          break;
      }

      if (!isValid) {
        setValidationErrors(prevErrors => [
          ...prevErrors.filter(e => e.key !== questionId),
          { key: questionId, errorMessage, type: currentSurveyItem.type }
        ]);
        return;
      }

      setValidationErrors(prevErrors => prevErrors.filter(e => e.key !== questionId));

      if (currentStep < stepsArray.length - 1) {
        setCurrentStep(currentStep + 1);
        dispatch(clearImage())
        setCapturePicture('');
      } else {
        const submissionResponses: GeneratedSurveyResponse[] = surveyResponses.map(({ question, response, type }) => ({
          question,
          response,
          type
        }));

        const requestData: NewOutletSurveyResponseCreateRequest = {
          surveyId: newOutlet?.id,
          surveyData: submissionResponses,
          employeeEmail: employeeDetails?.Email,
          timeStamp: getCurrentTimeStampOfEndMarket(),
          noOfQuestions: memoizedSurveyJson.length,
          noOfAnswered: surveyResponses.length,
        };
        isOnline ? dispatch(createNewOutlet(requestData)) : dispatch(setNewOutLetSurvey(requestData))
        dispatch(clearImage());
        setCapturePicture('');
        dispatch(addRoute(RouterName.SucessfullPage));
        navigate(RouterName.SucessfullPage);
      }
    }
  };

  const handlePreviousClick = () => {
    if (currentStep > 0) {
      const currentQuestionId = `${surveyJson[currentStep].type}_${currentStep}`;
      setValidationErrors(prevErrors => prevErrors.filter(e => e.key !== currentQuestionId));
      setCurrentStep(currentStep - 1);
    }
  };


  return (
    <div className="relative h-screen">
      {!showPopup && <NavigateHeader />}
      {showPopup ? (
        <CameraPopup onCapture={handleCapture} onClose={closePopup} />
      ) : (
        <>
          <Body>
            {!newOutlet ? (
              <div className="flex flex-col items-center justify-center h-full">
                <Icons.WARNING size={100} />
                <h1 className="text-2xl font-bold text-heading items-center mx-5">No survey data available.!</h1>
              </div>
            ) : (
              <>
                <div>{stepsArray[currentStep]}</div>
                {validationErrors.length > 0 && (
                  <div className="validation-errors">
                    {validationErrors.map((error, index) => (
                      <span key={index} className={`${GetStatusColor('pending')}`}>
                        {error.errorMessage}
                      </span>
                    ))}
                  </div>
                )}
              </>
            )}
          </Body>
          <div className="absolute bottom-4 right-4">
            <div className="flex justify-between items-center gap-3">
              {newOutlet && currentStep > 0 && (
                <ButtonWithIcon
                  alt="Previous"
                  color={currentStep === 0 ? 'bg-grey' : 'bg-Ash'}
                  height_and_width="h-20 w-20"
                  icon={icons.LEFT_ARROW}
                  size={36}
                  onClick={handlePreviousClick}
                />
              )}
              <ButtonWithIcon
                alt="Next"
                color="bg-Ash"
                height_and_width="h-20 w-20"
                icon={icons.RIGHT_ARROW}
                size={36}
                onClick={handleNextClick}
              />
            </div>
          </div>
        </>
      )}
      {enableGeolocation && (
        <WarningPopUp
          message={"Enable Geolocation"}
          showPopup={popup}
          onClose={() => {
            setPopup(false)
            setEnableGeolocation(false)
          }}
        />
      )}
    </div>
  );
};

export default Survey;

setStepsArray(updatedSteps.filter((step) => step !== null) as JSX.Element[]); in setSteps
is causing the component to rerender Infinitely.

how can i solve this issue

const setSteps = (surveyData: SurveyDetail[]) => {}
function is updating the setStepsArray(updatedSteps.filter((step) => step !== null) as JSX.Element[]);
infinitely

iam not able to figure out how to solve this issue

hi ia want to ask about some cods [closed]

In fact, I need a JavaScript code that enables me to edit only one user and make modifications to it. I cannot do this step unless I specify the user name, but I do not know the way that makes me translate the command to the code to target the user with this name.

Since this class is shared with all users on the site
class =”fl hand nosel uzr uhtml”
And I cannot modify it because it will modify all the backgrounds and personal colors of the users. I hope that the matter is clear.

I can use the function, but I do not know what is the correct code to give a command to target a specific user name like user=”ali”
or user=”jamy”

just that what i want to

“Something went wrong” after adding scope for Google OAuth

When I try to add a scope that has an API, I get “Google hasn’t verified the app”, which is expected because I have it set as testing, but when I click on “continue”, I get “Something went wrong”. However, if I request a scope like profile, I don’t get the “Google hasn’t verified the app” nor the “Something went wrong”, but I can continue with “Sign in to Project” with no issues. Here is a simple piece of code that doesn’t work for me:

const { OAuth2Client } = require('google-auth-library')
const express = require('express')
const dotenv = require('dotenv')

dotenv.config()

const REDIRECT_URI = 'http://localhost:3000/oauth2callback'
const oauth2Client = new OAuth2Client(process.env.CLIENT_ID, process.env.CLIENT_SECRET, REDIRECT_URI)

const getAuthUrl = () => oauth2Client.generateAuthUrl({
  access_type: 'offline',
//   scope: ['https://www.googleapis.com/auth/userinfo.profile'],
  scope: ['https://www.googleapis.com/auth/presentations'],
})

const getToken = async (code) => {
  const { tokens } = await oauth2Client.getToken(code)
  oauth2Client.setCredentials(tokens)
  return tokens
}

const app = express()

app.get('/', (req, res) => {
  const authUrl = getAuthUrl()
  res.send(`<a href="${authUrl}">Authorize</a>`)
})

app.get('/oauth2callback', async (req, res) => {
  const { code } = req.query
  try {
    const tokens = await getToken(code)
    res.send('Authentication successful! Tokens: ' + JSON.stringify(tokens))
  } catch (error) {
    res.status(400).send('Error during authentication')
  }
})

app.listen(3000, () => console.log('Server running on http://localhost:3000'))

I’ve made sure that I’ve enabled the slides API, added the scope to the OAuth consent screen, and deleting connections with my project in my app permissions. The project is in testing and is External, because I can’t make it Internal.

Creating backend for Stripe payments on AWS Lambda for iOS App

I have a Swift iOS app that works well communicating with a local server on my laptop to make Stripe payments using the below server.js code

const stripe = require('stripe')('sk_test_');
const express = require('express');
const app = express();
app.use(express.json());

app.post('/prepare-payment-sheet', async (req, res) => {
    const customer = await stripe.customers.create();
    const ephemeralKey = await stripe.ephemeralKeys.create({customer: customer.id},
                                                           {apiVersion: '2024-04-10'});
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 1099,
        currency: 'usd',
        customer: customer.id,
        automatic_payment_methods: {
            enabled: true,
        },
    });
    
    res.json({
        paymentIntentID: paymentIntent.id,
        clientSecret: paymentIntent.client_secret,
        ephemeralKey: ephemeralKey.secret,
        customer: customer.id,
        publishableKey: 'pk_test_'
    });
});

app.post('/update-payment-sheet', async (req, res) => {
    const paymentIntent = await stripe.paymentIntents.update(
        req.body.paymentIntentID,
        {
            amount: req.body.amount,
        }
    );
    console.log(req.body)
    console.log(res.body)
    
    res.json({});
});

However I cannot transfer this code to AWS Lambda and get the app to communicate between the app and the function like it does on the local server on my laptop.

Below is the code for the Lambda function that is not working in the index.mjs file. The function is setup as a Node.js 20.x file within AWS.

//export const handler = async (event) => {
  // TODO implement
const stripe = require('stripe')('sk_test_');
const express = require('express');
const app = express();
app.use(express.json());

app.post('/prepare-payment-sheet', async (req, res) => {
    const customer = await stripe.customers.create();
    const ephemeralKey = await stripe.ephemeralKeys.create({customer: customer.id},
                                                           {apiVersion: '2024-04-10'});
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 1099,
        currency: 'usd',
        customer: customer.id,
        automatic_payment_methods: {
            enabled: true,
        },
    });
    
    res.json({
        paymentIntentID: paymentIntent.id,
        clientSecret: paymentIntent.client_secret,
        ephemeralKey: ephemeralKey.secret,
        customer: customer.id,
        publishableKey: 'pk_test_'
    });
});

app.post('/update-payment-sheet', async (req, res) => {
    const paymentIntent = await stripe.paymentIntents.update(
        req.body.paymentIntentID,
        {
            amount: req.body.amount,
        }
    );
    console.log(req.body)
    console.log(res.body)
    
    res.json({});
});

 //const response = {
 // statusCode: 200,
  //  body: JSON.stringify('Hello from Lambda!'),
 // };
 // return response;
//};

Below is the Swift code to call the URL of the local server as well as the AWS Lambda function

//private let backendtUrl = URL(string: "http://localhost:4242")!
    private let backendtUrl = URL(string: "https://i7phb...q0houbc.lambda-url.us-east-2.on.aws/")!

I’ve been stuck here for days and could really use some assistance on how to convert the server.js file that works on the local server to the index.mjs file in the Lambda function

const a = false; const z = ‘false’; console.log(a === z); [closed]

The reason const a = false; const z = ‘false’; console.log(a === z); gives false is that the strict equality operator (===) checks both value and datatype. In this case, a is a boolean with the value false, while z is a string with the value ‘false’. Since their datatypes (boolean and string) do not match, the result is false. Even though both appear to represent “false,” their types differ, which makes the comparison fail. Hence, strict equality returns false when comparing them.

Too many re-renders. React limits the number of renders to prevent an infinite loop in the component

when trying to capture the image its throwing an error, Too many re-renders
the function handleCapture is rendering too many times

const Survey: React.FC = () => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const [currentStep, setCurrentStep] = useState(0);

  const [capturedPicture, setCapturePicture] = useState<string>('');
  const [showPopup, setShowPopup] = useState(false);
  const [popup, setPopup] = useState(false)
  const [loading, setLoading] = useState(false)
  const [enableGeolocation, setEnableGeolocation] = useState(false)
  const [locationFetched, setLocationFetched] = useState(false)
  const [isOnline, setIsOnline] = useState(navigator.onLine);
  const currentDate = getCurrentTimeStampOfEndMarket()
  const [selectDate, setselectDate] = useState(currentDate)

  const employeeDetails = useSelector((state: RootState) => state.jwtToken.jwtTokenData?.UserData);
  const imageCaptureLimit = 8;
  const newOutlet = useSelector((state: RootState) => state.newOutletSurvey.data);
  const surveyJson: SurveyDetail[] = newOutlet ? JSON.parse(newOutlet?.content!) : [];
  const memoizedSurveyJson = useMemo(() => surveyJson, [surveyJson]);

  const capturedImages = useSelector((state: RootState) =>
    state?.photo.data.filter(image => image.source !== 'Survey') ?? []
  );
  const [surveyResponses, setSurveyResponses] = useState<LocalSurveyResponse[]>([]);

  const [validationErrors, setValidationErrors] = useState<{ key: string; errorMessage: string; type: string; }[]>([]);

  useEffect(() => {
    return () => {
      dispatch(clearImage())
      setCapturePicture('');
    }
  }, []);



  useEffect(() => {
    if (capturedImages.length > 0) {
      setCapturePicture(capturedImages[capturedImages.length - 1].images);
    }
  }, [capturedImages]);

  const handleCapture = (imgSrc: string) => {
    try {
      const base64Image = imgSrc.replace(/^data:image/(png|jpeg);base64,/, '');
      setCapturePicture(base64Image);
      const data: PhotoModel = {
        source: "newOutletSurvey",
        images: base64Image
      };
      dispatch(addPhoto(data));
      setShowPopup(false);
    } catch (error) {
      console.error("Error in capturing image", error);
    }

  }


  const handleClick = () => {
    setShowPopup(true);
  };

  const closePopup = () => {
    setShowPopup(false);
  };

  const onRemoveClick = (index: number) => {
    dispatch(deleteImage(index));
  };

  const updateSurveyResponse = (questionId: string, response: LocalSurveyResponse) => {
    setSurveyResponses(prevState => {
      const existingIndex = prevState.findIndex(item => item.questionId === questionId);
      if (existingIndex !== -1) {
        return prevState.map((item, i) => (i === existingIndex ? response : item));
      } else {
        return [...prevState, response];
      }
    });
  };

  const handleSelectedDate = (date: { day: string; month: string; year: string }) => {
    const formattedDate = `${date.year}-${date.month}-${date.day}`;
    setselectDate(formattedDate);
  }

  const setSteps = (surveyData: SurveyDetail[]) => {
    const updatedSteps = surveyData.map((data, index) => {
      const questionId = `${data.type}_${index}`;
      switch (data.type) {
        case 'text':
          return (
            <div key={questionId}>
              <TextBox
                label={data.Label}
                placeholder={data.Placeholder}
                onPageChange={(text) => {
                  const newResponse: LocalSurveyResponse = {
                    questionId,
                    question: data.Label,
                    response: [text],
                    type: data.type,
                  };
                  updateSurveyResponse(questionId, newResponse);
                }}
              />
            </div>
          );
        case 'checkbox':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>
                <div className="flex flex-wrap gap-2 overflow-y-scroll no-scrollbar">
                  {data.options && data.options.map((option, optionIndex) => (
                    <div key={optionIndex}>
                      <ButtonWithText
                        isEnabled={surveyResponses.find(r => r.questionId === questionId)?.response.includes(option)}
                        // isSelected={surveyResponses.find(r => r.questionId === questionId)?.response.includes(option)}
                        label={option}
                        onClick={() => {
                          const currentResponse = surveyResponses.find(r => r.questionId === questionId)?.response || [];
                          const newResponse: LocalSurveyResponse = {
                            questionId,
                            question: data.Label,
                            response: currentResponse.includes(option)
                              ? currentResponse.filter(item => item !== option)
                              : [...currentResponse, option],
                            type: data.type,
                          };
                          updateSurveyResponse(questionId, newResponse);
                        }}
                        type={'mini'}
                      />
                    </div>
                  ))}
                </div>
              </Label>
            </div>
          );
        case 'radio':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>
                <div className="flex flex-wrap gap-2 overflow-y-scroll no-scrollbar">
                  {data.options && data.options.map((option, optionIndex) => (
                    <div key={optionIndex}>
                      <SurveyRadioButton
                        isEnabled={surveyResponses.find(r => r.questionId === questionId)?.response.includes(option)}
                        label={option}
                        onClick={() => {
                          const newResponse: LocalSurveyResponse = {
                            questionId,
                            question: data.Label,
                            response: [option],
                            type: data.type,
                          };
                          updateSurveyResponse(questionId, newResponse);
                        }}
                        type={'mini'}
                      />
                    </div>
                  ))}
                </div>
              </Label>
            </div>
          );
        case 'counter':
          return (
            <div key={questionId}>
              <Counter
                label={data.Label}
                value={parseInt(surveyResponses.find(r => r.questionId === questionId)?.response[0] || '0')}
                onCountChange={(newCount) => {
                  const newResponse: LocalSurveyResponse = {
                    questionId,
                    question: data.Label,
                    response: [newCount.toString()],
                    type: data.type,
                  };
                  updateSurveyResponse(questionId, newResponse);
                }}
              />
            </div>
          );
        case 'signature':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>
                <SignatureCapture
                  onSave={(image) => {
                    const base64Image = image.replace(/^data:image/(png|jpeg);base64,/, '');
                    const newResponse: LocalSurveyResponse = {
                      questionId,
                      question: data.Label,
                      response: [base64Image],
                      type: data.type,
                    };
                    updateSurveyResponse(questionId, newResponse);
                  }}
                />
              </Label>
            </div>
          );
        case 'capture':
          return (
            <div className="w-full " key={questionId}>
              <Label Label={t("Upload")}>
                {capturedImages.length === 0 && (
                  <div
                    className="font-poppins-bold rounded-lg flex items-center justify-center w-full h-24"
                    onClick={() => handleClick()}
                  style={{ backgroundImage: "url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='8' ry='8' stroke='black' stroke-width='2' stroke-dasharray='10' stroke-dashoffset='10' stroke-linecap='butt'/%3e%3c/svg%3e")" }}
                  >
                    <Icons.CAMERA_PLUS size={32} />
                  </div>
                )}
                <div className="w-full flex flex-wrap justify-space gap-3">
                  {capturedImages.length > 0 && capturedImages.length < imageCaptureLimit && (
                    <div
                      className="font-poppins-bold rounded-lg flex items-center justify-center bg-white w-24 h-24"
                      onClick={() => handleClick()}
                    >
                      <Icons.CAMERA_PLUS size={32} />
                    </div>
                  )}
                  {capturedImages.map((img: PhotoModel, i: number) => {
                    const newResponse: LocalSurveyResponse = {
                      questionId,
                      question: data.Label,
                      response: capturedImages.map(img => img.images),
                      type: data.type,
                    };
                    updateSurveyResponse(questionId, newResponse);
                    return (
                      <ButtonWithImage
                        onRemoveClick={() => onRemoveClick(i)}
                        imageUrl={`data:image//(png|jpeg|jpg);base64,${img.images}`}
                        alt={`Image ${i}`}
                        enableCloseButton={true}
                        key={i}
                      />
                    )
                  })}
                </div>
              </Label>
            </div>
          )
        case 'date':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>

                <CalendarPicker
                  dateFormat="dd-mm-yyyy"
                  initialValue={currentDate}
                  onDateChange={(date) => {
                    handleSelectedDate(date);
                    const formattedDate = `${date.year}-${date.month}-${date.day}`;
                    const newResponse: LocalSurveyResponse = {
                      questionId,
                      question: data.Label,
                      response: [formattedDate],
                      type: data.type,
                    };
                    updateSurveyResponse(questionId, newResponse);
                  }}
                />
              </Label>
            </div>
          );
        case 'locate me':
          return (
            <div key={questionId}>
              <Label Label={data.Label}>
                <div className='w-full'>
                  <ButtonWithIconAndLable
                    iconSrc={{ icon: icons.LOCATE_ME, size: 45, iconColor: '#DEB00F' } as IconProps}
                    label={t("Locate Me")}
                    onClick={async () => {
                      setLoading(true); // Set loading to true when the button is clicked
                      try {
                        const { latitude, longitude } = await GetCurrentLocation();
                        if (latitude && longitude) {
                          setLoading(false);
                          setLocationFetched(true);
                          setTimeout(() => {
                            setLocationFetched(false);
                          }, 1000);
                          const newResponse: LocalSurveyResponse = {
                            questionId,
                            question: '',
                            response: [`${latitude}, ${longitude}`],
                            type: data.type,
                          };
                          updateSurveyResponse(questionId, newResponse);
                        } else {
                          setLoading(false);
                        }
                      } catch (error) {
                        setLoading(false);
                        setPopup(true);
                        setEnableGeolocation(true);
                        console.error('Error processing:', error);
                      }
                    }}
                  />
                  {loading ? (
                    <p className='font-bold text-lg text-center text-black'>Fetching location...</p>
                  ) : (
                    locationFetched && (
                      <p className='font-bold text-lg text-center text-green-600'>Location fetched successfully</p>
                    )
                  )}
                </div>
              </Label>
            </div>
          ); default:
          return null;
      }
    });
    return updatedSteps
  };

  const steps = useMemo(() => {
    return setSteps(surveyJson);
  }, [surveyJson]);

  const handleNextClick = async () => {
    if (!newOutlet) {
      navigate('/home');
    } else {
      const currentSurveyItem = surveyJson[currentStep];
      const questionId = `${currentSurveyItem.type}_${currentStep}`;
      const currentResponse = surveyResponses.find(r => r.questionId === questionId);

      let isValid = true;
      let errorMessage = '';

      switch (currentSurveyItem.type) {
        case 'text':
          if (!currentResponse?.response[0]?.trim()) {
            isValid = false;
            errorMessage = 'The field should not be empty.';
          }
          break;
        case 'checkbox':
          if (!currentResponse?.response.length) {
            isValid = false;
            errorMessage = 'Please select at least one option.';
          }
          break;
        case 'counter':
          if (!currentResponse?.response[0] || parseInt(currentResponse.response[0]) <= 0) {
            isValid = false;
            errorMessage = 'Count should be greater than zero';
          }
          break;
        case 'upload':
          if (!capturedImages.length) {
            isValid = false;
            errorMessage = 'Please capture/upload a picture.';
          }
          break;
        case 'radio':
          if (!currentResponse?.response.length) {
            isValid = false;
            errorMessage = 'Please select an option.';
          }
          break;
        case 'signature':
          if (!currentResponse?.response.length) {
            isValid = false;
            errorMessage = 'Please provide a signature.';
          }
          break;
        case 'date':
          if (!currentResponse?.response[0]) {
            isValid = false;
            errorMessage = 'Please select a date.';
          }
          break;
        case 'locate me':
          if (!currentResponse?.response[0]) {
            isValid = false;
            errorMessage = 'Please locate your position.';
          }
          break;
      }

      if (!isValid) {
        setValidationErrors(prevErrors => [
          ...prevErrors.filter(e => e.key !== questionId),
          { key: questionId, errorMessage, type: currentSurveyItem.type }
        ]);
        return;
      }

      setValidationErrors(prevErrors => prevErrors.filter(e => e.key !== questionId));

      if (currentStep < setSteps(surveyJson).length - 1) {
        setCurrentStep(currentStep + 1);
        dispatch(clearImage())
        setCapturePicture('');
      } else {
        const submissionResponses: GeneratedSurveyResponse[] = surveyResponses.map(({ question, response, type }) => ({
          question,
          response,
          type
        }));

        const requestData: NewOutletSurveyResponseCreateRequest = {
          surveyId: newOutlet?.id,
          surveyData: submissionResponses,
          employeeEmail: employeeDetails?.Email,
          timeStamp: getCurrentTimeStampOfEndMarket(),
          noOfQuestions: memoizedSurveyJson.length,
          noOfAnswered: surveyResponses.length,
        };
        isOnline ? dispatch(createNewOutlet(requestData)) : dispatch(setNewOutLetSurvey(requestData))
        dispatch(clearImage());
        setCapturePicture('');
        dispatch(addRoute(RouterName.SucessfullPage));
        navigate(RouterName.SucessfullPage);
      }
    }
  };

  const handlePreviousClick = () => {
    if (currentStep > 0) {
      const currentQuestionId = `${surveyJson[currentStep].type}_${currentStep}`;
      setValidationErrors(prevErrors => prevErrors.filter(e => e.key !== currentQuestionId));
      setCurrentStep(currentStep - 1);
    }
  };
  console.log('surveyJson', surveyJson)

  return (
    <div className="relative h-screen">
      {!showPopup && <NavigateHeader />}
      {showPopup ? (
        <CameraPopup onCapture={handleCapture} onClose={closePopup} />
      ) : (
        <>
          <Body>
            {!newOutlet ? (
              <div className="flex flex-col items-center justify-center h-full">
                <Icons.WARNING size={100} />
                <h1 className="text-2xl font-bold text-heading items-center mx-5">No survey data available.!</h1>
              </div>
            ) : (
              <>
                <div>{steps[currentStep]}</div>
                {validationErrors.length > 0 && (
                  <div className="validation-errors">
                    {validationErrors.map((error, index) => (
                      <span key={index} className={`${GetStatusColor('pending')}`}>
                        {error.errorMessage}
                      </span>
                    ))}
                  </div>
                )}
              </>
            )}
          </Body>
          <div className="absolute bottom-4 right-4">
            <div className="flex justify-between items-center gap-3">
              {newOutlet && currentStep > 0 && (
                <ButtonWithIcon
                  alt="Previous"
                  color={currentStep === 0 ? 'bg-grey' : 'bg-Ash'}
                  height_and_width="h-20 w-20"
                  icon={icons.LEFT_ARROW}
                  size={36}
                  onClick={handlePreviousClick}
                />
              )}
              <ButtonWithIcon
                alt="Next"
                color="bg-Ash"
                height_and_width="h-20 w-20"
                icon={icons.RIGHT_ARROW}
                size={36}
                onClick={handleNextClick}
              />
            </div>
          </div>
        </>
      )}
      {enableGeolocation && (
        <WarningPopUp
          message={"Enable Geolocation"}
          showPopup={popup}
          onClose={() => {
            setPopup(false)
            setEnableGeolocation(false)
          }}
        />
      )}
    </div>
  );
};

export default Survey;

when trying to capture an image the handleCapture function is throwing an error

import React, {  useRef, useState } from 'react';
import { FiCamera, FiRefreshCw } from 'react-icons/fi';
import { AiOutlineFullscreenExit } from 'react-icons/ai';
import Webcam from 'react-webcam';

interface CameraPopupProps {
    onClose: () => void;
    onCapture?: (imageBase62: string) => void;
}
const CameraPopup: React.FC<CameraPopupProps> = ({ onClose , onCapture }) => {
    const webcamRef = useRef<Webcam | null>(null);
    const [facingMode, setFacingMode] = useState('environment');

    const capture = () => {
        if (webcamRef.current) {
            const newImageSrc = webcamRef.current.getScreenshot();
            if (newImageSrc) {
                onCapture && onCapture(newImageSrc); // Pass newImageSrc to onCapture callback
                onClose();
            } else {
                console.error("Failed to capture image."); // Log error if image capture fails
            }
        } else {
            console.error("Webcam reference is not available."); // Log error if webcam reference is not available
        }
    };
    
    const switchCamera = () => {
        setFacingMode(prevMode => (prevMode === 'user' ? 'environment' : 'user'));
    };

    const isMirrored = facingMode === 'user';

    return (
        <div className="z-index popup z-50">
            <div className="popup-inner">   
                <div className="w-[dvw] h-[dvh] bg-Ash relative">
                    <Webcam
                        mirrored={isMirrored}
                        audio={false}
                        ref={webcamRef}
                        screenshotFormat="image/jpeg"
                        videoConstraints={{ facingMode }}
                        style={{ width: '100dvh', height: '100dvh', objectFit: 'contain' }}
                    />
                    <div className="flex justify-around">
                        <button onClick={capture} className="absolute bottom-4 right-auto bg-white p-2 rounded-full">
                            <FiCamera size={24} color="#000" />
                        </button>
                        <button onClick={switchCamera} className="absolute bottom-4 left-4 bg-white p-2 rounded-full">
                            <FiRefreshCw size={24} color="#000" />
                        </button>
                        <button onClick={onClose} className="absolute bottom-4 right-4 bg-white p-2 rounded-full">
                            <AiOutlineFullscreenExit  size={24} color="#000" />
                        </button>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default CameraPopup;

how can i fix this issue

i have tried to use callback, but becouse the imgSrc on handleCapture is comming from capture function in CameraPopup its throwing an error
<CameraPopup onCapture={()=>handleCapture()} onClose={closePopup} />

Uncaught TypeError: type.getCollectionNode is not a function when using `DropdownSection` in NextUI with a custom component

I’m new to React and am using the NextUI library for my project. I want to create a custom function component, ProfDropdownItem, to render multiple DropdownSection components within a DropdownMenu. However, I’m encountering an error:

Uncaught TypeError: type.getCollectionNode is not a function

Here’s the code that is causing the issue:

import React from 'react';
import { Dropdown, DropdownTrigger, DropdownMenu, DropdownSection, DropdownItem, Avatar } from '@nextui-org/react';

const ProfDropdownItem = () => {
  return (
    <DropdownSection title="Actions" showDivider>
      <DropdownItem key="new" shortcut="⌘N" description="Create a new file">
        New file
      </DropdownItem>
      <DropdownItem key="copy" shortcut="⌘C" description="Copy the file link">
        Copy link
      </DropdownItem>
      <DropdownItem
        key="edit"
        shortcut="⌘⇧E"
        description="Allows you to edit the file"
      >
        Edit file
      </DropdownItem>
    </DropdownSection>
  );
};

const TopBar = () => {
  return (
    <Dropdown placement="bottom-end">
      <DropdownTrigger>
        <Avatar
          isBordered
          as="button"
          className="transition-transform"
          color="secondary"
          name="User Name"
          size="sm"
          src="profilePhotoURL"
        />
      </DropdownTrigger>
      <DropdownMenu aria-label="Profile Actions" variant="flat">
        <ProfDropdownItem />
      </DropdownMenu>
    </Dropdown>
  );
};

export default TopBar;

I’m trying to build a dockerfile, make an image and run it in a container; but i’m getting errors [closed]

This is the code I ran to try to build the container.

This is my terminal

docker build -t mynode-app:1.0 .

This is my server.js file.

This is the server.js file

const express = require('express');
const app = express();

app.get('/', (req,res)=>{
    res.send("welcome my boy to the app");
});

app.listen(3000, function (){
    console.log("app listening on port 3000");
});

This is the package.json file that has dependencies.

This the package.json file

{
    "name": "my-app",
    "version": "1.0",
    "dependencies": {
        "express": "4.18.2"
    }
}