Automate MATPEL I certificate
This commit is contained in:
parent
6ff5fddee6
commit
2938dd4dce
251
docx/main.ts
251
docx/main.ts
@ -7,8 +7,10 @@ import {
|
|||||||
HorizontalPositionAlign,
|
HorizontalPositionAlign,
|
||||||
VerticalPositionAlign,
|
VerticalPositionAlign,
|
||||||
TextRun,
|
TextRun,
|
||||||
|
AlignmentType,
|
||||||
} from "docx";
|
} from "docx";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
import * as QR from "qrcode";
|
||||||
|
|
||||||
|
|
||||||
function cm(centimeters: number) {
|
function cm(centimeters: number) {
|
||||||
@ -19,6 +21,10 @@ function cmToEmu(cm: number) {
|
|||||||
return Math.round(cm * 360000);
|
return Math.round(cm * 360000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cmText(cm: number) {
|
||||||
|
return Math.round(cm * 567);
|
||||||
|
}
|
||||||
|
|
||||||
type ImgConfig = {
|
type ImgConfig = {
|
||||||
name: string,
|
name: string,
|
||||||
height: number,
|
height: number,
|
||||||
@ -64,6 +70,7 @@ const imgFondoDoc = new ImageRun({
|
|||||||
relative: VerticalPositionRelativeFrom.TOP_MARGIN,
|
relative: VerticalPositionRelativeFrom.TOP_MARGIN,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
},
|
},
|
||||||
|
behindDocument: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -261,11 +268,11 @@ const imgEATE = new ImageRun({
|
|||||||
const certificateName = new Paragraph({
|
const certificateName = new Paragraph({
|
||||||
frame: {
|
frame: {
|
||||||
position: {
|
position: {
|
||||||
x: cmToEmu(3.13),
|
x: cmText(3.13),
|
||||||
y: cmToEmu(1.39),
|
y: cmText(1.9),
|
||||||
},
|
},
|
||||||
width: cm(14.28) * 5,
|
width: cmText(14.28),
|
||||||
height: cm(3.19) * 5,
|
height: cmText(3.19),
|
||||||
anchor: {
|
anchor: {
|
||||||
horizontal: FrameAnchorType.MARGIN,
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
vertical: FrameAnchorType.MARGIN,
|
vertical: FrameAnchorType.MARGIN,
|
||||||
@ -277,13 +284,236 @@ const certificateName = new Paragraph({
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "sample text",
|
text: "CAPACITACIÓN EN MANEJO; MANIPULACIÓN Y TRANSPORTE DE MATERIALES Y RESIDUOS PELIGROSOS - MATPEL I - Advertencia".toUpperCase(),
|
||||||
bold: true,
|
bold: true,
|
||||||
font: "Arial",
|
font: "Arial",
|
||||||
|
size: 32,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const certificatePersonName = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(0),
|
||||||
|
y: cmText(6.5),
|
||||||
|
},
|
||||||
|
width: cmText(23),
|
||||||
|
height: cmText(1.5),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "fernando enrique araoz morales".toUpperCase(),
|
||||||
|
bold: true,
|
||||||
|
font: "Arial",
|
||||||
|
allCaps: true,
|
||||||
|
size: 48,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
|
// "Se expide el presente certificado a:"
|
||||||
|
const certificateExpedite = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(2.85),
|
||||||
|
y: cmText(5.15),
|
||||||
|
},
|
||||||
|
width: cmText(14.28),
|
||||||
|
height: cmText(1),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Se expide el presente certificado a:",
|
||||||
|
font: "Arial",
|
||||||
|
size: 22,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
|
// N° XXXX-202X-EEG
|
||||||
|
const certificateCode = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(17.1),
|
||||||
|
y: cmText(5.35),
|
||||||
|
},
|
||||||
|
width: cmText(3.68),
|
||||||
|
height: cmText(0.7),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "N° 0524-2023-EEG",
|
||||||
|
font: "Arial",
|
||||||
|
size: 20,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Identificado con dni ...
|
||||||
|
const certificateBody = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(1.51),
|
||||||
|
y: cmText(8.35),
|
||||||
|
},
|
||||||
|
width: cmText(20.08),
|
||||||
|
height: cmText(3.7),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Identificado con DNI N° ",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "74059695",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: ", al haber aprobado el curso de capacitación sobre ",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "MANEJO DE MATERIALES Y RESIDUOS PELIGROSOS - MATPEL I - Advertencia",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: ", según lo estipulado en la Ley N°28256 (ley que regula el Transporte de Materiales y Residuos Peligrosos) y Decreto Supremo N° 021-2008-MTC (Reglamento Nacional de Transporte Terrestre de Materiales y Residuos Peligrosos) con una duración de 12 horas lectivas.\n",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.JUSTIFIED,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Se expide certificado...
|
||||||
|
const certificateFinishLabel = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(1.52),
|
||||||
|
y: cmText(11.25),
|
||||||
|
},
|
||||||
|
width: cmText(20.1),
|
||||||
|
height: cmText(0.8),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Se expide certificado para los fines que se estime conveniente.",
|
||||||
|
font: "Arial",
|
||||||
|
size: 24,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fecha de Emision: ...
|
||||||
|
const certificateDate = new Paragraph({
|
||||||
|
frame: {
|
||||||
|
position: {
|
||||||
|
x: cmText(16),
|
||||||
|
y: cmText(16.5),
|
||||||
|
},
|
||||||
|
width: cmText(9),
|
||||||
|
height: cmText(1.4),
|
||||||
|
anchor: {
|
||||||
|
horizontal: FrameAnchorType.MARGIN,
|
||||||
|
vertical: FrameAnchorType.MARGIN,
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
x: HorizontalPositionAlign.CENTER,
|
||||||
|
y: VerticalPositionAlign.TOP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Fecha de Emisión:\t\t{fecha_emision}",
|
||||||
|
font: "Arial",
|
||||||
|
size: 20,
|
||||||
|
break: 1,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "Fecha de Expiración:\t\t{fecha_expiracion}",
|
||||||
|
font: "Arial",
|
||||||
|
size: 20,
|
||||||
|
break: 1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.LEFT,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function create() {
|
||||||
|
const qr = await QR.toDataURL(/* join(__dirname, "img", "qr.png"), */ `https://www.eegsac.com/alumnoscertificados.php?DNI=${"74059695"}`, {margin: 1});
|
||||||
|
|
||||||
|
const imgQR = new ImageRun({
|
||||||
|
data: qr, // fs.readFileSync(join(__dirname, "img", "qr.png")),
|
||||||
|
transformation: {
|
||||||
|
height: cm(2.47),
|
||||||
|
width: cm(2.47),
|
||||||
|
},
|
||||||
|
floating: {
|
||||||
|
zIndex: 1,
|
||||||
|
horizontalPosition: {
|
||||||
|
relative: HorizontalPositionRelativeFrom.LEFT_MARGIN,
|
||||||
|
offset: cmToEmu(26.3),
|
||||||
|
},
|
||||||
|
verticalPosition: {
|
||||||
|
relative: VerticalPositionRelativeFrom.TOP_MARGIN,
|
||||||
|
offset: cmToEmu(16.48),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -297,6 +527,12 @@ const doc = new Document({
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
certificateName,
|
certificateName,
|
||||||
|
certificatePersonName,
|
||||||
|
certificateExpedite,
|
||||||
|
certificateCode,
|
||||||
|
certificateBody,
|
||||||
|
certificateFinishLabel,
|
||||||
|
certificateDate,
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [
|
children: [
|
||||||
imgFondoDoc,
|
imgFondoDoc,
|
||||||
@ -310,6 +546,7 @@ const doc = new Document({
|
|||||||
imgMichigan,
|
imgMichigan,
|
||||||
imgCEEM,
|
imgCEEM,
|
||||||
imgEATE,
|
imgEATE,
|
||||||
|
imgQR,
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -320,4 +557,8 @@ const doc = new Document({
|
|||||||
// Used to export the file into a .docx file
|
// Used to export the file into a .docx file
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
// fs.rmSync(join(__dirname, "temp", "qr.png"));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
create();
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/node": "18.15.11",
|
"@types/node": "18.15.11",
|
||||||
|
"@types/qrcode": "^1.5.0",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
|
@ -72,6 +72,9 @@ devDependencies:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: 18.15.11
|
specifier: 18.15.11
|
||||||
version: 18.15.11
|
version: 18.15.11
|
||||||
|
'@types/qrcode':
|
||||||
|
specifier: ^1.5.0
|
||||||
|
version: 1.5.0
|
||||||
'@types/supertest':
|
'@types/supertest':
|
||||||
specifier: ^2.0.11
|
specifier: ^2.0.11
|
||||||
version: 2.0.12
|
version: 2.0.12
|
||||||
@ -1735,6 +1738,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==}
|
resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/qrcode@1.5.0:
|
||||||
|
resolution: {integrity: sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 18.15.11
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/qs@6.9.7:
|
/@types/qs@6.9.7:
|
||||||
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
|
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -12,7 +12,7 @@ import { SubjectService } from "./controller/subject/subject.service";
|
|||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
|
|
||||||
// Must be done before initializing DB.
|
// Must be done before initializing DB.
|
||||||
dotenv.config();
|
console.log(dotenv.config());
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -8,7 +8,7 @@ export function template(ssr: string): string {
|
|||||||
<title>Registrar certificados - EEGSAC</title>
|
<title>Registrar certificados - EEGSAC</title>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="/static/styles.css" />
|
<link rel="stylesheet" href="/static/styles.css?t=${Date.now()}" />
|
||||||
${generateHydrationScript()}
|
${generateHydrationScript()}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -16,7 +16,7 @@ export function template(ssr: string): string {
|
|||||||
${ssr}
|
${ssr}
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="/static/hydration.js"></script>
|
<script src="/static/hydration.js?t=${Date.now()}"></script>
|
||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { createEffect, createSignal, onMount, Show } from "solid-js";
|
import { createSignal, onMount, Show } from "solid-js";
|
||||||
import type { CursoGIE } from "../../model/CursoGIE/cursoGIE.entity";
|
import type { CursoGIE } from "../../model/CursoGIE/cursoGIE.entity";
|
||||||
import { SearchableSelect } from "./NewRegister/SearchableSelect";
|
import { SearchableSelect } from "./NewRegister/SearchableSelect";
|
||||||
import { JSX } from "solid-js/jsx-runtime";
|
import { JSX } from "solid-js/jsx-runtime";
|
||||||
import { Person } from "src/types/Person";
|
import { Person } from "src/types/Person";
|
||||||
import QR from "qrcode";
|
|
||||||
|
|
||||||
|
|
||||||
type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & {
|
type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & {
|
||||||
@ -19,21 +18,9 @@ export function NewRegister(props: {person: Person | null, onSuccess: () => void
|
|||||||
|
|
||||||
const [selectedSubject, setSelectedSubject] = createSignal<number | null>(null);
|
const [selectedSubject, setSelectedSubject] = createSignal<number | null>(null);
|
||||||
|
|
||||||
const [qrBase64, setQrBase64] = createSignal<string | null>(null);
|
|
||||||
|
|
||||||
// Update QR
|
|
||||||
createEffect(() => {
|
|
||||||
if (props.person !== null) {
|
|
||||||
QR.toDataURL(`https://www.eegsac.com/alumnosceertificados.php?DNI=${props.person.dni}`, (err, res) => {
|
|
||||||
if (err) {
|
|
||||||
console.error("Error creating QR code");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setQrBase64(res);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const datePicker = (
|
const datePicker = (
|
||||||
<input
|
<input
|
||||||
@ -147,9 +134,6 @@ export function NewRegister(props: {person: Person | null, onSuccess: () => void
|
|||||||
disabled={loading()}
|
disabled={loading()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<img src={qrBase64() ?? ""} height="225" width="225" />
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { createSignal, Show } from "solid-js";
|
import { createEffect, createSignal, Show } from "solid-js";
|
||||||
import { JSX } from "solid-js/jsx-runtime";
|
import { JSX } from "solid-js/jsx-runtime";
|
||||||
import { Person } from "../../types/Person";
|
import { Person } from "../../types/Person";
|
||||||
import { RegisterPerson } from "./Search/RegisterPerson";
|
import { RegisterPerson } from "./Search/RegisterPerson";
|
||||||
|
import QR from "qrcode";
|
||||||
|
|
||||||
type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & {
|
type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & {
|
||||||
submitter: HTMLElement;
|
submitter: HTMLElement;
|
||||||
@ -16,6 +17,21 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
const [loading, setLoading] = createSignal(false);
|
const [loading, setLoading] = createSignal(false);
|
||||||
const [error, setError] = createSignal("");
|
const [error, setError] = createSignal("");
|
||||||
const [warning, setWarning] = createSignal("");
|
const [warning, setWarning] = createSignal("");
|
||||||
|
const [qrBase64, setQrBase64] = createSignal<string | null>(null);
|
||||||
|
|
||||||
|
// Update QR
|
||||||
|
createEffect(() => {
|
||||||
|
if (dni() !== "") {
|
||||||
|
QR.toDataURL(`https://www.eegsac.com/alumnoscertificados.php?DNI=${dni()}`, {margin: 1}, (err, res) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Error creating QR code");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setQrBase64(res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the user data from the DB
|
Get the user data from the DB
|
||||||
@ -51,7 +67,8 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="p-4">
|
<div class="p-4 grid" style={{"grid-template-columns": "40rem auto"}}>
|
||||||
|
<div>
|
||||||
<h2 class="my-2 font-bold text-xl">1. Buscar persona</h2>
|
<h2 class="my-2 font-bold text-xl">1. Buscar persona</h2>
|
||||||
<form onSubmit={searchDNI} class="px-4">
|
<form onSubmit={searchDNI} class="px-4">
|
||||||
<label for="search-dni">DNI</label>
|
<label for="search-dni">DNI</label>
|
||||||
@ -105,5 +122,9 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
|
|||||||
<RegisterPerson dni={dni()} onSuccess={search} />
|
<RegisterPerson dni={dni()} onSuccess={search} />
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src={qrBase64() ?? ""} height="225" width="225" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user