1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00

(quality) Improve responsive

This commit is contained in:
vincent 2022-09-20 15:21:44 +02:00
parent 2e1784b291
commit 75d327f410
18 changed files with 392 additions and 135 deletions

View File

@ -144,6 +144,9 @@ const StoreCart: React.FC<StoreCartProps> = ({ onSuccess, onError, currentUser,
<div className="ref">
<span>{t('app.public.store_cart.reference_short')} {item.orderable_ref || ''}</span>
<p>{item.orderable_name}</p>
{item.quantity_min > 1 &&
<span className='min'>{t('app.public.store_cart.minimum_purchase')}{item.quantity_min}</span>
}
</div>
<div className="actions">
<div className='price'>

View File

@ -6,7 +6,7 @@ import { FabButton } from '../base/fab-button';
import { User } from '../../models/user';
import { FabStateLabel } from '../base/fab-state-label';
import OrderLib from '../../lib/order';
import { ArrowClockwise } from 'phosphor-react';
import { PlusCircle } from 'phosphor-react';
interface OrderItemProps {
order?: Order,
@ -37,11 +37,9 @@ export const OrderItem: React.FC<OrderItemProps> = ({ order, currentUser }) => {
return (
<div className='order-item'>
<p className="ref">{order.reference}</p>
<div>
<FabStateLabel status={OrderLib.statusColor(order)} background>
{t(`app.shared.store.order_item.state.${OrderLib.statusText(order)}`)}
</FabStateLabel>
</div>
{isPrivileged() &&
<div className='client'>
<span>{t('app.shared.store.order_item.client')}</span>
@ -52,7 +50,7 @@ export const OrderItem: React.FC<OrderItemProps> = ({ order, currentUser }) => {
<span>{t('app.shared.store.order_item.created_at')}</span>
<p>{FormatLib.date(order.created_at)}
<div className="fab-tooltip">
<span className="trigger"><ArrowClockwise size={16} weight="light" /></span>
<span className="trigger"><PlusCircle size={16} weight="light" /></span>
<div className="content">
{t('app.shared.store.order_item.last_update')}<br />
{FormatLib.date(order.updated_at)}

View File

@ -15,7 +15,7 @@ import { FormInput } from '../form/form-input';
import OrderAPI from '../../api/order';
import { Order, OrderIndexFilter } from '../../models/order';
import { FabPagination } from '../base/fab-pagination';
import { X } from 'phosphor-react';
import { CaretDoubleUp, X } from 'phosphor-react';
declare const Application: IApplication;
@ -54,6 +54,7 @@ const Orders: React.FC<OrdersProps> = ({ currentUser, onError }) => {
const [orders, setOrders] = useState<Array<Order>>([]);
const [filters, setFilters] = useImmer<OrderIndexFilter>(window[FablabOrdersFilters] || initFilters);
const [accordion, setAccordion] = useState({});
const [filtersPanel, setFiltersPanel] = useState<boolean>(true);
const [pageCount, setPageCount] = useState<number>(0);
const [totalCount, setTotalCount] = useState<number>(0);
const [reference, setReference] = useState<string>(filters.reference);
@ -256,14 +257,15 @@ const Orders: React.FC<OrdersProps> = ({ currentUser, onError }) => {
}
</header>
<div className="store-filters">
<aside className={`store-filters ${filtersPanel ? '' : 'collapsed'}`}>
<header>
<h3>{t('app.admin.store.orders.filter')}</h3>
<div className='grpBtn'>
<FabButton onClick={clearAllFilters} className="is-black">{t('app.admin.store.orders.filter_clear')}</FabButton>
<CaretDoubleUp className='filters-toggle' size={16} weight="bold" onClick={() => setFiltersPanel(!filtersPanel)} />
</div>
</header>
<div className="accordion">
<div className="grp accordion">
<AccordionItem id={0}
isOpen={accordion[0]}
onChange={handleAccordion}
@ -331,7 +333,7 @@ const Orders: React.FC<OrdersProps> = ({ currentUser, onError }) => {
</div>
</AccordionItem>
</div>
</div>
</aside>
<div className="store-list">
<StoreListHeader

View File

@ -13,7 +13,7 @@ import ProductAPI from '../../api/product';
import ProductCategoryAPI from '../../api/product-category';
import MachineAPI from '../../api/machine';
import { AccordionItem } from './accordion-item';
import { X } from 'phosphor-react';
import { CaretDoubleUp, X } from 'phosphor-react';
import { StoreListHeader } from './store-list-header';
import { FabPagination } from '../base/fab-pagination';
import ProductLib from '../../lib/product';
@ -47,6 +47,7 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
const [machines, setMachines] = useState<checklistOption[]>([]);
const [update, setUpdate] = useState(false);
const [accordion, setAccordion] = useState({});
const [filtersPanel, setFiltersPanel] = useState<boolean>(true);
const [pageCount, setPageCount] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
@ -242,14 +243,15 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
<FabButton className="main-action-btn" onClick={newProduct}>{t('app.admin.store.products.create_a_product')}</FabButton>
</div>
</header>
<div className='store-filters'>
<aside className={`store-filters ${filtersPanel ? '' : 'collapsed'}`}>
<header>
<h3>{t('app.admin.store.products.filter')}</h3>
<div className='grpBtn'>
<FabButton onClick={clearAllFilters} className="is-black">{t('app.admin.store.products.filter_clear')}</FabButton>
<CaretDoubleUp className='filters-toggle' size={16} weight="bold" onClick={() => setFiltersPanel(!filtersPanel)} />
</div>
</header>
<div className='accordion'>
<div className='grp accordion'>
<AccordionItem id={0}
isOpen={accordion[0]}
onChange={handleAccordion}
@ -328,7 +330,7 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
</div>
</AccordionItem>
</div>
</div>
</aside>
<div className='store-list'>
<StoreListHeader
productsCount={filteredProductsList.length}

View File

@ -81,6 +81,9 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
<img src={productImageUrl(product)} alt='' />
</div>
<p className="name">{product.name}</p>
{product.quantity_min > 1 &&
<span className='min'>{t('app.public.store_product_item.minimum_purchase')}{product.quantity_min}</span>
}
{product.amount &&
<div className='price'>
<p>{FormatLib.price(product.amount)}</p>

View File

@ -181,6 +181,9 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
</div>
{product.stock.external > 0 &&
<div className='to-cart'>
{product.quantity_min > 1 &&
<span className='min'>{t('app.public.store_product_item.minimum_purchase')}{product.quantity_min}</span>
}
<FabButton onClick={() => setCount('remove')} icon={<Minus size={16} />} className="minus" />
<input type="number"
value={toCartCount}

View File

@ -16,6 +16,7 @@ import { Order } from '../../models/order';
import { AccordionItem } from './accordion-item';
import { StoreListHeader } from './store-list-header';
import { FabPagination } from '../base/fab-pagination';
import { CaretDoubleDown } from 'phosphor-react';
declare const Application: IApplication;
@ -45,6 +46,7 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
const [filterVisible, setFilterVisible] = useState<boolean>(false);
const [machines, setMachines] = useState<checklistOption[]>([]);
const [accordion, setAccordion] = useState({});
const [filtersPanel, setFiltersPanel] = useState<boolean>(false);
const [pageCount, setPageCount] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
@ -183,12 +185,20 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
</li>
}
</ul>
<aside className='store-filters'>
<aside className={`store-filters ${filtersPanel ? '' : 'collapsed'}`}>
<header>
<h3>{t('app.public.store.products.filter')}</h3>
<div className='grpBtn'>
<FabButton onClick={clearAllFilters} className="is-black">{t('app.public.store.products.filter_clear')}</FabButton>
<CaretDoubleDown className='filters-toggle' size={16} weight="bold" onClick={() => setFiltersPanel(!filtersPanel)} />
</div>
</header>
<div className='grp'>
<div className="categories">
<header>
<h3>{t('app.public.store.products.filter_categories')}</h3>
</header>
<div className="group u-scrollbar">
<div className="list u-scrollbar">
{categoriesTree.map(c =>
<div key={c.parent.id} className={`parent ${activeCategory?.id === c.parent.id || activeCategory?.parent === c.parent.id ? 'is-active' : ''}`}>
<p onClick={() => filterCategory(c.parent.id)}>
@ -210,12 +220,6 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
</div>
</div>
<div className='filters'>
<header>
<h3>{t('app.public.store.products.filter')}</h3>
<div className='grpBtn'>
<FabButton onClick={clearAllFilters} className="is-black">{t('app.public.store.products.filter_clear')}</FabButton>
</div>
</header>
<div className="accordion">
<AccordionItem id={1}
isOpen={accordion[1]}
@ -236,6 +240,7 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser }) => {
</AccordionItem>
</div>
</div>
</div>
</aside>
<div className='store-list'>
<StoreListHeader

View File

@ -2,35 +2,33 @@
width: 100%;
max-width: 1600px;
margin: 0 auto;
padding-bottom: 6rem;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-template-rows: minmax(0, min-content);
gap: 3.2rem;
align-items: flex-start;
&-list {
grid-area: 1 / 1 / 2 / 10;
display: grid;
gap: 1.6rem;
&-item {
padding: 0.8rem;
display: grid;
grid-auto-flow: column;
grid-template-columns: min-content 1fr;
gap: 1.6rem;
justify-content: space-between;
grid-template-columns: min-content 1fr;
align-items: center;
background-color: var(--gray-soft-lightest);
border: 1px solid var(--gray-soft-dark);
border-radius: var(--border-radius);
.picture {
grid-area: 1 / 1 / 2 / 2;
width: 10rem !important;
@include imageRatio(76%);
border-radius: var(--border-radius);
}
.ref {
grid-area: 1 / 2 / 2 / 3;
display: flex;
flex-direction: column;
span {
@ -43,8 +41,14 @@
margin: 0;
@include text-base(600);
}
.min {
margin-top: 0.8rem;
color: var(--alert);
text-transform: none;
}
}
.actions {
grid-area: 2 / 1 / 3 / 3;
align-self: stretch;
padding: 0.8rem;
display: grid;
@ -56,7 +60,8 @@
border-radius: var(--border-radius);
}
.offer {
align-self: stretch;
grid-area: 3 / 1 / 4 / 3;
justify-self: flex-end;
display: flex;
justify-content: space-between;
align-items: center;
@ -101,7 +106,6 @@
}
}
.group {
grid-area: 2 / 1 / 3 / 10;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2.4rem;
@ -128,7 +132,6 @@
}
aside {
grid-area: 1 / 10 / 3 / 13;
& > div {
margin-bottom: 3.2rem;
padding: 1.6rem;
@ -183,4 +186,36 @@
}
}
}
@media (min-width: 1024px) {
&-list-item {
.ref { grid-area: 1 / 2 / 2 / 4; }
.actions { grid-area: 2 / 1 / 3 / 3; }
.offer { grid-area: 2 / 3 / 3 / 4; }
}
}
@media (min-width: 1440px) {
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-template-rows: minmax(0, min-content);
&-list {
grid-area: 1 / 1 / 2 / 10;
&-item {
grid-auto-flow: column;
grid-template-columns: min-content 1fr;
justify-content: space-between;
align-items: center;
.picture { grid-area: auto; }
.ref { grid-area: auto; }
.actions { grid-area: auto; }
.offer {
grid-area: auto;
align-self: flex-start;
}
}
}
.group { grid-area: 2 / 1 / 3 / 10; }
aside { grid-area: 1 / 10 / 3 / 13; }
}
}

View File

@ -1,33 +1,33 @@
.order-item {
width: 100%;
display: flex;
gap: 2.4rem;
justify-items: flex-start;
display: grid;
grid-template-rows: repeat(2, min-content);
grid-template-columns: 2fr 1fr 10ch;
gap: 1.6rem 2.4rem;
align-items: center;
padding: 1.6rem;
border: 1px solid var(--gray-soft-dark);
border-radius: var(--border-radius);
background-color: var(--gray-soft-lightest);
& > *:not(button) { flex: 0 1 40%; }
p { margin: 0; }
.ref {
flex: 1 1 100%;
grid-area: 1 / 1 / 2 / 2;
@include text-base(600);
}
.fab-state-label {
--status-color: var(--success);
&.cart { --status-color: var(--secondary-dark); }
&.paid { --status-color: var(--success-light); }
&.cart { --status-color: var(--information); }
&.paid { --status-color: var(--success); }
&.ready { --status-color: var(--success); }
&.error { --status-color: var(--alert); }
&.canceled { --status-color: var(--alert-light); }
&.pending { --status-color: var(--information); }
&.normal { --status-color: var(--success); }
margin: 0 auto;
grid-area: 1 / 2 / 2 / 3;
}
.status .state-label { margin: 0 auto; }
.client {
grid-area: 2 / 1 / 3 / 2;
display: flex;
flex-direction: column;
span {
@ -37,6 +37,7 @@
p { @include text-sm; }
}
.date {
grid-area: 2 / 2 / 3 / 3;
& > span {
@include text-xs;
color: var(--gray-hard-light);
@ -51,7 +52,7 @@
}
}
.price {
flex: 0 1 30%;
grid-area: 1 / 3 / 3 / 4;
display: flex;
flex-direction: column;
justify-self: flex-end;
@ -61,4 +62,20 @@
}
p { @include text-base(600); }
}
button { grid-area: 1 / 4 / 3 / 5; }
@media (min-width: 1440px) {
grid-auto-flow: column;
grid-template-rows: auto;
grid-template-columns: 1fr minmax(max-content, 1fr) 2fr 12ch 12ch;
gap: 2.4rem;
.ref,
.fab-state-label,
.client,
.date,
.price,
button { grid-area: auto; }
.fab-state-label { justify-self: center; }
}
}

View File

@ -3,9 +3,6 @@
max-width: 1600px;
margin: 0 auto;
padding-bottom: 6rem;
@include grid-col(12);
gap: 3.2rem;
align-items: flex-start;
header {
@include header();
@ -14,13 +11,47 @@
}
&-list {
padding-bottom: 6rem;
& > *:not(:first-child) {
margin-top: 1.6rem;
}
}
}
.orders {
display: grid;
grid-template-rows: min-content 8rem 1fr;
align-items: flex-start;
& > header { margin-bottom: 2.4rem; }
.store-filters {
grid-area: 2 / 1 / 4 / 2;
background-color: var(--gray-soft-lightest);
z-index: 1;
}
.store-list { grid-area: 3 / 1 / 4 / 2; }
@media (min-width: 1200px) {
@include grid-col(12);
gap: 2.4rem 3.2rem;
align-items: flex-start;
& > header { margin-bottom: 0; }
.store-filters {
position: static;
grid-area: 2 / 1 / 3 / 4;
}
.store-list { grid-area: 2 / 4 / 3 / -1; }
}
}
.show-order {
@include grid-col(12);
gap: 3.2rem;
align-items: flex-start;
&-nav {
max-width: 1600px;
margin: 0 auto;

View File

@ -1,6 +1,6 @@
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
gap: 3.2rem;
.store-product-item {
@ -16,10 +16,11 @@
display: grid;
grid-template-areas: "image image"
"name name"
"min min"
"price btn"
"stock btn";
grid-template-columns: auto min-content;
grid-template-rows: min-content auto min-content min-content;
grid-template-rows: repeat(2, min-content) auto repeat(2, min-content);
border: 1px solid var(--gray-soft-dark);
border-radius: var(--border-radius);
cursor: pointer;
@ -30,11 +31,16 @@
border-radius: var(--border-radius);
}
.name {
margin: 2.4rem 0 1.6rem;
margin: 1.6rem 0 0.8rem;
grid-area: name;
align-self: flex-start;
@include text-base(600);
}
.min {
grid-area: min;
@include text-sm;
color: var(--alert);
}
.price {
grid-area: price;
display: flex;

View File

@ -11,8 +11,10 @@
}
width: 100%;
display: flex;
display: grid;
justify-content: space-between;
grid-template-columns: 1fr min-content;
gap: 1.6rem;
align-items: center;
padding: 1.6rem 0.8rem;
border: 1px solid var(--gray-soft-dark);
@ -21,8 +23,7 @@
&.out-of-stock { border-color: var(--status-color); }
.itemInfo {
min-width: 20ch;
flex: 1;
grid-area: 1 / 1 / 2 / 2;
display: flex;
align-items: center;
@ -42,13 +43,12 @@
}
}
.details {
grid-area: 2 / 1 / 3 / 3;
display: grid;
grid-template-columns: 120px repeat(2, minmax(min-content, 120px)) 120px;
grid-template-columns: repeat(4, minmax(min-content, 12ch));
justify-items: center;
align-items: center;
gap: 1.6rem;
margin-left: auto;
margin-right: 4rem;
p {
margin: 0;
@include text-base(600);
@ -68,8 +68,8 @@
justify-self: flex-end;
}
}
.actions {
grid-area: 1 / 2 / 2 / 3;
display: flex;
justify-content: flex-end;
align-items: center;
@ -87,5 +87,12 @@
.delete-btn {background: var(--main) }
}
}
@media (min-width: 1024px) {
grid-template-columns: 1fr auto min-content;
.itemInfo,
.details,
.actions { grid-area: auto; }
}
}
}

View File

@ -4,9 +4,6 @@
max-width: 1600px;
margin: 0 auto;
padding-bottom: 6rem;
@include grid-col(12);
gap: 3.2rem;
align-items: flex-start;
header {
@include header();
@ -15,8 +12,41 @@
}
}
.products {
display: grid;
grid-template-rows: min-content 8rem 1fr;
align-items: flex-start;
& > header { margin-bottom: 2.4rem; }
.store-filters {
grid-area: 2 / 1 / 4 / 2;
background-color: var(--gray-soft-lightest);
z-index: 1;
}
.store-list { grid-area: 3 / 1 / 4 / 2; }
@media (min-width: 1200px) {
@include grid-col(12);
grid-template-rows: min-content 1fr;
gap: 2.4rem 3.2rem;
align-items: flex-start;
& > header { margin-bottom: 0; }
.store-filters {
position: static;
grid-area: 2 / 1 / 3 / 4;
}
.store-list { grid-area: 2 / 4 / 3 / -1; }
}
}
.new-product,
.edit-product {
@include grid-col(12);
gap: 3.2rem;
align-items: flex-start;
&-nav {
max-width: 1600px;

View File

@ -1,8 +1,41 @@
.store-filters {
grid-column: 1 / 4;
margin: 0 -30px;
padding: 0 30px;
box-shadow: 0 10px 10px 0 rgb(39 32 32 / 12%);
.grp {
max-height: 0;
overflow: hidden;
transition: all 500ms ease-in-out;
}
&.collapsed {
header .grpBtn svg { transform: rotateZ(-180deg); }
header .grpBtn button { display: flex; }
.grp {
max-height: 100vh;
padding-bottom: 2.4rem;
}
}
header {
@include header();
margin: 0;
padding: 0 0 2.4rem 0;
.grpBtn {
display: flex;
align-items: center;
button { display: none; }
svg {
cursor: pointer;
transition: transform 250ms ease-in-out;
}
}
}
.categories {
margin-bottom: 3.2rem;
margin-bottom: 1.6rem;
h3 { @include text-base(600); }
.list {
max-height: 30vh;
overflow: auto;
@ -36,7 +69,6 @@
transition: max-height 500ms ease-in-out;
}
}
.children {
max-height: 0;
overflow: hidden;
@ -56,11 +88,6 @@
border-top: 1px solid var(--gray-soft-dark);
}
header {
@include header();
padding: 0 0 2.4rem 0;
}
.accordion {
&-item:not(:last-of-type) {
margin-bottom: 1.6rem;
@ -158,4 +185,13 @@
flex-direction: column;
}
}
@media (min-width: 1200px) {
margin: 0;
padding: 0 0 2.4rem;
box-shadow: none;
.filters-toggle { display: none; }
.grp { max-height: 100vh; }
header .grpBtn button { display: flex; }
}
}

View File

@ -1,12 +1,14 @@
.store-list-header {
padding: 0.8rem 2.4rem;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: var(--gray-soft);
border-radius: var(--border-radius);
p { margin: 0; }
.count {
margin-right: 2.4rem;
display: flex;
align-items: center;
p {
@ -19,8 +21,14 @@
}
.display {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
@media (min-width: 1024px) {
width: auto;
& > *:not(:first-child) {
&::before {
content: "";
@ -30,6 +38,7 @@
background-color: var(--gray-hard-darkest);
}
}
}
.sort {
display: flex;

View File

@ -1,5 +1,4 @@
.store-list {
grid-column: 4 / -1;
display: grid;
grid-template-columns: 1fr;
gap: 2.4rem 0;

View File

@ -1,18 +1,14 @@
.store,
.store-product {
.store {
max-width: 1600px;
@include grid-col(12);
gap: 2.4rem 3.2rem;
align-items: flex-start;
margin: 0 auto;
padding-bottom: 6rem;
}
display: grid;
grid-template-rows: min-content 8rem 1fr;
align-items: flex-start;
.store {
.breadcrumbs {
grid-column: 1 / -1;
display: none;
padding: 0.8rem 1.6rem;
display: flex;
list-style: none;
border-radius: var(--border-radius-sm);
background-color: var(--gray-soft-light);
@ -31,6 +27,31 @@
color: var(--gray-hard-light);
cursor: pointer;
}
}
&-filters {
grid-area: 2 / 1 / 4 / 2;
background-color: var(--gray-soft-lightest);
z-index: 1;
}
&-list { grid-area: 3 / 1 / 4 / 2; }
@media (min-width: 768px) {
.breadcrumbs { display: flex; }
}
@media (min-width: 1200px) {
@include grid-col(12);
grid-template-rows: min-content 1fr;
gap: 2.4rem 3.2rem;
align-items: flex-start;
.breadcrumbs { grid-column: 1 / -1; }
&-filters {
position: static;
grid-area: 2 / 1 / 3 / 4;
}
&-list { grid-area: 2 / 4 / 3 / -1; }
}
}
@ -39,24 +60,31 @@
&.low { --status-color: var(--alert-light); }
&.out-of-stock { --status-color: var(--alert); }
padding-top: 4rem;
gap: 0 3.2rem;
max-width: 1600px;
margin: 0 auto;
padding: 4rem 0 6rem;
display: grid;
grid-template-columns: 1fr;
justify-items: flex-start;
align-items: flex-start;
gap: 0 3.2rem;
.ref {
grid-area: 1 / 1 / 2 / 9;
grid-row: 1 / 2;
@include text-sm;
color: var(--gray-hard-lightest);
text-transform: uppercase;
}
.name {
grid-area: 2 / 1 / 3 / 9;
grid-row: 2 / 3;
margin: 0.8rem 0 3.2rem;
@include title-lg;
color: var(--gray-hard-darkest) !important;
}
.gallery {
grid-area: 3 / 1 / 4 / 4;
grid-row: 3 / 4;
width: 100%;
max-width: 50rem;
.picture{
@include imageRatio;
border-radius: var(--border-radius-sm);
@ -78,7 +106,7 @@
}
}
.description {
grid-area: 3 / 4 / 4 / 9;
grid-row: 5 / 6;
&-text {
padding-bottom: 4rem;
overflow: hidden;
@ -121,6 +149,7 @@
&-document {
padding: 2.4rem;
background-color: var(--gray-soft-light);
border-radius: var(--border-radius-sm);
p { @include text-sm(500); }
.list {
display: flex;
@ -135,8 +164,8 @@
}
}
aside {
grid-area: 1 / -4 / 4 / -1;
position: sticky;
margin: 2.4rem 0;
grid-row: 4 / 5;
top: 4rem;
padding: 4rem;
background-color: var(--gray-soft-light);
@ -166,11 +195,20 @@
margin-top: 1.6rem;
padding-top: 3.2rem;
display: grid;
grid-template-areas: "minus input plus"
grid-template-areas: "min min min"
"minus input plus"
"btn btn btn";
grid-template-columns: repeat(3, minmax(0, min-content));
grid-template-columns: repeat(4, minmax(0, min-content));
justify-content: center;
gap: 1.6rem;
border-top: 1px solid var(--gray-soft-dark);
.min {
grid-area: min;
display: flex;
justify-content: center;
@include text-sm;
color: var(--alert);
}
.minus {
grid-area: minus;
color: var(--gray-hard-darkest);
@ -189,4 +227,35 @@
}
}
}
@media (min-width: 1024px) {
.ref { grid-area: 1 / 1 / 2 / 3; }
.name { grid-area: 2 / 1 / 3 / 3; }
.gallery { grid-area: 3 / 1 / 4 / 2; }
.description {
margin-top: 2.4rem;
grid-area: 4 / 1 / 5 / 3;
}
aside {
margin: 0;
grid-area: 3 / 2 / 4 / 3;
}
}
@media (min-width: 1200px) {
@include grid-col(12);
grid-template-rows: repeat(2, min-content) 1fr;
align-items: flex-start;
.ref { grid-area: 1 / 1 / 2 / 9; }
.name { grid-area: 2 / 1 / 3 / 9; }
.gallery { grid-area: 3 / 1 / 4 / 4; }
.description { grid-area: 3 / 4 / 4 / 9; }
aside {
grid-area: 1 / 9 / 4 / -1;
position: sticky;
}
}
@media (min-width: 1600px) {
aside { grid-area: 1 / 10 / 4 / -1; }
}
}

View File

@ -408,6 +408,7 @@ en:
available: "Available"
limited_stock: "Limited stock"
out_of_stock: "Out of stock"
minimum_purchase: "Minimum purchase: "
add: "Add"
add_to_cart: "Add to cart"
unit: "unit"
@ -420,6 +421,7 @@ en:
cart_is_empty: "Your cart is empty"
pickup: "Pickup your products"
reference_short: "ref:"
minimum_purchase: "Minimum purchase: "
unit: "Unit"
total: "Total"
checkout_header: "Total amount for your cart"