Compare commits

...

7 commits

9 changed files with 464 additions and 115 deletions

View file

@ -31,7 +31,7 @@ func getCORSConfig(env string) cors.Config {
case "dev": case "dev":
return cors.Config{ return cors.Config{
AllowOrigins: []string{"http://localhost:5173"}, AllowOrigins: []string{"http://localhost:5173"},
AllowMethods: []string{"GET", "POST", "OPTIONS"}, AllowMethods: []string{"GET", "POST", "OPTIONS", "DELETE"},
AllowHeaders: []string{"Origin", "OCBO-Token", "Content-Length", "Content-Type", "X-Server"}, AllowHeaders: []string{"Origin", "OCBO-Token", "Content-Length", "Content-Type", "X-Server"},
ExposeHeaders: []string{"Content-Length"}, ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true, AllowCredentials: true,
@ -39,7 +39,7 @@ func getCORSConfig(env string) cors.Config {
case "prod": case "prod":
return cors.Config{ return cors.Config{
AllowOrigins: []string{"https://ocboapps.davaocity.gov.ph", "https://esign.patalcala.com"}, AllowOrigins: []string{"https://ocboapps.davaocity.gov.ph", "https://esign.patalcala.com"},
AllowMethods: []string{"GET", "POST", "OPTIONS"}, AllowMethods: []string{"GET", "POST", "OPTIONS", "DELETE"},
// AllowHeaders: []string{"Origin", "OCBO-Token", "Content-Length", "Content-Type", "X-Server", "Authorization"}, // AllowHeaders: []string{"Origin", "OCBO-Token", "Content-Length", "Content-Type", "X-Server", "Authorization"},
AllowHeaders: []string{"*"}, AllowHeaders: []string{"*"},
ExposeHeaders: []string{"Content-Length"}, ExposeHeaders: []string{"Content-Length"},
@ -1419,7 +1419,7 @@ func connect() {
"result": result, "result": result,
}) })
case "get-totalamount-electrical": case "get-totalamount-electrical":
err := db.QueryRow(`SELECT IFNULL(SUM(amount), 0) AS result FROM electrical_orderofpayment_new WHERE electricalid = (SELECT electricalid FROM electrical WHERE electricalNo = ?)`, data).Scan(&result) err := db.QueryRow(`SELECT IFNULL(SUM(amount), 0) AS result FROM electrical_orderofpayment_new WHERE electricalid = (SELECT electricalid FROM electrical WHERE electricalNo = ?)`, data).Scan(&result)
if err != nil { if err != nil {
c.AbortWithError(http.StatusBadRequest, err) c.AbortWithError(http.StatusBadRequest, err)
@ -1430,8 +1430,19 @@ func connect() {
"result": result, "result": result,
}) })
case "check-popsrecord": case "check-popsrecord":
err := dbpop.QueryRow("SELECT COUNT(OrderPayId) AS result FROM orderpaydetail WHERE oprefid = ?" , data).Scan(&result) err := dbpop.QueryRow("SELECT COUNT(OrderPayId) AS result FROM orderpaydetail WHERE oprefid = ?", data).Scan(&result)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
c.String(http.StatusBadRequest, err.Error())
return
}
c.JSON(http.StatusOK, gin.H{
"result": result,
})
case "get-opdata-electrical":
err := db.QueryRow(`SELECT IFNULL(CONCAT(electricalid, '-', assessedbyid, '-', reviewedbyid, '-', SUM(ref_bldgcomputationsheetid), '-', SUM(amount)),'') AS result FROM electrical_orderofpayment_new WHERE electricalid = (SELECT electricalid FROM electrical WHERE electricalNo = ?)`, data).Scan(&result)
if err != nil { if err != nil {
c.AbortWithError(http.StatusBadRequest, err) c.AbortWithError(http.StatusBadRequest, err)
c.String(http.StatusBadRequest, err.Error()) c.String(http.StatusBadRequest, err.Error())
@ -2265,5 +2276,221 @@ func connect() {
}) })
router.POST("/api/save-lockdata", middleware.TokenChecker(), func(c *gin.Context) {
type saveLockData struct {
Data string `json:"data"` //referenceNo
Data2 string `json:"data2"` //lock_data
}
var savelockData saveLockData
if err := c.ShouldBindJSON(&savelockData); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; img-src 'self';")
c.Writer.Header().Set("X-Server", "OCBO Server")
dbpost, err := db.Prepare("INSERT INTO esign_lock (esign_lockid, referenceNo, lock_code) VALUES (NULL, ?, ?)")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(savelockData.Data, savelockData.Data2)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Saving Lock Data")
} else {
c.String(http.StatusInternalServerError, "Failed on Saving Lock Data")
}
})
router.DELETE("/api/delete-orderofpayment-electrical", middleware.TokenChecker(), func(c *gin.Context) {
type DeleteOP struct {
Data int `json:"data"`
}
var deleteOp DeleteOP
if err := c.ShouldBindJSON(&deleteOp); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; img-src 'self';")
c.Writer.Header().Set("X-Server", "OCBO Server")
var isPaid int
checkErr := db.QueryRow("SELECT is_paid FROM electrical_orderofpayment_new WHERE electricalid = ?", deleteOp.Data).Scan(&isPaid)
if checkErr != nil {
c.AbortWithError(http.StatusInternalServerError, checkErr)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
if isPaid == 1 {
c.String(http.StatusBadRequest, "Order of Payment has Already been Paid")
return
}
dbpost, err := db.Prepare("DELETE FROM electrical_orderofpayment_new WHERE electricalid = ? AND is_paid = 0")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(deleteOp.Data)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Deleting Order of Payment")
} else {
c.String(http.StatusInternalServerError, "Failed on Deleting Order of Payment")
}
})
router.DELETE("/api/delete-orderofpayment-occupancy", middleware.TokenChecker(), func(c *gin.Context) {
type DeleteOP struct {
Data int `json:"data"`
}
var deleteOp DeleteOP
if err := c.ShouldBindJSON(&deleteOp); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; img-src 'self';")
c.Writer.Header().Set("X-Server", "OCBO Server")
var isPaid int
checkErr := db.QueryRow("SELECT is_paid FROM occupancy_orderofpayment WHERE occupancyid = ?", deleteOp.Data).Scan(&isPaid)
if checkErr != nil {
c.AbortWithError(http.StatusInternalServerError, checkErr)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
if isPaid == 1 {
c.String(http.StatusBadRequest, "Order of Payment has Already been Paid")
return
}
dbpost, err := db.Prepare("DELETE FROM occupancy_orderofpayment WHERE occupancyid = ? AND is_paid = 0")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(deleteOp.Data)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Deleting Order of Payment")
} else {
c.String(http.StatusInternalServerError, "Failed on Deleting Order of Payment")
}
})
router.DELETE("/api/void-op-local", func(c *gin.Context) {
type DeleteOPLocal struct {
Data string `json:"data"`
}
var deleteOpLocal DeleteOPLocal
if err := c.ShouldBindJSON(&deleteOpLocal); err != nil {
c.String(http.StatusBadRequest, "Invalid request body")
return
}
c.Writer.Header().Set("X-XSS-Protection", "1; mode=block")
c.Writer.Header().Set("X-Content-Type-Options", "nosniff")
c.Writer.Header().Set("X-DNS-Prefetch-Control", "off")
c.Writer.Header().Set("X-Frame-Options", "DENY")
c.Writer.Header().Set("X-Download-Options", "noopen")
c.Writer.Header().Set("Referrer-Policy", "no-referrer")
c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; img-src 'self';")
c.Writer.Header().Set("X-Server", "OCBO Server")
var resultCount int
checkErr := dbpop.QueryRow("SELECT COUNT(AFNum) AS resultCount FROM orderpaydetail WHERE OPRefId = ?", deleteOpLocal.Data).Scan(&resultCount)
if checkErr != nil {
c.AbortWithError(http.StatusInternalServerError, checkErr)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
if resultCount > 0 {
c.String(http.StatusBadRequest, "Error! Payment already exist.")
return
}
dbpost, err := dbpop.Prepare("DELETE FROM orderpaydetail WHERE OPRefId = ?")
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
c.String(http.StatusInternalServerError, "Internal Server Error")
return
}
defer dbpost.Close()
exec, err := dbpost.Exec(deleteOpLocal.Data)
if err != nil {
panic(err.Error())
}
affect, err := exec.RowsAffected()
if err != nil {
panic(err.Error())
}
if affect > 0 {
c.String(http.StatusOK, "Success on Deleting POPS Local")
} else {
c.String(http.StatusInternalServerError, "Failed on Deleting POPS Local")
}
})
router.Run(":4320") router.Run(":4320")
} }

