diff --git a/locale.xml b/locale.xml index 1d2c6178c14b2fa3ce8f38d33a7812265a98f968..27e67eb2938696c0b377ebac0a5aedac78410edd 100644 --- a/locale.xml +++ b/locale.xml @@ -250,8 +250,8 @@ <en><![CDATA[Copy from order #[orderId]]]></en> </locale> <locale name="message.basket.is.empty"> - <de><![CDATA[Ihr Warenkorb enthält keine Produkte.]]></de> - <en><![CDATA[There are no products in your shopping cart.]]></en> + <de><![CDATA[Ihr Warenkorb enthält keine Produkte]]></de> + <en><![CDATA[There are no products in your shopping cart]]></en> </locale> <locale name="control.basket.buttonAdd.text"> diff --git a/src/QUI/ERP/Order/Controls/Basket/Basket.css b/src/QUI/ERP/Order/Controls/Basket/Basket.css index 6749d02704c66b96d839a7388d75561ad95ad09d..2d8de53918cc2966c7fb07267aa50b5bf60fe52b 100644 --- a/src/QUI/ERP/Order/Controls/Basket/Basket.css +++ b/src/QUI/ERP/Order/Controls/Basket/Basket.css @@ -1,5 +1,162 @@ +.quiqqer-order-controls-basket { + --_min-Height: var(--min-Height, 30dvh); + --_decorative-element-height: var(--decorative-element-height, 1rem); + --_decorative-element-width: var(--decorative-element-width, 0.25rem); + --_decorative-element-rotation: var(--decorative-element-rotation, 35deg); + + min-height: var(--_min-Height); +} + :where(.quiqqer-order-basket-articles .offer-original-price) { display: block; font-size: 0.875rem; text-decoration: line-through; +} + +:where(.quiqqer-order-controls-basket .quiqqer-order-basket-isEmpty) { + text-align: center; + min-height: var(--_min-Height); + display: flex; + flex-direction: column; + justify-content: center; +} + +:where(.quiqqer-order-controls-basket .quiqqer-order-basket-isEmpty__iconContainer) { + font-size: 5rem; + opacity: 0.5; +} + +:where(.quiqqer-order-controls-basket .quiqqer-order-basket-isEmpty__text) { + max-width: 40ch; + margin-inline: auto; + margin-top: 1rem; + font-size: 1.25rem; + + opacity: 0; + animation-name: fadeIn; + animation-duration: 0.3s; + animation-delay: 0.25s; + animation-fill-mode: forwards; + animation-timing-function: ease; +} + +:where(.quiqqer-order-controls-basket .quiqqer-order-basket-isEmpty__icon) { + opacity: 0; + animation-name: fadeInIcon; + animation-duration: 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.35s; + animation-timing-function: ease; +} + +:where(.quiqqer-order-controls-basket .decorative-element) { + text-align: center; + display: flex; + justify-content: center; + align-items: end; + gap: 0.5rem; +} + +:where(.quiqqer-order-controls-basket .decorative-element__line) { + display: inline-block; + width: var(--_decorative-element-width); + height: var(--_decorative-element-height); + background: currentColor; + flex-shrink: 0; + border-radius: 0.25rem; + opacity: 0; + + animation-name: fadeInWithSlideDecorationEls; + animation-duration: 0.3s; + animation-fill-mode: forwards; + animation-timing-function: ease; +} + +:where(.quiqqer-order-controls-basket .decorative-element__line--1) { + --transform-start: translateY(5px) rotate(calc(var(--_decorative-element-rotation) * -1)) scaleY(0); + --transform-end: translateY(0) rotate(calc(var(--_decorative-element-rotation) * -1)) scaleY(1); + + transform-origin: bottom left; + transform: var(--transform-start); + animation-delay: 0.5s; +} + +:where(.quiqqer-order-controls-basket .decorative-element__line--2) { + --transform-start: translateY(5px) scaleY(0); + --transform-end: translateY(0) scaleY(1); + + transform-origin: bottom center; + height: calc(var(--_decorative-element-height) * 1.35); + transform: var(--transform-start); + animation-delay: 0.45s; +} + +:where(.quiqqer-order-controls-basket .decorative-element__line--3) { + --transform-start: translateY(5px) rotate(var(--_decorative-element-rotation)) scaleY(0); + --transform-end: translateY(0) rotate(var(--_decorative-element-rotation)) scaleY(1); + + transform-origin: bottom right; + transform: var(--transform-start); + animation-delay: 0.55s; +} + +/* state: loading */ +:where(.quiqqer-order-basket-isLoading) { + min-height: var(--_min-Height); + display: flex; + align-items: center; + justify-content: center; + font-size: 4rem; + opacity: 0.5; +} + +/* keyframes */ +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes fadeInIcon { + from { + opacity: 0; + transform: translateY(10px) scale(0.95); + } + + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes fadeInWithSlideDecorationEls { + from { + opacity: 0; + transform: var(--transform-start); + } + + to { + opacity: 0.75; + transform: var(--transform-end); + } +} + +/* disable animation */ +@media (prefers-reduced-motion: reduce) { + .animation { + animation: none; + } + + .decorative-element__line.animation { + opacity: 0.75; + transform: var(--transform-end) + } + + .quiqqer-order-basket-isEmpty__text.animation { + opacity: 1; + } } \ No newline at end of file diff --git a/src/QUI/ERP/Order/Controls/Basket/Basket.html b/src/QUI/ERP/Order/Controls/Basket/Basket.html index c5233fbb75f117be0fb6c12378b49b4927cd0eac..aaadc8d2de3f7afbd7b90000b04f10dc429d3b81 100644 --- a/src/QUI/ERP/Order/Controls/Basket/Basket.html +++ b/src/QUI/ERP/Order/Controls/Basket/Basket.html @@ -227,11 +227,23 @@ {elseif $this->isGuest() && $this->isLoading()} <div class="quiqqer-order-basket-isLoading"> - <span class="fa fa-spinner fa-spin"></span> + <div class="quiqqer-order-basket-isLoading__inner"> + <span class="fa fa-circle-notch fa-spin"></span> + </div> </div> {else} <div class="quiqqer-order-basket-isEmpty"> - {locale group="quiqqer/order" var="message.basket.is.empty"} + <div class="quiqqer-order-basket-isEmpty__iconContainer"> + <div class="decorative-element"> + <div class="decorative-element__line decorative-element__line--1 animation"></div> + <div class="decorative-element__line decorative-element__line--2 animation"></div> + <div class="decorative-element__line decorative-element__line--3 animation"></div> + </div> + <i class="fa-solid fa-cart-shopping quiqqer-order-basket-isEmpty__icon animation"></i> + </div> + <div class="quiqqer-order-basket-isEmpty__text animation"> + {locale group="quiqqer/order" var="message.basket.is.empty"} + </div> </div> {/if} diff --git a/src/QUI/ERP/Order/Controls/Basket/Basket.php b/src/QUI/ERP/Order/Controls/Basket/Basket.php index 068165bf24a1d34f207d5b98bbcef7c46995fe1b..50df09a52b86357a48b24c968c99dac0cd588d19 100644 --- a/src/QUI/ERP/Order/Controls/Basket/Basket.php +++ b/src/QUI/ERP/Order/Controls/Basket/Basket.php @@ -51,6 +51,8 @@ public function __construct(array $attributes = []) $this->addCSSFile(dirname(__FILE__) . '/Basket.css'); + $this->addCSSClass('quiqqer-order-controls-basket'); + $this->setAttributes([ 'data-qui' => 'package/quiqqer/order/bin/frontend/controls/basket/Basket' ]);