import './Support.styles.scss'; import { Button, Card, Modal, Typography } from 'antd'; import updateCreditCardApi from 'api/billing/checkout'; import logEvent from 'api/common/logEvent'; import { SOMETHING_WENT_WRONG } from 'constants/api'; import { FeatureKeys } from 'constants/features'; import useFeatureFlags from 'hooks/useFeatureFlag'; import useLicense from 'hooks/useLicense'; import { useNotifications } from 'hooks/useNotifications'; import { Book, Cable, Calendar, CreditCard, Github, MessageSquare, Slack, X, } from 'lucide-react'; import { useEffect, useState } from 'react'; import { useMutation } from 'react-query'; import { useHistory } from 'react-router-dom'; import { ErrorResponse, SuccessResponse } from 'types/api'; import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout'; import { License } from 'types/api/licenses/def'; const { Title, Text } = Typography; interface Channel { key: any; name?: string; icon?: JSX.Element; title?: string; url: any; btnText?: string; } const channelsMap = { documentation: 'documentation', github: 'github', slack_community: 'slack_community', chat: 'chat', schedule_call: 'schedule_call', slack_connect: 'slack_connect', }; const supportChannels = [ { key: 'documentation', name: 'Documentation', icon: , title: 'Find answers in the documentation.', url: 'https://signoz.io/docs/', btnText: 'Visit docs', }, { key: 'github', name: 'Github', icon: , title: 'Create an issue on GitHub to report bugs or request new features.', url: 'https://github.com/SigNoz/signoz/issues', btnText: 'Create issue', }, { key: 'slack_community', name: 'Slack Community', icon: , title: 'Get support from the SigNoz community on Slack.', url: 'https://signoz.io/slack', btnText: 'Join Slack', }, { key: 'chat', name: 'Chat', icon: , title: 'Get quick support directly from the team.', url: '', btnText: 'Launch chat', }, { key: 'schedule_call', name: 'Schedule a call', icon: , title: 'Schedule a call with the founders.', url: 'https://calendly.com/pranay-signoz/signoz-intro-calls', btnText: 'Schedule call', }, { key: 'slack_connect', name: 'Slack Connect', icon: , title: 'Get a dedicated support channel for your team.', url: '', btnText: 'Request Slack connect', }, ]; export default function Support(): JSX.Element { const history = useHistory(); const { notifications } = useNotifications(); const { data: licenseData, isFetching } = useLicense(); const [activeLicense, setActiveLicense] = useState(null); const [isAddCreditCardModalOpen, setIsAddCreditCardModalOpen] = useState( false, ); const handleChannelWithRedirects = (url: string): void => { window.open(url, '_blank'); }; useEffect(() => { if (history?.location?.state) { const histroyState = history?.location?.state as any; if (histroyState && histroyState?.from) { logEvent(`Support : From URL : ${histroyState.from}`, {}); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleSlackConnectRequest = (): void => { const recipient = 'support@signoz.io'; const subject = 'Slack Connect Request'; const body = `I'd like to request a dedicated Slack Connect channel for me and my team. Users (emails) to include besides mine:`; // Create the mailto link const mailtoLink = `mailto:${recipient}?subject=${encodeURIComponent( subject, )}&body=${encodeURIComponent(body)}`; // Open the default email client window.location.href = mailtoLink; }; const isPremiumChatSupportEnabled = useFeatureFlags(FeatureKeys.PREMIUM_SUPPORT)?.active || false; const showAddCreditCardModal = !isPremiumChatSupportEnabled && !licenseData?.payload?.trialConvertedToSubscription; useEffect(() => { const activeValidLicense = licenseData?.payload?.licenses?.find( (license) => license.isCurrent === true, ) || null; setActiveLicense(activeValidLicense); }, [licenseData, isFetching]); const handleBillingOnSuccess = ( data: ErrorResponse | SuccessResponse, ): void => { if (data?.payload?.redirectURL) { const newTab = document.createElement('a'); newTab.href = data.payload.redirectURL; newTab.target = '_blank'; newTab.rel = 'noopener noreferrer'; newTab.click(); } }; const handleBillingOnError = (): void => { notifications.error({ message: SOMETHING_WENT_WRONG, }); }; const { mutate: updateCreditCard, isLoading: isLoadingBilling } = useMutation( updateCreditCardApi, { onSuccess: (data) => { handleBillingOnSuccess(data); }, onError: handleBillingOnError, }, ); const handleAddCreditCard = (): void => { logEvent('Add Credit card modal: Clicked', { source: `chat`, page: 'support', }); updateCreditCard({ licenseKey: activeLicense?.key || '', successURL: window.location.href, cancelURL: window.location.href, }); }; const handleChat = (): void => { if (showAddCreditCardModal) { setIsAddCreditCardModalOpen(true); } else if (window.Intercom) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore window.Intercom('show'); } }; const handleChannelClick = (channel: Channel): void => { logEvent(`Support : ${channel.name}`, {}); switch (channel.key) { case channelsMap.documentation: case channelsMap.github: case channelsMap.slack_community: case channelsMap.schedule_call: handleChannelWithRedirects(channel.url); break; case channelsMap.chat: handleChat(); break; case channelsMap.slack_connect: handleSlackConnectRequest(); break; default: handleChannelWithRedirects('https://signoz.io/slack'); break; } }; return (
Support We are here to help in case of questions or issues. Pick the channel that is most convenient for you.
{supportChannels.map( (channel): JSX.Element => (
{channel.icon} {channel.name}{' '} {channel.title}
), )}
{/* Add Credit Card Modal */} Add Credit Card for Chat Support} open={isAddCreditCardModalOpen} closable onCancel={(): void => setIsAddCreditCardModalOpen(false)} destroyOnClose footer={[ , , ]} > You're currently on Trial plan . Add a credit card to access SigNoz chat support to your workspace.
); }