Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:FosterCommerce/foster-checkout i…
Browse files Browse the repository at this point in the history
…nto develop
  • Loading branch information
sjcallender committed Sep 19, 2024
2 parents f734273 + 14556cb commit 30e5378
Show file tree
Hide file tree
Showing 24 changed files with 595 additions and 156 deletions.
Binary file removed src/.DS_Store
Binary file not shown.
164 changes: 164 additions & 0 deletions src/FosterCheckout.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

namespace fostercommerce\craftfostercheckout;

use CommerceGuys\Addressing\AddressFormat\AddressField;
use Craft;
use craft\base\Model;
use craft\base\Plugin;
use craft\events\DefineAddressFieldLabelEvent;
use craft\events\DefineAddressFieldsEvent;
use craft\events\DefineAddressSubdivisionsEvent;
use craft\events\RegisterTemplateRootsEvent;
use craft\events\RegisterUrlRulesEvent;
use craft\services\Addresses;
use craft\web\twig\variables\CraftVariable;
use craft\web\UrlManager;
use craft\web\View;
Expand Down Expand Up @@ -146,5 +151,164 @@ function (RegisterUrlRulesEvent $event): void {
];
}
);

// Although a county is not actually required for UK addresses (the postal service ignores it)
// it is normal in the UK to write addresses with a county
// with that said, UK counties are a minefield so we should not make the field required
// but simply provide it as an option with a reasonable list of county names

// Adds the Administrative area to UK addresses
Event::on(
Addresses::class,
Addresses::EVENT_DEFINE_USED_FIELDS,
function (DefineAddressFieldsEvent $event): void {
if ($event->countryCode === 'GB') {
$event->fields[] = AddressField::ADMINISTRATIVE_AREA;
}
}
);

// Changes the label of the Administrative area field to "County" for UK addresses
Event::on(
Addresses::class,
Addresses::EVENT_DEFINE_FIELD_LABEL,
function (DefineAddressFieldLabelEvent $event): void {
if (
$event->countryCode === 'GB' &&
$event->field === AddressField::ADMINISTRATIVE_AREA
) {
$event->label = 'County';
}
}
);

