Convert Class component to functional component - react calendar timeline

147 Views Asked by At

I have an example of React Calendar Timeline npm. This is developed with Class component can someone help me to convert this to use functional component in React. I am new to react so couldn't make it work with functional component.

Example link: https://codesandbox.io/s/r1mxzj581m

1

There are 1 best solutions below

2
Ferin Patel On BEST ANSWER

Here is the working sandbox link for functional component.

import React, { useState } from "react";
import moment from "moment";
import Timeline from "react-calendar-timeline";
import generateFakeData from "./generate-fake-data";

const keys = {
  groupIdKey: "id",
  groupTitleKey: "title",
  groupRightTitleKey: "rightTitle",
  itemIdKey: "id",
  itemTitleKey: "title",
  itemDivTitleKey: "title",
  itemGroupKey: "group",
  itemTimeStartKey: "start",
  itemTimeEndKey: "end",
  groupLabelKey: "title"
};

const App = () => {
  const { groups: initialGroups, items: initialItems } = generateFakeData();
  const defaultTimeStart = moment().startOf("day").toDate();
  const defaultTimeEnd = moment().startOf("day").add(1, "day").toDate();

  // convert every 2 groups out of 3 to nodes, leaving the first as the root
  const newGroups = initialGroups.map((group) => {
    const isRoot = (parseInt(group.id) - 1) % 3 === 0;
    const parent = isRoot
      ? null
      : Math.floor((parseInt(group.id) - 1) / 3) * 3 + 1;

    return { ...group, root: isRoot, parent };
  });

  const [groups, setGroups] = useState(newGroups);
  const [items] = useState(initialItems);
  const [openGroups, setOpenGroups] = useState({});

  const toggleGroup = (id) => {
    setOpenGroups((prevOpenGroups) => ({
      ...prevOpenGroups,
      [id]: !prevOpenGroups[id]
    }));
  };

  // hide (filter) the groups that are closed, for the rest, patch their "title" and add some callbacks or padding
  const filteredGroups = groups.filter((g) => g.root || openGroups[g.parent]);
  const newGroupsToShow = filteredGroups.map((group) => {
    return {
      ...group,
      title: group.root ? (
        <div
          onClick={() => toggleGroup(parseInt(group.id))}
          style={{ cursor: "pointer" }}
        >
          {openGroups[parseInt(group.id)] ? "[-]" : "[+]"} {group.title}
        </div>
      ) : (
        <div style={{ paddingLeft: 20 }}>{group.title}</div>
      )
    };
  });

  return (
    <Timeline
      groups={newGroupsToShow}
      items={items}
      keys={keys}
      sidebarWidth={150}
      canMove
      canResize="right"
      canSelect
      itemsSorted
      itemTouchSendsClick={false}
      stackItems
      itemHeightRatio={0.75}
      showCursorLine
      defaultTimeStart={defaultTimeStart}
      defaultTimeEnd={defaultTimeEnd}
    />
  );
};

export default App;