View file

@ -12,6 +12,7 @@
"dependencies": { "dependencies": {
"@fontsource-variable/roboto": "^5.2.10", "@fontsource-variable/roboto": "^5.2.10",
"@kobalte/core": "^0.13.11", "@kobalte/core": "^0.13.11",
"@rabbit-company/xchacha20": "^2.3.0",
"@solidjs-use/integrations": "^2.3.0", "@solidjs-use/integrations": "^2.3.0",
"@solidjs/router": "^0.15.4", "@solidjs/router": "^0.15.4",
"consola": "^3.4.2", "consola": "^3.4.2",

12
pnpm-lock.yaml generated
View file

@ -14,6 +14,9 @@ importers:
'@kobalte/core': '@kobalte/core':
specifier: ^0.13.11 specifier: ^0.13.11
version: 0.13.11(solid-js@1.9.11) version: 0.13.11(solid-js@1.9.11)
'@rabbit-company/xchacha20':
specifier: ^2.3.0
version: 2.3.0(typescript@5.8.3)
'@solidjs-use/integrations': '@solidjs-use/integrations':
specifier: ^2.3.0 specifier: ^2.3.0
version: 2.3.0(qrcode@1.5.4)(sortablejs@1.15.6) version: 2.3.0(qrcode@1.5.4)(sortablejs@1.15.6)
@ -814,6 +817,11 @@ packages:
resolution: {integrity: sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==} resolution: {integrity: sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
'@rabbit-company/xchacha20@2.3.0':
resolution: {integrity: sha512-d2itZPlgb+Sxpdi9jBMGEfenQQyQwdynxw6pkgoDXth6y236c9NGxi8Y5k12tlE6l0vhzwRcrmfL/DpOIOnSRg==}
peerDependencies:
typescript: ^5.6.2
'@rollup/pluginutils@5.3.0': '@rollup/pluginutils@5.3.0':
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -2568,6 +2576,10 @@ snapshots:
'@parcel/watcher-win32-x64': 2.5.4 '@parcel/watcher-win32-x64': 2.5.4
optional: true optional: true
'@rabbit-company/xchacha20@2.3.0(typescript@5.8.3)':
dependencies:
typescript: 5.8.3
'@rollup/pluginutils@5.3.0(rollup@4.52.1)': '@rollup/pluginutils@5.3.0(rollup@4.52.1)':
dependencies: dependencies:
'@types/estree': 1.0.8 '@types/estree': 1.0.8

View file

@ -450,12 +450,12 @@ export default () => {
const postTransaction = async (application: string) => { const postTransaction = async (application: string) => {
const id = await geteSignId(employeeId()) const id = await geteSignId(employeeId())
const today = await getDateTime() const today = await getDateTime()
const formatedDate = dayjs(today).format('YYYY-MM-DD HH:mm:ss') const formattedDate = dayjs(today).format('YYYY-MM-DD HH:mm:ss')
await postApi('post-esigntransaction', { await postApi('post-esigntransaction', {
data: parseInt(id, 10), data: parseInt(id, 10),
data2: application, data2: application,
data3: formatedDate, data3: formattedDate,
}) })
} }

View file

@ -102,3 +102,14 @@ h1
opacity: 0.6 opacity: 0.6
text-align: center text-align: center
margin: 1rem 0 -0.75rem 0 margin: 1rem 0 -0.75rem 0
.incomplete
padding: 0.5rem 0 0.5rem 0
&__text
padding: 0 0 0.25rem 0
color: #c85656
&__error
color: #c85656

View file

@ -1,14 +1,13 @@
import { Tabs } from '@kobalte/core/tabs' import { Tabs } from '@kobalte/core/tabs'
import { useNavigate } from '@solidjs/router' import { useNavigate } from '@solidjs/router'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { FaSolidThumbsUp } from 'solid-icons/fa' import { FaSolidThumbsUp, FaSolidUserGear } from 'solid-icons/fa'
import { FiLogOut } from 'solid-icons/fi' import { FiLogOut } from 'solid-icons/fi'
import { VsRefresh } from 'solid-icons/vs' import { VsRefresh } from 'solid-icons/vs'
import { createSignal, onMount, createEffect } from 'solid-js' import { createEffect, createSignal, onMount } from 'solid-js'
import { Box, Button, Clickable, Column, Link, Logo, Modal, ModalButton, Padding, Page, Row, Input } from '../../components/'
import { checkConnection, getApi, getApiMulti, getDateTime, postApi, saveNewName, saveNewPassword, securePassword } from '../../utils/functions'
import { FaSolidUserGear } from 'solid-icons/fa'
import { Show } from 'solid-js/web' import { Show } from 'solid-js/web'
import { Box, Button, Clickable, Column, Input, Link, Logo, Modal, ModalButton, Padding, Page, Row } from '../../components/'
import { checkConnection, deleteApi, getApi, getApiMulti, getDateTime, lockData, postApi, saveNewName, saveNewPassword, securePassword, voidPopsApi } from '../../utils/functions'
import './Main.sass' import './Main.sass'
const PESO = import.meta.env.VITE_PESO const PESO = import.meta.env.VITE_PESO
@ -131,7 +130,7 @@ export default () => {
} }
const isDetailsComplete = (result: string[], result2: string[], result3: string[], result4: string[], result5: string[], result6: string[]) => { const isDetailsComplete = (result: string[], result2: string[], result3: string[], result4: string[], result5: string[], result6: string[]) => {
return result.length > 0 && result2.length > 0 && result3.length > 0 && result4.length > 0 && result5.length > 0 && result6.length > 0 ? false : false return result.length > 0 && result2.length > 0 && result3.length > 0 && result4.length > 0 && result5.length > 0 && result6.length > 0 ? true : false
} }
const calculateTotal = (list: number[]) => { const calculateTotal = (list: number[]) => {
@ -139,6 +138,11 @@ export default () => {
return total return total
} }
// const sample = async () => {
// const data = await lockData('asdasdsadsad')
// console.log(data)
// }
const approveHandler = async (division: string, application: string) => { const approveHandler = async (division: string, application: string) => {
let signed: boolean = false let signed: boolean = false
let forprinting: boolean = false let forprinting: boolean = false
@ -151,10 +155,12 @@ export default () => {
} }
if (division === 'electrical') { if (division === 'electrical') {
await voidPopsOp(application)
await postPops(division, application) await postPops(division, application)
const popsResult = await checkPops(application) const popsResult = await checkPops(application)
const lockResult = await lockOpData(division, application)
if (popsResult) { if (popsResult && lockResult) {
signed = await setNewStatus(division, 'ELECTRICAL ORDER OF PAYMENT APPROVED AND SIGNED', '170', 'ELECOPAPPROVEDSIGNED', 1) signed = await setNewStatus(division, 'ELECTRICAL ORDER OF PAYMENT APPROVED AND SIGNED', '170', 'ELECOPAPPROVEDSIGNED', 1)
updateDocflow(division, application, 'FOR ELECTRICAL ORDER OF PAYMENT APPROVAL') updateDocflow(division, application, 'FOR ELECTRICAL ORDER OF PAYMENT APPROVAL')
if (!signed) return if (!signed) return
@ -174,17 +180,16 @@ export default () => {
setErrorMessage('Error on posting on POPS Server, please try again') setErrorMessage('Error on posting on POPS Server, please try again')
return return
} }
} else if (division === 'occupancy') { } else if (division === 'occupancy') {
const additionalResult = await getApi('check-bldgadditional-approval', application) const additionalResult = await getApi('check-bldgadditional-approval', application)
bldgadditional = additionalResult > 0 bldgadditional = additionalResult > 0
await voidPopsOp(application)
await postPops(division, application) await postPops(division, application)
const popsResult = await checkPops(application) const popsResult = await checkPops(application)
const lockResult = await lockOpData(division, application)
console.log('popsResult', popsResult) if (popsResult && lockResult) {
if (popsResult) {
signed = await setNewStatus(division, 'OCCUPANCY ORDER OF PAYMENT APPROVED AND SIGNED', '172', 'OCCOPAPPROVEDSIGNED', 1) signed = await setNewStatus(division, 'OCCUPANCY ORDER OF PAYMENT APPROVED AND SIGNED', '172', 'OCCOPAPPROVEDSIGNED', 1)
updateDocflow(division, application, 'FOR OCCUPANCY RECOMMENDING APPROVAL') updateDocflow(division, application, 'FOR OCCUPANCY RECOMMENDING APPROVAL')
if (bldgadditional) { if (bldgadditional) {
@ -211,6 +216,54 @@ export default () => {
} }
} }
const lockOpData = async (division: string, application: string) => {
const dataToLock = await getApi(`get-opdata-${division}`, application)
const lockedData = await lockData(dataToLock)
const fixedLockedData = lockedData.replace(/\//g, '~')
const saveLockedData = await postApi('save-lockdata', { data: application, data2: fixedLockedData })
return saveLockedData
}
const voidPopsOp = async (application: string) => {
const response = await voidPopsApi(application)
if (response.includes('Error')) return false
return true
}
const returnAssessment = async (division: string, application: string) => {
const id = await getApplicationById(division, application)
setApplicationId(id)
let forassessment
if (division === 'electrical') {
forassessment = await setNewStatus(division, 'FOR ELECTRICAL ASSESSMENT', '88', 'ELECASSESSMENT', 0)
} else {
forassessment = await setNewStatus(division, 'OCCUPANCY ASSESSMENT', '21', 'OCASSESSMENT', 0)
}
if (!forassessment) return
if (division === 'electrical') {
updateDocflow(division, application, 'FOR ELECTRICAL ORDER OF PAYMENT APPROVAL')
} else {
updateDocflow(division, application, 'FOR OCCUPANCY RECOMMENDING APPROVAL')
}
await deleteOrderofPayment(division, id)
await load('all')
}
const getApplicationById = async (division: string, application: string) => {
const id = await getApi(`get-idbyapplication-${division}`, application)
return parseInt(id)
}
const deleteOrderofPayment = async (division: string, id: number) => {
const deleteOp = await deleteApi(`delete-orderofpayment-${division}`, {
data: id,
})
return deleteOp
}
const setNewStatus = async (division: string, status: string, tag: string, tagword: string, approved: number) => { const setNewStatus = async (division: string, status: string, tag: string, tagword: string, approved: number) => {
// const today = new Date() // const today = new Date()
const today = await getDateTime() const today = await getDateTime()
@ -334,9 +387,9 @@ export default () => {
const postTransaction = async () => { const postTransaction = async () => {
const id = await geteSignId() const id = await geteSignId()
const today = await getDateTime() const today = await getDateTime()
const formatedDate = dayjs(today).format('YYYY-MM-DD HH:mm:ss') const formattedDate = dayjs(today).format('YYYY-MM-DD HH:mm:ss')
await postApi('post-esigntransaction', { data: parseInt(id), data2: approvedApplication(), data3: formatedDate }) await postApi('post-esigntransaction', { data: parseInt(id), data2: approvedApplication(), data3: formattedDate })
} }
const updateDocflow = async (division: string, application: string, status: string) => { const updateDocflow = async (division: string, application: string, status: string) => {
@ -375,7 +428,6 @@ export default () => {
setConfigError('') setConfigError('')
encryptNewPassword() encryptNewPassword()
} }
} else { } else {
setConfigError('Invalid Password') setConfigError('Invalid Password')
setConfigNewEncPassword('') setConfigNewEncPassword('')
@ -404,7 +456,7 @@ export default () => {
// const saveNewPassword = async (password: string) => { // const saveNewPassword = async (password: string) => {
// await postApi('update-password', { // await postApi('update-password', {
// data: parseInt(ID), // data: parseInt(ID),
// data2: password // data2: password
// }) // })
// } // }
@ -653,48 +705,76 @@ export default () => {
await getopdetails('electrical', item) await getopdetails('electrical', item)
}} }}
> >
<Padding top={0} left={2} right={2} bottom={0}> <Show when={isIncomplete()}>
<span class="modal__application-number">{item}</span> <Padding top={0} left={2} right={2} bottom={0}>
<span class="modal__application-number">{item}</span>
<Padding top={1} left={0} right={0} bottom={0}> <Padding top={1} left={0} right={0} bottom={0}>
<section class="modal__row"> <Column padding="0 0 1rem 0">
<span class="modal__row__label">Name of Applicant:</span> <Box curved thickness={3} color="#c85656" padding="1rem">
<span class="modal__row__detail">{nameListElectrical()[index]}</span> <h2 class="incomplete__error">Signing Error</h2>
</section> </Box>
<h3 class="incomplete__error">Missing Data Detected</h3>
</Column>
<section class="modal__row"> <div class="incomplete">
<span class="modal__row__label">Location:</span> <Column>
<span class="modal__row__detail">{location()}</span> <span class="incomplete__text">Some required information is missing from the application details</span>
</section> <span class="incomplete__text">Please return to Assessment to complete the required fields</span>
</Column>
<section class="modal__row"> </div>
<span class="modal__row__label">Type:</span> </Padding>
<span class="modal__row__detail">{type().toUpperCase()}</span> <Column padding="1rem 0 0 0">
</section> <Button wide label="Return to Assessment" edges="curved" design="bo-primary" onClick={() => returnAssessment('electrical', item)} />
<span class="modal__cancel">Click anywhere to cancel</span>
<section class="modal__row"> </Column>
<span class="modal__row__label">Assessed By:</span>
<span class="modal__row__detail">{assessor()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Date Assessed:</span>
<span class="modal__row__detail">{dateOp().toUpperCase()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Total Fee:</span>
<span class="modal__row__detail__price">
{PESO} {totalOp()}
</span>
</section>
</Padding> </Padding>
</Show>
<Row padding="2rem 0 0 0"> <Show when={!isIncomplete()}>
<Button wide label="Approve" edges="curved" design="bo-primary" onClick={() => approveHandler('electrical', item)}></Button> <Padding top={0} left={2} right={2} bottom={0}>
<span class="modal__cancel">Click anywhere to cancel</span> <span class="modal__application-number">{item}</span>
</Row>
</Padding> <Padding top={1} left={0} right={0} bottom={0}>
<section class="modal__row">
<span class="modal__row__label">Name of Applicant:</span>
<span class="modal__row__detail">{nameListElectrical()[index]}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Location:</span>
<span class="modal__row__detail">{location()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Type:</span>
<span class="modal__row__detail">{type().toUpperCase()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Assessed By:</span>
<span class="modal__row__detail">{assessor()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Date Assessed:</span>
<span class="modal__row__detail">{dateOp().toUpperCase()}</span>
</section>
<section class="modal__row">
<span class="modal__row__label">Total Fee:</span>
<span class="modal__row__detail__price">
{PESO} {totalOp()}
</span>
</section>
</Padding>
<Column padding="2rem 0 0 0">
<Button wide label="Approve" edges="curved" design="bo-primary" onClick={() => approveHandler('electrical', item)} />
<span class="modal__cancel">Click anywhere to cancel</span>
</Column>
</Padding>
</Show>
</ModalButton> </ModalButton>
</td> </td>
</tr> </tr>
@ -774,24 +854,24 @@ export default () => {
</Modal> </Modal>
</div> </div>
<Modal trigger={openConfig()} background="#16212c" color="#ffffffed" opacity={0.8} width='30rem'> <Modal trigger={openConfig()} background="#16212c" color="#ffffffed" opacity={0.8} width="30rem">
<Padding top={1} bottom={1} left={4} right={4}> <Padding top={1} bottom={1} left={4} right={4}>
<section class='config'> <section class="config">
<div class='config__row'> <div class="config__row">
Name: Name:
<span>{employeeName()}</span> <span>{employeeName()}</span>
</div> </div>
<div class='config__edit'> <div class="config__edit">
<span class='config__edit__title'>Change Displayed Name</span> <span class="config__edit__title">Change Displayed Name</span>
<Input value={configNewName()} onChange={setConfigNewName} placeholder='Enter new name' /> <Input value={configNewName()} onChange={setConfigNewName} placeholder="Enter new name" />
<span class='config__edit__info'>Leave blank to remain unchanged.</span> <span class="config__edit__info">Leave blank to remain unchanged.</span>
</div> </div>
<div class='config__edit'> <div class="config__edit">
<span class='config__edit__title'>Change Password</span> <span class="config__edit__title">Change Password</span>
<Input isPassword value={configPassword()} onChange={setConfigPassword} placeholder='Enter current password' /> <Input isPassword value={configPassword()} onChange={setConfigPassword} placeholder="Enter current password" />
<Input isPassword value={configNewPassword()} onChange={setConfigNewPassword} placeholder='Enter new password' /> <Input isPassword value={configNewPassword()} onChange={setConfigNewPassword} placeholder="Enter new password" />
<Show when={configNewPassword().length !== 0}> <Show when={configNewPassword().length !== 0}>
<span style="padding: 1.75rem 0 0 0">Current Encrypted Password:</span> <span style="padding: 1.75rem 0 0 0">Current Encrypted Password:</span>
@ -804,18 +884,18 @@ export default () => {
<Show when={configError() !== ''}> <Show when={configError() !== ''}>
<span class="required-config">{configError()}</span> <span class="required-config">{configError()}</span>
<Button label='Cancel' edges='curved' design='bo-danger' onClick={() => setOpenConfig(false)} wide /> <Button label="Cancel" edges="curved" design="bo-danger" onClick={() => setOpenConfig(false)} wide />
</Show> </Show>
<div class='config__button'> <div class="config__button">
<Show when={configError() === ''}> <Show when={configError() === ''}>
<Button label='Confirm' edges='curved' design='bo-primary' onClick={saveConfig} wide /> <Button label="Confirm" edges="curved" design="bo-primary" onClick={saveConfig} wide />
<Button label='Cancel' edges='curved' design='bo-danger' onClick={() => setOpenConfig(false)} wide /> <Button label="Cancel" edges="curved" design="bo-danger" onClick={() => setOpenConfig(false)} wide />
</Show> </Show>
</div> </div>
</section> </section>
</Padding> </Padding>
</Modal > </Modal>
<div onClick={closeConfig}> <div onClick={closeConfig}>
<Modal trigger={configNotification() === true} background="#123220ff" color="#cdfbe1f0" opacity={0.8}> <Modal trigger={configNotification() === true} background="#123220ff" color="#cdfbe1f0" opacity={0.8}>
@ -832,7 +912,7 @@ export default () => {
</Row> </Row>
</Column> </Column>
</Padding> </Padding>
</Modal > </Modal>
</div> </div>
<div onClick={() => setPostError(false)}> <div onClick={() => setPostError(false)}>
@ -856,32 +936,6 @@ export default () => {
</Padding> </Padding>
</Modal> </Modal>
</div> </div>
<div onClick={() => setIsIncomplete(false)}>
<Modal trigger={isIncomplete() === true} background="#562020ff" color="#ffebebe6" opacity={0.8}>
<Padding top={1} bottom={1} left={4} right={4}>
<Column>
<Row>
<Box curved thickness={3} color="#ffebebe6" padding="1rem">
<h2>Incomplete Data</h2>
</Box>
</Row>
<Row>
<h2>Some Data were missing</h2>
</Row>
<Row>
<h4>To avoid further error, application will be automatically pushed back on Assessment for correction</h4>
</Row>
<Row>
<span class="close-text">Click anywhere to close</span>
</Row>
</Column>
</Padding>
</Modal>
</div>
</> </>
) )
} }

View file

@ -0,0 +1,31 @@
import { ofetch } from 'ofetch'
import dayjs from 'dayjs'
import encryptRsa from './encryptRsa'
const API = import.meta.env.VITE_BACKEND
export default async (api: string, body: Object) => {
const today = new Date()
const todayUnix = dayjs(today).unix()
const expiration = todayUnix + 9
const aes = await encryptRsa(`${api.toString()}-${todayUnix.toString()}-${expiration.toString()}`)
const hash = `ocbo=${aes}token`
try {
await ofetch(API + api, {
headers: {
Accept: 'application/json',
'Cache-Control': 'no-cache',
'OCBO-Token': hash,
},
retry: 3,
retryDelay: 500,
retryStatusCodes: [400, 404, 405, 500, 502],
method: 'DELETE',
body: body,
})
return true
} catch {
return false
}
}

View file

@ -1,12 +1,14 @@
export { default as checkConnection } from './checkConnection.ts'; export { default as checkConnection } from './checkConnection.ts'
export { default as createPdfElectrical } from './createPdfElectrical.ts'; export { default as createPdfElectrical } from './createPdfElectrical.ts'
export { default as createPdfOccupancy } from './createPdfOccupancy.ts'; export { default as createPdfOccupancy } from './createPdfOccupancy.ts'
export { default as getApi } from './getApi.ts'; export { default as getApi } from './getApi.ts'
export { default as getApiMulti } from './getApiMulti.ts'; export { default as getApiMulti } from './getApiMulti.ts'
export { default as postApi } from './postApi.ts'; export { default as postApi } from './postApi.ts'
export { default as statusPopsApi } from './statusPopsApi.ts'; export { default as statusPopsApi } from './statusPopsApi.ts'
export { default as voidPopsApi } from './voidPopsApi.ts'; export { default as voidPopsApi } from './voidPopsApi.ts'
export { default as securePassword } from './securePassword.ts'; export { default as securePassword } from './securePassword.ts'
export { default as saveNewName } from './saveNewName.ts'; export { default as saveNewName } from './saveNewName.ts'
export { default as saveNewPassword } from './saveNewPassword.ts'; export { default as saveNewPassword } from './saveNewPassword.ts'
export { default as getDateTime } from './getDateTime.ts'; export { default as getDateTime } from './getDateTime.ts'
export { default as deleteApi } from './deleteApi.ts'
export { default as lockData } from './lockData.ts'

View file

@ -0,0 +1,11 @@
import XChaCha20 from '@rabbit-company/xchacha20'
export default async (text: string) => {
const SECRET_KEY = import.meta.env.VITE_SECRET_KEY
try {
const enc = XChaCha20.encrypt(text, SECRET_KEY)
return enc
} catch {
return ''
}
}