feat: init project SelfChckout
This commit is contained in:
parent
765cc0c7cf
commit
9d31ea245c
62 changed files with 8869 additions and 7149 deletions
28
app/account/controller/AuthController.tsx
Normal file
28
app/account/controller/AuthController.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { BASE_URL_AUTHENTICATION } from "@package/config/ApiPath"
|
||||
import { FetchData } from "@package/config/FetchData"
|
||||
|
||||
async function auth(ae_user: string, ae_password: string): Promise<string> {
|
||||
const options: RequestInit = {
|
||||
method: "POST",
|
||||
// mode: 'cors',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: ae_user,
|
||||
password: ae_password,
|
||||
}),
|
||||
}
|
||||
|
||||
const data = await FetchData<{ token: string }>(BASE_URL_AUTHENTICATION, "login", options)
|
||||
|
||||
console.log(data)
|
||||
if (data.correct) {
|
||||
return data.object.token
|
||||
} else {
|
||||
console.error("Error en la autenticación:", data.message)
|
||||
return "error en la autenticación"
|
||||
}
|
||||
}
|
||||
|
||||
export { auth }
|
||||
26
app/account/login/page.tsx
Normal file
26
app/account/login/page.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"use client"
|
||||
import LoginForm from "@organisms/LoginForm"
|
||||
import React from "react"
|
||||
|
||||
const LoginPage: React.FC = () => {
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-blue-900 to-blue-700">
|
||||
<div className="w-full max-w-md rounded-lg bg-white p-10 shadow-lg">
|
||||
<h2 className="mb-8 text-center text-4xl font-bold text-blue-900">Iniciar Sesión</h2>
|
||||
|
||||
<LoginForm />
|
||||
|
||||
<div className="mt-4 text-center">
|
||||
<button
|
||||
onClick={() => alert("Recuperación de contraseña")} //TODO: Implement password recovery
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
¿Olvidaste tu contraseña?
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoginPage
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
export async function GET() {
|
||||
return Response.json({ status: "ok" })
|
||||
return new Response(JSON.stringify({ status: "ok" }), {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
}
|
||||
|
|
|
|||
14
app/home/page.tsx
Normal file
14
app/home/page.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import CheckoutScreen from "@app/selfcheckout/CheckoutScreen"
|
||||
import LoyaltyProgramScreen from "@app/selfcheckout/LoyaltyProgramScreen"
|
||||
import PreCheckoutScreen from "@app/selfcheckout/PreCheckoutScreen"
|
||||
import React from "react"
|
||||
|
||||
const HomeAfterLogin: React.FC = () => {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 p-6">
|
||||
<LoyaltyProgramScreen />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HomeAfterLogin
|
||||
|
|
@ -1,9 +1,15 @@
|
|||
import "styles/tailwind.css"
|
||||
import "@package/styles/tailwind.css";
|
||||
import Navbar from "@organisms/Navbar";
|
||||
import React from "react";
|
||||
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
<body>
|
||||
<Navbar />
|
||||
<main>{children}</main>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
121
app/page.tsx
121
app/page.tsx
|
|
@ -1,65 +1,68 @@
|
|||
import { Metadata } from "next"
|
||||
import { Button } from "components/Button/Button"
|
||||
import { LP_GRID_ITEMS } from "lp-items"
|
||||
"use client"
|
||||
import Grid from "@mui/material/Grid2"
|
||||
import Image from "next/image"
|
||||
import { useRouter } from "next/navigation"
|
||||
import Button from "@package/components/atoms/Button"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Next.js Enterprise Boilerplate",
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
},
|
||||
openGraph: {
|
||||
url: "https://next-enterprise.vercel.app/",
|
||||
images: [
|
||||
{
|
||||
width: 1200,
|
||||
height: 630,
|
||||
url: "https://raw.githubusercontent.com/Blazity/next-enterprise/main/.github/assets/project-logo.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
const HomePage: React.FC = () => {
|
||||
const router = useRouter()
|
||||
|
||||
const handleLoginClick = () => {
|
||||
router.push("/account/login")
|
||||
}
|
||||
|
||||
const handleFeaturesClick = () => {
|
||||
router.push("/features")
|
||||
}
|
||||
|
||||
export default function Web() {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-white dark:bg-gray-900">
|
||||
<div className="mx-auto grid max-w-screen-xl px-4 py-8 text-center lg:py-16">
|
||||
<div className="mx-auto place-self-center">
|
||||
<h1 className="mb-4 max-w-2xl text-4xl font-extrabold leading-none tracking-tight dark:text-white md:text-5xl xl:text-6xl">
|
||||
Next.js Enterprise Boilerplate
|
||||
</h1>
|
||||
<p className="mb-6 max-w-2xl font-light text-gray-500 dark:text-gray-400 md:text-lg lg:mb-8 lg:text-xl">
|
||||
Jumpstart your enterprise project with our feature-packed, high-performance Next.js boilerplate!
|
||||
Experience rapid UI development, AI-powered code reviews, and an extensive suite of tools for a smooth and
|
||||
enjoyable development process.
|
||||
</p>
|
||||
<Button href="https://github.com/Blazity/next-enterprise" className="mr-3">
|
||||
Get started
|
||||
</Button>
|
||||
<Grid
|
||||
container
|
||||
className="min-h-screen"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
sx={{
|
||||
background: "linear-gradient(to right, black, #2c3e50, #0064dc)",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<Grid size={{ xs: 12, md: 6 }} display="flex" justifyContent={{ xs: "center", md: "flex-end" }}>
|
||||
<Image
|
||||
src="/img/selfcheckout.jpg"
|
||||
alt="Checkout"
|
||||
width={500}
|
||||
height={400}
|
||||
style={{ width: 'auto', height: 'auto' }}
|
||||
className="rounded-lg shadow-lg"
|
||||
priority
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, md: 6 }} textAlign={{ xs: "center", md: "left" }} padding={{ md: "0 24px" }}>
|
||||
<h1 className="mb-4 text-5xl font-bold text-white md:text-6xl">SELF CHECKOUT</h1>
|
||||
|
||||
<p className="mb-6 text-xl text-gray-200 md:text-2xl">Mejorando la experiencia en tienda</p>
|
||||
|
||||
<Grid container justifyContent={{ xs: "center", md: "flex-start" }} spacing={2}>
|
||||
<Grid size={{ xs: 6, md: 6 }}>
|
||||
<Button
|
||||
href="https://vercel.com/new/git/external?repository-url=https://github.com/Blazity/next-enterprise"
|
||||
intent="secondary"
|
||||
>
|
||||
Deploy Now
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="bg-white dark:bg-gray-900">
|
||||
<div className="mx-auto max-w-screen-xl px-4 py-8 sm:py-16 lg:px-6">
|
||||
<div className="justify-center space-y-8 md:grid md:grid-cols-2 md:gap-12 md:space-y-0 lg:grid-cols-3">
|
||||
{LP_GRID_ITEMS.map((singleItem) => (
|
||||
<div key={singleItem.title} className="flex flex-col items-center justify-center text-center">
|
||||
<div className="mb-4 flex h-10 w-10 items-center justify-center rounded-full bg-primary-100 p-1.5 text-blue-700 dark:bg-primary-900 lg:h-12 lg:w-12">
|
||||
{singleItem.icon}
|
||||
</div>
|
||||
<h3 className="mb-2 text-xl font-bold dark:text-white">{singleItem.title}</h3>
|
||||
<p className="text-gray-500 dark:text-gray-400">{singleItem.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
label="Iniciar Sesión"
|
||||
onClick={handleLoginClick}
|
||||
className="rounded-lg bg-blue-600 px-6 py-3 text-lg text-white transition hover:bg-blue-700"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 6, md: 6 }}>
|
||||
<Button
|
||||
label="Ver Funcionalidades"
|
||||
onClick={handleFeaturesClick}
|
||||
className="rounded-lg bg-gray-200 px-6 py-3 text-lg text-blue-600 transition hover:bg-gray-300"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default HomePage
|
||||
|
|
|
|||
34
app/selfcheckout/CheckoutScreen.tsx
Normal file
34
app/selfcheckout/CheckoutScreen.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
"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
|
||||
99
app/selfcheckout/LoyaltyProgramScreen.tsx
Normal file
99
app/selfcheckout/LoyaltyProgramScreen.tsx
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
"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
|
||||
36
app/selfcheckout/PreCheckoutScreen.tsx
Normal file
36
app/selfcheckout/PreCheckoutScreen.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"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
|
||||
Loading…
Add table
Add a link
Reference in a new issue