Calculating a Price Quote

I have created a dynamic quote calculator for a Next.js project that allows users to calculate prices based on word count and selected languages. Currently, the price is calculated using a fixed rate of 0.05 per word.

'use client';

import { useState } from 'react';
import styles from '../styles';
import { allLanguages } from '../constants';

const QuoteContainer = () => {
  const [wordCount, setWordCount] = useState('');
  const [sourceLanguage, setSourceLanguage] = useState('');
  const [targetLanguage, setTargetLanguage] = useState('');
  const [totalPrice, setTotalPrice] = useState('');
  const handleWordCountChange = (event) => {
    setWordCount(event.target.value);
  };

  const handleSourceLanguageChange = (event) => {
    setSourceLanguage(event.target.value);
  };

  const handleTargetLanguageChange = (event) => {
    setTargetLanguage(event.target.value);
  };
 

  const handleCalculatePrice = () => {
    let priceRate;
    switch(parseInt(sourceLanguage)) {
      case 1:
        priceRate = 0.05;
        break;
      case 2:
        priceRate = 0.06;
        break;
      case 3:
        priceRate = 0.07;
        break;
      case 4:
        priceRate = 0.08;
        break;
      default:
        priceRate = 0.05;
    }
    const price = Number(wordCount) * priceRate;
    setTotalPrice(price.toFixed(2));
   
  };
  return (
    <section className={`${styles.paddings} mt-0`} id="quote">
      <div className="theme-neon relative bg-skin-fill max-w-6xl mt-12 mx-auto overflow-hidden sm:rounded-2xl">
        <img className="absolute inset-0 h-full w-full object-cover opacity-30" src="https://images.unsplash.com/photo-1613217784112-e0e197be6a0b?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1600&q=80&sat=-100" alt="People working on laptops" />
        <div className="absolute inset-0 bg-gradient-to-br from-skin-hue via-skin-hue to-transparent opacity-90" />
        <div className="relative max-w-2xl mx-auto text-center py-16 px-4 sm:py-20 sm:px-6 lg:px-8">
          <h2 className="text-3xl font-extrabold text-skin-base sm:text-4xl">
            <span className="block">Professional translations made easy.</span>
          </h2>
          <p className="mt-4 text-md leading-6 text-skin-muted">
            <span className="font-extrabold text-gray-300" /> In few clicks, input your order and receive your quote instantly.
          </p>
          <div className="flex flex-row w-full items-center justify-between">
            <div className="flex flex-col w-full mt-6 items-center justify-center text-left">
              <div className="flex flex-row w-full">
                <div className="mt-12 flex flex-col w-full">
                  <div className="flex flex-row">
                    <div className="w-full mr-4 ml-0">
                      <label htmlFor="InstantQuoteSourceLanguages" className="block mb-2 text-base font-medium text-gray-900 dark:text-white">Source Language</label>
                      <div className="flex relative z-[1]">

                        <select
                          required id="InstantQuoteSourceLanguages"
                          className="block w-full px-4 py-3 text-base text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                          value={sourceLanguage}
                          onChange={handleSourceLanguageChange}
                        >
                          <option value="" disabled>From</option>
                          {allLanguages
                          && allLanguages.map((language) => (
                            <option
                              key={`${language.name}-matrix`}
                              value={[language.group.toString(), language.name]}
                            >
                              {language.name}
                            </option>
                          ))}
                        </select>
                      </div>
                    </div>
                    <div className="w-full mr-4 ml-0 ">
                      <label htmlFor="InstantQuoteTargetLanguages" className="block mb-2 text-base font-medium text-gray-900 dark:text-white">Target Language</label>
                      <div className="flex relative z-[1]">
                        <select
                          required id="InstantQuoteTargetLanguages"
                          className="block w-full px-4 py-3 text-base text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                          value={targetLanguage}
                          onChange={handleTargetLanguageChange}
                        >
                          <option value="" disabled>To</option>
                          {allLanguages
                          && allLanguages.map((language) => (
                            <option
                              key={language.name}
                              value={[language.group.toString(), language.name]}
                            >
                              {language.name}
                            </option>
                          ))}
                        </select>
                      </div>
                    </div>

                  </div>
                  <div className="relative flex flex-col ml-0 mt-4 w-full self-end min-w-0">
                    <label htmlFor="InstantQuoteWordCount" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Word count</label>
                    <input
                      id="InstantQuoteWordCount"
                      value={wordCount}
                      onChange={handleWordCountChange}
                      type="text"
                      placeholder="Enter the word count in numbers"
                      className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                    />
                  </div>
                  <div className="realatie flex flex-col flex-[1] self-end min-w-0 mx-4 my-0 ">

                    <input
                      type="submit"
                      className="text-skin-inverted bg-skin-button-accent hover:bg-skin-button-accent-hover flex items-center justify-center px-4 py-3 mt-4 border border-transparent text-base font-medium rounded-md shadow-sm sm:px-8"
                      value="Show prices"
                      onClick={handleCalculatePrice}
                    />
                  </div>
                </div>

              </div>
              <div className="relative flex-[1] flex flex-col items-center  mt-6 pt-2 pb-6 px-4">
                {totalPrice && (

                <div className="flex flex-col max-w-md p-6 space-y-4 divide-y">
                  <h2 className="text-2xl font-semibold">Quote Summary</h2>
                  <ul className="flex flex-col pt-4 space-y-2">
                    <li className="flex items-start justify-between">
                      <h3>Language:
                        <span className="text-sm dark:text-violet-400">Source</span>
                      </h3>
                      <div className="text-right">
                        <span>{sourceLanguage}</span>

                      </div>
                    </li>
                    <li className="flex items-start justify-between">
                      <h3>Language:
                        <span className="text-sm dark:text-violet-400">Target</span>
                      </h3>
                      <div className="text-right">
                        <span>{targetLanguage}</span>
                      </div>
                    </li>
                    <li className="flex items-start justify-between">
                      <h3>Word Count
                        <span className="text-sm dark:text-violet-400">#</span>
                      </h3>
                      <div className="text-right">
                        <span>{wordCount}</span>

                      </div>
                    </li>
                  </ul>
                  <div className="pt-4 space-y-2">
                    <div className="flex justify-between">
                      <span>Rate</span>
                      <span>$0.50</span>
                    </div>
                    <div className="flex items-center space-x-2 text-xs">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" className="w-3 h-3 mt-1 fill-current dark:text-violet-400">
                        <path d="M485.887,263.261,248,25.373A31.791,31.791,0,0,0,225.373,16H64A48.055,48.055,0,0,0,16,64V225.078A32.115,32.115,0,0,0,26.091,248.4L279.152,486.125a23.815,23.815,0,0,0,16.41,6.51q.447,0,.9-.017a23.828,23.828,0,0,0,16.79-7.734L486.581,296.479A23.941,23.941,0,0,0,485.887,263.261ZM295.171,457.269,48,225.078V64A16.019,16.019,0,0,1,64,48H225.373L457.834,280.462Z"></path>
                        <path d="M148,96a52,52,0,1,0,52,52A52.059,52.059,0,0,0,148,96Zm0,72a20,20,0,1,1,20-20A20.023,20.023,0,0,1,148,168Z"></path>
                      </svg>
                      <span className="dark:text-gray-400">Order until August 31, 2023, get 20% off</span>
                    </div>
                    <div className="space-y-6">
                      <div className="flex justify-between">
                        <span>Total</span>
                        <span className="font-semibold">{totalPrice}</span>
                      </div>
                      <button type="button" className="w-full py-2 font-semibold border rounded text-skin-inverted bg-skin-button-accent hover:bg-skin-button-accent-hover">Order Now</button>
                    </div>
                  </div>
                </div>
                )}

              </div>
              <div className="text-sm leading-[26px] mt-[30px]">
                <span className="text-lg leading-5 font-medium text-blue-700 align-middle m-0 px-3 py-1.5 rounded-2xl bg-skin-button-accent;">Pay after delivery</span> We trust you: feel free to pay within 5 days from delivery via bank transfer, credit card, or PayPal.  <a href="frequently-asked-questions#payments">Learn more</a>
              </div>

            </div>

          </div>
        </div>
      </div>
    </section>

  );
};

