🔀 Merge branch 'trunk'

# Conflicts:
#	modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabOverview.js
This commit is contained in:
Philipp Stracker 2025-01-28 13:12:50 +01:00
commit 6aecfdad31
No known key found for this signature in database
70 changed files with 1178 additions and 821 deletions

View file

@ -12,7 +12,7 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
}
return (
<span className="ppcp-r-feature-item__notes">
<span className="ppcp--item-notes">
{ notes.map( ( note, index ) => (
<span key={ index }>{ note }</span>
) ) }
@ -20,30 +20,39 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
);
};
const renderButton = ( button ) => {
const buttonElement = (
<Button
className={ button.class ? button.class : '' }
key={ button.text }
isBusy={ props.actionProps?.isBusy }
variant={ button.type }
onClick={ button.onClick }
>
{ button.text }
</Button>
);
const FeatureButton = ( {
className,
variant,
text,
isBusy,
url,
urls,
onClick,
} ) => {
const buttonProps = {
className,
isBusy,
variant,
};
// If there's a URL (either direct or in urls object), wrap in anchor tag
if ( button.url || button.urls ) {
const href = button.urls ? button.urls.live : button.url;
return (
<a href={ href } key={ button.text }>
{ buttonElement }
</a>
);
if ( url || urls ) {
buttonProps.href = urls ? urls.live : url;
buttonProps.target = '_blank';
}
if ( ! buttonProps.href ) {
buttonProps.onClick = onClick;
}
return buttonElement;
return <Button { ...buttonProps }>{ text }</Button>;
};
const renderDescription = () => {
return (
<span
className="ppcp-r-feature-item__description ppcp-r-settings-block__feature__description"
dangerouslySetInnerHTML={ { __html: description } }
/>
);
};
return (
@ -56,13 +65,33 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
) }
</Title>
<Description className="ppcp-r-settings-block__feature__description">
{ description }
{ renderDescription() }
{ printNotes() }
</Description>
</Header>
<Action>
<div className="ppcp-r-feature-item__buttons">
{ props.actionProps?.buttons.map( renderButton ) }
<div className="ppcp--action-buttons">
{ props.actionProps?.buttons.map(
( {
class: className,
type,
text,
url,
urls,
onClick,
} ) => (
<FeatureButton
key={ text }
className={ className }
variant={ type }
text={ text }
isBusy={ props.actionProps.isBusy }
url={ url }
urls={ urls }
onClick={ onClick }
/>
)
) }
</div>
</Action>
</SettingsBlock>

View file

@ -2,7 +2,6 @@ import { ToggleControl } from '@wordpress/components';
import SettingsBlock from '../SettingsBlock';
import PaymentMethodIcon from '../PaymentMethodIcon';
import data from '../../../utils/data';
const PaymentMethodItemBlock = ( {
paymentMethod,
@ -11,33 +10,35 @@ const PaymentMethodItemBlock = ( {
isSelected,
} ) => {
return (
<SettingsBlock className="ppcp-r-settings-block__payment-methods__item">
<div className="ppcp-r-settings-block__payment-methods__item__inner">
<div className="ppcp-r-settings-block__payment-methods__item__title-wrapper">
<PaymentMethodIcon
icons={ [ paymentMethod.icon ] }
type={ paymentMethod.icon }
/>
<span className="ppcp-r-settings-block__payment-methods__item__title">
<SettingsBlock className="ppcp--method-item" separatorAndGap={ false }>
<div className="ppcp--method-inner">
<div className="ppcp--method-title-wrapper">
{ paymentMethod?.icon && (
<PaymentMethodIcon
icons={ [ paymentMethod.icon ] }
type={ paymentMethod.icon }
/>
) }
<span className="ppcp--method-title">
{ paymentMethod.itemTitle }
</span>
</div>
<p className="ppcp-r-settings-block__payment-methods__item__description">
<p className="ppcp--method-description">
{ paymentMethod.itemDescription }
</p>
<div className="ppcp-r-settings-block__payment-methods__item__footer">
<div className="ppcp--method-footer">
<ToggleControl
__nextHasNoMarginBottom={ true }
checked={ isSelected }
onChange={ onSelect }
/>
{ paymentMethod?.fields && onTriggerModal && (
<div
className="ppcp-r-settings-block__payment-methods__item__settings"
<Button
className="ppcp--method-settings"
onClick={ onTriggerModal }
>
{ data().getImage( 'icon-settings.svg' ) }
</div>
<Icon icon={ cog } />
</Button>
) }
</div>
</div>

View file

@ -1,42 +1,38 @@
import SettingsBlock from '../SettingsBlock';
import PaymentMethodItemBlock from './PaymentMethodItemBlock';
import { usePaymentMethods } from '../../../data/payment/hooks';
import { PaymentHooks } from '../../../data';
const PaymentMethodsBlock = ( {
paymentMethods,
className = '',
onTriggerModal,
} ) => {
const { setPersistent } = usePaymentMethods();
// TODO: This is not a reusable component, as it's connected to the Redux store.
const PaymentMethodsBlock = ( { paymentMethods = [], onTriggerModal } ) => {
const { changePaymentSettings } = PaymentHooks.useStore();
if ( ! paymentMethods?.length ) {
const handleSelect = ( methodId, isSelected ) =>
changePaymentSettings( methodId, {
enabled: isSelected,
} );
if ( ! paymentMethods.length ) {
return null;
}
const handleSelect = ( paymentMethod, isSelected ) => {
setPersistent( paymentMethod.id, {
...paymentMethod,
enabled: isSelected,
} );
};
return (
<SettingsBlock
className={ `ppcp-r-settings-block__payment-methods ${ className }` }
>
{ paymentMethods.map( ( paymentMethod ) => (
<PaymentMethodItemBlock
key={ paymentMethod.id }
paymentMethod={ paymentMethod }
isSelected={ paymentMethod.enabled }
onSelect={ ( checked ) =>
handleSelect( paymentMethod, checked )
}
onTriggerModal={ () =>
onTriggerModal?.( paymentMethod.id )
}
/>
) ) }
<SettingsBlock className="ppcp--grid ppcp-r-settings-block__payment-methods">
{ paymentMethods
// Remove empty/invalid payment method entries.
.filter( ( m ) => m.id )
.map( ( paymentMethod ) => (
<PaymentMethodItemBlock
key={ paymentMethod.id }
paymentMethod={ paymentMethod }
isSelected={ paymentMethod.enabled }
onSelect={ ( checked ) =>
handleSelect( paymentMethod.id, checked )
}
onTriggerModal={ () =>
onTriggerModal?.( paymentMethod.id )
}
/>
) ) }
</SettingsBlock>
);
};