Files
paraguay/js/main.js
T

488 lines
20 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
checkSession();
if (getCookie('sessionid')) {
loadUsers();
loadWiki();
}
});
function getCookie(name) {
// Check localStorage first (for cookies set by n8n)
const localVal = localStorage.getItem(name);
if (localVal) {
return localVal;
}
// Check document.cookie (for non-HttpOnly cookies)
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) {
const val = parts.pop().split(';').shift();
return val.replace(/^"|"$/g, '');
}
return '';
}
function setCookie(name, value, days) {
const expires = new Date();
expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = name + '=' + encodeURIComponent(value) + ';expires=' + expires.toUTCString() + ';path=/';
// Also save to localStorage for HttpOnly cookies
localStorage.setItem(name, value);
}
const API_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/login';
const NEWSLETTER_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/newsletter';
const USER_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/user';
const PROFILE_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/profile';
const WIKI_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/wiki';
function checkSession() {
const sessionid = getCookie('sessionid');
const intro = document.getElementById('intro-section');
const news = document.getElementById('news-col');
const login = document.getElementById('login-panel');
const newsletter = document.getElementById('newsletter-panel');
const notebook = document.getElementById('notebook-panel');
if (sessionid) {
// User is logged in via n8n cookie
if (intro) intro.classList.add('hidden');
if (news) news.classList.add('hidden');
if (login) login.classList.add('hidden');
if (notebook) notebook.classList.remove('hidden');
document.querySelectorAll('.user-actions').forEach(el => el.classList.remove('hidden'));
if (newsletter) newsletter.classList.remove('hidden');
} else {
// User is not logged in
if (notebook) notebook.classList.add('hidden');
if (login) login.classList.remove('hidden');
if (newsletter) newsletter.classList.remove('hidden');
document.querySelectorAll('.user-actions').forEach(el => el.classList.add('hidden'));
}
}
document.querySelectorAll('.lang-btn').forEach(btn => {
btn.addEventListener('click', () => {
const lang = btn.dataset.lang;
document.body.dataset.lang = lang;
document.querySelectorAll('.lang-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
// Reload active tab content with new language
const activeTab = document.querySelector('.notebook .tab.active');
if (activeTab) {
const tabName = activeTab.dataset.tab;
if (tabName === 'users') loadUsers();
if (tabName === 'wiki') loadWiki();
}
});
});
document.querySelectorAll('.notebook .tab').forEach(tab => {
tab.addEventListener('click', () => {
document.querySelectorAll('.notebook .tab').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
const tabName = tab.dataset.tab;
document.querySelectorAll('.notebook .tab-content').forEach(c => c.classList.add('hidden'));
document.getElementById('tab-' + tabName).classList.remove('hidden');
if (tabName === 'users') loadUsers();
if (tabName === 'wiki') loadWiki();
});
});
async function sendTelegramUser() {
const user = document.getElementById('telegram-user').value.trim();
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
const btn = document.querySelector('#login-step-1 .btn-primary');
btn.disabled = true; btn.textContent = 'Verifizierung läuft...';
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: user })
});
if (response.ok) {
const data = await response.json();
if (data.Error && data.Error.includes('user not found')) {
const msg = document.body.dataset.lang === 'de'
? 'Dieser Benutzername ist noch nicht in unserer Datenbank. Bitte melden Sie sich über den Telegram Bot an, um sich zu registrieren.'
: 'This username is not yet in our database. Please sign up via the Telegram bot to register.';
alert(msg);
} else if (data.status === 'code send') {
document.getElementById('login-step-1').classList.add('hidden');
document.getElementById('login-step-2').classList.remove('hidden');
alert('Code wurde an Ihren Telegram-Account gesendet.');
} else if (data.sessionid) {
setCookie('sessionid', data.sessionid, 1);
document.getElementById('login-step-1').classList.add('hidden');
document.getElementById('login-step-2').classList.remove('hidden');
alert('Code wurde an Ihren Telegram-Account gesendet.');
} else {
alert('Fehler bei der Verifizierung. Bitte versuchen Sie es erneut.');
}
} else {
alert('Fehler bei der Verifizierung. Bitte versuchen Sie es erneut.');
}
} catch (error) {
alert('Fehler bei der Verbindung. Bitte versuchen Sie es erneut.');
btn.disabled = false; btn.textContent = document.body.dataset.lang === 'de' ? 'Anmelden' : 'Login';
}
}
async function verifyCode() {
const code = document.getElementById('verification-code').value.trim();
if (!code) { alert('Bitte geben Sie den Verifizierungscode ein.'); return; }
const btns = document.querySelectorAll('#login-step-2 .btn-primary');
btns.forEach(b => b.disabled = true);
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: document.getElementById('telegram-user').value,
code: code,
sessionid: getCookie('sessionid')
})
});
if (response.ok) {
const data = await response.json();
if (data.sessionid) {
setCookie('sessionid', data.sessionid, 1);
document.getElementById('intro-section').classList.add('hidden');
document.getElementById('news-col').classList.add('hidden');
document.getElementById('login-panel').classList.add('hidden');
document.getElementById('notebook-panel').classList.remove('hidden');
}
} else {
alert('Ungültiger Code. Bitte versuchen Sie es erneut.');
btns.forEach(b => b.disabled = false);
}
} catch (error) {
alert('Fehler bei der Verbindung. Bitte versuchen Sie es erneut.');
btns.forEach(b => b.disabled = false);
}
}
async function submitLoginData() {
const name = document.getElementById('full-name').value.trim();
const llc = document.getElementById('llc-name').value.trim();
if (!name || !llc) { alert('Bitte geben Sie Name und LLC-Namen ein.'); return; }
const btns = document.querySelectorAll('#login-step-3 .btn-primary');
btns.forEach(b => b.disabled = true);
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: document.getElementById('telegram-user').value,
name: name,
llc: llc
})
});
if (response.ok) {
const data = await response.json();
if (data.sessionid) {
setCookie('sessionid', data.sessionid, 1);
}
document.getElementById('intro-section').classList.add('hidden');
document.getElementById('news-col').classList.add('hidden');
document.getElementById('login-panel').classList.add('hidden');
document.getElementById('notebook-panel').classList.remove('hidden');
document.getElementById('profile-username').value = document.getElementById('telegram-user').value;
document.getElementById('profile-name').value = document.getElementById('full-name').value;
document.getElementById('profile-llc').value = document.getElementById('llc-name').value;
document.querySelectorAll('.user-actions').forEach(el => el.classList.remove('hidden'));
alert('Erfolgreich angemeldet! Willkommen!');
} else {
alert('Fehler bei der Anmeldung.');
btns.forEach(b => b.disabled = false);
}
} catch (error) {
alert('Fehler bei der Verbindung.');
btns.forEach(b => b.disabled = false);
}
}
async function subscribeNewsletter() {
const email = document.getElementById('newsletter-email').value.trim();
if (!email) { alert('Bitte geben Sie eine E-Mail-Adresse ein.'); return; }
const btn = document.querySelector('#newsletter-form .btn-primary');
btn.disabled = true; btn.textContent = document.body.dataset.lang === 'de' ? 'Absenden...' : 'Submitting...';
try {
const response = await fetch(NEWSLETTER_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: email })
});
if (response.ok) {
document.getElementById('newsletter-form').classList.add('hidden');
document.getElementById('newsletter-success').classList.remove('hidden');
} else {
alert('Fehler bei der Anmeldung. Bitte versuchen Sie es erneut.');
btn.disabled = false;
btn.textContent = document.body.dataset.lang === 'de' ? 'Abonnieren' : 'Subscribe';
}
} catch (error) {
alert('Fehler bei der Verbindung. Bitte versuchen Sie es erneut.');
btn.disabled = false;
btn.textContent = document.body.dataset.lang === 'de' ? 'Abonnieren' : 'Subscribe';
}
}
async function loadUsers() {
const usersContainer = document.getElementById('users-list');
if (!usersContainer) return;
try {
const response = await fetch(USER_URL);
if (!response.ok) throw new Error('Failed to fetch users');
const data = await response.json();
if (data.data && Array.isArray(data.data)) {
usersContainer.innerHTML = '';
data.data.forEach(user => {
const card = document.createElement('div');
card.className = 'user-card';
card.style.cursor = 'pointer';
const avatarContent = user.image
? `<img src="${user.image}" alt="${user.username || 'user'}" class="user-avatar-img" />`
: `<span class="user-avatar-text">${(user.username || '').charAt(0).toUpperCase()}</span>`;
const rank = getRank(user.posts || 0);
card.innerHTML = `
<div class="user-avatar">${avatarContent}</div>
<div class="user-info">
<h4 style="margin:0">${user.username || 'N/A'}</h4>
<p class="user-company">${user.company || ''}</p>
<p class="user-email">${user.email ? `<a href="mailto:${user.email}">${user.email}</a>` : ''}</p>
<p class="user-homepage">${user.homepage ? `<a href="${user.homepage.startsWith('http') ? '' : 'https://'}${user.homepage}" target="_blank">${user.homepage}</a>` : ''}</p>
<p class="user-location">${user.location || ''}</p>
<p class="user-description">${user.Description || ''}</p>
${user.posts ? `<p class="user-posts">${user.posts} <span class="hide-de">Beiträge</span><span class="hide-en">posts</span></p>` : ''}
</div>
<span class="rank-badge rank-${rank.level}" title="${rank.emoji} ${rank.title}">${rank.emoji} ${rank.title}</span>
`;
card.addEventListener('click', () => openUserDetailModal(user));
usersContainer.appendChild(card);
});
} else {
usersContainer.innerHTML = '<p>No users found.</p>';
}
} catch (error) {
usersContainer.innerHTML = '<p>Error loading users: ' + error.message + '</p>';
}
}
function getRank(posts) {
const isDE = document.body.dataset.lang !== 'en';
if (posts >= 500) return { level: 'legend', title: isDE ? 'Legende' : 'Legend', emoji: '👑' };
if (posts >= 200) return { level: 'expert', title: isDE ? 'Experte' : 'Expert', emoji: '🏆' };
if (posts >= 100) return { level: 'veteran', title: isDE ? 'Veteran' : 'Veteran', emoji: '💎' };
if (posts >= 50) return { level: 'contributor', title: isDE ? 'Mitwirkender' : 'Contributor', emoji: '⭐' };
if (posts >= 30) return { level: 'member', title: isDE ? 'Mitglied' : 'Member', emoji: '🌳' };
if (posts >= 5) return { level: 'beginner', title: isDE ? 'Einsteiger' : 'Beginner', emoji: '🌿' };
return { level: 'rookie', title: isDE ? 'Anfänger' : 'Rookie', emoji: '🌱' };
}
function filterUsers(searchTerm) {
const usersContainer = document.getElementById('users-list');
if (!usersContainer) return;
const cards = usersContainer.querySelectorAll('.user-card');
const term = searchTerm.toLowerCase();
cards.forEach(card => {
const username = card.querySelector('h4')?.innerText?.toLowerCase() || '';
const company = card.querySelector('.user-company')?.innerText?.toLowerCase() || '';
const email = card.querySelector('.user-email')?.innerText?.toLowerCase() || '';
const location = card.querySelector('.user-location')?.innerText?.toLowerCase() || '';
const description = card.querySelector('.user-description')?.innerText?.toLowerCase() || '';
const displayText = username + ' ' + company + ' ' + email + ' ' + location + ' ' + description;
card.style.display = displayText.includes(term) ? 'block' : 'none';
});
}
async function openProfileModal() {
const sessionid = getCookie('sessionid');
if (!sessionid) { alert('Bitte melden Sie sich an.'); return; }
try {
const response = await fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sessionid));
if (response.ok) {
const user = await response.json();
document.getElementById('profile-username-display').textContent = user.username || '';
document.getElementById('profile-company').value = user.company || '';
document.getElementById('profile-email').value = user.email || '';
document.getElementById('profile-homepage').value = user.homepage || '';
document.getElementById('profile-image').value = user.image || '';
document.getElementById('profile-location').value = user.location || '';
document.getElementById('profile-description').value = user.Description || '';
document.getElementById('profile-publish').checked = true;
document.getElementById('profile-edit-fields').classList.remove('hidden');
}
} catch (error) {
alert('Fehler beim Laden des Profils.');
}
document.getElementById('profile-modal').classList.remove('hidden');
}
function closeProfileModal() {
document.getElementById('profile-modal').classList.add('hidden');
}
function openUserDetailModal(user) {
const modal = document.getElementById('user-detail-modal');
const avatar = document.getElementById('user-detail-avatar');
const initial = document.getElementById('user-detail-initial');
const img = document.getElementById('user-detail-img');
// Avatar: image or initial
if (user.image) {
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}" style="width:100%;height:100%;object-fit:cover;border-radius:50%;">`;
} else {
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
}
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
document.getElementById('user-detail-company').textContent = user.company || '';
const emailEl = document.getElementById('user-detail-email');
emailEl.innerHTML = user.email ? `<a href="mailto:${user.email}">${user.email}</a>` : '-';
const hpEl = document.getElementById('user-detail-homepage');
const hp = user.homepage || '';
hpEl.innerHTML = hp ? `<a href="${hp.startsWith('http') ? '' : 'https://'}${hp}">${hp}</a>` : '-';
document.getElementById('user-detail-location').textContent = user.location || '-';
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
modal.classList.remove('hidden');
}
function closeUserDetailModal() {
document.getElementById('user-detail-modal').classList.add('hidden');
}
async function loadWiki() {
const wikiContainer = document.getElementById('wiki-content');
if (!wikiContainer) return;
try {
const response = await fetch(WIKI_URL);
if (!response.ok) throw new Error('Failed to fetch wiki');
const result = await response.json();
if (result.data && Array.isArray(result.data)) {
wikiContainer.innerHTML = '';
const isEN = document.body.dataset.lang === 'en';
const topics = {};
result.data.forEach(item => {
const topic = isEN && item.topic_en ? item.topic_en : item.topic || 'Unknown';
if (!topics[topic]) topics[topic] = [];
topics[topic].push(item);
});
for (const [topicName, subtopics] of Object.entries(topics)) {
const topicDiv = document.createElement('div');
topicDiv.className = 'wiki-topic';
topicDiv.innerHTML = `
<h4 class="topic-title">${topicName}</h4>
<div class="wiki-subtopics"></div>
`;
wikiContainer.appendChild(topicDiv);
const subtopicsDiv = topicDiv.querySelector('.wiki-subtopics');
const topicTitle = topicDiv.querySelector('.topic-title');
// All topics start collapsed
subtopicsDiv.classList.add('hidden');
// Track open state for this topic
let isOpen = false;
let openSubtopicIndex = -1;
// Toggle topic: click opens/closes subtopics, closes other topics
topicTitle.onclick = () => {
// Close all other topics first
document.querySelectorAll('.wiki-subtopics:not(.hidden)').forEach(otherSubtopics => {
if (otherSubtopics !== subtopicsDiv) {
otherSubtopics.classList.add('hidden');
}
});
if (isOpen) {
subtopicsDiv.classList.add('hidden');
isOpen = false;
} else {
subtopicsDiv.classList.remove('hidden');
isOpen = true;
}
};
subtopics.forEach((sub, index) => {
const subtopicTitle = isEN && sub.subtopic_en ? sub.subtopic_en : sub.subtopic;
const subtopicContent = isEN && sub.wiki_en ? sub.wiki_en : sub.wiki;
const subtopicDiv = document.createElement('div');
subtopicDiv.className = 'wiki-subtopic';
subtopicDiv.innerHTML = `
<div class="wiki-subtopic-title">${subtopicTitle || ''}</div>
<div class="wiki-subtopic-content hidden">
<p>${subtopicContent || ''}</p>
</div>
`;
subtopicsDiv.appendChild(subtopicDiv);
const title = subtopicDiv.querySelector('.wiki-subtopic-title');
const content = subtopicDiv.querySelector('.wiki-subtopic-content');
title.onclick = (e) => {
e.stopPropagation();
// Close other subtopics in this topic
subtopicsDiv.querySelectorAll('.wiki-subtopic').forEach(s => {
if (s !== subtopicDiv) {
s.querySelector('.wiki-subtopic-content').classList.add('hidden');
}
});
// Toggle this subtopic's content
content.classList.toggle('hidden');
};
});
}
} else {
wikiContainer.innerHTML = '<p>No wiki data found.</p>';
}
} catch (error) {
wikiContainer.innerHTML = '<p>Error loading wiki: ' + error.message + '</p>';
}
}
function logout() {
setCookie('sessionid', '', -1);
checkSession();
closeProfileModal();
}
async function saveProfile() {
const company = document.getElementById('profile-company').value.trim();
if (!company) { alert('Bitte geben Sie LLC/SRL-Namen ein.'); return; }
try {
const response = await fetch(PROFILE_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: document.getElementById('profile-username-display').textContent,
company: company,
email: document.getElementById('profile-email').value,
homepage: document.getElementById('profile-homepage').value,
image: document.getElementById('profile-image').value,
location: document.getElementById('profile-location').value,
Description: document.getElementById('profile-description').value,
sessionid: getCookie('sessionid'),
publish: document.getElementById('profile-publish').checked
})
});
if (response.ok) {
alert('Profil erfolgreich gespeichert!');
closeProfileModal();
checkSession();
} else {
alert('Fehler beim Speichern.');
}
} catch (error) {
alert('Fehler bei der Verbindung.');
}
}