Add production-ready SuperAdmin API features for tenants, SMS, servers, and plugins.
Includes mobile auth, get_user/get_version, SMS wallet parity endpoints, appearance backfill, and related Prisma migrations. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/** Shared Iran timezone helpers for SuperAdmin API. */
|
||||
|
||||
export const IRAN_TZ = 'Asia/Tehran';
|
||||
|
||||
/** Gregorian YYYY-MM-DD for the calendar day in Asia/Tehran. */
|
||||
export function iranYmd(date: Date = new Date()): string {
|
||||
return new Intl.DateTimeFormat('en-CA', {
|
||||
timeZone: IRAN_TZ,
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
export function formatIranDate(date: Date): string {
|
||||
return new Intl.DateTimeFormat('fa-IR-u-ca-persian', {
|
||||
timeZone: IRAN_TZ,
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
export function formatIranDateTime(date: Date): string {
|
||||
return new Intl.DateTimeFormat('fa-IR-u-ca-persian', {
|
||||
timeZone: IRAN_TZ,
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
/** Whole days from Iran "today" to Iran calendar day of `expiresAt`. */
|
||||
export function iranDaysUntil(expiresAt: Date, now: Date = new Date()): number {
|
||||
const start = Date.parse(`${iranYmd(now)}T12:00:00+03:30`);
|
||||
const end = Date.parse(`${iranYmd(expiresAt)}T12:00:00+03:30`);
|
||||
return Math.round((end - start) / 86_400_000);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/** Normalize Iranian mobile to 09xxxxxxxxx, or null if invalid. */
|
||||
export function normalizeMobile(input?: string | null): string | null {
|
||||
if (!input) return null;
|
||||
let digits = String(input).replace(/\D/g, '');
|
||||
if (digits.startsWith('98') && digits.length >= 12) {
|
||||
digits = `0${digits.slice(2)}`;
|
||||
}
|
||||
if (digits.startsWith('9') && digits.length === 10) {
|
||||
digits = `0${digits}`;
|
||||
}
|
||||
if (!/^09\d{9}$/.test(digits)) {
|
||||
return null;
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
export function displayName(firstName: string, lastName: string) {
|
||||
return `${firstName} ${lastName}`.replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
Reference in New Issue
Block a user