feat(marks): add full name

This commit is contained in:
en 2025-03-07 12:15:26 +00:00
parent 8e23a2d8a1
commit cc681af11a
6 changed files with 139 additions and 3 deletions

View File

@ -0,0 +1,20 @@
import { useDidMount } from '../../../hooks'
import { useLocalStorage } from '../../../hooks/useLocalStorage'
import { MarkInputProps } from '../MarkStrategy'
import { MarkInputText } from '../Text/Input'
export const MarkInputFullName = (props: MarkInputProps) => {
const [fullName, setFullName] = useLocalStorage('mark-fullname', '')
useDidMount(() => {
props.handler(fullName)
})
return MarkInputText({
...props,
placeholder: 'Full Name',
value: fullName,
handler: (value) => {
setFullName(value)
props.handler(value)
}
})
}

View File

@ -0,0 +1,7 @@
import { MarkStrategy } from '../MarkStrategy'
import { MarkInputFullName } from './Input'
export const FullNameStrategy: MarkStrategy = {
input: MarkInputFullName,
render: ({ value }) => <>{value}</>
}

View File

@ -2,6 +2,7 @@ import { MarkType } from '../../types/drawing'
import { CurrentUserMark, Mark } from '../../types/mark'
import { TextStrategy } from './Text'
import { SignatureStrategy } from './Signature'
import { FullNameStrategy } from './FullName'
export interface MarkInputProps {
value: string
@ -28,5 +29,6 @@ export type MarkStrategies = {
export const MARK_TYPE_CONFIG: MarkStrategies = {
[MarkType.TEXT]: TextStrategy,
[MarkType.SIGNATURE]: SignatureStrategy
[MarkType.SIGNATURE]: SignatureStrategy,
[MarkType.FULLNAME]: FullNameStrategy
}

View File

@ -0,0 +1,64 @@
import React, { useMemo } from 'react'
import {
getLocalStorageItem,
mergeWithInitialValue,
removeLocalStorageItem,
setLocalStorageItem
} from '../utils'
const useLocalStorageSubscribe = (callback: () => void) => {
window.addEventListener('storage', callback)
return () => window.removeEventListener('storage', callback)
}
export function useLocalStorage<T>(
key: string,
initialValue: T
): [T, React.Dispatch<React.SetStateAction<T>>] {
const getSnapshot = () => {
// Get the stored value
const storedValue = getLocalStorageItem(key, initialValue)
// Parse the value
const parsedStoredValue = JSON.parse(storedValue)
// Merge the default and the stored in case some of the required fields are missing
return JSON.stringify(
mergeWithInitialValue(parsedStoredValue, initialValue)
)
}
const data = React.useSyncExternalStore(useLocalStorageSubscribe, getSnapshot)
const setState: React.Dispatch<React.SetStateAction<T>> = React.useCallback(
(v: React.SetStateAction<T>) => {
try {
const nextState =
typeof v === 'function'
? (v as (prevState: T) => T)(JSON.parse(data))
: v
if (nextState === undefined || nextState === null) {
removeLocalStorageItem(key)
} else {
setLocalStorageItem(key, JSON.stringify(nextState))
}
} catch (e) {
console.warn(e)
}
},
[data, key]
)
React.useEffect(() => {
// Set local storage only when it's empty
const data = window.localStorage.getItem(key)
if (data === null) {
setLocalStorageItem(key, JSON.stringify(initialValue))
}
}, [key, initialValue])
const memoized = useMemo(() => JSON.parse(data) as T, [data])
return [memoized, setState]
}

View File

@ -42,3 +42,47 @@ export const clear = () => {
clearAuthToken()
clearState()
}
export function mergeWithInitialValue<T>(storedValue: T, initialValue: T): T {
if (
!Array.isArray(storedValue) &&
typeof storedValue === 'object' &&
storedValue !== null
) {
return { ...initialValue, ...storedValue }
}
return storedValue
}
export function getLocalStorageItem<T>(key: string, defaultValue: T): string {
try {
const data = window.localStorage.getItem(key)
if (data === null) return JSON.stringify(defaultValue)
return data
} catch (err) {
console.error(`Error while fetching local storage value: `, err)
return JSON.stringify(defaultValue)
}
}
export function setLocalStorageItem(key: string, value: string) {
try {
window.localStorage.setItem(key, value)
dispatchLocalStorageEvent(key, value)
} catch (err) {
console.error(`Error while saving local storage value: `, err)
}
}
export function removeLocalStorageItem(key: string) {
try {
window.localStorage.removeItem(key)
dispatchLocalStorageEvent(key, null)
} catch (err) {
console.error(`Error while deleting local storage value: `, err)
}
}
function dispatchLocalStorageEvent(key: string, newValue: string | null) {
window.dispatchEvent(new StorageEvent('storage', { key, newValue }))
}

View File

@ -171,8 +171,7 @@ export const DEFAULT_TOOLBOX: DrawTool[] = [
{
identifier: MarkType.FULLNAME,
icon: faIdCard,
label: 'Full Name',
isComingSoon: true
label: 'Full Name'
},
{
identifier: MarkType.JOBTITLE,