Files
2026-06-06 18:43:00 +08:00

202 lines
6.5 KiB
JavaScript

import { defineStore } from 'pinia'
export const useUIStore = defineStore('ui', {
state: () => ({
appName: 'BukidBounty',
appLogo: '/assets/mainlogo.png',
pageTitle: 'BukidBounty',
isFullWidth: false,
showHeader: true,
showBottomNav: true,
darkMode: localStorage.getItem('dark_mode') === 'true',
disabledPages: [],
top_up_enabled: false,
app_mode: 'corporate',
defaultOrgType: 'COOPERATIVE',
groupTypes: ['COOPERATIVE', 'NGO', 'CORPORATION'],
mainOrganization: null,
mainOrganizationData: null,
primaryColor: null,
accentColor: null,
backgroundTint: null,
moduleStates: {},
lastSynced: null,
bibleVerseText: '',
bibleVerseReference: ''
}),
getters: {
isModuleEnabled: (state) => (key) => {
if (!key) return true;
if (!state.moduleStates || !Object.prototype.hasOwnProperty.call(state.moduleStates, key)) {
return true;
}
return state.moduleStates[key] !== false;
}
},
actions: {
setHeaderVisibility(visible) {
this.showHeader = visible
},
setBottomNavVisibility(visible) {
this.showBottomNav = visible
},
setPageTitle(title) {
this.pageTitle = title
document.title = title
},
resetPageTitle() {
this.pageTitle = this.appName
document.title = this.appName
this.isFullWidth = false
this.showHeader = true
this.showBottomNav = true
},
setFullWidth(isFull) {
this.isFullWidth = isFull
},
setDarkMode(isDark) {
this.darkMode = isDark
localStorage.setItem('dark_mode', isDark)
},
setAppName(name) {
if (name) {
const oldName = this.appName;
this.appName = name;
// If the current title is the old app name or the default, update it to the new name
if (this.pageTitle === oldName || this.pageTitle === 'BukidBounty' || this.pageTitle === 'Bukid Bounty App') {
this.setPageTitle(name);
}
}
},
setDisabledPages(pages) {
this.disabledPages = Array.isArray(pages) ? pages : [];
},
async refreshSettings() {
try {
const response = await fetch('/api/public/system-settings');
const result = await response.json();
if (result.success && result.data) {
this.syncSettings(result.data);
this.lastSynced = new Date().toISOString();
}
} catch (error) {
console.error('Failed to refresh system settings:', error);
}
},
syncSettings(settings) {
if (settings && typeof settings === 'object') {
const isDark = settings.dark_mode ?? settings.darkmode ?? this.darkMode;
this.setDarkMode(!!isDark);
if (settings.app_name) {
this.setAppName(settings.app_name);
}
if (settings.app_logo_url) {
this.appLogo = settings.app_logo_url;
}
this.applyBrandPalette({
primary: settings.primary_color,
accent: settings.accent_color,
tint: settings.background_tint,
});
if (settings.disabled_pages) {
try {
const dp = typeof settings.disabled_pages === 'string'
? JSON.parse(settings.disabled_pages)
: settings.disabled_pages;
this.setDisabledPages(dp);
} catch (e) { console.error('Failed to parse disabled_pages', e) }
}
if (settings.module_states && typeof settings.module_states === 'object') {
const normalized = {};
for (const [k, v] of Object.entries(settings.module_states)) {
normalized[k] = v === true || v === 'true' || v === 1 || v === '1';
}
this.moduleStates = normalized;
}
if (settings.hasOwnProperty('top_up_enabled')) {
this.top_up_enabled = settings.top_up_enabled === true || settings.top_up_enabled === 'true' || settings.top_up_enabled === '1' || settings.top_up_enabled === 1;
}
if (settings.app_mode) {
this.app_mode = settings.app_mode;
}
if (settings.hasOwnProperty('main_organization')) {
this.mainOrganization = settings.main_organization || null;
}
if (settings.hasOwnProperty('main_organization_data')) {
this.mainOrganizationData = settings.main_organization_data || null;
}
if (settings.default_org_type) {
this.defaultOrgType = settings.default_org_type;
}
if (settings.group_types) {
try {
const gt = typeof settings.group_types === 'string'
? JSON.parse(settings.group_types)
: settings.group_types;
if (Array.isArray(gt) && gt.length > 0) {
this.groupTypes = gt;
}
} catch (e) { /* keep default */ }
}
if (settings.hasOwnProperty('bible_verse_text')) {
this.bibleVerseText = settings.bible_verse_text || '';
}
if (settings.hasOwnProperty('bible_verse_reference')) {
this.bibleVerseReference = settings.bible_verse_reference || '';
}
this.lastSynced = new Date().toISOString();
}
},
applyBrandPalette({ primary, accent, tint }) {
const root = typeof document !== 'undefined' ? document.documentElement : null;
if (!root) return;
const isHex = (v) => typeof v === 'string' && /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v.trim());
const hexToRgb = (hex) => {
let h = hex.trim().replace('#', '');
if (h.length === 3) h = h.split('').map(c => c + c).join('');
const n = parseInt(h, 16);
return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };
};
if (isHex(primary)) {
const { r, g, b } = hexToRgb(primary);
this.primaryColor = primary;
root.style.setProperty('--brand-primary', primary);
root.style.setProperty('--brand-primary-rgb', `${r}, ${g}, ${b}`);
root.style.setProperty('--accent-color', primary);
root.style.setProperty('--accent-soft', `rgba(${r}, ${g}, ${b}, 0.12)`);
}
if (isHex(accent)) {
const { r, g, b } = hexToRgb(accent);
this.accentColor = accent;
root.style.setProperty('--brand-accent', accent);
root.style.setProperty('--brand-accent-rgb', `${r}, ${g}, ${b}`);
}
if (isHex(tint)) {
this.backgroundTint = tint;
root.style.setProperty('--brand-tint', tint);
}
},
syncDisabledPages(pages) {
if (Array.isArray(pages)) {
this.setDisabledPages(pages);
this.lastSynced = new Date().toISOString();
}
}
}
})