// A 'reasonable' list of UK county names
Event::on(
Addresses::class,
Addresses::EVENT_DEFINE_ADDRESS_SUBDIVISIONS,
function (DefineAddressSubdivisionsEvent $event): void {
if (count($event->parents) === 1 && $event->parents[0] === 'GB') {
$event->subdivisions = [
'' => 'N/A',
'Aberdeenshire' => 'Aberdeenshire',
'Angus' => 'Angus',
'Argyll' => 'Argyll',
'Avon' => 'Avon',
'Ayrshire' => 'Ayrshire',
'Banffshire' => 'Banffshire',
'Bedfordshire' => 'Bedfordshire',
'Berkshire' => 'Berkshire',
'Berwickshire' => 'Berwickshire',
'Buckinghamshire' => 'Buckinghamshire',
'Caithness' => 'Caithness',
'Cambridgeshire' => 'Cambridgeshire',
'Cheshire' => 'Cheshire',
'Clackmannanshire' => 'Clackmannanshire',
'Cleveland' => 'Cleveland',
'Clwyd' => 'Clwyd',
'Cornwall' => 'Cornwall',
'County Antrim' => 'County Antrim',
'County Armagh' => 'County Armagh',
'County Down' => 'County Down',
'County Durham' => 'County Durham',
'County Fermanagh' => 'County Fermanagh',
'County Londonderry' => 'County Londonderry',
'County Tyrone' => 'County Tyrone',
'Cumbria' => 'Cumbria',
'Derbyshire' => 'Derbyshire',
'Devon' => 'Devon',
'Dorset' => 'Dorset',
'Dumfriesshire' => 'Dumfriesshire',
'Dunbartonshire' => 'Dunbartonshire',
'Dyfed' => 'Dyfed',
'East Lothian' => 'East Lothian',
'East Sussex' => 'East Sussex',
'Essex' => 'Essex',
'Fife' => 'Fife',
'Gloucestershire' => 'Gloucestershire',
'Gwent' => 'Gwent',
'Gwynedd' => 'Gwynedd',
'Hampshire' => 'Hampshire',
'Herefordshire' => 'Herefordshire',
'Hertfordshire' => 'Hertfordshire',
'Inverness-shire' => 'Inverness-shire',
'Isle of Arran' => 'Isle of Arran',
'Isle of Barra' => 'Isle of Barra',
'Isle of Benbecula' => 'Isle of Benbecula',
'Isle of Bute' => 'Isle of Bute',
'Isle of Canna' => 'Isle of Canna',
'Isle of Coll' => 'Isle of Coll',
'Isle of Colonsay' => 'Isle of Colonsay',
'Isle of Cumbrae' => 'Isle of Cumbrae',
'Isle of Eigg' => 'Isle of Eigg',
'Isle of Gigha' => 'Isle of Gigha',
'Isle of Harris' => 'Isle of Harris',
'Isle of Iona' => 'Isle of Iona',
'Isle of Islay' => 'Isle of Islay',
'Isle of Jura' => 'Isle of Jura',
'Isle of Lewis' => 'Isle of Lewis',
'Isle of Mull' => 'Isle of Mull',
'Isle of North Uist' => 'Isle of North Uist',
'Isle of Rhum' => 'Isle of Rhum',
'Isle of Scalpay' => 'Isle of Scalpay',
'Isle of Skye' => 'Isle of Skye',
'Isle of South Uist' => 'Isle of South Uist',
'Isle of Tiree' => 'Isle of Tiree',
'Isle of Wight' => 'Isle of Wight',
'Kent' => 'Kent',
'Kincardineshire' => 'Kincardineshire',
'Kinross-shire' => 'Kinross-shire',
'Kirkcudbrightshire' => 'Kirkcudbrightshire',
'Lanarkshire' => 'Lanarkshire',
'Lancashire' => 'Lancashire',
'Leicestershire' => 'Leicestershire',
'Lincolnshire' => 'Lincolnshire',
'London' => 'London',
'Merseyside' => 'Merseyside',
'Mid Glamorgan' => 'Mid Glamorgan',
'Middlesex' => 'Middlesex',
'Midlothian' => 'Midlothian',
'Morayshire' => 'Morayshire',
'Nairnshire' => 'Nairnshire',
'Norfolk' => 'Norfolk',
'North Humberside' => 'North Humberside',
'North Yorkshire' => 'North Yorkshire',
'Northamptonshire' => 'Northamptonshire',
'Northumberland' => 'Northumberland',
'Nottinghamshire' => 'Nottinghamshire',
'Orkney' => 'Orkney',
'Oxfordshire' => 'Oxfordshire',
'Peeblesshire' => 'Peeblesshire',
'Perthshire' => 'Perthshire',
'Powys' => 'Powys',
'Renfrewshire' => 'Renfrewshire',
'Ross-shire' => 'Ross-shire',
'Roxburghshire' => 'Roxburghshire',
'Selkirkshire' => 'Selkirkshire',
'Shetland' => 'Shetland',
'Shropshire' => 'Shropshire',
'Somerset' => 'Somerset',
'South Glamorgan' => 'South Glamorgan',
'South Humberside' => 'South Humberside',
'South Yorkshire' => 'South Yorkshire',
'Staffordshire' => 'Staffordshire',
'Stirlingshire' => 'Stirlingshire',
'Suffolk' => 'Suffolk',
'Surrey' => 'Surrey',
'Sutherland' => 'Sutherland',
'Tyne and Wear' => 'Tyne and Wear',
'Warwickshire' => 'Warwickshire',
'West Glamorgan' => 'West Glamorgan',
'West Lothian' => 'West Lothian',
'West Midlands' => 'West Midlands',
'West Sussex' => 'West Sussex',
'West Yorkshire' => 'West Yorkshire',
'Wigtownshire' => 'Wigtownshire',
'Wiltshire' => 'Wiltshire',
'Worcestershire' => 'Worcestershire',
];
}
}
);
}
}
25 changes: 25 additions & 0 deletions src/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@
*/

