diff --git a/.claude/settings.local.json b/.claude/settings.local.json index f1e57c9..0a37a01 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,17 +1,7 @@ { "permissions": { "allow": [ - "WebSearch", - "Bash(git add:*)", - "Bash(git commit:*)", - "Bash(find:*)", - "Bash(curl:*)", - "WebFetch(domain:snipcart.com)", - "Bash(grep:*)", - "Bash(npm run build:*)", - "Bash(php test-shopify.php:*)", - "WebFetch(domain:getkirby.com)", - "WebFetch(domain:forum.getkirby.com)" + "WebSearch" ] } } diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 87654ef..5ea23f5 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -26,7 +26,7 @@ jobs: set ftp:ssl-allow no open -u $USERNAME,$PASSWORD $PRODUCTION_HOST mirror --reverse --verbose --ignore-time --parallel=10 -x local/ assets assets - mirror --reverse --verbose --ignore-time --parallel=10 -x accounts/ -x cache/ -x sessions/ site site + mirror --reverse --verbose --ignore-time --parallel=10 -x accounts/ -x cache/ -x sessions/ -x header.php site site mirror --reverse --verbose --ignore-time --parallel=10 kirby kirby mirror --reverse --verbose --ignore-time --parallel=10 vendor vendor quit diff --git a/.gitignore b/.gitignore index d2b4a11..975043c 100644 --- a/.gitignore +++ b/.gitignore @@ -51,9 +51,4 @@ Icon # Guide d'intégration (contient des informations sensibles) # --------------- -GUIDE-INTEGRATION-MONDIAL-RELAY.md - -# Claude settings -# --------------- -.claude -/.claude/* \ No newline at end of file +GUIDE-INTEGRATION-MONDIAL-RELAY.md \ No newline at end of file diff --git a/assets/css/components/_shopify-buy-button.scss b/assets/css/components/_shopify-buy-button.scss deleted file mode 100644 index ca48dde..0000000 --- a/assets/css/components/_shopify-buy-button.scss +++ /dev/null @@ -1,68 +0,0 @@ -.product-purchase { - margin-top: 2rem; -} - -.product-stock-info { - margin-bottom: 1rem; -} - -.stock-status { - font-size: 0.9rem; - font-weight: 600; - margin: 0; -} - -.stock-status.in-stock { - color: #00cc00; -} - -.stock-status.low-stock { - color: #ff9900; -} - -.stock-status.out-of-stock { - color: #ff3333; -} - -.btn-add-to-cart { - font-family: "Open Sans", sans-serif; - font-weight: bold; - font-size: 1rem; - color: #000000; - background-color: #00ff00; - border: none; - border-radius: 40px; - padding: 12px 34px; - cursor: pointer; - transition: background-color 0.3s ease; - width: 100%; - max-width: 300px; -} - -.btn-add-to-cart:hover:not(:disabled) { - background-color: #00e600; -} - -.btn-add-to-cart:focus { - outline: 2px solid #00e600; - outline-offset: 2px; -} - -.btn-add-to-cart:disabled { - opacity: 0.6; - cursor: not-allowed; -} - -.btn-add-to-cart.success { - background-color: #00cc00; -} - -.btn-add-to-cart.error { - background-color: #ff3333; - color: #ffffff; -} - -.btn-add-to-cart.out-of-stock { - background-color: #cccccc; - color: #666666; -} diff --git a/assets/css/components/_shopify-cart-drawer.scss b/assets/css/components/_shopify-cart-drawer.scss deleted file mode 100644 index 265a436..0000000 --- a/assets/css/components/_shopify-cart-drawer.scss +++ /dev/null @@ -1,258 +0,0 @@ -/* Cart Drawer Styles */ -.cart-drawer { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 9999; - pointer-events: none; - opacity: 0; - transition: opacity 0.3s ease; - color: #000; - - &.is-open { - pointer-events: auto; - opacity: 1; - - .cart-drawer__panel { - transform: translateX(0); - } - } - - &__overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - cursor: pointer; - } - - &__panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 100%; - max-width: 420px; - background-color: #ffffff; - box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15); - display: flex; - flex-direction: column; - transform: translateX(100%); - transition: transform 0.3s ease; - - @media (max-width: 768px) { - max-width: 100%; - } - } - - &__header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1.5rem; - border-bottom: 1px solid #e0e0e0; - - h3 { - margin: 0; - font-size: 1.5rem; - font-weight: bold; - } - } - - &__close { - background: none; - border: none; - cursor: pointer; - padding: 0.5rem; - display: flex; - align-items: center; - justify-content: center; - transition: opacity 0.2s; - - &:hover { - opacity: 0.7; - } - - svg { - stroke: #000; - } - } - - &__content { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - - &.is-loading { - opacity: 0.5; - pointer-events: none; - } - } - - &__empty { - text-align: center; - padding: 3rem 1rem; - color: #666; - - &.hidden { - display: none; - } - } - - &__items { - display: flex; - flex-direction: column; - gap: 1rem; - - &.hidden { - display: none; - } - } - - &__footer { - border-top: 1px solid #e0e0e0; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1rem; - } - - &__total { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 1.125rem; - font-weight: bold; - - &-label { - color: #000; - } - - &-amount { - color: #000; - font-size: 1.25rem; - } - } - - &__checkout-btn { - width: 100%; - font-family: "Open Sans", sans-serif; - font-weight: bold; - font-size: 1rem; - color: #000000; - background-color: #00ff00; - border: none; - border-radius: 40px; - padding: 14px 34px; - cursor: pointer; - transition: background-color 0.3s ease; - - &:hover:not(:disabled) { - background-color: #00e600; - } - - &:disabled { - opacity: 0.6; - cursor: not-allowed; - } - } -} - -// Cart Item -.cart-item { - display: flex; - gap: 1rem; - padding: 1rem; - border: 1px solid #e0e0e0; - border-radius: 8px; - - &__image { - width: 80px; - height: 80px; - object-fit: cover; - border-radius: 4px; - flex-shrink: 0; - } - - &__details { - flex: 1; - display: flex; - flex-direction: column; - gap: 0.5rem; - } - - &__title { - font-weight: 600; - margin: 0; - font-size: 1rem; - } - - &__variant { - font-size: 0.875rem; - color: #666; - margin: 0; - } - - &__price { - font-weight: bold; - color: #000; - } - - &__quantity { - display: flex; - align-items: center; - gap: 0.5rem; - margin-top: auto; - } - - &__qty-btn { - width: 28px; - height: 28px; - border: 1px solid #000; - background: #fff; - color: #000; - border-radius: 4px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 1rem; - font-weight: bold; - transition: all 0.2s; - - &:hover:not(:disabled) { - background-color: #000; - color: #fff; - } - - &:disabled { - opacity: 0.4; - cursor: not-allowed; - } - } - - &__qty-value { - min-width: 30px; - text-align: center; - font-weight: 600; - } - - &__remove { - background: none; - border: none; - color: #ff3333; - cursor: pointer; - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - text-decoration: underline; - align-self: flex-start; - - &:hover { - color: #cc0000; - } - } -} diff --git a/assets/css/components/_text.scss b/assets/css/components/_text.scss index 357fe64..80f55dd 100644 --- a/assets/css/components/_text.scss +++ b/assets/css/components/_text.scss @@ -1,7 +1,7 @@ [data-template="subscription-newsletter"], [data-template="thanks"], [data-template="support"], -[data-template="home"] { +[data-template="store"] { .p__baseline-big { font-family: var(--title); font-size: var(--fs-big); diff --git a/assets/css/partials/_site-header.scss b/assets/css/partials/_site-header.scss index 5e80fc5..cf92821 100644 --- a/assets/css/partials/_site-header.scss +++ b/assets/css/partials/_site-header.scss @@ -43,20 +43,14 @@ } } - .header-left { + .header-left, + .header-right { width: 90px; display: flex; align-items: center; justify-content: flex-end; } - .header-right { - display: flex; - align-items: center; - justify-content: flex-end; - gap: 1rem; - } - .header-center { display: flex; flex-direction: column; @@ -81,40 +75,4 @@ color: var(--color-txt); } } - - .header-cart-btn { - font-family: var(--font); - background: none; - border: none; - cursor: pointer; - font-size: 0.875rem; - text-transform: uppercase; - color: var(--color-txt); - padding: 0; - line-height: 1; - display: flex; - align-items: center; - gap: 0.25rem; - transition: opacity 0.2s; - - &:hover { - opacity: 0.7; - } - } - - .header-cart-count { - font-weight: normal; - - &:empty { - display: none; - } - - &:not(:empty)::before { - content: "("; - } - - &:not(:empty)::after { - content: ")"; - } - } } diff --git a/assets/css/style.css b/assets/css/style.css index 90a36fa..bb34132 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -402,7 +402,7 @@ main { [data-template=subscription-newsletter] .p__baseline-big, [data-template=thanks] .p__baseline-big, [data-template=support] .p__baseline-big, -[data-template=home] .p__baseline-big { +[data-template=store] .p__baseline-big { font-family: var(--title); font-size: var(--fs-big); font-weight: var(--fw-bold); @@ -413,14 +413,14 @@ main { [data-template=subscription-newsletter] .p__baseline-big strong, [data-template=thanks] .p__baseline-big strong, [data-template=support] .p__baseline-big strong, -[data-template=home] .p__baseline-big strong { +[data-template=store] .p__baseline-big strong { font-weight: var(--fw-bolf); color: var(--color-accent); } [data-template=subscription-newsletter] .p__baseline-big .link-don, [data-template=thanks] .p__baseline-big .link-don, [data-template=support] .p__baseline-big .link-don, -[data-template=home] .p__baseline-big .link-don { +[data-template=store] .p__baseline-big .link-don { display: block; color: var(--color-accent); text-decoration: none; @@ -428,7 +428,7 @@ main { [data-template=subscription-newsletter] .p__baseline-big .link-don:hover, [data-template=thanks] .p__baseline-big .link-don:hover, [data-template=support] .p__baseline-big .link-don:hover, -[data-template=home] .p__baseline-big .link-don:hover { +[data-template=store] .p__baseline-big .link-don:hover { -webkit-text-decoration: underline 2px; text-decoration: underline 2px; text-underline-offset: 4px; @@ -436,7 +436,7 @@ main { [data-template=subscription-newsletter] .p__baseline, [data-template=thanks] .p__baseline, [data-template=support] .p__baseline, -[data-template=home] .p__baseline { +[data-template=store] .p__baseline { font-size: var(--fs-medium); font-weight: var(--fw-medium); line-height: 1.1; @@ -447,7 +447,7 @@ main { [data-template=subscription-newsletter] .p__baseline, [data-template=thanks] .p__baseline, [data-template=support] .p__baseline, - [data-template=home] .p__baseline { + [data-template=store] .p__baseline { text-align: center; margin: var(--spacing) 0; } @@ -455,7 +455,7 @@ main { [data-template=subscription-newsletter] .p__details, [data-template=thanks] .p__details, [data-template=support] .p__details, -[data-template=home] .p__details { +[data-template=store] .p__details { font-size: var(--fs-small); margin-bottom: 0.5em; color: var(--grey-400); @@ -463,7 +463,7 @@ main { [data-template=subscription-newsletter] .section__heading, [data-template=thanks] .section__heading, [data-template=support] .section__heading, -[data-template=home] .section__heading { +[data-template=store] .section__heading { font-size: var(--fs-normal); font-weight: var(--fw-medium); line-height: 1; @@ -477,8 +477,8 @@ main { [data-template=thanks] ol, [data-template=support] ul, [data-template=support] ol, -[data-template=home] ul, -[data-template=home] ol { +[data-template=store] ul, +[data-template=store] ol { margin-left: 3ch; margin-bottom: 0.5em; } @@ -524,18 +524,13 @@ main { #site-header.is-shrinked .site-title { width: 80px !important; } -#site-header .header-left { +#site-header .header-left, +#site-header .header-right { width: 90px; display: flex; align-items: center; justify-content: flex-end; } -#site-header .header-right { - display: flex; - align-items: center; - justify-content: flex-end; - gap: 1rem; -} #site-header .header-center { display: flex; flex-direction: column; @@ -558,36 +553,6 @@ main { #site-header #toggle-lang li.is-selected { color: var(--color-txt); } -#site-header .header-cart-btn { - font-family: var(--font); - background: none; - border: none; - cursor: pointer; - font-size: 0.875rem; - text-transform: uppercase; - color: var(--color-txt); - padding: 0; - line-height: 1; - display: flex; - align-items: center; - gap: 0.25rem; - transition: opacity 0.2s; -} -#site-header .header-cart-btn:hover { - opacity: 0.7; -} -#site-header .header-cart-count { - font-weight: normal; -} -#site-header .header-cart-count:empty { - display: none; -} -#site-header .header-cart-count:not(:empty)::before { - content: "("; -} -#site-header .header-cart-count:not(:empty)::after { - content: ")"; -} #site-footer { background-color: black; @@ -975,36 +940,36 @@ body.is-fullscreen { overflow: hidden; } -[data-template=home] .p__baseline-big { +[data-template=store] .p__baseline-big { margin-top: calc(var(--spacing) * 2); } -[data-template=home] #store__container { +[data-template=store] #store__container { margin-top: calc(var(--spacing) * 2); margin-bottom: calc(var(--spacing) * 4); width: 100%; max-width: 1000px; } -[data-template=home] #store__container .store__product { +[data-template=store] #store__container .store__product { position: relative; } -[data-template=home] #store__container .store__product figure { +[data-template=store] #store__container .store__product figure { aspect-ratio: 4/3; background-color: var(--color-bg); background-color: var(--data-bg); margin-bottom: calc(var(--spacing) * 0.5); overflow: hidden; } -[data-template=home] #store__container .store__product img { +[data-template=store] #store__container .store__product img { width: 100%; height: 100%; -o-object-fit: contain; object-fit: contain; transition: var(--curve) 0.5s; } -[data-template=home] #store__container .store__product a { +[data-template=store] #store__container .store__product a { text-decoration: none; } -[data-template=home] #store__container .store__product .link-block { +[data-template=store] #store__container .store__product .link-block { display: block; height: 100%; width: 100%; @@ -1013,23 +978,23 @@ body.is-fullscreen { left: 0; cursor: pointer; } -[data-template=home] #store__container .store__product:hover figure { +[data-template=store] #store__container .store__product:hover figure { overflow: hidden; } -[data-template=home] #store__container .store__product:hover img { +[data-template=store] #store__container .store__product:hover img { transform: scale(1.05); } -[data-template=home] #store__container .store__product:hover .line-1 { +[data-template=store] #store__container .store__product:hover .line-1 { text-decoration: underline; } @media screen and (max-width: 720px) { - [data-template=home] #store__container .store__product { + [data-template=store] #store__container .store__product { margin-top: calc(var(--spacing) * 1.5); margin-bottom: calc(var(--spacing) * 0.5); } } @media screen and (min-width: 720px) { - [data-template=home] #store__container { + [data-template=store] #store__container { display: grid; grid-template-columns: repeat(6, 1fr); -moz-column-gap: calc(var(--padding-body) * 0.75); @@ -1038,11 +1003,11 @@ body.is-fullscreen { margin-left: auto; margin-right: auto; } - [data-template=home] #store__container .store__product { + [data-template=store] #store__container .store__product { grid-column: span 2; } - [data-template=home] #store__container .store__product:nth-of-type(1), - [data-template=home] #store__container .store__product:nth-of-type(2) { + [data-template=store] #store__container .store__product:nth-of-type(1), + [data-template=store] #store__container .store__product:nth-of-type(2) { grid-column: span 3; } } @@ -1054,8 +1019,11 @@ body.is-fullscreen { margin-right: auto; } -.product-content { - display: contents; +.section__product, +.store__nav { + max-width: 1200px; + margin-left: auto; + margin-right: auto; } .store__nav { @@ -1067,17 +1035,11 @@ body.is-fullscreen { .store__nav a { text-decoration: none; } -.store__nav a::before { - content: "← "; -} .store__nav a:hover { text-decoration: underline; } -@media screen and (max-width: 720px) { - .store__nav a { - padding-top: 0; - font-size: var(--fs-small); - } +.store__nav a::before { + content: "← "; } .section__product .details ul { @@ -1086,7 +1048,122 @@ body.is-fullscreen { .section__product .details ul li { padding-bottom: 0.2em; } + +.product-options__list { + list-style: none; + display: flex; + gap: 2ch; +} +.product-options__list li { + position: relative; +} +.product-options__list li input[type=radio] { + position: fixed; + opacity: 0; + pointer-events: none; +} +.product-options__list li label { + font-family: var(--title); + font-size: var(--fs-normal); + height: 4ch; + width: 4ch; + border-radius: 50%; + border: var(--border); + border-color: transparent; + display: flex; + align-items: center; + justify-content: center; + padding-top: 0px; + cursor: pointer; +} +.product-options__list li input[type=radio]:checked + label { + border-color: var(--color-txt); +} +.product-options__list li input[type=radio]:not(:checked) + label:hover { + border-color: var(--grey-600); + background-color: var(--grey-800); +} + +.product-gallery { + position: relative; + aspect-ratio: 4/3; +} +.product-gallery .swiper-slide { + width: 100%; +} +.product-gallery .swiper-slide figure { + aspect-ratio: 4/3; + width: 100%; + height: 100%; +} +.product-gallery .swiper-slide figure img { + width: 100%; + height: 100%; + -o-object-fit: contain; + object-fit: contain; +} +.product-gallery .swiper-button-prev, +.product-gallery .swiper-button-next { + color: var(--color-txt); + width: 20px; + height: 20px; +} +.product-gallery .swiper-button-prev:after, +.product-gallery .swiper-button-next:after { + font-size: 20px; + font-weight: bold; +} +.product-gallery .swiper-button-prev:hover, +.product-gallery .swiper-button-next:hover { + opacity: 0.7; +} +.product-gallery .swiper-pagination { + position: relative; + margin-top: calc(var(--spacing) * 0.5); + bottom: 0; +} +.product-gallery .swiper-pagination .swiper-pagination-bullet { + width: 8px; + height: 8px; + background: var(--grey-600); + opacity: 0.5; + transition: opacity 0.3s; +} +.product-gallery .swiper-pagination .swiper-pagination-bullet:hover { + opacity: 0.7; +} +.product-gallery .swiper-pagination .swiper-pagination-bullet-active { + background: var(--color-txt); + opacity: 1; +} + +.hero { + margin-bottom: calc(var(--spacing) * 1); + padding: calc(var(--spacing) * 0.5) 0; + border-top: var(--border-light); + border-bottom: var(--border-light); +} +.hero .p__baseline-big { + margin: 0; + text-align: left; +} + +.add-to-cart { + margin: 0; + border-bottom: var(--border-light); + padding: calc(var(--spacing) * 0.5) 0; +} + +.product-options { + border-bottom: var(--border-light); + padding: calc(var(--spacing) * 0.25) 0; +} + @media screen and (max-width: 720px) { + .store__nav a { + padding-top: 0; + font-size: var(--fs-small); + } .section__product { display: flex; flex-direction: column; @@ -1125,7 +1202,7 @@ body.is-fullscreen { } } @media screen and (min-width: 720px) { - .section__product .product-content { + .section__product { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--padding-body) * 2); @@ -1144,123 +1221,10 @@ body.is-fullscreen { display: flex; flex-direction: column; } -} - -.product-options { - border-bottom: var(--border-light); - padding: calc(var(--spacing) * 0.25) 0; -} - -.product-options__list { - list-style: none; - display: flex; - gap: 2ch; -} -.product-options__list li { - position: relative; -} -.product-options__list li input[type=radio] { - position: fixed; - opacity: 0; - pointer-events: none; -} -.product-options__list li input[type=radio]:checked + label { - border-color: var(--color-txt); -} -.product-options__list li input[type=radio]:not(:checked) + label:hover { - border-color: var(--grey-600); - background-color: var(--grey-800); -} -.product-options__list li label { - font-family: var(--title); - font-size: var(--fs-normal); - height: 4ch; - width: 4ch; - border-radius: 50%; - border: var(--border); - border-color: transparent; - display: flex; - align-items: center; - justify-content: center; - padding-top: 0px; - cursor: pointer; -} - -.product-gallery { - position: relative; - aspect-ratio: 4/3; -} -.product-gallery .swiper-slide { - width: 100%; -} -.product-gallery .swiper-slide figure { - aspect-ratio: 4/3; - width: 100%; - height: 100%; -} -.product-gallery .swiper-slide figure img { - width: 100%; - height: 100%; - -o-object-fit: contain; - object-fit: contain; -} -@media screen and (min-width: 720px) { .product-gallery .swiper-slide figure { width: calc(100% - 60px); } } -.product-gallery .swiper-button-prev, -.product-gallery .swiper-button-next { - color: var(--color-txt); - width: 20px; - height: 20px; -} -.product-gallery .swiper-button-prev:after, -.product-gallery .swiper-button-next:after { - font-size: 20px; - font-weight: bold; -} -.product-gallery .swiper-button-prev:hover, -.product-gallery .swiper-button-next:hover { - opacity: 0.7; -} -.product-gallery .swiper-pagination { - position: relative; - margin-top: calc(var(--spacing) * 0.5); - bottom: 0; -} -.product-gallery .swiper-pagination .swiper-pagination-bullet { - width: 8px; - height: 8px; - background: var(--grey-600); - opacity: 0.5; - transition: opacity 0.3s; -} -.product-gallery .swiper-pagination .swiper-pagination-bullet:hover { - opacity: 0.7; -} -.product-gallery .swiper-pagination .swiper-pagination-bullet.swiper-pagination-bullet-active { - background: var(--color-txt); - opacity: 1; -} - -.hero { - margin-bottom: calc(var(--spacing) * 1); - padding: calc(var(--spacing) * 0.5) 0; - border-top: var(--border-light); - border-bottom: var(--border-light); -} -.hero .p__baseline-big { - margin: 0; - text-align: left; -} - -.add-to-cart { - margin: 0; - border-bottom: var(--border-light); - padding: calc(var(--spacing) * 0.5) 0; -} - [data-template=thanks] .thanks-page { min-height: 60vh; display: flex; @@ -1268,325 +1232,32 @@ body.is-fullscreen { justify-content: center; padding: calc(var(--spacing) * 4) var(--spacing); } -[data-template=thanks] .thanks-page .thanks-content { +[data-template=thanks] .thanks-content { text-align: center; max-width: 600px; - display: flex; - flex-direction: column; - align-items: center; } -[data-template=thanks] .thanks-page .thanks-content h1 { +[data-template=thanks] .thanks-content h1 { + font-size: var(--fs-x-big); margin-bottom: calc(var(--spacing) * 2); } -[data-template=thanks] .thanks-page .thanks-content .thanks-message { - font-size: var(--fs-medium); - line-height: 1.1; +[data-template=thanks] .thanks-content .thanks-message { + font-size: var(--fs-big); + margin-bottom: calc(var(--spacing) * 3); + line-height: 1.6; } -[data-template=thanks] .thanks-page .thanks-content .thanks-message p { +[data-template=thanks] .thanks-content .thanks-message p { margin-bottom: var(--spacing); } -[data-template=thanks] .thanks-page .thanks-content .thanks-actions { - width: -moz-max-content; - width: max-content; +[data-template=thanks] .thanks-content .thanks-actions { + margin-top: calc(var(--spacing) * 3); } [data-template=thanks] #site-footer { border-top: none; margin-top: calc(var(--spacing) * 4); } -.product-purchase { - margin-top: 2rem; -} - -.product-stock-info { - margin-bottom: 1rem; -} - -.stock-status { - font-size: 0.9rem; - font-weight: 600; - margin: 0; -} - -.stock-status.in-stock { - color: #00cc00; -} - -.stock-status.low-stock { - color: #ff9900; -} - -.stock-status.out-of-stock { - color: #ff3333; -} - -.btn-add-to-cart { - font-family: "Open Sans", sans-serif; - font-weight: bold; - font-size: 1rem; - color: #000000; - background-color: #00ff00; - border: none; - border-radius: 40px; - padding: 12px 34px; - cursor: pointer; - transition: background-color 0.3s ease; - width: 100%; - max-width: 300px; -} - -.btn-add-to-cart:hover:not(:disabled) { - background-color: #00e600; -} - -.btn-add-to-cart:focus { - outline: 2px solid #00e600; - outline-offset: 2px; -} - -.btn-add-to-cart:disabled { - opacity: 0.6; - cursor: not-allowed; -} - -.btn-add-to-cart.success { - background-color: #00cc00; -} - -.btn-add-to-cart.error { - background-color: #ff3333; - color: #ffffff; -} - -.btn-add-to-cart.out-of-stock { - background-color: #cccccc; - color: #666666; -} - -/* Cart Drawer Styles */ -.cart-drawer { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 9999; - pointer-events: none; - opacity: 0; - transition: opacity 0.3s ease; - color: #000; -} -.cart-drawer.is-open { - pointer-events: auto; - opacity: 1; -} -.cart-drawer.is-open .cart-drawer__panel { - transform: translateX(0); -} -.cart-drawer__overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - cursor: pointer; -} -.cart-drawer__panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 100%; - max-width: 420px; - background-color: #ffffff; - box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15); - display: flex; - flex-direction: column; - transform: translateX(100%); - transition: transform 0.3s ease; -} -@media (max-width: 768px) { - .cart-drawer__panel { - max-width: 100%; - } -} -.cart-drawer__header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1.5rem; - border-bottom: 1px solid #e0e0e0; -} -.cart-drawer__header h3 { - margin: 0; - font-size: 1.5rem; - font-weight: bold; -} -.cart-drawer__close { - background: none; - border: none; - cursor: pointer; - padding: 0.5rem; - display: flex; - align-items: center; - justify-content: center; - transition: opacity 0.2s; -} -.cart-drawer__close:hover { - opacity: 0.7; -} -.cart-drawer__close svg { - stroke: #000; -} -.cart-drawer__content { - flex: 1; - overflow-y: auto; - padding: 1.5rem; -} -.cart-drawer__content.is-loading { - opacity: 0.5; - pointer-events: none; -} -.cart-drawer__empty { - text-align: center; - padding: 3rem 1rem; - color: #666; -} -.cart-drawer__empty.hidden { - display: none; -} -.cart-drawer__items { - display: flex; - flex-direction: column; - gap: 1rem; -} -.cart-drawer__items.hidden { - display: none; -} -.cart-drawer__footer { - border-top: 1px solid #e0e0e0; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1rem; -} -.cart-drawer__total { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 1.125rem; - font-weight: bold; -} -.cart-drawer__total-label { - color: #000; -} -.cart-drawer__total-amount { - color: #000; - font-size: 1.25rem; -} -.cart-drawer__checkout-btn { - width: 100%; - font-family: "Open Sans", sans-serif; - font-weight: bold; - font-size: 1rem; - color: #000000; - background-color: #00ff00; - border: none; - border-radius: 40px; - padding: 14px 34px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.cart-drawer__checkout-btn:hover:not(:disabled) { - background-color: #00e600; -} -.cart-drawer__checkout-btn:disabled { - opacity: 0.6; - cursor: not-allowed; -} - -.cart-item { - display: flex; - gap: 1rem; - padding: 1rem; - border: 1px solid #e0e0e0; - border-radius: 8px; -} -.cart-item__image { - width: 80px; - height: 80px; - -o-object-fit: cover; - object-fit: cover; - border-radius: 4px; - flex-shrink: 0; -} -.cart-item__details { - flex: 1; - display: flex; - flex-direction: column; - gap: 0.5rem; -} -.cart-item__title { - font-weight: 600; - margin: 0; - font-size: 1rem; -} -.cart-item__variant { - font-size: 0.875rem; - color: #666; - margin: 0; -} -.cart-item__price { - font-weight: bold; - color: #000; -} -.cart-item__quantity { - display: flex; - align-items: center; - gap: 0.5rem; - margin-top: auto; -} -.cart-item__qty-btn { - width: 28px; - height: 28px; - border: 1px solid #000; - background: #fff; - color: #000; - border-radius: 4px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 1rem; - font-weight: bold; - transition: all 0.2s; -} -.cart-item__qty-btn:hover:not(:disabled) { - background-color: #000; - color: #fff; -} -.cart-item__qty-btn:disabled { - opacity: 0.4; - cursor: not-allowed; -} -.cart-item__qty-value { - min-width: 30px; - text-align: center; - font-weight: 600; -} -.cart-item__remove { - background: none; - border: none; - color: #ff3333; - cursor: pointer; - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - text-decoration: underline; - align-self: flex-start; -} -.cart-item__remove:hover { - color: #cc0000; +.snipcart-modal__container { + z-index: 1000; } [data-template=subscription-newsletter] main { diff --git a/assets/css/style.css.map b/assets/css/style.css.map index abb3324..9cd0665 100644 --- a/assets/css/style.css.map +++ b/assets/css/style.css.map @@ -1 +1 @@ -{"version":3,"sources":["style.css","base/_var.scss","base/_body.scss","components/_nav-tabs.scss","components/_btn--default.scss","components/_btn--don.scss","components/_form-newsletter.scss","components/_gauge.scss","components/_text.scss","partials/_site-header.scss","partials/_site-footer.scss","template/support/_layout.scss","template/support/_section--donation.scss","template/support/_section--comments.scss","template/support/_section--questions.scss","template/support/_section--video.scss","template/shop/_layout.scss","template/shop/_section--product.scss","template/shop/_thanks.scss","components/_shopify-buy-button.scss","components/_shopify-cart-drawer.scss","template/subscription-newsletter/_layout.scss"],"names":[],"mappings":"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","file":"style.css"} \ No newline at end of file +{"version":3,"sources":["style.css","base/_var.scss","base/_body.scss","components/_nav-tabs.scss","components/_btn--default.scss","components/_btn--don.scss","components/_form-newsletter.scss","components/_gauge.scss","components/_text.scss","partials/_site-header.scss","partials/_site-footer.scss","template/support/_layout.scss","template/support/_section--donation.scss","template/support/_section--comments.scss","template/support/_section--questions.scss","template/support/_section--video.scss","template/shop/_layout.scss","template/shop/_section--product.scss","template/shop/_thanks.scss","template/shop/_snipcart.scss","template/subscription-newsletter/_layout.scss"],"names":[],"mappings":"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","file":"style.css"} \ No newline at end of file diff --git a/assets/css/style.scss b/assets/css/style.scss index 334ba35..9687a73 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -22,7 +22,6 @@ @import "template/shop/layout"; @import "template/shop/section--product"; @import "template/shop/thanks"; -@import "components/shopify-buy-button.scss"; -@import "components/shopify-cart-drawer.scss"; +@import "template/shop/snipcart"; @import "template/subscription-newsletter/layout"; diff --git a/assets/css/template/shop/_layout.scss b/assets/css/template/shop/_layout.scss index 0f7f984..22685bb 100644 --- a/assets/css/template/shop/_layout.scss +++ b/assets/css/template/shop/_layout.scss @@ -1,4 +1,6 @@ -[data-template="home"] { +[data-template="store"] { + + .p__baseline-big { margin-top: calc(var(--spacing) * 2); } diff --git a/assets/css/template/shop/_section--product.scss b/assets/css/template/shop/_section--product.scss index 33573cb..82790ac 100644 --- a/assets/css/template/shop/_section--product.scss +++ b/assets/css/template/shop/_section--product.scss @@ -1,3 +1,12 @@ +.section__product, +.store__nav{ + max-width: 1200px; + margin-left: auto; + margin-right: auto; +} + + + .section__product, .store__nav { max-width: 1200px; @@ -5,9 +14,9 @@ margin-right: auto; } -.product-content { - display: contents; -} + + + .store__nav { padding-top: calc(var(--spacing) * 1); @@ -18,35 +27,174 @@ a { text-decoration: none; - &::before { - content: "← "; - } - &:hover { text-decoration: underline; } } - @media #{$small} { - a { - padding-top: 0; - font-size: var(--fs-small); + a::before { + content: "← "; + } +} + + + +.section__product .details { + // margin-bottom: calc(var(--spacing) * 2); + + ul{ + margin-left: 2ch; + li{ + padding-bottom: 0.2em; } } } -.section__product { - .details { - ul { - margin-left: 2ch; +.product-options__list { + list-style: none; + display: flex; + gap: 2ch; + li { - padding-bottom: 0.2em; + position: relative; + + input[type="radio"] { + position: fixed; + opacity: 0; + pointer-events: none; + } + + label { + font-family: var(--title); + font-size: var(--fs-normal); + height: 4ch; + width: 4ch; + border-radius: 50%; + border: var(--border); + border-color: transparent; + display: flex; + align-items: center; + justify-content: center; + padding-top: 0px; + cursor: pointer; + } + + input[type="radio"]:checked + label { + border-color: var(--color-txt); + } + + input[type="radio"]:not(:checked) + label:hover { + border-color: var(--grey-600); + background-color: var(--grey-800); + } + } + } + + + + + + + + + +.product-gallery { + position: relative; + aspect-ratio: 4 / 3; + + .swiper-slide { + width: 100%; + + figure { + + aspect-ratio: 4 / 3; + width: 100%; + height: 100%; + + img { + width: 100%; + height: 100%; + object-fit: contain; } } } - @media #{$small} { + // Swiper navigation arrows + .swiper-button-prev, + .swiper-button-next { + color: var(--color-txt); + width: 20px; + height: 20px; + + &:after { + font-size: 20px; + font-weight: bold; + } + + &:hover { + opacity: 0.7; + } + } + + // Swiper pagination dots + .swiper-pagination { + position: relative; + margin-top: calc(var(--spacing) * 0.5); + bottom: 0; + + .swiper-pagination-bullet { + width: 8px; + height: 8px; + background: var(--grey-600); + opacity: 0.5; + transition: opacity 0.3s; + + &:hover { + opacity: 0.7; + } + } + + .swiper-pagination-bullet-active { + background: var(--color-txt); + opacity: 1; + } + } +} + + + .hero { + margin-bottom: calc(var(--spacing) * 1); + padding: calc(var(--spacing) * 0.5) 0; + border-top: var(--border-light); + border-bottom: var(--border-light); + + .p__baseline-big { + margin: 0; + text-align: left; + } + } + + .add-to-cart { + margin: 0; + border-bottom: var(--border-light); + padding: calc(var(--spacing) * 0.5) 0; + } + + .product-options { + border-bottom: var(--border-light); + padding: calc(var(--spacing) * 0.25) 0; + } + + + +@media #{$small} { + .store__nav a { + padding-top: 0; + font-size: var(--fs-small); + } + + .section__product { display: flex; flex-direction: column; margin-bottom: 10vh; @@ -59,7 +207,6 @@ margin-top: calc(var(--spacing) * 0.5); order: 1; } - figure { order: 2; margin-bottom: calc(var(--spacing) * 1); @@ -79,25 +226,25 @@ order: 5; } - .product-gallery { + .product-gallery{ width: 100vw; position: relative; - left: calc(var(--padding-body) * -1); + left: calc(var(--padding-body)*-1); .swiper-button-prev, - .swiper-button-next { - display: none; - } + .swiper-button-next{ display: none; } } } +} - @media #{$small-up} { - .product-content { - display: grid; - grid-template-columns: 1fr 1fr; - gap: calc(var(--padding-body) * 2); - margin-bottom: calc(var(--spacing) * 3); - } +@media #{$small-up} { + + + .section__product{ + display: grid; + grid-template-columns: 1fr 1fr; + gap: calc(var(--padding-body)*2); + margin-bottom: calc(var(--spacing)*3); .details { margin-bottom: calc(var(--spacing) * 2); @@ -108,140 +255,17 @@ border-top: var(--border-light); } - .col-left { + .col-left{ min-height: 100%; - padding-bottom: 40px; + padding-bottom: 40px; //dots + display: flex; flex-direction: column; } - } -} -.product-options { - border-bottom: var(--border-light); - padding: calc(var(--spacing) * 0.25) 0; -} - -.product-options__list { - list-style: none; - display: flex; - gap: 2ch; - - li { - position: relative; - - input[type="radio"] { - position: fixed; - opacity: 0; - pointer-events: none; - - &:checked + label { - border-color: var(--color-txt); - } - - &:not(:checked) + label:hover { - border-color: var(--grey-600); - background-color: var(--grey-800); - } - } - - label { - font-family: var(--title); - font-size: var(--fs-normal); - height: 4ch; - width: 4ch; - border-radius: 50%; - border: var(--border); - border-color: transparent; - display: flex; - align-items: center; - justify-content: center; - padding-top: 0px; - cursor: pointer; - } - } -} - -.product-gallery { - position: relative; - aspect-ratio: 4 / 3; - - .swiper-slide { - width: 100%; - - figure { - aspect-ratio: 4 / 3; - width: 100%; - height: 100%; - - img { - width: 100%; - height: 100%; - object-fit: contain; - } - } - - @media #{$small-up} { - figure { - width: calc(100% - 60px); - } - } } - .swiper-button-prev, - .swiper-button-next { - color: var(--color-txt); - width: 20px; - height: 20px; - - &:after { - font-size: 20px; - font-weight: bold; - } - - &:hover { - opacity: 0.7; - } - } - - .swiper-pagination { - position: relative; - margin-top: calc(var(--spacing) * 0.5); - bottom: 0; - - .swiper-pagination-bullet { - width: 8px; - height: 8px; - background: var(--grey-600); - opacity: 0.5; - transition: opacity 0.3s; - - &:hover { - opacity: 0.7; - } - - &.swiper-pagination-bullet-active { - background: var(--color-txt); - opacity: 1; - } - } + .product-gallery .swiper-slide figure{ + width: calc(100% - 60px); } } - -.hero { - margin-bottom: calc(var(--spacing) * 1); - padding: calc(var(--spacing) * 0.5) 0; - border-top: var(--border-light); - border-bottom: var(--border-light); - - .p__baseline-big { - margin: 0; - text-align: left; - } -} - -.add-to-cart { - margin: 0; - border-bottom: var(--border-light); - padding: calc(var(--spacing) * 0.5) 0; -} diff --git a/assets/snipcart-archive/_snipcart.scss b/assets/css/template/shop/_snipcart.scss similarity index 100% rename from assets/snipcart-archive/_snipcart.scss rename to assets/css/template/shop/_snipcart.scss diff --git a/assets/css/template/shop/_thanks.scss b/assets/css/template/shop/_thanks.scss index f05bc1a..0453c62 100644 --- a/assets/css/template/shop/_thanks.scss +++ b/assets/css/template/shop/_thanks.scss @@ -5,30 +5,29 @@ align-items: center; justify-content: center; padding: calc(var(--spacing) * 4) var(--spacing); + } - .thanks-content { - text-align: center; - max-width: 600px; - display: flex; - flex-direction: column; - align-items: center; + .thanks-content { + text-align: center; + max-width: 600px; - h1 { - margin-bottom: calc(var(--spacing) * 2); + h1 { + font-size: var(--fs-x-big); + margin-bottom: calc(var(--spacing) * 2); + } + + .thanks-message { + font-size: var(--fs-big); + margin-bottom: calc(var(--spacing) * 3); + line-height: 1.6; + + p { + margin-bottom: var(--spacing); } + } - .thanks-message { - font-size: var(--fs-medium); - line-height: 1.1; - - p { - margin-bottom: var(--spacing); - } - } - - .thanks-actions { - width: max-content; - } + .thanks-actions { + margin-top: calc(var(--spacing) * 3); } } diff --git a/assets/js/cart-drawer.js b/assets/js/cart-drawer.js deleted file mode 100644 index 439c3d1..0000000 --- a/assets/js/cart-drawer.js +++ /dev/null @@ -1,290 +0,0 @@ -/** - * Cart Drawer Component - * Manages the cart sidebar with add/remove/update functionality - */ -(function() { - const drawer = document.getElementById('cart-drawer'); - const emptyState = document.querySelector('[data-cart-empty]'); - const itemsContainer = document.querySelector('[data-cart-items]'); - const checkoutBtn = document.querySelector('[data-cart-checkout]'); - const closeButtons = document.querySelectorAll('[data-cart-close]'); - const totalDisplay = document.querySelector('[data-cart-total]'); - const headerCartBtn = document.querySelector('[data-cart-open]'); - const headerCartCount = document.querySelector('[data-cart-count]'); - - // Get translated text - const removeText = drawer.dataset.textRemove || 'Remove'; - - let currentCart = null; - let cartInstance = null; - - // Wait for ShopifyCart to be available - function initCartDrawer() { - if (typeof ShopifyCart === 'undefined') { - setTimeout(initCartDrawer, 100); - return; - } - - cartInstance = new ShopifyCart({ - domain: 'nv7cqv-bu.myshopify.com', - storefrontAccessToken: 'dec3d35a2554384d149c72927d1cfd1b' - }); - - // Initialize event listeners - setupEventListeners(); - - // Load initial cart state - loadCart(); - } - - function setupEventListeners() { - // Close drawer - closeButtons.forEach(btn => { - btn.addEventListener('click', closeDrawer); - }); - - // Open drawer from header button - if (headerCartBtn) { - headerCartBtn.addEventListener('click', openDrawer); - } - - // Checkout button - checkoutBtn.addEventListener('click', () => { - if (currentCart?.checkoutUrl) { - window.location.href = currentCart.checkoutUrl; - } - }); - - // Listen for custom cart update events - document.addEventListener('cart:updated', (e) => { - currentCart = e.detail.cart; - renderCart(); - openDrawer(); - }); - } - - async function loadCart() { - if (!cartInstance) return; - - try { - const cart = await cartInstance.getCart(); - currentCart = cart; - renderCart(); - } catch (error) { - console.error('Error loading cart:', error); - } - } - - function openDrawer() { - drawer.classList.add('is-open'); - document.body.style.overflow = 'hidden'; - } - - function closeDrawer() { - drawer.classList.remove('is-open'); - document.body.style.overflow = ''; - } - - function calculateTotal() { - if (!currentCart || !currentCart.lines) return 0; - - return currentCart.lines.edges.reduce((total, edge) => { - const item = edge.node; - const price = parseFloat(item.merchandise.price.amount); - const quantity = item.quantity; - return total + (price * quantity); - }, 0); - } - - function formatPrice(amount, currency = 'EUR') { - return new Intl.NumberFormat('fr-FR', { - style: 'currency', - currency: currency - }).format(amount); - } - - function updateCartCount() { - if (!currentCart || !currentCart.lines || currentCart.lines.edges.length === 0) { - if (headerCartCount) { - headerCartCount.textContent = ''; - } - return; - } - - // Calculate total quantity - const totalQty = currentCart.lines.edges.reduce((sum, edge) => { - return sum + edge.node.quantity; - }, 0); - - if (headerCartCount) { - headerCartCount.textContent = totalQty > 0 ? totalQty : ''; - } - } - - function renderCart() { - if (!currentCart || !currentCart.lines || currentCart.lines.edges.length === 0) { - emptyState.classList.remove('hidden'); - itemsContainer.classList.add('hidden'); - checkoutBtn.disabled = true; - if (totalDisplay) { - totalDisplay.textContent = '0,00 €'; - } - updateCartCount(); - return; - } - - emptyState.classList.add('hidden'); - itemsContainer.classList.remove('hidden'); - checkoutBtn.disabled = false; - - // Calculate and display total - const total = calculateTotal(); - const currency = currentCart.lines.edges[0]?.node.merchandise.price.currencyCode || 'EUR'; - if (totalDisplay) { - totalDisplay.textContent = formatPrice(total, currency); - } - - // Update header cart count - updateCartCount(); - - // Render cart items - itemsContainer.innerHTML = currentCart.lines.edges.map(edge => { - const item = edge.node; - const merchandise = item.merchandise; - - return ` -
-
-

