Ref: modification components in selfcheckout

This commit is contained in:
Luis Felipe Cadavid 2024-09-30 15:17:38 -05:00
parent 251a6a2a6a
commit ab7a02bcca
40 changed files with 1315 additions and 557 deletions

View file

@ -0,0 +1,63 @@
"use client";
import { Box } from '@mui/material';
import Grid from '@mui/material/Grid2';
import React from 'react';
import { useTranslation } from 'react-i18next';
import Button from '@atoms/Button';
interface ActionButtonsProps {
onVoidOrder: () => void;
onVoidLast: () => void;
onResume: () => void;
}
const ActionButtons: React.FC<ActionButtonsProps> = ({ onVoidOrder, onVoidLast, onResume }) => {
const { t } = useTranslation()
return (
<Box
sx={{
mb: 1,
p: 1,
boxShadow: 4,
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
<Grid
container
spacing={2}
justifyContent="center"
alignItems="center"
>
<Grid size={{xs:4}}>
<Button
label={t("lbl_void_order")}
variant="danger"
onClick={onVoidOrder}
className="full-width-button"
/>
</Grid>
<Grid size={{xs:4}}>
<Button
label={t("lbl_void_last")}
variant="danger"
onClick={onVoidLast}
className="full-width-button"
/>
</Grid>
<Grid size={{xs:4}}>
<Button
label={t("lbl_resume")}
variant="primary"
onClick={onResume}
className="full-width-button"
/>
</Grid>
</Grid>
</Box>
);
};
export default ActionButtons;

View file

@ -0,0 +1,20 @@
"use client"
import { CardContent, CardHeader, Card as MUICard } from "@mui/material"
import React from "react"
interface CardProps {
title?: string
children: React.ReactNode
className?: string
}
const CustomCard: React.FC<CardProps> = ({ title, children, className }) => {
return (
<MUICard className={className}>
{title && <CardHeader title={title} />}
<CardContent>{children}</CardContent>
</MUICard>
)
}
export default CustomCard

View file

@ -1,20 +1,24 @@
"use client"
import Grid2 from "@mui/material/Grid2"
import React from "react"
import Button from "@atoms/Button"
"use client";
import Grid2 from "@mui/material/Grid2";
import React from "react";
import Button from "@atoms/Button";
interface NumericKeyProps {
label: string | number
onClick: () => void
className?: string
label: string | number;
onClick: () => void;
className?: string;
}
const NumericKey: React.FC<NumericKeyProps> = ({ label, onClick, className }) => {
return (
<Grid2 container justifyContent="center" component="div">
<Button label={label.toString()} onClick={onClick} className={`h-16 w-full ${className}`} />
<Button
label={label.toString()}
onClick={onClick}
className={`h-16 w-full text-3xl font-bold ${className}`}
/>
</Grid2>
)
}
);
};
export default NumericKey
export default NumericKey;

View file

