167 lines
3.5 KiB
JavaScript
167 lines
3.5 KiB
JavaScript
|
|
const config = require("../config/index");
|
||
|
|
const messages = require("../constants/messages");
|
||
|
|
const { formatDate } = require("../utils/date");
|
||
|
|
|
||
|
|
const STORAGE_KEYS = {
|
||
|
|
favorites: "naming:favorites",
|
||
|
|
quotaPrefix: "naming:quota:"
|
||
|
|
};
|
||
|
|
|
||
|
|
function createDefaultForm() {
|
||
|
|
return {
|
||
|
|
surname: "",
|
||
|
|
gender: "male",
|
||
|
|
birthDate: formatDate(new Date()),
|
||
|
|
birthTime: "",
|
||
|
|
nameLength: "double"
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const state = {
|
||
|
|
form: createDefaultForm(),
|
||
|
|
results: [],
|
||
|
|
favorites: [],
|
||
|
|
quota: {
|
||
|
|
date: "",
|
||
|
|
count: 0
|
||
|
|
},
|
||
|
|
lastError: ""
|
||
|
|
};
|
||
|
|
|
||
|
|
function getQuotaStorageKey(dateStr) {
|
||
|
|
return `${STORAGE_KEYS.quotaPrefix}${dateStr.replace(/-/g, "")}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function safeGetStorage(key, fallback) {
|
||
|
|
if (typeof tt === "undefined" || !tt.getStorageSync) {
|
||
|
|
return fallback;
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
const value = tt.getStorageSync(key);
|
||
|
|
return value === undefined || value === null ? fallback : value;
|
||
|
|
} catch (error) {
|
||
|
|
console.warn(`getStorageSync failed for key ${key}`, error);
|
||
|
|
return fallback;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function safeSetStorage(key, value) {
|
||
|
|
if (typeof tt === "undefined" || !tt.setStorageSync) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
tt.setStorageSync(key, value);
|
||
|
|
} catch (error) {
|
||
|
|
console.warn(`setStorageSync failed for key ${key}`, error);
|
||
|
|
state.lastError = error.message || "storage_error";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function syncQuota() {
|
||
|
|
const today = formatDate(new Date());
|
||
|
|
const storageKey = getQuotaStorageKey(today);
|
||
|
|
const storedCount = safeGetStorage(storageKey, 0);
|
||
|
|
const count = typeof storedCount === "number" ? storedCount : 0;
|
||
|
|
state.quota = {
|
||
|
|
date: today,
|
||
|
|
count
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function incrementQuota() {
|
||
|
|
const today = formatDate(new Date());
|
||
|
|
if (state.quota.date !== today) {
|
||
|
|
syncQuota();
|
||
|
|
}
|
||
|
|
const nextCount = state.quota.count + 1;
|
||
|
|
state.quota = {
|
||
|
|
date: today,
|
||
|
|
count: nextCount
|
||
|
|
};
|
||
|
|
safeSetStorage(getQuotaStorageKey(today), nextCount);
|
||
|
|
}
|
||
|
|
|
||
|
|
function canGenerateToday() {
|
||
|
|
const today = formatDate(new Date());
|
||
|
|
if (state.quota.date !== today) {
|
||
|
|
syncQuota();
|
||
|
|
}
|
||
|
|
return state.quota.count < config.maxDailyQuota;
|
||
|
|
}
|
||
|
|
|
||
|
|
function setForm(partial) {
|
||
|
|
state.form = Object.assign({}, state.form, partial);
|
||
|
|
}
|
||
|
|
|
||
|
|
function resetForm() {
|
||
|
|
state.form = createDefaultForm();
|
||
|
|
}
|
||
|
|
|
||
|
|
function setResults(results) {
|
||
|
|
state.results = Array.isArray(results) ? results : [];
|
||
|
|
}
|
||
|
|
|
||
|
|
function clearResults() {
|
||
|
|
state.results = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
function loadFavorites() {
|
||
|
|
const stored = safeGetStorage(STORAGE_KEYS.favorites, []);
|
||
|
|
state.favorites = Array.isArray(stored) ? stored : [];
|
||
|
|
}
|
||
|
|
|
||
|
|
function saveFavorites() {
|
||
|
|
safeSetStorage(STORAGE_KEYS.favorites, state.favorites);
|
||
|
|
}
|
||
|
|
|
||
|
|
function addFavorite(item) {
|
||
|
|
if (!item || !item.name) {
|
||
|
|
state.lastError = messages.GENERATION_FAILED;
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const timestamp = Date.now();
|
||
|
|
const newItem = {
|
||
|
|
id: `${item.name}_${timestamp}`,
|
||
|
|
name: item.name,
|
||
|
|
meaning: item.meaning || "",
|
||
|
|
createdAt: new Date(timestamp).toISOString()
|
||
|
|
};
|
||
|
|
const existingIndex = state.favorites.findIndex((fav) => fav.name === item.name);
|
||
|
|
if (existingIndex >= 0) {
|
||
|
|
state.favorites.splice(existingIndex, 1, newItem);
|
||
|
|
} else {
|
||
|
|
state.favorites.unshift(newItem);
|
||
|
|
}
|
||
|
|
saveFavorites();
|
||
|
|
return newItem;
|
||
|
|
}
|
||
|
|
|
||
|
|
function removeFavorite(id) {
|
||
|
|
const nextList = state.favorites.filter((favorite) => favorite.id !== id);
|
||
|
|
state.favorites = nextList;
|
||
|
|
saveFavorites();
|
||
|
|
}
|
||
|
|
|
||
|
|
function getState() {
|
||
|
|
return state;
|
||
|
|
}
|
||
|
|
|
||
|
|
function initStore() {
|
||
|
|
syncQuota();
|
||
|
|
loadFavorites();
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
initStore,
|
||
|
|
getState,
|
||
|
|
setForm,
|
||
|
|
resetForm,
|
||
|
|
setResults,
|
||
|
|
clearResults,
|
||
|
|
canGenerateToday,
|
||
|
|
incrementQuota,
|
||
|
|
addFavorite,
|
||
|
|
removeFavorite,
|
||
|
|
loadFavorites
|
||
|
|
};
|