Why do not working botton Save Position on an opencart site?

Good day everybody, I can not push to work the botton ‘Save Position’ on an opencart site. Zero reactions. Another bottons on the page are working. What I do wrong?

Thanks in advance for helping.

Script image

Botton code. File: systemconfigrevslideradminviewstemplateoc_layout.php

 <form action="<?php //echo $action; ?>" enctype="multipart/form-data" id="sds_rev_mod_form" method="post">


    <td class="right"><a id="sds_rev_save_mod" href="javascript:void(0)" class="button-primary revblue"><?php echo ControllerModulerevslideropencart::

$lang_var['sds_Save_Position']?></a><span style="display:none;" class="loader_round" id="sds_rev_save_mod_loader">updating... </span><span id="sds_rev_save_mod_success" class="success_message"></span></td>
              <td class="left"><a onclick="addModule();" class="button-primary revgreen"><?php echo ControllerModulerevslideropencart::

$lang_var['sds_Add_New']?></a></td>

For showing script I connected it in file – systemconfigrevslideradminviewsslider-overview.php

<?php
if(!empty($arrSliders)):
    require self::getPathTemplate("oc_layout");
endif;  
?>

JS code. File: systemconfigrevslideradminassetsjsrev_admin.js

Looks like this part not working:

//start save rev slider module position value
var initposvalSliderButton = function(ajaxAction){
    jQuery("#sds_rev_save_mod").click(function(){

    var data = UniteSettingsRev.getsdsformvalue("sds_rev_mod_form");
        

        // data = $('form#sds_rev_mod_form').serializeArray();

        
        if(ajaxAction == "add_slider_pos_val"){
            UniteAdminRev.setAjaxLoaderID("sds_rev_save_mod_loader");
            UniteAdminRev.setAjaxHideButtonID("sds_rev_save_mod");
            UniteAdminRev.setSuccessMessageID("sds_rev_save_mod_success");
        }
        UniteAdminRev.ajaxRequest(ajaxAction ,data);
    });
};
//end save rev slider module position value


// start
jQuery("#sds_rev_save_mod").click(function(){
initposvalSliderButton("add_slider_pos_val");
});
// end

I did some trials but no result…

Firebase: Why is my email verification not being sent?

I am trying to sendEmailVerification using Firebase but it’s failing.

