import { useState, useEffect } from 'react'; import { PublicClientApplication } from "@azure/msal-browser"; import { Client } from "@microsoft/microsoft-graph-client"; import { useTranslation } from 'react-i18next'; import { Button, Center } from 'components'; import { Loader } from '../Loading/loadingStyle'; import { LoginButton, CalendarList, CheckboxInput, CheckboxLabel, CalendarLabel, Info, Options, Title, Icon, } from '../GoogleCalendar/googleCalendarStyle'; import outlookLogo from 'res/outlook.svg'; const scopes = ['Calendars.Read', 'Calendars.Read.Shared']; // Initialise the MSAL object const publicClientApplication = new PublicClientApplication({ auth: { clientId: '5d1ab8af-1ba3-4b79-b033-b0ee509c2be6', redirectUri: process.env.NODE_ENV === 'production' ? 'https://crab.fit' : 'http://localhost:3000', }, cache: { cacheLocation: 'sessionStorage', storeAuthStateInCookie: true, }, }); const getAuthenticatedClient = accessToken => { const client = Client.init({ authProvider: done => done(null, accessToken), }); return client; }; const OutlookCalendar = ({ timeZone, timeMin, timeMax, onImport }) => { const [client, setClient] = useState(undefined); const [calendars, setCalendars] = useState(undefined); const [freeBusyLoading, setFreeBusyLoading] = useState(false); const { t } = useTranslation('event'); const checkLogin = async () => { const accounts = publicClientApplication.getAllAccounts(); if (accounts && accounts.length > 0) { try { const accessToken = await getAccessToken(); setClient(getAuthenticatedClient(accessToken)); } catch (e) { console.error(e); signOut(); } } else { setClient(null); } }; const signIn = async () => { try { await publicClientApplication.loginPopup({ scopes }); } catch (e) { console.error(e); } finally { checkLogin(); } }; const signOut = async () => { try { await publicClientApplication.logoutRedirect({ onRedirectNavigate: () => false, }); } catch (e) { console.error(e); } finally { checkLogin(); } }; const getAccessToken = async () => { try { const accounts = publicClientApplication.getAllAccounts(); if (accounts.length <= 0) throw new Error('login_required'); // Try to get silently const result = await publicClientApplication.acquireTokenSilent({ scopes, account: accounts[0], }); return result.accessToken; } catch (e) { if ([ 'consent_required', 'interaction_required', 'login_required', 'no_account_in_silent_request' ].includes(e.message)) { // Try to get with popup const result = await publicClientApplication.acquireTokenPopup({ scopes }); return result.accessToken; } else { throw e; } } }; const importAvailability = () => { setFreeBusyLoading(true); gtag('event', 'outlook_cal_sync', { 'event_category': 'event', }); client.api('/me/calendar/getSchedule').post({ schedules: calendars.filter(c => c.checked).map(c => c.id), startTime: { dateTime: timeMin, timeZone, }, endTime: { dateTime: timeMax, timeZone, }, availabilityViewInterval: 30, }) .then(response => { onImport(response.value.reduce((busy, c) => c.hasOwnProperty('error') ? busy : [...busy, ...c.scheduleItems.filter(item => item.status === 'busy' || item.status === 'tentative')], [])); }) .catch(e => { console.error(e); signOut(); }) .finally(() => setFreeBusyLoading(false)); }; useEffect(() => checkLogin(), []); useEffect(() => { if (client) { client.api('/me/calendars').get() .then(response => { setCalendars(response.value.map(item => ({ 'name': item.name, 'description': item.owner.name, 'id': item.owner.address, 'color': item.hexColor, 'checked': item.isDefaultCalendar === true, }))); }) .catch(e => { console.error(e); signOut(); }); } }, [client]); return ( <> {!client ? (
) : ( <Icon src={outlookLogo} alt="" /> {/* eslint-disable-next-line */} <strong>{t('event:you.outlook_cal')}</strong> (<a href="#" onClick={e => { e.preventDefault(); signOut(); }}>{t('event:you.google_cal.logout')}</a>) {calendars !== undefined && !calendars.every(c => c.checked) && ( /* eslint-disable-next-line */ { e.preventDefault(); setCalendars(calendars.map(c => ({...c, checked: true}))); }}>{t('event:you.google_cal.select_all')} )} {calendars !== undefined && calendars.every(c => c.checked) && ( /* eslint-disable-next-line */ { e.preventDefault(); setCalendars(calendars.map(c => ({...c, checked: false}))); }}>{t('event:you.google_cal.select_none')} )} {calendars !== undefined ? calendars.map(calendar => (
setCalendars(calendars.map(c => c.id === calendar.id ? {...c, checked: !c.checked} : c))} /> {calendar.name}
)) : ( )} {calendars !== undefined && ( <> {t('event:you.google_cal.info')} )}
)} ); }; export default OutlookCalendar;