@ -1,69 +1,57 @@
"use client"
import Grid from "@mui/material/Grid2"
import React from "react"
import NumericKey from "@molecules/NumericKey"
"use client";
import Grid from "@mui/material/Grid2";
import React from "react";
import { useTranslation } from "react-i18next";
import NumericKey from "@molecules/NumericKey";
const NumericPad: React.FC = () => {
const handleKeyClick = (key: number) => {
console.log(`Key pressed: ${key}`)
}
interface NumericPadProps {
onKeyClick: (key: string) => void;
}
const NumericPad: React.FC<NumericPadProps> = ({ onKeyClick }) => {
const { t } = useTranslation();
return (
<Grid container spacing={0.4} justifyContent="center" alignItems="center">
<Grid size={{ xs: 6 }}>
<NumericKey
label="Cancel"
onClick={() => console.log("Cancel pressed")}
label={t("lbl_cancel")}
onClick={() => onKeyClick("cancel")}
className="h-12 w-full bg-danger-light text-white hover:bg-danger-dark"
/>
</Grid>
<Grid size={{ xs: 6 }}>
<NumericKey label="clear" onClick={() => console.log("Clear pressed")} className="size-12 bg-secondary-light" />
</Grid>
<Grid size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
<NumericKey
label="0"
onClick={() => console.log("0")}
className="size-24 bg-primary-500 text-white hover:bg-primary-600"
label={t("lbl_clear")}
onClick={() => onKeyClick("clear")}
className="h-12 bg-secondary-light text-black"
/>
</Grid>
{[...Array(9).keys()].map((i) => (
<Grid key={i + 1} size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
{" "}
{[...Array(10).keys()].map((i) => (
<Grid key={i} size={{ xs: 4 }} sx={{ minWidth: "100px" }}>
<NumericKey
label={i + 1}
onClick={() => handleKeyClick(i + 1)}
className="size-24 bg-primary-500 text-white hover:bg-primary-600"
label={i}
onClick={() => onKeyClick(i.toString())}
className="h-16 bg-primary-500 text-white hover:bg-primary-600"
/>
</Grid>
))}
<Grid size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
<Grid size={{ xs: 4 }}>
<NumericKey
label="."
onClick={() => console.log(".")}
className="size-24 bg-primary-500 text-white hover:bg-primary-600"
onClick={() => onKeyClick(".")}
className="h-16 bg-primary-500 text-white hover:bg-primary-600"
/>
</Grid>
<Grid size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
<NumericKey label="/" onClick={() => console.log("Divide pressed")} className="size-12 bg-secondary-light" />
</Grid>
<Grid size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
<NumericKey label="QTY" onClick={() => console.log("QTY pressed")} className="size-12 bg-secondary-light" />
</Grid>
<Grid size={{ xs: 3 }} sx={{ minWidth: "100px" }}>
<NumericKey label="Price" onClick={() => console.log("Price pressed")} className="size-12 bg-secondary-light" />
</Grid>
<Grid size={{ xs: 6 }}>
<Grid size={{ xs: 4 }}>
<NumericKey
label="Enter"
onClick={() => console.log("Enter pressed")}
label={t("lbl_enter")}
onClick={() => onKeyClick("enter")}
className="h-12 w-full bg-success-light text-white hover:bg-success-dark"
/>
</Grid>
</Grid>
)
}
);
};
export default NumericPad
export default NumericPad;

View file

@ -1,28 +0,0 @@
"use client"
import { Box } from "@mui/material"
import React, { useState } from "react"
import { useTranslation } from "react-i18next"
import Input from "@atoms/Input"
const PluEntry: React.FC = () => {
const [plu, setPlu] = useState("")
const { t } = useTranslation()
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPlu(e.target.value)
}
return (
<Box sx={{ p: 1, backgroundColor: "#f5f5f5", borderRadius: 2 }}>
<Input
type="text"
value={plu}
onChange={handleInputChange}
placeholder={t("lbl_enter_PLU")}
autocomplete="off"
/>
</Box>
)
}
export default PluEntry

View file

@ -1,13 +0,0 @@
"use client"
import { Box, Typography } from "@mui/material"
import React from "react"
const ProductMatch: React.FC = () => {
return (
<Box sx={{ p: 2, backgroundColor: "#f5f5f5", borderRadius: 1 }}>
<Typography variant="h6">Coincidencia de productos:</Typography> {/* TODO: Aquí irán los productos que coincidan con el PLU */}
</Box>
)
}
export default ProductMatch

View file

@ -0,0 +1,28 @@
"use client";
import { TableCell, TableRow } from '@mui/material';
import React from 'react';
interface ProductRowProps {
amount: number;
name: string;
unitValue: number;
tax: number;
discount: number;
total: number;
}
const ProductRow: React.FC<ProductRowProps> = ({ amount, name, unitValue, tax, discount, total }) => {
return (
<TableRow>
<TableCell>{amount}</TableCell>
<TableCell>{name}</TableCell>
<TableCell>${unitValue.toFixed(2)}</TableCell>
<TableCell>${tax.toFixed(2)}</TableCell>
<TableCell>${discount.toFixed(2)}</TableCell>
<TableCell>${total.toFixed(2)}</TableCell>
</TableRow>
);
};
export default ProductRow;

View file

@ -0,0 +1,50 @@
// components/molecules/ProductSearch.tsx
"use client";
import { Box } from '@mui/material';
import Grid from '@mui/material/Grid2';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import Button from '@atoms/Button';
import Input from '@atoms/Input';
interface ProductSearchProps {
onSearch: (plu: string) => void;
}
const ProductSearch: React.FC<ProductSearchProps> = ({ onSearch }) => {
const [plu, setPlu] = useState('');
const { t } = useTranslation()
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setPlu(e.target.value);
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
onSearch(plu);
}
};
return (
<Box sx={{ p:1, mb: 1, boxShadow: '4' }}>
<Grid container spacing={3} alignItems="center">
<Grid size={{xs:8}}>
<Input
type="text"
value={plu}
placeholder={t("msj_enter_plu")}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
/>
</Grid>
<Grid size={{xs:4}}>
<Button label={t("lbl_search")} variant="primary" onClick={() => onSearch(plu)} />
</Grid>
</Grid>
</Box>
);
};
export default ProductSearch;

View file

