This commit is contained in:
mrfelfel
2026-07-18 19:41:33 +03:30
parent 87ba0d253d
commit dfb0e857f1
158 changed files with 20278 additions and 0 deletions

172
src/pages/api/admin/save.ts Normal file
View File

@@ -0,0 +1,172 @@
import type { APIRoute } from 'astro';
import { requireAdmin } from '../../../lib/adminAuth';
import { readCms, writeCms, type PostStatus } from '../../../lib/cms';
import { publishPost } from '../../../lib/publisher';
import { getTassFeedLinks } from '../../../lib/tassAgent';
const toList = (value: FormDataEntryValue | null) => String(value ?? '')
.split(/\r?\n|,/)
.map((item) => item.trim())
.filter(Boolean);
const toParagraphs = (value: FormDataEntryValue | null) => String(value ?? '')
.split(/\n\s*\n/)
.map((item) => item.trim())
.filter(Boolean);
export const POST: APIRoute = async (context) => {
const unauthorized = requireAdmin(context);
if (unauthorized) {
return unauthorized;
}
const formData = await context.request.formData();
const action = String(formData.get('action') ?? '');
const cms = await readCms();
const tab = String(formData.get('tab') ?? 'pending');
if (action === 'post-status') {
const slug = String(formData.get('slug') ?? '');
const status = String(formData.get('status') ?? 'pending') as PostStatus;
cms.posts = cms.posts.map((post) => (
post.slug === slug ? { ...post, status } : post
));
}
if (action === 'toggle-post-flag') {
const slug = String(formData.get('slug') ?? '');
const flag = String(formData.get('flag') ?? '');
cms.posts = cms.posts.map((post) => {
if (post.slug !== slug) {
return post;
}
if (flag === 'urgent') {
return { ...post, urgent: !post.urgent };
}
if (flag === 'sidebar') {
return { ...post, sidebar: !post.sidebar };
}
return post;
});
}
if (action === 'set-breaking-post') {
const slug = String(formData.get('slug') ?? '');
const post = cms.posts.find((item) => item.slug === slug);
if (post) {
cms.settings.breakingNews = {
...cms.settings.breakingNews,
href: `/posts/${post.slug}/`,
items: [post.title],
postSlugs: [post.slug],
};
}
}
if (action === 'set-home-featured') {
const slug = String(formData.get('slug') ?? '');
cms.settings.homeLayout.featuredSlug = slug;
}
if (action === 'clear-tass-memory') {
cms.settings.agents = {
...cms.settings.agents,
tass: { processedLinks: [] },
};
}
if (action === 'fill-tass-memory') {
const links = cms.posts
.map((post) => post.sourceUrl)
.filter(Boolean) as string[];
const feedLinks = await getTassFeedLinks(50);
cms.settings.agents = {
...cms.settings.agents,
tass: { processedLinks: Array.from(new Set([...links, ...feedLinks])) },
};
}
if (action === 'delete-post') {
const slug = String(formData.get('slug') ?? '');
const confirm = String(formData.get('confirm') ?? '');
if (confirm !== 'confirm') {
return context.redirect(`/admin/?deleteError=1&tab=${encodeURIComponent(tab)}`, 302);
}
cms.posts = cms.posts.filter((post) => post.slug !== slug);
}
if (action === 'delete-all-posts') {
const confirm = String(formData.get('confirm') ?? '');
if (confirm !== 'confirm') {
return context.redirect(`/admin/?deleteError=1&tab=${encodeURIComponent(tab)}`, 302);
}
cms.posts = [];
}
if (action === 'save-post') {
const originalSlug = String(formData.get('originalSlug') ?? '');
const title = String(formData.get('title') ?? '').trim();
const post = await publishPost({
slug: String(formData.get('slug') ?? '') || title,
title,
category: String(formData.get('category') ?? cms.categories[0] ?? 'عمومی'),
time: String(formData.get('time') ?? '').trim() || 'هم‌اکنون',
readTime: String(formData.get('readTime') ?? '').trim() || '۳ دقیقه',
excerpt: String(formData.get('excerpt') ?? '').trim(),
status: String(formData.get('status') ?? 'pending') as PostStatus,
body: toParagraphs(formData.get('body')),
image: String(formData.get('image') ?? '').trim() || undefined,
thumbnail: String(formData.get('thumbnail') ?? '').trim() || undefined,
urgent: formData.get('urgent') === 'on',
sidebar: formData.get('sidebar') === 'on',
});
if (originalSlug && originalSlug !== post.slug) {
const updatedCms = await readCms();
updatedCms.posts = updatedCms.posts.filter((post) => post.slug !== originalSlug);
await writeCms(updatedCms);
}
return context.redirect(`/admin/?saved=1&tab=${post.status === 'approved' ? 'approved' : 'pending'}`, 302);
}
if (action === 'categories') {
cms.categories = toList(formData.get('categories'));
}
if (action === 'settings') {
cms.settings.breakingNews = {
label: String(formData.get('breakingLabel') ?? 'فوری').trim(),
href: String(formData.get('breakingHref') ?? '/').trim(),
items: toList(formData.get('breakingItems')),
postSlugs: toList(formData.get('breakingPostSlugs')),
};
cms.settings.hotTopics = toList(formData.get('hotTopics'));
cms.settings.homeLayout = {
featuredSlug: String(formData.get('featuredSlug') ?? '').trim(),
sideFeaturedSlugs: toList(formData.get('sideFeaturedSlugs')).slice(0, 2),
latestCount: Math.max(1, Number(formData.get('latestCount') ?? 4)),
showAd: formData.get('showAd') === 'on',
};
cms.settings.ad = {
enabled: formData.get('adEnabled') === 'on',
label: String(formData.get('adLabel') ?? 'آگهی').trim(),
href: String(formData.get('adHref') ?? '/advertise/').trim(),
text: String(formData.get('adText') ?? '').trim(),
};
}
await writeCms(cms);
return context.redirect(`/admin/?saved=1&tab=${encodeURIComponent(tab)}`, 302);
};