Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import { texts } from '@/texts'
|
|
|
|
const PERSIAN_TEXT_PATTERN = /[\u0600-\u06ff]/
|
|
|
|
const ERROR_CODE_MESSAGES: Record<string, string> = { ...texts.errors.codes }
|
|
|
|
const STATUS_MESSAGES: Record<number, string> = Object.fromEntries(
|
|
Object.entries(texts.errors.httpStatus).map(([status, message]) => [Number(status), message])
|
|
)
|
|
|
|
const DEFAULT_API_ERROR_MESSAGE = texts.errors.defaultApi
|
|
|
|
export const containsPersianText = (value: string): boolean => PERSIAN_TEXT_PATTERN.test(value)
|
|
|
|
export const getProductApiErrorMessage = (code: string): string | undefined => ERROR_CODE_MESSAGES[code.toUpperCase()]
|
|
|
|
/**
|
|
* API error codes stay machine-readable, while every user-facing message is
|
|
* guaranteed to contain Persian texts. Unknown English server details are not
|
|
* exposed because they are often framework or database implementation text.
|
|
*/
|
|
export const ensurePersianApiErrorMessage = (message: unknown, status?: number, code?: string): string => {
|
|
if (typeof message === 'string') {
|
|
const trimmed = message.trim()
|
|
|
|
if (trimmed && containsPersianText(trimmed)) return trimmed
|
|
}
|
|
|
|
if (code) {
|
|
const localizedCodeMessage = ERROR_CODE_MESSAGES[code.toUpperCase()]
|
|
|
|
if (localizedCodeMessage) return localizedCodeMessage
|
|
}
|
|
|
|
if (status) {
|
|
return STATUS_MESSAGES[status] ?? (status >= 500 ? STATUS_MESSAGES[500] : DEFAULT_API_ERROR_MESSAGE)
|
|
}
|
|
|
|
return DEFAULT_API_ERROR_MESSAGE
|
|
}
|
|
|
|
const localizeMessageValue = (message: unknown, status?: number, code?: string): string | string[] => {
|
|
if (!Array.isArray(message)) return ensurePersianApiErrorMessage(message, status, code)
|
|
|
|
const localized = message.map((item) => ensurePersianApiErrorMessage(item, status, code))
|
|
|
|
return [...new Set(localized)]
|
|
}
|
|
|
|
/** Returns an error payload with Persian top-level and nested body messages. */
|
|
export const localizeApiErrorPayload = (data: unknown, status?: number): Record<string, unknown> => {
|
|
const source = data && typeof data === 'object' && !Array.isArray(data) ? (data as Record<string, unknown>) : {}
|
|
const code = typeof source.code === 'string' ? source.code : undefined
|
|
const body =
|
|
source.body && typeof source.body === 'object' && !Array.isArray(source.body) ? (source.body as Record<string, unknown>) : undefined
|
|
const bodyCode = typeof body?.code === 'string' ? body.code : code
|
|
const localized: Record<string, unknown> = {
|
|
...source,
|
|
success: false,
|
|
message: localizeMessageValue(source.message ?? data, status, code),
|
|
}
|
|
|
|
if (body) {
|
|
localized.body = {
|
|
...body,
|
|
message: localizeMessageValue(body.message, status, bodyCode),
|
|
}
|
|
}
|
|
|
|
return localized
|
|
}
|