${merchandise.product.title}

- ${merchandise.title !== 'Default Title' ? `

${merchandise.title}

` : ''} -

${formatPrice(parseFloat(merchandise.price.amount), merchandise.price.currencyCode)}

- -
- - ${item.quantity} - -
- - -
-
- `; - }).join(''); - - // Attach event listeners to quantity buttons - attachQuantityListeners(); - } - - function attachQuantityListeners() { - const buttons = itemsContainer.querySelectorAll('[data-action]'); - - buttons.forEach(btn => { - btn.addEventListener('click', async (e) => { - const action = e.target.dataset.action; - const lineId = e.target.dataset.lineId; - - await handleQuantityChange(action, lineId); - }); - }); - } - - async function handleQuantityChange(action, lineId) { - if (!cartInstance || !currentCart) return; - - // Find the line item - const line = currentCart.lines.edges.find(edge => edge.node.id === lineId); - if (!line) return; - - const currentQty = line.node.quantity; - let newQty = currentQty; - - if (action === 'increase') { - newQty = currentQty + 1; - } else if (action === 'decrease') { - newQty = Math.max(0, currentQty - 1); - } else if (action === 'remove') { - newQty = 0; - } - - // Update cart via API - try { - itemsContainer.classList.add('is-loading'); - - const query = ` - mutation cartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) { - cartLinesUpdate(cartId: $cartId, lines: $lines) { - cart { - id - checkoutUrl - lines(first: 10) { - edges { - node { - id - quantity - merchandise { - ... on ProductVariant { - id - title - price { - amount - currencyCode - } - product { - title - } - } - } - } - } - } - } - userErrors { - field - message - } - } - } - `; - - const data = await cartInstance.query(query, { - cartId: currentCart.id, - lines: [{ - id: lineId, - quantity: newQty - }] - }); - - if (data.cartLinesUpdate.userErrors.length > 0) { - throw new Error(data.cartLinesUpdate.userErrors[0].message); - } - - currentCart = data.cartLinesUpdate.cart; - renderCart(); - - } catch (error) { - console.error('Error updating cart:', error); - alert('Erreur lors de la mise à jour du panier'); - } finally { - itemsContainer.classList.remove('is-loading'); - } - } - - // Public API - window.CartDrawer = { - open: openDrawer, - close: closeDrawer, - updateCart: (cart) => { - currentCart = cart; - renderCart(); - } - }; - - // Initialize when DOM is ready - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initCartDrawer); - } else { - initCartDrawer(); - } -})(); diff --git a/assets/js/product-add-to-cart.js b/assets/js/product-add-to-cart.js deleted file mode 100644 index 1e421d7..0000000 --- a/assets/js/product-add-to-cart.js +++ /dev/null @@ -1,70 +0,0 @@ -(function() { - const cart = new ShopifyCart({ - domain: 'nv7cqv-bu.myshopify.com', - storefrontAccessToken: 'dec3d35a2554384d149c72927d1cfd1b' - }); - - const addToCartBtn = document.querySelector('[data-shopify-add-to-cart]'); - - if (!addToCartBtn) { - return; - } - - const buttonTextDiv = addToCartBtn.querySelector('.txt[data-button-text]'); - - if (!buttonTextDiv) { - console.error('Button text div not found'); - return; - } - - const texts = { - add: addToCartBtn.dataset.textAdd || 'Add to cart', - adding: addToCartBtn.dataset.textAdding || 'Adding...', - added: addToCartBtn.dataset.textAdded || 'Added! ✓', - error: addToCartBtn.dataset.textError || 'Error - Try again' - }; - - addToCartBtn.addEventListener('click', async function(e) { - e.preventDefault(); - - const variantId = this.dataset.variantId; - - if (!variantId) { - console.error('No variant ID found'); - return; - } - - addToCartBtn.disabled = true; - const originalText = buttonTextDiv.textContent; - buttonTextDiv.textContent = texts.adding; - - try { - const cartResult = await cart.addToCart(variantId, 1); - - buttonTextDiv.textContent = texts.added; - addToCartBtn.classList.add('success'); - - document.dispatchEvent(new CustomEvent('cart:updated', { - detail: { cart: cartResult } - })); - - setTimeout(() => { - addToCartBtn.disabled = false; - buttonTextDiv.textContent = originalText; - addToCartBtn.classList.remove('success'); - }, 1500); - - } catch (error) { - console.error('Error adding to cart:', error); - - buttonTextDiv.textContent = texts.error; - addToCartBtn.classList.add('error'); - - setTimeout(() => { - addToCartBtn.disabled = false; - buttonTextDiv.textContent = originalText; - addToCartBtn.classList.remove('error'); - }, 2000); - } - }); -})(); diff --git a/assets/js/product-loader.js b/assets/js/product-loader.js deleted file mode 100644 index 58293ce..0000000 --- a/assets/js/product-loader.js +++ /dev/null @@ -1,306 +0,0 @@ -(async function () { - const container = document.querySelector("[data-product-loader]"); - if (!container) return; - - const handle = container.dataset.shopifyHandle; - const language = container.dataset.language || "fr"; - const isEnglish = language === "en"; - const loadingState = container.querySelector(".product-loading"); - const contentState = container.querySelector(".product-content"); - const errorState = container.querySelector(".product-error"); - - try { - const cart = new ShopifyCart({ - domain: "nv7cqv-bu.myshopify.com", - storefrontAccessToken: "dec3d35a2554384d149c72927d1cfd1b", - }); - - const product = await cart.getProductByHandle(handle); - - if (!product) { - throw new Error("Product not found"); - } - - renderProduct(product, isEnglish); - updateMetaTags(product, isEnglish); - - loadingState.style.display = "none"; - contentState.removeAttribute("style"); - - setTimeout(() => { - if (typeof Swiper !== "undefined" && product.images.edges.length > 0) { - new Swiper(".product-gallery", { - loop: product.images.edges.length > 1, - navigation: { - nextEl: ".swiper-button-next", - prevEl: ".swiper-button-prev", - }, - pagination: { - el: ".swiper-pagination", - clickable: true, - }, - keyboard: { - enabled: true, - }, - }); - } - }, 100); - } catch (error) { - console.error("Error loading product:", error); - loadingState.style.display = "none"; - errorState.style.display = "block"; - } - - function renderProduct(product, isEnglish) { - renderTitle(product, isEnglish); - renderPrice(product); - renderDetails(product, isEnglish); - renderImages(product, isEnglish); - renderOptions(product); - setupAddToCart(product); - } - - function renderTitle(product, isEnglish) { - const titleEl = document.querySelector("[data-product-title]"); - if (titleEl) { - const title = - isEnglish && product.titleEn?.value - ? product.titleEn.value - : product.title; - titleEl.textContent = title; - } - } - - function renderPrice(product) { - const priceEl = document.querySelector("[data-product-price]"); - if (priceEl) { - const price = parseFloat(product.priceRange.minVariantPrice.amount); - priceEl.textContent = price.toFixed(2) + "€"; - } - } - - function renderDetails(product, isEnglish) { - const detailsEl = document.querySelector("[data-product-details]"); - if (detailsEl) { - const description = - isEnglish && product.descriptionEn?.value - ? product.descriptionEn.value.replaceAll("\n", "
") - : product.descriptionHtml || ""; - detailsEl.innerHTML = description; - } - } - - function renderImages(product, isEnglish) { - const imagesContainer = document.querySelector("[data-product-images]"); - - if (imagesContainer && product.images.edges.length > 0) { - const productTitle = - isEnglish && product.titleEn?.value - ? product.titleEn.value - : product.title; - - imagesContainer.innerHTML = product.images.edges - .map((edge) => { - const img = edge.node; - return ` -
-
- ${img.altText || productTitle} -
-
- `; - }) - .join(""); - } - } - - function renderOptions(product) { - if (product.variants.edges.length <= 1) return; - - const firstVariant = product.variants.edges[0].node; - if ( - !firstVariant.selectedOptions || - firstVariant.selectedOptions.length === 0 - ) - return; - - const mainOption = firstVariant.selectedOptions[0]; - const optionValues = new Set(); - - product.variants.edges.forEach((edge) => { - const variant = edge.node; - if (variant.selectedOptions && variant.selectedOptions[0]) { - optionValues.add(variant.selectedOptions[0].value); - } - }); - - if (optionValues.size <= 1) return; - - const optionsContainer = document.querySelector("[data-product-options]"); - const optionsList = document.querySelector("[data-product-options-list]"); - - if (!optionsContainer || !optionsList) return; - - const optionName = mainOption.name; - const optionSlug = optionName.toLowerCase().replace(/\s+/g, "-"); - - optionsList.innerHTML = Array.from(optionValues) - .map((value) => { - const uniqueId = `${optionSlug}-${value - .toLowerCase() - .replace(/\s+/g, "-")}`; - const variant = product.variants.edges.find( - (e) => - e.node.selectedOptions && e.node.selectedOptions[0]?.value === value - )?.node; - const isAvailable = variant?.availableForSale || false; - - return ` -
  • - - -
  • - `; - }) - .join(""); - - optionsContainer.style.display = "block"; - - const radios = optionsList.querySelectorAll('input[type="radio"]'); - const addToCartBtn = document.querySelector("[data-shopify-add-to-cart]"); - const buttonText = addToCartBtn?.querySelector("[data-button-text]"); - - radios.forEach((radio) => { - radio.addEventListener("change", function () { - const variantId = this.dataset.variantId; - - if (addToCartBtn) { - addToCartBtn.dataset.variantId = variantId; - addToCartBtn.removeAttribute("disabled"); - } - - if (buttonText) { - buttonText.textContent = - addToCartBtn.dataset.defaultText || "Ajouter au panier"; - } - - const allLi = optionsList.querySelectorAll("li"); - allLi.forEach((li) => li.classList.remove("is-selected")); - this.closest("li").classList.add("is-selected"); - }); - }); - } - - function setupAddToCart(product) { - const addToCartBtn = document.querySelector("[data-shopify-add-to-cart]"); - if (!addToCartBtn) return; - - const productId = product.id.replace("gid://shopify/Product/", ""); - addToCartBtn.dataset.productId = productId; - - const hasMultipleVariants = product.variants.edges.length > 1; - const firstVariant = product.variants.edges[0]?.node; - const hasOptions = - firstVariant?.selectedOptions && firstVariant.selectedOptions.length > 0; - - const uniqueOptions = new Set(); - product.variants.edges.forEach((edge) => { - if (edge.node.selectedOptions && edge.node.selectedOptions[0]) { - uniqueOptions.add(edge.node.selectedOptions[0].value); - } - }); - const hasMultipleOptions = uniqueOptions.size > 1; - - if (hasMultipleVariants && hasOptions && hasMultipleOptions) { - addToCartBtn.setAttribute("disabled", "disabled"); - const buttonText = addToCartBtn.querySelector("[data-button-text]"); - if (buttonText) { - buttonText.textContent = - addToCartBtn.dataset.textChooseOption || "Choisissez une option"; - } - } else { - const firstAvailableVariant = product.variants.edges.find( - (e) => e.node.availableForSale - ); - if (firstAvailableVariant) { - const variantId = firstAvailableVariant.node.id.replace( - "gid://shopify/ProductVariant/", - "" - ); - addToCartBtn.dataset.variantId = variantId; - } - } - } - - function updateMetaTags(product, isEnglish) { - // Update title and description - const title = - isEnglish && product.titleEn?.value - ? product.titleEn.value - : product.title; - const description = - isEnglish && product.descriptionEn?.value - ? product.descriptionEn.value - : product.description; - - // Update Open Graph title - const ogTitle = document.getElementById("og-title"); - if (ogTitle) { - ogTitle.setAttribute("content", title); - } - - // Update Open Graph description - const ogDescription = document.getElementById("og-description"); - if (ogDescription && description) { - const excerpt = description.substring(0, 160); - ogDescription.setAttribute("content", excerpt); - } - - // Update Open Graph image - const ogImage = document.getElementById("og-image"); - if (ogImage && product.images.edges.length > 0) { - ogImage.setAttribute("content", product.images.edges[0].node.url); - } - - // Update product price - const ogPrice = document.getElementById("og-price"); - if (ogPrice) { - const price = parseFloat( - product.priceRange.minVariantPrice.amount - ).toFixed(2); - ogPrice.setAttribute("content", price); - } - - // Update availability - const ogAvailability = document.getElementById("og-availability"); - if (ogAvailability) { - const availability = product.availableForSale - ? "in stock" - : "out of stock"; - ogAvailability.setAttribute("content", availability); - } - - // Update page title - document.title = `${title} | Index.ngo`; - - // Update meta description - let metaDescription = document.querySelector('meta[name="description"]'); - if (metaDescription && description) { - const excerpt = description.substring(0, 160); - metaDescription.setAttribute("content", excerpt); - } - } -})(); diff --git a/assets/js/products-list-loader.js b/assets/js/products-list-loader.js deleted file mode 100644 index be32f4a..0000000 --- a/assets/js/products-list-loader.js +++ /dev/null @@ -1,47 +0,0 @@ -(async function() { - const container = document.querySelector('[data-products-loader]'); - if (!container) return; - - const language = (container.dataset.language || 'FR').toLowerCase(); - const isEnglish = language === 'en'; - - try { - const cart = new ShopifyCart({ - domain: 'nv7cqv-bu.myshopify.com', - storefrontAccessToken: 'dec3d35a2554384d149c72927d1cfd1b' - }); - - const productsData = await cart.getAllProducts(); - const products = productsData.edges; - - const productsHtml = products.map(edge => { - const product = edge.node; - const image = product.images.edges[0]?.node; - const price = parseFloat(product.priceRange.minVariantPrice.amount).toFixed(2); - const slug = product.handle; - const productUrl = isEnglish ? `/en/${slug}` : `/${slug}`; - const productTitle = isEnglish && product.titleEn?.value - ? product.titleEn.value - : product.title; - - return ` -
    -
    - ${image ? `${image.altText || productTitle}` : ''} -
    -

    - ${productTitle} -

    -

    ${price}€

    - -
    - `; - }).join(''); - - container.innerHTML = productsHtml; - - } catch (error) { - console.error('Error loading products:', error); - container.innerHTML = '

    Erreur lors du chargement des produits

    '; - } -})(); diff --git a/assets/js/shopify-cart.js b/assets/js/shopify-cart.js deleted file mode 100644 index 396ae38..0000000 --- a/assets/js/shopify-cart.js +++ /dev/null @@ -1,395 +0,0 @@ -/** - * Shopify Storefront API Client - * Custom implementation using Cart API (2026-01) - */ -class ShopifyCart { - constructor(config) { - this.domain = config.domain; - this.storefrontAccessToken = config.storefrontAccessToken; - this.apiVersion = '2026-01'; - this.endpoint = `https://${this.domain}/api/${this.apiVersion}/graphql.json`; - this.cartId = null; - this.cartItems = []; - - // Load existing cart from localStorage - this.loadCart(); - } - - /** - * Make GraphQL request to Shopify Storefront API - */ - async query(query, variables = {}) { - const response = await fetch(this.endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Shopify-Storefront-Access-Token': this.storefrontAccessToken, - }, - body: JSON.stringify({ query, variables }), - }); - - const result = await response.json(); - - if (result.errors) { - console.error('Shopify API Error:', result.errors); - throw new Error(result.errors[0].message); - } - - return result.data; - } - - /** - * Get product information by ID - */ - async getProduct(productId) { - const query = ` - query getProduct($id: ID!) { - product(id: $id) { - id - title - description - availableForSale - variants(first: 10) { - edges { - node { - id - title - price { - amount - currencyCode - } - availableForSale - } - } - } - } - } - `; - - const data = await this.query(query, { - id: `gid://shopify/Product/${productId}` - }); - - return data.product; - } - - /** - * Get product by handle - * @param {string} handle - Product handle (slug) - */ - async getProductByHandle(handle) { - const query = ` - query getProductByHandle($handle: String!) { - product(handle: $handle) { - id - handle - title - description - descriptionHtml - availableForSale - tags - titleEn: metafield(namespace: "custom", key: "title_en") { - value - } - descriptionEn: metafield(namespace: "custom", key: "description_en") { - value - } - priceRange { - minVariantPrice { - amount - currencyCode - } - } - images(first: 10) { - edges { - node { - id - url - altText - width - height - } - } - } - variants(first: 20) { - edges { - node { - id - title - sku - availableForSale - price { - amount - currencyCode - } - selectedOptions { - name - value - } - } - } - } - } - } - `; - - const data = await this.query(query, { handle }); - return data.product || null; - } - - /** - * Get all products for listing page - * @param {number} first - Number of products to fetch - */ - async getAllProducts(first = 20) { - const query = ` - query getAllProducts($first: Int!) { - products(first: $first, sortKey: TITLE) { - edges { - node { - id - handle - title - description - availableForSale - titleEn: metafield(namespace: "custom", key: "title_en") { - value - } - priceRange { - minVariantPrice { - amount - currencyCode - } - } - images(first: 1) { - edges { - node { - id - url - altText - } - } - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } - `; - - const data = await this.query(query, { first }); - return data.products; - } - - /** - * Create a new cart - */ - async createCart(lines = []) { - const query = ` - mutation cartCreate($input: CartInput!) { - cartCreate(input: $input) { - cart { - id - checkoutUrl - lines(first: 10) { - edges { - node { - id - quantity - merchandise { - ... on ProductVariant { - id - title - price { - amount - currencyCode - } - product { - title - } - } - } - } - } - } - } - userErrors { - field - message - } - } - } - `; - - const data = await this.query(query, { - input: { lines } - }); - - if (data.cartCreate.userErrors.length > 0) { - throw new Error(data.cartCreate.userErrors[0].message); - } - - this.cartId = data.cartCreate.cart.id; - this.saveCart(); - - return data.cartCreate.cart; - } - - /** - * Add item to cart - */ - async addToCart(variantId, quantity = 1) { - const lines = [{ - merchandiseId: `gid://shopify/ProductVariant/${variantId}`, - quantity: quantity - }]; - - let cart; - - if (this.cartId) { - // Add to existing cart - const query = ` - mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) { - cartLinesAdd(cartId: $cartId, lines: $lines) { - cart { - id - checkoutUrl - lines(first: 10) { - edges { - node { - id - quantity - merchandise { - ... on ProductVariant { - id - title - price { - amount - currencyCode - } - product { - title - } - } - } - } - } - } - } - userErrors { - field - message - } - } - } - `; - - const data = await this.query(query, { - cartId: this.cartId, - lines - }); - - if (data.cartLinesAdd.userErrors.length > 0) { - throw new Error(data.cartLinesAdd.userErrors[0].message); - } - - cart = data.cartLinesAdd.cart; - } else { - // Create new cart - cart = await this.createCart(lines); - } - - this.cartItems = cart.lines.edges; - return cart; - } - - /** - * Get existing cart by ID - */ - async getCart() { - if (!this.cartId) { - return null; - } - - const query = ` - query getCart($cartId: ID!) { - cart(id: $cartId) { - id - checkoutUrl - lines(first: 10) { - edges { - node { - id - quantity - merchandise { - ... on ProductVariant { - id - title - price { - amount - currencyCode - } - product { - title - } - } - } - } - } - } - } - } - `; - - try { - const data = await this.query(query, { - cartId: this.cartId - }); - - return data.cart; - } catch (error) { - // Cart might be expired or invalid - console.error('Error fetching cart:', error); - this.clearCart(); - return null; - } - } - - /** - * Get checkout URL to redirect user - */ - getCheckoutUrl(cart) { - return cart?.checkoutUrl || null; - } - - /** - * Save cart ID to localStorage - */ - saveCart() { - if (this.cartId) { - localStorage.setItem('shopify_cart_id', this.cartId); - } - } - - /** - * Load cart ID from localStorage - */ - loadCart() { - this.cartId = localStorage.getItem('shopify_cart_id'); - } - - /** - * Clear cart - */ - clearCart() { - this.cartId = null; - this.cartItems = []; - localStorage.removeItem('shopify_cart_id'); - } -} - -// Export for use in other scripts -window.ShopifyCart = ShopifyCart; diff --git a/assets/js/snipcart.js b/assets/js/snipcart.js index 13eef65..0e0dfee 100644 --- a/assets/js/snipcart.js +++ b/assets/js/snipcart.js @@ -6,13 +6,13 @@ window.SnipcartSettings = { // Redirection après paiement réussi document.addEventListener('snipcart.ready', function() { - Snipcart.events.on('cart.confirmed', function(cartState) { + Snipcart.execute('bind', 'order.completed', function(order) { // Détecter la langue actuelle depuis l'URL const currentPath = window.location.pathname; const langMatch = currentPath.match(/^\/([a-z]{2})(\/|$)/); const langPrefix = langMatch ? '/' + langMatch[1] : ''; - window.location.href = langPrefix + '/thanks?order=' + cartState.token; + window.location.href = langPrefix + '/thanks?order=' + order.token; }); }); diff --git a/assets/snipcart-archive/README.md b/assets/snipcart-archive/README.md deleted file mode 100644 index 3b1c388..0000000 --- a/assets/snipcart-archive/README.md +++ /dev/null @@ -1,164 +0,0 @@ -# Archive Snipcart - -Cette archive contient tous les fichiers et le code nécessaires pour réactiver l'intégration Snipcart si besoin. - -## Date d'archivage -13 janvier 2026 - -## Raison de l'archivage -Remplacement par l'intégration Shopify Buy Button - ---- - -## Fichiers archivés - -### Fichiers JavaScript -- `snipcart.js` - Loader Snipcart avec configuration de la clé API -- `product-size.js` - Gestion des options produit (tailles, etc.) pour Snipcart - -### Fichiers SCSS -- `_snipcart.scss` - Styles pour le modal Snipcart - ---- - -## Comment restaurer l'intégration Snipcart - -### 1. Restaurer les fichiers JavaScript - -#### Fichier: `assets/js/snipcart.js` -Copier le fichier depuis l'archive: -```bash -cp assets/snipcart-archive/snipcart.js assets/js/ -``` - -#### Fichier: `assets/js/product-size.js` -Copier le fichier depuis l'archive: -```bash -cp assets/snipcart-archive/product-size.js assets/js/ -``` - -### 2. Restaurer les styles SCSS - -#### Fichier: `assets/css/template/shop/_snipcart.scss` -Copier le fichier depuis l'archive: -```bash -cp assets/snipcart-archive/_snipcart.scss assets/css/template/shop/ -``` - -Puis décommenter l'import dans `assets/css/style.scss`: -```scss -// Décommenter cette ligne: -@import 'template/shop/snipcart'; -``` - -### 3. Restaurer le template produit - -#### Fichier: `site/templates/product.php` - -1. **Restaurer le bouton "Ajouter au panier" avec les attributs Snipcart** (ligne ~40-78): - - Décommenter tous les attributs `data-item-*` du bouton - - Ajouter la classe `snipcart-add-item` au bouton - -2. **Restaurer les scripts dans le footer** (ligne 114): - ```php - ['assets/js/product-size.js', 'assets/js/snipcart.js', 'assets/js/product-gallery.js']]) ?> - ``` - -### 4. Restaurer les routes et webhooks - -#### Fichier: `site/config/config.php` - -Décommenter les routes Snipcart (lignes 39-147): - -1. **Route de validation produit** (`validate.json`): - - Permet à Snipcart de valider les prix et stock - - Route: `(:any)/validate.json` - -2. **Webhook Snipcart**: - - Gère les événements de commande (décrémente le stock) - - Route: `snipcart-webhook` - -### 5. Configuration Snipcart - -#### Clé API publique -La clé API publique Snipcart est dans `snipcart.js`: -```javascript -publicApiKey: 'NGU4ODQ3MjAtY2MzMC00MWEyLWI2YTMtNjBmNGYzMTBlOTZkNjM4OTY1NDY4OTE5MTQyMTI3' -``` - -#### Configuration du webhook -Pour que le webhook fonctionne, il faut: -1. Configurer l'URL du webhook dans le dashboard Snipcart -2. URL: `https://votre-domaine.com/snipcart-webhook` -3. Événements à écouter: `order.completed` - -### 6. Vérifications après restauration - -- [ ] Les fichiers JS sont présents dans `assets/js/` -- [ ] Le fichier SCSS est présent et importé -- [ ] Les boutons "Ajouter au panier" ont la classe `snipcart-add-item` -- [ ] Les attributs `data-item-*` sont présents sur les boutons -- [ ] Les routes sont décommentées dans `config.php` -- [ ] Le CSS de Snipcart est compilé -- [ ] Le webhook est configuré dans le dashboard Snipcart -- [ ] Les traductions sont restaurées dans `site/languages/en.php` et `fr.php` - ---- - -## Fonctionnalités Snipcart implémentées - -### Gestion des produits -- Affichage du prix -- Options de produit (tailles, couleurs, etc.) -- Validation des options obligatoires -- Images produit - -### Gestion du panier -- Ajout au panier -- Gestion du stock -- Calcul des frais de port (basé sur poids/dimensions) -- Validation des prix côté serveur - -### Gestion des commandes -- Webhook pour décrémenter le stock automatiquement -- Redirection vers page de remerciement après paiement -- Token de commande dans l'URL - -### Multi-langue -- Support FR/EN -- Redirection post-paiement avec détection de la langue - ---- - -## Dépendances externes - -### CDN Snipcart -Snipcart est chargé depuis le CDN officiel: -- Version: 3.0 -- JS: `https://cdn.snipcart.com/themes/v3.0/default/snipcart.js` -- CSS: `https://cdn.snipcart.com/themes/v3.0/default/snipcart.css` - -### Stratégie de chargement -- `loadStrategy: 'on-user-interaction'` -- Chargement différé pour optimiser les performances -- Timeout: 2750ms - ---- - -## Notes importantes - -1. **Sécurité**: Le webhook devrait valider la signature Snipcart en production (voir commentaire dans `config.php`) - -2. **Stock**: Le système décrémente automatiquement le stock via le webhook `order.completed` - -3. **Validation**: Chaque produit expose une route `validate.json` pour que Snipcart puisse vérifier les prix - -4. **Multi-langue**: La redirection post-paiement détecte automatiquement la langue depuis l'URL - ---- - -## Support - -Pour toute question sur Snipcart: -- Documentation: https://docs.snipcart.com/ -- Support: https://snipcart.com/support diff --git a/assets/snipcart-archive/product-size.js b/assets/snipcart-archive/product-size.js deleted file mode 100644 index 399ffce..0000000 --- a/assets/snipcart-archive/product-size.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Gestion de la sélection des options produit - * Met à jour les attributs Snipcart et gère les classes CSS - */ - -(function() { - 'use strict'; - - /** - * Initialise la gestion des options - */ - function initOptionSelector() { - const optionsContainer = document.querySelector('.product-options'); - const addToCartButton = document.querySelector('.snipcart-add-item'); - - if (!addToCartButton) { - return; - } - - // Si pas d'options, le bouton est déjà actif - if (!optionsContainer) { - return; - } - - const radios = optionsContainer.querySelectorAll('input[type="radio"]'); - - // Réinitialiser toutes les options (important pour le cache navigateur) - radios.forEach(radio => { - radio.checked = false; - }); - - // Retirer la classe is-selected de tous les li - const allLi = optionsContainer.querySelectorAll('li'); - allLi.forEach(li => li.classList.remove('is-selected')); - - // S'assurer que le bouton est désactivé au départ - addToCartButton.setAttribute('disabled', 'disabled'); - - // Écouter les changements de sélection - radios.forEach(radio => { - radio.addEventListener('change', function() { - // Mettre à jour l'attribut Snipcart - addToCartButton.setAttribute('data-item-custom1-value', this.value); - - // Activer le bouton - addToCartButton.removeAttribute('disabled'); - - // Changer le texte du bouton - const buttonText = addToCartButton.querySelector('.txt'); - if (buttonText) { - buttonText.textContent = buttonText.getAttribute('data-default-text') || 'Ajouter au panier'; - } - - // Gérer la classe is-selected sur les li parents - allLi.forEach(li => li.classList.remove('is-selected')); - this.closest('li').classList.add('is-selected'); - }); - }); - } - - /** - * Initialisation au chargement de la page - */ - document.addEventListener('DOMContentLoaded', initOptionSelector); - -})(); diff --git a/assets/snipcart-archive/snipcart.js b/assets/snipcart-archive/snipcart.js deleted file mode 100644 index 13eef65..0000000 --- a/assets/snipcart-archive/snipcart.js +++ /dev/null @@ -1,94 +0,0 @@ -window.SnipcartSettings = { - publicApiKey: - 'NGU4ODQ3MjAtY2MzMC00MWEyLWI2YTMtNjBmNGYzMTBlOTZkNjM4OTY1NDY4OTE5MTQyMTI3', - loadStrategy: 'on-user-interaction', -}; - -// Redirection après paiement réussi -document.addEventListener('snipcart.ready', function() { - Snipcart.events.on('cart.confirmed', function(cartState) { - // Détecter la langue actuelle depuis l'URL - const currentPath = window.location.pathname; - const langMatch = currentPath.match(/^\/([a-z]{2})(\/|$)/); - const langPrefix = langMatch ? '/' + langMatch[1] : ''; - - window.location.href = langPrefix + '/thanks?order=' + cartState.token; - }); -}); - -(() => { - var c, d; - (d = (c = window.SnipcartSettings).version) != null || (c.version = '3.0'); - var s, S; - (S = (s = window.SnipcartSettings).timeoutDuration) != null || - (s.timeoutDuration = 2750); - var l, p; - (p = (l = window.SnipcartSettings).domain) != null || - (l.domain = 'cdn.snipcart.com'); - var w, u; - (u = (w = window.SnipcartSettings).protocol) != null || - (w.protocol = 'https'); - var f = - window.SnipcartSettings.version.includes('v3.0.0-ci') || - (window.SnipcartSettings.version != '3.0' && - window.SnipcartSettings.version.localeCompare('3.4.0', void 0, { - numeric: !0, - sensitivity: 'base', - }) === -1), - m = ['focus', 'mouseover', 'touchmove', 'scroll', 'keydown']; - window.LoadSnipcart = o; - document.readyState === 'loading' - ? document.addEventListener('DOMContentLoaded', r) - : r(); - function r() { - window.SnipcartSettings.loadStrategy - ? window.SnipcartSettings.loadStrategy === 'on-user-interaction' && - (m.forEach((t) => document.addEventListener(t, o)), - setTimeout(o, window.SnipcartSettings.timeoutDuration)) - : o(); - } - var a = !1; - function o() { - if (a) return; - a = !0; - let t = document.getElementsByTagName('head')[0], - e = document.querySelector('#snipcart'), - i = document.querySelector( - `src[src^="${window.SnipcartSettings.protocol}://${window.SnipcartSettings.domain}"][src$="snipcart.js"]` - ), - n = document.querySelector( - `link[href^="${window.SnipcartSettings.protocol}://${window.SnipcartSettings.domain}"][href$="snipcart.css"]` - ); - e || - ((e = document.createElement('div')), - (e.id = 'snipcart'), - e.setAttribute('hidden', 'true'), - document.body.appendChild(e)), - v(e), - i || - ((i = document.createElement('script')), - (i.src = `${window.SnipcartSettings.protocol}://${window.SnipcartSettings.domain}/themes/v${window.SnipcartSettings.version}/default/snipcart.js`), - (i.async = !0), - t.appendChild(i)), - n || - ((n = document.createElement('link')), - (n.rel = 'stylesheet'), - (n.type = 'text/css'), - (n.href = `${window.SnipcartSettings.protocol}://${window.SnipcartSettings.domain}/themes/v${window.SnipcartSettings.version}/default/snipcart.css`), - t.prepend(n)), - m.forEach((g) => document.removeEventListener(g, o)); - } - function v(t) { - !f || - ((t.dataset.apiKey = window.SnipcartSettings.publicApiKey), - window.SnipcartSettings.addProductBehavior && - (t.dataset.configAddProductBehavior = - window.SnipcartSettings.addProductBehavior), - window.SnipcartSettings.modalStyle && - (t.dataset.configModalStyle = window.SnipcartSettings.modalStyle), - window.SnipcartSettings.currency && - (t.dataset.currency = window.SnipcartSettings.currency), - window.SnipcartSettings.templatesUrl && - (t.dataset.templatesUrl = window.SnipcartSettings.templatesUrl)); - } -})(); diff --git a/content/1_tshirt-index-01/product.en.txt b/content/1_tshirt-index-01/product.en.txt new file mode 100644 index 0000000..0541df2 --- /dev/null +++ b/content/1_tshirt-index-01/product.en.txt @@ -0,0 +1,52 @@ +Title: T-shirt Index 01 + +---- + +Price: 35 + +---- + +Description:

    T-shirt de soutien à Index, 100% coton

    + +---- + +Details: + +[ + { + "content": { + "text": "

    100% cotton

    " + }, + "id": "detail1", + "isHidden": false, + "type": "text" + }, + { + "content": { + "text": "

    Lorem ipsum dolor sit amet

    " + }, + "id": "detail2", + "isHidden": false, + "type": "text" + } +] + +---- + +Options: + +- + label: Size + values: XS, S, M, L, XL + +---- + +Snipcartid: tshirt-01 + +---- + +Backgroundcolor: #ffffff + +---- + +Template: product \ No newline at end of file diff --git a/content/1_tshirt-index-01/product.fr.txt b/content/1_tshirt-index-01/product.fr.txt new file mode 100644 index 0000000..2226ab3 --- /dev/null +++ b/content/1_tshirt-index-01/product.fr.txt @@ -0,0 +1,56 @@ +Title: T-shirt Index 01 + +---- + +Price: 35 + +---- + +Stock: 10 + +---- + +Description: T-shirt de soutien à Index, 100% coton + +---- + +Details:

    T-shirt en coton organique avec impression sérigraphique.
    Marquage sur la face avant : logo « INDEX » de 10 cm de large.

    Envoi uniquement via Mondial Relay vers la France, la Belgique et la Suisse.

    + +---- + +Hasoptions: true + +---- + +Optionlabel: Taille + +---- + +Optionvalues: XS, S, M, L, XL + +---- + +Options: + +- + label: Taille + values: XS, S, M, L, XL +- + label: Couleur + values: Rouge, Vert + +---- + +Snipcartid: tshirt-01 + +---- + +Backgroundcolor: #ffffff + +---- + +Template: product + +---- + +Uuid: udrrfizhayqixfoo \ No newline at end of file diff --git a/content/1_tshirt-index-01/tshirt-01.png b/content/1_tshirt-index-01/tshirt-01.png new file mode 100644 index 0000000..99899b8 Binary files /dev/null and b/content/1_tshirt-index-01/tshirt-01.png differ diff --git a/content/1_tshirt-index-01/tshirt-01.png.fr.txt b/content/1_tshirt-index-01/tshirt-01.png.fr.txt new file mode 100644 index 0000000..c8fd3f3 --- /dev/null +++ b/content/1_tshirt-index-01/tshirt-01.png.fr.txt @@ -0,0 +1,9 @@ +Sort: 1 + +---- + +Uuid: deupkqq83jvloz0r + +---- + +Template: image \ No newline at end of file diff --git a/content/error/error.en.txt b/content/error/error.en.txt deleted file mode 100644 index e7a7a4d..0000000 --- a/content/error/error.en.txt +++ /dev/null @@ -1,5 +0,0 @@ -Title: Error - ----- - -Template: default diff --git a/content/error/error.fr.txt b/content/error/error.fr.txt index 986fe1a..1301277 100644 --- a/content/error/error.fr.txt +++ b/content/error/error.fr.txt @@ -1,5 +1 @@ -Title: Erreur - ----- - -Uuid: kcrqkszqasludg2h +Uuid: kcrqkszqasludg2h \ No newline at end of file diff --git a/content/thanks/thanks.en.txt b/content/thanks/thanks.en.txt deleted file mode 100644 index 41baccd..0000000 --- a/content/thanks/thanks.en.txt +++ /dev/null @@ -1,13 +0,0 @@ -Title: Thank you for your order - ----- - -Text: - -Your order has been confirmed! You will receive a confirmation email shortly. - -Thank you for your purchase. - ----- - -Template: thanks \ No newline at end of file diff --git a/content/thanks/thanks.fr.txt b/content/thanks/thanks.fr.txt index 067eeda..1972914 100644 --- a/content/thanks/thanks.fr.txt +++ b/content/thanks/thanks.fr.txt @@ -7,7 +7,3 @@ Text: Votre commande a été confirmée ! Vous allez recevoir un email de confirmation sous peu. Merci pour votre achat. - ----- - -Template: thanks diff --git a/content/thanks/thanks.txt b/content/thanks/thanks.txt index a2fae52..e968ef6 100644 --- a/content/thanks/thanks.txt +++ b/content/thanks/thanks.txt @@ -1 +1,9 @@ -Title: Thanks \ No newline at end of file +Title: Thank you for your order + +---- + +Text: + +Your order has been confirmed! You will receive a confirmation email shortly. + +Thank you for your purchase. diff --git a/create-og-image.html b/create-og-image.html deleted file mode 100644 index 5dc314c..0000000 --- a/create-og-image.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - Generate OG Image - - - -

    Générer l'image Open Graph

    -

    Cette page génère une image 1200x630px avec le logo Index pour les partages sociaux.

    - -
    - -
    -
    - - - - diff --git a/site/blueprints/pages/product.yml b/site/blueprints/pages/product.yml index 978bcde..52fde12 100644 --- a/site/blueprints/pages/product.yml +++ b/site/blueprints/pages/product.yml @@ -1,21 +1,134 @@ -title: Product +title: + en: Product + fr: Produit icon: cart -columns: - - width: 1/1 - fields: - info: - type: info - text: - en: "Product data (title, description, images, price) is managed in Shopify Admin. This Kirby page only serves for routing." - fr: "Les données produit (titre, description, images, prix) sont gérées dans Shopify Admin. Cette page Kirby sert uniquement au routing." +tabs: + content: + label: + en: Content + fr: Contenu + columns: + - width: 2/3 + sections: + main: + type: fields + fields: + price: + label: + en: Price (€) + fr: Prix (€) + type: number + min: 0 + step: 0.01 + required: true + translate: false + width: 1/4 + stock: + label: Stock + type: number + min: 0 + default: 0 + help: + en: Edit through french version + fr: Partagé entre les versions FR et EN + translate: false + width: 1/4 + space: + type: gap + width: 2/4 + weight: + label: + en: Weight (g) + fr: Poids (g) + type: number + min: 0 + default: 0 + help: + en: Weight in grams for shipping calculation + fr: Poids en grammes pour le calcul de la livraison + translate: false + width: 1/4 + length: + label: + en: Length (cm) + fr: Longueur (cm) + type: number + min: 0 + default: 0 + help: + en: Package length in centimeters + fr: Longueur du colis en centimètres + translate: false + width: 1/4 + width: + label: + en: Width (cm) + fr: Largeur (cm) + type: number + min: 0 + default: 0 + help: + en: Package width in centimeters + fr: Largeur du colis en centimètres + translate: false + width: 1/4 + height: + label: + en: Height (cm) + fr: Hauteur (cm) + type: number + min: 0 + default: 0 + help: + en: Package height in centimeters + fr: Hauteur du colis en centimètres + translate: false + width: 1/4 + description: + label: Description panier + type: writer + help: Visible dans le panier seulement. + details: + label: + en: Details + fr: Détails + type: writer + hasOptions: + label: + en: Options + fr: Options + type: toggle + default: false + translate: false + width: 1/7 + optionLabel: + label: + en: Option label + fr: Libellé de l'option + type: text + width: 3/7 + when: + hasOptions: true + optionValues: + label: + en: Option values + fr: Valeurs de l'option + type: tags + help: + en: "Comma-separated values (e.g.: XS, S, M, L, XL)" + fr: "Valeurs séparées par des virgules (ex: XS, S, M, L, XL)" + translate: false + when: + hasOptions: true + width: 3/7 - shopifyHandle: - label: - en: Shopify Handle - fr: Shopify Handle - type: text - help: - en: "Product handle from Shopify (e.g. tshirt-index-01). If empty, uses the page slug." - fr: "Handle du produit Shopify (ex: tshirt-index-01). Si vide, utilise le slug de la page Kirby." - placeholder: tshirt-index-01 + - width: 1/3 + sections: + images: + type: files + headline: + en: Product Images + fr: Images du produit + template: image + layout: cards diff --git a/site/blueprints/site.yml b/site/blueprints/site.yml index 13b775f..df442f5 100644 --- a/site/blueprints/site.yml +++ b/site/blueprints/site.yml @@ -1,11 +1,15 @@ title: Site sections: - shopify: - type: fields - fields: - shopifyRefreshButton: - type: shopify-refresh - label: - en: Shopify Products - fr: Produits Shopify + pages: + type: pages + headline: + en: Products + fr: Produits + template: product + sortBy: title asc + info: "{{ page.stock }} en stock" + layout: cardlets + image: + query: page.files.first + cover: true diff --git a/site/config/config.php b/site/config/config.php index 5023f17..55d96fb 100644 --- a/site/config/config.php +++ b/site/config/config.php @@ -1,142 +1,10 @@ true, 'languages' => true, - 'cache' => [ - 'shopify' => true - ], - - 'routes' => [ - // Sitemap - [ - 'pattern' => 'sitemap.xml', - 'action' => function() { - $sitemap = page('home'); - return new Kirby\Cms\Response( - snippet('sitemap', ['page' => $sitemap], true), - 'application/xml' - ); - } - ], - // English homepage - [ - 'pattern' => 'en', - 'action' => function() { - $home = page('home'); - if ($home) { - site()->visit($home, 'en'); - return $home; - } - return null; - } - ], - // English thanks page - [ - 'pattern' => 'en/thanks', - 'action' => function() { - $thanks = page('thanks'); - if ($thanks) { - site()->visit($thanks, 'en'); - return $thanks; - } - return null; - } - ], - // English error page - [ - 'pattern' => 'en/error', - 'action' => function() { - $error = page('error'); - if ($error) { - site()->visit($error, 'en'); - return $error; - } - return null; - } - ], - // French thanks page - [ - 'pattern' => 'thanks', - 'action' => function() { - return page('thanks'); - } - ], - // French error page - [ - 'pattern' => 'error', - 'action' => function() { - return page('error'); - } - ], - // French products (default) - [ - 'pattern' => '(:any)', - 'action' => function($slug) { - if (in_array($slug, ['home', 'error', 'thanks'])) { - return null; - } - - $products = getShopifyProducts(); - - foreach ($products as $product) { - if ($product['handle'] === $slug) { - $page = Page::factory([ - 'slug' => $product['handle'], - 'template' => 'product', - 'content' => [ - 'title' => $product['title'], - 'shopifyHandle' => $product['handle'], - 'uuid' => $product['id'] - ] - ]); - - site()->visit($page, 'fr'); - return $page; - } - } - - return null; - } - ], - // English products - [ - 'pattern' => 'en/(:any)', - 'action' => function($slug) { - if (in_array($slug, ['home', 'error', 'thanks'])) { - return null; - } - - $products = getShopifyProducts(); - - foreach ($products as $product) { - if ($product['handle'] === $slug) { - $page = Page::factory([ - 'slug' => $product['handle'], - 'template' => 'product', - 'content' => [ - 'title' => $product['title'], - 'shopifyHandle' => $product['handle'], - 'uuid' => $product['id'] - ] - ]); - - site()->visit($page, 'en'); - return $page; - } - } - - return null; - } - ] - ], - 'thumbs' => [ 'quality' => 85, 'format' => 'webp', @@ -167,4 +35,114 @@ return [ ], ], ], + + 'routes' => [ + [ + 'pattern' => '(:any)/validate.json', + 'method' => 'GET', + 'action' => function ($slug) { + $page = page($slug); + + if (!$page || $page->intendedTemplate() !== 'product') { + header('Content-Type: application/json'); + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + return; + } + + // Récupérer le stock actuel + $stock = (int) $page->stock()->value(); + + // Préparer la réponse JSON pour Snipcart + $response = [ + 'id' => $page->slug(), + 'price' => (float) $page->price()->value(), + 'url' => $page->url() . '/validate.json', + 'name' => $page->title()->value(), + 'description' => $page->description()->value(), + 'image' => $page->images()->first() ? $page->images()->first()->url() : '', + 'inventory' => $stock, + 'stock' => $stock + ]; + + // Ajouter les options si disponibles + if ($page->hasOptions()->toBool() && $page->optionValues()->isNotEmpty()) { + $values = $page->optionValues()->split(','); + $trimmedValues = array_map('trim', $values); + $snipcartOptions = implode('|', $trimmedValues); + + $response['customFields'] = [ + [ + 'name' => $page->optionLabel()->value(), + 'options' => $snipcartOptions, + 'required' => true + ] + ]; + } + + header('Content-Type: application/json'); + echo json_encode($response); + } + ], + [ + 'pattern' => 'snipcart-webhook', + 'method' => 'POST', + 'action' => function () { + // Webhook handler pour Snipcart + // Vérifie la signature et décrémente le stock + + $requestBody = file_get_contents('php://input'); + $event = json_decode($requestBody, true); + + // Vérifier la signature Snipcart (à implémenter avec la clé secrète) + // $signature = $_SERVER['HTTP_X_SNIPCART_REQUESTTOKEN'] ?? ''; + + if (!$event || !isset($event['eventName'])) { + return Response::json(['error' => 'Invalid request'], 400); + } + + // Gérer l'événement order.completed + if ($event['eventName'] === 'order.completed') { + $order = $event['content'] ?? null; + + if ($order && isset($order['items'])) { + // Impersonate pour avoir les permissions d'écriture + kirby()->impersonate('kirby'); + + foreach ($order['items'] as $item) { + $productId = $item['id'] ?? null; + $quantity = $item['quantity'] ?? 0; + + if ($productId && $quantity > 0) { + // Trouver le produit par son slug + $products = site()->index()->filterBy('intendedTemplate', 'product'); + + foreach ($products as $product) { + if ($product->slug() === $productId) { + // Décrémenter le stock + $currentStock = (int) $product->stock()->value(); + $newStock = max(0, $currentStock - $quantity); + + // Mettre à jour le stock + try { + $product->update([ + 'stock' => $newStock + ]); + } catch (Exception $e) { + // Log l'erreur mais continue le traitement + error_log('Webhook stock update error: ' . $e->getMessage()); + } + + break; + } + } + } + } + } + } + + return Response::json(['status' => 'success'], 200); + } + ] + ] ]; diff --git a/site/config/shopify.php b/site/config/shopify.php deleted file mode 100644 index cbd0d2e..0000000 --- a/site/config/shopify.php +++ /dev/null @@ -1,82 +0,0 @@ -cache('shopify'); - $products = $cache->get('products'); - - if ($products === null) { - $products = fetchShopifyProducts(); - $cache->set('products', $products, 60); // Cache 60 minutes - } - - return $products; -} - -/** - * Appel direct à l'API Shopify Storefront - */ -function fetchShopifyProducts(): array -{ - $domain = 'nv7cqv-bu.myshopify.com'; - $token = 'dec3d35a2554384d149c72927d1cfd1b'; - $apiVersion = '2026-01'; - $endpoint = "https://{$domain}/api/{$apiVersion}/graphql.json"; - - $query = ' - query getAllProducts { - products(first: 250, sortKey: TITLE) { - edges { - node { - id - handle - title - } - } - } - } - '; - - $ch = curl_init($endpoint); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Nécessaire pour dev local sur Windows - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Content-Type: application/json', - 'X-Shopify-Storefront-Access-Token: ' . $token - ]); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ - 'query' => $query - ])); - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if ($httpCode !== 200) { - error_log("Shopify API error: HTTP {$httpCode}"); - return []; - } - - $data = json_decode($response, true); - - if (isset($data['errors'])) { - error_log("Shopify API GraphQL errors: " . json_encode($data['errors'])); - return []; - } - - $products = []; - foreach ($data['data']['products']['edges'] as $edge) { - $node = $edge['node']; - $products[] = [ - 'id' => $node['id'], - 'handle' => $node['handle'], - 'title' => $node['title'] - ]; - } - - return $products; -} diff --git a/site/controllers/product.php b/site/controllers/product.php deleted file mode 100644 index bbf1fe7..0000000 --- a/site/controllers/product.php +++ /dev/null @@ -1,11 +0,0 @@ -shopifyHandle()->or($page->slug())->value(); - $language = $kirby->language()->code(); - - return [ - 'shopifyHandle' => $shopifyHandle, - 'language' => $language - ]; -}; diff --git a/site/languages/en.php b/site/languages/en.php index e356f2c..55c6d63 100644 --- a/site/languages/en.php +++ b/site/languages/en.php @@ -13,24 +13,7 @@ return [ 'backToShop' => 'Back to shop', 'supportText' => 'To support us, you can also', 'makeDonation' => 'make a donation', - - // Shop / Cart 'addToCart' => 'Add to cart', - 'cart' => 'Cart', - 'cartEmpty' => 'Your cart is empty', - 'total' => 'Total', - 'checkout' => 'Checkout', - 'remove' => 'Remove', - 'inStock' => 'In stock', - 'outOfStock' => 'Out of stock', - 'addingToCart' => 'Adding...', - 'addedToCart' => 'Added! ✓', - 'errorAddToCart' => 'Error - Try again', - 'closeCart' => 'Close cart', - 'loading' => 'Loading...', - 'productNotFound' => 'Product not found', - 'selectVariant' => 'Select', - 'chooseOption' => 'Choose an option', // Blueprints - Home 'home.title' => 'Home', diff --git a/site/languages/fr.php b/site/languages/fr.php index 98c263d..64f3f5e 100644 --- a/site/languages/fr.php +++ b/site/languages/fr.php @@ -13,24 +13,7 @@ return [ 'backToShop' => 'Retour à la boutique', 'supportText' => 'Pour nous soutenir, vous pouvez aussi', 'makeDonation' => 'faire un don', - - // Shop / Cart 'addToCart' => 'Ajouter au panier', - 'cart' => 'Panier', - 'cartEmpty' => 'Votre panier est vide', - 'total' => 'Total', - 'checkout' => 'Passer commande', - 'remove' => 'Retirer', - 'inStock' => 'En stock', - 'outOfStock' => 'Rupture de stock', - 'addingToCart' => 'Ajout en cours...', - 'addedToCart' => 'Ajouté ! ✓', - 'errorAddToCart' => 'Erreur - Réessayer', - 'closeCart' => 'Fermer le panier', - 'loading' => 'Chargement...', - 'productNotFound' => 'Produit non trouvé', - 'selectVariant' => 'Choisir', - 'chooseOption' => 'Choisissez une option', // Blueprints - Home 'home.title' => 'Accueil', diff --git a/site/plugins/shopify-refresh-button/.editorconfig b/site/plugins/shopify-refresh-button/.editorconfig deleted file mode 100644 index 3b762c9..0000000 --- a/site/plugins/shopify-refresh-button/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.php] -indent_size = 4 - -[*.md,*.txt] -trim_trailing_whitespace = false -insert_final_newline = false - -[composer.json] -indent_size = 4 diff --git a/site/plugins/shopify-refresh-button/.gitattributes b/site/plugins/shopify-refresh-button/.gitattributes deleted file mode 100644 index 033ba13..0000000 --- a/site/plugins/shopify-refresh-button/.gitattributes +++ /dev/null @@ -1,11 +0,0 @@ -# Note: You need to uncomment the lines you want to use; the other lines can be deleted - -# Git -# .gitattributes export-ignore -# .gitignore export-ignore - -# Tests -# /.coveralls.yml export-ignore -# /.travis.yml export-ignore -# /phpunit.xml.dist export-ignore -# /tests/ export-ignore diff --git a/site/plugins/shopify-refresh-button/.gitignore b/site/plugins/shopify-refresh-button/.gitignore deleted file mode 100644 index 4d81cf5..0000000 --- a/site/plugins/shopify-refresh-button/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# OS files -.DS_Store - -# npm modules -/node_modules - -# Parcel cache folder -.cache - -# Composer files -/vendor - -# kirbyup temp development entry -/index.dev.mjs diff --git a/site/plugins/shopify-refresh-button/LICENSE.md b/site/plugins/shopify-refresh-button/LICENSE.md deleted file mode 100755 index 8e663d7..0000000 --- a/site/plugins/shopify-refresh-button/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/site/plugins/shopify-refresh-button/README.md b/site/plugins/shopify-refresh-button/README.md deleted file mode 100755 index ad2b202..0000000 --- a/site/plugins/shopify-refresh-button/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# Kirby Pluginkit: Example plugin for Kirby - -> Variant "Panel plugin setup" - -This is a boilerplate for a Kirby Panel plugin that can be installed via all three [supported installation methods](https://getkirby.com/docs/guide/plugins/plugin-setup-basic#the-three-plugin-installation-methods). - -You can find a list of Pluginkit variants on the [`master` branch](https://github.com/getkirby/pluginkit/tree/master). - -**** - -## How to use the Pluginkit - -1. Fork this repository -2. Change the plugin name and description in the `composer.json` -3. Change the plugin name in the `index.php` and `src/index.js` -4. Change the license if you don't want to publish under MIT -5. Add your plugin code to the `index.php` and `src/index.js` -6. Update this `README` with instructions for your plugin - -### Install the development and build setup - -We use [kirbyup](https://github.com/johannschopplich/kirbyup) for the development and build setup. - -You can start developing directly. kirbyup will be fetched remotely with your first `npm run` command, which may take a short amount of time. - -### Development - -You can start the dev process with: - -```bash -npm run dev -``` - -This will automatically update the `index.js` and `index.css` of your plugin as soon as you make changes. -Reload the Panel to see your code changes reflected. - -With kirbyup 2.0.0+ and Kirby 3.7.4+ you can alternatively use hot module reloading (HMR): - -```bash -npm run serve -``` - -This will start a development server that updates the page as soon as you make changes. Some updates are instant, like CSS or Vue template changes, others require a reload of the page, which happens automatically. - -> [!NOTE] -> The live reload functionality requires top level await, [which is only supported in modern browsers](https://caniuse.com/mdn-javascript_operators_await_top_level). If you're developing in older browsers, use `npm run dev` and reload the page manually to see changes. - -### Production - -As soon as you are happy with your plugin, you should build the final version with: - -```bash -npm run build -``` - -This will automatically create a minified and optimized version of your `index.js` and `index.css` -which you can ship with your plugin. - -We have a tutorial on how to build your own plugin based on the Pluginkit [in the Kirby documentation](https://getkirby.com/docs/guide/plugins/plugin-setup-basic). - -### Build reproducibility - -While kirbyup will stay backwards compatible, exact build reproducibility may be of importance to you. If so, we recommend to target a specific package version, rather than using npx: - -```json -{ - "scripts": { - "dev": "kirbyup src/index.js --watch", - "build": "kirbyup src/index.js" - }, - "devDependencies": { - "kirbyup": "^3.1.0" - } -} -``` - -What follows is an example README for your plugin. - -**** - -## Installation - -### Download - -Download and copy this repository to `/site/plugins/{{ plugin-name }}`. - -### Git submodule - -```bash -git submodule add https://github.com/{{ your-name }}/{{ plugin-name }}.git site/plugins/{{ plugin-name }} -``` - -### Composer - -```bash -composer require {{ your-name }}/{{ plugin-name }} -``` - -## Setup - -*Additional instructions on how to configure the plugin (e.g. blueprint setup, config options, etc.)* - -## Options - -*Document the options and APIs that this plugin offers* - -## Development - -*Add instructions on how to help working on the plugin (e.g. npm setup, Composer dev dependencies, etc.)* - -## License - -MIT - -## Credits - -- [Your Name](https://github.com/ghost) diff --git a/site/plugins/shopify-refresh-button/SECURITY.md b/site/plugins/shopify-refresh-button/SECURITY.md deleted file mode 100644 index 3726336..0000000 --- a/site/plugins/shopify-refresh-button/SECURITY.md +++ /dev/null @@ -1,18 +0,0 @@ -# Security Policy - -## Supported Versions - -*Use this section to tell people about which versions of your project are currently being supported with security updates.* - -| Version | Supported | -| ------- | ------------------ | -| 5.1.x | :white_check_mark: | -| 5.0.x | :x: | -| 4.0.x | :white_check_mark: | -| < 4.0 | :x: | - -## Reporting a Vulnerability - -*Use this section to tell people how to report a vulnerability.* - -*Tell them where to go, how often they can expect to get an update on a reported vulnerability, what to expect if the vulnerability is accepted or declined, etc.* diff --git a/site/plugins/shopify-refresh-button/composer.json b/site/plugins/shopify-refresh-button/composer.json deleted file mode 100755 index fa07b14..0000000 --- a/site/plugins/shopify-refresh-button/composer.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "getkirby/pluginkit", - "description": "Kirby Example Plugin", - "license": "MIT", - "type": "kirby-plugin", - "version": "1.0.0", - "authors": [ - { - "name": "Your Name", - "email": "you@example.com" - } - ], - "require": { - "getkirby/composer-installer": "^1.1" - }, - "config": { - "allow-plugins": { - "getkirby/composer-installer": true - } - } -} diff --git a/site/plugins/shopify-refresh-button/composer.lock b/site/plugins/shopify-refresh-button/composer.lock deleted file mode 100644 index a5ae0fa..0000000 --- a/site/plugins/shopify-refresh-button/composer.lock +++ /dev/null @@ -1,66 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "37a8e61308b9b6f49cb9835f477f0c64", - "packages": [ - { - "name": "getkirby/composer-installer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/getkirby/composer-installer.git", - "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d", - "reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0" - }, - "require-dev": { - "composer/composer": "^1.8 || ^2.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Kirby\\ComposerInstaller\\Plugin" - }, - "autoload": { - "psr-4": { - "Kirby\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins", - "homepage": "https://getkirby.com", - "support": { - "issues": "https://github.com/getkirby/composer-installer/issues", - "source": "https://github.com/getkirby/composer-installer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://getkirby.com/buy", - "type": "custom" - } - ], - "time": "2020-12-28T12:54:39+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/site/plugins/shopify-refresh-button/index.js b/site/plugins/shopify-refresh-button/index.js deleted file mode 100644 index 677cea5..0000000 --- a/site/plugins/shopify-refresh-button/index.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){"use strict";function l(n,r,t,e,o,a,s,f){var i=typeof n=="function"?n.options:n;return r&&(i.render=r,i.staticRenderFns=t,i._compiled=!0),{exports:n,options:i}}const p={__name:"ShopifyRefreshButton",props:{products:{type:Array,default:()=>[]}},setup(n){const r=n,t=Vue.ref("Synchroniser depuis Shopify"),e=Vue.ref("refresh"),o=Vue.ref("aqua-icon"),a=Vue.ref(!1),s=Vue.ref([]);Vue.onMounted(()=>{s.value=r.products||[]});const f=Vue.computed(()=>{const u=s.value.length;return`${u} produit${u>1?"s":""} Shopify en cache`}),i=Vue.computed(()=>s.value.length===0?"Aucun produit trouvé. Cliquez sur 'Rafraîchir Shopify' pour récupérer les produits.":s.value.map(u=>`• ${u.title}
    `).join(` -`));async function y(){a.value=!0,e.value="loader",o.value="orange-icon",t.value="En cours…";try{const c=await(await fetch("/shopify/refresh-cache.json",{method:"POST",headers:{"Content-Type":"application/json"}})).json();if(c.status==="error")throw new Error(c.message);s.value=c.products||[],t.value=`Terminé - ${c.count} produit${c.count>1?"s":""}`,e.value="check",o.value="green-icon",setTimeout(()=>{t.value="Synchroniser depuis Shopify",e.value="refresh",o.value="aqua-icon",a.value=!1},3e3)}catch(u){console.error(u),t.value="Erreur",e.value="alert",o.value="red-icon",setTimeout(()=>{t.value="Synchroniser depuis Shopify",e.value="refresh",o.value="aqua-icon",a.value=!1},3e3)}}return{__sfc:!0,props:r,text:t,icon:e,theme:o,isProcessing:a,currentProducts:s,infoLabel:f,infoText:i,refreshCache:y}}};var h=function(){var r=this,t=r._self._c,e=r._self._setupProxy;return t("div",[t("k-info-field",{attrs:{label:e.infoLabel,text:e.infoText,theme:"info"}}),t("k-button",{staticStyle:{"margin-top":"1rem"},attrs:{theme:e.theme,variant:"dimmed",icon:e.icon,title:"Synchroniser le cache des produits Shopify",disabled:e.isProcessing},on:{click:function(o){return e.refreshCache()}}},[r._v(" "+r._s(e.text)+" ")])],1)},d=[],v=l(p,h,d);const m=v.exports;window.panel.plugin("index/shopify-refresh-button",{fields:{"shopify-refresh":m}})})(); diff --git a/site/plugins/shopify-refresh-button/index.php b/site/plugins/shopify-refresh-button/index.php deleted file mode 100755 index 2fd9cdf..0000000 --- a/site/plugins/shopify-refresh-button/index.php +++ /dev/null @@ -1,46 +0,0 @@ - [ - 'shopify-refresh' => [ - 'props' => [ - 'products' => function() { - return getShopifyProducts(); - } - ], - ] - ], - 'routes' => [ - [ - 'pattern' => 'shopify/refresh-cache.json', - 'method' => 'POST', - 'action' => function() { - if (!kirby()->user()) { - return [ - 'status' => 'error', - 'message' => 'Unauthorized' - ]; - } - - try { - kirby()->cache('shopify')->flush(); - - $products = fetchShopifyProducts(); - - return [ - 'status' => 'success', - 'message' => 'Cache Shopify rafraîchi avec succès', - 'count' => count($products), - 'products' => $products - ]; - } catch (\Throwable $e) { - return [ - 'status' => 'error', - 'message' => 'Erreur lors du rafraîchissement du cache', - 'details' => $e->getMessage() - ]; - } - } - ] - ] -]); diff --git a/site/plugins/shopify-refresh-button/package.json b/site/plugins/shopify-refresh-button/package.json deleted file mode 100644 index bdbe47f..0000000 --- a/site/plugins/shopify-refresh-button/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "scripts": { - "dev": "npx -y kirbyup src/index.js --watch", - "serve": "npx -y kirbyup serve src/index.js", - "build": "npx -y kirbyup src/index.js" - } -} diff --git a/site/plugins/shopify-refresh-button/src/components/ShopifyRefreshButton.vue b/site/plugins/shopify-refresh-button/src/components/ShopifyRefreshButton.vue deleted file mode 100644 index 83425e4..0000000 --- a/site/plugins/shopify-refresh-button/src/components/ShopifyRefreshButton.vue +++ /dev/null @@ -1,97 +0,0 @@ - - - diff --git a/site/plugins/shopify-refresh-button/src/index.js b/site/plugins/shopify-refresh-button/src/index.js deleted file mode 100755 index 7fedea6..0000000 --- a/site/plugins/shopify-refresh-button/src/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import ShopifyRefreshButton from "./components/ShopifyRefreshButton.vue"; - -window.panel.plugin("index/shopify-refresh-button", { - fields: { - "shopify-refresh": ShopifyRefreshButton - } -}); diff --git a/site/snippets/buy-button--t-shirt.php b/site/snippets/buy-button--t-shirt.php deleted file mode 100644 index 489b08d..0000000 --- a/site/snippets/buy-button--t-shirt.php +++ /dev/null @@ -1,20 +0,0 @@ -
    -
    -

    -
    - - -
    \ No newline at end of file diff --git a/site/snippets/buy-button.php b/site/snippets/buy-button.php deleted file mode 100644 index 4f2bc74..0000000 --- a/site/snippets/buy-button.php +++ /dev/null @@ -1,20 +0,0 @@ -
    - -
    diff --git a/site/snippets/cart-drawer.php b/site/snippets/cart-drawer.php deleted file mode 100644 index 8ba5459..0000000 --- a/site/snippets/cart-drawer.php +++ /dev/null @@ -1,32 +0,0 @@ -
    -
    -
    -
    -

    - -
    - -
    -
    -

    -
    - -
    -
    - - -
    -
    \ No newline at end of file diff --git a/site/snippets/footer.php b/site/snippets/footer.php index 91cbf60..6acee68 100644 --- a/site/snippets/footer.php +++ b/site/snippets/footer.php @@ -1,5 +1,3 @@ - -
    - - - - - - - - - + + + + - - diff --git a/site/snippets/header.php b/site/snippets/header.php index f25287e..ff9bf58 100644 --- a/site/snippets/header.php +++ b/site/snippets/header.php @@ -1,16 +1,19 @@ - + + + + <?= $title ?? $page->title() ?> | Index.ngo + - - + diff --git a/site/snippets/seo.php b/site/snippets/seo.php deleted file mode 100644 index 2959ace..0000000 --- a/site/snippets/seo.php +++ /dev/null @@ -1,79 +0,0 @@ -language()->code(); - -// Basic meta -$title = $page->customTitle()->or($page->title())->value(); -$siteName = 'Index.ngo'; -$fullTitle = $title . ' | ' . $siteName; - -// Default descriptions by language -$defaultDescriptionFr = 'Boutique de Index, ONG d\'investigation indépendante'; -$defaultDescriptionEn = 'Index shop, independent investigative NGO'; -$defaultDescription = $lang == 'en' ? $defaultDescriptionEn : $defaultDescriptionFr; - -$description = $page->metaDescription()->or($page->description())->value(); -if ($description) { - $description = excerpt($description, 160); -} else { - $description = $defaultDescription; -} - -$url = $page->url(); -// Use product image if available, otherwise use default OG image -// TODO: Create assets/og-logo.png (1200x630px) with Index logo + description -$image = $page->image() ? $page->image()->url() : url('assets/favicon.png'); -?> - - - - -<?= $fullTitle ?> - - - - - - -languages() as $language): ?> - - - - - - - - - - - - - - -languages() as $language): ?> -code() != $lang): ?> - - - -template() == 'product'): ?> - - - - - - - - - - - - - - - - - diff --git a/site/snippets/sitemap.php b/site/snippets/sitemap.php deleted file mode 100644 index 122172d..0000000 --- a/site/snippets/sitemap.php +++ /dev/null @@ -1,54 +0,0 @@ -' ?> - -index()->filterBy('template', 'in', ['home', 'error', 'thanks']); - -foreach ($pages as $p) { - foreach ($kirby->languages() as $lang) { - $url = $p->url($lang->code()); -?> - - - modified('c', 'date') ?> - monthly - isHomePage() ? '1.0' : '0.8' ?> - languages() as $altLang): ?> - - - -languages() as $lang) { - $url = $lang->code() == 'fr' - ? $site->url() . '/' . $product['handle'] - : $site->url() . '/en/' . $product['handle']; -?> - - - - weekly - 0.9 - languages() as $altLang): ?> - code() == 'fr' - ? $site->url() . '/' . $product['handle'] - : $site->url() . '/en/' . $product['handle']; - ?> - - - - - diff --git a/site/snippets/structured-data-product.php b/site/snippets/structured-data-product.php deleted file mode 100644 index 2390bc8..0000000 --- a/site/snippets/structured-data-product.php +++ /dev/null @@ -1,94 +0,0 @@ - - - diff --git a/site/templates/home.php b/site/templates/home.php index dcb47e5..cce6b62 100644 --- a/site/templates/home.php +++ b/site/templates/home.php @@ -1,24 +1,35 @@ $site->title(), 'template' => 'store']) ?> -
    -

    - baseline()->or('Bienvenue sur la boutique de soutien à Index') ?> -

    +
    +

    + baseline()->or('Bienvenue sur la boutique de soutien à Index') ?> +

    -
    +
    + children()->listed() as $product): ?> +
    +
    + files()->sort()->first()): ?> + $cover, + 'alt' => $product->title()->html(), + 'preset' => 'product-card', + 'size' => 25, + 'lazy' => true + ]) ?> + +
    +

    title()->html() ?>

    +

    price() ?>€

    + +
    + +
    -
    -

    -
    - -
    - -

    - - -

    -
    +

    + + +

    +
    diff --git a/site/templates/product.php b/site/templates/product.php index a750891..4fc4969 100644 --- a/site/templates/product.php +++ b/site/templates/product.php @@ -1,52 +1,115 @@ -shopifyHandle()->or($page->slug()); + $page->title(), 'template' => 'shop']) ?> -snippet('header', ['title' => $page->title(), 'template' => 'shop']); -?> +
    + -
    - - -
    - -
    -

    -
    - -
    - - -
    - - - ['product']]) ?> + ['assets/js/product-size.js', 'assets/js/snipcart.js', 'assets/js/product-gallery.js']]) ?>