export default QuoteContainer;

Now, I want to introduce variations in pricing based on different language groups. For example, I would like to assign different price rates to different language groups: group 1 - $0.05, group 2 - $0.06, group 3 - $0.07, and group 4 - $0.08 as shown below:

const allLanguages = [
  { name: 'Spanish (ES)', group: 1},
  { name: 'Spanish (LATAM)', group: 2 },
  { name: 'US English', group: 3},
  { name: 'English UK', group: 4},
];

How can I modify my existing logic to incorporate this new requirement?

Answer №1

In order to accommodate the varying prices among different language groups, you can establish a function named getPricePerWord. This function can be utilized to adjust for the specific language group.

const allLanguages = [
  { name: 'Spanish (ES)', group: 1},
  { name: 'Spanish (LATAM)', group: 2 },
  { name: 'US English', group: 3},
  { name: 'English UK', group: 4},
];

function getPricePerWord(language) {
  let pricePerWord = 0.05;
  switch(language.group) {
    case 1:
      pricePerWord = 0.05;
      break;
    case 2:
      pricePerWord = 0.06;
      break;
    case 3:
      pricePerWord = 0.07;
      break;
    case 4:
      pricePerWord = 0.08;
      break;
    default:
      pricePerWord = 0.05;
  }
  return pricePerWord;
}

This functionality can then be integrated into the calculatePrice function to retrieve accurate pricing for specific languages. It is important to ensure that the language parameter is also passed to the calculatePrice function.

