Add 5 website variations: neo-mirai, wikipedia, apple, facebook, aurora + community webhook stats
This commit is contained in:
@@ -0,0 +1,467 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
</head>
|
||||
<body data-lang="de" data-logged-in="false">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">Paraguay LLC & SRL</span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-outline" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<!-- Step 1: Username -->
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username eingeben</h2>
|
||||
<h2 class="hide-en">Enter Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 2: Code -->
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 3: Registration -->
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal user-detail-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero-particles" id="hero-particles"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL Community</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL Community</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-scroll-indicator">
|
||||
<div class="scroll-arrow"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner (nicht logged-in) -->
|
||||
<div class="telegram-banner" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-telegram">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content (logged-in) -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section (nur logged-in) -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">
|
||||
Telegram
|
||||
</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/* Apple Style — Minimal, Clean, Premium */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: #fff;
|
||||
color: #1d1d1f;
|
||||
line-height: 1.47059;
|
||||
font-size: 17px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
background: rgba(0,0,0,0.8);
|
||||
backdrop-filter: saturate(180%) blur(20px);
|
||||
-webkit-backdrop-filter: saturate(180%) blur(20px);
|
||||
height: 44px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
padding: 0 22px;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
color: #f5f5f7;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.nav-logo { font-size: 1.4rem; }
|
||||
.nav-menu { display: flex; gap: 28px; align-items: center; }
|
||||
.nav-link {
|
||||
color: #f5f5f7;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.nav-link:hover { opacity: 1; }
|
||||
.nav-actions { display: flex; gap: 12px; align-items: center; }
|
||||
.lang-select { display: flex; gap: 4px; }
|
||||
.lang-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #f5f5f7;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.3s;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.lang-btn.active { opacity: 1; }
|
||||
.lang-btn:hover { opacity: 1; }
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 4px 16px;
|
||||
font-size: 12px;
|
||||
border-radius: 980px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
border: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.btn-primary { background: #0071e3; color: #fff; }
|
||||
.btn-primary:hover { background: #0077ed; }
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: #f5f5f7;
|
||||
border: 1px solid rgba(255,255,255,0.4);
|
||||
}
|
||||
.btn-outline:hover { border-color: #f5f5f7; }
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
.btn-telegram { background: #0088cc; color: #fff; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: #000;
|
||||
color: #f5f5f7;
|
||||
text-align: center;
|
||||
padding: 120px 20px 80px;
|
||||
min-height: 80vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 56px;
|
||||
line-height: 1.07143;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.005em;
|
||||
margin-bottom: 16px;
|
||||
background: linear-gradient(180deg, #f5f5f7 0%, #a1a1a6 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 24px;
|
||||
line-height: 1.16667;
|
||||
font-weight: 400;
|
||||
color: #a1a1a6;
|
||||
max-width: 600px;
|
||||
margin: 0 auto 40px;
|
||||
}
|
||||
.hero-stats { display: flex; justify-content: center; gap: 80px; }
|
||||
.stat { text-align: center; }
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.003em;
|
||||
color: #f5f5f7;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
padding: 100px 20px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-alt { background: #f5f5f7; }
|
||||
.section-title {
|
||||
font-size: 40px;
|
||||
line-height: 1.1;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.015em;
|
||||
margin-bottom: 60px;
|
||||
text-align: center;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
.container { max-width: 100%; }
|
||||
|
||||
/* About */
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 30px;
|
||||
}
|
||||
.about-card {
|
||||
padding: 24px;
|
||||
border-radius: 18px;
|
||||
background: #f5f5f7;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
.about-card:hover { transform: scale(1.02); }
|
||||
.about-icon { font-size: 2rem; margin-bottom: 12px; }
|
||||
.about-card h3 {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
color: #1d1d1f;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.about-card p { font-size: 14px; color: #6e6e73; line-height: 1.4; }
|
||||
|
||||
/* Search */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
max-width: 380px;
|
||||
margin: 0 auto 40px;
|
||||
position: relative;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #86868b;
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 12px 16px 12px 40px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: #f5f5f7;
|
||||
font-size: 15px;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
.search-input:focus { outline: 2px solid #0071e3; outline-offset: -2px; }
|
||||
|
||||
/* Members Grid */
|
||||
.members-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.member-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||
}
|
||||
.member-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); transform: translateY(-2px); }
|
||||
.user-avatar {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background: #f5f5f7;
|
||||
color: #86868b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
.member-info h4 { font-size: 15px; font-weight: 600; color: #1d1d1f; margin-bottom: 2px; }
|
||||
.member-company { font-size: 13px; color: #6e6e73; }
|
||||
.member-location, .member-posts { font-size: 13px; color: #6e6e73; }
|
||||
.rank-badge {
|
||||
font-size: 11px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 980px;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: #f5f5f7; color: #6e6e73; }
|
||||
.rank-badge.rank-beginner { background: #e8f5e9; color: #2e7d32; }
|
||||
.rank-badge.rank-member { background: #e3f2fd; color: #1565c0; }
|
||||
.rank-badge.rank-contributor { background: #e0f7fa; color: #00838f; }
|
||||
.rank-badge.rank-veteran { background: #f3e5f5; color: #8e24aa; }
|
||||
.rank-badge.rank-expert { background: #fff3e0; color: #e65100; }
|
||||
.rank-badge.rank-legend { background: #fce4ec; color: #c62828; }
|
||||
|
||||
/* Wiki Cards */
|
||||
.wiki-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 28px;
|
||||
border-radius: 18px;
|
||||
background: #f5f5f7;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
border: none;
|
||||
}
|
||||
.wiki-card:hover { background: #e8e8ed; transform: translateY(-3px); }
|
||||
.wiki-card-title { font-size: 17px; font-weight: 600; color: #1d1d1f; margin-bottom: 8px; }
|
||||
.wiki-card-excerpt { font-size: 14px; color: #6e6e73; margin-bottom: 12px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 13px; color: #86868b; }
|
||||
.wiki-card-subtopic { color: #0071e3; }
|
||||
.no-results { padding: 40px; text-align: center; color: #86868b; }
|
||||
.loading-text { padding: 40px; text-align: center; color: #86868b; font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 36px;
|
||||
max-width: 480px;
|
||||
width: 90%;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
||||
position: relative;
|
||||
animation: modalIn 0.3s ease;
|
||||
}
|
||||
@keyframes modalIn {
|
||||
from { opacity: 0; transform: scale(0.95); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 20px;
|
||||
background: #f5f5f7;
|
||||
border: none;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: #86868b;
|
||||
}
|
||||
.login-icon { font-size: 3rem; text-align: center; margin-bottom: 20px; }
|
||||
.login-hint { color: #6e6e73; text-align: center; margin-bottom: 24px; font-size: 15px; }
|
||||
.form-group { margin-bottom: 16px; }
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #d2d2d7;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
color: #1d1d1f;
|
||||
background: #fff;
|
||||
}
|
||||
.form-input:focus { outline: 2px solid #0071e3; outline-offset: -2px; border-color: transparent; }
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile & Detail */
|
||||
.profile-username { font-size: 1.3rem; font-weight: 600; margin-bottom: 10px; }
|
||||
.profile-rank { margin-bottom: 20px; }
|
||||
.user-detail-modal { max-width: 560px; }
|
||||
.user-detail-content { padding: 10px; }
|
||||
.user-detail-avatar {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 20px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 8px; }
|
||||
.user-detail-name-rank h2 { font-size: 1.3rem; font-weight: 600; }
|
||||
.user-detail-fields { display: grid; gap: 12px; }
|
||||
.detail-field { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #e5e5e7; }
|
||||
.detail-label { color: #6e6e73; font-size: 14px; }
|
||||
.detail-value { color: #1d1d1f; font-size: 14px; text-align: right; }
|
||||
.user-detail-company { color: #6e6e73; text-align: center; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
background: #f5f5f7;
|
||||
padding: 20px;
|
||||
margin: 30px auto;
|
||||
max-width: 980px;
|
||||
border-radius: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.banner-icon { font-size: 1.8rem; }
|
||||
.banner-text strong { color: #1d1d1f; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 380px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 2.5rem; margin-bottom: 16px; }
|
||||
.newsletter-hint { color: #6e6e73; margin-bottom: 20px; font-size: 15px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background: #f5f5f7;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #d2d2d7;
|
||||
}
|
||||
.footer-brand { margin-bottom: 16px; }
|
||||
.footer-logo { font-size: 1.6rem; }
|
||||
.footer-title { color: #1d1d1f; margin-left: 10px; font-size: 14px; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 24px; margin-bottom: 16px; flex-wrap: wrap; }
|
||||
.footer-links a { color: #424245; text-decoration: none; font-size: 12px; }
|
||||
.footer-links a:hover { color: #0071e3; }
|
||||
.footer-bottom p { color: #86868b; margin: 4px 0; font-size: 11px; }
|
||||
.footer-bottom a { color: #0071e3; }
|
||||
.footer-copy { font-size: 11px; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0,0,0,0.95);
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
gap: 12px;
|
||||
}
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-toggle span { display: block; width: 18px; height: 1.5px; background: #f5f5f7; }
|
||||
.hero-title { font-size: 32px; }
|
||||
.hero-subtitle { font-size: 19px; }
|
||||
.hero-stats { gap: 30px; flex-wrap: wrap; }
|
||||
.stat-number { font-size: 36px; }
|
||||
.section-title { font-size: 28px; }
|
||||
.about-grid { grid-template-columns: 1fr; }
|
||||
.wiki-grid { grid-template-columns: 1fr; }
|
||||
.members-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
@@ -0,0 +1,455 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">Paraguay LLC & SRL</span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-outline" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal glass" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username eingeben</h2>
|
||||
<h2 class="hide-en">Enter Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal glass" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal glass user-detail-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL Community</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL Community</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner -->
|
||||
<div class="telegram-banner glass" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-telegram">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card glass">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card glass">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card glass">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card glass">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card glass">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">Telegram</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
/* Aurora Glassmorphism — Dreamy Gradient with Frosted Glass */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
||||
background: #0f0c29;
|
||||
color: #fff;
|
||||
line-height: 1.6;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Animated Aurora Background */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#0f0c29 0%,
|
||||
#302b63 25%,
|
||||
#24243e 50%,
|
||||
#0f0c29 75%,
|
||||
#302b63 100%
|
||||
);
|
||||
background-size: 400% 400%;
|
||||
animation: aurora 20s ease infinite;
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
@keyframes aurora {
|
||||
0% { background-position: 0% 50%; }
|
||||
25% { background-position: 100% 50%; }
|
||||
50% { background-position: 100% 100%; }
|
||||
75% { background-position: 0% 100%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
/* Floating orbs */
|
||||
body::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background:
|
||||
radial-gradient(circle at 20% 20%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 80%, rgba(255, 119, 198, 0.2) 0%, transparent 50%),
|
||||
radial-gradient(circle at 50% 50%, rgba(120, 255, 198, 0.15) 0%, transparent 60%);
|
||||
animation: float 30s ease-in-out infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||
33% { transform: translate(30px, -30px) rotate(120deg); }
|
||||
66% { transform: translate(-20px, 20px) rotate(240deg); }
|
||||
}
|
||||
|
||||
/* Glass Card Mixin */
|
||||
.glass {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
background: rgba(15, 12, 41, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding: 0 20px;
|
||||
height: 60px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.nav-logo { font-size: 24px; }
|
||||
.nav-menu { display: flex; gap: 24px; align-items: center; }
|
||||
.nav-link {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.nav-link:hover {
|
||||
color: #fff;
|
||||
text-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.nav-actions { display: flex; gap: 10px; align-items: center; }
|
||||
.lang-select { display: flex; gap: 6px; }
|
||||
.lang-btn {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
padding: 6px 14px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 20px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.lang-btn.active {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 10px 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
|
||||
}
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
color: #fff;
|
||||
}
|
||||
.btn-outline:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
.btn-telegram { background: linear-gradient(135deg, #0088cc, #00aaff); color: #fff; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 100px 20px 60px;
|
||||
position: relative;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 48px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 16px;
|
||||
background: linear-gradient(135deg, #fff 0%, #a78bfa 50%, #f472b6 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 40px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.hero-stats { display: flex; justify-content: center; gap: 60px; }
|
||||
.stat { text-align: center; }
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-size: 40px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
padding: 60px 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-alt {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
.container { max-width: 100%; }
|
||||
|
||||
/* About */
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: 24px;
|
||||
}
|
||||
.about-card {
|
||||
padding: 30px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.about-card:hover {
|
||||
transform: translateY(-5px);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.about-icon { font-size: 2.5rem; margin-bottom: 16px; }
|
||||
.about-card h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
.about-card p { font-size: 14px; color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
/* Search */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
max-width: 400px;
|
||||
margin: 0 auto 30px;
|
||||
position: relative;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 14px 18px 14px 44px;
|
||||
border-radius: 25px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
.search-input:focus {
|
||||
outline: none;
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
/* Members */
|
||||
.members-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.member-card {
|
||||
padding: 20px;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.member-card:hover {
|
||||
transform: translateY(-3px);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.member-info h4 { font-size: 16px; font-weight: 600; margin-bottom: 4px; }
|
||||
.member-company { font-size: 13px; color: rgba(255, 255, 255, 0.6); }
|
||||
.member-location, .member-posts { font-size: 13px; color: rgba(255, 255, 255, 0.5); }
|
||||
.rank-badge {
|
||||
font-size: 11px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 15px;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.6); }
|
||||
.rank-badge.rank-beginner { background: rgba(74,222,128,0.2); color: #4ade80; }
|
||||
.rank-badge.rank-member { background: rgba(96,165,250,0.2); color: #60a5fa; }
|
||||
.rank-badge.rank-contributor { background: rgba(45,212,191,0.2); color: #2dd4bf; }
|
||||
.rank-badge.rank-veteran { background: rgba(192,132,252,0.2); color: #c084fc; }
|
||||
.rank-badge.rank-expert { background: rgba(251,191,36,0.2); color: #fbbf24; }
|
||||
.rank-badge.rank-legend { background: rgba(248,113,113,0.2); color: #f87171; }
|
||||
|
||||
/* Wiki Cards */
|
||||
.wiki-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 24px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.wiki-card:hover {
|
||||
transform: translateY(-4px);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.wiki-card-title { font-size: 17px; font-weight: 600; margin-bottom: 8px; }
|
||||
.wiki-card-excerpt { font-size: 14px; color: rgba(255, 255, 255, 0.6); margin-bottom: 12px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 13px; color: rgba(255, 255, 255, 0.5); }
|
||||
.wiki-card-subtopic { color: #a78bfa; }
|
||||
.no-results { padding: 30px; text-align: center; color: rgba(255, 255, 255, 0.5); }
|
||||
.loading-text { padding: 30px; text-align: center; color: rgba(255, 255, 255, 0.4); font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
padding: 32px;
|
||||
max-width: 480px;
|
||||
width: 90%;
|
||||
position: relative;
|
||||
animation: glassIn 0.3s ease;
|
||||
}
|
||||
@keyframes glassIn {
|
||||
from { opacity: 0; transform: scale(0.95) translateY(10px); }
|
||||
to { opacity: 1; transform: scale(1) translateY(0); }
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 20px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
.modal-close:hover { background: rgba(255, 255, 255, 0.2); }
|
||||
.login-icon { font-size: 3rem; text-align: center; margin-bottom: 20px; }
|
||||
.login-hint { color: rgba(255, 255, 255, 0.7); text-align: center; margin-bottom: 24px; }
|
||||
.form-group { margin-bottom: 16px; }
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 14px 18px;
|
||||
border-radius: 16px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
}
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: rgba(167, 139, 250, 0.5);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile & Detail */
|
||||
.profile-username { font-size: 1.3rem; font-weight: 600; margin-bottom: 10px; }
|
||||
.profile-rank { margin-bottom: 20px; }
|
||||
.user-detail-modal { max-width: 540px; }
|
||||
.user-detail-content { padding: 10px; }
|
||||
.user-detail-avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 20px;
|
||||
overflow: hidden;
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 20px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; }
|
||||
.user-detail-name-rank h2 { font-size: 1.3rem; font-weight: 700; }
|
||||
.user-detail-fields { display: grid; gap: 12px; }
|
||||
.detail-field {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.detail-label { color: rgba(255, 255, 255, 0.6); font-size: 14px; }
|
||||
.detail-value { color: #fff; font-size: 14px; text-align: right; }
|
||||
.user-detail-company { color: rgba(255, 255, 255, 0.6); text-align: center; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
padding: 20px;
|
||||
margin: 20px auto;
|
||||
max-width: 1200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
animation: glow 3s ease-in-out infinite;
|
||||
}
|
||||
@keyframes glow {
|
||||
0%, 100% { box-shadow: 0 0 20px rgba(102, 126, 234, 0.2); }
|
||||
50% { box-shadow: 0 0 40px rgba(102, 126, 234, 0.4); }
|
||||
}
|
||||
.banner-icon { font-size: 2rem; }
|
||||
.banner-text strong { color: #fff; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 400px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 2.5rem; margin-bottom: 16px; }
|
||||
.newsletter-hint { color: rgba(255, 255, 255, 0.7); margin-bottom: 20px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-top: 40px;
|
||||
}
|
||||
.footer-brand { margin-bottom: 16px; }
|
||||
.footer-logo { font-size: 1.5rem; }
|
||||
.footer-title { color: #fff; margin-left: 10px; font-size: 14px; font-weight: 600; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 24px; margin-bottom: 16px; flex-wrap: wrap; }
|
||||
.footer-links a { color: rgba(255, 255, 255, 0.6); text-decoration: none; font-size: 13px; }
|
||||
.footer-links a:hover { color: #fff; text-shadow: 0 0 10px rgba(255, 255, 255, 0.5); }
|
||||
.footer-bottom p { color: rgba(255, 255, 255, 0.4); margin: 4px 0; font-size: 12px; }
|
||||
.footer-bottom a { color: #a78bfa; }
|
||||
.footer-copy { font-size: 12px; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(15, 12, 41, 0.95);
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-toggle span { display: block; width: 20px; height: 2px; background: #fff; }
|
||||
.hero-title { font-size: 28px; }
|
||||
.hero-subtitle { font-size: 16px; }
|
||||
.hero-stats { gap: 30px; flex-wrap: wrap; }
|
||||
.stat-number { font-size: 28px; }
|
||||
.about-grid { grid-template-columns: 1fr; }
|
||||
.wiki-grid { grid-template-columns: 1fr; }
|
||||
.members-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
</head>
|
||||
<body data-lang="de" data-logged-in="false">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">Paraguay LLC & SRL</span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-outline" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<!-- Step 1: Username -->
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username eingeben</h2>
|
||||
<h2 class="hide-en">Enter Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 2: Code -->
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 3: Registration -->
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal user-detail-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero-particles" id="hero-particles"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL Community</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL Community</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-scroll-indicator">
|
||||
<div class="scroll-arrow"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner (nicht logged-in) -->
|
||||
<div class="telegram-banner" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-telegram">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content (logged-in) -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section (nur logged-in) -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">
|
||||
Telegram
|
||||
</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
/* Facebook Style — Blue social network */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: #f0f2f5;
|
||||
color: #1c1e21;
|
||||
line-height: 1.33;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
height: 56px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-decoration: none;
|
||||
color: #1877f2;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.nav-logo { font-size: 28px; }
|
||||
.nav-menu { display: flex; gap: 8px; align-items: center; }
|
||||
.nav-link {
|
||||
color: #65676b;
|
||||
text-decoration: none;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.nav-link:hover { background: #f0f2f5; }
|
||||
.nav-actions { display: flex; gap: 8px; align-items: center; }
|
||||
.lang-select { display: flex; gap: 4px; }
|
||||
.lang-btn {
|
||||
background: #f0f2f5;
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.lang-btn.active { background: #e7f3ff; color: #1877f2; }
|
||||
.lang-btn:hover { background: #e4e6eb; }
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.btn-primary { background: #1877f2; color: #fff; }
|
||||
.btn-primary:hover { background: #166fe5; }
|
||||
.btn-outline {
|
||||
background: #f0f2f5;
|
||||
color: #1c1e21;
|
||||
border: none;
|
||||
}
|
||||
.btn-outline:hover { background: #e4e6eb; }
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
.btn-telegram { background: #0088cc; color: #fff; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: linear-gradient(135deg, #1877f2 0%, #42b0ff 100%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 60px 20px 40px;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 42px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 18px;
|
||||
opacity: 0.9;
|
||||
margin-bottom: 30px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.hero-stats { display: flex; justify-content: center; gap: 60px; }
|
||||
.stat { text-align: center; }
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
margin: 16px auto;
|
||||
max-width: 1200px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||
}
|
||||
.section-alt { background: #fff; border-radius: 8px; padding: 24px; margin: 16px auto; max-width: 1200px; box-shadow: 0 1px 2px rgba(0,0,0,0.1); }
|
||||
.section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
color: #1c1e21;
|
||||
}
|
||||
.container { max-width: 100%; }
|
||||
|
||||
/* About */
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.about-card {
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
background: #f0f2f5;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.about-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
||||
.about-icon { font-size: 2.5rem; margin-bottom: 12px; }
|
||||
.about-card h3 { font-size: 16px; font-weight: 600; color: #1c1e21; margin-bottom: 8px; }
|
||||
.about-card p { font-size: 14px; color: #65676b; line-height: 1.4; }
|
||||
|
||||
/* Search */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
max-width: 400px;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #65676b;
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 10px 12px 10px 36px;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
background: #f0f2f5;
|
||||
font-size: 15px;
|
||||
}
|
||||
.search-input:focus { outline: 2px solid #1877f2; outline-offset: 0; }
|
||||
|
||||
/* Members Grid */
|
||||
.members-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
.member-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
background: #f0f2f5;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.member-card:hover { background: #e4e6eb; }
|
||||
.user-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: #1877f2;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.member-info h4 { font-size: 15px; font-weight: 600; color: #1c1e21; margin-bottom: 2px; }
|
||||
.member-company { font-size: 13px; color: #65676b; }
|
||||
.member-location, .member-posts { font-size: 13px; color: #65676b; }
|
||||
.rank-badge {
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 12px;
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: #e4e6eb; color: #65676b; }
|
||||
.rank-badge.rank-beginner { background: #e7f3e9; color: #0a832c; }
|
||||
.rank-badge.rank-member { background: #e7f0ff; color: #1877f2; }
|
||||
.rank-badge.rank-contributor { background: #e0f7fa; color: #00838f; }
|
||||
.rank-badge.rank-veteran { background: #f3e5f5; color: #8e24aa; }
|
||||
.rank-badge.rank-expert { background: #fff3e0; color: #e65100; }
|
||||
.rank-badge.rank-legend { background: #fce4ec; color: #c62828; }
|
||||
|
||||
/* Wiki Cards */
|
||||
.wiki-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
background: #f0f2f5;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
border-left: 4px solid #1877f2;
|
||||
}
|
||||
.wiki-card:hover { background: #e4e6eb; }
|
||||
.wiki-card-title { font-size: 15px; font-weight: 600; color: #1c1e21; margin-bottom: 6px; }
|
||||
.wiki-card-excerpt { font-size: 13px; color: #65676b; margin-bottom: 8px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 13px; color: #65676b; }
|
||||
.wiki-card-subtopic { color: #1877f2; }
|
||||
.no-results { padding: 20px; text-align: center; color: #65676b; }
|
||||
.loading-text { padding: 20px; text-align: center; color: #65676b; font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255,255,255,0.8);
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
max-width: 440px;
|
||||
width: 90%;
|
||||
box-shadow: 0 8px 30px rgba(0,0,0,0.2);
|
||||
position: relative;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 16px;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: #65676b;
|
||||
}
|
||||
.login-icon { font-size: 3rem; text-align: center; margin-bottom: 16px; }
|
||||
.login-hint { color: #65676b; text-align: center; margin-bottom: 20px; font-size: 15px; }
|
||||
.form-group { margin-bottom: 14px; }
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #dddfe2;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
.form-input:focus { border-color: #1877f2; outline: 2px solid #1877f2; outline-offset: -2px; }
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile & Detail */
|
||||
.profile-username { font-size: 1.2rem; font-weight: 600; margin-bottom: 8px; }
|
||||
.profile-rank { margin-bottom: 16px; }
|
||||
.user-detail-modal { max-width: 520px; }
|
||||
.user-detail-content { padding: 16px; }
|
||||
.user-detail-avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 16px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 8px; }
|
||||
.user-detail-name-rank h2 { font-size: 1.2rem; font-weight: 600; }
|
||||
.user-detail-fields { display: grid; gap: 10px; }
|
||||
.detail-field { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #e4e6eb; }
|
||||
.detail-label { color: #65676b; font-size: 14px; }
|
||||
.detail-value { color: #1c1e21; font-size: 14px; text-align: right; }
|
||||
.user-detail-company { color: #65676b; text-align: center; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
background: #e7f3ff;
|
||||
padding: 16px 24px;
|
||||
margin: 16px auto;
|
||||
max-width: 1200px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.banner-icon { font-size: 2rem; }
|
||||
.banner-text strong { color: #1c1e21; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 400px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 2.5rem; margin-bottom: 16px; }
|
||||
.newsletter-hint { color: #65676b; margin-bottom: 16px; font-size: 15px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background: #fff;
|
||||
padding: 24px 16px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #e4e6eb;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.footer-brand { margin-bottom: 12px; }
|
||||
.footer-logo { font-size: 1.5rem; }
|
||||
.footer-title { color: #1c1e21; margin-left: 10px; font-size: 14px; font-weight: 600; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 20px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||
.footer-links a { color: #65676b; text-decoration: none; font-size: 13px; }
|
||||
.footer-links a:hover { text-decoration: underline; }
|
||||
.footer-bottom p { color: #65676b; margin: 4px 0; font-size: 12px; }
|
||||
.footer-bottom a { color: #1877f2; }
|
||||
.footer-copy { font-size: 12px; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
flex-direction: column;
|
||||
padding: 12px;
|
||||
gap: 8px;
|
||||
border-top: 1px solid #e4e6eb;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-toggle span { display: block; width: 20px; height: 2px; background: #65676b; }
|
||||
.hero-title { font-size: 28px; }
|
||||
.hero-subtitle { font-size: 16px; }
|
||||
.hero-stats { gap: 30px; flex-wrap: wrap; }
|
||||
.stat-number { font-size: 28px; }
|
||||
.about-grid { grid-template-columns: 1fr; }
|
||||
.wiki-grid { grid-template-columns: 1fr; }
|
||||
.members-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=Rajdhani:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="neon-grid-bg"></div>
|
||||
<div class="scanline"></div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav neo-nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">PARAGUAY<span class="accent">LLC</span></span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-neon" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-neon-outline" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-neon-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal neo-modal" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username</h2>
|
||||
<h2 class="hide-en">Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input neo-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-neon btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input neo-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-neon btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input neo-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input neo-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-neon btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal neo-modal" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input neo-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input neo-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input neo-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input neo-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input neo-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input neo-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-neon btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal user-detail-modal neo-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero neo-hero" id="hero">
|
||||
<div class="hero-particles" id="hero-particles"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title neo-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL</span>
|
||||
<span class="accent">COMMUNITY</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats neo-stats">
|
||||
<div class="stat neo-stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat neo-stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat neo-stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner -->
|
||||
<div class="telegram-banner neo-banner" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-neon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section neo-section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card neo-card">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card neo-card">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card neo-card">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card neo-card">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section neo-section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input neo-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-neon btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer neo-footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">Telegram</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/* Neo-Mirai — Cyberpunk/Futuristic Design */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Rajdhani', sans-serif;
|
||||
background: #0a0a1a;
|
||||
color: #e0e0e0;
|
||||
overflow-x: hidden;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Neon Grid Background */
|
||||
.neon-grid-bg {
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background-image:
|
||||
linear-gradient(rgba(0,255,255,0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0,255,255,0.03) 1px, transparent 1px);
|
||||
background-size: 50px 50px;
|
||||
pointer-events: none; z-index: 0;
|
||||
}
|
||||
|
||||
/* Scanline Effect */
|
||||
.scanline {
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: repeating-linear-gradient(
|
||||
0deg, transparent, transparent 2px, rgba(0,0,0,0.1) 2px, rgba(0,0,0,0.1) 4px
|
||||
);
|
||||
pointer-events: none; z-index: 9999; opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
|
||||
background: rgba(10,10,26,0.95);
|
||||
border-bottom: 1px solid rgba(0,255,255,0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 1200px; margin: 0 auto; padding: 0 20px;
|
||||
display: flex; align-items: center; justify-content: space-between; height: 70px;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex; align-items: center; gap: 10px; text-decoration: none;
|
||||
font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 1.2rem; color: #0ff;
|
||||
text-shadow: 0 0 10px rgba(0,255,255,0.5);
|
||||
}
|
||||
.nav-title { letter-spacing: 2px; }
|
||||
.accent { color: #f0f; text-shadow: 0 0 10px rgba(255,0,255,0.5); }
|
||||
.nav-logo { font-size: 1.5rem; }
|
||||
|
||||
/* Nav Links */
|
||||
.nav-menu { display: flex; align-items: center; gap: 25px; }
|
||||
.nav-link {
|
||||
color: #888; text-decoration: none; font-size: 1rem; font-weight: 500;
|
||||
letter-spacing: 1px; transition: color 0.3s, text-shadow 0.3s;
|
||||
}
|
||||
.nav-link:hover { color: #0ff; text-shadow: 0 0 10px rgba(0,255,255,0.5); }
|
||||
|
||||
/* Nav Actions */
|
||||
.nav-actions { display: flex; align-items: center; gap: 15px; }
|
||||
.lang-select { display: flex; gap: 5px; }
|
||||
.lang-btn {
|
||||
background: none; border: 1px solid rgba(0,255,255,0.3); color: #888;
|
||||
padding: 5px 12px; font-family: 'Orbitron', sans-serif; font-size: 0.8rem;
|
||||
cursor: pointer; transition: all 0.3s; letter-spacing: 1px;
|
||||
}
|
||||
.lang-btn.active, .lang-btn:hover { color: #0ff; border-color: #0ff; box-shadow: 0 0 10px rgba(0,255,255,0.3); }
|
||||
|
||||
/* Buttons */
|
||||
.btn { padding: 8px 20px; font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: 1rem; cursor: pointer; transition: all 0.3s; letter-spacing: 1px; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; border: none; }
|
||||
.btn-neon {
|
||||
background: transparent; border: 1px solid #0ff; color: #0ff;
|
||||
box-shadow: 0 0 5px rgba(0,255,255,0.3), inset 0 0 5px rgba(0,255,255,0.1);
|
||||
}
|
||||
.btn-neon:hover {
|
||||
background: rgba(0,255,255,0.1);
|
||||
box-shadow: 0 0 20px rgba(0,255,255,0.5), inset 0 0 10px rgba(0,255,255,0.2);
|
||||
text-shadow: 0 0 10px #0ff;
|
||||
}
|
||||
.btn-neon-outline { background: transparent; border: 1px solid rgba(0,255,255,0.3); color: #0ff; }
|
||||
.btn-neon-outline:hover { border-color: #0ff; background: rgba(0,255,255,0.1); }
|
||||
.btn-telegram { background: #0088cc; border: none; color: white; padding: 8px 20px; font-family: 'Rajdhani', sans-serif; font-weight: 600; }
|
||||
.btn-telegram:hover { background: #0099dd; }
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
min-height: 100vh; display: flex; align-items: center; justify-content: center;
|
||||
text-align: center; position: relative; padding: 100px 20px 60px;
|
||||
background: radial-gradient(ellipse at center, rgba(0,255,255,0.05) 0%, transparent 70%);
|
||||
}
|
||||
.hero-content { position: relative; z-index: 2; }
|
||||
.neo-title {
|
||||
font-family: 'Orbitron', sans-serif; font-size: 3.5rem; font-weight: 900;
|
||||
color: #fff; letter-spacing: 4px; margin-bottom: 20px;
|
||||
text-shadow: 0 0 20px rgba(0,255,255,0.5), 0 0 40px rgba(0,255,255,0.3);
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 1.3rem; color: #aaa; max-width: 600px; margin: 0 auto 40px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.neo-stats { display: flex; justify-content: center; gap: 60px; }
|
||||
.neo-stat {
|
||||
text-align: center; padding: 20px;
|
||||
border: 1px solid rgba(0,255,255,0.2); border-radius: 10px;
|
||||
background: rgba(0,255,255,0.02);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
.stat-number {
|
||||
display: block; font-family: 'Orbitron', sans-serif; font-size: 2.5rem;
|
||||
font-weight: 900; color: #0ff; text-shadow: 0 0 10px rgba(0,255,255,0.5);
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section { padding: 80px 20px; position: relative; z-index: 1; }
|
||||
.section-alt { background: rgba(0,255,255,0.02); }
|
||||
.section-title {
|
||||
font-family: 'Orbitron', sans-serif; font-size: 2rem; font-weight: 700;
|
||||
color: #0ff; text-align: center; margin-bottom: 50px; letter-spacing: 3px;
|
||||
text-shadow: 0 0 10px rgba(0,255,255,0.3);
|
||||
}
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
|
||||
/* About Cards */
|
||||
.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 25px; }
|
||||
.neo-card {
|
||||
background: rgba(0,255,255,0.02); border: 1px solid rgba(0,255,255,0.15);
|
||||
border-radius: 15px; padding: 30px; transition: all 0.3s;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
.neo-card:hover {
|
||||
border-color: #0ff; box-shadow: 0 0 20px rgba(0,255,255,0.2);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
.about-icon { font-size: 2.5rem; margin-bottom: 15px; }
|
||||
.about-card h3 {
|
||||
font-family: 'Orbitron', sans-serif; font-size: 1.1rem; color: #0ff;
|
||||
margin-bottom: 10px; letter-spacing: 1px;
|
||||
}
|
||||
.about-card p { color: #aaa; font-size: 0.95rem; }
|
||||
|
||||
/* Members */
|
||||
.search-bar { display: flex; align-items: center; max-width: 400px; margin: 0 auto 30px; position: relative; }
|
||||
.search-icon { position: absolute; left: 15px; width: 20px; height: 20px; color: #555; }
|
||||
.search-input {
|
||||
width: 100%; padding: 12px 15px 12px 45px; background: rgba(0,255,255,0.05);
|
||||
border: 1px solid rgba(0,255,255,0.2); border-radius: 8px;
|
||||
color: #fff; font-family: 'Rajdhani', sans-serif; font-size: 1rem;
|
||||
}
|
||||
.search-input:focus { outline: none; border-color: #0ff; box-shadow: 0 0 10px rgba(0,255,255,0.3); }
|
||||
|
||||
.members-grid {
|
||||
display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.member-card {
|
||||
display: flex; align-items: center; gap: 15px; padding: 20px;
|
||||
background: rgba(0,255,255,0.02); border: 1px solid rgba(0,255,255,0.1);
|
||||
border-radius: 10px; cursor: pointer; transition: all 0.3s;
|
||||
}
|
||||
.member-card:hover { border-color: #0ff; box-shadow: 0 0 15px rgba(0,255,255,0.2); }
|
||||
.user-avatar {
|
||||
width: 50px; height: 50px; border-radius: 50%; object-fit: cover;
|
||||
border: 2px solid rgba(0,255,255,0.3);
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 50px; height: 50px; border-radius: 50%;
|
||||
background: rgba(0,255,255,0.1); color: #0ff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: 700;
|
||||
}
|
||||
.member-info h4 { color: #0ff; font-family: 'Orbitron', sans-serif; font-size: 1rem; }
|
||||
.member-company { color: #888; font-size: 0.85rem; }
|
||||
.member-location, .member-posts { color: #aaa; font-size: 0.85rem; }
|
||||
.rank-badge {
|
||||
position: absolute; top: -8px; right: 0; font-size: 0.7rem; padding: 2px 8px;
|
||||
border-radius: 10px; font-weight: 600; letter-spacing: 1px;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: rgba(128,128,128,0.2); color: #888; }
|
||||
.rank-badge.rank-beginner { background: rgba(0,255,0,0.2); color: #0f0; }
|
||||
.rank-badge.rank-member { background: rgba(0,128,255,0.2); color: #08f; }
|
||||
.rank-badge.rank-contributor { background: rgba(0,255,255,0.2); color: #0ff; }
|
||||
.rank-badge.rank-veteran { background: rgba(255,0,255,0.2); color: #f0f; }
|
||||
.rank-badge.rank-expert { background: rgba(255,200,0,0.2); color: #fc0; }
|
||||
.rank-badge.rank-legend { background: rgba(255,0,0,0.2); color: #f44; }
|
||||
|
||||
/* Wiki Grid */
|
||||
.wiki-grid {
|
||||
display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 25px; border-radius: 12px; cursor: pointer;
|
||||
transition: all 0.3s; position: relative; overflow: hidden;
|
||||
}
|
||||
.wiki-card::before {
|
||||
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
|
||||
}
|
||||
.wiki-card[data-color="blue"] { background: rgba(0,100,255,0.05); border: 1px solid rgba(0,100,255,0.2); }
|
||||
.wiki-card[data-color="blue"]::before { background: #0064ff; }
|
||||
.wiki-card[data-color="teal"] { background: rgba(0,200,200,0.05); border: 1px solid rgba(0,200,200,0.2); }
|
||||
.wiki-card[data-color="teal"]::before { background: #00c8c8; }
|
||||
.wiki-card[data-color="green"] { background: rgba(0,200,0,0.05); border: 1px solid rgba(0,200,0,0.2); }
|
||||
.wiki-card[data-color="green"]::before { background: #00c800; }
|
||||
.wiki-card[data-color="orange"] { background: rgba(255,150,0,0.05); border: 1px solid rgba(255,150,0,0.2); }
|
||||
.wiki-card[data-color="orange"]::before { background: #ff9600; }
|
||||
.wiki-card[data-color="purple"] { background: rgba(150,0,255,0.05); border: 1px solid rgba(150,0,255,0.2); }
|
||||
.wiki-card[data-color="purple"]::before { background: #9600ff; }
|
||||
.wiki-card[data-color="pink"] { background: rgba(255,0,150,0.05); border: 1px solid rgba(255,0,150,0.2); }
|
||||
.wiki-card[data-color="pink"]::before { background: #ff0096; }
|
||||
.wiki-card:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
|
||||
.wiki-card-title { font-family: 'Orbitron', sans-serif; font-size: 1.1rem; color: #fff; margin-bottom: 10px; }
|
||||
.wiki-card-excerpt { color: #888; font-size: 0.9rem; margin-bottom: 15px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 0.85rem; color: #aaa; }
|
||||
.wiki-card-subtopic { color: #0ff; }
|
||||
.no-results { color: #888; text-align: center; padding: 40px; }
|
||||
.loading-text { color: #555; text-align: center; padding: 40px; font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.8); backdrop-filter: blur(5px);
|
||||
z-index: 2000; display: none; align-items: center; justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
background: rgba(10,10,26,0.95); border: 1px solid rgba(0,255,255,0.3);
|
||||
border-radius: 15px; padding: 40px; max-width: 500px; width: 90%;
|
||||
box-shadow: 0 0 30px rgba(0,255,255,0.2); position: relative;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute; top: 15px; right: 20px; background: none; border: none;
|
||||
color: #0ff; font-size: 1.5rem; cursor: pointer;
|
||||
}
|
||||
.login-icon { font-size: 3rem; text-align: center; margin-bottom: 20px; }
|
||||
.login-hint { color: #888; text-align: center; margin-bottom: 25px; font-size: 0.95rem; }
|
||||
.form-group { margin-bottom: 15px; }
|
||||
.form-input {
|
||||
width: 100%; padding: 12px; background: rgba(0,255,255,0.05);
|
||||
border: 1px solid rgba(0,255,255,0.2); border-radius: 8px;
|
||||
color: #fff; font-family: 'Rajdhani', sans-serif; font-size: 1rem;
|
||||
}
|
||||
.form-input:focus { outline: none; border-color: #0ff; box-shadow: 0 0 10px rgba(0,255,255,0.3); }
|
||||
.login-steps { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile Modal */
|
||||
.profile-username { font-family: 'Orbitron', sans-serif; font-size: 1.3rem; color: #0ff; margin-bottom: 10px; }
|
||||
.profile-rank { margin-bottom: 20px; }
|
||||
.profile-edit-fields { max-height: 500px; overflow-y: auto; }
|
||||
|
||||
/* User Detail Modal */
|
||||
.user-detail-modal { max-width: 600px; }
|
||||
.user-detail-content { padding: 20px; }
|
||||
.user-detail-avatar {
|
||||
width: 80px; height: 80px; border-radius: 50%; margin: 0 auto 20px;
|
||||
border: 2px solid #0ff; overflow: hidden;
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 20px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; }
|
||||
.user-detail-name-rank h2 { color: #0ff; font-family: 'Orbitron', sans-serif; }
|
||||
.user-detail-fields { display: grid; gap: 10px; }
|
||||
.detail-field { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid rgba(0,255,255,0.1); }
|
||||
.detail-label { color: #888; font-size: 0.9rem; }
|
||||
.detail-value { color: #0ff; font-size: 0.9rem; text-align: right; }
|
||||
.user-detail-company { color: #aaa; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
background: rgba(0,136,204,0.1); border: 1px solid rgba(0,136,204,0.3);
|
||||
padding: 20px; margin: 20px; border-radius: 10px;
|
||||
display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
|
||||
}
|
||||
.banner-icon { font-size: 2rem; }
|
||||
.banner-text { flex: 1; }
|
||||
.banner-text strong { color: #fff; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 400px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 3rem; margin-bottom: 20px; }
|
||||
.newsletter-hint { color: #aaa; margin-bottom: 20px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background: rgba(0,0,0,0.3); border-top: 1px solid rgba(0,255,255,0.1);
|
||||
padding: 40px 20px; text-align: center; position: relative; z-index: 1;
|
||||
}
|
||||
.footer-brand { margin-bottom: 20px; }
|
||||
.footer-logo { font-size: 2rem; }
|
||||
.footer-title { color: #0ff; font-family: 'Orbitron', sans-serif; margin-left: 10px; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 30px; margin-bottom: 20px; flex-wrap: wrap; }
|
||||
.footer-links a { color: #888; text-decoration: none; transition: color 0.3s; letter-spacing: 1px; }
|
||||
.footer-links a:hover { color: #0ff; }
|
||||
.footer-bottom p { color: #555; margin: 5px 0; }
|
||||
.footer-bottom a { color: #0ff; text-decoration: none; }
|
||||
.footer-copy { font-size: 0.85rem; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open { display: flex; position: absolute; top: 70px; left: 0; right: 0; background: rgba(10,10,26,0.98); flex-direction: column; padding: 20px; gap: 15px; border-bottom: 1px solid rgba(0,255,255,0.2); }
|
||||
.nav-toggle { display: block; background: none; border: none; cursor: pointer; display: flex; flex-direction: column; gap: 5px; }
|
||||
.nav-toggle span { display: block; width: 25px; height: 2px; background: #0ff; }
|
||||
.neo-title { font-size: 2rem; }
|
||||
.neo-stats { gap: 15px; flex-wrap: wrap; }
|
||||
.neo-stat { flex: 1; min-width: 120px; }
|
||||
.stat-number { font-size: 1.5rem; }
|
||||
.section-title { font-size: 1.5rem; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
</head>
|
||||
<body data-lang="de" data-logged-in="false">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">Paraguay LLC & SRL</span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-outline" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<!-- Step 1: Username -->
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username eingeben</h2>
|
||||
<h2 class="hide-en">Enter Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 2: Code -->
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 3: Registration -->
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal user-detail-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero-particles" id="hero-particles"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL Community</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL Community</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-scroll-indicator">
|
||||
<div class="scroll-arrow"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner (nicht logged-in) -->
|
||||
<div class="telegram-banner" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-telegram">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content (logged-in) -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section (nur logged-in) -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">
|
||||
Telegram
|
||||
</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/* Wikipedia Style — Clean, Content-First */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: #f8f9fa;
|
||||
color: #202122;
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #a2a9b1;
|
||||
padding: 10px 20px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-decoration: none;
|
||||
color: #202122;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nav-logo { font-size: 1.8rem; }
|
||||
.nav-menu { display: flex; gap: 20px; align-items: center; }
|
||||
.nav-link {
|
||||
color: #0645ad;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.nav-link:hover { text-decoration: underline; }
|
||||
.nav-actions { display: flex; gap: 10px; align-items: center; }
|
||||
.lang-select { display: flex; gap: 5px; }
|
||||
.lang-btn {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #a2a9b1;
|
||||
padding: 4px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.lang-btn.active { background: #36c; color: #fff; border-color: #36c; }
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 6px 16px;
|
||||
font-size: 13px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-weight: 500;
|
||||
border: 1px solid;
|
||||
}
|
||||
.btn-primary { background: #36c; color: #fff; border-color: #36c; }
|
||||
.btn-primary:hover { background: #2a4b8d; }
|
||||
.btn-outline {
|
||||
background: #f8f9fa;
|
||||
color: #202122;
|
||||
border-color: #a2a9b1;
|
||||
}
|
||||
.btn-outline:hover { background: #eaecf0; }
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
.btn-telegram {
|
||||
background: #0088cc;
|
||||
color: #fff;
|
||||
border-color: #0088cc;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #a2a9b1;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 400;
|
||||
margin-bottom: 10px;
|
||||
color: #202122;
|
||||
}
|
||||
.hero-subtitle {
|
||||
color: #72777d;
|
||||
margin-bottom: 30px;
|
||||
font-size: 15px;
|
||||
}
|
||||
.hero-stats { display: flex; justify-content: center; gap: 40px; }
|
||||
.stat { text-align: center; }
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 600;
|
||||
color: #36c;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
background: #fff;
|
||||
border: 1px solid #a2a9b1;
|
||||
border-radius: 4px;
|
||||
padding: 25px;
|
||||
margin: 20px auto;
|
||||
max-width: 1200px;
|
||||
}
|
||||
.section-alt { background: #f8f9fa; border: none; }
|
||||
.section-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
border-bottom: 1px solid #a2a9b1;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
color: #202122;
|
||||
}
|
||||
.container { max-width: 100%; }
|
||||
|
||||
/* About */
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.about-card {
|
||||
padding: 15px;
|
||||
border: 1px solid #eaecf0;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
}
|
||||
.about-icon { font-size: 2rem; margin-bottom: 10px; }
|
||||
.about-card h3 {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 8px;
|
||||
color: #0645ad;
|
||||
}
|
||||
.about-card p { font-size: 13px; color: #555; }
|
||||
|
||||
/* Search */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
max-width: 400px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #72777d;
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #a2a9b1;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.search-input:focus { border-color: #36c; outline: none; }
|
||||
|
||||
/* Members Grid */
|
||||
.members-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
.member-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #eaecf0;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.member-card:hover { background: #eaecf0; }
|
||||
.user-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 1px solid #eaecf0;
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: #eaecf0;
|
||||
color: #72777d;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.member-info h4 { font-size: 14px; color: #0645ad; }
|
||||
.member-company { font-size: 12px; color: #72777d; }
|
||||
.member-location, .member-posts { font-size: 12px; color: #555; }
|
||||
.rank-badge {
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: 0;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: #eee; color: #666; }
|
||||
.rank-badge.rank-beginner { background: #e6f3e6; color: #0a0; }
|
||||
.rank-badge.rank-member { background: #e6f0ff; color: #0066cc; }
|
||||
.rank-badge.rank-contributor { background: #e6f9f9; color: #009999; }
|
||||
.rank-badge.rank-veteran { background: #f9e6ff; color: #990099; }
|
||||
.rank-badge.rank-expert { background: #fff3e6; color: #cc8800; }
|
||||
.rank-badge.rank-legend { background: #ffe6e6; color: #cc0000; }
|
||||
|
||||
/* Wiki Cards */
|
||||
.wiki-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 15px;
|
||||
border: 1px solid #eaecf0;
|
||||
border-left: 4px solid #36c;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.wiki-card:hover { background: #eaecf0; }
|
||||
.wiki-card-title { font-size: 15px; color: #0645ad; margin-bottom: 5px; }
|
||||
.wiki-card-excerpt { font-size: 13px; color: #72777d; margin-bottom: 8px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 12px; color: #555; }
|
||||
.wiki-card-subtopic { color: #0645ad; }
|
||||
.no-results { padding: 20px; text-align: center; color: #72777d; }
|
||||
.loading-text { padding: 20px; text-align: center; color: #72777d; font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255,255,255,0.95);
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
background: #fff;
|
||||
border: 1px solid #a2a9b1;
|
||||
border-radius: 4px;
|
||||
padding: 25px;
|
||||
max-width: 500px;
|
||||
width: 90%;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
color: #72777d;
|
||||
}
|
||||
.login-icon { font-size: 3rem; text-align: center; margin-bottom: 15px; }
|
||||
.login-hint { color: #72777d; text-align: center; margin-bottom: 15px; font-size: 13px; }
|
||||
.form-group { margin-bottom: 12px; }
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #a2a9b1;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.form-input:focus { border-color: #36c; outline: none; }
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile & Detail Modals */
|
||||
.profile-username { font-size: 1.2rem; margin-bottom: 10px; }
|
||||
.profile-rank { margin-bottom: 15px; }
|
||||
.user-detail-modal { max-width: 600px; }
|
||||
.user-detail-content { padding: 15px; }
|
||||
.user-detail-avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 15px;
|
||||
border: 1px solid #a2a9b1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 15px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; }
|
||||
.user-detail-name-rank h2 { font-size: 1.2rem; }
|
||||
.user-detail-fields { display: grid; gap: 8px; }
|
||||
.detail-field { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eaecf0; }
|
||||
.detail-label { color: #72777d; font-size: 13px; }
|
||||
.detail-value { color: #202122; font-size: 13px; text-align: right; }
|
||||
.user-detail-company { color: #555; text-align: center; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
background: #f0f8ff;
|
||||
border: 1px solid #a2a9b1;
|
||||
padding: 15px 20px;
|
||||
margin: 20px auto;
|
||||
max-width: 1200px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
.banner-icon { font-size: 1.5rem; }
|
||||
.banner-text strong { color: #202122; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 400px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 2.5rem; margin-bottom: 15px; }
|
||||
.newsletter-hint { color: #72777d; margin-bottom: 15px; font-size: 13px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background: #f8f9fa;
|
||||
border-top: 1px solid #a2a9b1;
|
||||
padding: 25px 20px;
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
.footer-brand { margin-bottom: 15px; }
|
||||
.footer-logo { font-size: 1.5rem; }
|
||||
.footer-title { color: #202122; margin-left: 10px; font-size: 1rem; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 20px; margin-bottom: 15px; flex-wrap: wrap; }
|
||||
.footer-links a { color: #0645ad; text-decoration: none; font-size: 13px; }
|
||||
.footer-links a:hover { text-decoration: underline; }
|
||||
.footer-bottom p { color: #72777d; margin: 5px 0; font-size: 12px; }
|
||||
.footer-bottom a { color: #0645ad; }
|
||||
.footer-copy { font-size: 12px; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
flex-direction: column;
|
||||
padding: 15px;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid #a2a9b1;
|
||||
}
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.nav-toggle span { display: block; width: 20px; height: 2px; background: #202122; }
|
||||
.hero-stats { gap: 20px; flex-wrap: wrap; }
|
||||
.stat-number { font-size: 1.5rem; }
|
||||
.about-grid { grid-template-columns: 1fr; }
|
||||
.wiki-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Paraguay SRL LLC — Community</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
</head>
|
||||
<body data-lang="de" data-logged-in="false">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav" id="main-nav">
|
||||
<div class="nav-container">
|
||||
<a href="#hero" class="nav-brand">
|
||||
<span class="nav-logo">🌴</span>
|
||||
<span class="nav-title">Paraguay LLC & SRL</span>
|
||||
</a>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<div class="nav-menu" id="nav-menu">
|
||||
<a href="#hero" class="nav-link">
|
||||
<span class="hide-de">Start</span>
|
||||
<span class="hide-en">Home</span>
|
||||
</a>
|
||||
<a href="#about" class="nav-link">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members" class="nav-link">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki" class="nav-link">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-select" id="lang-select">
|
||||
<button class="lang-btn" data-lang="de">DE</button>
|
||||
<button class="lang-btn" data-lang="en">EN</button>
|
||||
</div>
|
||||
<button class="btn btn-outline" id="login-btn">
|
||||
<span class="hide-de">Anmelden</span>
|
||||
<span class="hide-en">Login</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" id="logout-btn" style="display:none;" onclick="logout()">
|
||||
<span class="hide-de">Abmelden</span>
|
||||
<span class="hide-en">Logout</span>
|
||||
</button>
|
||||
<button class="btn btn-outline" id="profile-btn" style="display:none;" onclick="openProfileModal()">
|
||||
<span class="hide-de">Profil</span>
|
||||
<span class="hide-en">Profile</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal-overlay" id="login-modal-overlay">
|
||||
<div class="modal" id="login-modal">
|
||||
<button class="modal-close" onclick="closeLoginModal()">×</button>
|
||||
<div class="login-steps">
|
||||
<!-- Step 1: Username -->
|
||||
<div class="login-step active" id="login-step-1">
|
||||
<div class="login-icon">💬</div>
|
||||
<h2 class="hide-de">Telegram Username eingeben</h2>
|
||||
<h2 class="hide-en">Enter Telegram Username</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Geben Sie Ihren Telegram-Nutzernamen ein, um einen Login-Link per Nachricht zu erhalten.</span>
|
||||
<span class="hide-en">Enter your Telegram username to receive a login link via message.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="telegram-user" class="form-input" placeholder="@username" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="sendTelegramUser()">
|
||||
<span class="hide-de">Login-Link senden</span>
|
||||
<span class="hide-en">Send Login Link</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 2: Code -->
|
||||
<div class="login-step" id="login-step-2">
|
||||
<div class="login-icon">🔐</div>
|
||||
<h2 class="hide-de">Verifizierungscode</h2>
|
||||
<h2 class="hide-en">Verification Code</h2>
|
||||
<p class="login-hint">
|
||||
<span class="hide-de">Der Code wurde an Ihren Telegram-Account gesendet.</span>
|
||||
<span class="hide-en">The code has been sent to your Telegram account.</span>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="verification-code" class="form-input" placeholder="123456" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="verifyCode()">
|
||||
<span class="hide-de">Verifizieren</span>
|
||||
<span class="hide-en">Verify</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Step 3: Registration -->
|
||||
<div class="login-step" id="login-step-3">
|
||||
<div class="login-icon">🎉</div>
|
||||
<h2 class="hide-de">Registrierung abschließen</h2>
|
||||
<h2 class="hide-en">Complete Registration</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" class="form-input" placeholder="Ihr Name" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="llc-name" class="form-input" placeholder="LLC / SRL Name" />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="submitLoginData()">
|
||||
<span class="hide-de">Registrieren</span>
|
||||
<span class="hide-en">Register</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Modal -->
|
||||
<div class="modal-overlay" id="profile-modal-overlay">
|
||||
<div class="modal" id="profile-modal">
|
||||
<button class="modal-close" onclick="closeProfileModal()">×</button>
|
||||
<h2 class="hide-de">Dein Profil</h2>
|
||||
<h2 class="hide-en">Your Profile</h2>
|
||||
<div id="profile-username-display" class="profile-username"></div>
|
||||
<div class="profile-rank" id="profile-rank-badge"></div>
|
||||
<div class="profile-edit-fields">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Name der LLC / SRL</span>
|
||||
<span class="hide-en">LLC / SRL name</span>
|
||||
</label>
|
||||
<input type="text" id="profile-company" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</label>
|
||||
<input type="email" id="profile-email" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</label>
|
||||
<input type="url" id="profile-homepage" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Bild URL</span>
|
||||
<span class="hide-en">Image URL</span>
|
||||
</label>
|
||||
<input type="text" id="profile-image" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</label>
|
||||
<input type="text" id="profile-location" class="form-input" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</label>
|
||||
<textarea id="profile-description" class="form-input" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="profile-publish" class="checkbox" />
|
||||
<label for="profile-publish" class="hide-de">Veröffentlichen</label>
|
||||
<label for="profile-publish" class="hide-en">Publish</label>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" onclick="saveProfile()">
|
||||
<span class="hide-de">Speichern</span>
|
||||
<span class="hide-en">Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Detail Modal -->
|
||||
<div class="modal-overlay" id="user-detail-modal-overlay">
|
||||
<div class="modal user-detail-modal" id="user-detail-modal">
|
||||
<button class="modal-close" onclick="closeUserDetailModal()">×</button>
|
||||
<div class="user-detail-content">
|
||||
<div class="user-detail-avatar" id="user-detail-avatar">
|
||||
<span class="user-avatar-text" id="user-detail-initial">?</span>
|
||||
</div>
|
||||
<div class="user-detail-header">
|
||||
<div class="user-detail-info">
|
||||
<div class="user-detail-name-rank">
|
||||
<h2 id="user-detail-username">@username</h2>
|
||||
<span class="rank-badge" id="user-detail-rank-badge"></span>
|
||||
</div>
|
||||
<p class="user-detail-company" id="user-detail-company">Company</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-detail-fields">
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">E-Mail</span>
|
||||
<span class="hide-en">Email</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-email">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Homepage</span>
|
||||
<span class="hide-en">Homepage</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-homepage">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Standort</span>
|
||||
<span class="hide-en">Location</span>
|
||||
</span>
|
||||
<span class="detail-value" id="user-detail-location">-</span>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<span class="detail-label">
|
||||
<span class="hide-de">Beschreibung</span>
|
||||
<span class="hide-en">Description</span>
|
||||
</span>
|
||||
<span class="detail-value user-desc-value" id="user-detail-description">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero-particles" id="hero-particles"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">
|
||||
<span class="hide-de">Paraguay LLC & SRL Community</span>
|
||||
<span class="hide-en">Paraguay LLC & SRL Community</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span class="hide-de">Der Erfahrungsaustausch für deutsche und amerikanische Expats in Paraguay</span>
|
||||
<span class="hide-en">The experience exchange for German and American expats in Paraguay</span>
|
||||
</p>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-members">--</span>
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-posts">--</span>
|
||||
<span class="hide-de">Beiträge</span>
|
||||
<span class="hide-en">Posts</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number" id="stat-wiki">--</span>
|
||||
<span class="hide-de">Wiki-Artikel</span>
|
||||
<span class="hide-en">Wiki Articles</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-scroll-indicator">
|
||||
<div class="scroll-arrow"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Telegram Banner (nicht logged-in) -->
|
||||
<div class="telegram-banner" id="telegram-banner">
|
||||
<div class="banner-content">
|
||||
<span class="banner-icon">📱</span>
|
||||
<div class="banner-text">
|
||||
<strong>
|
||||
<span class="hide-de">Noch nicht angemeldet?</span>
|
||||
<span class="hide-en">Not logged in yet?</span>
|
||||
</strong>
|
||||
<span class="hide-de">Tritt unserer Telegram-Gruppe bei und erhalte einen Login-Link!</span>
|
||||
<span class="hide-en">Join our Telegram group and receive a login link!</span>
|
||||
</div>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener" class="btn btn-telegram">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12s5.37 12 12 12 12-5.37 12-12S18.63 0 12 0zm5.94 8.13l-1.97 9.27c-.15.67-.54.83-1.09.52l-3.02-2.22-1.46 1.4c-.16.16-.3.3-.61.3l.22-3.06 5.55-5.02c.24-.22-.05-.34-.38-.13L8.69 14.7l-2.95-.92c-.64-.2-.66-.64.14-.95l11.15-4.3c.52-.19.97.13.81.9z"/></svg>
|
||||
<span class="hide-de">Telegram beitreten</span>
|
||||
<span class="hide-en">Join Telegram</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content (logged-in) -->
|
||||
<main class="main-content" id="main-content">
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="section" id="about">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Über die Community</span>
|
||||
<span class="hide-en">About the Community</span>
|
||||
</h2>
|
||||
<div class="about-grid">
|
||||
<div class="about-card">
|
||||
<div class="about-icon">🏦</div>
|
||||
<h3>
|
||||
<span class="hide-de">Banken & Zahlungsverkehr</span>
|
||||
<span class="hide-en">Banking & Payments</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit paraguayischen und internationalen Banken, Konten, Überweisungen und Kreditkarten.</span>
|
||||
<span class="hide-en">Experiences with Paraguayan and international banks, accounts, transfers and credit cards.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">⚖️</div>
|
||||
<h3>
|
||||
<span class="hide-de">Rechtliches</span>
|
||||
<span class="hide-en">Legal Matters</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Gesellschaftsrecht, Verträge, Steuern, Compliance und Rechtsprechung in Paraguay.</span>
|
||||
<span class="hide-en">Corporate law, contracts, taxes, compliance and jurisprudence in Paraguay.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">📊</div>
|
||||
<h3>
|
||||
<span class="hide-de">Steuern & Buchhaltung</span>
|
||||
<span class="hide-en">Taxes & Accounting</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Steuerberatung, Buchhaltungssysteme, Jahresabschlüsse und internationale Steuerplanung.</span>
|
||||
<span class="hide-en">Tax advice, accounting systems, annual statements and international tax planning.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-icon">💻</div>
|
||||
<h3>
|
||||
<span class="hide-de">ERP-Systeme</span>
|
||||
<span class="hide-en">ERP Systems</span>
|
||||
</h3>
|
||||
<p>
|
||||
<span class="hide-de">Erfahrungen mit verschiedenen ERP-Systemen, Software-Lösungen und digitalem Management.</span>
|
||||
<span class="hide-en">Experiences with various ERP systems, software solutions and digital management.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Members Section -->
|
||||
<section class="section section-alt" id="members">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="member-search" class="search-input" placeholder="Mitglieder durchsuchen..." />
|
||||
</div>
|
||||
<div class="members-grid" id="members-list">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Mitglieder...</span>
|
||||
<span class="hide-en">Loading members...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Wiki Section -->
|
||||
<section class="section" id="wiki">
|
||||
<div class="container">
|
||||
<h2 class="section-title">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</h2>
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||
</div>
|
||||
<div class="wiki-grid" id="wiki-grid">
|
||||
<p class="loading-text">
|
||||
<span class="hide-de">Lade Wiki...</span>
|
||||
<span class="hide-en">Loading wiki...</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Newsletter Section (nur logged-in) -->
|
||||
<section class="section section-alt newsletter-section" id="newsletter-section" style="display:none;">
|
||||
<div class="container">
|
||||
<div class="newsletter-card">
|
||||
<div class="newsletter-icon">✉️</div>
|
||||
<h2>
|
||||
<span class="hide-de">Newsletter</span>
|
||||
<span class="hide-en">Newsletter</span>
|
||||
</h2>
|
||||
<p class="newsletter-hint">
|
||||
<span class="hide-de">Erhalten Sie Updates und wichtige Informationen direkt in Ihr Postfach.</span>
|
||||
<span class="hide-en">Receive updates and important information directly in your inbox.</span>
|
||||
</p>
|
||||
<form id="newsletter-form">
|
||||
<div class="form-group">
|
||||
<input type="email" id="newsletter-email" class="form-input" placeholder="name@example.com" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="subscribeNewsletter()">
|
||||
<span class="hide-de">Abonnieren</span>
|
||||
<span class="hide-en">Subscribe</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="newsletter-success" class="hidden">
|
||||
<p class="success-message">
|
||||
<span class="hide-de">Danke! Bitte prüfen Sie Ihre E-Mails.</span>
|
||||
<span class="hide-en">Thank you! Please check your emails.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-brand">
|
||||
<span class="footer-logo">🌴</span>
|
||||
<span class="footer-title">Paraguay LLC & SRL Community</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#about">
|
||||
<span class="hide-de">Über uns</span>
|
||||
<span class="hide-en">About</span>
|
||||
</a>
|
||||
<a href="#members">
|
||||
<span class="hide-de">Mitglieder</span>
|
||||
<span class="hide-en">Members</span>
|
||||
</a>
|
||||
<a href="#wiki">
|
||||
<span class="hide-de">Wiki</span>
|
||||
<span class="hide-en">Wiki</span>
|
||||
</a>
|
||||
<a href="https://t.me/+2s0N78kM5n4xMzBi" target="_blank" rel="noopener">
|
||||
Telegram
|
||||
</a>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>
|
||||
<span class="hide-de">Gesponsert von</span>
|
||||
<span class="hide-en">Sponsored by</span>
|
||||
<a href="https://ODOO4projects.com" target="_blank" rel="noopener">ODOO4projects</a>
|
||||
</p>
|
||||
<p class="footer-copy">
|
||||
<span class="hide-de">© 2025 Paraguay LLC & SRL Community. Alle Rechte vorbehalten.</span>
|
||||
<span class="hide-en">© 2025 Paraguay LLC & SRL Community. All rights reserved.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,637 @@
|
||||
// ========================================
|
||||
// Paraguay LLC & SRL — Main JS
|
||||
// ========================================
|
||||
|
||||
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';
|
||||
const COMMUNITY_URL = 'https://n8n.odoo4projects.com/webhook/paraguay/community';
|
||||
|
||||
let currentLang = 'de';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
currentLang = document.body.dataset.lang || 'de';
|
||||
checkSession();
|
||||
loadCommunityStats();
|
||||
|
||||
// Smooth scroll nav links
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(link.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
// Close mobile nav
|
||||
document.getElementById('nav-menu').classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Mobile nav toggle
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const navMenu = document.getElementById('nav-menu');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
navMenu.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
window.addEventListener('scroll', () => {
|
||||
const nav = document.getElementById('main-nav');
|
||||
if (nav) {
|
||||
nav.classList.toggle('scrolled', window.scrollY > 20);
|
||||
}
|
||||
});
|
||||
|
||||
// Language toggle
|
||||
document.querySelectorAll('.lang-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lang = btn.dataset.lang;
|
||||
setLanguage(lang);
|
||||
// Reload content in new language
|
||||
if (isLoggedIn) {
|
||||
if (document.querySelector('.notebook') || document.getElementById('members-list')) loadUsers();
|
||||
if (document.getElementById('wiki-grid')) loadWiki();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Member search
|
||||
const memberSearch = document.getElementById('member-search');
|
||||
if (memberSearch) {
|
||||
memberSearch.addEventListener('input', (e) => {
|
||||
filterMembers(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Wiki search
|
||||
const wikiSearch = document.getElementById('wiki-search');
|
||||
if (wikiSearch) {
|
||||
wikiSearch.addEventListener('input', (e) => {
|
||||
searchWiki(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// Close modals on overlay click
|
||||
document.querySelectorAll('.modal-overlay').forEach(overlay => {
|
||||
overlay.addEventListener('click', (e) => {
|
||||
if (e.target === overlay) {
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close modals on Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => m.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
// Login button
|
||||
const loginBtn = document.getElementById('login-btn');
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', () => {
|
||||
openLoginModal();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LANGUAGE
|
||||
// ========================================
|
||||
function setLanguage(lang) {
|
||||
currentLang = lang;
|
||||
document.body.dataset.lang = lang;
|
||||
document.querySelectorAll('.lang-btn').forEach(b => {
|
||||
b.classList.toggle('active', b.dataset.lang === lang);
|
||||
});
|
||||
}
|
||||
|
||||
function isDE() {
|
||||
return currentLang !== 'en';
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COMMUNITY STATS
|
||||
// ========================================
|
||||
async function loadCommunityStats() {
|
||||
try {
|
||||
const response = await fetch(COMMUNITY_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.users !== undefined) {
|
||||
animateCounter('stat-members', data.users);
|
||||
}
|
||||
if (data.topics !== undefined) {
|
||||
document.getElementById('stat-wiki').textContent = data.topics;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load community stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function animateCounter(elementId, targetNumber) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
let current = 0;
|
||||
const duration = 1500; // ms
|
||||
const steps = 40;
|
||||
const increment = targetNumber / steps;
|
||||
const stepTime = duration / steps;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += increment;
|
||||
if (current >= targetNumber) {
|
||||
element.textContent = targetNumber;
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current);
|
||||
}
|
||||
}, stepTime);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// AUTH / SESSION
|
||||
// ========================================
|
||||
let isLoggedIn = false;
|
||||
|
||||
function isSessionValid() {
|
||||
const sid = getCookie('sessionid');
|
||||
return sid.length > 0;
|
||||
}
|
||||
|
||||
function checkSession() {
|
||||
isLoggedIn = isSessionValid();
|
||||
|
||||
if (isLoggedIn) {
|
||||
document.body.dataset.loggedIn = 'true';
|
||||
document.getElementById('login-btn').style.display = 'none';
|
||||
document.getElementById('logout-btn').style.display = 'inline-flex';
|
||||
document.getElementById('profile-btn').style.display = 'inline-flex';
|
||||
document.getElementById('telegram-banner').style.display = 'none';
|
||||
document.getElementById('main-content').style.display = 'block';
|
||||
document.getElementById('newsletter-section').style.display = 'block';
|
||||
loadUsers();
|
||||
loadWiki();
|
||||
} else {
|
||||
document.body.dataset.loggedIn = 'false';
|
||||
document.getElementById('login-btn').style.display = 'inline-flex';
|
||||
document.getElementById('logout-btn').style.display = 'none';
|
||||
document.getElementById('profile-btn').style.display = 'none';
|
||||
document.getElementById('telegram-banner').style.display = 'block';
|
||||
document.getElementById('main-content').style.display = 'none';
|
||||
document.getElementById('newsletter-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN MODAL
|
||||
// ========================================
|
||||
function openLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.add('active');
|
||||
// Reset to step 1
|
||||
document.querySelectorAll('.login-step').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('login-step-1').classList.add('active');
|
||||
document.getElementById('telegram-user').value = '';
|
||||
document.getElementById('verification-code').value = '';
|
||||
}
|
||||
|
||||
function closeLoginModal() {
|
||||
document.getElementById('login-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROFILE MODAL
|
||||
// ========================================
|
||||
function openProfileModal() {
|
||||
const sid = getCookie('sessionid');
|
||||
if (!sid) { alert('Bitte anmelden.'); return; }
|
||||
|
||||
fetch(PROFILE_URL + '?sessionid=' + encodeURIComponent(sid))
|
||||
.then(r => r.json())
|
||||
.then(user => {
|
||||
document.getElementById('profile-username-display').textContent = user.username || '';
|
||||
const rank = getRank(user.posts || 0);
|
||||
const badge = document.getElementById('profile-rank-badge');
|
||||
badge.innerHTML = `<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>`;
|
||||
|
||||
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-modal-overlay').classList.add('active');
|
||||
})
|
||||
.catch(() => alert('Fehler beim Laden des Profils.'));
|
||||
}
|
||||
|
||||
function closeProfileModal() {
|
||||
document.getElementById('profile-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
const sid = getCookie('sessionid');
|
||||
fetch(PROFILE_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('profile-username-display').textContent,
|
||||
company: document.getElementById('profile-company').value.trim(),
|
||||
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: sid,
|
||||
publish: document.getElementById('profile-publish').checked
|
||||
})
|
||||
})
|
||||
.then(r => r.ok ? alert('Profil gespeichert!') : alert('Fehler beim Speichern.'))
|
||||
.catch(() => alert('Fehler bei der Verbindung.'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USER DETAIL MODAL
|
||||
// ========================================
|
||||
function openUserDetailModal(user) {
|
||||
const avatar = document.getElementById('user-detail-avatar');
|
||||
if (user.image) {
|
||||
avatar.innerHTML = `<img src="${user.image}" alt="${user.username}">`;
|
||||
} else {
|
||||
avatar.innerHTML = `<span class="user-avatar-text">${(user.username || '?').charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
document.getElementById('user-detail-initial').textContent = '';
|
||||
document.getElementById('user-detail-username').textContent = '@' + (user.username || 'Unknown');
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
document.getElementById('user-detail-rank-badge').className = `rank-badge rank-${rank.level}`;
|
||||
document.getElementById('user-detail-rank-badge').textContent = rank.emoji + ' ' + rank.title;
|
||||
|
||||
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}" target="_blank">${hp}</a>` : '-';
|
||||
|
||||
document.getElementById('user-detail-location').textContent = user.location || '-';
|
||||
document.getElementById('user-detail-description').innerHTML = (user.Description || '-').replace(/\n/g, '<br>');
|
||||
|
||||
document.getElementById('user-detail-modal-overlay').classList.add('active');
|
||||
}
|
||||
|
||||
function closeUserDetailModal() {
|
||||
document.getElementById('user-detail-modal-overlay').classList.remove('active');
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LOGIN FLOW
|
||||
// ========================================
|
||||
function sendTelegramUser() {
|
||||
const user = document.getElementById('telegram-user').value.trim();
|
||||
if (!user) { alert('Bitte geben Sie einen Telegram-Nutzernamen ein.'); return; }
|
||||
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = isDE() ? 'Sende...' : 'Sending...';
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-3').classList.add('active');
|
||||
} else if (data.status === 'code send') {
|
||||
document.getElementById('login-step-1').classList.remove('active');
|
||||
document.getElementById('login-step-2').classList.add('active');
|
||||
} else {
|
||||
alert(isDE() ? 'Benutzername nicht gefunden. Bitte über Telegram Bot anmelden.' : 'Username not found. Please sign up via Telegram bot.');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
btn.disabled = false;
|
||||
alert(isDE() ? 'Verbindungsfehler' : 'Connection error');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
const code = document.getElementById('verification-code').value.trim();
|
||||
if (!code) { alert('Bitte geben Sie den Code ein.'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
code: code,
|
||||
sessionid: getCookie('sessionid')
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Ungültiger Code' : 'Invalid code');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function submitLoginData() {
|
||||
const name = document.getElementById('full-name').value.trim();
|
||||
const llc = document.getElementById('llc-name').value.trim();
|
||||
if (!name || !llc) { alert(isDE() ? 'Bitte Name und LLC eintragen' : 'Please enter name and LLC'); return; }
|
||||
|
||||
fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: document.getElementById('telegram-user').value,
|
||||
name: name,
|
||||
llc: llc
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.sessionid) {
|
||||
setCookie('sessionid', data.sessionid, 1);
|
||||
checkSession();
|
||||
closeLoginModal();
|
||||
} else {
|
||||
alert(isDE() ? 'Registrierung fehlgeschlagen' : 'Registration failed');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setCookie('sessionid', '', -1);
|
||||
checkSession();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NEWSLETTER
|
||||
// ========================================
|
||||
function subscribeNewsletter() {
|
||||
const email = document.getElementById('newsletter-email').value.trim();
|
||||
if (!email) { alert(isDE() ? 'Bitte E-Mail eingeben' : 'Please enter email'); return; }
|
||||
|
||||
fetch(NEWSLETTER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email })
|
||||
})
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
document.getElementById('newsletter-form').classList.add('hidden');
|
||||
document.getElementById('newsletter-success').classList.remove('hidden');
|
||||
} else {
|
||||
alert(isDE() ? 'Fehler beim Abonnieren' : 'Error subscribing');
|
||||
}
|
||||
})
|
||||
.catch(() => alert(isDE() ? 'Verbindungsfehler' : 'Connection error'));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// USERS / MEMBERS
|
||||
// ========================================
|
||||
async function loadUsers() {
|
||||
try {
|
||||
const response = await fetch(USER_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const data = await response.json();
|
||||
const container = document.getElementById('members-list');
|
||||
|
||||
if (data.data && Array.isArray(data.data)) {
|
||||
container.innerHTML = '';
|
||||
container.style.display = 'grid';
|
||||
|
||||
data.data.forEach(user => {
|
||||
const card = createMemberCard(user);
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
// Update stats will be handled by loadCommunityStats
|
||||
} else {
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Mitglieder gefunden' : 'No members found') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
const container = document.getElementById('members-list');
|
||||
container.innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function createMemberCard(user) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'member-card';
|
||||
|
||||
const rank = getRank(user.posts || 0);
|
||||
const avatarContent = user.image
|
||||
? `<img src="${user.image}" alt="${user.username}">`
|
||||
: (user.username || '?').charAt(0).toUpperCase();
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="user-avatar">${avatarContent}</div>
|
||||
<div class="member-info" style="position:relative;">
|
||||
<h4>${user.username || 'N/A'}</h4>
|
||||
<p class="member-company">${user.company || ''}</p>
|
||||
${user.location ? `<p class="member-location">📍 ${user.location}</p>` : ''}
|
||||
${user.posts ? `<p class="member-posts">${user.posts} ${isDE() ? 'Beiträge' : 'posts'}</p>` : ''}
|
||||
<span class="rank-badge rank-${rank.level}">${rank.emoji} ${rank.title}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
card.addEventListener('click', () => openUserDetailModal(user));
|
||||
return card;
|
||||
}
|
||||
|
||||
function filterMembers(term) {
|
||||
const cards = document.querySelectorAll('.member-card');
|
||||
const t = term.toLowerCase();
|
||||
cards.forEach(card => {
|
||||
const text = card.textContent.toLowerCase();
|
||||
card.style.display = text.includes(t) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RANKS
|
||||
// ========================================
|
||||
function getRank(posts) {
|
||||
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: '🌱' };
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WIKI
|
||||
// ========================================
|
||||
let wikiData = [];
|
||||
|
||||
async function loadWiki() {
|
||||
try {
|
||||
const response = await fetch(WIKI_URL);
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
wikiData = result.data;
|
||||
renderWikiCards(wikiData);
|
||||
|
||||
// Wiki count will be loaded from community webhook
|
||||
} else {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderWikiCards(data) {
|
||||
const grid = document.getElementById('wiki-grid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
grid.innerHTML = '<p class="no-results">' + (isDE() ? 'Keine Ergebnisse gefunden' : 'No results found') + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by topic
|
||||
const topics = {};
|
||||
data.forEach(item => {
|
||||
const topicKey = (item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || 'Unknown');
|
||||
if (!topics[topicKey]) topics[topicKey] = [];
|
||||
topics[topicKey].push(item);
|
||||
});
|
||||
|
||||
const colors = ['blue', 'teal', 'green', 'orange', 'purple', 'pink', 'yellow'];
|
||||
|
||||
Object.entries(topics).forEach(([topicName, subtopics], idx) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'wiki-card';
|
||||
card.dataset.color = colors[idx % colors.length];
|
||||
|
||||
// Get excerpt from first subtopic
|
||||
const firstSub = subtopics[0];
|
||||
const excerpt = currentLang === 'en' && firstSub.wiki_en ? firstSub.wiki_en : (firstSub.wiki || '');
|
||||
const subtopicTitle = currentLang === 'en' && firstSub.subtopic_en ? firstSub.subtopic_en : (firstSub.subtopic || '');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="wiki-card-title">${escapeHtml(topicName)}</div>
|
||||
<div class="wiki-card-excerpt">${escapeHtml(excerpt.substring(0, 150))}${excerpt.length > 150 ? '...' : ''}</div>
|
||||
<div class="wiki-card-footer">
|
||||
<span class="wiki-card-subtopic">${escapeHtml(subtopicTitle)}</span>
|
||||
<span>${subtopics.length} ${isDE() ? 'Unterpunkte' : 'subtopics'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Open modal on click
|
||||
card.addEventListener('click', () => openWikiModal(topicName, subtopics));
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function openWikiModal(topicName, subtopics) {
|
||||
// Create modal if not exists
|
||||
let modalOverlay = document.getElementById('wiki-modal-overlay');
|
||||
if (!modalOverlay) {
|
||||
modalOverlay = document.createElement('div');
|
||||
modalOverlay.id = 'wiki-modal-overlay';
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
document.body.appendChild(modalOverlay);
|
||||
}
|
||||
|
||||
let html = '<div class="modal wiki-modal"><button class="modal-close" onclick="closeWikiModal()">×</button>';
|
||||
html += '<div class="wiki-modal-content">';
|
||||
html += `<h2 class="wiki-modal-title">${escapeHtml(topicName)}</h2>`;
|
||||
|
||||
subtopics.forEach(sub => {
|
||||
const title = currentLang === 'en' && sub.subtopic_en ? sub.subtopic_en : (sub.subtopic || '');
|
||||
const content = currentLang === 'en' && sub.wiki_en ? sub.wiki_en : (sub.wiki || '');
|
||||
html += `<h3 class="wiki-modal-subtitle">${escapeHtml(title)}</h3>`;
|
||||
html += `<div class="wiki-modal-text">${escapeHtml(content)}</div>`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
modalOverlay.innerHTML = html;
|
||||
modalOverlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeWikiModal() {
|
||||
const overlay = document.getElementById('wiki-modal-overlay');
|
||||
if (overlay) overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
function searchWiki(term) {
|
||||
if (!term.trim()) {
|
||||
renderWikiCards(wikiData);
|
||||
return;
|
||||
}
|
||||
|
||||
const t = term.toLowerCase();
|
||||
const filtered = wikiData.filter(item => {
|
||||
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
|
||||
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
|
||||
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
|
||||
return topic.toLowerCase().includes(t);
|
||||
});
|
||||
|
||||
renderWikiCards(filtered);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COOKIES
|
||||
// ========================================
|
||||
function getCookie(name) {
|
||||
const localVal = localStorage.getItem('paraguay_' + name);
|
||||
if (localVal) return localVal;
|
||||
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) {
|
||||
return parts.pop().split(';').shift().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=/';
|
||||
localStorage.setItem('paraguay_' + name, value);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILS
|
||||
// ========================================
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
/* X (Twitter) Style — Dark, Minimal, Icon-Driven */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background: #000;
|
||||
color: #e7e9ea;
|
||||
line-height: 1.4;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.nav {
|
||||
background: #000;
|
||||
border-bottom: 1px solid #2f3336;
|
||||
padding: 0 16px;
|
||||
height: 48px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.nav-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
.nav-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-decoration: none;
|
||||
color: #e7e9ea;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.nav-logo { font-size: 22px; }
|
||||
.nav-menu { display: flex; gap: 24px; align-items: center; }
|
||||
.nav-link {
|
||||
color: #71767b;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-link:hover { color: #e7e9ea; }
|
||||
.nav-actions { display: flex; gap: 12px; align-items: center; }
|
||||
.lang-select { display: flex; gap: 6px; }
|
||||
.lang-btn {
|
||||
background: #2f3336;
|
||||
border: none;
|
||||
color: #e7e9ea;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 16px;
|
||||
}
|
||||
.lang-btn.active { background: #1d9bf0; }
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 8px 20px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
border-radius: 9999px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.btn-primary { background: #1d9bf0; color: #fff; }
|
||||
.btn-primary:hover { background: #1a8cd8; }
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: #e7e9ea;
|
||||
border: 1px solid #536471;
|
||||
}
|
||||
.btn-outline:hover { background: rgba(231,233,234,0.1); }
|
||||
.btn-block { display: block; width: 100%; text-align: center; }
|
||||
.btn-telegram { background: #0088cc; color: #fff; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: #000;
|
||||
color: #e7e9ea;
|
||||
text-align: center;
|
||||
padding: 80px 20px 50px;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 17px;
|
||||
color: #71767b;
|
||||
margin-bottom: 30px;
|
||||
max-width: 500px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.hero-stats { display: flex; justify-content: center; gap: 50px; }
|
||||
.stat { text-align: center; }
|
||||
.stat-number {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
.stat { font-size: 13px; color: #71767b; margin-top: 4px; }
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
background: #000;
|
||||
padding: 24px 16px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
border-bottom: 1px solid #2f3336;
|
||||
}
|
||||
.section-alt { background: #000; }
|
||||
.section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
color: #e7e9ea;
|
||||
}
|
||||
.container { max-width: 100%; }
|
||||
|
||||
/* About */
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.about-card {
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
background: #0f1419;
|
||||
border: 1px solid #2f3336;
|
||||
}
|
||||
.about-icon { font-size: 1.8rem; margin-bottom: 10px; }
|
||||
.about-card h3 { font-size: 14px; font-weight: 600; color: #e7e9ea; margin-bottom: 6px; }
|
||||
.about-card p { font-size: 13px; color: #71767b; line-height: 1.4; }
|
||||
|
||||
/* Search */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #71767b;
|
||||
}
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 12px 14px 12px 38px;
|
||||
border: 1px solid #2f3336;
|
||||
border-radius: 24px;
|
||||
background: #202327;
|
||||
font-size: 15px;
|
||||
color: #e7e9ea;
|
||||
}
|
||||
.search-input:focus { outline: none; border-color: #1d9bf0; }
|
||||
|
||||
/* Members */
|
||||
.members-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
.member-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 16px;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.member-card:hover { background: #16181c; }
|
||||
.user-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.user-avatar-text {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: #1d9bf0;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.member-info h4 { font-size: 15px; font-weight: 600; color: #e7e9ea; }
|
||||
.member-company { font-size: 13px; color: #71767b; }
|
||||
.member-location, .member-posts { font-size: 13px; color: #71767b; }
|
||||
.rank-badge {
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.rank-badge.rank-rookie { background: #2f3336; color: #71767b; }
|
||||
.rank-badge.rank-beginner { background: #0f3a0f; color: #4ade80; }
|
||||
.rank-badge.rank-member { background: #0c2a5e; color: #60a5fa; }
|
||||
.rank-badge.rank-contributor { background: #0a3d3d; color: #2dd4bf; }
|
||||
.rank-badge.rank-veteran { background: #3a0a5e; color: #c084fc; }
|
||||
.rank-badge.rank-expert { background: #5e3a0a; color: #fbbf24; }
|
||||
.rank-badge.rank-legend { background: #5e0a0a; color: #f87171; }
|
||||
|
||||
/* Wiki Cards */
|
||||
.wiki-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
.wiki-card {
|
||||
padding: 14px 16px;
|
||||
border-radius: 12px;
|
||||
background: #0f1419;
|
||||
border: 1px solid #2f3336;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.wiki-card:hover { background: #16181c; }
|
||||
.wiki-card-title { font-size: 15px; font-weight: 600; color: #e7e9ea; margin-bottom: 4px; }
|
||||
.wiki-card-excerpt { font-size: 13px; color: #71767b; margin-bottom: 6px; }
|
||||
.wiki-card-footer { display: flex; justify-content: space-between; font-size: 13px; color: #71767b; }
|
||||
.wiki-card-subtopic { color: #1d9bf0; }
|
||||
.no-results { padding: 20px; text-align: center; color: #71767b; }
|
||||
.loading-text { padding: 20px; text-align: center; color: #71767b; font-style: italic; }
|
||||
|
||||
/* Modal */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(91,112,131,0.4);
|
||||
z-index: 2000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal {
|
||||
background: #000;
|
||||
border: 1px solid #2f3336;
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
max-width: 440px;
|
||||
width: 90%;
|
||||
position: relative;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 16px;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
color: #e7e9ea;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-close:hover { background: #202327; }
|
||||
.login-icon { font-size: 2.5rem; text-align: center; margin-bottom: 16px; }
|
||||
.login-hint { color: #71767b; text-align: center; margin-bottom: 20px; font-size: 15px; }
|
||||
.form-group { margin-bottom: 14px; }
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #2f3336;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
color: #e7e9ea;
|
||||
background: transparent;
|
||||
}
|
||||
.form-input:focus { border-color: #1d9bf0; outline: 2px solid #1d9bf0; outline-offset: -2px; }
|
||||
.login-step { display: none; }
|
||||
.login-step.active { display: block; }
|
||||
|
||||
/* Profile & Detail */
|
||||
.profile-username { font-size: 1.2rem; font-weight: 600; margin-bottom: 8px; }
|
||||
.profile-rank { margin-bottom: 16px; }
|
||||
.user-detail-modal { max-width: 480px; }
|
||||
.user-detail-content { padding: 16px; }
|
||||
.user-detail-avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-detail-header { text-align: center; margin-bottom: 16px; }
|
||||
.user-detail-name-rank { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 8px; }
|
||||
.user-detail-name-rank h2 { font-size: 1.2rem; font-weight: 700; }
|
||||
.user-detail-fields { display: grid; gap: 10px; }
|
||||
.detail-field { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #2f3336; }
|
||||
.detail-label { color: #71767b; font-size: 14px; }
|
||||
.detail-value { color: #e7e9ea; font-size: 14px; text-align: right; }
|
||||
.user-detail-company { color: #71767b; text-align: center; }
|
||||
|
||||
/* Telegram Banner */
|
||||
.telegram-banner {
|
||||
background: #0f1419;
|
||||
border: 1px solid #2f3336;
|
||||
padding: 14px 20px;
|
||||
margin: 16px auto;
|
||||
max-width: 600px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
.banner-icon { font-size: 1.6rem; }
|
||||
.banner-text strong { color: #e7e9ea; }
|
||||
|
||||
/* Newsletter */
|
||||
.newsletter-card { text-align: center; max-width: 360px; margin: 0 auto; }
|
||||
.newsletter-icon { font-size: 2rem; margin-bottom: 14px; }
|
||||
.newsletter-hint { color: #71767b; margin-bottom: 14px; font-size: 14px; }
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
background: #000;
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #2f3336;
|
||||
}
|
||||
.footer-brand { margin-bottom: 12px; }
|
||||
.footer-logo { font-size: 1.4rem; }
|
||||
.footer-title { color: #e7e9ea; margin-left: 10px; font-size: 14px; font-weight: 600; }
|
||||
.footer-links { display: flex; justify-content: center; gap: 18px; margin-bottom: 10px; flex-wrap: wrap; }
|
||||
.footer-links a { color: #71767b; text-decoration: none; font-size: 13px; }
|
||||
.footer-links a:hover { color: #e7e9ea; }
|
||||
.footer-bottom p { color: #71767b; margin: 4px 0; font-size: 12px; }
|
||||
.footer-bottom a { color: #1d9bf0; }
|
||||
.footer-copy { font-size: 12px; }
|
||||
|
||||
/* Hide/Show */
|
||||
.hide-en { display: none; }
|
||||
body[data-lang="en"] .hide-en { display: inline; }
|
||||
body[data-lang="en"] .hide-de { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.nav-menu { display: none; }
|
||||
.nav-menu.open {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #000;
|
||||
flex-direction: column;
|
||||
padding: 12px;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid #2f3336;
|
||||
}
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-toggle span { display: block; width: 18px; height: 2px; background: #e7e9ea; }
|
||||
.hero-title { font-size: 24px; }
|
||||
.hero-subtitle { font-size: 15px; }
|
||||
.hero-stats { gap: 24px; flex-wrap: wrap; }
|
||||
.stat-number { font-size: 22px; }
|
||||
.about-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (min-width: 769px) {
|
||||
.nav-toggle { display: none; }
|
||||
}
|
||||
Reference in New Issue
Block a user