Skip to content

Commit

Permalink
Merge pull request #67 from thelia/feat/cart
Browse files Browse the repository at this point in the history
Feat/cart
  • Loading branch information
leanormandon authored Dec 9, 2024
2 parents e96184b + 7b7c2c7 commit 80291f6
Show file tree
Hide file tree
Showing 54 changed files with 2,396 additions and 1,309 deletions.
25 changes: 25 additions & 0 deletions assets/controllers/cartitem_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller } from '@hotwired/stimulus';
import { getComponent } from '@symfony/ux-live-component';

export default class extends Controller {
timeout = null;

async initialize() {
this.component = await getComponent(this.element);
window.addEventListener('cartitem:toast', (event) => this.toast(event));
};

cancelDelete({ params: { id } }) {
clearTimeout(this.timeout);
this.component.action('cancelDelete', { id: id });
};

// toast event : delete after [timer] seconds
toast(event) {
const nbSeconds = event.detail.timer;
const id = event.detail.id;
this.timeout = setTimeout(() => {
this.component.action('deleteCartItem', { id });
}, nbSeconds * 1000);
}
}
3 changes: 0 additions & 3 deletions assets/js/routes/checkout.js
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
import Checkout from '@react/Layout/Checkout';

Checkout();
1 change: 1 addition & 0 deletions assets/js/twig/PathTwig.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ path }}
21 changes: 17 additions & 4 deletions assets/js/twig/custom-twig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,34 @@
import Twig from 'twig';
// @ts-ignore
import IconTwig from './IconTwig.twig';
// @ts-ignore
import PathTwig from './PathTwig.html.twig';

Twig.extendFunction('ux_icon', (iconName: string): string => {
return IconTwig({ icon: iconName });
});

