Files
3x-ui/frontend/src/hooks/useDatepicker.ts
T
MHSanaei c6f15cd53f refactor(api)!: move /panel/setting and /panel/xray under /panel/api
Settings and Xray config endpoints now live at /panel/api/setting/* and /panel/api/xray/*, registered under the existing /panel/api group so they inherit the same Bearer-or-session auth (checkAPIAuth) as the rest of the API. An API token is a full-admin credential, so this just makes the surface consistent. The SPA page routes /panel/settings and /panel/xray are unchanged.

BREAKING CHANGE: the old /panel/setting/* and /panel/xray/* paths are removed. External callers must switch to the /panel/api/ prefix. Frontend call sites, API docs, the dev proxy, and the route-documentation test are updated to match.
2026-06-06 16:22:41 +02:00

58 lines
1.4 KiB
TypeScript

import { useEffect, useState } from 'react';
import { HttpUtil } from '@/utils';
import { parseMsg } from '@/utils/zodValidate';
import { DefaultsPayloadSchema } from '@/schemas/defaults';
type Calendar = 'gregorian' | 'jalalian';
let cachedValue: Calendar = 'gregorian';
let fetched = false;
let pending: Promise<void> | null = null;
const listeners = new Set<(value: Calendar) => void>();
function notify(value: Calendar) {
listeners.forEach((fn) => fn(value));
}
async function loadOnce(): Promise<void> {
if (fetched) return;
if (pending) {
await pending;
return;
}
pending = (async () => {
try {
const msg = await HttpUtil.post('/panel/api/setting/defaultSettings');
if (msg?.success) {
const validated = parseMsg(msg, DefaultsPayloadSchema, 'setting/defaultSettings');
cachedValue = validated.obj?.datepicker || 'gregorian';
notify(cachedValue);
}
} finally {
fetched = true;
pending = null;
}
})();
await pending;
}
export function setDatepicker(value: Calendar) {
fetched = true;
cachedValue = value || 'gregorian';
notify(cachedValue);
}
export function useDatepicker() {
const [datepicker, setLocal] = useState<Calendar>(cachedValue);
useEffect(() => {
listeners.add(setLocal);
loadOnce();
return () => {
listeners.delete(setLocal);
};
}, []);
return { datepicker };
}