Initial commit: Hedena Gold monorepo.

First commit of the Hedena Gold product (separate from gold-bank): branding, package names, and deploy defaults aligned to the new brand; legacy Henza trees stay local-only via .gitignore.
This commit is contained in:
s.esmaeili
2026-10-15 17:19:10 +03:30
commit ea86636027
1121 changed files with 401065 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
// Ported from legacy henza_admin/src/filters/filters.js
//
// Vue 3 removed `Vue.filter`, so these are plain functions imported where needed.
// Each body is carried over verbatim, including legacy's quirks:
// - priceUnit returns the input UNCHANGED when falsy (so 0 renders as "0",
// not "0 تومان") and appends a trailing space after 'تومان'
// - jdateTime uses 'hh:mm:ss' (12-hour) rather than 'HH:mm:ss'
import moment from 'moment-jalaali';
export function capitalize(value: string) {
if (!value) return '';
value = value.toString();
const arr = value.split(' ');
const capitalized_array: string[] = [];
arr.forEach((word) => {
const capitalized = word.charAt(0).toUpperCase() + word.slice(1);
capitalized_array.push(capitalized);
});
return capitalized_array.join(' ');
}
export function title(value: string, replacer = '_') {
if (!value) return '';
value = value.toString();
const arr = value.split(replacer);
const capitalized_array: string[] = [];
arr.forEach((word) => {
const capitalized = word.charAt(0).toUpperCase() + word.slice(1);
capitalized_array.push(capitalized);
});
return capitalized_array.join(' ');
}
export function truncate(value: string, limit: number) {
return value.substring(0, limit);
}
/** legacy: thousands separators + ' تومان ' (note the trailing space) */
export function priceUnit(val: unknown) {
if (val) {
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ' تومان ';
}
return val;
}
/** legacy: plain thousands separators, no unit */
export function price(val: unknown) {
if (val) {
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
return val;
}
/** Jalali date, legacy format 'jYYYY/jMM/jDD' */
export function jdate(val: unknown) {
if (val) {
return moment(val as string).format('jYYYY/jMM/jDD');
}
return val;
}
/** Jalali date+time. Legacy used 12-hour 'hh' here — preserved. */
/**
* A date column in an XTable grid. The legacy API sent `caj`/`uaj`/… already
* formatted (Selector::convertDate, Jalalian) and the grid printed the string;
* the new API sends an ISO timestamp, which the grid printed raw
* ("2026-07-25T12:32:29.000Z"). Same shape the legacy screen shows:
* 1405/5/3-16:02, in the viewer's local (Tehran) time. Anything that is not
* an ISO timestamp is returned untouched.
*/
export function gridDate(val: unknown) {
if (typeof val !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(val)) return val;
return moment(val).format('jYYYY/jM/jD-HH:mm');
}
export function jdateTime(val: unknown) {
if (val) {
return moment(val as string).format('jYYYY/jMM/jDD - hh:mm:ss');
}
return val;
}
export function none<T>(val: T) {
return val;
}
+26
View File
@@ -0,0 +1,26 @@
// Ported from legacy henza_admin/src/utils/index.js
//
// Legacy:
// export function isBranch(){
// console.log(process.env.NODE_ENV)
// return process.env.NODE_ENV=='branch'
// }
//
// Vite has no process.env at runtime; the equivalent build-time switch is the
// --mode flag, exposed as import.meta.env.MODE. Run `pnpm dev:branch` for branch mode.
// The legacy console.log is intentionally not carried over (debug noise, no behaviour).
export function isBranch(): boolean {
return import.meta.env.MODE === 'branch';
}
// Legacy stored the token under a different localStorage key per mode.
// See henza_admin/src/axios.js:6 and router.js:173-174,188.
/** آدرس همین پنل، با پیشوند /branch در حالت شعبه. */
export function iamAppUrl(path: string) {
const base = import.meta.env.BASE_URL || '/';
const prefix = base.endsWith('/') ? base : `${base}/`;
return `${window.location.origin}${prefix}${path.replace(/^\//, '')}`;
}
export const tokenName = isBranch() ? 'branch_token' : 'token';
export const userName = isBranch() ? 'branch_user' : 'user';
+34
View File
@@ -0,0 +1,34 @@
/**
* Rids of the features only the super admin (09128081392) may use: retail
* customers and orders, branches and workshops, retail promotions and wallet
* management. The permission screen hides them from everyone else. Bankers,
* walk-in shopkeepers and trays ride on rids other screens share, so they are
* gated by `users.isSuperAdmin` in place instead.
*
* Keep in step with SUPER_ADMIN_RIDS in apps/api/src/modules/auth/super-admin.ts.
*/
export const SUPER_ADMIN_RIDS: ReadonlySet<string> = new Set([
'persons.create.single',
'persons.list.client.single',
'persons.list.client.single.view',
'persons.list.client.single.edit',
'branch',
'branch.create',
'branch.list',
'workshop',
'workshop.create',
'workshop.list',
'order.create',
'order.list',
'order.list.view',
'order.list.sts',
'order.list.sts.view',
'order.list.sts.remove',
'order.list.sts.submit',
'order.list.view.edit',
'order.list.pdf',
'offers.create.tak',
'offers.list.tak.edit',
'offers.list.tak.remove',
'config.wallet',
]);