All files / libs/lti/components/src/lib/enrollment/plan-information-widgets PlanInformationWidgetsPresentation.tsx

0% Statements 0/114
0% Branches 0/1
0% Functions 0/1
0% Lines 0/114

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115                                                                                                                                                                                                                                     
import { css } from '@emotion/react';
import { memo, useCallback, useMemo } from 'react';
import { match } from 'ts-pattern';
import { type SetNonNullable } from 'type-fest';

import { Stack } from '@allshares/studio-design-system';
import { type CurrencyValue } from '@amalia/kernel/monetary/types';
import { type EnrollmentPlanInformationWidget, type LtiGrant } from '@amalia/lti/types';

import { PlanInformationWidgetRowContainer } from './PlanInformationWidgetRowContainer';
import { EstimatedRewardDateWidget } from './widgets/EstimatedRewardDateWidget';
import { GrantDateWidget } from './widgets/GrantDateWidget';
import { GrantedSharesWidget } from './widgets/GrantedSharesWidget';
import { OfferExpiryDateWidget } from './widgets/OfferExpiryDateWidget';
import { PerformancePeriodWidget } from './widgets/PerformancePeriodWidget';

const getWidgetContainerWidth = (...conditions: (string | undefined)[]): string =>
  conditions.every(Boolean) ? 'initial' : '50%';

type PlanInformationWidgetsPresentationProps = {
  readonly grantedShares: number;
  readonly grantDate: Date;
  readonly offerExpiryDate: LtiGrant['offerExpiryDate'];
  readonly estimatedRewardDate: Date;
  readonly performancePeriod: {
    endDate: Date;
    startDate: Date;
  };
  readonly grantedSharesMonetaryValue?: SetNonNullable<CurrencyValue>;
  readonly widgetsConfiguration: Omit<EnrollmentPlanInformationWidget, 'id' | 'isDraft' | 'type'>;
};

const widgetsThatCanBeAutomaticallyReordered: readonly (keyof Pick<
  PlanInformationWidgetsPresentationProps['widgetsConfiguration'],
  'showEstimatedRewardDate' | 'showGrantDate' | 'showOfferExpiryDate' | 'showPerformancePeriodDates'
>)[] = ['showGrantDate', 'showOfferExpiryDate', 'showEstimatedRewardDate', 'showPerformancePeriodDates'] as const;

export const PlanInformationWidgetsPresentation = memo(function PlanInformationWidgetsPresentation({
  grantDate,
  grantedShares,
  grantedSharesMonetaryValue,
  offerExpiryDate,
  performancePeriod,
  estimatedRewardDate,
  widgetsConfiguration,
}: PlanInformationWidgetsPresentationProps) {
  const widgetsToDisplayAfterGrantedShares = useMemo(
    () => widgetsThatCanBeAutomaticallyReordered.filter((widgetName) => widgetsConfiguration[widgetName]),
    [widgetsConfiguration],
  );

  const renderWidget = useCallback(
    (widgetName: (typeof widgetsToDisplayAfterGrantedShares)[number] | undefined) =>
      match(widgetName)
        .with(undefined, () => null)
        .with('showGrantDate', () => <GrantDateWidget value={grantDate} />)
        .with('showOfferExpiryDate', () => (offerExpiryDate ? <OfferExpiryDateWidget value={offerExpiryDate} /> : null))
        .with('showEstimatedRewardDate', () => <EstimatedRewardDateWidget value={estimatedRewardDate} />)
        .with('showPerformancePeriodDates', () => (
          <PerformancePeriodWidget
            endDate={performancePeriod.endDate}
            startDate={performancePeriod.startDate}
          />
        ))
        .exhaustive(),
    [estimatedRewardDate, grantDate, offerExpiryDate, performancePeriod.endDate, performancePeriod.startDate],
  );

  return (
    <Stack gap={16}>
      {!!widgetsConfiguration.showGrantedShares && (
        <PlanInformationWidgetRowContainer
          css={css`
            width: 50%;
          `}
        >
          <GrantedSharesWidget
            monetaryValue={grantedSharesMonetaryValue}
            showMonetaryValue={widgetsConfiguration.showMonetaryValues}
            value={grantedShares}
          />
        </PlanInformationWidgetRowContainer>
      )}

      {!!(widgetsToDisplayAfterGrantedShares.length > 0) && (
        <PlanInformationWidgetRowContainer
          css={css`
            width: ${getWidgetContainerWidth(
              widgetsToDisplayAfterGrantedShares.at(0),
              widgetsToDisplayAfterGrantedShares.at(1),
            )};
          `}
        >
          {renderWidget(widgetsToDisplayAfterGrantedShares.at(0))}
          {renderWidget(widgetsToDisplayAfterGrantedShares.at(1))}
        </PlanInformationWidgetRowContainer>
      )}

      {!!(widgetsToDisplayAfterGrantedShares.length > 2) && (
        <PlanInformationWidgetRowContainer
          css={css`
            width: ${getWidgetContainerWidth(
              widgetsToDisplayAfterGrantedShares.at(2),
              widgetsToDisplayAfterGrantedShares.at(3),
            )};
          `}
        >
          {renderWidget(widgetsToDisplayAfterGrantedShares.at(2))}
          {renderWidget(widgetsToDisplayAfterGrantedShares.at(3))}
        </PlanInformationWidgetRowContainer>
      )}
    </Stack>
  );
});