+
-async function loadInlineComments(featureId) {
- const list = $(`#inline-comments-${featureId}`);
- if (!list) return;
+
+
+
+
EN
+
ع
+
- list.innerHTML = '';
- const { comments, error } = await fetchComments(featureId);
- if (error) {
- list.innerHTML = '';
- return;
- }
+
استكشف الجوهر
+
ذكاء NexCore
+
+
المبادرات جديد
- list.innerHTML = renderCommentCollection(comments, featureId);
- updateCommentCountUI(featureId, comments.length);
- list.scrollTop = list.scrollHeight;
- refreshExpandedHeight(featureId);
-}
+
-async function openComments(featureId, title) {
- state.activeFeatureId = featureId;
- const titleEl = $('#comments-feature-title');
- if (titleEl) titleEl.innerHTML = ` ${escHtml(title)}`;
+
المركز
+
المشاريع
- openModal('comments-modal');
+
- const compose = $('#comments-compose');
- const nudge = $('#comments-auth-nudge');
+
الأدوات والأنظمة
+
من نحن
+
الفريق
+
اتصل بنا
- if (state.user) {
- compose?.classList.remove('hidden');
- nudge?.classList.add('hidden');
- } else {
- compose?.classList.add('hidden');
- nudge?.classList.remove('hidden');
- // Re-bind sign-in inside nudge
- const siBtn = $('#comments-sign-in-btn');
- if (siBtn) {
- siBtn.onclick = () => { closeModal('comments-modal'); openAuthModal(); };
- }
- }
+
- await loadComments(featureId);
-}
+
لوحة الميزات
+
الإصدارات والتحديثات
-async function loadComments(featureId) {
- const list = $('#comments-list');
- list.innerHTML = '';
- const { comments, error } = await fetchComments(featureId);
- if (error) {
- list.innerHTML = '';
- return;
- }
+
- list.innerHTML = renderCommentCollection(comments, featureId);
- updateCommentCountUI(featureId, comments.length);
- list.scrollTop = list.scrollHeight;
-}
+
التسعير جديد
+
سياسة التسعير جديد
-function buildCommentEl(comment, featureId) {
- const el = document.createElement('div');
- el.className = 'comment-item';
- const uid = comment.user_id?.slice(0, 6) || '??????';
- const initial = uid[0]?.toUpperCase() || 'U';
- const date = new Date(comment.created_at).toLocaleDateString('ar-OM', { month: 'short', day: 'numeric' });
- const canManage = state.user && comment.user_id === state.user.id;
+
- el.innerHTML = `
-
-
-
-
- `;
- return el;
-}
-
-async function submitComment() {
- if (!state.user || !state.activeFeatureId) return;
- const input = $('#comment-input');
- const content = input?.value.trim();
- if (!content) return;
-
- const btn = $('#submit-comment');
- btn.disabled = true;
- btn.textContent = '…';
-
- const { data, error } = await db.from('feature_comments').insert({
- feature_id: state.activeFeatureId,
- user_id: state.user.id,
- content,
- }).select().single();
-
- btn.disabled = false;
- btn.textContent = 'إرسال';
-
- if (error) {
- showToast('فشل نشر التعليق.', '
');
- return;
- }
-
- input.value = '';
- const cached = state.commentsByFeature[state.activeFeatureId] || [];
- cached.push(data);
- state.commentsByFeature[state.activeFeatureId] = cached;
- await loadComments(state.activeFeatureId);
- const inlineList = $(`#inline-comments-${state.activeFeatureId}`);
- if (inlineList) inlineList.innerHTML = renderCommentCollection(cached, state.activeFeatureId);
- updateCommentCountUI(state.activeFeatureId, cached.length);
- showToast('تم نشر التعليق!', '
');
-}
-
-async function submitInlineComment(featureId) {
- if (!state.user) {
- openAuthModal();
- return;
- }
- const input = $(`#inline-comment-input-${featureId}`);
- const btn = $(`#inline-comment-btn-${featureId}`);
- const content = input?.value.trim();
- if (!content || !btn) return;
+
- btn.disabled = true;
- btn.textContent = '…';
+
+
+
+
+
خارطة الطريق العامة
+
شارك في تشكيل
ما نبنيه لاحقاً
+
صوّت على الميزات، واقترح الأفكار، وتابع التقدم — ملاحظاتك تساعد في تحديد ما نطوره لاحقاً في NexCore Labs.
+
+
—الطلبات
+
—إجمالي الأصوات
+
—تم إطلاقه
+
+
+
+
+
+
+
مسار الحالة
+
نظرة مباشرة على الميزات
+
+
مخطط—
+
قيد التنفيذ—
+
مكتمل—
+
+
+
+
+
+
- const { data, error } = await db.from('feature_comments').insert({
- feature_id: featureId,
- user_id: state.user.id,
- content,
- }).select().single();
+
+
+
+
+
+
+
+
+
+
+
+
+
- btn.disabled = false;
- btn.textContent = 'إرسال';
+
- if (error) {
- showToast('فشل نشر التعليق.', '
');
- return;
- }
+
+
+
لا توجد ميزات هنا بعد
+
كن أول من يقترح ميزة!
+
+
- input.value = '';
- const cached = state.commentsByFeature[featureId] || [];
- cached.push(data);
- state.commentsByFeature[featureId] = cached;
+
+
- const list = $(`#inline-comments-${featureId}`);
- if (list) {
- list.innerHTML = renderCommentCollection(cached, featureId);
- list.scrollTop = list.scrollHeight;
- }
+
+
+
+
+
+
+
تابع باستخدام Google لتسجيل الدخول.
+
+
+
+
+
- if (state.activeFeatureId === featureId) {
- const modalList = $('#comments-list');
- if (modalList && !$('#comments-modal')?.classList.contains('hidden')) {
- modalList.innerHTML = renderCommentCollection(cached, featureId);
- modalList.scrollTop = modalList.scrollHeight;
- }
- }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- updateCommentCountUI(featureId, cached.length);
- refreshExpandedHeight(featureId);
- showToast('تم نشر التعليق!', '');
-}
+
+
-// ── TABS & FILTERS ─────────────────────────────────────────
-function bindTabs() {
- $$('.tab-btn').forEach(btn => {
- btn.addEventListener('click', () => {
- if (btn.dataset.tab === state.currentTab) return;
- $$('.tab-btn').forEach(b => b.classList.remove('active'));
- btn.classList.add('active');
- state.currentTab = btn.dataset.tab;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- const filterBar = $('#status-filter');
- if (filterBar) {
- filterBar.style.display = state.currentTab === 'roadmap' ? 'flex' : 'none';
- }
+
+
+ ✓
+
+
- if (state.currentTab !== 'roadmap') {
- state.statusFilter = 'all';
- $$('.chip').forEach(c => c.classList.toggle('active', c.dataset.filter === 'all'));
- }
- loadFeatures();
- });
- });
-}
+
+

+
+
-function bindFilters() {
- $$('.chip').forEach(chip => {
- chip.addEventListener('click', () => {
- if (chip.dataset.filter === state.statusFilter) return;
- $$('.chip').forEach(c => c.classList.remove('active'));
- chip.classList.add('active');
- state.statusFilter = chip.dataset.filter;
- loadFeatures();
- });
- });
-}
+
-// ── SKELETON ───────────────────────────────────────────────
-function showSkeleton(visible) {
- const skel = $('#skeleton-wrap');
- if (!skel) return;
- if (visible) {
- skel.style.display = 'flex';
- skel.style.flexDirection = 'column';
- skel.style.gap = '10px';
- } else {
- skel.style.display = 'none';
- }
- $$('.feature-card').forEach(c => {
- if (visible) c.remove();
- });
-}
+
-// ── TOAST ──────────────────────────────────────────────────
-let toastTimer;
-function showToast(message, iconHtml = '
') {
- const toast = $('#toast');
- const iconEl = $('#toast-icon');
- const msgEl = $('#toast-msg');
- if (!toast) return;
+ -->
- iconEl.innerHTML = iconHtml;
- msgEl.textContent = message;
- toast.classList.remove('hidden');
+
+
- clearTimeout(toastTimer);
- toastTimer = setTimeout(() => toast.classList.add('hidden'), 3200);
-}
+
-// ── FORM ERROR ─────────────────────────────────────────────
-function showFormError(el, msg) {
- if (!el) return;
- el.textContent = msg;
- el.classList.remove('hidden');
-}
+
-// ── BOOT ───────────────────────────────────────────────────
-document.addEventListener('DOMContentLoaded', init);
-
+
+