Skip to content
Snippets Groups Projects
index.tsx 9.47 KiB
import React, { useState } from 'react'
import {
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Button,
} from '@mui/material'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'

import Page from 'components/page'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { Guest, Role } from 'interfaces'
import format from 'date-fns/format'
import SponsorGuestButtons from '../../components/sponsorGuestButtons'

interface GuestProps {
  persons: Guest[]
  cancelCallback?: (roleId: string) => void
}

interface PersonLineProps {
  person: Guest
  role: Role
  showStatusColumn?: boolean
  displayCancel?: boolean
  cancelCallback?: (roleId: string) => void
}

const PersonLine = ({
  person,
  role,
  showStatusColumn,
  displayCancel,
  cancelCallback,
}: PersonLineProps) => {
  const [t, i18n] = useTranslation(['common'])

  return (
    <TableRow
      key={`${person.first} ${person.last}`}
      sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
    >
      <TableCell component="th" scope="row">
        {`${person.first} ${person.last}`}
      </TableCell>
      <TableCell align="left">
        {i18n.language === 'en' ? role.name_en : role.name_nb}
      </TableCell>

      {showStatusColumn &&
        (person.active ? (
          <TableCell sx={{ color: 'green' }} align="left">
            {t('common:active')}
          </TableCell>
        ) : (
          <TableCell sx={{ color: 'red' }} align="left">
            {t('common:expired')}
          </TableCell>
        ))}

      <TableCell align="left">
        {role.start_date ? format(role.start_date, 'yyyy-MM-dd') : null} -{' '}
        {format(role.end_date, 'yyyy-MM-dd')}
      </TableCell>
      <TableCell align="left">
        {i18n.language === 'en' ? role.ou_en : role.ou_nb}
      </TableCell>
      <TableCell align="left">
        {displayCancel ? (
          <Button
            data-testid="button-invite-cancel"
            sx={{ color: 'theme.palette.secondary', mr: 1 }}
            onClick={() => {
              if (cancelCallback) {
                cancelCallback(role.id)
              }
            }}
          >
            {t('common:button.cancel')}
          </Button>
        ) : (
          <Button
            variant="contained"
            component={Link}
            to={`/sponsor/guest/${person.pid}`}
          >
            {t('common:details')}
          </Button>
        )}
      </TableCell>
    </TableRow>
  )
}

PersonLine.defaultProps = {
  showStatusColumn: false,
  displayCancel: false,
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  cancelCallback: (roleId: number) => {},
}

const WaitingForGuestRegistration = ({
  persons,
  cancelCallback,
}: GuestProps) => {
  const [activeExpanded, setActiveExpanded] = useState(false)

  // Show guests that have not responded to the invite yet
  let guests = persons.length > 0 ? persons : []

  if (guests.length > 0) {
    guests = guests.filter((person) => !person.registered)
  }
  const [t] = useTranslation(['common'])
  return (
    <Accordion
      expanded={activeExpanded}
      onChange={() => {
        setActiveExpanded(!activeExpanded)
      }}
    >
      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
        <h4>{t('common:sentInvitations')}</h4>
      </AccordionSummary>
      <AccordionDetails>
        <p>{t('common:sentInvitationsDescription')}</p>
        <TableContainer component={Paper}>
          <Table sx={{ minWidth: 650 }} aria-label="simple table">
            <TableHead sx={{ backgroundColor: 'primary.light' }}>
              <TableRow>
                <TableCell>{t('common:name')}</TableCell>
                <TableCell align="left">{t('common:role')}</TableCell>
                <TableCell align="left">{t('common:period')}</TableCell>
                <TableCell align="left">{t('common:ou')}</TableCell>
                <TableCell align="left">{t('common:choice')}</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {guests.length > 0 ? (
                guests.map((person) =>
                  person.roles ? (
                    person.roles.map((role) => (
                      <PersonLine
                        role={role}
                        person={person}
                        displayCancel
                        cancelCallback={cancelCallback}
                      />
                    ))
                  ) : (
                    <></>
                  )
                )
              ) : (
                <></>
              )}

              <TableRow>
                <TableCell>
                  {guests.length > 0 ? '' : t('common:noActiveGuests')}
                </TableCell>
              </TableRow>
            </TableBody>
          </Table>
        </TableContainer>
      </AccordionDetails>
    </Accordion>
  )
}

