Ref: modification components in selfcheckout
This commit is contained in:
parent
251a6a2a6a
commit
ab7a02bcca
40 changed files with 1315 additions and 557 deletions
|
|
@ -1,34 +0,0 @@
|
|||
"use client"
|
||||
import { Box, Container } from "@mui/material"
|
||||
import Grid from "@mui/material/Grid2" // Usando Grid2
|
||||
import ButtonPanel from "@organisms/ButtonPanel"
|
||||
import Header from "@organisms/Header"
|
||||
import MainPanel from "@organisms/MainPanel"
|
||||
import ProductList from "@organisms/ProductList"
|
||||
import React from "react"
|
||||
|
||||
const CheckoutScreen: React.FC = () => {
|
||||
return (
|
||||
<Container maxWidth="xl" sx={{ minHeight: "100vh", bgcolor: "background.default", padding: 0 }}>
|
||||
<Header sx={{ minHeight: "64px", marginBottom: 1 }} />
|
||||
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Grid container spacing={2} alignItems="stretch" sx={{ height: "calc(100vh - 64px)" }}>
|
||||
<Grid size={{ xs: 12, md: 4 }} sx={{ height: "100%" }}>
|
||||
<ProductList />
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 4 }} sx={{ height: "100%" }}>
|
||||
<ButtonPanel />
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 4 }} sx={{ height: "100%" }}>
|
||||
<MainPanel />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default CheckoutScreen
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
"use client"
|
||||
import CheckoutScreen from "@app/selfcheckout/CheckoutScreen"
|
||||
import AskForAffiliation from "@layouts/AskForAffiliation"
|
||||
import IdentityDocumentNumber from "@layouts/IdentityDocumentNumber"
|
||||
import TypeIdentityDocument from "@layouts/TypeIdentityDocument"
|
||||
import { Box, Card, CardContent, Container } from "@mui/material"
|
||||
import Grid from "@mui/material/Grid2"
|
||||
import Header from "@organisms/Header"
|
||||
import { getDocumentsByCountry } from "@package/utils/getDocumentsByCountry"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
const LoyaltyProgramScreen: React.FC = () => {
|
||||
const [isAffiliated, setIsAffiliated] = useState<boolean | null>(null)
|
||||
const [documentType, setDocumentType] = useState<string | null>(null)
|
||||
const [documentNumber, setDocumentNumber] = useState<string | null>(null)
|
||||
const [goToCheckout, setGoToCheckout] = useState<boolean>(false)
|
||||
const [countryDocumentTypes, setCountryDocumentTypes] = useState<string[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const documents = getDocumentsByCountry()
|
||||
setCountryDocumentTypes(documents)
|
||||
}, [])
|
||||
|
||||
const handleAffiliationSelect = (isAffiliated: boolean) => {
|
||||
setIsAffiliated(isAffiliated)
|
||||
if (!isAffiliated) {
|
||||
setDocumentType("13")
|
||||
setDocumentNumber("222222222222")
|
||||
setGoToCheckout(true)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDocumentSelect = (selectedDocumentType: string) => {
|
||||
setDocumentType(selectedDocumentType)
|
||||
}
|
||||
|
||||
const handleDocumentNumberSubmit = (enteredDocumentNumber: string) => {
|
||||
setDocumentNumber(enteredDocumentNumber)
|
||||
setGoToCheckout(true)
|
||||
}
|
||||
|
||||
if (goToCheckout) {
|
||||
return <CheckoutScreen />
|
||||
}
|
||||
|
||||
return (
|
||||
<Container
|
||||
maxWidth={false}
|
||||
sx={{
|
||||
height: "100hv",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<Card sx={{ width: "100%", p: 2 }}>
|
||||
<Header sx={{ minHeight: "32px", marginBottom: 1 }} />
|
||||
|
||||
<CardContent sx={{ padding: "4px", height: "100%" }}>
|
||||
<Grid container spacing={2} sx={{ height: "100%" }} alignItems="center">
|
||||
<Grid size={{ xs: 12, md: 6 }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
bgcolor: "#f5f5f5",
|
||||
p: 5,
|
||||
borderRadius: 5,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="img"
|
||||
src="/img/logo.png"
|
||||
alt="Rhiscom Logo"
|
||||
sx={{ width: "600px", height: "auto", mb: 15 }}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, md: 6 }}>
|
||||
{isAffiliated === null && <AskForAffiliation onAffiliationSelect={handleAffiliationSelect} />}
|
||||
{isAffiliated && !documentType && (
|
||||
<TypeIdentityDocument typesDocument={countryDocumentTypes} onDocumentSelect={handleDocumentSelect} />
|
||||
)}
|
||||
{isAffiliated && documentType && (
|
||||
<IdentityDocumentNumber documentType={documentType} onSubmit={handleDocumentNumberSubmit} />
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoyaltyProgramScreen
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
"use client"
|
||||
import Title from "@atoms/Title"
|
||||
import { Tooltip } from "@atoms/Tooltip"
|
||||
import { Box, Button, Container } from "@mui/material"
|
||||
import React from "react"
|
||||
|
||||
const PreCheckoutScreen: React.FC = () => {
|
||||
const handleStartCheckout = () => {
|
||||
console.log("Comenzar checkout")
|
||||
}
|
||||
|
||||
return (
|
||||
<Container maxWidth="md" sx={{ textAlign: "center", marginTop: "20vh" }}>
|
||||
<Box sx={{ backgroundColor: "#f1f1f1", padding: "40px", borderRadius: "8px", boxShadow: 3 }}>
|
||||
<Title text="Esta caja está" size="h4" />
|
||||
<Title text="Abierta" size="h2" />
|
||||
|
||||
<Tooltip explainer="Escanee un producto o pulse el botón para comenzar" withArrow side="top">
|
||||
<Title text="Escanee un producto o pulse aquí para comenzar" size="h6" />
|
||||
</Tooltip>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="success"
|
||||
size="large"
|
||||
sx={{ marginTop: "40px" }}
|
||||
onClick={handleStartCheckout}
|
||||
>
|
||||
Comenzar
|
||||
</Button>
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default PreCheckoutScreen
|
||||
22
app/selfcheckout/checkout/page.tsx
Normal file
22
app/selfcheckout/checkout/page.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"use client";
|
||||
import { Box } from "@mui/material";
|
||||
import React from "react";
|
||||
import MainLayout from "@layouts/MainLayout";
|
||||
|
||||
const CheckoutScreen: React.FC = () => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
overflow: 'hidden',
|
||||
bgcolor: "background.default",
|
||||
boxShadow: '4'
|
||||
}}
|
||||
>
|
||||
<MainLayout />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckoutScreen;
|
||||
242
app/selfcheckout/clientSearch/page.tsx
Normal file
242
app/selfcheckout/clientSearch/page.tsx
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
'use client';
|
||||
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Paper, Typography } from '@mui/material';
|
||||
import Grid from '@mui/material/Grid2';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Button from '@atoms/Button';
|
||||
import CustomLoading from '@atoms/CustomLoading';
|
||||
import Icon from '@atoms/Icon';
|
||||
import Input from '@atoms/Input';
|
||||
import Label from '@atoms/Label';
|
||||
import CustomerAtom from '@atoms/states/CustomerAtom';
|
||||
import Title from '@atoms/Title';
|
||||
import { Tooltip } from '@atoms/Tooltip';
|
||||
import { useClientSearchLogic } from '@hooks/useClientSearchLogic';
|
||||
import { CustomerDniTypeInterface } from '@interfaces/ResponseInterfaces/Customer/DNITypeResponseInterface';
|
||||
|
||||
const ClientSearch: React.FC = () => {
|
||||
const {
|
||||
idTypes,
|
||||
loading,
|
||||
error,
|
||||
result,
|
||||
formData,
|
||||
handleInputChange,
|
||||
handleSubmitForm,
|
||||
isAffiliated,
|
||||
} = useClientSearchLogic();
|
||||
const { t } = useTranslation();
|
||||
const [openDialog, setOpenDialog] = useState(false);
|
||||
const setCustomer = useSetAtom(CustomerAtom);
|
||||
const router = useRouter();
|
||||
|
||||
const handleOpenDialog = () => {
|
||||
setOpenDialog(true);
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
setOpenDialog(false);
|
||||
};
|
||||
|
||||
const handleUseGenericCustomer = () => {
|
||||
setCustomer({
|
||||
id: '',
|
||||
idCompany: 'default-company',
|
||||
companyName: 'default-company-name',
|
||||
idSubsidiary: 0,
|
||||
nameSubsidiary: 'default-subsidiary',
|
||||
externalClientId: null,
|
||||
name: 'Cliente',
|
||||
secondName: '',
|
||||
firstSurname: 'Generico',
|
||||
secondSurname: '',
|
||||
idTypeCustomer: 'Tarjeta de identidad',
|
||||
nameTypeCustomer: 'Tarjeta',
|
||||
dni: '222222222222',
|
||||
idGender: '',
|
||||
nameGender: '',
|
||||
idMaritalStatus: null,
|
||||
nameMaritalStatus: null,
|
||||
address: '',
|
||||
idCity: null,
|
||||
nameCity: null,
|
||||
idCountry: null,
|
||||
nameCountry: null,
|
||||
mail: '',
|
||||
phone: '',
|
||||
idUser: '',
|
||||
nameUser: '',
|
||||
status: true,
|
||||
birthdate: null,
|
||||
group: [],
|
||||
NameSurname: '',
|
||||
SurnameName: ''
|
||||
});
|
||||
|
||||
router.push("/selfcheckout/checkout");
|
||||
};
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault(); // Evita el comportamiento por defecto del formulario
|
||||
handleSubmitForm(); // Ejecuta la función de búsqueda con los datos actuales
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper elevation={3} className="p-6 max-w-2xl mx-auto">
|
||||
<Title text={t("lbl_client_search")} size="h2" />
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4 mt-4">
|
||||
<Grid container spacing={2}>
|
||||
<Grid size={{ xs: 12, sm: 6 }}>
|
||||
<Label htmlFor="idType" text={t("lbl_id_type")} />
|
||||
<select
|
||||
name="idType"
|
||||
value={formData.idType}
|
||||
onChange={handleInputChange} // Asegura que el estado del input cambie
|
||||
className="w-full p-2 border rounded"
|
||||
disabled={loading}
|
||||
>
|
||||
<option value="">{t("lbl_selectid_type")}</option>
|
||||
{idTypes.length > 0 ? (
|
||||
idTypes.map((type: CustomerDniTypeInterface) => (
|
||||
<option key={type.id} value={type.id}>
|
||||
{type.name}
|
||||
</option>
|
||||
))
|
||||
) : (
|
||||
<option disabled>{t("msj_loading_id_types")}</option>
|
||||
)}
|
||||
</select>
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<Label htmlFor="idNumber" text={t("lbl_id_number")} />
|
||||
<Input
|
||||
type="text"
|
||||
name="idNumber"
|
||||
placeholder={t("msj_enter_id_number")}
|
||||
value={formData.idNumber}
|
||||
onChange={handleInputChange} // Actualiza el valor del input al escribir
|
||||
disabled={loading}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Tooltip explainer={t("mjs_search_for_client")} withArrow>
|
||||
<Button
|
||||
label={t("lbl_search")}
|
||||
variant="primary"
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
startIcon={<Icon name="Search" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{loading && (
|
||||
<div className="flex justify-center mt-4">
|
||||
<CustomLoading />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<Typography color="error" className="mt-4">
|
||||
{error}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{result.length === 0 && !isAffiliated && (
|
||||
<Paper elevation={2} className="mt-6 p-4">
|
||||
<Title text={t("msj_no_affiliate")} size="h3" />
|
||||
<Typography variant="body1" className="mt-2">
|
||||
{t("msj_choose_option_for_non_affiliate")}
|
||||
</Typography>
|
||||
<div className="flex justify-center gap-4 mt-4">
|
||||
<Button
|
||||
label={t("lbl_use_generic_customer")}
|
||||
variant="primary"
|
||||
onClick={handleOpenDialog}
|
||||
/>
|
||||
<Button
|
||||
label={t("lbl_create_new_customer")}
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
// Lógica para crear nuevo cliente
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Paper>
|
||||
)}
|
||||
|
||||
{result.length > 0 && (
|
||||
<Paper elevation={2} className="mt-6 p-4">
|
||||
<Title text={t("lbl_search_result")} size="h3" />
|
||||
{result.map((customer) => (
|
||||
<Grid container spacing={2} className="mt-2" key={customer.id}>
|
||||
<Grid size={{ xs: 6 }}>
|
||||
<Typography variant="body1">
|
||||
<strong>{t("lbl_name")}:</strong> {customer.name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 6 }}>
|
||||
<Typography variant="body1">
|
||||
<strong>{t("lbl_last_name")}:</strong> {customer.firstSurname}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 6 }}>
|
||||
<Typography variant="body1">
|
||||
<strong>{t("lbl_email")}:</strong> {customer.mail}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 6 }}>
|
||||
<Typography variant="body1">
|
||||
<strong>{t("lbl_phone")}:</strong> {customer.phone}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<Typography variant="body1">
|
||||
<strong>{t("lbl_address")}:</strong> {customer.address}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
<div className="flex justify-end mt-4">
|
||||
<Button
|
||||
label={t("lbl_continue")}
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
router.push("/selfcheckout/checkout");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Paper>
|
||||
)}
|
||||
|
||||
<Dialog open={openDialog} onClose={handleCloseDialog} maxWidth="xs" fullWidth>
|
||||
<DialogTitle sx={{ textAlign: 'center' }}>
|
||||
{t("msj_confirm_generic_customer")}
|
||||
</DialogTitle>
|
||||
<DialogContent sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<DialogContentText>
|
||||
{t("msj_are_you_sure_generic_customer")}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ justifyContent: 'center' }}>
|
||||
<Button onClick={handleCloseDialog} label={t("lbl_cancel")} />
|
||||
<Button
|
||||
onClick={handleUseGenericCustomer}
|
||||
label={t("lbl_confirm")}
|
||||
variant="primary"
|
||||
/>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClientSearch;
|
||||
57
app/selfcheckout/precheckout/page.tsx
Normal file
57
app/selfcheckout/precheckout/page.tsx
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"use client";
|
||||
import { Box, Button, Container } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid2";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Title from "@atoms/Title";
|
||||
|
||||
const PreCheckout: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
|
||||
const handleStartCheckout = useCallback(() => {
|
||||
router.push("/selfcheckout/verifyAffiliation");
|
||||
}, [router]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyPress = () => {
|
||||
handleStartCheckout();
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleKeyPress);
|
||||
|
||||
// Cleanup the event listener
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleKeyPress);
|
||||
};
|
||||
}, [handleStartCheckout]);
|
||||
|
||||
return (
|
||||
<Container maxWidth="md" sx={{ textAlign: "center", marginTop: "20vh" }}>
|
||||
<Box sx={{ backgroundColor: "#f1f1f1", padding: "80px", borderRadius: "10px", boxShadow: 6 }}>
|
||||
<Grid size={{ xs: 4, md: 6 }}>
|
||||
<Title text={t("msj_this_box_is")} size="h3" />
|
||||
</Grid>
|
||||
<Grid size={{ xs: 4, md: 6 }}>
|
||||
<Title text={t("lb_open")} size="h1" />
|
||||
</Grid>
|
||||
<Grid size={{ xs: 4, md: 6 }}>
|
||||
<Title text={t("msj_press_any_key_button_start")} size="h5" />
|
||||
</Grid>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="large"
|
||||
sx={{ marginTop: "40px" }}
|
||||
onClick={handleStartCheckout}
|
||||
>
|
||||
{t("lbl_start")}
|
||||
</Button>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default PreCheckout;
|
||||
61
app/selfcheckout/verifyAffiliation/page.tsx
Normal file
61
app/selfcheckout/verifyAffiliation/page.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
"use client";
|
||||
import { Box, Card, CardContent, Container } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid2";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import CustomLoading from "@atoms/CustomLoading";
|
||||
|
||||
const ClientSearch = React.lazy(() => import("@app/selfcheckout/clientSearch/page"));
|
||||
|
||||
const VerifyAffiliation: React.FC = () => {
|
||||
return (
|
||||
<Container
|
||||
maxWidth={false}
|
||||
sx={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<Card sx={{ width: "100%", p: 2 }}>
|
||||
|
||||
<CardContent sx={{ padding: "4px", height: "100%" }}>
|
||||
<Grid container spacing={2} sx={{ height: "100%" }} alignItems="center">
|
||||
<Grid size = {{xs:12, md:6}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
bgcolor: "#f5f5f5",
|
||||
p: 5,
|
||||
borderRadius: 5,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/img/logo.png"
|
||||
alt="Rhiscom Logo"
|
||||
width={600}
|
||||
height={400}
|
||||
priority={true}
|
||||
style={{ marginBottom: 15 }}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid size = {{xs:12, md:6}}>
|
||||
<React.Suspense fallback={<CustomLoading />}>
|
||||
<ClientSearch />
|
||||
</React.Suspense>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default VerifyAffiliation;
|
||||
Loading…
Add table
Add a link
Reference in a new issue