refactor: global project hardening and integrity verification
- Add safety checks for direct Appwrite document index access across all root pages. - Harden NewsTicker and AdWrappers with robust fallback settings and length checks. - Apply strict typing to dashboard settings page and resolve icon conflicts. - Final global audit for deprecated Zod .errors usage (0 occurrences remaining). - Standardize PublicationLayout across creation and edit workflows for posts.
This commit is contained in:
parent
956360a693
commit
5279af2003
@ -13,7 +13,12 @@ async function fetchClasificadosData() {
|
||||
|
||||
// 1. Settings
|
||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {}) as Settings;
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {
|
||||
ticker_count: 10,
|
||||
rotation_seconds: 5,
|
||||
feed_news_count: 12,
|
||||
show_news_date: true
|
||||
}) as Settings;
|
||||
|
||||
const postsCount = settings.feed_news_count || 12;
|
||||
const cardSettings = {
|
||||
@ -30,7 +35,9 @@ async function fetchClasificadosData() {
|
||||
|
||||
let posts: Post[] = [];
|
||||
if (typeRes.documents.length > 0) {
|
||||
const typeId = typeRes.documents[0].$id;
|
||||
const firstType = typeRes.documents[0];
|
||||
const typeId = firstType?.$id;
|
||||
if (!typeId) return { posts: [], cardSettings };
|
||||
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||
Query.equal('tipo_publicacion_id', typeId),
|
||||
Query.equal('estado', 'Publicado'),
|
||||
|
||||
@ -2,11 +2,12 @@ import { APPWRITE_ALMEIRA_CONFIG } from '@/lib/appwrite';
|
||||
import { createSessionClient } from '@/lib/appwrite.server';
|
||||
import { getEntity, updateEntity } from '@/app/actions/entity';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { Settings, Save, Clock, Menu, Building, Image as ImageIcon, Link as LinkIcon, Share2 } from 'lucide-react';
|
||||
import { Settings as SettingsIcon, Save, Clock, Menu, Building, Image as ImageIcon, Link as LinkIcon, Share2 } from 'lucide-react';
|
||||
import { Settings as SettingsInterface } from '@/types/settings';
|
||||
|
||||
export default async function SettingsPage() {
|
||||
let settings = { ticker_count: 10, rotation_seconds: 5 };
|
||||
let docId = 'global_config';
|
||||
let settings: SettingsInterface = { ticker_count: 10, rotation_seconds: 5 };
|
||||
let docId = '';
|
||||
let entity: any = null;
|
||||
|
||||
try {
|
||||
@ -18,7 +19,7 @@ export default async function SettingsPage() {
|
||||
[]
|
||||
);
|
||||
if (response.documents.length > 0) {
|
||||
settings = response.documents[0] as any;
|
||||
settings = response.documents[0] as unknown as SettingsInterface;
|
||||
docId = response.documents[0].$id;
|
||||
}
|
||||
}
|
||||
@ -69,7 +70,7 @@ export default async function SettingsPage() {
|
||||
<div className="max-w-5xl mx-auto space-y-6 animate-fade-in pb-12">
|
||||
<div className="flex items-center gap-4 bg-slate-900 border border-slate-800 p-6 rounded-2xl shadow-xl shadow-cyan-500/5">
|
||||
<div className="p-3 bg-cyan-500/10 rounded-xl text-cyan-400">
|
||||
<Settings size={32} />
|
||||
<SettingsIcon size={32} />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-black font-outfit uppercase tracking-tighter text-white">
|
||||
@ -109,7 +110,7 @@ export default async function SettingsPage() {
|
||||
<input
|
||||
type="number"
|
||||
name="feed_news_count"
|
||||
defaultValue={(settings as any).feed_news_count || 12}
|
||||
defaultValue={settings.feed_news_count || 12}
|
||||
min="4" max="100"
|
||||
required
|
||||
className="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-3 text-white focus:border-cyan-400 text-xl font-black font-mono transition-all"
|
||||
@ -122,7 +123,7 @@ export default async function SettingsPage() {
|
||||
type="checkbox"
|
||||
name="show_news_date"
|
||||
value="true"
|
||||
defaultChecked={(settings as any).show_news_date === true}
|
||||
defaultChecked={settings.show_news_date === true}
|
||||
id="show_news_date"
|
||||
className="w-5 h-5 accent-cyan-500 cursor-pointer"
|
||||
/>
|
||||
|
||||
@ -13,7 +13,12 @@ async function fetchEventosData() {
|
||||
|
||||
// 1. Settings
|
||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {}) as Settings;
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {
|
||||
ticker_count: 10,
|
||||
rotation_seconds: 5,
|
||||
feed_news_count: 12,
|
||||
show_news_date: true
|
||||
}) as Settings;
|
||||
|
||||
const postsCount = settings.feed_news_count || 12;
|
||||
const cardSettings = {
|
||||
@ -30,7 +35,9 @@ async function fetchEventosData() {
|
||||
|
||||
let posts: Post[] = [];
|
||||
if (typeRes.documents.length > 0) {
|
||||
const typeId = typeRes.documents[0].$id;
|
||||
const firstType = typeRes.documents[0];
|
||||
const typeId = firstType?.$id;
|
||||
if (!typeId) return { posts: [], cardSettings };
|
||||
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||
Query.equal('tipo_publicacion_id', typeId),
|
||||
Query.equal('estado', 'Publicado'),
|
||||
|
||||
@ -15,7 +15,12 @@ async function fetchHomeData() {
|
||||
|
||||
// 1. Settings
|
||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {}) as Settings;
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {
|
||||
ticker_count: 10,
|
||||
rotation_seconds: 5,
|
||||
feed_news_count: 12,
|
||||
show_news_date: true
|
||||
}) as Settings;
|
||||
|
||||
const postsCount = settings.feed_news_count || 12;
|
||||
const cardSettings = {
|
||||
@ -32,7 +37,9 @@ async function fetchHomeData() {
|
||||
|
||||
let posts: Post[] = [];
|
||||
if (typeRes.documents.length > 0) {
|
||||
const typeId = typeRes.documents[0].$id;
|
||||
const firstType = typeRes.documents[0];
|
||||
const typeId = firstType?.$id;
|
||||
if (!typeId) return { posts: [], cardSettings };
|
||||
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||
Query.equal('tipo_publicacion_id', typeId),
|
||||
Query.equal('estado', 'Publicado'),
|
||||
|
||||
@ -8,12 +8,12 @@ import { Settings } from '@/types/settings';
|
||||
async function fetchSettings(): Promise<Settings> {
|
||||
try {
|
||||
const client = await createAdminClient();
|
||||
const res = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', [Query.limit(1)]);
|
||||
if (res.documents.length > 0) return res.documents[0] as unknown as Settings;
|
||||
const res = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', [Query.limit(1)]);
|
||||
if (res.documents.length > 0) return res.documents[0] as unknown as Settings;
|
||||
} catch(e) {
|
||||
console.error("fetchSettings error:", e);
|
||||
}
|
||||
return { rotation_seconds: 5, ticker_count: 10 };
|
||||
return { rotation_seconds: 5, ticker_count: 10, feed_news_count: 12, show_news_date: true };
|
||||
}
|
||||
|
||||
export async function GlobalTopBanner() {
|
||||
@ -27,7 +27,9 @@ export async function GlobalTopBanner() {
|
||||
]);
|
||||
|
||||
if (typesRes.documents.length > 0) {
|
||||
const typeId = typesRes.documents[0].$id;
|
||||
const firstType = typesRes.documents[0];
|
||||
const typeId = firstType?.$id;
|
||||
if (!typeId) return null;
|
||||
|
||||
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||
Query.equal('tipo_publicacion_id', typeId),
|
||||
|
||||
@ -19,7 +19,12 @@ export default async function NewsTicker() {
|
||||
|
||||
// 1. Fetch Settings
|
||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {}) as Settings;
|
||||
const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : {
|
||||
ticker_count: 10,
|
||||
rotation_seconds: 5,
|
||||
feed_news_count: 12,
|
||||
show_news_date: true
|
||||
}) as Settings;
|
||||
const tickerCount = settings.ticker_count || 10;
|
||||
|
||||
// 2. Fetch News (NOTICIA)
|
||||
@ -28,7 +33,9 @@ export default async function NewsTicker() {
|
||||
]);
|
||||
|
||||
if (typeRes.documents.length > 0) {
|
||||
const typeId = typeRes.documents[0].$id;
|
||||
const firstType = typeRes.documents[0];
|
||||
const typeId = firstType?.$id;
|
||||
if (!typeId) throw new Error("Could not find typeId for NOTICIA");
|
||||
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||
Query.equal('tipo_publicacion_id', typeId),
|
||||
Query.equal('estado', 'Publicado'),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user