Import source: app/teknav-store
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
// teknav-store.js — Frontend state management via localStorage (ES module)
|
||||
import { TeknavData } from './teknav-data.js';
|
||||
|
||||
export const TeknavStore = (() => {
|
||||
const DATA_VERSION = '2026-05-02-v1';
|
||||
|
||||
const LS = {
|
||||
get: (k, def) => { try { const v = localStorage.getItem(k); return v ? JSON.parse(v) : def; } catch { return def; } },
|
||||
set: (k, v) => { try { localStorage.setItem(k, JSON.stringify(v)); } catch {} },
|
||||
};
|
||||
|
||||
// Version check — Clear old 2024 placeholder data
|
||||
if (localStorage.getItem('teknav_data_version') !== DATA_VERSION) {
|
||||
localStorage.removeItem('teknav_articles');
|
||||
localStorage.removeItem('teknav_activity');
|
||||
localStorage.setItem('teknav_data_version', DATA_VERSION);
|
||||
}
|
||||
|
||||
// Session
|
||||
const getUser = () => LS.get('teknav_user', null);
|
||||
const setUser = (user) => LS.set('teknav_user', user);
|
||||
const logout = () => { localStorage.removeItem('teknav_user'); };
|
||||
|
||||
const login = (_email, _password) => {
|
||||
// localStorage auth removed. All auth goes through /api/auth/login.
|
||||
return null;
|
||||
};
|
||||
|
||||
// Articles (seed + created)
|
||||
const getArticles = () => {
|
||||
const created = LS.get('teknav_articles', []);
|
||||
return [...TeknavData.articles, ...created];
|
||||
};
|
||||
|
||||
const createArticle = (article) => {
|
||||
const articles = LS.get('teknav_articles', []);
|
||||
const newArt = { ...article, id: 'art_' + Date.now(), date: new Date().toLocaleDateString('fa-IR'), views: 0, reactions: 0 };
|
||||
LS.set('teknav_articles', [newArt, ...articles]);
|
||||
addActivity('مقاله جدید ایجاد شد', newArt.title, 'draft');
|
||||
return newArt;
|
||||
};
|
||||
|
||||
const updateArticle = (id, updates) => {
|
||||
// Update in seed if exists
|
||||
const seedIdx = TeknavData.articles.findIndex(a => a.id === id);
|
||||
if (seedIdx !== -1) {
|
||||
Object.assign(TeknavData.articles[seedIdx], updates);
|
||||
return;
|
||||
}
|
||||
const articles = LS.get('teknav_articles', []);
|
||||
const idx = articles.findIndex(a => a.id === id);
|
||||
if (idx !== -1) { articles[idx] = { ...articles[idx], ...updates }; LS.set('teknav_articles', articles); }
|
||||
addActivity('مقاله ویرایش شد', updates.title || id, 'edit');
|
||||
};
|
||||
|
||||
const deleteArticle = (id) => {
|
||||
const articles = LS.get('teknav_articles', []);
|
||||
LS.set('teknav_articles', articles.filter(a => a.id !== id));
|
||||
addActivity('مقاله حذف شد', id, 'delete');
|
||||
};
|
||||
|
||||
// Saved articles
|
||||
const getSaved = () => LS.get('teknav_saved', []);
|
||||
const toggleSaved = (id) => {
|
||||
const saved = getSaved();
|
||||
const newSaved = saved.includes(id) ? saved.filter(s => s !== id) : [...saved, id];
|
||||
LS.set('teknav_saved', newSaved);
|
||||
return newSaved.includes(id);
|
||||
};
|
||||
const isSaved = (id) => getSaved().includes(id);
|
||||
|
||||
// Newsletter
|
||||
const subscribeNewsletter = (email) => {
|
||||
const subs = LS.get('teknav_newsletter', []);
|
||||
if (subs.includes(email)) return false;
|
||||
LS.set('teknav_newsletter', [...subs, email]);
|
||||
return true;
|
||||
};
|
||||
|
||||
// Reactions
|
||||
const getReactions = () => LS.get('teknav_reactions', {});
|
||||
const toggleReaction = (articleId, type) => {
|
||||
const reactions = getReactions();
|
||||
const key = `${articleId}_${type}`;
|
||||
const reacted = reactions[key];
|
||||
reactions[key] = !reacted;
|
||||
LS.set('teknav_reactions', reactions);
|
||||
return !reacted;
|
||||
};
|
||||
const hasReacted = (articleId, type) => getReactions()[`${articleId}_${type}`] || false;
|
||||
|
||||
// Activity log
|
||||
const getActivity = () => {
|
||||
const extra = LS.get('teknav_activity', []);
|
||||
return [...extra, ...TeknavData.activityLog];
|
||||
};
|
||||
const addActivity = (action, target, type) => {
|
||||
const log = LS.get('teknav_activity', []);
|
||||
const user = getUser();
|
||||
log.unshift({ id: Date.now(), user: user?.name || 'سیستم', action, target, time: 'همین الان', type });
|
||||
LS.set('teknav_activity', log.slice(0, 50));
|
||||
};
|
||||
|
||||
// Users management
|
||||
const getUsers = () => {
|
||||
const overrides = LS.get('teknav_users_override', {});
|
||||
return TeknavData.users.map(u => ({ ...u, ...(overrides[u.id] || {}) }));
|
||||
};
|
||||
const updateUser = (id, updates) => {
|
||||
const overrides = LS.get('teknav_users_override', {});
|
||||
overrides[id] = { ...(overrides[id] || {}), ...updates };
|
||||
LS.set('teknav_users_override', overrides);
|
||||
};
|
||||
|
||||
// Categories management
|
||||
const getCategories = () => {
|
||||
const extra = LS.get('teknav_categories', []);
|
||||
return [...TeknavData.categories, ...extra];
|
||||
};
|
||||
const addCategory = (cat) => {
|
||||
const cats = LS.get('teknav_categories', []);
|
||||
cats.push({ ...cat, id: 'cat_' + Date.now(), articleCount: 0, authorCount: 0, avgReadTime: 0 });
|
||||
LS.set('teknav_categories', cats);
|
||||
};
|
||||
const deleteCategory = (id) => {
|
||||
const cats = LS.get('teknav_categories', []);
|
||||
LS.set('teknav_categories', cats.filter(c => c.id !== id));
|
||||
};
|
||||
|
||||
// Tags management
|
||||
const getTags = () => {
|
||||
const extra = LS.get('teknav_tags', []);
|
||||
return [...TeknavData.tags, ...extra];
|
||||
};
|
||||
const addTag = (name) => {
|
||||
const tags = LS.get('teknav_tags', []);
|
||||
tags.push({ id: Date.now(), name, count: 0 });
|
||||
LS.set('teknav_tags', tags);
|
||||
};
|
||||
const deleteTag = (id) => {
|
||||
const tags = LS.get('teknav_tags', []);
|
||||
LS.set('teknav_tags', tags.filter(t => t.id !== id));
|
||||
};
|
||||
|
||||
return {
|
||||
getUser, setUser, logout, login,
|
||||
getArticles, createArticle, updateArticle, deleteArticle,
|
||||
getSaved, toggleSaved, isSaved,
|
||||
subscribeNewsletter,
|
||||
getReactions, toggleReaction, hasReacted,
|
||||
getActivity, addActivity,
|
||||
getUsers, updateUser,
|
||||
getCategories, addCategory, deleteCategory,
|
||||
getTags, addTag, deleteTag,
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user