return [
// Plugin options
'options' => [
// Whether or not to show the "save for later" button
'enableSaveForLater' => false, // true|false

// Whether or not to show the shipping estimator
'enableEstimatedShipping' => false, // true|false

// Whether or not to show the free shipping message
'enableFreeShippingMessage' => false, // true|false

// Whether or not to show the "No Image" placeholder images
'enablePlaceholderImages' => false,

// Whether or not to enable CSS page transitions
//(see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API#browser_compatibility for browser compatibility)
'enablePageTransitions' => false,
],
// Branding Settings
'branding' => [
// The brand primary custom color in HEX color
Expand All @@ -35,6 +53,13 @@
// The relative path from the web root of the logo file
// (ex. '/assets/images/logo.svg')
'logo' => '',

// The general component styles. Either 'rounded' (default) or 'flat'
'style' => 'rounded',

// The first part of the text in the title meta tag.
// Leave blank to use the Craft's siteName
'title' => '',
],

// Path Settings
Expand Down
10 changes: 10 additions & 0 deletions src/models/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,20 @@
*/
class Settings extends Model
{
public array $options = [
'enableSaveForLater' => false,
'enableEstimatedShipping' => false,
'enableFreeShippingMessage' => false,
'enablePlaceholderImages' => false,
'enablePageTransitions' => false,
];

public array $branding = [
'color' => '#1F2937',
'font' => 'Rubik',
'style' => 'rounded',
'logo' => '',
'title' => '',
];

public array $paths = [
Expand Down
18 changes: 18 additions & 0 deletions src/services/Checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@
*/
class Checkout extends Component
{
/*
* Gets the options settings array
*/
public function options(): array
{
$settings = FosterCheckout::getInstance()->getSettings();
return $settings->options;
}

/**
* Gets the value of a single option from the settings
*/
public function option(string $option): string|bool|null
{
$settings = FosterCheckout::getInstance()->getSettings();
return $settings->options[$option] ?? null;
}

/*
* Gets the branding settings array
*/
Expand Down
Binary file removed src/templates/.DS_Store
Binary file not shown.
Binary file removed src/templates/_components/.DS_Store
Binary file not shown.
5 changes: 2 additions & 3 deletions src/templates/_components/app/address-fields.twig
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,15 @@
</div>

{% else %}

{% include 'foster-checkout/_components/base/input-text-clearable' with {
context: context,
label: customField.name,
id: 'custom-field-' ~ customField.handle,
name: 'fields[' ~ customField.handle ~ ']',
type: 'text',
placeholder: customField.placeholder,
value: address ? address[customField.handle] : '',
required: customField.required,
value: address ? address[customField.handle]|escape : '',
required: customField.layoutElement.required,
errors: errors[customField.handle] ?? []
} %}

Expand Down
49 changes: 44 additions & 5 deletions src/templates/_components/app/coupon-code.twig
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
<div v-scope="{ isOpen: false }" class="border-t border-b border-gray-400">
{% set couponCodeError = cart.getFirstNotice(null, 'couponCode') ?? null %}
{% set couponCodeSuccess = craft.app.session.getFlash('success') ?? null %}

{% if couponCodeError %}
{% set couponMessage = couponCodeError.message %}
{% else %}
{% if couponCodeSuccess
and couponCodeSuccess == 'Coupon code added' | t('Foster Checkout')
and cart.couponCode
%}
{% set couponMessage = couponCodeSuccess %}
{% else %}
{% set couponMessage = null %}
{% endif %}
{% endif %}

<div
v-scope="{ isOpen: {{ couponMessage ? 'true' : 'false' }}, sending: false }"
class="border-t border-b border-gray-400"
>

<button class="flex justify-between items-center w-full py-4" @click="isOpen = !isOpen">
<span id="couponCodeLabel" class="font-medium text-gray-500">
Expand All @@ -22,10 +41,16 @@
aria-describedby="couponCodeDesc"
class="pb-6"
>
<form class="grid grid-cols-[1fr,_90px] gap-4" method="post">
<form
class="grid grid-cols-[1fr,_120px] items-start gap-4"
:class="sending ? 'grid-cols-[1fr,_120px]' : 'grid-cols-[1fr,_90px]'"
method="post"
@submit="sending = true"
>
{{ csrfInput() }}
{{ actionInput('commerce/cart/update-cart') }}
{{ hiddenInput('successMessage', 'Coupon code added' | t('Foster Checkout') | hash) }}
{{ hiddenInput('clearNotices', 'Yes, please!') }}
<p id="couponCodeDesc" class="sr-only">
{{ cart.couponCode|default ?
('Coupon Code'|t('foster-checkout') ~ ': ' ~ cart.couponCode) :
Expand All @@ -38,13 +63,27 @@
name: 'couponCode',
type: 'text',
autocomplete: 'off',
placeholder: 'Enter your Coupon Code'|t('foster-checkout'),
placeholder: 'Enter Coupon Code'|t('foster-checkout'),
errors: couponCodeError ? [couponMessage] : [],
success: cart.couponCode and couponMessage ? [couponMessage] : [],
value: cart.couponCode,
action: 'if (isOpen) $el.focus()'
} %}
<button type="submit"
class="text-white bg-[var(--brandColor)] rounded-xl">{{ 'Submit'|t('foster-checkout') }}</button>
<button
type="submit"
class="h-[48px] flex justify-center items-center gap-2 px-4 text-white bg-[var(--brandColor)] rounded-xl"
:disabled="sending"
>
<svg v-show="sending" aria-hidden="true" role="status" class="inline-block w-4 h-4 me-3 text-gray-200 animate-spin dark:text-gray-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="#ffffff"/>
</svg>
<span class="inline-block">{{ 'Submit'|t('foster-checkout') }}</span>
</button>
</form>
</div>

</div>

{% do cart.clearNotices(null, 'couponCode') %}
{% do craft.app.elements.saveElement(cart) %}
Loading

0 comments on commit 30e5378

Please sign in to comment.