import './UserCalendars.scss' import { __ } from '@wordpress/i18n' import classNames from 'classnames' import warningIcon from '../../../../../public/images/warning-icon.png' import successIcon from '../../../../../public/images/succesessful-icon.png' import iconGoogle from '../../../../../public/images/icon-google.svg' import iconMicrosoft from '../../../../../public/images/icon-microsoft.svg' import { useDispatch, useSelect } from '@wordpress/data' import { addQueryArgs } from '@wordpress/url' import { useCallback, useEffect, useMemo, useState } from 'react' import { store } from '../../../../store/backend' const urlCreationTimes = new Map() const useCountdownTimer = (url: string, initialMinutes: number = 5) => { const getCreationTime = useCallback(() => { if (!urlCreationTimes.has(url)) { urlCreationTimes.set(url, Date.now()) } return urlCreationTimes.get(url)! }, [url]) const [currentTime, setCurrentTime] = useState(Date.now()) const creationTime = getCreationTime() const expirationTime = creationTime + initialMinutes * 60 * 1000 const timeLeft = Math.max( 0, Math.floor((expirationTime - currentTime) / 1000) ) const isExpired = timeLeft <= 0 useEffect(() => { if (isExpired) { return } const timer = setInterval(() => { setCurrentTime(Date.now()) }, 1000) return () => clearInterval(timer) }, [isExpired]) const formatTime = useCallback((seconds: number) => { const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins}:${secs.toString().padStart(2, '0')}` }, []) return { timeLeft, isExpired, formattedTime: formatTime(timeLeft), } } interface TimedLinkProps { href: string children: React.ReactNode className?: string target?: string rel?: string } const TimedLink: React.FC = ({ href, children, className, target = '_blank', rel = 'noopener noreferrer', }) => { const { isExpired, formattedTime } = useCountdownTimer(href, 5) if (isExpired) { return (
{__( 'Link expired. Please reload the page to get a new link.', 'webba-booking-lite' )}
) } return (
{children}
{__('Link expires in:', 'webba-booking-lite')} {formattedTime}
) } export const CalendarItem = ({ calendar }: any) => { const calendarId = calendar?.id const easyAuth = calendar?.easy_auth const provider = calendar?.provider || 'google' const { updateUserCalendar } = useDispatch(store) const authData = useSelect( (select: any) => select(store).getGgAuthData(calendarId), [calendarId] ) const isLoading = !authData || (typeof authData === 'object' && Object.keys(authData).length === 0) const { isAuthenticated, internalError, authUrl, revokeUrl } = authData || {} const manageAuthLink = ( {__('Manage authorization', 'webba-booking-lite')} ) const controlButton = provider === 'outlook' && isAuthenticated && revokeUrl ? ( {__('Revoke', 'webba-booking-lite')} ) : ( manageAuthLink ) const isOutlook = provider === 'outlook' const providerIcon = isOutlook ? iconMicrosoft : iconGoogle const providerLabel = isOutlook ? __('Outlook', 'webba-booking-lite') : provider === 'google' ? __('Google', 'webba-booking-lite') : provider const calendarOptions = useMemo(() => { const raw = authData?.calendars if (!raw) return [] if (Array.isArray(raw)) { return raw.map((item: any) => ({ value: item?.id ?? item, label: item?.name ?? item?.id ?? item, })) } if (typeof raw === 'object' && Object.keys(raw).length > 0) { return Object.entries(raw).map(([id, name]) => ({ value: id, label: String(name), })) } return [] }, [authData?.calendars]) const handleCalendarInProviderChange = useCallback( (e: React.ChangeEvent) => { const newId = e.target.value updateUserCalendar({ ...calendar, in_provider_id: newId, }) }, [calendar, updateUserCalendar] ) return (

{calendar?.name}

{providerLabel} {providerLabel}
{__('Mode: ', 'webba-booking-lite')} {calendar?.mode}
{isAuthenticated && (
{__('Calendar in Provider Account: ', 'webba-booking-lite')} {calendarOptions.length > 0 ? ( ) : ( {calendar?.in_provider_id} )}
)}
{isLoading ? (
{__('Loading...', 'webba-booking-lite')}
) : easyAuth === 'yes' ? (
{ {isAuthenticated ? __('Authorized', 'webba-booking-lite') : __('Not authorized', 'webba-booking-lite')}
{!isAuthenticated && !internalError && authUrl && ( {__('Authorize', 'webba-booking-lite')} )} {!isAuthenticated && internalError && (
{__( 'Internal error occurred. Please try again later.', 'webba-booking-lite' )}
)} {isAuthenticated && revokeUrl && ( {__('Revoke', 'webba-booking-lite')} )}
) : ( <> {isAuthenticated ? (
{__('Success', {__('Authorized', 'webba-booking-lite')}
{controlButton}
) : (
{__('Warning', {internalError ? __('Internal error', 'webba-booking-lite') : __('Not authorized', 'webba-booking-lite')}
{internalError ? (
{__( 'An internal error occurred. Please check API credentials and calendar ID.', 'webba-booking-lite' )} . {controlButton}
) : ( <> {authUrl ? ( {__('Authorize', 'webba-booking-lite')} ) : (
{__( 'Click on the link below to start the authorization process', 'webba-booking-lite' )} . {controlButton}
)} )}
)} )}
) }