connectDialog

 avatar
unknown
plain_text
2 years ago
6.7 kB
2
Indexable
import {
  Avatar,
  Box,
  Button,
  ButtonBase,
  Dialog,
  DialogContent,
  DialogProps,
  Divider,
  Tab,
  Tabs,
  Typography,
} from '@mui/material';
import { completeParametrizedUrl } from '../../lib/url';
import { Icon } from '@iconify/react';
import { MoloAgentExt, MoloAgentLink } from '../../types/molo/moloAgentExt';
import { MoloShare, MoloShareState, MoloShareType } from '../../types/molo/moloShare';
import { useAgentMediaUrl } from '../../hooks/useAgentMediaUrl';
import { useAppConfig } from '../../contexts/configContext';
import { useMemo, useState } from 'react';
import { useMutationShare } from '../../hooks/useMutationShare';
import castArray from 'lodash/castArray';

const enabledSocialLinks = new Set<MoloAgentLink['typename']>([
  'facebook',
  'twitter',
  'instagram',
  'linkedin',
]);

interface ConnectDialogProps {
  agent: MoloAgentExt;
  share: MoloShare;
}

interface ContactItemProps {
  icon: JSX.Element;
  title: string;
  url: string;
}

const ContactItem = ({ icon, title, url }: ContactItemProps) => (
  <Box sx={{ mb: 2 }}>
    <ButtonBase>
      <Box
        sx={{
          color: 'secondary.main',
          border: 1,
          borderColor: '#ECEDF2',
          borderRadius: '50%',
          width: 48,
          height: 48,
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        {icon}
      </Box>
      <Typography
        component="a"
        href={url}
        target="_blank"
        variant="small"
        color="primary"
        sx={{ textDecoration: 'none', ml: 1 }}
      >
        {title}
      </Typography>
    </ButtonBase>
  </Box>
);

const Contacts = ({ agent }: ConnectDialogProps) => {
  const website = agent.item.Links.item?.find(({ typename }) => typename === 'website');
  return (
    <Box>
      {agent.item.email && (
        <ContactItem
          icon={<Icon width={24} icon="material-symbols:mail-outline-sharp" />}
          title={agent.item.email}
          url={`mailto:${agent.item.email}`}
        />
      )}
      {agent.item.cellphone && (
        <ContactItem
          icon={<Icon width={24} icon="material-symbols:phone-enabled-outline" />}
          title={agent.item.cellphone}
          url={`tel:${agent.item.cellphone}`}
        />
      )}
      {(agent.item.whatsapp || agent.item.cellphone) && (
        <ContactItem
          icon={<Icon width={24} icon="mdi:whatsapp" />}
          title="WhatsApp"
          url={`https://wa.me/${agent.item.whatsapp || agent.item.cellphone}`}
        />
      )}
      {website && (
        <ContactItem
          icon={<Icon width={24} icon="mdi:open-in-new" />}
          title="Visit website"
          url={website.url}
        />
      )}
    </Box>
  );
};

const Socials = ({ links }: { links: MoloAgentLink[] }) => (
  <Box>
    {links.map((link) => (
      <ContactItem
        key={link.id}
        icon={<Icon width={24} icon={`typcn:social-${link.typename}`} />}
        title={link.typename}
        url={link.url}
      />
    ))}
  </Box>
);

const ConnectDialog = ({ agent, share, ...props }: ConnectDialogProps & DialogProps) => {
  const { mutate } = useMutationShare();
  const appConfig = useAppConfig();
  const mediaUrl = useAgentMediaUrl(agent, 'Image');
  const [currentTab, setCurrentTab] = useState(0);
  const agentLinks = useMemo(
    () => (agent.item.Links.item || []).filter(({ typename }) => enabledSocialLinks.has(typename)),
    [agent],
  );

  const handleOpenContactForm = () => {
    const contactForm = castArray(agent.item.Profileforms.item).find(
      ({ type }) => type === 'contact',
    );
    if (!contactForm) return;
    mutate(
      {
        docId: share.item.assetuid,
        docContentType: share.item.contenttype,
        docTitle: share.item.contenttitle,
        docImage: share.item.shareimageurl,
        shareType: MoloShareType.contactForm,
        state: MoloShareState.unauthorized,
        agentId: agent.item.id,
        processId: share.item.processid,
        clientId: share.item.clientid,
      },
      {
        onSuccess: (share) => {
          const destinationUrl = completeParametrizedUrl(contactForm.url, {
            token: share.item.token,
            sharetoken: share.item.token,
            environment: appConfig?.config?.environment,
            firstname: agent.item.firstname,
            lastname: agent.item.surname,
            email: agent.item.email,
            telephone: agent.item.cellphone,
            process_id: share.item.processid,
            client_id: share.item.clientid,
          });
          window.open(destinationUrl, '_top');
        },
      },
    );
  };

  return (
    <Dialog {...props} PaperProps={{ sx: { width: 1, maxWidth: 470 } }}>
      <Box sx={{ p: 3, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Typography variant="h4">Contact</Typography>
        <Button
          variant="outlined"
          color="white"
          startIcon={<Icon icon="mdi:chevron-left" />}
          onClick={(event) => props.onClose?.(event, 'escapeKeyDown')}
        >
          Back
        </Button>
      </Box>
      <Divider />
      <DialogContent>
        <Box bgcolor="background.default" sx={{ p: 2, display: 'flex' }}>
          <Box>
            {mediaUrl ? (
              <img src={mediaUrl} width={70} />
            ) : (
              <Avatar
                alt={`${agent.item.firstname} ${agent.item.surname}`}
                sx={{ width: 70, height: 70 }}
              />
            )}
          </Box>
          <Box sx={{ ml: 2 }}>
            <Typography variant="h5" fontWeight={600}>
              {agent.item.firstname} {agent.item.surname}
            </Typography>
            <Typography sx={{ mt: 1 }} variant="subtitle2" color="text.secondary" lineHeight={1.1}>
              {agent.item.position}
            </Typography>
          </Box>
        </Box>
        <Tabs
          sx={{ mb: 2 }}
          value={currentTab}
          variant="scrollable"
          scrollButtons="auto"
          allowScrollButtonsMobile
          onChange={(_, newValue: number) => setCurrentTab(newValue)}
        >
          <Tab label="Contact" />
          {agentLinks.length > 0 && <Tab label="Socials" />}
        </Tabs>
        {currentTab === 0 && <Contacts agent={agent} share={share} />}
        {currentTab === 1 && <Socials links={agentLinks} />}
        <Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
          <Button onClick={handleOpenContactForm} variant="contained" color="secondary">
            Leave your details
          </Button>
        </Box>
      </DialogContent>
    </Dialog>
  );
};

export default ConnectDialog;