import React, { useState, useEffect, useCallback, FC } from 'react' import apiFetch from '@wordpress/api-fetch' import { Credentials, CredentialsResponse } from './model/models' import passwordImage from '../../assets/img/illustration-password.png' import activatedImage from '../../assets/img/happy.svg' import almostActivatedImage from '../../assets/img/not-so-happy.svg' import { Button, ButtonGroup, Notice, Card, CardBody, } from '@wordpress/components' import './styles.scss' import { useI18n } from '@wordpress/react-i18n' import { arrowRight } from '@wordpress/icons' import FeedbackForm from './components/FeedbackForm' import ToggleRemoteLog from './ToggleRemoteLog' import ToggleDarkMode from './ToggleDarkMode' // @ts-expect-error 7016 import { getAdminLink } from '@woocommerce/settings' import { useEnableWpCompatOverlaySlot } from '@wordpress/ui' type CredentialsState = { apiKey: string webShopId: string } type ErrorsState = { credentialsError?: string webShopIdError?: string noAccessToWebshopError?: string } export declare interface SettingsProps { onTaskComplete?: () => void } const Settings: FC = ({ onTaskComplete }) => { const [credentials, setCredentials] = useState({ apiKey: '', webShopId: '', }) const [isLoading, setIsLoading] = useState(false) const [isSaving, setIsSaving] = useState(false) const [formActive, setFormActive] = useState(false) const [errors, setErrors] = useState({}) const [missingCredentials, setMissingCredentials] = useState(false) const [failedCredentials, setFailedCredentials] = useState(false) const [keyPresent, setKeyPresent] = useState(false) const [clipboardRequested, setClipboardRequested] = useState(false) const [clipboardSupported, setClipboardSupported] = useState(false) useEnableWpCompatOverlaySlot() const { __ } = useI18n() // @ts-expect-error 2339 const blockCheckoutActive = window.shopDetails?.checkoutBlockActive // @ts-expect-error 2339 const shopAddressConfigured = window.shopDetails?.shopAddressConfigured const toggleFormActive = useCallback(() => { setFormActive(!formActive) if (!formActive) { setCredentials(prev => ({ ...prev, apiKey: '', })) setErrors({}) } else { setFailedCredentials(false) } }, [formActive]) useEffect(() => { const fetchCredentials = async () => { setIsLoading(true) const response: Credentials = await apiFetch({ path: '/posten-bring-checkout/credentials', }) if (response) { const credentialsMissing = !(response.webshop_id && response.apikey) setMissingCredentials(credentialsMissing) setCredentials({ apiKey: credentialsMissing ? '' : response.apikey, webShopId: credentialsMissing ? '' : response.webshop_id, }) if (!credentialsMissing && onTaskComplete) { onTaskComplete() } } else { setMissingCredentials(true) } setIsLoading(false) } fetchCredentials() }, []) const storeCredentials = async ( e: React.FormEvent | undefined, creds: CredentialsState | undefined ) => { e && e.preventDefault && e.preventDefault() setErrors({}) setFailedCredentials(false) setIsSaving(true) const response: CredentialsResponse = await apiFetch({ path: 'posten-bring-checkout/credentials', method: 'POST', data: { apikey: creds ? creds.apiKey : credentials.apiKey, webshop_id: creds ? creds.webShopId : credentials.webShopId, }, }) if ( !( response.validCredentials && response.validWebshopId && response.accessToWebshop ) ) { setErrors({ credentialsError: response.validCredentials ? undefined : __('Invalid API Key', 'posten-bring-checkout'), noAccessToWebshopError: response.accessToWebshop ? undefined : __( 'Provided API Key has no access to this webshop', 'posten-bring-checkout' ), }) setFailedCredentials(true) setIsSaving(false) } else { setClipboardRequested(false) setKeyPresent(false) setIsSaving(false) setMissingCredentials(false) setFormActive(false) onTaskComplete && onTaskComplete() } } const fillOutForm = useCallback(async () => { setClipboardRequested(true) try { const clipboardText = await navigator.clipboard.readText() const [webShopId, apiKey] = clipboardText.split(':') setClipboardSupported(true) const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/ if (uuidRegex.test(webShopId) && base64Regex.test(apiKey)) { const creds = { apiKey: apiKey.trim(), webShopId: webShopId.trim(), } setCredentials(creds) setKeyPresent(true) await storeCredentials(undefined, creds) // Save credentials } else { setKeyPresent(false) } } catch (err: any) { if (err.name === 'NotAllowedError') { setClipboardSupported(false) } else if (err.name === 'NotFoundError') { setClipboardSupported(false) } setKeyPresent(false) } }, []) const handleChange = (e: React.ChangeEvent) => { const { value } = e.target const [webShopId, apiKey] = value.split(':') if (webShopId && apiKey) { setCredentials({ webShopId: webShopId.trim(), apiKey: apiKey.trim(), }) } // Clear any previous errors setErrors({}) } const ErrorNotice = () => (
{__('⚠️ A problem has occurred', 'posten-bring-checkout')}

