Merge pull request #490 from ae-utbm/taiste

Eboutic
This commit is contained in:
thomas girod authored and GitHub committed 2022-11-16 17:04:13 +01:00
commit 1281104d96
26 files changed
+1708 -841

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
(()=>{var We=!1,Ge=!1,B=[];function $t(e){an(e)}function an(e){B.includes(e)||B.push(e),cn()}function he(e){let t=B.indexOf(e);t!==-1&&B.splice(t,1)}function cn(){!Ge&&!We&&(We=!0,queueMicrotask(ln))}function ln(){We=!1,Ge=!0;for(let e=0;e<B.length;e++)B[e]();B.length=0,Ge=!1}var A,K,Y,Ye,Je=!0;function Lt(e){Je=!1,e(),Je=!0}function jt(e){A=e.reactive,Y=e.release,K=t=>e.effect(t,{scheduler:r=>{Je?$t(r):r()}}),Ye=e.raw}function Ze(e){K=e}function Ft(e){let t=()=>{};return[n=>{let i=K(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),Y(i))},i},()=>{t()}]}var Bt=[],Kt=[],zt=[];function Vt(e){zt.push(e)}function _e(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Kt.push(t))}function Ht(e){Bt.push(e)}function qt(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function Qe(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var et=new MutationObserver(Xe),tt=!1;function rt(){et.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),tt=!0}function fn(){un(),et.disconnect(),tt=!1}var te=[],nt=!1;function un(){te=te.concat(et.takeRecords()),te.length&&!nt&&(nt=!0,queueMicrotask(()=>{dn(),nt=!1}))}function dn(){Xe(te),te.length=0}function m(e){if(!tt)return e();fn();let t=e();return rt(),t}var it=!1,ge=[];function Ut(){it=!0}function Wt(){it=!1,Xe(ge),ge=[]}function Xe(e){if(it){ge=ge.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;o<e.length;o++)if(!e[o].target._x_ignoreMutationObserver&&(e[o].type==="childList"&&(e[o].addedNodes.forEach(s=>s.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{Qe(s,o)}),n.forEach((o,s)=>{Bt.forEach(a=>a(s,o))});for(let o of r)if(!t.includes(o)&&(Kt.forEach(s=>s(o)),o._x_cleanups))for(;o._x_cleanups.length;)o._x_cleanups.pop()();t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.includes(o)||!o.isConnected||(delete o._x_ignoreSelf,delete o._x_ignore,zt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function xe(e){return D(k(e))}function C(e,t,r){return e._x_dataStack=[t,...k(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function ot(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function k(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?k(e.host):e.parentNode?k(e.parentNode):[]}function D(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function ye(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function be(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>pn(n,i),s=>st(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function pn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function st(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),st(e[t[0]],t.slice(1),r)}}var Gt={};function x(e,t){Gt[e]=t}function re(e,t){return Object.entries(Gt).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){let[i,o]=at(t);return i={interceptor:be,...i},_e(t,o),n(t,i)},enumerable:!1})}),e}function Yt(e,t,r,...n){try{return r(...n)}catch(i){J(i,e,t)}}function J(e,t,r=void 0){Object.assign(e,{el:t,expression:r}),console.warn(`Alpine Expression E Line truncated
${r?'Expression: "'+r+`"
`:""}`,t),setTimeout(()=>{throw e},0)}var ve=!0;function Jt(e){let t=ve;ve=!1,e(),ve=t}function P(e,t,r={}){let n;return g(e,t)(i=>n=i,r),n}function g(...e){return Zt(...e)}var Zt=ct;function Qt(e){Zt=e}function ct(e,t){let r={};re(r,e);let n=[r,...k(e)];if(typeof t=="function")return mn(n,t);let i=hn(n,t,e);return Yt.bind(null,e,t,i)}function mn(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(D([n,...e]),i);we(r,o)}}var lt={};function _n(e,t){if(lt[e])return lt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e,o=(()=>{try{return new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`)}catch(s){return J(s,t,e),Promise.resolve()}})();return lt[e]=o,o}function hn(e,t,r){let n=_n(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=D([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>J(l,r,t));n.finished?(we(i,n.result,a,s,r),n.result=void 0):c.then(l=>{we(i,l,a,s,r)}).catch(l=>J(l,r,t)).finally(()=>n.result=void 0)}}}function we(e,t,r,n,i){if(ve&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>we(e,s,r,n)).catch(s=>J(s,i,t)):e(o)}else e(t)}var ut="x-";function E(e=""){return ut+e}function Xt(e){ut=e}var er={};function d(e,t){er[e]=t}function ne(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=ft(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(tr((o,s)=>n[o]=s)).filter(rr).map(xn(n,r)).sort(yn).map(o=>gn(e,o))}function ft(e){return Array.from(e).map(tr()).filter(t=>!rr(t))}var dt=!1,ie=new Map,nr=Symbol();function ir(e){dt=!0;let t=Symbol();nr=t,ie.set(t,[]);let r=()=>{for(;ie.get(t).length;)ie.get(t).shift()();ie.delete(t)},n=()=>{dt=!1,r()};e(r),n()}function at(e){let t=[],r=a=>t.push(a),[n,i]=Ft(e);return t.push(i),[{Alpine:I,effect:n,cleanup:r,evaluateLater:g.bind(g,e),evaluate:P.bind(P,e)},()=>t.forEach(a=>a())]}function gn(e,t){let r=()=>{},n=er[t.type]||r,[i,o]=at(e);qt(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),dt?ie.get(nr).push(n):n())};return s.runCleanups=o,s}var Ee=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Se=e=>e;function tr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=or.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var or=[];function Z(e){or.push(e)}function rr({name:e}){return sr().test(e)}var sr=()=>new RegExp(`^${ut}([^:^.]+)\\b`);function xn(e,t){return({name:r,value:n})=>{let i=r.match(sr()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var pt="DEFAULT",Ae=["ignore","ref","data","id","bind","init","for","mask","model","modelable","transition","show","if",pt,"teleport"];function yn(e,t){let r=Ae.indexOf(e.type)===-1?pt:e.type,n=Ae.indexOf(t.type)===-1?pt:t.type;return Ae.indexOf(r)-Ae.indexOf(n)}function z(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}var mt=[],ht=!1;function Te(e=()=>{}){return queueMicrotask(()=>{ht||setTimeout(()=>{Oe()})}),new Promise(t=>{mt.push(()=>{e(),t()})})}function Oe(){for(ht=!1;mt.length;)mt.shift()()}function ar(){ht=!0}function R(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>R(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)R(n,t,!1),n=n.nextElementSibling}function O(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}function lr(){document.body||O("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),z(document,"alpine:init"),z(document,"alpine:initializing"),rt(),Vt(t=>w(t,R)),_e(t=>bn(t)),Ht((t,r)=>{ne(t,r).forEach(n=>n())});let e=t=>!V(t.parentElement,!0);Array.from(document.querySelectorAll(cr())).filter(e).forEach(t=>{w(t)}),z(document,"alpine:initialized")}var _t=[],ur=[];function fr(){return _t.map(e=>e())}function cr(){return _t.concat(ur).map(e=>e())}function Ce(e){_t.push(e)}function Re(e){ur.push(e)}function V(e,t=!1){return Q(e,r=>{if((t?cr():fr()).some(i=>r.matches(i)))return!0})}function Q(e,t){if(!!e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),!!e.parentElement)return Q(e.parentElement,t)}}function dr(e){return fr().some(t=>e.matches(t))}function w(e,t=R){ir(()=>{t(e,(r,n)=>{ne(r,r.attributes).forEach(i=>i()),r._x_ignore&&n()})})}function bn(e){R(e,t=>Qe(t))}function oe(e,t){return Array.isArray(t)?pr(e,t.join(" ")):typeof t=="object"&&t!==null?vn(e,t):typeof t=="function"?oe(e,t()):pr(e,t)}function pr(e,t){let r=o=>o.split(" ").filter(Boolean),n=o=>o.Line truncated
+66 -44
View File
@@ -135,6 +135,10 @@ a {
width: 23%;
}
.clickable:hover {
cursor: pointer;
}
/*--------------------------------HEADER-------------------------------*/
#header_language_chooser {
@@ -159,9 +163,9 @@ a {
header {
width: 90%;
margin: 0px auto;
margin: 0 auto;
display: flex;
box-shadow: $shadow-color 0px 0px 15px;
box-shadow: $shadow-color 0 0 15px;
border-top: none;
background-color: $primary-neutral-dark-color;
border-radius: 0px 0px 10px 10px;
@@ -199,7 +203,7 @@ header {
}
#header_connect_links {
margin: 0.6em 0.6em 0em auto;
margin: 0.6em 0.6em 0 auto;
padding: 0.2em;
color: $white-color;
form {
@@ -226,7 +230,7 @@ header {
a {
text-decoration: none;
margin: 0em 1em;
margin: 0 1em;
font-weight: bold;
color: $white-color;
&:hover {
@@ -254,7 +258,7 @@ header {
#header_search {
display: inline-block;
flex: auto;
margin: 0.8em 0em;
margin: 0.8em 0;
input {
width: 14ch;
}
@@ -265,10 +269,10 @@ header {
flex: initial;
flex-wrap: wrap;
text-align: right;
margin: 0em;
margin: 0;
div {
display: inline;
padding: 1.2em 0em;
padding: 1.2em 0;
&:first-child {
flex: auto;
}
@@ -290,7 +294,7 @@ header {
background: white;
text-align: left;
font-size: 80%;
margin: 1.5em 0em 0em -14em;
margin: 1.5em 0 0em -14em;
.header_notif_date {
font-weight: bold;
}
@@ -298,7 +302,7 @@ header {
color: grey;
}
a {
margin: 0em;
margin: 0;
color: $black-color;
&:hover {
color: $primary-dark-color;
@@ -326,7 +330,7 @@ header {
#popupheader {
width: 88%;
margin: 0px auto;
margin: 0 auto;
padding: 0.3em 1%;
}
@@ -369,15 +373,15 @@ header {
#page {
width: 90%;
margin: 0em auto;
/*---------------------------------NAV---------------------------------*/
margin: 20px auto 0;
/*---------------------------------NAV---------------------------------*/
nav {
display: flex;
flex-wrap: wrap;
background-color: $primary-dark-color;
color: $white-color;
border-radius: 6px 6px 0px 0px;
box-shadow: $shadow-color 0px 0px 15px;
border-radius: 6px 6px 0 0;
box-shadow: $shadow-color 0 0 15px;
a {
flex: auto;
@@ -392,10 +396,10 @@ header {
background: $secondary-neutral-color;
color: $white-color;
&:first-of-type {
border-radius: 6px 0px 0px 0px;
border-radius: 6px 0 0 0;
}
&:last-of-type {
border-radius: 0px 6px 0px 0px;
border-radius: 0 6px 0 0;
}
}
}
@@ -418,7 +422,7 @@ header {
overflow: auto;
width: 100%;
background-color: #f9f9f9;
box-shadow: 3px 3px 3px 0px $shadow-color;
box-shadow: 3px 3px 3px 0 $shadow-color;
z-index: 1;
}
@@ -443,7 +447,7 @@ header {
/*--------------------------------CONTENT------------------------------*/
#quick_notif {
width: 100%;
margin: 0px auto;
margin: 0 auto;
list-style-type: none;
background: $second-color;
li {
@@ -454,11 +458,29 @@ header {
#content {
padding: 1em 1%;
box-shadow: $shadow-color 0px 5px 10px;
box-shadow: $shadow-color 0 5px 10px;
background: $white-color;
overflow: auto;
}
.alert {
margin: 10px;
border: #fc8181 1px solid;
background-color: rgb(255,245,245);
border-radius: 4px;
color: #c53030;
padding: 12px 16px;
display: flex;
gap: 16px;
max-width: 100%;
align-items: center;
text-align: justify;
.alert-main {
flex: 2;
}
}
.tool_bar {
overflow: auto;
padding: 4px;
@@ -499,7 +521,7 @@ header {
flex-wrap: wrap;
.news_column {
display: inline-block;
margin: 0px;
margin: 0;
vertical-align: top;
}
#news_admin {
@@ -540,7 +562,7 @@ header {
margin-bottom: 1em;
#agenda_title,#birthdays_title {
margin: 0em;
border-radius: 5px 5px 0px 0px;
border-radius: 5px 5px 0 0;
box-shadow: $shadow-color 1px 1px 1px;
padding: 0.5em;
font-weight: bold;
@@ -609,10 +631,10 @@ header {
font-weight: bold;
font-family: monospace;
font-size: 1.4em;
border-radius: 7px 0px 0px 7px;
border-radius: 7px 0 0 7px;
div {
margin: 0px auto;
margin: 0 auto;
.day {
font-size: 1.5em;
}
@@ -697,7 +719,7 @@ header {
padding: 0.4em;
padding-left: 1em;
background: $secondary-neutral-light-color;
box-shadow: $shadow-color 0px 0px 2px;
box-shadow: $shadow-color 0 0 2px;
border-radius: 18px 5px 18px 5px;
h4 {
margin: 0em;
@@ -1030,7 +1052,7 @@ h1, h2, h3, h4, h5, h6 {
h1 {
font-size: 160%;
margin-left: 0px;
margin-left: 0;
}
h2 {
@@ -1060,7 +1082,7 @@ h6 {
p, pre {
margin-top: 0.8em;
margin-left: 0px;
margin-left: 0;
}
ul, ol, dl {
@@ -1118,7 +1140,7 @@ td {
overflow: hidden;
text-overflow: ellipsis;
> ul {
margin-top: 0px;
margin-top: 0;
}
}
@@ -1471,7 +1493,7 @@ textarea {
}
.search_bar {
margin: 10px 0px;
margin: 10px 0;
display: flex;
flex-wrap: wrap;
height: 20p;
@@ -1487,7 +1509,7 @@ textarea {
margin-top: 5px;
background: $secondary-color;
color: white;
border-radius: 10px 10px 0px 0px;
border-radius: 10px 10px 0 0;
.title {
text-transform: uppercase;
}
@@ -1527,7 +1549,7 @@ textarea {
text-align: center;
img {
max-width: 70%;
margin: 0px auto;
margin: 0 auto;
}
}
@@ -1615,7 +1637,7 @@ footer {
display: flex;
flex-wrap: wrap;
background-color: $primary-neutral-dark-color;
box-shadow: $shadow-color 0px 0px 15px;
box-shadow: $shadow-color 0 0 15px;
a {
padding: 0.8em;
flex: 1;
@@ -1631,7 +1653,7 @@ footer {
/*---------------------------------FORMS-------------------------------*/
form {
margin: 0px auto;
margin: 0 auto;
margin-bottom: 10px;
}
@@ -1645,7 +1667,7 @@ label {
}
.ui-dialog .ui-dialog-buttonpane {
bottom: 0px;
bottom: 0;
position: absolute;
width: 97%;
}
@@ -1690,8 +1712,8 @@ label {
/*-------------------------------MARKDOWN------------------------------*/
.markdown {
margin: 0px;
padding: 0px;
margin: 0;
padding: 0;
code {
font-family: monospace;
color: $white-color;
@@ -1722,7 +1744,7 @@ label {
}
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-top,
.ui-corner-left {
border-radius: 0px;
border-radius: 0;
}
#club_detail {
@@ -1748,13 +1770,13 @@ $pedagogy-white-text: #f0f0f0;
.pedagogy {
&.star-not-checked {
color : #f7f7f7;
margin-bottom: 0px;
margin-top: 0px;
margin-bottom: 0;
margin-top: 0;
}
&.star-checked {
color: $pedagogy-orange;
margin-bottom: 0px;
margin-top: 0px;
margin-bottom: 0;
margin-top: 0;
}
&.grade-without-star {
@@ -2126,8 +2148,8 @@ $pedagogy-white-text: #f0f0f0;
grid-area: markdown;
min-height: 139px;
margin-top: 0px;
margin-right: 0px;
margin-top: 0;
margin-right: 0;
padding: 10px;
text-align: justify;
overflow: auto;
@@ -2173,7 +2195,7 @@ $pedagogy-white-text: #f0f0f0;
"report"
"date"
"author";
margin-top: 0px;
margin-top: 0;
text-align: center;
}
@@ -2188,7 +2210,7 @@ $pedagogy-white-text: #f0f0f0;
@media screen and (max-width: $large-devices){
clip-path: none;
padding: 0px;
padding: 0;
padding-bottom: 7px;
}
+191
View File
@@ -0,0 +1,191 @@
#eboutic {
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
column-gap: 20px;
margin: 0 20px 20px;
}
#eboutic-title {
margin-left: 20px;
}
#eboutic h3 {
margin-left: 0;
margin-right: 0;
}
#basket {
min-width: 300px;
border-radius: 8px;
box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 4px 8px 3px;
padding: 10px;
}
#basket h3 {
margin-top: 0;
}
@media screen and (max-width: 765px) {
#eboutic {
flex-direction: column;
align-items: center;
margin: 10px;
row-gap: 20px;
}
#eboutic-title {
margin-bottom: 20px;
margin-top: 4px;
}
#basket {
}
}
#eboutic #basket .error-message {
margin-top: 5px;
background-color: #f8d7da;
border: #f5c6cb 1px solid;
border-radius: 4px;
padding: 10px;
display: flex;
flex-direction: column;
row-gap: 7px;
}
#eboutic #basket .error-message p {
margin: 0;
}
#eboutic .item-list {
margin-left: 0;
list-style: none;
}
#eboutic .item-list li {
display: flex;
align-items: center;
margin-bottom: 10px
}
#eboutic .item-name {
flex: 1;
}
#eboutic .item-price, #eboutic .item-quantity {
width: 65px;
}
#eboutic .item-quantity {
text-align: center;
}
#eboutic .fa-plus, #eboutic .fa-minus {
cursor: pointer;
}
#eboutic .item-price {
text-align: right;
}
/* CSS du catalogue */
#eboutic #catalog {
display: flex;
flex-grow: 1;
flex-direction: column;
row-gap: 30px;
}
#eboutic .category-header {
margin-bottom: 15px;
}
#eboutic .product-group {
display: flex;
flex-wrap: wrap;
column-gap: 15px;
row-gap: 15px;
}
@media screen and (max-width: 765px) {
#eboutic #catalog {
row-gap: 15px;
}
#eboutic section {
text-align: center;
}
#eboutic .product-group {
justify-content: space-around;
}
}
#eboutic .product-button {
position: relative;
box-sizing: border-box;
min-width: 120px;
max-width: 150px;
padding: 10px;
overflow: hidden;
box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 4px 8px 3px;
display: flex;
flex-direction: column;
align-items: center;
row-gap: 5px;
}
#eboutic .product-button:active {
box-shadow: none;
}
#eboutic .product-button img, #eboutic .product-button .fa {
margin: 0;
border-radius: 4px;
height: 40px;
line-height: 40px;
}
#eboutic .product-button p {
font-size: 13px;
margin: 0;
}
#eboutic .catalog-buttons {
display: flex;
justify-content: center;
column-gap: 30px;
margin: 30px 0 0;
}
#eboutic input {
all: unset;
}
#eboutic .catalog-buttons button {
font-size: 15px;
font-weight: normal;
color: white;
min-width: 60px;
padding: 5px 10px;
}
#eboutic .catalog-buttons .validate {
background-color: #354a5f;
}
#eboutic .catalog-buttons .clear {
background-color: gray;
}
#eboutic .catalog-buttons button i {
margin-right: 4px;
}
#eboutic .catalog-buttons button.validate:hover {
background-color: #2c3646;
}
#eboutic .catalog-buttons button.clear:hover {
background-color:hsl(210,5%,30%);
}
#eboutic .catalog-buttons form {
margin: 0;
}
+104
View File
@@ -0,0 +1,104 @@
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function get_starting_items() {
const cookie = getCookie("basket_items")
try {
// django cookie backend does an utter mess on non-trivial data types
// so we must perform a conversion of our own
const biscuit = JSON.parse(JSON.parse(cookie.replace(/\\054/g, ',')));
if (Array.isArray(biscuit)) {
return biscuit;
}
return [];
} catch (e) {
return [];
}
}
document.addEventListener('alpine:init', () => {
Alpine.data('basket', () => ({
items: get_starting_items(),
get_total() {
let total = 0;
for (const item of this.items) {
total += item["quantity"] * item["unit_price"];
}
return total;
},
add(item) {
item.quantity++;
this.edit_cookies()
},
remove(item_id) {
const index = this.items.findIndex(e => e.id === item_id);
if (index < 0) return;
this.items[index].quantity -= 1;
if (this.items[index].quantity === 0) {
this.items = this.items.filter((e) => e.id !== this.items[index].id);
}
this.edit_cookies();
},
clear_basket() {
this.items = []
this.edit_cookies();
},
edit_cookies() {
// a cookie survives an hour
document.cookie = "basket_items=" + JSON.stringify(this.items) + ";Max-Age=3600";
},
/**
* Create an item in the basket if it was not already in
* @param id : int the id of the product to add
* @param name : String the name of the product
* @param price : number the unit price of the product
*/
create_item(id, name, price) {
let new_item = {
id: id,
name: name,
quantity: 0,
unit_price: price
};
this.items.push(new_item);
this.add(new_item);
},
/**
* add an item to the basket.
* This is called when the user click
* on a button in the catalog (left side of the page)
* @param id : int the id of the product to add
* @param name : String the name of the product
* @param price : number the unit price of the product
*/
add_from_catalog(id, name, price) {
const item = this.items.find(e => e.id === id)
if (item === undefined) {
this.create_item(id, name, price);
} else {
// the user clicked on an item which is already in the basket
this.add(item);
}
},
}))
})