import { useState, useRef, useEffect } from "react";
// ─── SYSTEM PROMPT ────────────────────────────────────────────────────────────
const SYSTEM_PROMPT = `أنت "المساعد الذكي في أمن وسرية الوثائق والمعلومات". مهمتك تقديم استشارات متكاملة وشاملة تجمع بين معايير ISO الدولية الرائدة في إدارة الوثائق وأمن المعلومات.
**المعايير المرجعية التي تستند إليها:**
- ISO 15489-1 & 15489-2: إدارة الوثائق والسجلات (المتطلبات والمفاهيم)
- ISO 16175-1 & 16175-2: مبادئ وأداء الوظائف لسجلات الأعمال
- ISO 27001:2022: نظام إدارة أمن المعلومات (ISMS)
- ISO 27002:2022: ضوابط أمن المعلومات
- ISO 27005: إدارة مخاطر أمن المعلومات
- ISO 30300/30301: نظام إدارة الوثائق (MoRS)
- ISO 14721 (OAIS): نموذج المعلومات الأرشيفية المفتوح
- NIST SP 800-53 / 800-88: ضوابط الأمن والخصوصية وإتلاف الوسائط
**الأقسام المتخصصة التي تغطيها:**
[قسم 1 - تصنيف الوثائق]:
- بناء مخطط التصنيف الوظيفي (BCS) وفق ISO 15489 البند 9.4 و ISO 15836
- تحليل القيمة الأولية والثانوية للوثيقة
- هيكل التصنيف الهرمي: وظيفة → نشاط → معاملة → وثيقة
- معايير الأهمية: إدارية، قانونية، مالية، تاريخية
- ربط التصنيف بمستوى السرية وفترة الاستبقاء تلقائياً
[قسم 2 - الوثائق السرية]:
- بروتوكولات التعامل مع الوثائق وفق مستويات السرية: عام / مقيد / سري / سري للغاية
- ضوابط وصول CIA Triad: السرية والنزاهة والتوافر
- تطبيق IRM (إدارة حقوق المعلومات) على الوثائق الرقمية
- التشفير: AES-256 للتخزين، TLS 1.3 للنقل، PKI للتوقيع
- إجراءات التعامل المادي: التخزين في خزائن مقاومة، وضع علامات التصنيف
- المعيار المرجعي: ISO 27001 الملحق A.8 + ISO 27002 البنود 8.1-8.3
[قسم 3 - الإتلاف الآمن]:
- بناء جداول الاستبقاء وفق المتطلبات القانونية والتشغيلية
- آليات الإتلاف الورقي: التقطيع بمعيار DIN 66399 المستوى P-4 فأعلى
- الإتلاف الرقمي: الكتابة الفوق (Overwrite) × 7 مرات أو التدمير المغناطيسي (Degaussing)
- وثائق شهادة الإتلاف ومتطلبات التوثيق
- لجنة الإتلاف: التشكيل والصلاحيات والإجراءات
- المعيار المرجعي: ISO 15489 البند 9.9 + ISO 27002 البند 8.10 + NIST SP 800-88
[قسم 4 - الوثائق الإلكترونية]:
- صيغ الحفظ الرقمي طويل الأمد: PDF/A-3، TIFF، XML، ODF
- نموذج OAIS (ISO 14721) لإدارة الأرشيف الرقمي
- استراتيجية الحفاظ الرقمي: التحويل، التحاكي (Emulation)، التجديد (Refreshing)
- البيانات الوصفية: Dublin Core + ISO 23081 للأرشيف الرقمي
- النسخ الاحتياطي: قاعدة 3-2-1-1 مع التحقق الدوري من السلامة (Hash Verification)
- الأمن السحابي: ISO 27017 + ISO 27018 لحماية البيانات الشخصية
[قسم 5 - تسريب المعلومات]:
- إطار منع تسريب البيانات DLP: الشبكة / النقطة / السحابة
- اكتشاف التهديدات الداخلية (Insider Threats): المراقبة السلوكية UEBA
- خطة الاستجابة للاختراق: الاحتواء، الاستئصال، الاسترداد، الإبلاغ
- الإبلاغ عن الحوادث: المتطلبات القانونية (GDPR 72 ساعة، ISO 27001 A.6.8)
- التحقيق الجنائي الرقمي (Digital Forensics) وحفظ الأدلة
- التدريب والتوعية: بروتوكولات مكافحة الهندسة الاجتماعية
**قواعد الإجابة الذكية:**
1. حدد القسم المناسب للاستفسار وأجب من منظوره المتخصص
2. اربط كل إجراء عملي بالمعيار الدولي المحدد (اسم المعيار + رقم البند)
3. قدم إجابة منظمة: تحليل المشكلة ← الضوابط المطلوبة ← خطوات التطبيق ← مؤشر الامتثال
4. استخدم الجداول والقوائم للمقارنات والمتطلبات المتعددة
5. عند تقاطع أكثر من قسم، أشر للترابط بين المعايير
6. اختم كل إجابة بـ"مؤشر الامتثال" يوضح مستوى التطبيق المطلوب
7. اللغة: عربية فصحى واضحة مع المصطلحات التقنية باللغتين عند الحاجة
**تذكر:** أنت شريك استراتيجي يقود المؤسسات نحو النضج في حوكمة الوثائق وأمن المعلومات.`;
// ─── SECTIONS ─────────────────────────────────────────────────────────────────
const SECTIONS = [
{
id: "home", icon: "🏠", label: "الرئيسية",
color: "#C9A84C", desc: "", isoTags: [], questions: [],
},
{
id: "classification", icon: "📂", label: "تصنيف الوثائق",
color: "#4A9EDB", badge: "ISO 15489",
desc: "بناء مخططات التصنيف الوظيفي وتحديد القيمة الإدارية",
isoTags: ["ISO 15489", "ISO 16175"],
questions: [
"كيف أبني مخطط التصنيف الوظيفي (BCS) لمؤسستي؟",
"ما معايير تحديد القيمة الأولية والثانوية للوثيقة؟",
"كيف أصمم هيكلاً هرمياً للتصنيف من الوظيفة إلى الوثيقة؟",
"كيف يرتبط التصنيف بمستوى السرية وفترة الاستبقاء تلقائياً؟",
],
},
{
id: "confidential", icon: "🔐", label: "الوثائق السرية",
color: "#E85D75", badge: "ISO 27001",
desc: "بروتوكولات التعامل مع الوثائق الحساسة وضوابط الحماية الشاملة",
isoTags: ["ISO 27001", "ISO 27002"],
questions: [
"ما مستويات تصنيف السرية وضوابط كل مستوى؟",
"كيف أطبق IRM لحماية الوثائق الرقمية السرية؟",
"ما بروتوكولات التعامل المادي مع الوثائق سرية للغاية؟",
"كيف أطبق التشفير AES-256 على الوثائق المخزنة؟",
],
},
{
id: "destruction", icon: "🗑️", label: "الإتلاف الآمن",
color: "#F4A261", badge: "ISO 15489 + NIST",
desc: "سياسات التخلص الآمن من الوثائق المنتهية ورقياً ورقمياً",
isoTags: ["ISO 15489", "NIST 800-88"],
questions: [
"كيف أبني جدول استبقاء متوافق مع المتطلبات القانونية؟",
"ما معايير التقطيع الورقي الآمن وفق DIN 66399؟",
"كيف أتلف البيانات الرقمية بشكل غير قابل للاسترداد؟",
"ما محتويات شهادة الإتلاف الرسمية ومتطلباتها؟",
],
},
{
id: "digital", icon: "💾", label: "الوثائق الإلكترونية",
color: "#56CFB2", badge: "ISO 14721",
desc: "الحفظ الرقمي طويل الأمد والمعايير التقنية للأرشيف الإلكتروني",
isoTags: ["ISO 14721", "ISO 16175"],
questions: [
"ما صيغ الملفات الموصى بها للحفظ الرقمي طويل الأمد؟",
"كيف أطبق نموذج OAIS لإدارة الأرشيف الرقمي؟",
"ما استراتيجيات الحفاظ الرقمي وكيف أختار المناسب؟",
"كيف أبني نظام نسخ احتياطي وفق قاعدة 3-2-1-1؟",
],
},
{
id: "leak", icon: "🚨", label: "تسريب المعلومات",
color: "#A855F7", badge: "ISO 27001",
desc: "إجراءات منع التسريب والتعامل مع الاختراقات البشرية والتقنية",
isoTags: ["ISO 27001", "ISO 27002"],
questions: [
"كيف أبني إطار DLP لمنع تسريب البيانات؟",
"ما إجراءات الاستجابة الفورية عند اكتشاف اختراق؟",
"كيف أكشف التهديدات الداخلية باستخدام UEBA؟",
"ما متطلبات الإبلاغ القانوني عن حوادث تسريب البيانات؟",
],
},
];
// ─── HELPERS ──────────────────────────────────────────────────────────────────
function getColor(id) {
return SECTIONS.find(s => s.id === id)?.color || "#C9A84C";
}
function IsoTag({ label, color }) {
return (
{label}
);
}
function TypingIndicator() {
return (
{[0, 1, 2].map(i => (
))}
);
}
// ─── MESSAGE BUBBLE ───────────────────────────────────────────────────────────
function MessageBlock({ msg, sectionId }) {
const isUser = msg.role === "user";
const section = SECTIONS.find(s => s.id === sectionId);
const color = getColor(sectionId);
return (
{isUser ? "👤" : (section?.icon || "🤖")}
{msg.content}
{!isUser && section && section.id !== "home" && (
{section.isoTags?.map(t => )}
)}
);
}
// ─── SIDEBAR ──────────────────────────────────────────────────────────────────
function Sidebar({ active, onSelect, collapsed, onToggle }) {
return (
{/* Toggle */}
{ e.currentTarget.style.color = "#C9A84C"; }}
onMouseLeave={e => { e.currentTarget.style.color = "#8a7040"; }}
>
{collapsed ? "◀" : "▶"}
{!collapsed && (
القائمة الرئيسية
)}
{SECTIONS.map(sec => {
const isActive = active === sec.id;
const c = sec.color;
return (
onSelect(sec.id)}
title={collapsed ? sec.label : ""}
style={{
background: isActive ? `${c}18` : "transparent",
border: isActive ? `1px solid ${c}38` : "1px solid transparent",
borderRadius: "9px", padding: collapsed ? "11px 0" : "10px 11px",
cursor: "pointer", display: "flex", alignItems: "center",
gap: "9px", justifyContent: collapsed ? "center" : "flex-end",
width: "100%", transition: "all 0.18s", textAlign: "right",
}}
onMouseEnter={e => { if (!isActive) e.currentTarget.style.background = `${c}0d`; }}
onMouseLeave={e => { if (!isActive) e.currentTarget.style.background = "transparent"; }}
>
{!collapsed && (
{sec.label}
)}
{sec.icon}
{isActive && !collapsed && (
)}
);
})}
{!collapsed && (
ISO 15489 · ISO 16175 ISO 27001 · ISO 14721 NIST SP 800-88
)}
);
}
// ─── HOME SCREEN ──────────────────────────────────────────────────────────────
function HomeScreen({ onSelect, onSend }) {
return (
🛡️
المساعد الذكي في أمن وسرية الوثائق والمعلومات
ISO 15489 · ISO 16175 · ISO 27001 · ISO 14721 · NIST SP 800-88
✦ الأقسام المتخصصة
{SECTIONS.filter(s => s.id !== "home").map(sec => (
onSelect(sec.id)} style={{
background: `linear-gradient(135deg,${sec.color}0f,${sec.color}05)`,
border: `1px solid ${sec.color}28`,
borderRadius: "11px", padding: "13px 11px",
cursor: "pointer", textAlign: "right", direction: "rtl",
transition: "all 0.22s",
}}
onMouseEnter={e => {
e.currentTarget.style.background = `linear-gradient(135deg,${sec.color}20,${sec.color}0a)`;
e.currentTarget.style.borderColor = `${sec.color}4a`;
e.currentTarget.style.transform = "translateY(-2px)";
}}
onMouseLeave={e => {
e.currentTarget.style.background = `linear-gradient(135deg,${sec.color}0f,${sec.color}05)`;
e.currentTarget.style.borderColor = `${sec.color}28`;
e.currentTarget.style.transform = "translateY(0)";
}}
>
{sec.label}
{sec.icon}
{sec.desc}
))}
✦ أسئلة شائعة
{[
"ما الفرق بين ISO 15489 و ISO 16175 في إدارة الوثائق؟",
"كيف أبدأ تطبيق ISO 27001 في مؤسستي من الصفر؟",
"ما علاقة ISO 14721 بالحفاظ الرقمي طويل الأمد؟",
].map((q, i) => (
onSend(q)} style={{
background: "rgba(201,168,76,0.04)", border: "1px solid rgba(201,168,76,0.1)",
borderRadius: "9px", padding: "10px 14px", color: "#6a7a88",
fontSize: "12px", cursor: "pointer", textAlign: "right",
width: "100%", marginBottom: "7px", fontFamily: "'Cairo', sans-serif",
direction: "rtl", transition: "all 0.18s",
}}
onMouseEnter={e => { e.currentTarget.style.borderColor = "#C9A84C55"; e.currentTarget.style.color = "#C9A84C"; }}
onMouseLeave={e => { e.currentTarget.style.borderColor = "rgba(201,168,76,0.1)"; e.currentTarget.style.color = "#6a7a88"; }}
>
{q}
))}
);
}
// ─── SECTION CONTENT ──────────────────────────────────────────────────────────
function SectionContent({ section, messages, loading, error, onSend, bottomRef }) {
const color = section.color;
const hasMessages = messages.length > 0;
return (
{/* Banner */}
{section.icon}
{section.label}
{section.desc}
{section.isoTags?.map(t => )}
{/* Messages or Suggestions */}
{!hasMessages ? (
✦ أسئلة شائعة في هذا القسم
{section.questions.map((q, i) => (
onSend(q)} style={{
background: `${color}09`, border: `1px solid ${color}1e`,
borderRadius: "9px", padding: "11px 14px", color: "#6a7888",
fontSize: "12.5px", cursor: "pointer", textAlign: "right",
fontFamily: "'Cairo', sans-serif", direction: "rtl",
transition: "all 0.18s", width: "100%",
}}
onMouseEnter={e => { e.currentTarget.style.background = `${color}18`; e.currentTarget.style.color = color; e.currentTarget.style.borderColor = `${color}44`; }}
onMouseLeave={e => { e.currentTarget.style.background = `${color}09`; e.currentTarget.style.color = "#6a7888"; e.currentTarget.style.borderColor = `${color}1e`; }}
>
{q}
))}
) : (
{messages.map((msg, i) => (
))}
{loading && (
{section.icon}
جارٍ تحليل الاستفسار وفق المعايير الدولية...
)}
{error && (
⚠️ {error}
)}
)}
);
}
// ─── MAIN APP ─────────────────────────────────────────────────────────────────
export default function ISOConsultant() {
const [active, setActive] = useState("home");
const [sectionMsgs, setSectionMsgs] = useState({});
const [input, setInput] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [collapsed, setCollapsed] = useState(false);
const bottomRef = useRef(null);
const textareaRef = useRef(null);
const currentSection = SECTIONS.find(s => s.id === active);
const currentMsgs = sectionMsgs[active] || [];
const color = getColor(active);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}, [sectionMsgs, loading, active]);
const sendMessage = async (text) => {
const txt = (text || input).trim();
if (!txt || loading) return;
setInput("");
setError(null);
if (textareaRef.current) { textareaRef.current.style.height = "auto"; }
const section = active === "home" ? "home" : active;
const prev = sectionMsgs[section] || [];
const newMsgs = [...prev, { role: "user", content: txt }];
setSectionMsgs(p => ({ ...p, [section]: newMsgs }));
setLoading(true);
const sec = SECTIONS.find(s => s.id === section);
const ctx = sec && sec.id !== "home"
? `\n\nالمستخدم يسأل من قسم "${sec.label}". ركّز إجابتك على هذا القسم مع ربطه بالمعايير: ${sec.isoTags?.join(", ")}.`
: "";
try {
const res = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: "claude-sonnet-4-20250514",
max_tokens: 1000,
system: SYSTEM_PROMPT + ctx,
messages: newMsgs,
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
const reply = data.content?.find(b => b.type === "text")?.text || "لم أتمكن من الإجابة.";
setSectionMsgs(p => ({ ...p, [section]: [...newMsgs, { role: "assistant", content: reply }] }));
} catch {
setError("حدث خطأ في الاتصال. يرجى المحاولة مرة أخرى.");
} finally {
setLoading(false);
}
};
return (
{/* BG */}
{/* ── HEADER ── */}
🛡️
المساعد الذكي في أمن وسرية الوثائق والمعلومات
●
{active !== "home" ? `القسم الحالي: ${currentSection?.label}` : "الصفحة الرئيسية"}
{currentMsgs.length > 0 && (
{ setSectionMsgs(p => ({ ...p, [active]: [] })); setError(null); }} style={{
background: "transparent", border: "1px solid rgba(255,80,80,0.16)",
color: "#5a3535", borderRadius: "7px", padding: "4px 9px",
fontSize: "10.5px", cursor: "pointer", fontFamily: "'Cairo',sans-serif",
transition: "all 0.18s",
}}
onMouseEnter={e => { e.currentTarget.style.color = "#ff7777"; }}
onMouseLeave={e => { e.currentTarget.style.color = "#5a3535"; }}
>مسح ✕
)}
setActive("home")} style={{
background: "rgba(201,168,76,0.07)", border: "1px solid rgba(201,168,76,0.16)",
color: "#C9A84C", borderRadius: "7px", padding: "4px 10px",
fontSize: "10.5px", cursor: "pointer", fontFamily: "'Cairo',sans-serif",
transition: "all 0.18s",
}}
onMouseEnter={e => { e.currentTarget.style.background = "rgba(201,168,76,0.14)"; }}
onMouseLeave={e => { e.currentTarget.style.background = "rgba(201,168,76,0.07)"; }}
>🏠 الرئيسية
{/* ── BODY ── */}
{/* Sidebar */}
{ setActive(id); setError(null); }}
collapsed={collapsed} onToggle={() => setCollapsed(v => !v)} />
{/* Main */}
{active === "home" ? (
<>
{ setActive(id); }} onSend={sendMessage} />
>
) : (
)}
{/* Input (only for non-home sections) */}
{active !== "home" && (
sendMessage()}
disabled={!input.trim() || loading}
style={{
width: "42px", height: "42px", borderRadius: "11px", border: "none",
background: !input.trim() || loading
? "rgba(80,80,80,0.12)"
: `linear-gradient(135deg,${color},${color}99)`,
cursor: !input.trim() || loading ? "not-allowed" : "pointer",
display: "flex", alignItems: "center", justifyContent: "center",
fontSize: "17px", flexShrink: 0, transition: "all 0.18s",
boxShadow: !input.trim() || loading ? "none" : `0 3px 12px ${color}44`,
opacity: !input.trim() || loading ? 0.4 : 1,
}}
>➤
{currentSection?.isoTags?.map(t => (
{t}
))}
Enter للإرسال · Shift+Enter لسطر جديد
)}
);
}