Twig.extend(function (Twig: any) {
Twig.filters.trans = function (value: any) {
Twig.extendFunction('asset', (path: string): string => {
return PathTwig({ path: path });
});

Twig.extend(function(Twig: any) {
Twig.filters.trans = function(value: any) {
return value;
};
Twig.filters.format_currency = function(value: any) {
return value + ' €';
};

Twig.exports.functions.t = function (value: any) {
Twig.exports.functions.t = function(value: any) {
return value;
};

Twig.exports.functions.resources = function (value: any) {
Twig.exports.functions.resources = function(value: any) {
return value;
};

Twig.exports.functions.stimulus_controller = function() {
return '';
};
});
26 changes: 16 additions & 10 deletions checkout.html.twig
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
{% extends 'base.html.twig' %}
{% extends 'base.html.twig' %}

{% block title %}
Tunnel d'achat
Tunnel d'achat
{% endblock %}

{% block javascripts %}
{{ encore_entry_script_tags('checkout') }}
{{ parent() }}
{{ encore_entry_script_tags('checkout') }}
{% endblock %}

{% block header %}
{% include '@components/Layout/Header/HeaderCheckout.html.twig' %}
{% include '@components/Layout/Header/HeaderCheckout.html.twig' %}
{% endblock %}

{% block body %}
{% set products = resources('/api/front/products', {'productCategories.category.id':1, itemsPerPage:3}) %}
<div id="Checkout"></div>
<div class="bg-theme-lighter">
{% include '@components/Layout/CrossSelling/CrossSelling.html.twig' with {products: products, title: 'Consultés récemment'} %}
</div>
{% set products = resources('/api/front/products', {'productCategories.category.id':1, itemsPerPage:3}) %}

{% include '@components/Layout/CheckoutSteps/CheckoutSteps.html.twig' with {steps: ["Your cart", "Delivery", "Payment", "Confirmation"], current: 1} %}

{{ component('Flexy:Layout:Checkout') }}

<div class="bg-theme-lighter">
{% include '@components/Layout/CrossSelling/CrossSelling.html.twig' with {products: products, title: 'Consultés récemment'} %}
</div>
{% endblock %}
{% block footer %}
{% include '@components/Layout/Footer/FooterCheckout.html.twig' %}
{% include '@components/Layout/Footer/FooterCheckout.html.twig' %}
{% endblock %}
31 changes: 31 additions & 0 deletions components/Layout/Checkout/Checkout.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class='grid grid-cols-12' {{ attributes }}>

<div class='md:col-span-7 col-span-12 Checkout-main'>
<div class='Checkout-main-container'>
<div class='Checkout-main-header'>
{{ this.cart.items|length }} {{ 'articles'|trans }}
</div>

<div class='flex flex-col gap-4'>
{% for item in this.cart.items %}
{{ component('Flexy:Organisms:CartItem', {cartItemId: item.id}) }}
{% endfor %}
</div>
</div>
</div>

<div class='Checkout-sidebar md:col-span-5 col-span-12'>
<div class='Checkout-sidebar-container'>
<h2 class='h3 text-black'>{{ 'Summary'|trans }}</h2>
{% include '@components/Organisms/SummaryCard/SummaryCard.html.twig' with {
nbArticles: this.cart.items|length,
subTotal: 5
} %}
</div>
</div>

<div>

</div>
{{ component('Flexy:Organisms:CartItemDelete') }}
</div>
45 changes: 45 additions & 0 deletions components/Layout/Checkout/checkout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.Checkout {

&-main {
margin-bottom: rem-convert(36px);
margin-top: rem-convert(50px);
display: flex;
justify-content: center;
padding: 0 rem-convert(30px);
&-header {
@apply text-right mb-1;
display: none;
@screen sm {
display: block;
}
}
&-container {
flex: 1;
max-width: rem-convert(444px);
@screen lg {
max-width: rem-convert(540px);
}
}
}

&-sidebar {
background-color: var(--theme-light);
display: flex;
justify-content: center;
padding: rem-convert(80px) rem-convert(30px);
h2 {
padding-bottom: rem-convert(16px);
}

&-container {
flex: 1;
max-width: rem-convert(444px);
@screen md {
max-width: rem-convert(328px);
}
@screen lg {
max-width: rem-convert(400px);
}
}
}
}
22 changes: 22 additions & 0 deletions components/Layout/CheckoutSteps/CheckoutSteps.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% set percent = (current|default(1)/ steps|length * 100)|round %}
<div class='CheckoutSteps'>
<div class='flex items-center'>
<div class='CheckoutSteps-mobile'>
<div class="w-5 h-5 mr-0.5">{{ ux_icon('chevron-left') }}</div>
</div>
<div class='CheckoutSteps-steps'>
{% for step in steps %}
<div
class='Step {% if loop.index == current %}current{% elseif loop.index > current %}next{% else %}previous{% endif %}'>
<span class='Step-number' style="--p: {{ percent }}%;"><span>{{ loop.index }}</span></span>
<span class='Step-label'>{{ step|trans }}</span>
</div>
{% endfor %}
</div>
</div>

<div class='CheckoutSteps-mobile text-right'>
<div class='paragraph-4 font-semibold'>2 050,00€</div>
<div class='paragraph-6'>2 articles</div>
</div>
</div>
14 changes: 14 additions & 0 deletions components/Layout/CheckoutSteps/CheckoutSteps.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CheckoutSteps from './CheckoutSteps.html.twig';

export default {
title: 'Design System/Layout/CheckoutSteps'
};

export const base = {
render : (args) => CheckoutSteps(args),
args : {
steps : ['Votre panier', 'Votre livraison', 'Paiement', 'Confirmation'],
current: 1
},
argTypes: {}
};
126 changes: 126 additions & 0 deletions components/Layout/CheckoutSteps/checkoutSteps.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
.CheckoutSteps {
background: var(--theme-lightest);
display: flex;
align-items: center;
border-bottom: 1px solid var(--theme-medium);
padding: 0 20px;
height: rem-convert(60px);
justify-content: space-between;

&-steps {
display: flex;
align-items: center;
}

&-mobile {
display: block;
}
@screen xs {
justify-content: center;
padding: 0;
height: rem-convert(98px);

&-mobile {
display: none;
}

&-steps {
gap: rem-convert(60px);
}


}
}

.Step {
@apply paragraph-4;
align-items: center;
gap: rem-convert(6px);
position: relative;
color: var(--grey);
display: none;

&-label {
display: none;
}

&-number {
height: rem-convert(24px);
width: rem-convert(24px);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid var(--theme-medium);

&:after {
content: "";
position: absolute;
height: rem-convert(27px);
width: rem-convert(27px);
border-radius: 50%;
background: conic-gradient(
var(--theme-medium) 0% var(--p), /* Bordure couvrant 25% */
transparent var(--p) 100% /* Reste transparent */
);
-webkit-mask: radial-gradient(circle, transparent calc(50% - 1px), black calc(50% - 1x)); /* Bordure de 2px env */
mask: radial-gradient(circle, transparent calc(50% - 1px), black calc(50% - 1px));
z-index: 5;

@screen xs {
content: none;
}

}

}

&.current {
display: flex;
color: var(--grey-dark);



.Step-label {
display: inline-block;
@apply paragraph-4;
font-weight: 600;
padding-left: rem-convert(6px);
}
}
&.previous {
.Step-number {
background-color: var(--theme-light);
}
}


@screen md {
&-label {
display: inline-block;
}
}

@screen xs {
display: flex;
&.current {
color: var(--black);
.Step-number {
background-color: var(--theme-medium);
}
.Step-label {
font-weight: 400;
padding-left: rem-convert(2px);
}
}

&:not(:first-child):before {
content: "";
width: 50px;
height: 1px;
position: absolute;
left: -50px;
background-color: var(--theme-medium);
}
}
}
5 changes: 3 additions & 2 deletions components/Layout/CrossSelling/CrossSelling.html.twig
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{% set title = title|default('') %}

{% set button = button|default(null) %}
{% set products = products|default([]) %}

{% if this.products is not empty %}
{% if products is not empty %}
<div class="pt-[56px] pb-[68px] pl-[24px] md:pl-[48px] xl:pt-[68px] xl:pb-[104px] lg:px-0 lg:container lg:mx-auto">
<div class='pb-6 text-black h2'>{{ title }}</div>
<div class='CrossSelling slider'>
{% for product in this.products %}
{% for product in products %}
{{ component('Flexy:Components:ProductCard', {product}) }}
{% endfor %}
</div>
Expand Down
Loading

0 comments on commit 80291f6

Please sign in to comment.