Merge pull request 'this Application is unfinshed and pending works in (UI,Logical Workflows)last git push by Hasan (28/7/2026)' (#19) from hasan_frontend into dev

Reviewed-on: https://gitea.maskantech.in/gitea_admin/productcatalogue_frontend/pulls/19
This commit is contained in:
Hasan
2026-07-28 05:37:55 +00:00
+47 -38
View File
@@ -4,80 +4,89 @@
* Single Responsibility: Orchestrate theme business logic.
*
* This service is the ONLY layer that knows about both storage and DOM.
* It delegates:
* - Persistence → theme.storage.ts
* - DOM mutation → applyTheme.ts (utils)
*
* FUTURE API INTEGRATION:
* When a backend API is introduced, only this file changes.
* The storage layer, DOM utility, context, and hook remain untouched.
* Pattern: replace loadTheme() / saveTheme() calls with API calls,
* keeping the same method signatures.
*
* RULES:
* - No React imports.
* - No JSX.
* - No component access.
* It delegates persistence to the backend database via REST API.
*/
import type { Theme } from "../types/theme.types";
import {
loadTheme as storageLoad,
saveTheme as storageSave,
clearTheme as storageClear,
} from "../storage/theme.storage";
import apiClient from "../api/axiosInstance";
import { applyTheme as applyThemeToDom } from "../utils/applyTheme";
import { DEFAULT_THEME, AVAILABLE_THEMES } from "../constants/themes";
export { DEFAULT_THEME, AVAILABLE_THEMES };
let currentTheme: Theme = DEFAULT_THEME;
// Load user theme preference asynchronously during application initialization (module import)
try {
const token = localStorage.getItem("accessToken");
if (token) {
const response = await apiClient.get<{ success: boolean; data: { themeCode: string } }>("/api/v1/settings/theme");
if (response && response.success && response.data?.themeCode) {
const themeCode = response.data.themeCode;
const found = AVAILABLE_THEMES.find((t) => t.id === themeCode);
if (found) {
currentTheme = found;
}
}
}
} catch (error) {
console.error("Failed to load user theme preference asynchronously at startup:", error);
}
// Apply the resolved theme to the DOM immediately prior to React tree mount
applyThemeToDom(currentTheme.palette);
if (typeof document !== "undefined") {
if (currentTheme.mode === "dark") {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
}
// ─────────────────────────────────────────────────────────────────────────────
// PUBLIC SERVICE METHODS
// ─────────────────────────────────────────────────────────────────────────────
/**
* Returns the currently persisted theme from storage.
* Falls back to DEFAULT_THEME if nothing is saved or storage fails.
* Returns the loaded theme.
*/
export function getCurrentTheme(): Theme {
const saved = storageLoad();
if (!saved) return DEFAULT_THEME;
// If the saved theme id still exists in the registry, use it.
// Otherwise (e.g. default changed), fall back to DEFAULT_THEME.
const exists = AVAILABLE_THEMES.some((t) => t.id === saved.id);
return exists ? saved : DEFAULT_THEME;
return currentTheme;
}
/**
* Returns all themes available for selection.
* Future: merge with API-fetched tenant themes.
*/
export function getAvailableThemes(): Theme[] {
return AVAILABLE_THEMES;
}
/**
* Persists a theme to storage.
* Does NOT apply it to the DOM — call applyTheme() separately if needed.
* Persists a theme to the backend database.
*
* @param theme - The theme to persist.
*/
export function saveTheme(theme: Theme): void {
storageSave(theme);
currentTheme = theme;
const themeCode = (theme as any).code || theme.id;
apiClient.put("/api/v1/settings/theme", { themeCode })
.catch((err) => {
console.error("Failed to save theme preference to DB:", err);
});
}
/**
* Resets to the default theme:
* 1. Clears persisted theme from storage.
* 2. Removes all runtime CSS variable overrides from the DOM.
* The static @theme values in index.css take effect again.
* Resets to the default theme.
*
* @returns The default theme, so the caller can update its state.
*/
export function resetTheme(): Theme {
storageClear();
// Apply explicitly so the DOM reflects DEFAULT_THEME (Royal Purple),
// matching the static @theme values in index.css.
currentTheme = DEFAULT_THEME;
apiClient.put("/api/v1/settings/theme", { themeCode: DEFAULT_THEME.id })
.catch((err) => {
console.error("Failed to reset theme preference on DB:", err);
});
applyThemeToDom(DEFAULT_THEME.palette);
if (typeof document !== "undefined") {
document.documentElement.classList.remove("dark");