fix(pos): hide selfpay controls and normalize trend labels
This commit is contained in:
@@ -1 +1 @@
|
|||||||
0.2.2
|
0.2.3
|
||||||
|
|||||||
4
project/apps/admin/package-lock.json
generated
4
project/apps/admin/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@mercadodevida/admin",
|
"name": "@mercadodevida/admin",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@mercadodevida/admin",
|
"name": "@mercadodevida/admin",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lexical/history": "^0.49.0",
|
"@lexical/history": "^0.49.0",
|
||||||
"@lexical/html": "^0.49.0",
|
"@lexical/html": "^0.49.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mercadodevida/admin",
|
"name": "@mercadodevida/admin",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --port 3001",
|
"dev": "next dev --port 3001",
|
||||||
|
|||||||
@@ -16,28 +16,36 @@ interface TrendChartProps {
|
|||||||
export function TrendChart({ data, maxValue, height = 120 }: TrendChartProps) {
|
export function TrendChart({ data, maxValue, height = 120 }: TrendChartProps) {
|
||||||
if (data.length === 0) return null;
|
if (data.length === 0) return null;
|
||||||
|
|
||||||
const width = 100; // percentage-based SVG
|
const chartWidth = Math.max(420, data.length * 26);
|
||||||
const barWidth = Math.min(3, (width * 0.9) / data.length);
|
const padding = { top: 12, right: 14, bottom: 28, left: 14 };
|
||||||
const gap = Math.max(0.2, (width - barWidth * data.length) / (data.length + 1));
|
const plotWidth = chartWidth - padding.left - padding.right;
|
||||||
const chartHeight = height - 34; // leave room for labels
|
const chartHeight = Math.max(60, height - padding.top - padding.bottom);
|
||||||
|
const barWidth = Math.min(16, Math.max(7, (plotWidth / data.length) * 0.62));
|
||||||
|
const gap = Math.max(4, (plotWidth - barWidth * data.length) / Math.max(data.length + 1, 1));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full overflow-x-auto rounded-xl bg-white">
|
<div className="w-full overflow-x-auto rounded-xl bg-white">
|
||||||
<svg
|
<svg
|
||||||
viewBox={`0 0 ${width} ${height}`}
|
viewBox={`0 0 ${chartWidth} ${height}`}
|
||||||
className="block w-full"
|
className="block min-w-full"
|
||||||
style={{ minWidth: `${Math.max(360, data.length * 10)}px`, height: `${height}px` }}
|
style={{ width: '100%', minWidth: `${chartWidth}px`, height: `${height}px` }}
|
||||||
preserveAspectRatio="none"
|
|
||||||
aria-label="Tendencia de ventas"
|
aria-label="Tendencia de ventas"
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
{/* Y-axis baseline */}
|
{/* Y-axis baseline */}
|
||||||
<line x1="0" y1={chartHeight} x2={width} y2={chartHeight} stroke="#e5e7eb" strokeWidth="0.5" />
|
<line
|
||||||
|
x1={padding.left}
|
||||||
|
y1={padding.top + chartHeight}
|
||||||
|
x2={chartWidth - padding.right}
|
||||||
|
y2={padding.top + chartHeight}
|
||||||
|
stroke="#e5e7eb"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
|
||||||
{data.map((point, i) => {
|
{data.map((point, i) => {
|
||||||
const barH = maxValue > 0 ? (point.value / maxValue) * chartHeight : 0;
|
const barH = maxValue > 0 ? (point.value / maxValue) * chartHeight : 0;
|
||||||
const x = gap + i * (barWidth + gap);
|
const x = padding.left + gap + i * (barWidth + gap);
|
||||||
const y = chartHeight - barH;
|
const y = padding.top + chartHeight - barH;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g key={i} className="group">
|
<g key={i} className="group">
|
||||||
@@ -48,16 +56,16 @@ export function TrendChart({ data, maxValue, height = 120 }: TrendChartProps) {
|
|||||||
width={barWidth}
|
width={barWidth}
|
||||||
height={barH}
|
height={barH}
|
||||||
fill="#2D6A4F"
|
fill="#2D6A4F"
|
||||||
rx="1"
|
rx="3"
|
||||||
className="transition-all duration-200 hover:fill-[#245a42]"
|
className="transition-all duration-200 hover:fill-[#245a42]"
|
||||||
/>
|
/>
|
||||||
{/* Label (show every ~7 bars or if narrow) */}
|
|
||||||
{data.length <= 31 && (
|
{data.length <= 31 && (
|
||||||
<text
|
<text
|
||||||
x={x + barWidth / 2}
|
x={x + barWidth / 2}
|
||||||
y={height - 2}
|
y={height - 8}
|
||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
fontSize="2.5"
|
fontSize="11"
|
||||||
|
fontWeight="500"
|
||||||
fill="#9ca3af"
|
fill="#9ca3af"
|
||||||
>
|
>
|
||||||
{point.label.slice(5, 10)}
|
{point.label.slice(5, 10)}
|
||||||
|
|||||||
4
project/apps/pos/package-lock.json
generated
4
project/apps/pos/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-pos",
|
"name": "mercadodevida-pos",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mercadodevida-pos",
|
"name": "mercadodevida-pos",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "^16.3.1",
|
"next": "^16.3.1",
|
||||||
"react": "^19.2.8",
|
"react": "^19.2.8",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-pos",
|
"name": "mercadodevida-pos",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --port 3002",
|
"dev": "next dev --port 3002",
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ interface Config {
|
|||||||
terminal: {
|
terminal: {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
settings?: { lineDiscountsEnabled?: boolean } & Record<string, unknown>;
|
settings?: { lineDiscountsEnabled?: boolean; selfpayMode?: boolean } & Record<string, unknown>;
|
||||||
};
|
};
|
||||||
store: { id: string; name: string };
|
store: { id: string; name: string };
|
||||||
paymentMethods: PaymentMethod[];
|
paymentMethods: PaymentMethod[];
|
||||||
@@ -439,7 +439,8 @@ export default function RegisterPage() {
|
|||||||
}, [cart]);
|
}, [cart]);
|
||||||
const paidCents = payments.reduce((sum, payment) => sum + payment.amountCents, 0);
|
const paidCents = payments.reduce((sum, payment) => sum + payment.amountCents, 0);
|
||||||
const remainingCents = Math.max(0, totals.total - paidCents);
|
const remainingCents = Math.max(0, totals.total - paidCents);
|
||||||
const lineDiscountsEnabled = config?.terminal.settings?.lineDiscountsEnabled !== false;
|
const isSelfpayMode = config?.terminal.settings?.selfpayMode === true;
|
||||||
|
const lineDiscountsEnabled = !isSelfpayMode && config?.terminal.settings?.lineDiscountsEnabled !== false;
|
||||||
|
|
||||||
const applyDiscount = (lineId: string, discountCents: number) => {
|
const applyDiscount = (lineId: string, discountCents: number) => {
|
||||||
setCart((current) =>
|
setCart((current) =>
|
||||||
@@ -921,7 +922,7 @@ export default function RegisterPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen" style={{ '--color-primary': '#2D6A4F' } as React.CSSProperties}>
|
<div className="flex h-screen" style={{ '--color-primary': '#2D6A4F' } as React.CSSProperties}>
|
||||||
{showSidebar && (
|
{!isSelfpayMode && showSidebar && (
|
||||||
<aside
|
<aside
|
||||||
className="hidden w-[380px] shrink-0 flex-col border-r bg-gray-50 p-3 lg:flex"
|
className="hidden w-[380px] shrink-0 flex-col border-r bg-gray-50 p-3 lg:flex"
|
||||||
aria-label="Pedidos"
|
aria-label="Pedidos"
|
||||||
@@ -1200,17 +1201,19 @@ export default function RegisterPage() {
|
|||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<div className="mb-2 flex items-center gap-3">
|
<div className="mb-2 flex items-center gap-3">
|
||||||
{/* Panel toggle button - LEFT */}
|
{/* Panel toggle button - LEFT */}
|
||||||
<button
|
{!isSelfpayMode && (
|
||||||
type="button"
|
<button
|
||||||
onClick={() => setShowSidebar((v) => !v)}
|
type="button"
|
||||||
title={showSidebar ? 'Ocultar panel' : 'Mostrar panel'}
|
onClick={() => setShowSidebar((v) => !v)}
|
||||||
className="flex items-center gap-1.5 rounded-lg border border-gray-300 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-50 transition-colors"
|
title={showSidebar ? 'Ocultar panel' : 'Mostrar panel'}
|
||||||
>
|
className="flex items-center gap-1.5 rounded-lg border border-gray-300 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-50 transition-colors"
|
||||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d={showSidebar ? "M4 6h16M4 12h16M4 18h7" : "M4 6h16M4 12h16M4 18h16"} />
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||||
</svg>
|
<path strokeLinecap="round" strokeLinejoin="round" d={showSidebar ? "M4 6h16M4 12h16M4 18h7" : "M4 6h16M4 12h16M4 18h16"} />
|
||||||
{showSidebar ? 'Ocultar' : 'Panel'}
|
</svg>
|
||||||
</button>
|
{showSidebar ? 'Ocultar' : 'Panel'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Store name */}
|
{/* Store name */}
|
||||||
<span className="text-sm font-bold text-[#2D6A4F]">{config.store.name}</span>
|
<span className="text-sm font-bold text-[#2D6A4F]">{config.store.name}</span>
|
||||||
@@ -1234,7 +1237,7 @@ export default function RegisterPage() {
|
|||||||
{currentTime.toLocaleDateString('es-ES', { day: '2-digit', month: 'short', year: 'numeric' })}
|
{currentTime.toLocaleDateString('es-ES', { day: '2-digit', month: 'short', year: 'numeric' })}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{!config?.terminal?.settings?.selfpayMode && (
|
{!isSelfpayMode && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -1588,7 +1591,7 @@ export default function RegisterPage() {
|
|||||||
<span>Subtotal</span>
|
<span>Subtotal</span>
|
||||||
<span>{formatPrice(totals.subtotal)}</span>
|
<span>{formatPrice(totals.subtotal)}</span>
|
||||||
</div>
|
</div>
|
||||||
{totals.discount > 0 && (
|
{!isSelfpayMode && totals.discount > 0 && (
|
||||||
<div className="flex justify-between text-red-600">
|
<div className="flex justify-between text-red-600">
|
||||||
<span>Descuentos</span>
|
<span>Descuentos</span>
|
||||||
<span>−{formatPrice(totals.discount)}</span>
|
<span>−{formatPrice(totals.discount)}</span>
|
||||||
@@ -1689,7 +1692,7 @@ export default function RegisterPage() {
|
|||||||
</button>
|
</button>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
{showDiscountPanel && selectedItem && (
|
{!isSelfpayMode && showDiscountPanel && selectedItem && (
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
|
||||||
<DiscountPanel
|
<DiscountPanel
|
||||||
unitPriceCents={selectedItem.unitPriceCents}
|
unitPriceCents={selectedItem.unitPriceCents}
|
||||||
|
|||||||
4
project/frontend/package-lock.json
generated
4
project/frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "16.3.1",
|
"next": "16.3.1",
|
||||||
"react": "19.2.8",
|
"react": "19.2.8",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
4
project/package-lock.json
generated
4
project/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-backend",
|
"name": "mercadodevida-backend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mercadodevida-backend",
|
"name": "mercadodevida-backend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cookie": "^11.1.2",
|
"@fastify/cookie": "^11.1.2",
|
||||||
"@fastify/cors": "^11.3.0",
|
"@fastify/cors": "^11.3.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-backend",
|
"name": "mercadodevida-backend",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "mercadodevida vNext backend - modular monolith skeleton",
|
"description": "mercadodevida vNext backend - modular monolith skeleton",
|
||||||
|
|||||||
4
project/storefront/package-lock.json
generated
4
project/storefront/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-storefront",
|
"name": "mercadodevida-storefront",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mercadodevida-storefront",
|
"name": "mercadodevida-storefront",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.17",
|
"@tailwindcss/postcss": "^4.1.17",
|
||||||
"next": "^16.0.5",
|
"next": "^16.0.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mercadodevida-storefront",
|
"name": "mercadodevida-storefront",
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "mercadodevida customer storefront shell",
|
"description": "mercadodevida customer storefront shell",
|
||||||
|
|||||||
Reference in New Issue
Block a user