const ActiveGuests = ({ persons }: GuestProps) => {
  const [activeExpanded, setActiveExpanded] = useState(false)

  // Show all verified guests
  let guests = persons.length > 0 ? persons : []
  if (guests.length > 0) {
    guests = guests.filter((person) => person.verified)
  }
  const [t] = useTranslation(['common'])
  return (
    <Accordion
      expanded={activeExpanded}
      onChange={() => {
        setActiveExpanded(!activeExpanded)
      }}
    >
      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
        <h4>{t('common:activeGuests')}</h4>
      </AccordionSummary>
      <AccordionDetails>
        <p>{t('common:activeGuestsDescription')}</p>
        <TableContainer component={Paper}>
          <Table sx={{ minWidth: 650 }} aria-label="simple table">
            <TableHead sx={{ backgroundColor: 'primary.light' }}>
              <TableRow>
                <TableCell>{t('common:name')}</TableCell>
                <TableCell align="left">{t('common:role')}</TableCell>

                <TableCell align="left">{t('common:status')}</TableCell>

                <TableCell align="left">{t('common:period')}</TableCell>
                <TableCell align="left">{t('common:ou')}</TableCell>
                <TableCell align="left">{t('common:choice')}</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {guests.length > 0 ? (
                guests.map((person) =>
                  person.roles ? (
                    person.roles.map((role) => (
                      <PersonLine
                        role={role}
                        person={person}
                        showStatusColumn
                      />
                    ))
                  ) : (
                    <></>
                  )
                )
              ) : (
                <></>
              )}

              <TableRow>
                <TableCell>
                  {guests.length > 0 ? '' : t('common:noActiveGuests')}
                </TableCell>
              </TableRow>
            </TableBody>
          </Table>
        </TableContainer>
      </AccordionDetails>
    </Accordion>
  )
}

const WaitingGuests = ({ persons }: GuestProps) => {
  const [waitingExpanded, setWaitingExpanded] = useState(false)

  // Show guests that have completed the registration but are not verified yet
  let guests = persons.length > 0 ? persons : []
  if (guests.length > 0) {
    guests = guests.filter((person) => person.registered && !person.verified)
  }
  const [t] = useTranslation(['common'])

  return (
    <Accordion
      expanded={waitingExpanded}
      onChange={() => {
        setWaitingExpanded(!waitingExpanded)
      }}
      sx={{ border: 'none' }}
    >
      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
        <h4>{t('common:waitingGuests')}</h4>
      </AccordionSummary>
      <AccordionDetails>
        <p>{t('common:waitingGuestsDescription')}</p>

        <TableContainer component={Paper}>
          <Table sx={{ minWidth: 650 }} aria-label="simple table">
            <TableHead sx={{ backgroundColor: 'primary.light' }}>
              <TableRow>
                <TableCell>{t('common:name')}</TableCell>
                <TableCell align="left">{t('common:role')}</TableCell>
                <TableCell align="left">{t('common:period')}</TableCell>
                <TableCell align="left">{t('common:ou')}</TableCell>
                <TableCell align="left">{t('common:choice')}</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {guests.length > 0 ? (
                guests.map((person) =>
                  person.roles ? (
                    person.roles.map((role) => (
                      <PersonLine role={role} person={person} />
                    ))
                  ) : (
                    <></>
                  )
                )
              ) : (
                <></>
              )}
              <TableRow>
                <TableCell>
                  {guests.length > 0 ? '' : t('common:noWaitingGuests')}
                </TableCell>
              </TableRow>
            </TableBody>
          </Table>
        </TableContainer>
      </AccordionDetails>
    </Accordion>
  )
}

interface FrontPageProps {
  guests: Guest[]
  cancelRole: (roleId: string) => void
}

function FrontPage({ guests, cancelRole }: FrontPageProps) {
  return (
    <Page>
      <SponsorGuestButtons yourGuestsActive />
      <WaitingForGuestRegistration
        persons={guests}
        cancelCallback={cancelRole}
      />
      <WaitingGuests persons={guests} />
      <ActiveGuests persons={guests} />
    </Page>
  )
}

export default FrontPage