const handleSubmit = (e) => {
    e.preventDefault();
    fetch("http://localhost:4000/auth/register", {
      method: "POST",
      body: JSON.stringify({
        email,
        password,
      }),
      headers: {
        "Content-Type": "application/json",
      },
    })
    .then((res) => {
            return res.json()
    }).then((data) => {
        signInWithEmailAndPassword(auth, email, password);
    }).then(() => {
        console.log("data", auth.currentUser)
        sendEmailVerification(auth.currentUser)
        .then(() => {
            navigate('/')
        })

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

It seems like there’a delay to sendEmailVerification. If I sign up user1, no email verification is sent, but after I sign up user2, user1 email is then sent. Why is there a delay? I want the user email verification to be immediately sent after registration.

I have to put a semicolon on every line of js? [duplicate]

when I remove the semicolon on the 3rd line my javascript code breaks and I get this error “ReferenceError: Cannot access ‘updatedTasks’ before initialization
at moveTaskUp”.I always thought that JavaScript’s automatic semicolon insertion always worked

    function moveTaskUp(index){
        if(index>0){
            const updatedTasks=[...tasks];
            [updatedTasks[index],updatedTasks[index - 1]]=[updatedTasks[index-1],updatedTasks[index]]
            setTasks(updatedTasks)
        }
    }

I guess I’m put a semicolon on every line of js from now on

How to add an aud claim to a Microsoft Entra ID JWT

I am using Microsoft Identity Platform with Microsoft Entra to manage user authentication and authorization within a single tenant [web] app, and I would like to use it as an external access provider to a 3rd party database — faunaDB.

The problem is Fauna expects a JWT token with a given audience like https://db.fauna.com/db/xxxx... but msal id and access tokens audiences are a single string value of the application ID and I cannot seem to append anymore.


The documentation for fauna says that

the aud claim must be configurable

is this not the case for Microsoft Entra JWTs? Or am I going about adding the aud wrong, should I be creating a new JWT with msal/MS Entra?


  • I have tried adding an optional claim aud from the entrprise application -> single sign-on page to append an audience claim, but the aud claim is restricted.
  • I tried using the audOverride optional claim but this caused the received JWT from the msal login redierct not to be accepted as it replaced the previous aud claim instead appending my override, or simply added audienceOverride field to the JWT
  • I also tried to change the application URI ID to the neeeded audience claim by fauna (since that is used the aud claim value), for example https://db.fauna.com/db/xxxx... but I receive an error since the domain is not a sub-domain nor registered with my tenant

(the web app is built with gatsbyJS and using the msal-react and browser packages)

Frontend does not show working correctly when uploading to a server from visual studio code in Java

It works locally perfectly, when I upload it to the server it loads fine but it has no functionality, the APIs are in status 200 and I don’t get any errors

–Dockerfile frontend (GVisorSiam)
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline

COPY src ./src

RUN mvn clean package

FROM tomcat:9.0-jdk11-openjdk

RUN sed -i ‘s/port=”8080″/port=”1090″/’ /usr/local/tomcat/conf/server.xml

COPY –from=build /app/target/GVisorSiam-1.0.war /usr/local/tomcat/webapps/ROOT.war

RUN mkdir -p /usr/local/tomcat/logs &&
chmod -R 777 /usr/local/tomcat/logs

EXPOSE 1090

CMD [“catalina.sh”, “run”]

–Dockerfile BACKEND (clases)

FROM maven:3.8.4-openjdk-17 AS build
WORKDIR /app

COPY pom.xml .

RUN mvn dependency:go-offline

COPY src ./src

RUN mvn clean package

CMD [“java”, “-jar”, “/app/target/clases-0.0.1-SNAPSHOT.jar”]

–docker-compose

version: ‘3.8’
services:
clases:
build:
context: ./clases
dockerfile: Dockerfile
image: backendgvsiam
container_name: backendgeovisorsiam
environment:
TZ: America/Bogota
CHOKIDAR_USEPOLLING: “true”
ports:
– “8081:8081”
GVisorSiam:
build:
context: ./GVisorSiam
dockerfile: Dockerfile
image: frontendgvsiam
container_name: frontendgeovisorsiam
environment:
TZ: America/Bogota
CHOKIDAR_USEPOLLING: “true”
ports:
– “1090:1090”

How can I create MediaStream or MediaTrack from a downloaded mp3 audio?

I need to download an mp3 file from a server and pass audiostream to webrtc peer.
To do that I was trying to create MediaStream, but I have failed.

I have got an error in this line:

let newStream = newAudio.captureStream(); // ERROR here:
// TypeError: newAudio.captureStream is not a function

My code is as followed.

How can I get mediastream or track from an audio blob ?

function getFileFromServer(httpAddress) {
    let resp = fetch(httpAddress).then(getFile_Fulfilled, blob_Rejected);
    return;

} // function getFileFromServer(httpAddress)

function getFile_Fulfilled(response) {


    if (response.ok) {

        let fileBlob = response.blob();
        fileBlob.then(
            function blob_Fulfilled(f_blob) {

                // OK here

                let blobURL = URL.createObjectURL(f_blob);

                // OK here

                try {
                    let newAudio = new Audio(blobURL);
                    newAudio.autoplay = false;
                    // newAudio.play();

                    console.log("--- newAudio ---");
                    console.log(newAudio);

                // Audio created - OK

                    let newStream = newAudio.captureStream(); // ERROR here:
                    // TypeError: newAudio.captureStream is not a function

                }
                catch(e) {
                    console.log(e);
                }
            } // function blob_Fulfilled()
            ,
            function blob_Rejected(e) {

                console.log(e);

            } // function blob_Rejected()
        ); //let fileBlob =
    }
}

How to perform Faster Object detection on webcam using onnx runtime web?

This is the javascript script which is performing object detection accurately but processing is taking time which creates lags in frames.There is no smoothness in it.

This is the script from some code I followed.

<script>
    var video_Element = document.getElementById("videoElement");
    var session = null;
    var arraybuffer = null;
    var modelPromise = null;

    async function fillarraybuffer() {
        var modelPath = "api/Models/TestSeven";
        console.log(`Loading model from ${modelPath}`);

        try {
            var response = await fetch(modelPath);
            if (!response.ok) {
                throw new Error(`Failed to fetch model from ${modelPath}: ${response.statusText}`);
            }
            arraybuffer = await response.arrayBuffer();
            //modelPromise = ort.InferenceSession.create(arraybuffer);

            modelPromise = ort.InferenceSession.create(arraybuffer, {
                executionProviders: ['wasm'],
                wasmPaths: {
                    'ort-wasm.wasm': 'js/ort-wasm.wasm',
                    'ort-wasm-simd.wasm': 'js/ort-wasm-simd.wasm',
                    'ort-wasm-simd-threaded.wasm': 'js/ort-wasm-threaded.wasm'
                }
            });
        } catch (error) {
            console.error("Error loading model:", error);
        }
    }

    fillarraybuffer();

    navigator.mediaDevices.getUserMedia({ video: true })
        .then(stream => {
            video_Element.srcObject = stream;
        })
        .catch(error => {
            console.error("Error accessing webcam:", error);
        });

    var detectButton = document.getElementById("detectButton");

    detectButton.addEventListener("click", async () => {
        detectButton.disabled = true;
        const canvas = document.createElement("canvas");
        canvas.width = video_Element.videoWidth;
        canvas.height = video_Element.videoHeight;
        var ctx = canvas.getContext("2d");



        const detectFrame = async () => {

            ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
            const imageBlob = await new Promise(resolve => canvas.toBlob(resolve, 'image/jpeg'));
            const boxes = await detect_objects_on_image(imageBlob);
            draw_image_and_boxes(imageBlob, boxes);

            requestAnimationFrame(detectFrame); // Detect objects in the next frame
        };

        detectFrame();

        // var lastFrameTime = 0;
        // //1700 best so far
        // var frameDelay = 1200; // Delay in milliseconds between frames

       
        // var detectFrame = async (timestamp) => {
        //     if (timestamp - lastFrameTime < frameDelay) {
        //         requestAnimationFrame(detectFrame);
        //         return;
        //     }
        //     lastFrameTime = timestamp;

        //     ctx.drawImage(video_Element, 0, 0, canvas.width, canvas.height);
        //     var imageBlob = await new Promise(resolve => canvas.toBlob(resolve, 'image/jpeg'));
        //     var boxes = await detect_objects_on_image(imageBlob);
        //     draw_image_and_boxes(imageBlob, boxes);

        //     requestAnimationFrame(detectFrame);
        // };

        // requestAnimationFrame(detectFrame);
    });

    function draw_image_and_boxes(file, boxes) {
        console.log("Drawing image and boxes");
        var img = new Image();
        img.src = URL.createObjectURL(file);
        img.onload = () => {
            var canvas = document.querySelector("canvas");
            canvas.width = img.width;
            canvas.height = img.height;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(img, 0, 0);
            ctx.strokeStyle = "#00FF00";
            ctx.lineWidth = 3;
            ctx.font = "18px serif";
            boxes.forEach(([x1, y1, x2, y2, label]) => {
                ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
                ctx.fillStyle = "#00FF00";
                var width = ctx.measureText(label).width;
                ctx.fillRect(x1, y1, width + 10, 25);
                ctx.fillStyle = "#000000";
                ctx.fillText(label, x1, y1 + 18);
            });
        };
    }

    async function detect_objects_on_image(buf) {
        try {
            var [input, img_width, img_height] = await prepare_input(buf);
            var output = await run_model(input);
            return process_output(output, img_width, img_height);
        } catch (error) {
            console.error("Error detecting objects:", error);
            return [];
        }
    }

    async function prepare_input(buf) {
        return new Promise(resolve => {
            var img = new Image();
            img.src = URL.createObjectURL(buf);
            img.onload = () => {
                var [img_width, img_height] = [img.width, img.height];
                var canvas = document.createElement("canvas");
                canvas.width = 640;
                canvas.height = 640;
                var context = canvas.getContext("2d");
                context.drawImage(img, 0, 0, 640, 640);
                var imgData = context.getImageData(0, 0, 640, 640);
                var pixels = imgData.data;

                var red = [], green = [], blue = [];
                for (let index = 0; index < pixels.length; index += 4) {
                    red.push(pixels[index] / 255.0);
                    green.push(pixels[index + 1] / 255.0);
                    blue.push(pixels[index + 2] / 255.0);
                }
                var input = [...red, ...green, ...blue];
                resolve([input, img_width, img_height]);
            };
        });
    }

    async function run_model(input) {
        try {
            var model = await modelPromise;
            input = new ort.Tensor(Float32Array.from(input), [1, 3, 640, 640]);
            var outputs = await model.run({ images: input });
            return outputs["output0"].data;
        } catch (error) {
            console.error("Error running model:", error);
            return [];
        }
    }



     function process_output(output, img_width, img_height) {
        let boxes = [];
        for (let index = 0; index < 8400; index++) {
            var [class_id, prob] = [...Array(80).keys()]
                .map(col => [col, output[8400 * (col + 4) + index]])
                .reduce((accum, item) => item[1] > accum[1] ? item : accum, [0, 0]);
            if (prob < 0.5) continue;
            var label = yolo_classes[class_id];
            var xc = output[index];
            var yc = output[8400 + index];
            var w = output[2 * 8400 + index];
            var h = output[3 * 8400 + index];
            var x1 = (xc - w / 2) / 640 * img_width;
            var y1 = (yc - h / 2) / 640 * img_height;
            var x2 = (xc + w / 2) / 640 * img_width;
            var y2 = (yc + h / 2) / 640 * img_height;
            boxes.push([x1, y1, x2, y2, label, prob]);
        }

        boxes = boxes.sort((box1, box2) => box2[5] - box1[5]);
        var result = [];
        while (boxes.length > 0) {
            result.push(boxes[0]);
            boxes = boxes.filter(box => iou(boxes[0], box) < 0.7);
        }
        console.log(result);
        return result;
    }



    function iou(box1, box2) {
        return intersection(box1, box2) / union(box1, box2);
    }

    function union(box1, box2) {
        var [box1_x1, box1_y1, box1_x2, box1_y2] = box1;
        var [box2_x1, box2_y1, box2_x2, box2_y2] = box2;
        var box1_area = (box1_x2 - box1_x1) * (box1_y2 - box1_y1);
        var box2_area = (box2_x2 - box2_x1) * (box2_y2 - box2_y1);
        return box1_area + box2_area - intersection(box1, box2);
    }

    function intersection(box1, box2) {
        var [box1_x1, box1_y1, box1_x2, box1_y2] = box1;
        var [box2_x1, box2_y1, box2_x2, box2_y2] = box2;
        var x1 = Math.max(box1_x1, box2_x1);
        var y1 = Math.max(box1_y1, box2_y1);
        var x2 = Math.min(box1_x2, box2_x2);
        var y2 = Math.min(box1_y2, box2_y2);
        return (x2 - x1) * (y2 - y1);
    }

    var yolo_classes = [
        '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', 'kwh'
    ];
</script>

The problem is there is a slight lag or no smoothness in frames.

The good is that it detects and accuracy is great to 90+ percent.

For faster frames I tried worker on it. Where webcam run normally but drawing boxes were drawn on updated frames not the frames at input time. Worker visually presents slow drawn bounding boxes and bring accuracy at 80.

Just an example be if object is at X axis = 10 and passed as input after slow performing it detects with boxes at X= 10 but the object has slightly moved to X axis= 12 or 13 due to constantly updates of frames which bounding boxes processing is done on.

Can functions of his code be made more efficient so no lags occurs. Also tried intervals for processing but did not work too.

ReactJS – To determine if useEffect is necessary in the TableCellComponent

I am working on the ReactJS Project and I want to know if useEffect and useState in this case is necessary or if you have any logic explanation for this component:
I have component TableCellComponent that receive a value as props and this value can be primitive and non-primitive ,I use function to switch and then return the element. in this case is useEffect and useState is good solution or just using a function that render the element it sufficient ?

const TableCellComponent = ({ value }: { value: any }) => {
  const renderValue = (value: any) => {
    switch (value) {
      case typeof value === "number":
        return <h1>number</h1>;
      case typeof value === "object" && Array.isArray(value):
        return <h1>Array</h1>;
    }
  };

  return <td>{renderValue(value)}</td>;
};

export default TableCellComponent;

Can a website like Fiverr.com detect Tempermonkey script? [closed]

I am applying CSS script using GM_addStyle on fiverr seller dashboard to hide the balance.

(function() {
    'use strict';

    // Add CSS styles for blur effect
    GM_addStyle(`
        li.display-from-sm a.user-balance {
            filter: blur(5px); /* Apply blur */
            transition: filter 0.3s; /* Smooth transition */
        }
        li.display-from-sm a.user-balance:hover {
            filter: blur(0); /* Remove blur on hover */
        }
    `); })();

My question does it detectable by the admin of the website? or violates any term?

Highcharts: addSeries() in 2nd drilldown level not working

I have a barchart with 3 levels (2 drilldown levels), which works perfectly. Now I want to add a linechart to the third level, which I’m doing by using the drilldown event. So I have a counter (“betriebskostendrill”) and when that counter is on 2, which means that I’m on the last level of my data I use the addSeries() function to add the new series to my chart. Unfortunately this does not work. I can see all the debug logs in the console, which means the addseries function gets called, but I still don’t see it in my chart.

The strange thing is, that if I call the addSeries() function on the first or second level it works perfectly fine.

The data for the chart is a series, which has a drilldown series, and that drilldown series has another series, which gives my 3 levels of barcharts and that works. Only the linechart won’t show on the third level.

Do you guys have any ideas what the problem could be?

var betriesbkostenData = JSON.parse(args.betriebskosten);

    Highcharts.chart('betriebskostendiv', {
        chart: {
            type: 'pie',
            backgroundColor: '#EFF7FF',
            events: {
                drilldown: function(e) {
                        this.setTitle({text: 'Betriebskostenquote'});
                        betriebskostendrill++;

                        if(betriebskostendrill === 2) {
                            var chart = $('#betriebskostendiv').highcharts();
                            chart.addSeries({
                                name: 'Added',
                                data: [1, 2, 3],
                                type: 'line'
                            });
                            console.log('drilldown called...');
                            /*var b = document.getElementById("button");
                            b.click();*/
                        }
                        console.log(betriebskostendrill);
                },
                drillup: function(e){
                    betriebskostendrill--;
                    console.log(betriebskostendrill);
                    if (betriebskostendrill===1){
                        this.setTitle({text: 'Betriebskostenquote'});
                        removelinedata('#betriebskostendiv');
                    }
                }
            }
        },
        title: {
            text: 'Betriebskostenquote'
        },
        xAxis: {
            type: 'category',
            lineWidth: 0    //for drillup bug
        },
        yAxis: {
            title: {
                text: ""
            }
        },
        plotOptions:{
            series: {
                cursor: 'pointer',
                point: {
                    events: {
                        click: function (event) {
                            if (this.name != null) {
                                if (this.options.url!=null){
                                    window.open(this.options.url);
                                }
                            }
                        }
                    }
                },
                minPointLength: 3
            },
            pie: {
                dataLabels: {
                    style: {
                        fontSize: '15px'
                    }
                }
            }
        },
        tooltip: {
            shared: true,
            useHTML: true,
            formatter: function () {
                switch (betriebskostendrill){
                    case 0: {
                        //return '<span style="color:{'+this.point.color+'}">'+this.point.name+'</span>: <b>'+this.point.y+'</b><br/>';
                    }
                    case 1:
                    case 2:{
                        /*var quote = this.points[0].y;
                        var umsatz = this.points[0].total;
                        var betriebskosten = this.points[0].percentage;
                        var tooltipMarkup = "";
                        tooltipMarkup += 'Betriebskostenquote: <b>'+Highcharts.numberFormat(quote, 2)+'%</b></br>';
                        tooltipMarkup += 'Betriebskosten: <b>€ '+Highcharts.numberFormat(betriebskosten, 0)+'</b></br>';
                        tooltipMarkup += 'Umsatz: <b>€ '+Highcharts.numberFormat(umsatz, 0)+'</b></br>';
                        return tooltipMarkup;*/
                    }
                }
            }
        },
        series: betriesbkostenData.series,
        drilldown: betriesbkostenData.drilldown,
        credits: {
            enabled: false
        },
        exporting:{
            url:'https://export.highcharts.com/'
        }
    });```

How to import a list of icons as array in Angular using Typescript

I’m working in Angular.
And I import a lot of icons one by one.
I want to import all one time for all as an array using typescript.

[OK]

import { Icon1, Icon2, Icon3, ... } from '@myLibrary/icons';
const icons: IconDefinition[] = [Icon1, Icon2, Icon2, ...];

[KO]

import * as myLibraryIcons from '@library/icons';
const icons: IconDefinition[] = myLibraryIcons; // as an array

[Error]

Type 'typeof import("@myLibrary/icons")' is missing the following properties from type
'IconDefinition[]': length, pop, push, concat, and 29 more.```

Repeated button appears despite no code for it

I have this code where it’s supposed to save an rgb combination to the database. A next button appears when i start entering the sequence and another one appears after i click confirm.

A screenshot was taken while entering the sequence

This is afterwards

A screenshot after i clicked confirm

Here is the functions that handle confirmation:

ConfirmSequence (): (runs when clicking confirm)

window.confirmSequence = function () {
  const form = document.getElementById('clickForm');
 const formData = new FormData(form);
  fetch('save_sequence.php', {
       method: 'POST',
       body: formData
        })
        .then(response => response.json())
   .then(data => {
    const responseDiv = document.getElementById('sequenceDisplay');
    if (data.status === 'success') {
     responseDiv.innerHTML = `<p>${data.message}</p><button onclick="window.location.href='${data.next}'">Next</button>`;
     document.getElementById('confirmationButtons').style.display = 'none';
     } else {
      responseDiv.innerHTML = `<p>${data.message}</p>`;
                }
           })

Confirmation buttons part in the html page:

 <div id="confirmationButtons" style="display: none;">
            <input type="button" value="Confirm" onclick="confirmSequence()">
            <button onclick="reenterSequence()">Re-enter</button>
        </div>

I tried deleting a button from the relevant php page but that didn’t work.

Ramped slow motion in a html5 video in Safari

As you can check here https://hyperaud.io/lab/pbr-test/ with any browser except Safari you can modify plabackRate without video playing interruptions.

In Safari seems every time you modify playbackrate video is rebuferring (making a 0.5 seconds pause)

I would change video.playbackRate every 50ms to show a ramped slow motion or progressive slow motion of the video.

This javascript code does the job, but, unfortunately is not working in Safari (iOS or MacOS)

var rint=null;
function iniramp(){
//pt is the central time point where make the ramped slow motion
    var sr=pt-1.5,er=pt+1.5; 
    if(sr<0)sr=0;
//et is end time of video
    if(er>et)er=et;
    video.currentTime=sr;
    video.playbackRate=0.98;
    rint=setInterval(function(){doramp(sr,er)},50);
    if (video.paused) video.play();
}


function doramp(sr,er){
    var p,step=0.02,pbr=video.playbackRate,minrate=0.25,ct=parseFloat(video.currentTime);
    if (pbr<0.5)step=0.01;
    if (ct<pt){
        p=pbr-step;
        if(p<minrate)p=minrate;
    } else {
        p=pbr+step;
        if(p>1)p=1;
        if (ct>er){endramp();iniramp();return false;}
    }
    video.playbackRate=p;
}

Any ideas for Safari?

React / API route is unable to post the form data

I have an Add Product form. In this form, there is an Upload Image field to upload jpg and png from your computer. Anyway it doesn’t work and products get uploaded without image. My aim is to convert it to a URL field which I can paste product image URLs.

You can find the code snippets from before I started working on below.

Client side AddProduct.js component:

const AddProduct = props => {
  const {
    user,
    productFormData,
    formErrors,
    productChange,
    addProduct,
    brands,
    image
  } = props;

  const handleSubmit = event => {
    event.preventDefault();
    addProduct();
  };

  return (
    <div className='add-product'>
      <form onSubmit={handleSubmit} noValidate>
        <Row>
          <Col xs='12' lg='6'>
            <Input
              type={'text'}
              error={formErrors['sku']}
              label={'Sku'}
              name={'sku'}
              placeholder={'Product Sku'}
              value={productFormData.sku}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' lg='6'>
            <Input
              type={'text'}
              error={formErrors['name']}
              label={'Name'}
              name={'name'}
              placeholder={'Product Name'}
              value={productFormData.name}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' md='12'>
            <Input
              type={'textarea'}
              error={formErrors['description']}
              label={'Description'}
              name={'description'}
              placeholder={'Product Description'}
              value={productFormData.description}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' lg='6'>
            <Input
              type={'number'}
              error={formErrors['quantity']}
              label={'Quantity'}
              name={'quantity'}
              decimals={false}
              placeholder={'Product Quantity'}
              value={productFormData.quantity}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' lg='6'>
            <Input
              type={'number'}
              error={formErrors['price']}
              label={'Price'}
              name={'price'}
              min={1}
              placeholder={'Product Price'}
              value={productFormData.price}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' md='12'>
            <SelectOption
              error={formErrors['taxable']}
              label={'Taxable'}
              name={'taxable'}
              options={taxableSelect}
              value={productFormData.taxable}
              handleSelectChange={value => {
                productChange('taxable', value);
              }}
            />
          </Col>

          <Col xs='12' md='12'>
            <SelectOption
              disabled={user.role === ROLES.Merchant}
              error={formErrors['brand']}
              name={'brand'}
              label={'Select Brand'}
              value={
                user.role === ROLES.Merchant ? brands[1] : productFormData.brand
              }
              options={brands}
              handleSelectChange={value => {
                productChange('brand', value);
              }}
            />
          </Col>

          <Col xs='12' md='12'>
            <Input
              type={'file'}
              error={formErrors['file']}
              name={'image'}
              label={'file'}
              placeholder={'Please Upload Image'}
              value={image}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

          <Col xs='12' md='12' className='my-2'>
            <Switch
              id={'active-product'}
              name={'isActive'}
              label={'Active?'}
              checked={productFormData.isActive}
              toggleCheckboxChange={value => productChange('isActive', value)}
            />
          </Col>
        </Row>

Client side Input.js component:

  const _onChange = e => {
    if (e.target.name == 'image') {
      onInputChange(e.target.name, e.target.files[0]);
    } else {
      onInputChange(e.target.name, e.target.value);
    }
  };

Client side Product reducer:

const initialState = {
  products: [],
  storeProducts: [],
  product: {
    _id: ''
  },
  storeProduct: {},
  productsSelect: [],
  productFormData: {
    sku: '',
    name: '',
    description: '',
    quantity: 1,
    price: 1,
    image: {},
    isActive: true,
    taxable: { value: 0, label: 'No' },
    brand: {
      value: 0,
      label: 'No Options Selected'
    }
  },
  isLoading: false,
  productShopData: {
    quantity: 1
  },
  formErrors: {},
  editFormErrors: {},
  shopFormErrors: {},
};

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    // ... Other cases
    case ADD_PRODUCT:
      return {
        ...state,
        products: [...state.products, action.payload]
      };
    case RESET_PRODUCT:
      return {
        ...state,
        productFormData: {
          sku: '',
          name: '',
          description: '',
          quantity: 1,
          price: 1,
          image: {},
          isActive: true,
          taxable: { value: 0, label: 'No' },
          brand: {
            value: 0,
            label: 'No Options Selected'
          }
        },
        product: {
          _id: ''
        },
        formErrors: {}
      };
    default:
      return state;
  }
};

export default productReducer;

Client side Product actions:

export const addProduct = () => {
  return async (dispatch, getState) => {
    try {
      const rules = {
        sku: 'required|alpha_dash',
        name: 'required',
        description: 'required|max:200',
        quantity: 'required|numeric',
        price: 'required|numeric',
        taxable: 'required',
        image: 'required',
        brand: 'required'
      };

      const product = getState().product.productFormData;
      const user = getState().account.user;
      const brands = getState().brand.brandsSelect;

      const brand = unformatSelectOptions([product.brand]);

      const newProduct = {
        sku: product.sku,
        name: product.name,
        description: product.description,
        price: product.price,
        quantity: product.quantity,
        image: product.image,
        isActive: product.isActive,
        taxable: product.taxable.value,
        brand:
          user.role !== ROLES.Merchant
            ? brand !== 0
              ? brand
              : null
            : brands[1].value
      };

      const { isValid, errors } = allFieldsValidation(newProduct, rules, {
        'required.sku': 'Sku is required.',
        'alpha_dash.sku':
          'Sku may have alpha-numeric characters, as well as dashes and underscores only.',
        'required.name': 'Name is required.',
        'required.description': 'Description is required.',
        'max.description':
          'Description may not be greater than 200 characters.',
        'required.quantity': 'Quantity is required.',
        'required.price': 'Price is required.',
        'required.taxable': 'Taxable is required.',
        'required.image': 'Please upload files with jpg, jpeg, png format.',
        'required.brand': 'Brand is required.'
      });

      if (!isValid) {
        return dispatch({ type: SET_PRODUCT_FORM_ERRORS, payload: errors });
      }
      const formData = new FormData();
      if (newProduct.image) {
        for (const key in newProduct) {
          if (newProduct.hasOwnProperty(key)) {
            if (key === 'brand' && newProduct[key] === null) {
              continue;
            } else {
              formData.set(key, newProduct[key]);
            }
          }
        }
      }

      const response = await axios.post(`${API_URL}/product/add`, formData, {
        headers: { 'Content-Type': 'multipart/form-data' }
      });

      const successfulOptions = {
        title: `${response.data.message}`,
        position: 'tr',
        autoDismiss: 1
      };

      if (response.data.success === true) {
        dispatch(success(successfulOptions));
        dispatch({
          type: ADD_PRODUCT,
          payload: response.data.product
        });
        dispatch(resetProduct());
        dispatch(goBack());
      }
    } catch (error) {
      handleError(error, dispatch);
    }
  };
};

Server side Product API route:

const { s3Upload } = require('../../utils/image');
const storage = multer.memoryStorage();
const upload = multer({ storage });

router.post('/add', auth, role.check(ROLES.Admin, ROLES.Merchant), upload.single('image'), async (req, res) => {
    try {
      const sku = req.body.sku;
      const name = req.body.name;
      const description = req.body.description;
      const quantity = req.body.quantity;
      const price = req.body.price;
      const taxable = req.body.taxable;
      const isActive = req.body.isActive;
      const brand = req.body.brand;
      const image = req.file;

      if (!sku) {
        return res.status(400).json({ error: 'You must enter product SKU.' });
      }

      if (!description || !name) {
        return res.status(400).json({ error: 'You must enter product name and description.' });
      }

      if (!quantity) {
        return res.status(400).json({ error: 'You must enter a quantity.' });
      }

      if (!price) {
        return res.status(400).json({ error: 'You must enter a price.' });
      }

      const foundProduct = await Product.findOne({ sku });
      if (foundProduct) {
        return res.status(400).json({ error: 'This SKU is already in use.' });
      }

      const { imageUrl, imageKey } = await s3Upload(image);

      const product = new Product({
        sku,
        name,
        description,
        quantity,
        price,
        taxable,
        isActive,
        brand,
        imageUrl,
        imageKey
      });

      const savedProduct = await product.save();

      res.status(200).json({
        success: true,
        message: `Product has been successfully added!`,
        product: savedProduct
      });
    } catch (error) {
      return res.status(400).json({
        error: 'Your request could not be processed. Please try again.'
      });
    }
  }
);

Server side image.js utils file:

exports.s3Upload = async image => {
  try {
    let imageUrl = '';
    let imageKey = '';

    if (image) {

      const params = {
        Key: image.originalname,
        Body: image.buffer,
        ContentType: image.mimetype
      };

      const s3Upload = await s3bucket.upload(params).promise();

      imageUrl = s3Upload.Location;
      imageKey = s3Upload.key;
    }

    return { imageUrl, imageKey };
  } catch (error) {
    return { imageUrl: '', imageKey: '' };
  }
};

Server side Product database schema:

const Mongoose = require('mongoose');
const slug = require('mongoose-slug-generator');
const { Schema } = Mongoose;

const options = {
  separator: '-',
  lang: 'en',
  truncate: 120
};

Mongoose.plugin(slug, options);

const ProductSchema = new Schema({
  sku: { type: String },
  name: { type: String, trim: true },
  slug: { type: String, slug: 'name', unique: true },
  imageUrl: { type: String },
  imageKey: { type: String },
  description: { type: String, trim: true },
  quantity: { type: Number },
  price: { type: Number },
  taxable: { type: Boolean, default: false },
  isActive: { type: Boolean, default: true },
  brand: { type: Schema.Types.ObjectId, ref: 'Brand', default: null },
  updated: Date,
  created: { type: Date, default: Date.now }
});

module.exports = Mongoose.model('Product', ProductSchema);

I made the following modifications in the code.

Client side AddProduct.js component: (Set the input type to text and changed file and image values to imageUrl for matching the database)

          <Col xs='12' md='12'>
            <Input
              type={'text'}
              error={formErrors['imageUrl']}
              name={'imageUrl'}
              label={'Image'}
              placeholder={'Please Enter Product Image URL'}
              value={productFormData.imageUrl}
              onInputChange={(name, value) => {
                productChange(name, value);
              }}
            />
          </Col>

Client side Input.js component: (Removed if else statement related to image and file)

  const _onChange = e => {
      onInputChange(e.target.name, e.target.value);
  };

Client side Product reducer: Changed image: {} to imageUrl: '' in productFormData since it’s accepting string now)

const initialState = {
  productFormData: {
    sku: '',
    name: '',
    description: '',
    quantity: 1,
    price: 1,
    imageUrl: '',
    isActive: true,
    taxable: { value: 0, label: 'No' },
    brand: {
      value: 0,
      label: 'No Options Selected'
    }
  }
}

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    // ... Other cases
    case RESET_PRODUCT:
      return {
        ...state,
        productFormData: {
          sku: '',
          name: '',
          description: '',
          quantity: 1,
          price: 1,
          imageUrl: '',
          isActive: true,
          taxable: { value: 0, label: 'No' },
          brand: {
            value: 0,
            label: 'No Options Selected'
          }
        },
        product: {
          _id: ''
        },
        formErrors: {}
      };

Client side Product actions: (Removed image.required rules and changed image to imageUrl)

export const addProduct = () => {
  return async (dispatch, getState) => {
    try {
      const rules = {
        sku: 'required|alpha_dash',
        name: 'required',
        description: 'required|max:200',
        quantity: 'required|numeric',
        price: 'required|numeric',
        taxable: 'required',
        brand: 'required'
      };

      const product = getState().product.productFormData;
      const user = getState().account.user;
      const brands = getState().brand.brandsSelect;

      const brand = unformatSelectOptions([product.brand]);

      const newProduct = {
        sku: product.sku,
        name: product.name,
        description: product.description,
        price: product.price,
        quantity: product.quantity,
        imageUrl: product.imageUrl,
        isActive: product.isActive,
        taxable: product.taxable.value,
        brand:
          user.role !== ROLES.Merchant
            ? brand !== 0
              ? brand
              : null
            : brands[1].value
      };

      const { isValid, errors } = allFieldsValidation(newProduct, rules, {
        'required.sku': 'Sku is required.',
        'alpha_dash.sku':
          'Sku may have alpha-numeric characters, as well as dashes and underscores only.',
        'required.name': 'Name is required.',
        'required.description': 'Description is required.',
        'max.description':
          'Description may not be greater than 200 characters.',
        'required.quantity': 'Quantity is required.',
        'required.price': 'Price is required.',
        'required.taxable': 'Taxable is required.',
        'required.brand': 'Brand is required.'
      });

      if (!isValid) {
        return dispatch({ type: SET_PRODUCT_FORM_ERRORS, payload: errors });
      }
      const formData = new FormData();
      if (newProduct.imageUrl) {
        for (const key in newProduct) {
          if (newProduct.hasOwnProperty(key)) {
            if (key === 'brand' && newProduct[key] === null) {
              continue;
            } else {
              formData.set(key, newProduct[key]);
            }
          }
        }
      }

      const response = await axios.post(`${API_URL}/product/add`, formData, {
        headers: { 'Content-Type': 'multipart/form-data' }
      });

      const successfulOptions = {
        title: `${response.data.message}`,
        position: 'tr',
        autoDismiss: 1
      };

      if (response.data.success === true) {
        dispatch(success(successfulOptions));
        dispatch({
          type: ADD_PRODUCT,
          payload: response.data.product
        });
        dispatch(resetProduct());
        dispatch(goBack());
      }
    } catch (error) {
      handleError(error, dispatch);
    }
  };
};

Server side Product API route: (Removed upload.single('image') and const { imageUrl, imageKey } = await s3Upload(image);, changed const image = req.file; to const imageUrl = req.body.imageUrl;)

// Add product
router.post('/add', auth, role.check(ROLES.Admin, ROLES.Merchant), async (req, res) => {
    try {
      const sku = req.body.sku;
      const name = req.body.name;
      const description = req.body.description;
      const quantity = req.body.quantity;
      const price = req.body.price;
      const taxable = req.body.taxable;
      const isActive = req.body.isActive;
      const brand = req.body.brand;
      const imageUrl = req.body.imageUrl;

      if (!sku) {
        return res.status(400).json({ error: 'You must enter product SKU.' });
      }

      if (!description || !name) {
        return res.status(400).json({ error: 'You must enter product name and description.' });
      }

      if (!quantity) {
        return res.status(400).json({ error: 'You must enter a quantity.' });
      }

      if (!price) {
        return res.status(400).json({ error: 'You must enter a price.' });
      }

      const foundProduct = await Product.findOne({ sku });
      if (foundProduct) {
        return res.status(400).json({ error: 'This SKU is already in use.' });
      }
// ... ...

Completely removed image.js utils file

Didn’t modify anything in Product database schema

The above reveals my current code but now it doesn’t get my input values (product name, description, etc – not only imageUrl) and saves an empty form to the database. It’s weird because I didn’t change anything about other form fields. I’m probably missing something. Any help will be appreciated!

Basic JavaScript syntax-type question which consists of different types of syntax of functions [duplicate]

const onClickButton = (color) => {
 }  
 
const onClickButton = (color) => () => {
 }

Can anyone please tell the basic difference between these 2 functions?

I was making a very simple page on which,on clicking a particular button,the color changes.
Now in this,I needed to create a function for onClick.
On using the 1st function, my code did not worked, but the 2nd function worked fine.