{__( 'Please look carefully through the values you entered.', 'posten-bring-checkout' )}

) const MissingAddressNotice = () => (
{__('Missing address', 'posten-bring-checkout')}

{__( 'No webshop title or address has been configured. Posten Bring Checkout requires a complete address to be able to present shipping options.', 'posten-bring-checkout' )}

) return (

{__('Settings', 'posten-bring-checkout')}


{isLoading ? (
{__('Fetching settings…', 'posten-bring-checkout')}
) : ( <>
{missingCredentials && (

{__('Mybring key', 'posten-bring-checkout')}

{__( 'Register your webshop in Mybring. You will get your API key there.', 'posten-bring-checkout' )}

{(missingCredentials || formActive) && ( )}
)}
{(missingCredentials || formActive) && (
{clipboardRequested === false && ( <>

{__('Activate plugin', 'posten-bring-checkout')}

{__('Go to', 'posten-bring-checkout')}{' '} {__( 'Mybrings checkout area', 'posten-bring-checkout' )} {' '} {__( 'navigate to your shop configuration and get your key. Come back here when you have copied the key.', 'posten-bring-checkout' )}

)} {clipboardRequested === true && keyPresent === false && clipboardSupported === true && ( <>

{__( 'Activate plugin', 'posten-bring-checkout' )}

{__( 'Could not find key!', 'posten-bring-checkout' )}{' '}
{__('Go to', 'posten-bring-checkout')}{' '} {__( 'Mybrings checkout area', 'posten-bring-checkout' )} {' '} {__( 'and click Copy key again.', 'posten-bring-checkout' )}{' '}

)} {clipboardRequested === true && clipboardSupported === false && ( <>

{__( 'Activate plugin', 'posten-bring-checkout' )}

{__( 'Paste your key here:', 'posten-bring-checkout' )}

)} {clipboardRequested === true && keyPresent === true && (

{__('Activating…', 'posten-bring-checkout')}

)}
{clipboardRequested && !clipboardSupported && ( )} {(errors.webShopIdError || errors.noAccessToWebshopError) && ( ⚠️{' '} {errors.webShopIdError || errors.noAccessToWebshopError} )}
{!keyPresent && credentials.apiKey === '' && ( )} {credentials.apiKey !== '' && credentials.webShopId !== '' && ( )} {formActive && ( )}
)} {credentials.webShopId !== '' && !missingCredentials && !formActive && (
{shopAddressConfigured && (

{__( 'Posten Bring Checkout is active!', 'posten-bring-checkout' )}

)} {!shopAddressConfigured && (

{__( 'Posten Bring Checkout is almost ready for usage…', 'posten-bring-checkout' )}

)} {!missingCredentials && !shopAddressConfigured && ( )}
)}
{failedCredentials && }
{!missingCredentials && !blockCheckoutActive && ( )} {credentials.webShopId !== '' && !missingCredentials && !formActive && shopAddressConfigured && }
{credentials.webShopId !== '' && !missingCredentials && ( )} )}
) } export default Settings