function calculatePrice(words, language) {
  const pricePerWord = getPricePerWord(language);
  const totalPrice = words * pricePerWord;
  return totalPrice;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The jQuery functionality is not functioning properly within the aspx file

I came across some JavaScript code on stackoverflow that is not working in my own code, but strangely it works perfectly fine in the jsFiddle: https://jsfiddle.net/rxLg0bo4/9/ Here is how I am using inline jQuery in my code: <nav id="menu"> < ...

Encountered an issue while trying to assign a value to the 'value' property on an 'HTMLInputElement' within a reactive form

When I upload a picture as a data record, the image is sent to a server folder and its name is stored in the database. For this editing form, I retrieve the file name from the server and need to populate <input type="file"> in Angular 6 using reacti ...

Utilizing JavaScript to trigger a series of click events on a single button in order to

I am working on implementing a click event for a checkbox that will add and remove CSS classes using the "classList.toggle" method. Specifically, I want the checkbox to toggle between adding the "xyz" class on the first click, and then adding the "abc" cla ...

Leverage Node.js/Express backend objects within frontend JavaScript

I'm new to programming and feeling a bit lost. I've been struggling to find a solution for my issue despite spending a lot of time searching. Currently, I am working on coding a prototype for a simple web app using Node.js, Express, MongoDB, and ...

The iframe came to a halt as soon as it was no

I am currently developing a live video website that utilizes third-party tools to play the videos. To simplify things, I have embedded all the components required for live video into a single HTML page. Here is how it looks: <iframe data-v-140cfad2= ...

Utilizing the useEffect hook with outdated information

As I was learning about react hooks, I encountered a perplexing issue that I can't quite grasp. My goal is to create a list of numbers that can be incremented and should always display in descending order. However, when I input a high number initially ...

Eliminating Tailwind typography with PurgeCSS in a next.js project

Building a next.js site and utilizing specific text like the code snippet below: const defaultTheme = require('tailwindcss/defaultTheme') module.exports = { theme: { extend: { fontFamily: { sans: ['SFMono-Regular', ...

What method can I use to ensure that the sidebar stays fixed at a particular div as the user continues to scroll down the

Is there a way to automatically fix the sidebar once the user scrolls down and hits the top of the .Section2? Currently, I have to manually enter a threshold number which can be problematic due to varying positions across browsers and systems. Fiddle htt ...

"Enhance Your Online Shopping Experience with Woocommerce Ajax Filters and

I have a structure that looks like this: Company Google Apple Microsoft Material Wood Metal Plastic Essentially, Brand & Material are attributes in the Woocommerce system, while the rest are variables. I am currently working on implementing AJAX fi ...

Experimenting with an Angular Controller that invokes a service and receives a promise as a

I am currently in the process of testing an angular controller that relies on a service with a method that returns a promise. I have created a jasmine spy object to simulate the service and its promise-returning method. However, my mock promise is not retu ...

Error 400: The onCreate Trigger function for Cloud functions is experiencing issues with HTTP requests due to errors in the request

I am encountering an issue when attempting to add a trigger for Firestore OnCreate, as the deployment fails with HTTP Error: 400 stating that the request has errors. Essentially, my goal is to write to a new document if a record is created in a different ...

Submitting forms with Ajax in IE(8)

Sample Google form Related spreadsheet I modified the original code to create two custom forms: First created form Second created form Both forms are functional on most browsers except for IE(8). Any idea why? First form: <!DOCTYPE html> <h ...

Experimenting with React components that showcase various components in a loop

Currently, I am working on a react-native app where I have a simple component that receives an array and displays it as markers on a map using react-native-maps. My goal is to write tests for this component. The test should verify that there is a marker p ...

The issue I am encountering is that the keyboard controls in JavaScript are not causing the

One of the key elements in my code revolves around JavaScript functionality. I have implemented a feature where objects can be moved by pressing keys such as "down" or "right". However, there seems to be an issue where an object loaded from a .json file is ...

What is the best way to automatically set today's date as the default in a datepicker using jQuery

Currently utilizing the jQuery datepicker from (http://keith-wood.name/datepick.html), I am seeking to customize the calendar to display a specific date that I select as today's date, rather than automatically defaulting to the system date. Is there a ...

The file module.js is encountering an error at line 327 because it is unable to locate the module named 'express

Hey there, I'm new to nodejs and whenever I run a file in the command prompt like:- C:\demoData>node demo.js I encounter an error like this: module.js:327 throw err; ^ Error: Cannot find module 'express' at Function.M ...

Tips for utilizing jQuery Ajax data action

I've been trying to understand how to effectively utilize the data parameter in a $.Ajax call. However, I am facing confusion regarding the 'action' part within the data call. Is it meant to trigger an action in a controller? If so, how can ...

Access the data within a jsonArray using Cypress

I'm dealing with a test.json file that contains a jsonArray [{ "EMAIL": "email_1", "FIRST_NAME": "Daniel" }, [{ "EMAIL": "email_2", "FIRST_NAME": "John" }] ] I'm trying to figure out how to use cypre ...

Automatically populate select boxes with values from a different source using PHP

I'm in the process of setting up automatic population for 2 select boxes on a website. When a user chooses a class, the second select box automatically displays the main specialization of that class. If the user selects Tank (for example), the third ...

managing nested JSON arrays in JavaScript

I have a straightforward task with handling a simple array that is divided into two parts: a group of vid_ids and a single element named page. Initially, I was iterating through the vid_id array using a for loop. However, upon adding the page element, I en ...