[FE] Add copy and delete DNI buttons

master
Araozu 2023-06-10 21:31:03 -05:00
parent ac20c9391f
commit 179f948ed5
11 changed files with 107 additions and 36 deletions

View File

@ -6,6 +6,12 @@
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" /> <link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Solid App</title> <title>Solid App</title>
<!-- Phosphor icons -->
<link
rel="stylesheet"
type="text/css"
href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css"
/>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -5,7 +5,11 @@ module.exports = {
"../src/**/*.tsx" "../src/**/*.tsx"
], ],
theme: { theme: {
extend: {}, extend: {
fontFamily: {
"mono": ["Iosevka", "monospace"]
}
},
colors: { colors: {
"c-primary": "var(--c-primary)", "c-primary": "var(--c-primary)",
"c-on-primary": "var(--c-on-primary)", "c-on-primary": "var(--c-on-primary)",
@ -21,8 +25,11 @@ module.exports = {
"c-on-surface": "var(--c-on-surface)", "c-on-surface": "var(--c-on-surface)",
"c-outline": "var(--c-outline)", "c-outline": "var(--c-outline)",
"c-surface-variant": "var(--c-surface-variant)", "c-surface-variant": "var(--c-surface-variant)",
"c-on-surface-variant": "var(--c-on-surface-variant)" "c-on-surface-variant": "var(--c-on-surface-variant)",
} "c-green": "#006b54",
"c-success": "var(--c-success)",
"c-on-success": "var(--c-on-success)",
},
}, },
plugins: [] plugins: []
}; };

View File

@ -18,8 +18,7 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json", "test:e2e": "jest --config ./test/jest-e2e.json",
"ssr": "concurrently \"node esbuild.js\" \"tailwindcss -i static/tailwind.css -o ./static/styles.css --watch\"", "ssr": "concurrently \"node esbuild.js\" \"tailwindcss -i static/tailwind.css -o ./static/styles.css --watch\"",
"tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch", "tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch"
"docx": "tsc docx/main.ts && node docx/main.js"
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^9.0.0", "@nestjs/common": "^9.0.0",

View File

