add new request and add .example

This commit is contained in:
2025-09-17 16:47:19 -06:00
parent ba72417477
commit d0a3a9c365
10 changed files with 304 additions and 189 deletions
+1
View File
@@ -0,0 +1 @@
NEXT_PUBLIC_API_URL=
+75 -56
View File
@@ -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
+1 -1
View File
@@ -35,7 +35,7 @@ export default function Page() {
label: "Por recibo",
content: (
<>
<SearchDateBetween />
<SearchDateBetween />
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
+129 -102
View File
@@ -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
+6 -1
View File
@@ -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();
}}
>
+39 -29
View File
@@ -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;
+15
View File
@@ -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 };
}
}
+18
View File
@@ -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 };
}
}
+18
View File
@@ -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",
+2
View File
@@ -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",