Skip to content

Commit

Permalink
in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
tareq89 committed Jan 16, 2025
1 parent fa2b3ec commit 35f3822
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { v4 as uuid } from 'uuid'
import styled from 'styled-components'
import { useIntl } from 'react-intl'
import { useTypedParams } from 'react-router-typesafe-routes/dom'
import { getCurrentEventState, ActionType } from '@opencrvs/commons/client'
import { ActionType } from '@opencrvs/commons/client'
import { ROUTES } from '@client/v2-events/routes'
import { useEvents } from '@client/v2-events/features/events/useEvents/useEvents'
import { Review as ReviewComponent } from '@client/v2-events/features/events/components/Review'
Expand All @@ -37,6 +37,7 @@ import {
Stack
} from '@opencrvs/components'
import { api } from '@client/v2-events/trpc'
import { useAppConfig } from '@client/v2-events/hooks/useAppConfig'

const CertificateContainer = styled.div`
svg {
Expand Down Expand Up @@ -122,6 +123,13 @@ export function Review() {
const [modal, openModal] = useModal()
const navigate = useNavigate()
const { goToHome } = useEventFormNavigation()
const { appConfig, certificatesTemplate, language, initiateAppConfig } =
useAppConfig()

useEffect(() => {
initiateAppConfig()
}, [initiateAppConfig])

const collectCertificateMutation = events.actions.collectCertificate

const [event] = events.getEvent.useSuspenseQuery(eventId)
Expand All @@ -145,13 +153,8 @@ export function Review() {
const form = getFormValues(eventId)
console.trace(form)

const {
isLoadingInProgress,
svgCode,
handleCertify,
isPrintInAdvance,
canUserEditRecord
} = usePrintableCertificate(form)
const { svgCode, handleCertify, isPrintInAdvance, canUserEditRecord } =
usePrintableCertificate(form, appConfig, certificatesTemplate, language)

async function handleEdit({
pageId,
Expand Down Expand Up @@ -232,11 +235,11 @@ export function Review() {
))

if (saveAndExitConfirm) {
handleCertify()
handleCertify && handleCertify()
}
}

if (!isLoadingInProgress) {
if (!svgCode) {
return <Spinner id="review-certificate-loading" />
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

import { get, mapKeys, orderBy } from 'lodash'
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { useIntl } from 'react-intl'
import ReactTooltip from 'react-tooltip'
import styled, { useTheme } from 'styled-components'
Expand All @@ -32,6 +32,7 @@ import { useEvents } from '@client/v2-events/features/events/useEvents/useEvents
import { messages } from '@client/v2-events/messages'
import { ROUTES } from '@client/v2-events/routes'
import { WQContentWrapper } from './components/ContentWrapper'
import { useAppConfig } from '@client/v2-events/hooks/useAppConfig'

/**
* Based on packages/client/src/views/OfficeHome/requiresUpdate/RequiresUpdate.tsx and others in the same directory.
Expand Down
50 changes: 41 additions & 9 deletions packages/client/src/v2-events/hooks/useAppConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,53 @@
*/

import { create } from 'zustand'
import { api } from '@client/v2-events/trpc'
import { ApplicationConfigResponseSchema } from '@opencrvs/commons/events'
import { UseTRPCQueryResult } from '@trpc/react-query/shared'
import { TRPCClientErrorLike } from '@trpc/client'
import { DefaultErrorShape } from '@trpc/server/unstable-core-do-not-import'
import {
LanguageSchema,
ApplicationConfigSchema,
CertificateDataSchema
} from '@opencrvs/commons/events'
import { storage } from '@client/storage'

interface IApplicationConfig {
appConfig: ApplicationConfigResponseSchema
appConfig?: ApplicationConfigSchema
certificatesTemplate: CertificateDataSchema[]
language?: LanguageSchema
initiateAppConfig: () => Promise<void>
}

const isTruthyArray = (value: any) => Array.isArray(value) && value.length > 0

export const useAppConfig = create<IApplicationConfig>((set, get) => ({
appConfig: { config: undefined, certificates: [] },
language: undefined,
appConfig: undefined,
certificatesTemplate: [],
initiateAppConfig: async () => {
const { data: appConfig } = api.appConfig.get.useQuery()
set({ appConfig })
try {
const offlineJsonString = await storage.getItem('offline')
if (offlineJsonString) {
const offline = JSON.parse(offlineJsonString)

if (isTruthyArray(offline['languages'])) {
const defaultLangue = await storage.getItem('language')
const defaultLangueObj: LanguageSchema = offline['languages'].find(
(x: LanguageSchema) => x.lang === defaultLangue
)
set({ language: defaultLangueObj })
}

if (offline['config']) {
set({ appConfig: offline['config'] })
}

if (
offline['templates'] &&
isTruthyArray(offline['templates']['certificates'])
) {
set({ certificatesTemplate: offline['templates']['certificates'] })
}
}
} catch (error) {
console.error('Error initializing app config:', error)
}
}
}))
29 changes: 22 additions & 7 deletions packages/client/src/v2-events/hooks/usePrintableCertificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ import {
getRegisteredDate,
isCertificateForPrintInAdvance
} from './utils/certificateUtils'
import { CertificateDataSchema } from '@opencrvs/commons/events'
import {
ApplicationConfigSchema,
CertificateDataSchema,
LanguageSchema
} from '@opencrvs/commons/events'
import { ActionFormData, isMinioUrl } from '@opencrvs/commons/client'
import { fetchImageAsBase64 } from '@client/utils/imageUtils'
import { useAppConfig } from '@client/v2-events/hooks/useAppConfig'
import { useEffect } from 'react'
import { api } from '../trpc'
import { is } from 'date-fns/locale'

async function replaceMinioUrlWithBase64(template: Record<string, any>) {
async function recursiveTransform(obj: any) {
Expand All @@ -54,19 +59,29 @@ async function replaceMinioUrlWithBase64(template: Record<string, any>) {
return recursiveTransform(template)
}

export const usePrintableCertificate = (form: ActionFormData) => {
export const usePrintableCertificate = (
form: ActionFormData,
appConfig?: ApplicationConfigSchema,
certificatesTemplate?: CertificateDataSchema[],
language?: LanguageSchema
) => {
const handleCertify = () => {}

if (!appConfig || !language || !certificatesTemplate) return { svgCode: null }

const isPrintInAdvance = false
const canUserEditRecord = false
const handleEdit = () => {}
const { data: svgCode, isFetched } =
api.appConfig.getCertificateTemplateSVGById.useQuery({
id: form['collector.certificateTemplateId'] as string
})
const certificateConfig = certificatesTemplate.find(
(x) => x.id === form['collector.certificateTemplateId']
)

if (!certificateConfig) return { svgCode: null }
const certificateFonts = certificateConfig?.fonts ?? {}
const svgWithoutFonts = compileSvg(certificateConfig.svg, form, language)
const svgCode = addFontsToSvg(svgWithoutFonts, certificateFonts)

return {
isLoadingInProgress: isFetched,
svgCode,
handleCertify,
isPrintInAdvance,
Expand Down
47 changes: 24 additions & 23 deletions packages/client/src/v2-events/hooks/utils/PDFUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from '@client/utils/referenceApi'
import htmlToPdfmake from 'html-to-pdfmake'
import { Content } from 'pdfmake/interfaces'
import { LanguageSchema } from '@opencrvs/commons'

type TemplateDataType = string | MessageDescriptor | Array<string>
function isMessageDescriptor(
Expand Down Expand Up @@ -86,12 +87,12 @@ const cache = createIntlCache()
export function compileSvg(
templateString: string,
data: Record<string, any> = {},
state: IStoreState
language: LanguageSchema
): string {
const intl = createIntl(
{
locale: state.i18n.language,
messages: state.i18n.messages
locale: language.lang,
messages: language.messages
},
cache
)
Expand Down Expand Up @@ -168,31 +169,31 @@ export function compileSvg(
}
)

Handlebars.registerHelper(
'location',
function (this: any, locationId: string | undefined, key: keyof ILocation) {
const offlineData = getOfflineData(state)
// Handlebars.registerHelper(
// 'location',
// function (this: any, locationId: string | undefined, key: keyof ILocation) {
// const offlineData = getOfflineData(state)

if (!locationId) {
return ''
}
// if (!locationId) {
// return ''
// }

if (!['name', 'alias'].includes(key)) {
return `Unknown property ${key}`
}
// if (!['name', 'alias'].includes(key)) {
// return `Unknown property ${key}`
// }

const location: AdminStructure | undefined =
offlineData.locations[locationId] ??
offlineData.facilities[locationId] ??
offlineData.offices[locationId]
// const location: AdminStructure | undefined =
// offlineData.locations[locationId] ??
// offlineData.facilities[locationId] ??
// offlineData.offices[locationId]

const fallback = import.meta.env.DEV
? `Missing location for id: ${locationId}`
: locationId
// const fallback = import.meta.env.DEV
// ? `Missing location for id: ${locationId}`
// : locationId

return location?.[key] ?? fallback
}
)
// return location?.[key] ?? fallback
// }
// )

const template = Handlebars.compile(templateString)
const formattedTemplateData = formatAllNonStringValues(data, intl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,6 @@ const iLoginBackgroundSchema = z.object({
imageFit: z.string().optional()
})

enum EventType {
Birth = 'birth',
Death = 'death',
Marriage = 'marriage',
TENNIS_CLUB_MEMBERSHIP = 'TENNIS_CLUB_MEMBERSHIP'
}
const eventTypeSchema = z.nativeEnum(EventType)

const fontFamilyTypesSchema = z.object({
normal: z.string(),
bold: z.string(),
italics: z.string(),
bolditalics: z.string()
})

const CertificateConfigDataSchema = z.object({
id: z.string(),
event: eventTypeSchema,
label: z.object({
id: z.string(),
defaultMessage: z.string(),
description: z.string()
}),
isDefault: z.boolean(),
fee: z.object({
onTime: z.number(),
late: z.number(),
delayed: z.number()
}),
svgUrl: z.string(),
fonts: z.record(fontFamilyTypesSchema).optional()
})

const CertificateDataSchema = CertificateConfigDataSchema.extend({
hash: z.string().optional(),
svg: z.string()
})

export type CertificateDataSchema = z.infer<typeof CertificateDataSchema>

const iCurrencySchema = z.object({
isoCode: z.string(),
languagesAndCountry: z.array(z.string())
Expand All @@ -77,7 +37,7 @@ enum SearchCriteria {
}
const searchCriteriaTypeSchema = z.nativeEnum(SearchCriteria)

const ApplicationConfigSchema = z.object({
export const ApplicationConfigSchema = z.object({
APPLICATION_NAME: z.string(),
BIRTH: z.object({
REGISTRATION_TARGET: z.number(),
Expand Down Expand Up @@ -113,11 +73,4 @@ const ApplicationConfigSchema = z.object({
SEARCH_DEFAULT_CRITERIA: searchCriteriaTypeSchema.optional()
})

export const ApplicationConfigResponseSchema = z.object({
config: ApplicationConfigSchema.optional(),
certificates: z.array(CertificateDataSchema)
})

export type ApplicationConfigResponseSchema = z.infer<
typeof ApplicationConfigResponseSchema
>
export type ApplicationConfigSchema = z.infer<typeof ApplicationConfigSchema>
52 changes: 52 additions & 0 deletions packages/commons/src/events/OfflineData/CertificateConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* OpenCRVS is also distributed under the terms of the Civil Registration
* & Healthcare Disclaimer located at http://opencrvs.org/license.
*
* Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
*/

import { z } from 'zod'

enum EventType {
Birth = 'birth',
Death = 'death',
Marriage = 'marriage',
TENNIS_CLUB_MEMBERSHIP = 'tennis-club-membership'
}
const eventTypeSchema = z.nativeEnum(EventType)

const fontFamilyTypesSchema = z.object({
normal: z.string(),
bold: z.string(),
italics: z.string(),
bolditalics: z.string()
})

export const CertificateConfigDataSchema = z.object({
id: z.string(),
event: eventTypeSchema,
label: z.object({
id: z.string(),
defaultMessage: z.string(),
description: z.string()
}),
isDefault: z.boolean(),
fee: z.object({
onTime: z.number(),
late: z.number(),
delayed: z.number()
}),
svgUrl: z.string(),
fonts: z.record(fontFamilyTypesSchema).optional()
})

export const CertificateDataSchema = CertificateConfigDataSchema.extend({
hash: z.string().optional(),
svg: z.string()
})

export type CertificateDataSchema = z.infer<typeof CertificateDataSchema>
Loading

0 comments on commit 35f3822

Please sign in to comment.