1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-30 19:52:20 +01:00

Style list items

This commit is contained in:
vincent 2022-08-04 16:24:52 +02:00
parent dc67d08395
commit d118d045c6
5 changed files with 117 additions and 8 deletions

View File

@ -1,7 +1,10 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import FormatLib from '../../lib/format';
import { FabButton } from '../base/fab-button';
import { Product } from '../../models/product';
import { PencilSimple, Trash } from 'phosphor-react';
import noImage from '../../../../images/no_image.png';
interface ProductsListProps {
products: Array<Product>,
@ -13,6 +16,19 @@ interface ProductsListProps {
* This component shows a list of all Products
*/
export const ProductsList: React.FC<ProductsListProps> = ({ products, onEdit, onDelete }) => {
console.log('products: ', products);
const { t } = useTranslation('admin');
/**
* TODO, document this method
*/
const thumbnail = (id: number) => {
const image = products
?.find(p => p.id === id)
.product_images_attributes
.find(att => att.is_main);
return image;
};
/**
* Init the process of editing the given product
*/
@ -31,15 +47,47 @@ export const ProductsList: React.FC<ProductsListProps> = ({ products, onEdit, on
};
};
/**
* Returns CSS class from stock status
*/
const statusColor = (product: Product) => {
if (product.stock.external === 0 && product.stock.internal === 0) {
return 'out-of-stock';
}
if (product.low_stock_alert) {
return 'low';
}
};
return (
<>
{products.map((product) => (
<div className='products-list-item' key={product.id}>
<div className={`products-list-item ${statusColor(product)}`} key={product.id}>
<div className='itemInfo'>
<img src='https://via.placeholder.com/300' alt='' className='itemInfo-thumbnail' />
{/* TODO: image size version ? */}
<img src={thumbnail(product.id)?.attachment_url || noImage} alt='' className='itemInfo-thumbnail' />
<p className="itemInfo-name">{product.name}</p>
</div>
<div className=''></div>
<div className='details'>
<span className={`visibility ${product.is_active ? 'is-active' : ''}`}>
{product.is_active
? t('app.admin.store.products_list.visible')
: t('app.admin.store.products_list.hidden')
}
</span>
<div className='stock'>
<span>{t('app.admin.store.products_list.stock.internal')}</span>
<p>{product.stock.internal}</p>
</div>
<div className='stock'>
<span>{t('app.admin.store.products_list.stock.external')}</span>
<p>{product.stock.external}</p>
</div>
<div>
<p>{FormatLib.price(product.amount)}</p>
<span>/ {t('app.admin.store.products_list.unit')}</span>
</div>
</div>
<div className='actions'>
<div className='manage'>
<FabButton className='edit-btn' onClick={editProduct(product)}>

View File

@ -7,6 +7,7 @@ import { FabButton } from '../base/fab-button';
import { ProductsList } from './products-list';
import { Product } from '../../models/product';
import ProductAPI from '../../api/product';
import { X } from 'phosphor-react';
declare const Application: IApplication;
@ -91,11 +92,11 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
<div className='features'>
<div className='features-item'>
<p>feature name</p>
<button><i className="fa fa-times" /></button>
<button><X size={16} /></button>
</div>
<div className='features-item'>
<p>long feature name</p>
<button><i className="fa fa-times" /></button>
<button><X size={16} /></button>
</div>
</div>
<ProductsList

View File

@ -115,6 +115,8 @@
button {
width: 3.2rem;
height: 3.2rem;
display: flex;
align-items: center;
background: none;
border: none;
}
@ -122,20 +124,25 @@
}
&-item {
--status-color: var(--gray-hard-darkest);
&.low { --status-color: var(--alert-light); }
&.out-of-stock { --status-color: var(--alert); }
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.6rem 0.8rem;
padding: 1.6rem 0.8rem;
border: 1px solid var(--gray-soft-dark);
border-radius: var(--border-radius);
background-color: var(--gray-soft-lightest);
&.out-of-stock { border-color: var(--status-color); }
&:not(:first-child) {
margin-top: 1.6rem;
}
.itemInfo {
min-width: 20ch;
display: flex;
justify-content: flex-end;
align-items: center;
&-thumbnail {
@ -153,6 +160,46 @@
color: var(--gray-hard-darkest);
}
}
.details {
display: grid;
grid-template-columns: 140px repeat(3, minmax(120px, 1fr));
justify-items: flex-start;
align-items: center;
gap: 1rem;
margin-left: auto;
margin-right: 4rem;
p {
margin: 0;
@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);
}
}
.stock {
display: flex;
flex-direction: column;
color: var(--status-color);
span { @include text-xs; }
}
}
.actions {
display: flex;
@ -169,7 +216,7 @@
&:hover { opacity: 0.75; }
}
.edit-btn {background: var(--gray-hard-darkest) }
.delete-btn {background: var(--error) }
.delete-btn {background: var(--main) }
}
}
}

View File

@ -56,6 +56,12 @@
font-size: 1.4rem;
line-height: normal;
}
@mixin text-xs($weight: normal) {
font-family: var(--font-text);
font-weight: $weight;
font-size: 1.1rem;
line-height: 1.18;
}
// Text Editor
@mixin editor {

View File

@ -1933,6 +1933,13 @@ en:
create_a_product: "Create a product"
successfully_deleted: "The product has been successfully deleted"
unable_to_delete: "Unable to delete the product: "
products_list:
visible: "visible"
hidden: "hidden"
stock:
internal: "Private stock"
external: "Public stock"
unit: "unit"
new_product:
add_a_new_product: "Add a new product"
successfully_created: "The new product has been created."