add new request and add .example
This commit is contained in:
@@ -0,0 +1 @@
|
||||
NEXT_PUBLIC_API_URL=
|
||||
@@ -1,24 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import SearchUser from "../../Components/SearchUser/searchUser";
|
||||
import Receipt from "../../Components/Receipt/Receipt";
|
||||
import Impressions from "../../Components/Impressions/impressions";
|
||||
import Toggle from "../../Components/Toggle/Toggle";
|
||||
|
||||
import "@/app/globals.css";
|
||||
import Information from "../../Components/Information/information";
|
||||
|
||||
export default function Page() {
|
||||
import "@/app/globals.css";
|
||||
import { GetStudent } from "@/app/lib/getStudent";
|
||||
|
||||
export default async function Page({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: { numAccount?: number };
|
||||
}) {
|
||||
|
||||
const params = await searchParams;
|
||||
const numAccount = params.numAccount
|
||||
? Number(params.numAccount)
|
||||
: null;
|
||||
|
||||
let student: any = null;
|
||||
if (numAccount) {
|
||||
student = await GetStudent(numAccount);
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="containerSection">
|
||||
<h2 className="title">IMPRESIONES Y PLOTEO</h2>
|
||||
<SearchUser />
|
||||
|
||||
<Information
|
||||
NoCuenta="idcuanta"
|
||||
Nombre="juan"
|
||||
Carrera="carrera"
|
||||
Credito="credito"
|
||||
NoCuenta={student.id_cuenta}
|
||||
Nombre={student.nombre}
|
||||
Carrera={student.id_carrera}
|
||||
Credito={student.credito}
|
||||
/>
|
||||
|
||||
<Toggle
|
||||
@@ -32,68 +46,73 @@ export default function Page() {
|
||||
{
|
||||
key: "2",
|
||||
label: "Impresiones B/N",
|
||||
content: <Impressions
|
||||
costs={[
|
||||
{ value: 1 },
|
||||
{ value: 2 },
|
||||
]}
|
||||
/>,
|
||||
content: (
|
||||
<Impressions
|
||||
costs={[{ value: 1 }, { value: 2 }]}
|
||||
numAccount={student.id_cuenta}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: "Impresiones color",
|
||||
content: <Impressions
|
||||
costs={[
|
||||
{ value: 4 },
|
||||
{ value: 5 },
|
||||
{ value: 6 },
|
||||
{ value: 7 },
|
||||
{ value: 8 },
|
||||
{ value: 10 },
|
||||
{ value: 12 },
|
||||
{ value: 14 },
|
||||
]}
|
||||
/>,
|
||||
content: (
|
||||
<Impressions
|
||||
costs={[
|
||||
{ value: 4 },
|
||||
{ value: 5 },
|
||||
{ value: 6 },
|
||||
{ value: 7 },
|
||||
{ value: 8 },
|
||||
{ value: 10 },
|
||||
{ value: 12 },
|
||||
{ value: 14 },
|
||||
]}
|
||||
numAccount={student.id_cuenta}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "4",
|
||||
label: "Plotter",
|
||||
content: <Impressions
|
||||
costs={[
|
||||
{ value: 15 },
|
||||
{ value: 18 },
|
||||
{ value: 20 },
|
||||
{ value: 25 },
|
||||
{ value: 30 },
|
||||
{ value: 40 },
|
||||
{ value: 45 },
|
||||
{ value: 50 },
|
||||
{ value: 60 },
|
||||
{ value: 70 },
|
||||
{ value: 80 },
|
||||
{ value: 90 },
|
||||
{ value: 100 },
|
||||
{ value: 110 },
|
||||
{ value: 120 },
|
||||
{ value: 150 },
|
||||
{ value: 200 },
|
||||
]}
|
||||
/>,
|
||||
content: (
|
||||
<Impressions
|
||||
costs={[
|
||||
{ value: 15 },
|
||||
{ value: 18 },
|
||||
{ value: 20 },
|
||||
{ value: 25 },
|
||||
{ value: 30 },
|
||||
{ value: 40 },
|
||||
{ value: 45 },
|
||||
{ value: 50 },
|
||||
{ value: 60 },
|
||||
{ value: 70 },
|
||||
{ value: 80 },
|
||||
{ value: 90 },
|
||||
{ value: 100 },
|
||||
{ value: 110 },
|
||||
{ value: 120 },
|
||||
{ value: 150 },
|
||||
{ value: 200 },
|
||||
]}
|
||||
numAccount={student.id_cuenta}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "5",
|
||||
label: "Escaner",
|
||||
content: <Impressions
|
||||
costs={[
|
||||
{ value: 1 },
|
||||
{ value: 2 },
|
||||
{ value: 5 },
|
||||
]}
|
||||
/>,
|
||||
content: (
|
||||
<Impressions
|
||||
costs={[{ value: 1 }, { value: 2 }, { value: 5 }]}
|
||||
numAccount={student.id_cuenta}
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
//IO
|
||||
//IO
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function Page() {
|
||||
label: "Por recibo",
|
||||
content: (
|
||||
<>
|
||||
<SearchDateBetween />
|
||||
<SearchDateBetween />
|
||||
<div className={styles.tableContainer}>
|
||||
<table className={styles.machineTable}>
|
||||
<thead>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import './Impressions.css'
|
||||
import axios from "axios";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Cookies from "js-cookie";
|
||||
import { envConfig } from "@/app/lib/config";
|
||||
import "./Impressions.css";
|
||||
|
||||
interface CostOption {
|
||||
value: number;
|
||||
@@ -9,117 +13,140 @@ interface CostOption {
|
||||
|
||||
interface ImpressionsProps {
|
||||
costs: CostOption[];
|
||||
numAccount: number | null;
|
||||
}
|
||||
function Impressions({ costs }:ImpressionsProps) {
|
||||
const [pages, setPages] = useState("");
|
||||
const [cost, setCost] = useState("");
|
||||
function Impressions({ costs, numAccount }: ImpressionsProps) {
|
||||
const [pages, setPages] = useState("");
|
||||
const [cost, setCost] = useState("");
|
||||
|
||||
const [error, setError] = useState('');
|
||||
const [alert, setAlert] = useState('');
|
||||
const [showError, setShowError] = useState(false);
|
||||
const [showAlert, setShowAlert] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [alert, setAlert] = useState("");
|
||||
const [showError, setShowError] = useState(false);
|
||||
const [showAlert, setShowAlert] = useState(false);
|
||||
|
||||
// const handlePayment = async () => {
|
||||
// setAlert('')
|
||||
// setError('')
|
||||
// if (!studentData) {
|
||||
// setError('Error busca denuevo al estudiante');
|
||||
// return;
|
||||
// }
|
||||
// if (!pages) {
|
||||
// setError('Ingresa el numero de hojas a imprimir')
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// await axios.post(
|
||||
// `${url}/impressions`,
|
||||
// {
|
||||
// numAccount: numAccount,
|
||||
// pages: parseInt(pages),
|
||||
// cost: parseInt(pages),
|
||||
// },
|
||||
// { headers }
|
||||
// );
|
||||
// handleSearch()
|
||||
// setAlert('Cobro realizado correctamente');
|
||||
// setPages('')
|
||||
// } catch (error) {
|
||||
// const errorMessage = error.response?.data?.error || 'No se encontró el estudiante';
|
||||
const router = useRouter();
|
||||
|
||||
// if (errorMessage === 'Token inválido') {
|
||||
// handleLogout();
|
||||
// }
|
||||
const handleLogout = () => {
|
||||
Cookies.remove("token");
|
||||
Cookies.remove("session");
|
||||
router.push("/Login");
|
||||
};
|
||||
|
||||
// setError(errorMessage);
|
||||
// }
|
||||
// };
|
||||
const handlePayment = async () => {
|
||||
setAlert("");
|
||||
setError("");
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
// handlePayment();
|
||||
}}>
|
||||
<div className="gap">
|
||||
if (!numAccount) {
|
||||
setError("Error busca denuevo al estudiante");
|
||||
return;
|
||||
}
|
||||
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Costo:</label>
|
||||
<select
|
||||
value={cost}
|
||||
onChange={(e) => setCost(e.target.value)}
|
||||
>
|
||||
<option value="">-- Selecciona un tiempo --</option>
|
||||
{costs.map((c) => (
|
||||
<option key={c.value} value={c.value}>
|
||||
${c.value}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
if (!pages) {
|
||||
setError("Ingresa el numero de hojas a imprimir");
|
||||
return;
|
||||
}
|
||||
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Hojas:</label>
|
||||
<input
|
||||
type='text'
|
||||
value={pages}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value)) {
|
||||
setPages(value);
|
||||
}
|
||||
}}
|
||||
placeholder='Numero de hojas a imprimir...'
|
||||
inputMode='numeric'
|
||||
pattern='[0-9]*'
|
||||
/>
|
||||
</div>
|
||||
if(!cost){
|
||||
setError("Selecciona un costo")
|
||||
return;
|
||||
}
|
||||
|
||||
<div className='groupLabel'>
|
||||
<label className='label'>Total: {pages && `$${pages}.00`}</label>
|
||||
</div>
|
||||
const token = Cookies.get("token");
|
||||
if (!token) {
|
||||
handleLogout();
|
||||
return;
|
||||
}
|
||||
|
||||
<div className='containerButton'>
|
||||
<button
|
||||
className='button buttonCharge'
|
||||
type='submit'>
|
||||
Cobrar
|
||||
</button>
|
||||
try {
|
||||
await axios.post(
|
||||
`${envConfig.apiUrl}/impressions`,
|
||||
{
|
||||
numAccount: numAccount,
|
||||
pages: parseInt(pages),
|
||||
cost: parseInt(cost) * parseInt(pages),
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
{error &&
|
||||
<div className={`messageBox error ${!showError ? 'hidden' : ''}`}>
|
||||
{error}
|
||||
</div>
|
||||
}
|
||||
{alert &&
|
||||
<div className={`messageBox success ${!showAlert ? 'hidden' : ''}`}>
|
||||
{alert}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
setAlert("Cobro realizado correctamente");
|
||||
setPages("");
|
||||
} catch (error: any) {
|
||||
const errorMessage =
|
||||
error.response?.data?.error || "No se encontró el estudiante";
|
||||
|
||||
if (errorMessage === "Token inválido") {
|
||||
handleLogout();
|
||||
}
|
||||
|
||||
setError(errorMessage);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
handlePayment();
|
||||
}}
|
||||
>
|
||||
<div className="gap">
|
||||
<div className="groupInput">
|
||||
<label className="label">Costo:</label>
|
||||
<select value={cost} onChange={(e) => setCost(e.target.value)}>
|
||||
<option value="">-- Selecciona un tiempo --</option>
|
||||
{costs.map((c) => (
|
||||
<option key={c.value} value={c.value}>
|
||||
${c.value}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="groupInput">
|
||||
<label className="label">Hojas:</label>
|
||||
<input
|
||||
type="text"
|
||||
value={pages}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value)) {
|
||||
setPages(value);
|
||||
}
|
||||
}}
|
||||
placeholder="Numero de hojas a imprimir..."
|
||||
inputMode="numeric"
|
||||
pattern="[0-9]*"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="groupLabel">
|
||||
<label className="label">Total: {pages && `$${pages}.00`}</label>
|
||||
</div>
|
||||
|
||||
<div className="containerButton">
|
||||
<button className="button buttonCharge" type="submit">
|
||||
Cobrar
|
||||
</button>
|
||||
|
||||
{error && (
|
||||
<div className={`messageBox error ${!showError ? "hidden" : ""}`}>
|
||||
{error}
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
)}
|
||||
{alert && (
|
||||
<div className={`messageBox success ${!showAlert ? "hidden" : ""}`}>
|
||||
{alert}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default Impressions
|
||||
//IO
|
||||
export default Impressions;
|
||||
//IO
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
import { useEffect, useState } from "react";
|
||||
import "./Receipt.css"
|
||||
import { PostReceipt } from "@/app/lib/receipt";
|
||||
|
||||
function Receipt() {
|
||||
const [folio, setFolio] = useState('');
|
||||
@@ -46,11 +47,15 @@ function Receipt() {
|
||||
}, [error]);
|
||||
//fadeOut alert and error//
|
||||
|
||||
const handleSaveReceipt = ( )=>{
|
||||
//PostReceipt(data{folio,amount,date})
|
||||
}
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
// handleSaveReceipt();
|
||||
handleSaveReceipt();
|
||||
}}
|
||||
>
|
||||
|
||||
|
||||
@@ -1,34 +1,44 @@
|
||||
'use client'
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
function SearchUser() {
|
||||
const [numAccount, setNumAccount] = useState('');
|
||||
return (
|
||||
<>
|
||||
<form className="containerForm">
|
||||
<label className='label'>No.Cuenta</label>
|
||||
<div className='groupInput'>
|
||||
<input
|
||||
type='text'
|
||||
value={numAccount}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value) && value.length <= 9) {
|
||||
setNumAccount(value);
|
||||
}
|
||||
}}
|
||||
placeholder='Coloca un número de cuenta...'
|
||||
inputMode='numeric'
|
||||
pattern='[0-9]*'
|
||||
/>
|
||||
<button
|
||||
className='button buttonSearch'
|
||||
type='submit'
|
||||
>Buscar
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)
|
||||
const [numAccount, setNumAccount] = useState("");
|
||||
const router = useRouter();
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (numAccount) {
|
||||
router.push(`/Impresiones?numAccount=${numAccount}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<form className="containerForm"
|
||||
onSubmit={handleSubmit}>
|
||||
<label className="label">No.Cuenta</label>
|
||||
<div className="groupInput">
|
||||
<input
|
||||
type="text"
|
||||
value={numAccount}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value) && value.length <= 9) {
|
||||
setNumAccount(value);
|
||||
}
|
||||
}}
|
||||
placeholder="Coloca un número de cuenta..."
|
||||
inputMode="numeric"
|
||||
pattern="[0-9]*"
|
||||
/>
|
||||
<button className="button buttonSearch" type="submit">
|
||||
Buscar
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default SearchUser
|
||||
export default SearchUser;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import axios from "axios";
|
||||
import { envConfig } from "./config";
|
||||
|
||||
export async function GetStudent(numAccount: number) {
|
||||
try {
|
||||
const response = await axios.get(`${envConfig.apiUrl}/student/${numAccount}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const msg =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"Error desconocido al obtener estudiante";
|
||||
return { error: msg };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import axios from "axios";
|
||||
import { envConfig } from "./config";
|
||||
|
||||
export async function PostReceipt(usuario: string, password: string) {
|
||||
try {
|
||||
const response = await axios.post(`${envConfig.apiUrl}/operations`, {
|
||||
usuario,
|
||||
password,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const msg =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"Error desconocido en el guardado del Recibo";
|
||||
return { error: msg };
|
||||
}
|
||||
}
|
||||
Generated
+18
@@ -9,12 +9,14 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"axios": "^1.11.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "^15.5.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-icons": "^5.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
@@ -592,6 +594,13 @@
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/js-cookie": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
|
||||
"integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz",
|
||||
@@ -960,6 +969,15 @@
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/js-cookie": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
|
||||
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.11.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "^15.5.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-icons": "^5.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
||||
Reference in New Issue
Block a user