@ -0,0 +1,92 @@
"use client";
import { Box, Table, TableBody, TableCell, TableHead, TableRow, Typography } from '@mui/material';
import Grid from '@mui/material/Grid2';
import React from 'react';
import { useTranslation } from 'react-i18next';
interface SaleSummaryProps {
subtotal: number;
discount: number;
tax: number;
total: number;
}
const SaleSummary: React.FC<SaleSummaryProps> = ({ subtotal, discount, tax, total }) => {
const { t } = useTranslation()
return (
<Box sx={{
color: 'black',
borderRadius: '5px',
boxShadow: '2',
p: 1,
mb: 1
}}>
<Box sx={{mb: 1, p: 1, boxShadow: '2', }}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell sx={{ color: 'primary', borderColor: 'black', fontWeight: 'bold', width: '30%' }}>{t("tle_product")}</TableCell>
<TableCell sx={{ color: 'primary', borderColor: 'black', fontWeight: 'bold', width: '50%' }}>{t("tle_description")}</TableCell>
<TableCell sx={{ color: 'primary', borderColor: 'black', fontWeight: 'bold', width: '20%', textAlign: 'right' }}>{t("tle_amount")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell sx={{ color: 'black', borderColor: 'black' }}>Product R</TableCell>
<TableCell sx={{ color: 'black', borderColor: 'black' }}>Producto para r uso</TableCell>
<TableCell sx={{ color: 'black', borderColor: 'black', textAlign: 'right' }}>3</TableCell>
</TableRow>
</TableBody>
</Table>
<Grid container justifyContent='right'>
<Box sx={{ mt: 5, textAlign: 'right' }}>
<Grid container>
<Grid size={{xs:7}} sx={{ pr: 10 }}>
<Typography variant="body2" align="right">{t("lbl_subtotal")}:</Typography>
</Grid>
<Grid size={{xs:5}}>
<Typography variant="body2" align="left">$ 1.400</Typography>
</Grid>
</Grid>
<Grid container>
<Grid size={{xs:7}} sx={{ pr: 10 }}>
<Typography variant="body2" align="right">{t("lbl_discount")}:</Typography>
</Grid>
<Grid size={{xs:5}}>
<Typography variant="body2" align="left">$ 12</Typography>
</Grid>
</Grid>
<Grid container>
<Grid size={{xs:7}} sx={{ pr: 5.5 }}>
<Typography variant="body2" align="right">{t("lbl_tax")}:</Typography>
</Grid>
<Grid size={{xs:5}}>
<Typography variant="body2" align="left">$ 123</Typography>
</Grid>
</Grid>
<Grid container>
<Grid size={{xs:7}} sx={{ pr: 5.5 }}>
<Typography variant="body2" align="right">{t("lbl_total")}:</Typography>
</Grid>
<Grid size={{xs:5}}>
<Typography variant="body2" align="left">$ 1.511</Typography>
</Grid>
</Grid>
</Box>
</Grid>
</Box>
<Box sx={{ p: 3, boxShadow: '2' }}>
<Typography variant="h6" sx={{ color: 'primary', display: 'flex', justifyContent: 'space-between' }}>
<span>{t("tle_total")}:</span>
<span>$ 12.250</span>
</Typography>
</Box>
</Box>
);
};
export default SaleSummary;

View file

@ -1,15 +0,0 @@
"use client"
import { Box, Typography } from "@mui/material"
import React from "react"
const Screen: React.FC = () => {
return (
<Box sx={{ p: 2, backgroundColor: "#f5f5f5", borderRadius: 1, textAlign: "center" }}>{/* TODO: Logica para valores */}
<Typography variant="h6">Item Subtotal: $0.00</Typography>
<Typography variant="body1">Total Savings: $0.00</Typography>
<Typography variant="body1">Tax: $0.00</Typography>
</Box>
)
}
export default Screen

View file

@ -0,0 +1,46 @@
"use client";
import { Box } from '@mui/material';
import Grid2 from '@mui/material/Grid2';
import Typography from '@mui/material/Typography';
import { useAtom } from 'jotai';
import React from 'react';
import { useTranslation } from 'react-i18next';
import UserAtom from '@atoms/states/UserAtom';
const UserHeader: React.FC = () => {
const [user] = useAtom(UserAtom);
const { t } = useTranslation()
return (
<Box sx={{mb: 1, boxShadow: '4', }}>
<Grid2
container
justifyContent="space-between"
alignItems="center"
className="bg-blue-600 text-white p-4"
>
<Grid2>
<Typography variant="h6" className="font-bold">
{user ? `${t("lbl_name_customer")}: ${user.name} ${user.lastName}` : `${t("lbl_name_customer")}: Anónimo`}
</Typography>
</Grid2>
<Grid2>
<Typography variant="body2" color="textSecondary" className="text-white">
{user ? `${t("lbl_dni_customer")}: ${user.idTypeUser}` : `${t("lbl_dni_customer")}: 222222222222`}
</Typography>
</Grid2>
<Grid2>
<Typography variant="body2" className="text-white">
{user ? `${t("lbl_email_customer")}: ${user.email}` : `${t("lbl_email_customer")}: generic@example.com`}
</Typography>
</Grid2>
</Grid2>
</Box>
);
};
export default UserHeader;