diff --git a/src/pages/RegisterPage/Register.sass b/src/pages/RegisterPage/Register.sass index c875b7a..94e8415 100644 --- a/src/pages/RegisterPage/Register.sass +++ b/src/pages/RegisterPage/Register.sass @@ -1,3 +1,6 @@ +@use '/src/styles/variables' as vars +@use 'sass:color' + .back-button-text font-size: 1rem @@ -6,4 +9,132 @@ .box-title font-size: 1.75rem - font-weight: 700 \ No newline at end of file + font-weight: 700 + +.digital-sign-details + display: flex + flex-direction: column + gap: 0.25rem + font-size: 0.8rem + + &__image + margin: 0 0 1rem 0 + width: 14rem + +.already-registered + padding: 1rem + border-radius: 8px + background-color: color.adjust(#0D64E4, $blackness: 20%) + opacity: 0.6 + +.filefield + display: flex + flex-direction: column + align-items: center + justify-content: center + height: 250px + width: 100% + row-gap: 5px + border: 1px solid #ffffff6c + border-radius: 8px + + &__label + color: white + font-size: 14px + font-weight: 500 + user-select: none + + &__dropzone + display: flex + flex-direction: column + row-gap: 10px + align-items: center + justify-content: center + width: 100% + height: 100% + color: #5f8ebebf + cursor: pointer + font-size: 1rem + + // &__trigger + // background-color: vars.$primaryColor + // border: none + // border-radius: 8px + // color: white + // padding: 0.5rem 1.25rem + // text-align: center + // text-decoration: none + // display: inline-block + // font-size: 1rem + // font-weight: 500 + // cursor: pointer + // transition: all 0.2s ease-out + + // &:hover + // background-color: color.adjust(vars.$primaryColor, $blackness: 20%) + + // &:active + // transform: scale(0.95) + + &__itemList + display: flex + flex-direction: column + gap: 3px + width: 100% + + &__item + width: 82% + display: grid + // padding: 1rem + column-gap: 10px + border-radius: 8px + grid-template-columns: auto 1fr auto + grid-template-areas: "preview name delete" "preview size delete" + column-gap: 5px + // border: 1px solid rgba(187, 187, 187, 0.706) + padding: 10px + background-color: #2b405542 + margin: 0 1rem + + &__itemPreview + grid-area: preview + + &__itemPreviewImage + width: 6rem + object-fit: scale-down + height: auto + aspect-ratio: 1 + + &__itemName + font-weight: 500 + grid-area: name + font-size: 1rem + color: #fff + + &__itemSize + grid-area: size + font-size: 14px + color: rgb(181, 179, 173) + + &__itemDeleteTrigger + grid-area: delete + background-color: #a23434 + border: none + border-radius: 8px + color: white + padding: 0.5rem 1.25rem + text-align: center + text-decoration: none + display: inline-block + font-size: 1rem + font-weight: 500 + cursor: pointer + transition: all 0.2s ease-out + height: max-content + align-self: center + + &:hover + background-color: color.adjust(#a23434, $blackness: 20%) + + &:active + transform: scale(0.95) diff --git a/src/pages/RegisterPage/Register.tsx b/src/pages/RegisterPage/Register.tsx index e4d84d8..b29eb5b 100644 --- a/src/pages/RegisterPage/Register.tsx +++ b/src/pages/RegisterPage/Register.tsx @@ -1,34 +1,48 @@ import './Register.sass' -import { Logo, Link, Page, Row, Padding, Combobox, Box, File, Button, Modal, Column } from '../../components' +import { Logo, Link, Page, Row, Padding, Combobox, Box, Button, Modal, Column, QR, Input } from '../../components' import { IoChevronBack } from 'solid-icons/io' -import { Show, createSignal } from 'solid-js' +import { Show, createSignal, createEffect } from 'solid-js' import { ofetch } from 'ofetch' -import { SHA3 } from 'crypto-js' +import { SHA3, SHA1 } from 'crypto-js' +import dayjs from 'dayjs' +import { FileField } from '@kobalte/core/file-field' +import bcrypt from 'bcryptjs' export default () => { const API = import.meta.env.VITE_BACKEND + const APPROVERNAME = 'ARCH. KHASHAYAR L. TOGHYANI' const assessors = JSON.parse(sessionStorage.getItem('assessors')!) const roles = ['ASSESSOR', 'APPROVER'] const [role, setRole] = createSignal('') const [name, setName] = createSignal('') - const [id, setId] = createSignal(0) + const [password, setPassword] = createSignal('') + const [hashPassword, setHashPassword] = createSignal('') + const [id, setId] = createSignal(0) const [signature, setSignature] = createSignal('') const [saved, setSaved] = createSignal(false) + const [file, setFile] = createSignal() + const [base64image, setBase64image] = createSignal('') + const [allow, setAllow] = createSignal(0) const getEmployeeId = async (val: string) => { try { setName(val) const id = await ofetch(API + 'get-employeeid/' + val, { parseResponse: JSON.parse }) - setId(id.result) + setId(parseInt(id.result)) + await checkRegistered() } catch { setId(0) } } const generateSignature = () => { + if (role() === 'APPROVER') { + setId(276) + setName(APPROVERNAME) + } const hash = SHA3(id().toString()) - setSignature(hash.toString()) + setSignature(`Scan this using OCBO e-Sign Validator - scanid=${hash.toString()}`) try { register() @@ -39,12 +53,68 @@ export default () => { } const register = async () => { + await securePassword() + const blob = new Blob(file()) + const base64 = await convertBase64(blob) + setBase64image(base64 as string) + await ofetch(API + 'post-registration', { method: 'POST', - body: { data: id(), data2: signature() }, + body: { data: id(), data2: hashPassword(), data3: signature(), data4: base64 }, }) } + const getDate = () => { + const today = new Date() + const formattedDate = dayjs(today).format('YYYY-MM-DD HH:mm:ss Z') + return formattedDate + } + + const securePassword = async () => { + const salt = bcrypt.genSaltSync(9) + const hash = bcrypt.hashSync(password(), salt) + const sha = SHA1(hash) + setHashPassword(sha.toString()) + } + + const convertBase64 = (blob: Blob) => { + return new Promise((resolve, _) => { + const reader = new FileReader() + reader.onloadend = () => resolve(reader.result) + reader.readAsDataURL(blob) + }) + } + + const checkRegistered = async () => { + const employeeid = id() + + try { + const registered = await ofetch(API + 'check-registered/' + employeeid, { parseResponse: JSON.parse }) + if (registered.result > 0) { + setAllow(1) + } else { + setAllow(2) + } + } catch { + setAllow(2) + } + } + + createEffect(async () => { + if (role() === 'APPROVER') { + try { + const registered = await ofetch(API + 'check-registered/' + 276, { parseResponse: JSON.parse }) + if (registered.result > 0) { + setAllow(1) + } else { + setAllow(2) + } + } catch { + setAllow(2) + } + } + }) + return ( <> @@ -73,29 +143,85 @@ export default () => {

Role

+

List of Assessors

getEmployeeId(val!)} /> -

Upload Signature

- - - -