@ -25,7 +25,7 @@ const db = process.env.MY_SQL_DB;
imports: [ imports: [
TypeOrmModule.forRoot({ TypeOrmModule.forRoot({
type: "mysql", type: "mysql",
// To allow remote connections a manual URI is used, for some // To allow remote connections a manual URI is used
url: `mysql://${user}:${password}@${host}:${port}/${db}`, url: `mysql://${user}:${password}@${host}:${port}/${db}`,
// These values are rejected when using a remote connection, for some reason // These values are rejected when using a remote connection, for some reason

View File

@ -43,7 +43,6 @@ export class CertificateController {
@Delete(":id") @Delete(":id")
async delete(@Param() param: { id: number }) { async delete(@Param() param: { id: number }) {
console.log(param);
const result = await this.certificateService.deleteById(param.id); const result = await this.certificateService.deleteById(param.id);
if (!result) { if (!result) {
throw new InternalServerErrorException(); throw new InternalServerErrorException();

View File

@ -222,7 +222,6 @@ export class CertificateService {
const certificate = await this.registroGIERepository.findOneBy({ const certificate = await this.registroGIERepository.findOneBy({
id, id,
}); });
console.log(certificate);
if (certificate !== null) { if (certificate !== null) {
await this.registroGIERepository.delete(certificate); await this.registroGIERepository.delete(certificate);

View File

@ -9,6 +9,12 @@ export function template(ssr: string): string {
<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?t=${Date.now()}" /> <link rel="stylesheet" href="/static/styles.css?t=${Date.now()}" />
<!-- Phosphor icons -->
<link
rel="stylesheet"
type="text/css"
href="https://unpkg.com/@phosphor-icons/web@2.0.3/src/regular/style.css"
/>
${generateHydrationScript()} ${generateHydrationScript()}
</head> </head>
<body> <body>
@ -19,5 +25,4 @@ export function template(ssr: string): string {
<script src="/static/hydration.js?t=${Date.now()}"></script> <script src="/static/hydration.js?t=${Date.now()}"></script>
</html> </html>
`; `;
} }

View File

@ -40,6 +40,7 @@ export function Registers(props: { person: Person | null, lastUpdate: number })
<div class="px-4"> <div class="px-4">
<Show when={props.person !== null}> <Show when={props.person !== null}>
<div>
<span>Nombres y Apellidos</span> <span>Nombres y Apellidos</span>
<br /> <br />
<input <input
@ -49,6 +50,8 @@ export function Registers(props: { person: Person | null, lastUpdate: number })
class="bg-c-background text-c-on-background border-c-outline border rounded px-2 py-1 class="bg-c-background text-c-on-background border-c-outline border rounded px-2 py-1
disabled:cursor-text w-full" disabled:cursor-text w-full"
/> />
</div>
<p <p
class="my-2" class="my-2"
style={{ display: loading() ? "block" : "none" }} style={{ display: loading() ? "block" : "none" }}

View File

@ -7,6 +7,7 @@ import QR from "qrcode";
type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & { type HTMLEventFn = JSX.EventHandlerUnion<HTMLFormElement, Event & {
submitter: HTMLElement; submitter: HTMLElement;
}>; }>;
type HTMLButtonEvent = JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent>;
/* /*
@ -73,23 +74,8 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
<form onSubmit={searchDNI} class="px-4"> <form onSubmit={searchDNI} class="px-4">
<label for="search-dni">DNI</label> <label for="search-dni">DNI</label>
<br /> <br />
<input <InputBox dni={dni()} setDni={setDni} loading={loading()} />
id="search-dni"
class="bg-c-background text-c-on-background border-c-outline border-2 rounded px-2 py-1
invalid:border-c-error invalid:text-c-error
focus:border-c-primary outline-none font-mono
disabled:opacity-50 disabled:cursor-not-allowed"
type="text"
minLength={8}
maxLength={8}
pattern="[0-9]{8}"
placeholder="Número de DNI"
value={dni()}
required={true}
onChange={(e) => setDni(e.target.value)}
disabled={loading()}
/>
<br />
<br /> <br />
<input <input
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-md cursor-pointer class="bg-c-primary text-c-on-primary px-4 py-2 rounded-md cursor-pointer
@ -128,3 +114,58 @@ export function Search(props: {setPerson: (p: Person | null) => void}) {
</div> </div>
); );
} }
function InputBox(props: {
loading: boolean,
dni: string,
setDni: (v: string) => void,
}) {
const [successAnimation, setSuccessAnimation] = createSignal(false);
const copyToClipboard: HTMLButtonEvent = (ev) => {
ev.preventDefault();
if (props.dni.length == 8) {
navigator.clipboard.writeText(props.dni);
setSuccessAnimation(true);
setTimeout(() => setSuccessAnimation(false), 1000);
}
};
const clearDni: HTMLButtonEvent = (ev) => {
ev.preventDefault();
props.setDni("");
}
return (
<div class="grid gap-2 grid-cols-[10rem_3rem_3rem]">
<input
id="search-dni"
class="bg-c-background text-c-on-background border-c-outline border-2 rounded px-2 py-1
invalid:border-c-error invalid:text-c-error
focus:border-c-primary outline-none font-mono
disabled:opacity-50 disabled:cursor-not-allowed"
type="text"
minLength={8}
maxLength={8}
pattern="[0-9]{8}"
placeholder="Número de DNI"
value={props.dni}
required={true}
onChange={(e) => props.setDni(e.target.value)}
disabled={props.loading}
/>
<button
class={(successAnimation() ? "bg-c-success" : "bg-c-primary") + " rounded transition-colors"}
onclick={copyToClipboard}
type="button"
>
<i class={(successAnimation() ? "text-c-on-success" : "text-c-on-primary") + " ph ph-clipboard-text text-2xl"}></i>
</button>
<button class="bg-c-error rounded" onclick={clearDni} type="button">
<i class="ph ph-trash text-2xl text-c-on-primary"></i>
</button>
</div>
)
}

View File

@ -17,6 +17,9 @@
--c-outline: #9d8e81; --c-outline: #9d8e81;
--c-surface-variant: #50453a; --c-surface-variant: #50453a;
--c-on-surface-variant: #d5c3b5; --c-on-surface-variant: #d5c3b5;
--c-success: #78da9f;
--c-on-success: #00391f;
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
@ -36,6 +39,9 @@
--c-outline: #85736c; --c-outline: #85736c;
--c-surface-variant: #f4ded4; --c-surface-variant: #f4ded4;
--c-on-surface-variant: #52443d; --c-on-surface-variant: #52443d;
--c-success: #006d40;
--c-on-success: #ffffff;
} }
} }

View File

@ -4,7 +4,11 @@ module.exports = {
"./src/**/*.tsx", "./src/**/*.tsx",
], ],
theme: { theme: {
extend: {}, extend: {
fontFamily: {
"mono": ["Iosevka", "monospace"]
}
},
colors: { colors: {
"c-primary": "var(--c-primary)", "c-primary": "var(--c-primary)",
"c-on-primary": "var(--c-on-primary)", "c-on-primary": "var(--c-on-primary)",
@ -22,6 +26,8 @@ module.exports = {
"c-surface-variant": "var(--c-surface-variant)", "c-surface-variant": "var(--c-surface-variant)",
"c-on-surface-variant": "var(--c-on-surface-variant)", "c-on-surface-variant": "var(--c-on-surface-variant)",
"c-green": "#006b54", "c-green": "#006b54",
"c-success": "var(--c-success)",
"c-on-success": "var(--c-on-success)",
}, },
}, },
plugins: [], plugins: [],