mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
(quality) Create state label component
This commit is contained in:
parent
874be0bcb6
commit
23488284e8
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
interface FabStateLabelProps {
|
||||
status?: string,
|
||||
background?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a label preceded by a bot
|
||||
*/
|
||||
export const FabStateLabel: React.FC<FabStateLabelProps> = ({ status, background, children }) => {
|
||||
console.log('status: ', status);
|
||||
return (
|
||||
<span className={`fab-state-label ${status !== undefined ? status : ''} ${background ? 'bg' : ''}`}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
};
|
@ -3,38 +3,71 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Order } from '../../models/order';
|
||||
import FormatLib from '../../lib/format';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import { User } from '../../models/user';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
|
||||
interface OrderItemProps {
|
||||
order?: Order
|
||||
statusColor: string
|
||||
order?: Order,
|
||||
currentUser?: User
|
||||
}
|
||||
|
||||
/**
|
||||
* List item for an order
|
||||
*/
|
||||
export const OrderItem: React.FC<OrderItemProps> = ({ order, statusColor }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
export const OrderItem: React.FC<OrderItemProps> = ({ order, currentUser }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
/**
|
||||
* Go to order page
|
||||
*/
|
||||
const showOrder = (token: string) => {
|
||||
window.location.href = `/#!/admin/store/o/${token}`;
|
||||
const showOrder = (ref: string) => {
|
||||
isPrivileged()
|
||||
? window.location.href = `/#!/admin/store/o/${ref}`
|
||||
: window.location.href = `/#!/store/o/${ref}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the current operator has administrative rights or is a normal member
|
||||
*/
|
||||
const isPrivileged = (): boolean => {
|
||||
return (currentUser?.role === 'admin' || currentUser?.role === 'manager');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a className according to the status
|
||||
*/
|
||||
const statusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case 'error':
|
||||
return 'error';
|
||||
case 'canceled':
|
||||
return 'canceled';
|
||||
case 'pending' || 'under_preparation':
|
||||
return 'pending';
|
||||
default:
|
||||
return 'normal';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='order-item'>
|
||||
<p className="ref">order.token</p>
|
||||
<span className={`order-status ${statusColor}`}>order.state</span>
|
||||
<div className='client'>
|
||||
<span>{t('app.admin.store.order_item.client')}</span>
|
||||
<p>order.user.name</p>
|
||||
<p className="ref">order.ref</p>
|
||||
<div>
|
||||
<FabStateLabel status={statusColor('pending')} background>
|
||||
order.state
|
||||
</FabStateLabel>
|
||||
</div>
|
||||
{isPrivileged() &&
|
||||
<div className='client'>
|
||||
<span>{t('app.shared.store.order_item.client')}</span>
|
||||
<p>order.user.name</p>
|
||||
</div>
|
||||
}
|
||||
<p className="date">order.created_at</p>
|
||||
<div className='price'>
|
||||
<span>{t('app.admin.store.order_item.total')}</span>
|
||||
<span>{t('app.shared.store.order_item.total')}</span>
|
||||
<p>{FormatLib.price(order?.total)}</p>
|
||||
</div>
|
||||
<FabButton onClick={() => showOrder('orderToken')} icon={<i className="fas fa-eye" />} className="is-black" />
|
||||
<FabButton onClick={() => showOrder('orderRef')} icon={<i className="fas fa-eye" />} className="is-black" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { react2angular } from 'react2angular';
|
||||
import { Loader } from '../base/loader';
|
||||
import { IApplication } from '../../models/application';
|
||||
import { StoreListHeader } from './store-list-header';
|
||||
import { OrderItem } from './order-item';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -29,8 +30,8 @@ export const OrdersDashboard: React.FC<OrdersDashboardProps> = ({ onError }) =>
|
||||
*/
|
||||
const buildOptions = (): Array<selectOption> => {
|
||||
return [
|
||||
{ value: 0, label: t('app.public.store.orders_dashboard.sort.newest') },
|
||||
{ value: 1, label: t('app.public.store.orders_dashboard.sort.oldest') }
|
||||
{ value: 0, label: t('app.public.orders_dashboard.sort.newest') },
|
||||
{ value: 1, label: t('app.public.orders_dashboard.sort.oldest') }
|
||||
];
|
||||
};
|
||||
/**
|
||||
@ -43,7 +44,7 @@ export const OrdersDashboard: React.FC<OrdersDashboardProps> = ({ onError }) =>
|
||||
return (
|
||||
<section className="orders-dashboard">
|
||||
<header>
|
||||
<h2>{t('app.public.store.orders_dashboard.heading')}</h2>
|
||||
<h2>{t('app.public.orders_dashboard.heading')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="store-list">
|
||||
@ -52,6 +53,9 @@ export const OrdersDashboard: React.FC<OrdersDashboardProps> = ({ onError }) =>
|
||||
selectOptions={buildOptions()}
|
||||
onSelectOptionsChange={handleSorting}
|
||||
/>
|
||||
<div className="orders-list">
|
||||
<OrderItem />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
@ -9,10 +9,12 @@ import { StoreListHeader } from './store-list-header';
|
||||
import { AccordionItem } from './accordion-item';
|
||||
import { OrderItem } from './order-item';
|
||||
import { MemberSelect } from '../user/member-select';
|
||||
import { User } from '../../models/user';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
interface OrdersProps {
|
||||
currentUser?: User,
|
||||
onSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
}
|
||||
@ -32,7 +34,8 @@ type checklistOption = { value: number, label: string };
|
||||
*/
|
||||
// TODO: delete next eslint disable
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const Orders: React.FC<OrdersProps> = ({ onSuccess, onError }) => {
|
||||
const Orders: React.FC<OrdersProps> = ({ currentUser, onSuccess, onError }) => {
|
||||
console.log('currentUser: ', currentUser);
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [filters, setFilters] = useImmer<Filters>(initFilters);
|
||||
@ -123,22 +126,6 @@ const Orders: React.FC<OrdersProps> = ({ onSuccess, onError }) => {
|
||||
setAccordion({ ...accordion, [id]: state });
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a className according to the status
|
||||
*/
|
||||
const statusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case 'error':
|
||||
return 'error';
|
||||
case 'canceled':
|
||||
return 'canceled';
|
||||
case 'pending' || 'under_preparation':
|
||||
return 'pending';
|
||||
default:
|
||||
return 'normal';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='orders'>
|
||||
<header>
|
||||
@ -209,10 +196,7 @@ const Orders: React.FC<OrdersProps> = ({ onSuccess, onError }) => {
|
||||
onSelectOptionsChange={handleSorting}
|
||||
/>
|
||||
<div className="orders-list">
|
||||
<OrderItem statusColor={statusColor('error')} />
|
||||
<OrderItem statusColor={statusColor('canceled')} />
|
||||
<OrderItem statusColor={statusColor('pending')} />
|
||||
<OrderItem statusColor={statusColor('refunded')} />
|
||||
<OrderItem currentUser={currentUser} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -227,7 +211,7 @@ const OrdersWrapper: React.FC<OrdersProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('orders', react2angular(OrdersWrapper, ['onSuccess', 'onError']));
|
||||
Application.Components.component('orders', react2angular(OrdersWrapper, ['currentUser', 'onSuccess', 'onError']));
|
||||
|
||||
interface Filters {
|
||||
reference: string,
|
||||
|
@ -5,6 +5,7 @@ import { FabButton } from '../base/fab-button';
|
||||
import { Product } from '../../models/product';
|
||||
import { PencilSimple, Trash } from 'phosphor-react';
|
||||
import noImage from '../../../../images/no_image.png';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
|
||||
interface ProductItemProps {
|
||||
product: Product,
|
||||
@ -64,12 +65,12 @@ export const ProductItem: React.FC<ProductItemProps> = ({ product, onEdit, onDel
|
||||
<p className="itemInfo-name">{product.name}</p>
|
||||
</div>
|
||||
<div className='details'>
|
||||
<span className={`visibility ${product.is_active ? 'is-active' : ''}`}>
|
||||
<FabStateLabel status={product.is_active ? 'is-active' : ''} background>
|
||||
{product.is_active
|
||||
? t('app.admin.store.product_item.visible')
|
||||
: t('app.admin.store.product_item.hidden')
|
||||
}
|
||||
</span>
|
||||
</FabStateLabel>
|
||||
<div className={`stock ${product.stock.internal < product.low_stock_threshold ? 'low' : ''}`}>
|
||||
<span>{t('app.admin.store.product_item.stock.internal')}</span>
|
||||
<p>{product.stock.internal}</p>
|
||||
|
@ -12,6 +12,7 @@ import { FabButton } from '../base/fab-button';
|
||||
import { PencilSimple } from 'phosphor-react';
|
||||
import { FabModal, ModalSize } from '../base/fab-modal';
|
||||
import { ProductStockModal } from './product-stock-modal';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
|
||||
interface ProductStockFormProps<TFieldValues, TContext extends object> {
|
||||
product: Product,
|
||||
@ -135,7 +136,7 @@ export const ProductStockForm = <TFieldValues, TContext extends object> ({ produ
|
||||
<HtmlTranslate trKey="app.admin.store.product_stock_form.stock_threshold_information" />
|
||||
</FabAlert>
|
||||
{activeThreshold && <>
|
||||
<span className='stock-label'>{t('app.admin.store.product_stock_form.low_stock')}</span>
|
||||
<FabStateLabel>{t('app.admin.store.product_stock_form.low_stock')}</FabStateLabel>
|
||||
<div className="threshold-data-content">
|
||||
<FormInput id="threshold"
|
||||
type="number"
|
||||
|
@ -4,6 +4,7 @@ import { IApplication } from '../../models/application';
|
||||
import { react2angular } from 'react2angular';
|
||||
import { Loader } from '../base/loader';
|
||||
import noImage from '../../../../images/no_image.png';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -66,7 +67,9 @@ export const ShowOrder: React.FC<ShowOrderProps> = ({ orderRef, onError, onSucce
|
||||
<span>{t('app.admin.store.show_order.last_update')}</span>
|
||||
<p>order.???</p>
|
||||
</div>
|
||||
<span className={`order-status ${statusColor('error')}`}>order.state</span>
|
||||
<FabStateLabel status={statusColor('error')} background>
|
||||
order.state
|
||||
</FabStateLabel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -99,7 +102,7 @@ export const ShowOrder: React.FC<ShowOrderProps> = ({ orderRef, onError, onSucce
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="group">
|
||||
<div className="subgrid">
|
||||
<div className="payment-info">
|
||||
<label>{t('app.admin.store.show_order.payment_informations')}</label>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum rerum commodi quaerat possimus! Odit, harum.</p>
|
||||
|
@ -43,7 +43,7 @@ export const StoreListHeader: React.FC<StoreListHeaderProps> = ({ productsCount,
|
||||
</div>
|
||||
<div className="display">
|
||||
<div className='sort'>
|
||||
<p>{t('app.admin.store.store_list_header.display_options')}</p>
|
||||
<p>{t('app.admin.store.store_list_header.sort')}</p>
|
||||
<Select
|
||||
options={selectOptions}
|
||||
onChange={evt => onSelectOptionsChange(evt)}
|
||||
|
@ -4,6 +4,7 @@ import _ from 'lodash';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import { Product } from '../../models/product';
|
||||
import { Order } from '../../models/order';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
import FormatLib from '../../lib/format';
|
||||
import CartAPI from '../../api/cart';
|
||||
import noImage from '../../../../images/no_image.png';
|
||||
@ -57,6 +58,7 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
|
||||
if (product.low_stock_alert) {
|
||||
return 'low';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,9 +86,9 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
|
||||
<span>/ {t('app.public.store_product_item.unit')}</span>
|
||||
</div>
|
||||
}
|
||||
<div className="stock-label">
|
||||
<FabStateLabel status={statusColor(product)}>
|
||||
{productStockStatus(product)}
|
||||
</div>
|
||||
</FabStateLabel>
|
||||
{product.stock.external > 0 &&
|
||||
<FabButton icon={<i className="fas fa-cart-arrow-down" />} className="main-action-btn" onClick={addProductToCart}>
|
||||
{t('app.public.store_product_item.add')}
|
||||
|
@ -11,6 +11,7 @@ import ProductAPI from '../../api/product';
|
||||
import noImage from '../../../../images/no_image.png';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import { FilePdf, Minus, Plus } from 'phosphor-react';
|
||||
import { FabStateLabel } from '../base/fab-state-label';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -112,7 +113,7 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError
|
||||
|
||||
if (product) {
|
||||
return (
|
||||
<div className={`store-product ${statusColor(product)}`}>
|
||||
<div className={`store-product ${statusColor(product) || ''}`}>
|
||||
<span className='ref'>ref: {product.sku}</span>
|
||||
<h2 className='name'>{product.name}</h2>
|
||||
<div className='gallery'>
|
||||
@ -160,9 +161,9 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, onError
|
||||
</div>
|
||||
|
||||
<aside>
|
||||
<div className="stock-label">
|
||||
<FabStateLabel status={statusColor(product)}>
|
||||
{productStockStatus(product)}
|
||||
</div>
|
||||
</FabStateLabel>
|
||||
<div className='price'>
|
||||
<p>{FormatLib.price(product.amount)} <sup>TTC</sup></p>
|
||||
<span>/ {t('app.public.store_product_item.unit')}</span>
|
||||
|
@ -4,8 +4,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('ShowOrdersController', ['$scope', 'CSRF', 'growl', '$state', '$transition$',
|
||||
function ($scope, CSRF, growl, $state, $transition$) {
|
||||
Application.Controllers.controller('ShowOrdersController', ['$rootScope', '$scope', 'CSRF', 'growl', '$state', '$transition$',
|
||||
function ($rootScope, $scope, CSRF, growl, $state, $transition$) {
|
||||
/* PRIVATE SCOPE */
|
||||
|
||||
/* PUBLIC SCOPE */
|
||||
@ -32,6 +32,9 @@ Application.Controllers.controller('ShowOrdersController', ['$scope', 'CSRF', 'g
|
||||
$state.go('app.admin.store.orders');
|
||||
};
|
||||
|
||||
// currently logged-in user
|
||||
$scope.currentUser = $rootScope.currentUser;
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
|
||||
/**
|
||||
|
@ -631,6 +631,17 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
})
|
||||
|
||||
// show order
|
||||
.state('app.public.order_show', {
|
||||
url: '/store/o/:token',
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/orders/show.html',
|
||||
controller: 'ShowOrdersController'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// cart
|
||||
.state('app.public.cart', {
|
||||
url: '/cart',
|
||||
|
@ -27,6 +27,7 @@
|
||||
@import "modules/base/fab-output-copy";
|
||||
@import "modules/base/fab-panel";
|
||||
@import "modules/base/fab-popover";
|
||||
@import "modules/base/fab-state-label";
|
||||
@import "modules/base/fab-text-editor";
|
||||
@import "modules/base/labelled-input";
|
||||
@import "modules/calendar/calendar";
|
||||
@ -92,6 +93,7 @@
|
||||
@import "modules/settings/user-validation-setting";
|
||||
@import "modules/socials/fab-socials";
|
||||
@import "modules/store/_utilities";
|
||||
@import "modules/store/order-item";
|
||||
@import "modules/store/orders-dashboard";
|
||||
@import "modules/store/orders";
|
||||
@import "modules/store/product-categories";
|
||||
|
@ -0,0 +1,28 @@
|
||||
.fab-state-label {
|
||||
// --status-color needs to be defined in the component's CSS
|
||||
--status-color: var(--gray-hard-darkest);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include text-sm;
|
||||
line-height: 1.714;
|
||||
color: var(--status-color);
|
||||
|
||||
&.bg {
|
||||
width: fit-content;
|
||||
padding: 0.4rem 0.8rem;
|
||||
justify-content: center;
|
||||
background-color: var(--gray-soft-light);
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--gray-hard-darkest);
|
||||
}
|
||||
|
||||
&::before {
|
||||
flex-shrink: 0;
|
||||
content: "";
|
||||
margin-right: 0.8rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-color: var(--status-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
@ -68,21 +68,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.stock-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include text-sm;
|
||||
color: var(--status-color);
|
||||
&::before {
|
||||
content: "";
|
||||
margin-right: 0.8rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-color: var(--status-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
// Custom scrollbar
|
||||
.u-scrollbar {
|
||||
&::-webkit-scrollbar-track
|
||||
|
47
app/frontend/src/stylesheets/modules/store/order-item.scss
Normal file
47
app/frontend/src/stylesheets/modules/store/order-item.scss
Normal file
@ -0,0 +1,47 @@
|
||||
.order-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 2.4rem;
|
||||
justify-items: flex-start;
|
||||
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%;
|
||||
@include text-base(600);
|
||||
}
|
||||
.fab-state-label {
|
||||
--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;
|
||||
}
|
||||
.status .state-label { margin: 0 auto; }
|
||||
.client {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span {
|
||||
@include text-xs;
|
||||
color: var(--gray-hard-light);
|
||||
}
|
||||
p { @include text-sm; }
|
||||
}
|
||||
.date { @include text-sm; }
|
||||
.price {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-self: flex-end;
|
||||
span {
|
||||
@include text-xs;
|
||||
color: var(--gray-hard-light);
|
||||
}
|
||||
p { @include text-base(600); }
|
||||
}
|
||||
}
|
@ -11,4 +11,7 @@
|
||||
padding-bottom: 0;
|
||||
grid-column: 2 / -2;
|
||||
}
|
||||
.store-list {
|
||||
grid-column: 2 / -2;
|
||||
}
|
||||
}
|
@ -17,39 +17,6 @@
|
||||
& > *:not(:first-child) {
|
||||
margin-top: 1.6rem;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-columns: 1fr 15rem 15rem 10ch 12rem;
|
||||
gap: 2.4rem;
|
||||
justify-items: flex-start;
|
||||
align-items: center;
|
||||
padding: 1.6rem;
|
||||
border: 1px solid var(--gray-soft-dark);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--gray-soft-lightest);
|
||||
|
||||
p { margin: 0; }
|
||||
.ref { @include text-base(600); }
|
||||
.client {
|
||||
span {
|
||||
@include text-xs;
|
||||
color: var(--gray-hard-light);
|
||||
}
|
||||
p { @include text-sm; }
|
||||
}
|
||||
.date { @include text-sm; }
|
||||
.price {
|
||||
justify-self: flex-end;
|
||||
span {
|
||||
@include text-xs;
|
||||
color: var(--gray-hard-light);
|
||||
}
|
||||
p { @include text-base(600); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,6 +53,8 @@
|
||||
line-height: 1.18;
|
||||
}
|
||||
.group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span {
|
||||
@include text-xs;
|
||||
color: var(--gray-hard-light);
|
||||
@ -93,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
& > .group {
|
||||
.subgrid {
|
||||
grid-column: 2 / -2;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@ -130,29 +99,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-status {
|
||||
--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); }
|
||||
padding: 0.4rem 0.8rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--gray-soft-light);
|
||||
border-radius: var(--border-radius);
|
||||
@include text-sm(500);
|
||||
line-height: 1.714;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
margin-right: 0.8rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-color: var(--status-color);
|
||||
border-radius: 50%;
|
||||
.fab-state-label {
|
||||
--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); }
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@
|
||||
label { flex: 0 1 fit-content; }
|
||||
|
||||
}
|
||||
.stock-label {
|
||||
.fab-state-label {
|
||||
--status-color: var(--alert-light);
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,12 @@
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
.stock-label { grid-area: stock; }
|
||||
.fab-state-label {
|
||||
--status-color: var(--success);
|
||||
&.low { --status-color: var(--alert-light); }
|
||||
&.out-of-stock { --status-color: var(--alert); }
|
||||
grid-area: stock;
|
||||
}
|
||||
button {
|
||||
grid-area: btn;
|
||||
align-self: flex-end;
|
||||
|
@ -54,25 +54,8 @@
|
||||
@include text-base(600);
|
||||
}
|
||||
|
||||
.visibility {
|
||||
justify-self: center;
|
||||
padding: 0.4rem 0.8rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: var(--gray-soft-light);
|
||||
border-radius: var(--border-radius);
|
||||
&::before {
|
||||
flex-shrink: 0;
|
||||
margin-right: 1rem;
|
||||
content: "";
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-color: var(--gray-hard);
|
||||
border-radius: 50%;
|
||||
}
|
||||
&.is-active::before {
|
||||
background-color: var(--success);
|
||||
}
|
||||
.fab-state-label.is-active {
|
||||
--status-color: var(--success);
|
||||
}
|
||||
.stock {
|
||||
display: flex;
|
||||
|
@ -142,6 +142,12 @@
|
||||
background-color: var(--gray-soft-light);
|
||||
border-radius: var(--border-radius-sm);
|
||||
|
||||
.fab-state-label {
|
||||
--status-color: var(--success);
|
||||
&.low { --status-color: var(--alert-light); }
|
||||
&.out-of-stock { --status-color: var(--alert); }
|
||||
}
|
||||
|
||||
.price {
|
||||
p {
|
||||
margin: 0;
|
||||
|
@ -1 +1 @@
|
||||
<orders on-success="onSuccess" on-error="onError"/>
|
||||
<orders current-user="currentUser" on-success="onSuccess" on-error="onError"/>
|
||||
|
@ -1949,7 +1949,7 @@ en:
|
||||
price_high: "Price: high to low"
|
||||
store_list_header:
|
||||
result_count: "Result count:"
|
||||
display_options: "Display options:"
|
||||
sort: "Sort:"
|
||||
visible_only: "Visible products only"
|
||||
product_item:
|
||||
visible: "visible"
|
||||
@ -2049,9 +2049,6 @@ en:
|
||||
sort:
|
||||
newest: "Newest first"
|
||||
oldest: "Oldest first"
|
||||
order_item:
|
||||
total: "Total"
|
||||
client: "Client"
|
||||
show_order:
|
||||
see_invoice: "See invoice"
|
||||
client: "Client"
|
||||
|
@ -392,6 +392,11 @@ fr:
|
||||
store_cart:
|
||||
checkout: "Valider mon panier"
|
||||
cart_is_empty: "Votre panier est vide"
|
||||
orders_dashboard:
|
||||
heading: "My orders"
|
||||
sort:
|
||||
newest: "Newest first"
|
||||
oldest: "Oldest first"
|
||||
member_select:
|
||||
select_a_member: "Sélectionnez un membre"
|
||||
start_typing: "Commencez à écrire..."
|
||||
|
@ -560,3 +560,7 @@ en:
|
||||
browse: "Browse"
|
||||
edit: "Edit"
|
||||
main_image: "Main image"
|
||||
store:
|
||||
order_item:
|
||||
total: "Total"
|
||||
client: "Client"
|
||||
|
Loading…
x
Reference in New Issue
Block a user