javascriptreactjsnext.jsdate-fnsreact-big-calendar

How to show date on the popup in locale bn instead of en-US in react-big-calender


I'm using react-big-calender in my project where implemented Show more via a popup. Now, what i want as my overall data specially the date is in bn: Bengali so i want also to show the date e.g. Saturday Apr 08 in শনিবার ৮ এপ্রিল this format after clicking the "+{x} more" link on any calendar day that cannot fit all the days events to see an inline popup of all the events. You can see my attached image please have a look to get a clear idea.

How can i achieve this? Here is my code:

import React, { Children } from "react";
import { Calendar, dateFnsLocalizer } from "react-big-calendar";
import { SingleEventDetails } from "../../module/LiveClass/singleEventDetails";
import * as PropTypes from "prop-types";
import format from "date-fns/format";
import parse from "date-fns/parse";
import startOfWeek from "date-fns/startOfWeek";
import getDay from "date-fns/getDay";
import enUS from "date-fns/locale/en-US";
import getBangla, { getBanglaDayName } from "../../utils/engToBng";
import { getIsToday } from "../../utils/times";
import { useMediaQuery } from "react-responsive";
import { translateNumberToShongkha } from "../../lib/utils/helpers";

const locales = {
  "en-US": enUS,
};

const localizer = dateFnsLocalizer({
  format,
  parse,
  startOfWeek: () => {
    return startOfWeek(new Date(), { weekStartsOn: 6 });
  },
  getDay,
  locales,
});
// example implementation of a wrapper
const ColoredDateCellWrapper = ({ children }) =>
  React.cloneElement(Children.only(children), {
    style: {
      ...children.style,
      backgroundColor: "transparent",
      border: ".2px solid .2",
      borderStyle: "dotted",
    },
  });

const eventStyleGetter = function (event) {
  let style = {
    backgroundColor: event?.color_code,
    textAlign: "center",
    borderRadius: "0px",
    borderColor: "red",
    border: "none",
    margin: "0 0px",
  };
  return {
    style: style,
  };
};

const HeaderCellContent = (props) => {
  const isMobile = useMediaQuery({
    query: "(max-width: 767px)",
  });
  const { date } = props;
  const dayOfWeek = date.getDay();

  const className = dayOfWeek === 5 ? "text-Title3" : "text-Title3";
  return (
    <div
      component="span"
      className={`'bg-transparent border-0 py-4 font-hind font-medium text-base leading-20px' ${className}`}
    >
      {getBanglaDayName(props.label, isMobile)}
    </div>
  );
};

const DateCellContent = (props) => {
  const { date } = props;
  const className = getIsToday(date)
    ? "mx-auto pt-1 text-white bg-PinkMain w-8 h-8 my-1 border-1 rounded-md "
    : "pt-3 text-Title3";

  return (
    <div
      component="span"
      className={`'  text-center    font-balo font-medium  text-base leading-20px' ${className}`}
    >
      {getBangla(parseInt(props.label))}
    </div>
  );
};

export default function BigCalender(props) {
  // console.log('props.events', props.events)
  return (
    <Calendar
      localizer={localizer}
      popup
      messages={{
        showMore: (total) => (
          <div
            style={{
              cursor: "pointer",
              backgroundColor: `#FFECFA`,
              borderRadius: `2px`,
            }}
            className="w-full px-2 font-medium font-grotesk text-xs lg:text-sm text-PinkMain flex gap-x-2 justify-center lg:justify-between items-center"
            onMouseOver={(e) => {
              e.stopPropagation();
              e.preventDefault();
            }}
          >
            <div className="flex gap-x-1">
              {`+${translateNumberToShongkha(total)}`}
              <span className="hidden sm:inline-block xl:hidden">..</span>
              <span className="hidden xl:inline-block">আরো</span>
            </div>
            <svg
              width="10"
              height="7"
              viewBox="0 0 10 7"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              className="hidden sm:inline-block"
            >
              <path
                d="M0.492344 0.999296C0.247344 1.2443 0.247344 1.6393 0.492344 1.8843L4.64734 6.0393C4.84234 6.2343 5.15734 6.2343 5.35234 6.0393L9.50734 1.8843C9.75234 1.6393 9.75234 1.2443 9.50734 0.999296C9.26234 0.754296 8.86734 0.754296 8.62234 0.999296L4.99734 4.6193L1.37234 0.994297C1.13234 0.754296 0.732344 0.754296 0.492344 0.999296Z"
                fill="#CF278D"
              />
            </svg>
          </div>
        ),
      }}
      date={props.defaultDate}
      defaultView="month"
      events={props.events}
      showMultiDayTimes="true"
      style={{ height: "80vh" }}
      components={{
        event: SingleEventDetails,
        dateCellWrapper: ColoredDateCellWrapper,
        month: {
          header: HeaderCellContent,
          dateHeader: DateCellContent,
        },
      }}
      toolbar={false}
      eventPropGetter={eventStyleGetter}
      views={{ month: true }}
      tooltipAccessor={""}
      startAccessor="start"
      endAccessor="end"
    />
  );
}

BigCalender.propTypes = {
  defaultDate: PropTypes.any,
  events: PropTypes.arrayOf(PropTypes.any),
};


Solution

  • Following configuration of localizer will solve that issue using moment.

    const bnLocalizer = momentLocalizer(moment, {
      format: {
        dayOfMonth: "D",
        dayOfWeek: "ddd",
        timeGutterFormat: "LT",
        monthHeaderFormat: "MMMM YYYY",
        agendaDateFormat: "ddd, MMM D",
        agendaTimeFormat: "LT",
        agendaTimeRangeFormat: "LT",
        dateFormat: "DD/MM/YYYY",
        timeFormat: "LT",
        messages: null,
      },
      firstDayOfWeek: 0, // Sunday
      weekHeaderFormat: "ddd",
      getDayOfWeek: (date) => moment(date).locale("en").format("dd"),
      getMonth: (date) => moment(date).locale("bn").format("MMMM"),
      getMonths: (date) => moment(date).locale("bn").format("MMM"),
    });
    
    export default function BigCalender(props) {
      return (
        <Calendar
          localizer={bnLocalizer}
          ...
        />
      );
    }