Advanced Certificate in Particle Effects: VFX Industry Application

-- ViewingNow

The Advanced Certificate in Particle Effects: VFX Industry Application is a comprehensive course that focuses on the creation and implementation of particle effects, a crucial component in the visual effects (VFX) industry. This certificate program emphasizes the importance of particle effects in creating realistic and engaging visuals for films, video games, and other multimedia platforms.

4,0
Based on 3.117 reviews

5.251+

Students enrolled

GBP £ 140

GBP £ 202

Save 44% with our special offer

Start Now

รœber diesen Kurs

With the increasing demand for high-quality visual effects, this course is essential for professionals seeking to advance their careers in the VFX industry. Learners will gain hands-on experience in various particle effect techniques, including simulation, animation, and rendering, using industry-standard software such as Houdini and Nuke. By mastering these skills, learners will be able to create more compelling and immersive visuals, enhancing their marketability and competitiveness in the industry. This course is ideal for VFX artists, animators, and multimedia designers seeking to expand their skillset and stay up-to-date with the latest industry trends. By completing this program, learners will not only gain the technical skills necessary for creating impressive particle effects but also develop their creativity, problem-solving abilities, and attention to detail, making them valuable assets in the VFX industry.

100% online

Lernen Sie von รผberall

Teilbares Zertifikat

Zu Ihrem LinkedIn-Profil hinzufรผgen

2 Monate zum AbschlieรŸen

bei 2-3 Stunden pro Woche

Jederzeit beginnen

Keine Wartezeit

Kursdetails

โ€ข Advanced Particle System Simulation: This unit will cover the advanced simulation techniques for particle effects in the VFX industry.
โ€ข Fluid Dynamics and Smoke Effects: This unit will focus on creating realistic fluid dynamics and smoke effects using particle systems.
โ€ข Destruction and Explosion Effects: This unit will cover the creation of advanced destruction and explosion effects using particle systems.
โ€ข Nature and Organic Effects: This unit will focus on creating realistic nature and organic effects such as fire, water, and grass using particle systems.
โ€ข Rigid Body Simulation and Dynamics: This unit will cover the simulation and dynamics of rigid bodies in a particle system.
โ€ข Particle System Lighting and Rendering: This unit will focus on the lighting and rendering techniques for particle systems used in the VFX industry.
โ€ข Real-time Particle Effects: This unit will cover the creation of real-time particle effects for video games and other interactive media.
โ€ข Particle Effects in Maya and Houdini: This unit will focus on the practical application of particle effects in industry-standard software such as Maya and Houdini.
โ€ข Optimization and Performance Techniques: This unit will cover the optimization and performance techniques for particle effects in the VFX industry.

Note: The above-mentioned units are just a suggestion, the actual course content and units may vary based on the course provider, industry standard and other factors.

Please note: The above code is a simple HTML code and it's plain text format. You can copy and paste the code into your HTML file or text editor to view the formatted content.

Additional Note: The above code is not a complete HTML file, it only contains the content of the units. You need to include the necessary HTML tags like , , , , <body> etc to make it a complete and functional HTML file. </p> <p> <strong>Additional Additional Note:</strong> The </div> </div> </div> </div> <div class="col-md-12 mt-4"> <div class="card"> <div class="card-body"> <h2 class="text-2xl font-bold text-gray-900 mb-4">Karriereweg</h2> <div id="careerPath" class="mt-3"> <div style="width: 100%; height: 400px; margin-bottom: 20px;"> <div id="chart_div" style="width: 100%; height: 100%;"></div> </div> <script src="https://www.gstatic.com/charts/loader.js"></script> <script> google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ['Role', 'Percentage'], ['VFX Artist', 45], ['3D Modeler', 25], ['Particle Effects Artist', 16], ['VFX Compositor', 14] ]); var options = { title: 'Advanced Certificate in Particle Effects: VFX Industry Application Job Role Distribution', backgroundColor: 'transparent', is3D: true, legend: { position: 'labeled' }, slices: { 0: { color: '#ff6f69' }, 1: { color: '#ffcc5c' }, 2: { color: '#b8ffb0' }, 3: { color: '#8fd9ff' } } }; var chart = new google.visualization.PieChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> In the VFX industry, various roles contribute to the creation of stunning visual effects. Here's a breakdown of the most relevant positions in the sector: 1. **VFX Artist**: As a VFX Artist, you'll be responsible for generating and implementing visual effects in films, TV shows, and video games. With an Advanced Certificate in Particle Effects, you can specialize in dynamic and visually captivating particle effects. 2. **3D Modeler**: 3D Modelers create and refine the digital models used in various industries, including film, animation, and gaming. A strong foundation in particle effects can enhance your ability to create realistic and immersive environments. 3. **Particle Effects Artist**: A Particle Effects Artist specializes in the creation and animation of particle-based visual effects. This role is essential for creating convincing phenomena like fire, smoke, and magical effects in various media. 4. **VFX Compositor**: As a VFX Compositor, your primary responsibility is combining various visual elements seamlessly into a single scene. Understanding particle effects allows you to integrate these elements more effectively and realistically. These roles highlight the growing demand for professionals with advanced particle effects skills in the UK's VFX industry. </div> </div> </div> </div> <!-- Entry Requirements and Accreditation Grid --> <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6"> <!-- Entry Requirements Section --> <div class="bg-white rounded-lg shadow-sm overflow-hidden border border-gray-100"> <div class="p-6"> <div class="flex items-center mb-3"> <h2 class="text-lg font-semibold text-gray-900">Zugangsvoraussetzungen</h2> </div> <div class="prose prose-sm prose-blue max-w-none text-gray-600"> <ul class="list-disc pl-5 space-y-1 text-sm"> <li>Grundlegendes Verstรคndnis des Themas</li> <li>Englischkenntnisse</li> <li>Computer- und Internetzugang</li> <li>Grundlegende Computerkenntnisse</li> <li>Engagement, den Kurs abzuschlieรŸen</li> </ul> <p class="mt-2 text-sm">Keine vorherigen formalen Qualifikationen erforderlich. Kurs fรผr Zugรคnglichkeit konzipiert.</p> </div> </div> </div> <!-- Accreditation Section --> <div class="bg-white rounded-lg shadow-sm overflow-hidden border border-gray-100"> <div class="p-6"> <div class="flex items-center mb-3"> <h2 class="text-lg font-semibold text-gray-900">Kursstatus</h2> </div> <div class="prose prose-sm prose-green max-w-none text-gray-600"> <p class="text-sm">Dieser Kurs vermittelt praktisches Wissen und Fรคhigkeiten fรผr die berufliche Entwicklung. Er ist:</p> <ul class="list-disc pl-5 space-y-1 text-sm"> <li>Nicht von einer anerkannten Stelle akkreditiert</li> <li>Nicht von einer autorisierten Institution reguliert</li> <li>Ergรคnzend zu formalen Qualifikationen</li> </ul> <p class="mt-2 text-sm">Sie erhalten ein Abschlusszertifikat nach erfolgreichem Abschluss des Kurses.</p> </div> </div> </div> </div> <!-- Student Reviews Section (AJAX loaded) --> <div id="reviewsSection" class="my-8"> <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Warum Menschen uns fรผr ihre Karriere wรคhlen</h2> <div id="reviewsLoading" class="text-center text-gray-500"> <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-[#0056D2] mx-auto"></div> <p class="mt-2">Bewertungen werden geladen...</p> </div> </div> </div> <!-- FAQ Section --> <div class="my-4"> <div class="bg-white rounded-2xl shadow-md p-4"> <h2 class="text-2xl font-bold text-gray-900 mb-3">Hรคufig gestellte Fragen</h2> <div class="grid grid-cols-1 gap-2" itemscope itemtype="https://schema.org/FAQPage"> <!-- FAQ Item 1 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">Was macht diesen Kurs im Vergleich zu anderen einzigartig?</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>Unser Kurs bietet eine fokussierte Lernerfahrung mit:</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>Umfassende Kursmaterialien, die wesentliche Themen abdecken</li> <li>Flexibler Lernplan, der sich an Ihre Bedรผrfnisse anpasst</li> <li>Selbstgesteuertes Lernumfeld</li> <li>Zugang zu Kursinhalten wรคhrend der Dauer Ihrer Einschreibung</li> <li>Abschlusszertifikat nach Beendigung des Kurses</li> </ul> </div> </div> </div> <!-- FAQ Item 2 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">Wie lange dauert es, den Kurs abzuschlieรŸen?</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>Wir bieten zwei flexible Lernpfade, die sich an Ihren Zeitplan anpassen:</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li><strong>Schnellkurs:</strong> Abschluss in 1 Monat mit 3-4 Stunden Studium pro Woche</li> <li><strong>Standardmodus:</strong> Abschluss in 2 Monaten mit 2-3 Stunden Studium pro Woche</li> </ul> <p class="mt-0.5">Sie kรถnnen in Ihrem eigenen Tempo voranschreiten und 24/7 auf die Materialien zugreifen.</p> </div> </div> </div> <!-- FAQ Item 3 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">WhatSupportWillIReceive</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>DuringYourCourse</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>AccessCourseMaterials</li> <li>TechnicalSupport</li> <li>EmailSupport</li> <li>ClearCourseStructure</li> </ul> <p class="mt-0.5">SelfPacedCourseNote</p> </div> </div> </div> <!-- FAQ Item 4 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">IsCertificateRecognized</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>ProgramDesignedProvide</p> <p class="mt-0.5">WhatYouWillGain</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>KnowledgeUnderstanding</li> <li>CertificateShowcase</li> <li>SelfPacedLearningExperience</li> <li>Umfassende Kursmaterialien, die wesentliche Themen abdecken</li> <li>UnderstandingKeyConcepts</li> </ul> <p class="mt-0.5">Ergรคnzend zu formalen Qualifikationen</p> </div> </div> </div> <!-- FAQ Item 5 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">WhatCareerOpportunities</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>Dieser Kurs vermittelt Wissen und Verstรคndnis im Fachbereich, was wertvoll sein kann fรผr:</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>Verbesserung Ihres Verstรคndnisses des Fachgebiets</li> <li>Ergรคnzung Ihres Portfolios fรผr berufliche Entwicklung</li> <li>Demonstration Ihres Engagements fรผr das Lernen</li> <li>Aufbau von Grundlagenwissen im Fach</li> <li>Unterstรผtzung Ihres bestehenden Karrierewegs</li> </ul> <p class="mt-0.5">Bitte beachten Sie, dass dieser Kurs zwar wertvolles Wissen vermittelt, aber keine spezifischen Karriereergebnisse oder Arbeitsplatzvermittlungen garantiert. Der Wert des Kurses hรคngt davon ab, wie Sie das erworbene Wissen in Ihrem beruflichen Kontext anwenden.</p> </div> </div> </div> <!-- FAQ Item 6 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">Wann kann ich mit dem Kurs beginnen?</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>Wir bieten sofortigen Zugang zu unseren Kursmaterialien รผber unser offenes Einschreibesystem. Das bedeutet:</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>Der Kurs beginnt sofort, sobald Sie die Kursgebรผhr bezahlt haben</li> <li>Keine Wartezeiten oder feste Startdaten</li> <li>Sofortiger Zugang zu allen Kursmaterialien bei Zahlung</li> <li>Flexibilitรคt, wann Sie beginnen mรถchten</li> </ul> <p class="mt-0.5">Dieser selbstgesteuerte Ansatz ermรถglicht es Ihnen, sofort mit Ihrer beruflichen Entwicklungsreise zu beginnen und Ihr Lernen an Ihre bestehenden Verpflichtungen anzupassen.</p> </div> </div> </div> <!-- FAQ Item 7 --> <div class="expandable-card bg-gradient-to-br from-gray-50 to-white rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-200 cursor-pointer" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"> <div class="px-3 py-2 flex items-center justify-between card-header"> <h3 class="text-lg font-semibold text-gray-900" itemprop="name">Was ist das Kursformat und der Lernansatz?</h3> <span class="expand-icon text-gray-400 transition-transform duration-200">▼</span> </div> <div class="px-3 pb-2 card-content hidden" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"> <div class="text-gray-700 leading-relaxed" itemprop="text"> <p>Unser Kurs ist als umfassendes Selbststudienprogramm konzipiert, das Folgendes bietet:</p> <ul class="list-disc pl-4 mt-0.5 space-y-0.5"> <li>Strukturierte Lernmaterialien, die 24/7 zugรคnglich sind</li> <li>Umfassende Kursinhalte fรผr das Selbststudium</li> <li>Flexibler Lernplan, der sich an Ihren Lebensstil anpasst</li> <li>Zugang zu allen notwendigen Ressourcen und Materialien</li> </ul> <p class="mt-0.5">Dieser selbstgesteuerte Lernansatz ermรถglicht es Ihnen, in Ihrem eigenen Tempo voranzukommen, was ideal fรผr beschรคftigte Fachkrรคfte ist, die Flexibilitรคt in ihrem Lernplan benรถtigen. Obwohl es keine Live-Klassen oder praktische Sitzungen gibt, sind die Kursmaterialien so konzipiert, dass sie ein grรผndliches Verstรคndnis der Materie durch Selbststudium vermitteln.</p> </div> </div> </div> </div> </div> </div> </div> <!-- Sidebar --> <div class="space-y-6"> <!-- Debug line --> <div class="hidden">Debug: False</div> <!-- Podcast Box --> <!-- Skills Gained Box (replaces Course Information) --> <!-- Pricing Box --> <div class="course-fee-section bg-gradient-to-br from-blue-100/60 to-indigo-100/40 rounded-2xl shadow-xl border border-blue-200/40 p-1"> <div class="bg-white rounded-2xl p-6 md:p-8 shadow-lg"> <h3 class="text-2xl font-extrabold text-gray-900 mb-7 tracking-tight">Kursgebรผhr</h3> <div class="space-y-7"> <!-- Fast Track --> <div class="relative rounded-xl border border-gray-200 bg-white shadow-md p-4 transition-transform hover:scale-[1.02] hover:shadow-2xl duration-200"> <div class="flex justify-end mb-2"> <span class="inline-flex items-center gap-1.5 bg-gradient-to-r from-green-500 via-emerald-400 to-lime-400 text-white text-xs font-extrabold px-3 py-1 rounded-full shadow-xl ring-1 ring-green-300/40 tracking-wider uppercase animate-pulse"> <svg class="w-3.5 h-3.5 text-white drop-shadow" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg> AM BELIEBTESTEN </span> </div> <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-1 gap-2"> <span class="text-2xl font-extrabold text-gray-900">Schnellkurs:</span> <span class="text-3xl font-black text-gray-900 flex items-baseline whitespace-nowrap"><span class="mr-1 text-[1.25rem]">GBP £</span>140</span> </div> <div class="text-base text-gray-500 font-medium mb-2">Abschluss in 1 Monat</div> <div class="inline-flex items-center bg-green-100 text-green-800 font-semibold text-base rounded-lg px-3 py-1.5 mb-2 shadow-sm"> <svg class="w-4 h-4 mr-2 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg> Beschleunigter Lernpfad </div> <ul class="text-sm text-gray-700 space-y-1 mb-3"> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>3-4 Stunden pro Woche</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Frรผhe Zertifikatslieferung</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Offene Einschreibung - jederzeit beginnen</li> </ul> <a href="https://shortcourses.lsibonline.com/ExternalApi/GenerateCourseByTitle?CourseTitle=Advanced Certificate in Particle Effects: VFX Industry Application" target="_blank" class="w-full block text-center py-[0.6rem] rounded-lg bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-[1.01rem] text-white shadow-lg transition-all duration-200 tracking-wide">Start Now</a> </div> <!-- Standard Mode --> <div class="rounded-xl border border-gray-200 bg-white shadow p-4"> <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-1 gap-2"> <span class="text-2xl font-extrabold text-gray-900">Standardmodus:</span> <span class="text-3xl font-black text-gray-900 flex items-baseline whitespace-nowrap"><span class="mr-1 text-[1.25rem]">GBP £</span>90</span> </div> <div class="text-base text-gray-500 font-medium mb-2">Abschluss in 2 Monaten</div> <div class="inline-flex items-center bg-blue-100 text-blue-800 font-semibold text-base rounded-lg px-3 py-1.5 mb-2 shadow-sm"> <svg class="w-4 h-4 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2v-8a2 2 0 012-2h2"/></svg> Flexibler Lerntempo </div> <ul class="text-sm text-gray-700 space-y-1 mb-3"> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>2-3 Stunden pro Woche</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>RegelmรครŸige Zertifikatslieferung</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Offene Einschreibung - jederzeit beginnen</li> </ul> <a href="https://shortcourses.lsibonline.com/ExternalApi/GenerateCourseByTitle?CourseTitle=Advanced Certificate in Particle Effects: VFX Industry Application" target="_blank" class="w-full block text-center py-[0.6rem] rounded-lg bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-[1.01rem] text-white shadow-lg transition-all duration-200 tracking-wide">Start Now</a> </div> <!-- Included in both plans --> <div class="rounded-xl border border-gray-100 bg-gradient-to-r from-gray-50 to-white shadow p-3"> <div class="font-bold text-gray-900 mb-1 text-base">Was in beiden Plรคnen enthalten ist:</div> <ul class="text-sm text-gray-700 space-y-1"> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Voller Kurszugang</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Digitales Zertifikat</li> <li class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Kursmaterialien</li> </ul> </div> <div class="text-xs text-gray-500 mb-4 text-center font-medium">All-Inclusive-Preis โ€ข Keine versteckten Gebรผhren oder zusรคtzliche Kosten</div> </div> </div> </div> <!-- Email Form Box --> <div class="bg-white rounded-xl shadow-sm overflow-hidden"> <div class="p-6"> <h3 class="text-lg font-semibold text-gray-900 mb-4">Kursinformationen erhalten</h3> <form method="post" class="space-y-4" action="/de/global-uk/Course/SendCourseEmail"> <input type="hidden" name="id" value="320562" /> <div> <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Ihre E-Mail-Adresse</label> <div class="relative rounded-md shadow-sm"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> <svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207" /> </svg> </div> <input type="email" name="email" id="email" required class="block w-full pl-10 pr-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#0056D2] focus:border-[#0056D2] sm:text-sm transition duration-150 ease-in-out" placeholder="Enter your email address"> </div> <p class="mt-1 text-sm text-gray-500">Wir senden Ihnen detaillierte Kursinformationen</p> </div> <button type="submit" class="w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> Informationen erhalten </button> <input name="__RequestVerificationToken" type="hidden" value="CfDJ8NbB8zPi4aZJj-nCHzpyxgRjP8z_DV1UXpDWSq7rDhDIdSo-PP3NHYcZSaZv3tHw_2-UFAng6j7mqeWPMEmXQyiYUpRaaJ5Q9dHL_tESorWUJC0HM96zxbVeFNj76YtLu7FKrMHiMGJ1mw2-obWtBbA" /></form> </div> </div> <!-- Pay as a company Box --> <div class="bg-white rounded-xl shadow-sm overflow-hidden"> <div class="p-6"> <h3 class="text-lg font-semibold text-gray-900 mb-4">Als Unternehmen bezahlen</h3> <p class="text-sm text-gray-600 mb-4">Fordern Sie eine Rechnung fรผr Ihr Unternehmen an, um diesen Kurs zu bezahlen.</p> <a class="w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" href="/de/global-uk/Invoice?courseId=320562"> Per Rechnung bezahlen </a> </div> </div> <!-- Sample Certificate Box --> <div class="bg-white rounded-xl shadow-sm overflow-hidden"> <div class="p-6"> <h3 class="text-lg font-semibold text-gray-900 mb-4">Ein Karrierezertifikat erwerben</h3> <div class="w-full max-w-md mx-auto relative" style="aspect-ratio:1/1.414;"> <img src="/uploads/certificate-backgrounds/57003f95-5d8e-41e9-99b5-961a52d43d0a_001.jpg" alt="Beispiel-Zertifikatshintergrund" class="w-full h-full rounded-xl border border-gray-200 object-cover" onerror="this.onerror=null; this.src='/images/certificate-bg.jpg';" loading="lazy" width="600" height="850" /> <div class="absolute inset-0 flex flex-col items-center justify-center px-4 py-8 text-center pointer-events-none select-none"> <div class="text-sm md:text-lg font-bold text-gray-900 mb-2 drop-shadow-sm">ADVANCED CERTIFICATE IN PARTICLE EFFECTS: VFX INDUSTRY APPLICATION</div> <div class="text-xs md:text-sm text-gray-800 mb-0.5">wird verliehen an</div> <div class="text-sm md:text-lg font-bold text-gray-900 mb-1">Name des Lernenden</div> <div class="text-[11px] md:text-xs text-gray-800 mb-0.5">der ein Programm abgeschlossen hat bei</div> <div class="text-[11px] md:text-xs font-semibold text-gray-900 mb-2">London School of International Business (LSIB)</div> <div class="text-[11px] md:text-xs text-gray-800 mb-0.5">Verliehen am</div> <div class="text-[11px] md:text-xs font-semibold text-gray-900 mb-1">05 May 2025</div> <div class="text-[9px] md:text-[10px] text-gray-700 mt-1">Blockchain-ID: s-1-a-2-m-3-p-4-l-5-e</div> </div> </div> <div class="mt-4 text-sm text-gray-600"> Fรผgen Sie diese Qualifikation zu Ihrem LinkedIn-Profil, Lebenslauf oder CV hinzu. Teilen Sie sie in sozialen Medien und in Ihrer Leistungsbewertung. </div> </div> </div> </div> </div> </div> </div> <style> /* .prose { max-width: 65ch; color: #374151; } .prose h1, .prose h2, .prose h3, .prose h4 { color: #111827; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; } .prose p { margin-top: 1.25em; margin-bottom: 1.25em; } .prose ul { margin-top: 1.25em; margin-bottom: 1.25em; list-style-type: disc; padding-left: 1.625em; } .prose li { margin-top: 0.5em; margin-bottom: 0.5em; } */ .glass-card { background: rgba(255, 255, 255, 0.35); box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-radius: 1rem; border: 1px solid rgba(255, 255, 255, 0.18); padding: 1rem; transition: box-shadow 0.3s, transform 0.3s; } .glass-card:hover { box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.25); transform: translateY(-2px) scale(1.03); } .course-fee-section { font-size: 95%; } </style> <!-- Add chat component at the end of the body --> </script> <script> (function() { 'use strict'; // Get the API endpoint from the business info const API_ENDPOINT = 'https://reactor.LSIB.co.uk/api/process-page'; const API_KEY = '1234'; // <-- Set this to match your appsettings.json // Debug: Log the API endpoint being used console.log('API_ENDPOINT from BusinessInfo:', 'https://reactor.LSIB.co.uk/api/process-page'); console.log('Final API_ENDPOINT value:', API_ENDPOINT); console.log('BusinessInfo object:', {"id":1,"businessName":"London School of International Business (LSIB)","location":"London, United Kingdom (U.K.)","isActive":true,"updatedAt":"2025-09-23T19:23:53.663","updatedBy":null,"emailAddress":"admissions@LSIB.co.uk","smtpServer":"smtp.mandrillapp.com","smtpPort":587,"smtpUsername":"LSIB","smtpPassword":"md-9dtwpX.91IN676p8thZfIA","enableSsl":true,"footerColor":null,"loginUrl":"https://shortcourses.lsibonline.com/Account/Login","homeTitle":null,"homeMetaKeywords":null,"homeMetaDescription":null,"homeOGTitle":null,"homeOGDescription":null,"homeOGImageUrl":null,"homeTwitterTitle":null,"homeTwitterDescription":null,"homeTwitterImageUrl":null,"homeCanonicalUrl":null,"searchTitle":null,"searchMetaKeywords":null,"searchMetaDescription":null,"searchOGTitle":null,"searchOGDescription":null,"searchOGImageUrl":null,"searchTwitterTitle":null,"searchTwitterDescription":null,"searchTwitterImageUrl":null,"searchCanonicalUrl":null,"domainName":"https://pathways.lsib.nl","showExpertConversations":false,"defaultFee1":"140","defaultFee2":"90","currency":"GBP \u00A3","logoHeightInEmail":60,"logoHeightInWebsite":80,"reactorURL":"https://reactor.LSIB.co.uk/api/process-page"}); function init() { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', processPage); } else { processPage(); } } function processPage() { const h1Element = document.querySelector('h1'); if (!h1Element) { console.log('No H1 element found'); return; } const title = h1Element.textContent.trim(); const url = window.location.href; console.log('Found title:', title); console.log('Current URL:', url); console.log('Sending to API...'); sendToAPI(title, url); } function sendToAPI(title, url) { const payload = { title: title, url: url, timestamp: new Date().toISOString(), userAgent: navigator.userAgent, referrer: document.referrer, website: window.location.hostname }; fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY }, body: JSON.stringify(payload) }) .then(response => { console.log('API Response status:', response.status); if (response.ok) { console.log('Course title processed successfully'); return response.json(); } else { return response.json().then(data => { console.log('API error:', data); throw new Error(data.message || 'API request failed'); }); } }) .then(data => { if (data) { console.log('API Response data:', data); } }) .catch(error => { console.log('API call failed:', error.message); }); } init(); })(); </script> </main> <footer b-u4k2yyhrco class="text-white py-8 mt-12 shadow-inner" style="background: linear-gradient(to right, #1e3a8a, #0A2676, #1e3a8a);"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" crossorigin="anonymous" /> <div b-u4k2yyhrco class="max-w-7xl mx-auto px-4 flex flex-col md:flex-row items-center justify-between"> <div b-u4k2yyhrco class="text-left w-full md:w-auto mb-4 md:mb-0"> <span b-u4k2yyhrco class="text-xs md:text-sm" style="font-family: 'Source Sans Pro', sans-serif; font-weight: 400;"> © 2026 London School of International Business (LSIB), London, United Kingdom (U.K.). Alle Rechte vorbehalten. </span> </div> <div b-u4k2yyhrco class="flex flex-col md:flex-row md:items-center md:space-x-6 space-y-2 md:space-y-0 mb-4 md:mb-0"> <a b-u4k2yyhrco href="/CookiePolicy" class="text-white hover:text-blue-300 text-xs md:text-sm transition-colors">Cookie-Richtlinie</a> <a b-u4k2yyhrco href="/TermsAndConditions" class="text-white hover:text-blue-300 text-xs md:text-sm transition-colors">Allgemeine Geschรคftsbedingungen</a> <a b-u4k2yyhrco href="/PrivacyPolicy" class="text-white hover:text-blue-300 text-xs md:text-sm transition-colors">Datenschutzrichtlinie</a> </div> <div b-u4k2yyhrco class="flex space-x-2"> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="Facebook"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-facebook-f fa-stack-1x fa-inverse"></i></span></a> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="LinkedIn"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-linkedin-in fa-stack-1x fa-inverse"></i></span></a> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="Twitter"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-twitter fa-stack-1x fa-inverse"></i></span></a> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="YouTube"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-youtube fa-stack-1x fa-inverse"></i></span></a> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="Instagram"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-instagram fa-stack-1x fa-inverse"></i></span></a> <a b-u4k2yyhrco href="#" class="hover:text-blue-300" aria-label="TikTok"><span b-u4k2yyhrco class="fa-stack fa-sm"><i b-u4k2yyhrco class="fa fa-circle fa-stack-2x"></i><i b-u4k2yyhrco class="fab fa-tiktok fa-stack-1x fa-inverse"></i></span></a> </div> </div> <div b-u4k2yyhrco class="text-center mt-2"> <span b-u4k2yyhrco class="text-xs text-gray-300">IP: 216.73.216.150</span> </div> </footer> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/js/site.js?v=5t4OrdtvjXcig92cDnIv_JtyQzfFb98buyozA7dkZ-E"></script> <script src="/lib/microsoft/signalr/dist/browser/signalr.js" defer></script> <script src="/js/chat.js" defer></script> <script> // FAQ Toggle Function with improved reliability document.addEventListener('DOMContentLoaded', function() { const faqButtons = document.querySelectorAll('.faq-button'); faqButtons.forEach(button => { button.addEventListener('click', function() { const faqItem = this.closest('.faq-item'); const content = faqItem.querySelector('.faq-content'); const icon = faqItem.querySelector('.faq-icon'); // Toggle content visibility content.classList.toggle('hidden'); // Toggle icon rotation icon.classList.toggle('rotate-180'); // Add active state to the button this.classList.toggle('active'); }); }); }); const connection = new signalR.HubConnectionBuilder() .withUrl("/courseHub") .build(); connection.on("ReceiveCourseOverview", (courseId, overview) => { if (courseId === 320562) { const overviewElement = document.getElementById('courseOverview'); const preloader = document.getElementById('overviewPreloader'); if (overviewElement && preloader) { overviewElement.innerHTML = overview; preloader.style.display = 'none'; overviewElement.style.display = 'block'; } } }); // Remove the TitleSEOUpdated SignalR handler and add polling function pollTitleSEO() { fetch(`/Course/GetTitleSEO/${320562}`) .then(response => response.text()) .then(titleSEO => { if (titleSEO && titleSEO.trim() !== '') { // Update the page title document.title = titleSEO; // Update meta title const metaTitle = document.querySelector('meta[name="title"]'); if (metaTitle) { metaTitle.setAttribute('content', titleSEO); } // Update Open Graph title const ogTitle = document.querySelector('meta[property="og:title"]'); if (ogTitle) { ogTitle.setAttribute('content', titleSEO); } // Update Twitter title const twitterTitle = document.querySelector('meta[name="twitter:title"]'); if (twitterTitle) { twitterTitle.setAttribute('content', titleSEO); } } else { // If title is still empty, poll again after 2 seconds setTimeout(pollTitleSEO, 2000); } }) .catch(error => { console.error('Error polling TitleSEO:', error); setTimeout(pollTitleSEO, 2000); }); } // Start polling if TitleSEO is empty if (!True.ToString().toLowerCase()) { pollTitleSEO(); } connection.on("DescriptionUpdated", (courseId, description) => { if (courseId === 320562) { const descriptionElement = document.getElementById('courseDescription'); const preloader = document.getElementById('descriptionPreloader'); if (descriptionElement && preloader) { descriptionElement.innerHTML = description; preloader.style.display = 'none'; descriptionElement.style.display = 'block'; } } }); connection.on("CourseDetailsUpdated", (courseId, details) => { if (courseId === 320562) { console.log('Received CourseDetailsUpdated SignalR event for course:', courseId); const courseDetailsElement = document.getElementById('courseDetails'); const preloaderElement = document.getElementById('courseDetailsPreloader'); if (courseDetailsElement && preloaderElement) { courseDetailsElement.innerHTML = details; preloaderElement.style.display = 'none'; console.log('Course details updated via SignalR'); } } }); connection.on("CareerPathUpdated", (courseId, careerPath) => { if (courseId === 320562) { const careerPathElement = document.getElementById('careerPath'); const preloaderElement = document.getElementById('careerPathPreloader'); if (careerPathElement && preloaderElement) { careerPathElement.innerHTML = careerPath; preloaderElement.style.display = 'none'; } } }); connection.start() .then(() => console.log("SignalR Connected")) .catch(err => console.error("SignalR Connection Error: ", err)); </script> <script> document.addEventListener('DOMContentLoaded', function() { const courseId = 320562; // Load Reviews function loadReviews() { fetch(`/Course/GetReviewsText/${courseId}`) .then(response => { if (!response.ok) throw new Error('No reviews'); return response.json(); }) .then(reviews => { const reviewsSection = document.getElementById('reviewsSection'); if (!Array.isArray(reviews) || reviews.length === 0) { reviewsSection.innerHTML = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="text-center text-gray-500">No reviews available.</div> </div>`; return; } let html = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="space-y-6">`; reviews.forEach(review => { html += ` <div class="bg-gradient-to-br from-white to-gray-50 rounded-xl shadow-sm p-6 border border-gray-100 hover:shadow-md transition-shadow duration-200"> <div class="flex items-center mb-3"> <span class="text-2xl mr-3">${countryCodeToFlagEmoji(review.countryCode)}</span> <div> <span class="font-semibold text-lg text-gray-900">${review.name}</span> <span class="ml-2 px-2 py-0.5 rounded-full bg-blue-50 text-blue-700 text-xs font-medium uppercase tracking-wide">${review.countryCode ? review.countryCode.toUpperCase() : ''}</span> </div> <div class="ml-auto flex items-center"> <div class="flex items-center"> ${generateStarRating(review.rating)} </div> <span class="ml-2 text-sm text-gray-600">${review.rating.toFixed(1)}</span> </div> </div> <div class="text-gray-700 text-base leading-relaxed italic pl-11"> " ${review.review} " </div> </div>`; }); html += ` </div> </div>`; reviewsSection.innerHTML = html; }) .catch(() => { const reviewsSection = document.getElementById('reviewsSection'); reviewsSection.innerHTML = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="text-center text-gray-500">Unable to load reviews at this time.</div> </div>`; }); } // Load Podcast function loadPodcast() { fetch(`/Course/CheckPodcastStatus/${courseId}`) .then(response => response.json()) .then(data => { const podcastContainer = document.getElementById('podcastContainer'); if (data.status === 'ready') { podcastContainer.innerHTML = ` <audio id="podcastPlayer" controls class="w-full" preload="auto"> <source src="/Course/GetPodcastAudio/${courseId}" type="audio/mpeg"> Your browser does not support the audio element. </audio> <div class="flex justify-end items-center mt-2 mb-2"> <a href="#" id="toggleTranscript" class="text-blue-600 hover:underline text-xs font-medium">Show transcript</a> </div> <p class="text-sm text-gray-600 mb-4">Listen to industry experts discuss key concepts and real-world applications of this course</p> <div id="transcript" class="mt-2 hidden bg-gray-50 border border-gray-200 rounded-lg p-4 text-gray-900 text-sm max-h-48 overflow-y-auto"> Loading transcript... </div> `; // Load transcript fetch(`/Course/GetPodcastTranscript/${courseId}`) .then(response => response.text()) .then(content => { const transcript = document.getElementById('transcript'); if (transcript) { // Format the transcript content const formattedContent = content .split('\n') .map(line => { if (line.startsWith('HOST:')) { return `<div class="mb-2"><span class="font-semibold text-blue-700">HOST:</span> ${line.substring(5).trim()}</div>`; } else if (line.startsWith('GUEST:')) { return `<div class="mb-3"><span class="font-semibold text-green-700">GUEST:</span> ${line.substring(6).trim()}</div>`; } return line; }) .join(''); transcript.innerHTML = formattedContent; } }); // Setup transcript toggle const toggleButton = document.getElementById('toggleTranscript'); const transcript = document.getElementById('transcript'); if (toggleButton && transcript) { toggleButton.addEventListener('click', function(e) { e.preventDefault(); const isHidden = transcript.classList.contains('hidden'); transcript.classList.toggle('hidden'); toggleButton.textContent = isHidden ? 'Hide transcript' : 'Show transcript'; }); } } else { podcastContainer.innerHTML = ` <div class="text-center py-4"> <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-[#0056D2] mx-auto"></div> <p class="mt-2 text-sm text-gray-600">Generating podcast...</p> </div> `; // Check status again in 5 seconds setTimeout(loadPodcast, 5000); } }) .catch(error => { console.error('Error loading podcast:', error); const podcastContainer = document.getElementById('podcastContainer'); podcastContainer.innerHTML = ` <div class="text-center py-4"> <p class="text-sm text-red-600">Error loading podcast. Please try again later.</p> </div> `; }); } // Helper to convert country code to emoji flag function countryCodeToFlagEmoji(code) { if (!code || code.length !== 2) return ''; return String.fromCodePoint(0x1F1E6 + code.toUpperCase().charCodeAt(0) - 65) + String.fromCodePoint(0x1F1E6 + code.toUpperCase().charCodeAt(1) - 65); } function generateStarRating(rating) { let stars = ''; const fullStars = Math.floor(rating); const hasHalfStar = rating % 1 >= 0.5; // Add full stars for (let i = 0; i < fullStars; i++) { stars += `<svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20"> <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } // Add half star if needed if (hasHalfStar) { stars += `<svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20"> <defs> <linearGradient id="halfStar"> <stop offset="50%" stop-color="currentColor"/> <stop offset="50%" stop-color="#D1D5DB"/> </linearGradient> </defs> <path fill="url(#halfStar)" d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } // Add empty stars const emptyStars = 5 - fullStars - (hasHalfStar ? 1 : 0); for (let i = 0; i < emptyStars; i++) { stars += `<svg class="w-5 h-5 text-gray-300" fill="currentColor" viewBox="0 0 20 20"> <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } return stars; } // Start loading both sections loadReviews(); loadPodcast(); // AJAX call to update Fee2 if needed fetch('/Course/UpdateFee2IfNeeded', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value || '' }, body: 'id=' + encodeURIComponent(320562) }); // AJAX call to update Fee1 if needed fetch('/Course/UpdateFee1IfNeeded', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value || '' }, body: 'id=' + encodeURIComponent(320562) }); // Add AJAX call for Duration1 update // AJAX call to update Duration1 if needed fetch('/Course/UpdateDuration1IfNeeded', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value || '' }, body: 'id=' + encodeURIComponent(320562) }); // Add AJAX call for Duration2 update // AJAX call to update Duration2 if needed fetch('/Course/UpdateDuration2IfNeeded', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name=\"__RequestVerificationToken\"]')?.value || '' }, body: 'id=' + encodeURIComponent(320562) }); }); </script> <script> document.addEventListener('DOMContentLoaded', function() { const courseId = 320562; // Load Reviews function loadReviews() { fetch(`/Course/GetReviewsText/${courseId}`) .then(response => { if (!response.ok) throw new Error('No reviews'); return response.json(); }) .then(reviews => { const reviewsSection = document.getElementById('reviewsSection'); if (!Array.isArray(reviews) || reviews.length === 0) { reviewsSection.innerHTML = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="text-center text-gray-500">No reviews available.</div> </div>`; return; } let html = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="space-y-6">`; reviews.forEach(review => { html += ` <div class="bg-gradient-to-br from-white to-gray-50 rounded-xl shadow-sm p-6 border border-gray-100 hover:shadow-md transition-shadow duration-200"> <div class="flex items-center mb-3"> <span class="text-2xl mr-3">${countryCodeToFlagEmoji(review.countryCode)}</span> <div> <span class="font-semibold text-lg text-gray-900">${review.name}</span> <span class="ml-2 px-2 py-0.5 rounded-full bg-blue-50 text-blue-700 text-xs font-medium uppercase tracking-wide">${review.countryCode ? review.countryCode.toUpperCase() : ''}</span> </div> <div class="ml-auto flex items-center"> <div class="flex items-center"> ${generateStarRating(review.rating)} </div> <span class="ml-2 text-sm text-gray-600">${review.rating.toFixed(1)}</span> </div> </div> <div class="text-gray-700 text-base leading-relaxed italic pl-11"> " ${review.review} " </div> </div>`; }); html += ` </div> </div>`; reviewsSection.innerHTML = html; }) .catch(() => { const reviewsSection = document.getElementById('reviewsSection'); reviewsSection.innerHTML = ` <div class="bg-white rounded-2xl shadow-md p-8"> <h2 class="text-2xl font-bold text-gray-900 mb-6">Why people choose us for their career</h2> <div class="text-center text-gray-500">Unable to load reviews at this time.</div> </div>`; }); } // Load Podcast function loadPodcast() { fetch(`/Course/CheckPodcastStatus/${courseId}`) .then(response => response.json()) .then(data => { const podcastContainer = document.getElementById('podcastContainer'); if (data.status === 'ready') { podcastContainer.innerHTML = ` <audio id="podcastPlayer" controls class="w-full" preload="auto"> <source src="/Course/GetPodcastAudio/${courseId}" type="audio/mpeg"> Your browser does not support the audio element. </audio> <div class="flex justify-end items-center mt-2 mb-2"> <a href="#" id="toggleTranscript" class="text-blue-600 hover:underline text-xs font-medium">Show transcript</a> </div> <p class="text-sm text-gray-600 mb-4">Listen to industry experts discuss key concepts and real-world applications of this course</p> <div id="transcript" class="mt-2 hidden bg-gray-50 border border-gray-200 rounded-lg p-4 text-gray-900 text-sm max-h-48 overflow-y-auto"> Loading transcript... </div> `; // Load transcript fetch(`/Course/GetPodcastTranscript/${courseId}`) .then(response => response.text()) .then(content => { const transcript = document.getElementById('transcript'); if (transcript) { // Format the transcript content const formattedContent = content .split('\n') .map(line => { if (line.startsWith('HOST:')) { return `<div class="mb-2"><span class="font-semibold text-blue-700">HOST:</span> ${line.substring(5).trim()}</div>`; } else if (line.startsWith('GUEST:')) { return `<div class="mb-3"><span class="font-semibold text-green-700">GUEST:</span> ${line.substring(6).trim()}</div>`; } return line; }) .join(''); transcript.innerHTML = formattedContent; } }); // Setup transcript toggle const toggleButton = document.getElementById('toggleTranscript'); const transcript = document.getElementById('transcript'); if (toggleButton && transcript) { toggleButton.addEventListener('click', function(e) { e.preventDefault(); const isHidden = transcript.classList.contains('hidden'); transcript.classList.toggle('hidden'); toggleButton.textContent = isHidden ? 'Hide transcript' : 'Show transcript'; }); } } else { podcastContainer.innerHTML = ` <div class="text-center py-4"> <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-[#0056D2] mx-auto"></div> <p class="mt-2 text-sm text-gray-600">Generating podcast...</p> </div> `; // Check status again in 5 seconds setTimeout(loadPodcast, 5000); } }) .catch(error => { console.error('Error loading podcast:', error); const podcastContainer = document.getElementById('podcastContainer'); podcastContainer.innerHTML = ` <div class="text-center py-4"> <p class="text-sm text-red-600">Error loading podcast. Please try again later.</p> </div> `; }); } // Helper to convert country code to emoji flag function countryCodeToFlagEmoji(code) { if (!code || code.length !== 2) return ''; return String.fromCodePoint(0x1F1E6 + code.toUpperCase().charCodeAt(0) - 65) + String.fromCodePoint(0x1F1E6 + code.toUpperCase().charCodeAt(1) - 65); } function generateStarRating(rating) { let stars = ''; const fullStars = Math.floor(rating); const hasHalfStar = rating % 1 >= 0.5; // Add full stars for (let i = 0; i < fullStars; i++) { stars += `<svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20"> <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } // Add half star if needed if (hasHalfStar) { stars += `<svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20"> <defs> <linearGradient id="halfStar"> <stop offset="50%" stop-color="currentColor"/> <stop offset="50%" stop-color="#D1D5DB"/> </linearGradient> </defs> <path fill="url(#halfStar)" d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } // Add empty stars const emptyStars = 5 - fullStars - (hasHalfStar ? 1 : 0); for (let i = 0; i < emptyStars; i++) { stars += `<svg class="w-5 h-5 text-gray-300" fill="currentColor" viewBox="0 0 20 20"> <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg>`; } return stars; } // Start loading both sections loadReviews(); loadPodcast(); }); </script> <script> // Add polling for career path updates function pollCareerPath() { fetch(`/Course/GetCareerPath/${320562}`) .then(response => response.text()) .then(careerPath => { if (careerPath && careerPath.trim() !== '') { const careerPathElement = document.getElementById('careerPath'); const preloaderElement = document.getElementById('careerPathPreloader'); if (careerPathElement && preloaderElement) { careerPathElement.innerHTML = careerPath; preloaderElement.style.display = 'none'; } } else { setTimeout(pollCareerPath, 2000); // Poll every 2 seconds } }) .catch(error => { console.error('Error polling career path:', error); setTimeout(pollCareerPath, 2000); }); } // Start polling if career path is empty if (document.getElementById('careerPathPreloader')) { pollCareerPath(); } </script> <script> // Add polling for course details updates function pollCourseDetails() { console.log('Polling course details for course ID:', 320562); fetch(`/Course/GetCourseDetails/${320562}`) .then(response => { console.log('Course details response status:', response.status); return response.text(); }) .then(courseDetails => { console.log('Course details received:', courseDetails ? courseDetails.length + ' characters' : 'empty'); if (courseDetails && courseDetails.trim() !== '') { const courseDetailsElement = document.getElementById('courseDetails'); const preloaderElement = document.getElementById('courseDetailsPreloader'); if (courseDetailsElement && preloaderElement) { courseDetailsElement.innerHTML = courseDetails; preloaderElement.style.display = 'none'; console.log('Course details updated in UI'); } } else { console.log('Course details still empty, continuing to poll...'); setTimeout(pollCourseDetails, 2000); // Poll every 2 seconds } }) .catch(error => { console.error('Error polling course details:', error); setTimeout(pollCourseDetails, 2000); }); } // Start polling if course details is empty const preloaderElement = document.getElementById('courseDetailsPreloader'); const courseDetailsElement = document.getElementById('courseDetails'); // Check if CourseDetails is empty or preloader is visible const isCourseDetailsEmpty = !courseDetailsElement || !courseDetailsElement.innerHTML || courseDetailsElement.innerHTML.trim() === '' || courseDetailsElement.innerHTML.trim() === 'Page Not Found'; // Only start polling if preloader is visible AND CourseDetails is empty if (preloaderElement && preloaderElement.style.display !== 'none' && isCourseDetailsEmpty) { console.log('Starting course details polling...'); console.log('Preloader display:', preloaderElement.style.display); console.log('CourseDetails empty:', isCourseDetailsEmpty); pollCourseDetails(); } else { console.log('Course details already loaded, skipping polling'); console.log('Preloader display:', preloaderElement ? preloaderElement.style.display : 'null'); console.log('CourseDetails content length:', courseDetailsElement ? courseDetailsElement.innerHTML.length : 0); } // Add manual trigger for testing (remove in production) window.manualPollCourseDetails = function() { console.log('Manual polling triggered'); pollCourseDetails(); }; // Add a test function to check if polling is working window.testPolling = function() { console.log('Testing polling mechanism...'); const courseDetailsElement = document.getElementById('courseDetails'); const preloaderElement = document.getElementById('courseDetailsPreloader'); console.log('CourseDetails element:', courseDetailsElement); console.log('Preloader element:', preloaderElement); console.log('CourseDetails content:', courseDetailsElement ? courseDetailsElement.innerHTML : 'null'); console.log('Preloader display:', preloaderElement ? preloaderElement.style.display : 'null'); pollCourseDetails(); }; // Fallback: Start polling after a short delay if CourseDetails is still empty setTimeout(function() { const courseDetailsElement = document.getElementById('courseDetails'); const preloaderElement = document.getElementById('courseDetailsPreloader'); if (courseDetailsElement && preloaderElement && (!courseDetailsElement.innerHTML || courseDetailsElement.innerHTML.trim() === '' || courseDetailsElement.innerHTML.trim() === 'Page Not Found') && preloaderElement.style.display !== 'none') { console.log('Fallback: Starting course details polling after delay...'); pollCourseDetails(); } }, 1000); // Optimized Dynamic Viewer Count (function initializeViewerCount() { const viewersElement = document.getElementById('currentViewers'); if (!viewersElement) return; // Constants const MIN_VIEWERS = 10; const MAX_VIEWERS = 50; const UPDATE_INTERVAL = 5000; // 5 seconds const CHANGE_PROBABILITY = 0.7; // 70% chance of change // Initialize with a random number let currentViewers = Math.floor(Math.random() * (MAX_VIEWERS - MIN_VIEWERS + 1)) + MIN_VIEWERS; viewersElement.textContent = currentViewers; // Use requestAnimationFrame for smooth updates let lastUpdate = 0; function updateCount(timestamp) { if (timestamp - lastUpdate >= UPDATE_INTERVAL) { // Only update if probability threshold is met if (Math.random() < CHANGE_PROBABILITY) { // Weighted random change (-1 is more likely than +1) const change = Math.random() < 0.6 ? -1 : 1; currentViewers = Math.max(MIN_VIEWERS, Math.min(MAX_VIEWERS, currentViewers + change)); viewersElement.textContent = currentViewers; } lastUpdate = timestamp; } requestAnimationFrame(updateCount); } // Start the animation loop requestAnimationFrame(updateCount); })(); </script> <script> // Add polling for about this course updates function pollAboutThisCourse() { fetch(`/Course/GetAboutThisCourse/${320562}`) .then(response => response.text()) .then(overview => { if (overview && overview.trim() !== '') { const descriptionElement = document.getElementById('courseDescription'); const preloaderElement = document.getElementById('descriptionPreloader'); if (descriptionElement && preloaderElement) { // Split the overview into sentences and skip first two const sentences = overview.split('.'); const remainingContent = sentences.slice(2).join('.').trimStart('.'); descriptionElement.innerHTML = remainingContent; preloaderElement.style.display = 'none'; descriptionElement.style.display = 'block'; } } else { setTimeout(pollAboutThisCourse, 2000); // Poll every 2 seconds } }) .catch(error => { console.error('Error polling about this course:', error); setTimeout(pollAboutThisCourse, 2000); }); } // Start polling if description preloader exists if (document.getElementById('descriptionPreloader')) { pollAboutThisCourse(); } </script> <script> document.addEventListener('DOMContentLoaded', function() { const cards = document.querySelectorAll('.expandable-card'); cards.forEach(card => { const header = card.querySelector('.card-header'); const content = card.querySelector('.card-content'); const icon = card.querySelector('.expand-icon'); header.addEventListener('click', function(e) { // Close all other cards cards.forEach(otherCard => { if (otherCard !== card) { const otherContent = otherCard.querySelector('.card-content'); const otherIcon = otherCard.querySelector('.expand-icon'); if (otherContent && !otherContent.classList.contains('hidden')) { otherContent.classList.add('hidden'); otherIcon.classList.remove('rotate-180'); } } }); // Toggle this card content.classList.toggle('hidden'); icon.classList.toggle('rotate-180'); }); }); }); </script> <script> // Existing scripts... // Handle success badge document.addEventListener('DOMContentLoaded', function() { const successBadge = document.getElementById('successBadge'); if (successBadge) { setTimeout(() => { successBadge.style.opacity = '0'; successBadge.style.transform = 'translateY(-20px)'; setTimeout(() => { successBadge.remove(); }, 300); }, 5000); } }); </script> <script> // Language switcher functionality and visibility management document.addEventListener('DOMContentLoaded', function() { // Function to get current culture from URL path or default to current thread culture function getCurrentCulture() { const path = window.location.pathname; const segments = path.split('/').filter(segment => segment.length > 0); if (segments.length > 0) { const supportedLanguages = ['en', 'es', 'fr', 'de', 'ar', 'zh', 'ja', 'ko', 'hi', 'pt']; if (supportedLanguages.includes(segments[0])) { return segments[0]; } } return 'de'; } // Function to get current location from URL path or default to 'global' function getCurrentLocation() { const path = window.location.pathname; const segments = path.split('/').filter(segment => segment.length > 0); if (segments.length >= 2) { return segments[1]; } return 'global'; } // Function to update all search forms with the correct language and location-based action URLs function updateSearchFormsCulture() { const mobileSearchForm = document.getElementById('mobileSearchForm'); const desktopSearchForm = document.getElementById('desktopSearchForm'); const homeSearchForm = document.getElementById('homeSearchForm'); const currentCulture = getCurrentCulture(); const currentLocation = getCurrentLocation(); if (mobileSearchForm) { mobileSearchForm.action = `/${currentCulture}/${currentLocation}/Search`; } if (desktopSearchForm) { desktopSearchForm.action = `/${currentCulture}/${currentLocation}/Search`; } if (homeSearchForm) { homeSearchForm.action = `/${currentCulture}/${currentLocation}/Search`; } } // Initialize search forms with current culture updateSearchFormsCulture(); // Add form submit event listeners to ensure forms are always updated const mobileSearchForm = document.getElementById('mobileSearchForm'); const desktopSearchForm = document.getElementById('desktopSearchForm'); const homeSearchForm = document.getElementById('homeSearchForm'); if (mobileSearchForm) { mobileSearchForm.addEventListener('submit', function(e) { updateSearchFormsCulture(); }); } if (desktopSearchForm) { desktopSearchForm.addEventListener('submit', function(e) { updateSearchFormsCulture(); }); } if (homeSearchForm) { homeSearchForm.addEventListener('submit', function(e) { updateSearchFormsCulture(); }); } // Set up language switcher functionality function setupLanguageSwitcher() { const buttons = document.querySelectorAll('#language-menu-button'); const menus = document.querySelectorAll('#language-menu'); buttons.forEach((button, index) => { const menu = menus[index]; if (button && menu) { // Toggle menu on button click button.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); const isExpanded = button.getAttribute('aria-expanded') === 'true'; button.setAttribute('aria-expanded', !isExpanded); if (isExpanded) { menu.classList.add('hidden'); } else { menu.classList.remove('hidden'); } }); // Close menu when clicking outside document.addEventListener('click', function(event) { if (!button.contains(event.target) && !menu.contains(event.target)) { button.setAttribute('aria-expanded', 'false'); menu.classList.add('hidden'); } }); // Close menu on escape key document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { button.setAttribute('aria-expanded', 'false'); menu.classList.add('hidden'); } }); // Prevent menu from closing when clicking inside it menu.addEventListener('click', function(event) { event.stopPropagation(); }); } }); } // Initialize language switcher functionality setupLanguageSwitcher(); // Listen for language changes from the language switcher function setupLanguageChangeListener() { // Monitor for URL changes (when language is switched) let currentUrl = window.location.href; // Check for URL changes every 100ms setInterval(function() { if (window.location.href !== currentUrl) { currentUrl = window.location.href; updateSearchFormsCulture(); } }, 100); // Also listen for popstate events (back/forward navigation) window.addEventListener('popstate', function() { updateSearchFormsCulture(); }); // Listen for clicks on language switcher links document.addEventListener('click', function(e) { if (e.target.closest('#language-menu a')) { // Language link was clicked, update forms after a short delay setTimeout(updateSearchFormsCulture, 50); } }); } // Initialize language change listener setupLanguageChangeListener(); // Check if language switcher is visible and show fallback if needed setTimeout(function() { const mainLangSwitcher = document.querySelector('.language-switcher-desktop'); const fallbackLangSwitcher = document.querySelector('.language-switcher-fallback'); const directLangSwitcher = document.querySelector('.direct-language-switcher'); if (mainLangSwitcher && fallbackLangSwitcher) { const mainStyles = window.getComputedStyle(mainLangSwitcher); const isMainVisible = mainStyles.display !== 'none' && mainStyles.visibility !== 'hidden' && mainStyles.opacity !== '0'; if (!isMainVisible) { fallbackLangSwitcher.style.display = 'block'; mainLangSwitcher.style.display = 'none'; // Also check if fallback is visible setTimeout(function() { const fallbackStyles = window.getComputedStyle(fallbackLangSwitcher); const isFallbackVisible = fallbackStyles.display !== 'none' && fallbackStyles.visibility !== 'hidden' && fallbackStyles.opacity !== '0'; if (!isFallbackVisible && directLangSwitcher) { directLangSwitcher.style.display = 'block'; fallbackLangSwitcher.style.display = 'none'; mainLangSwitcher.style.display = 'none'; } }, 500); } } // Final check - ensure at least one language switcher is visible on desktop if (window.innerWidth >= 768) { setTimeout(function() { const anyVisible = document.querySelector('.language-switcher-desktop:not([style*="display: none"]), .language-switcher-fallback:not([style*="display: none"]), .direct-language-switcher:not([style*="display: none"])'); if (!anyVisible) { if (directLangSwitcher) { directLangSwitcher.style.display = 'block'; } } }, 2000); } }, 1000); // Add loading indicator when form is submitted const searchForm = document.querySelector('form[action*="/Search"]'); if (searchForm) { searchForm.addEventListener('submit', function() { const searchInput = this.querySelector('input[name="query"]'); if (searchInput.value.trim()) { const loadingOverlay = document.createElement('div'); loadingOverlay.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'; loadingOverlay.innerHTML = ` <div class="bg-white p-6 rounded-lg shadow-lg"> <div class="animate-spin rounded-full h-10 w-10 border-b-2 border-blue-600 mx-auto"></div> <p class="mt-4 text-gray-700 text-lg">Searching courses...</p> <p class="mt-2 text-gray-500 text-sm">Searching through our course database</p> </div> `; document.body.appendChild(loadingOverlay); } }); } }); </script> <!-- Tidio Chat --> <script src="//code.tidio.co/2b9vcx7pcchcf0q0jsnrjyx4vtzka7kw.js" async></script> <!-- Enrollment Notification Popup --> <div b-u4k2yyhrco id="enrollmentNotification" class="fixed bottom-4 left-4 bg-gradient-to-r from-white to-blue-50 rounded-lg shadow-lg p-4 max-w-md transform transition-all duration-500 translate-y-full opacity-0 flex items-start space-x-4 z-50 border border-blue-100 hover:shadow-xl cursor-pointer group hover:bg-blue-50/50 notification-container"> <!-- Full notification content --> <div b-u4k2yyhrco id="fullNotification" class="flex items-start space-x-4 w-full"> <div b-u4k2yyhrco class="flex-shrink-0 relative"> <img b-u4k2yyhrco src="/uploads/logos/9a66b2b4-4adb-40a7-a902-76765205caf8.png" alt="SSB Logo" class="h-12 w-12 object-contain transition-all duration-300 group-hover:scale-105"> <div b-u4k2yyhrco class="absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full border-2 border-white"></div> </div> <div b-u4k2yyhrco class="flex-1 min-w-0"> <div b-u4k2yyhrco class="flex items-center space-x-2"> <div b-u4k2yyhrco class="flex-1"> <p b-u4k2yyhrco class="text-sm font-semibold text-gray-900 line-clamp-2 group-hover:text-blue-700 transition-colors" id="notificationText"></p> <div b-u4k2yyhrco class="mt-0.5 flex items-center space-x-2"> <span b-u4k2yyhrco class="inline-flex items-center text-xs"> <svg b-u4k2yyhrco class="w-3 h-3 text-yellow-400 mr-1" fill="currentColor" viewBox="0 0 20 20"> <path b-u4k2yyhrco d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/> </svg> <span b-u4k2yyhrco id="courseRating" class="text-yellow-600 font-medium">4.8</span> </span> <span b-u4k2yyhrco class="inline-flex items-center text-xs text-gray-500"> <svg b-u4k2yyhrco class="w-3 h-3 text-gray-400 mr-1" fill="currentColor" viewBox="0 0 20 20"> <path b-u4k2yyhrco fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path> </svg> <span b-u4k2yyhrco id="notificationTime" class="group-hover:text-blue-600 transition-colors"></span> </span> </div> </div> </div> <div b-u4k2yyhrco class="mt-2 flex items-center justify-between"> <div b-u4k2yyhrco class="flex items-center space-x-2"> <span b-u4k2yyhrco class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 group-hover:bg-blue-200 transition-colors"> Neue Anmeldung </span> <span b-u4k2yyhrco id="courseLevelBadge" class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800 group-hover:bg-purple-200 transition-colors"></span> </div> <div b-u4k2yyhrco class="flex items-center space-x-2"> <a b-u4k2yyhrco id="courseLink" href="#" class="inline-flex items-center text-xs text-blue-600 hover:text-blue-800 font-medium"> <span b-u4k2yyhrco class="group-hover:inline mr-1">โ†’</span> Kurs Anzeigen </a> <button b-u4k2yyhrco id="muteNotification" class="inline-flex items-center text-xs text-gray-500 hover:text-gray-700 font-medium"> <svg b-u4k2yyhrco class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20"> <path b-u4k2yyhrco fill-rule="evenodd" d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg> Stummschalten </button> </div> </div> <div b-u4k2yyhrco class="mt-2 w-full bg-gray-200 rounded-full h-1.5 overflow-hidden"> <div b-u4k2yyhrco id="courseProgress" class="bg-blue-600 h-1.5 rounded-full w-0 transition-all duration-1000 ease-out transform scale-x-0 origin-left"></div> </div> </div> </div> <!-- Muted notification content (compact) --> <div b-u4k2yyhrco id="mutedNotification" class="flex items-center justify-between w-full hidden py-0"> <div b-u4k2yyhrco class="flex items-center space-x-1"> <span b-u4k2yyhrco id="mutedCountryFlag" class="text-xs"></span> <span b-u4k2yyhrco class="inline-flex items-center px-1 py-0 rounded text-xs font-medium bg-blue-100 text-blue-800"> Neue Anmeldung </span> <span b-u4k2yyhrco class="text-xs font-medium text-gray-900 truncate max-w-32" id="mutedCourseTitle"></span> </div> <button b-u4k2yyhrco id="unmuteNotification" class="inline-flex items-center text-xs text-blue-600 hover:text-blue-800 font-medium ml-1"> <svg b-u4k2yyhrco class="w-2.5 h-2.5 mr-0" fill="currentColor" viewBox="0 0 20 20"> <path b-u4k2yyhrco fill-rule="evenodd" d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg> Stummschaltung Aufheben </button> </div> </div> <style> #courseProgress { transform-origin: left; transition: all 7s linear; } .notification-container.muted { padding: 0.5rem !important; } </style> <!-- Add notification script --> <script> // Localized strings for notifications const localizedStrings = { enrolledIn: 'angemeldet fรผr', ago: 'vor' }; let availableCourses = []; let currentNotificationUrl = null; let nameQueue = []; let countryQueue = []; let isNotificationMuted = false; let currentCourseTitle = ''; let currentCountryFlag = ''; // Shuffle array function using Fisher-Yates algorithm function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } // Generate random rating between 4.5 and 5.0 function generateRating() { return (4.5 + Math.random() * 0.5).toFixed(1); } // Initialize name queues by region const namesByRegion = { westernNames: [ { name: 'Sarah Williams', gender: 'f' }, { name: 'John Anderson', gender: 'm' }, { name: 'Emma Thompson', gender: 'f' }, { name: 'James Wilson', gender: 'm' }, { name: 'Olivia Brown', gender: 'f' }, { name: 'William Parker', gender: 'm' }, { name: 'Charlotte Davis', gender: 'f' }, { name: 'Benjamin Foster', gender: 'm' } ], hispanicNames: [ { name: 'Maria Rodriguez', gender: 'f' }, { name: 'Alex Martinez', gender: 'm' }, { name: 'Isabella Garcia', gender: 'f' }, { name: 'Carlos Hernandez', gender: 'm' }, { name: 'Sofia Morales', gender: 'f' }, { name: 'Miguel Torres', gender: 'm' } ], eastAsianNames: [ { name: 'David Chen', gender: 'm' }, { name: 'Lisa Zhang', gender: 'f' }, { name: 'Thomas Lee', gender: 'm' }, { name: 'Isabella Kim', gender: 'f' }, { name: 'Andrew Wong', gender: 'm' }, { name: 'Michelle Liu', gender: 'f' }, { name: 'Kevin Tan', gender: 'm' }, { name: 'Grace Park', gender: 'f' } ], southAsianNames: [ { name: 'Arjun Patel', gender: 'm' }, { name: 'Priya Singh', gender: 'f' }, { name: 'Arun Kumar', gender: 'm' }, { name: 'Neha Sharma', gender: 'f' }, { name: 'Raj Malhotra', gender: 'm' }, { name: 'Anjali Mehta', gender: 'f' }, { name: 'Vikram Shah', gender: 'm' }, { name: 'Zara Khan', gender: 'f' } ], middleEasternNames: [ { name: 'Ahmed Hassan', gender: 'm' }, { name: 'Leila Rahman', gender: 'f' }, { name: 'Omar Malik', gender: 'm' }, { name: 'Yasmin Ahmed', gender: 'f' }, { name: 'Ali Syed', gender: 'm' } ], africanNames: [ { name: 'Samuel Okafor', gender: 'm' }, { name: 'Amara Okonkwo', gender: 'f' }, { name: 'Daniel Mensah', gender: 'm' }, { name: 'Zainab Diallo', gender: 'f' }, { name: 'Emmanuel Adebayo', gender: 'm' } ] }; // Country to region mapping const countryRegionMap = { // Western Countries 'UK': 'westernNames', 'Ireland': 'westernNames', 'Germany': 'westernNames', 'France': 'westernNames', 'Spain': 'hispanicNames', 'Italy': 'westernNames', 'USA': 'westernNames', 'Canada': 'westernNames', 'Australia': 'westernNames', 'New Zealand': 'westernNames', // East Asian Countries 'Singapore': 'eastAsianNames', 'Japan': 'eastAsianNames', 'South Korea': 'eastAsianNames', 'Malaysia': 'eastAsianNames', // South Asian Countries 'India': 'southAsianNames', 'Nepal': 'southAsianNames', 'Sri Lanka': 'southAsianNames', // Middle Eastern Countries 'UAE': 'middleEasternNames', 'Saudi Arabia': 'middleEasternNames', 'Qatar': 'middleEasternNames', 'Kuwait': 'middleEasternNames', // African Countries 'Nigeria': 'africanNames', 'South Africa': 'africanNames', 'Kenya': 'africanNames', 'Ghana': 'africanNames' }; // Initialize country queue function resetCountryQueue() { countryQueue = shuffleArray([ // Europe { name: 'UK', flag: '๐Ÿ‡ฌ๐Ÿ‡ง' }, { name: 'Ireland', flag: '๐Ÿ‡ฎ๐Ÿ‡ช' }, { name: 'Germany', flag: '๐Ÿ‡ฉ๐Ÿ‡ช' }, { name: 'France', flag: '๐Ÿ‡ซ๐Ÿ‡ท' }, { name: 'Spain', flag: '๐Ÿ‡ช๐Ÿ‡ธ' }, { name: 'Italy', flag: '๐Ÿ‡ฎ๐Ÿ‡น' }, // North America { name: 'USA', flag: '๐Ÿ‡บ๐Ÿ‡ธ' }, { name: 'Canada', flag: '๐Ÿ‡จ๐Ÿ‡ฆ' }, // Asia Pacific { name: 'Australia', flag: '๐Ÿ‡ฆ๐Ÿ‡บ' }, { name: 'New Zealand', flag: '๐Ÿ‡ณ๐Ÿ‡ฟ' }, { name: 'Singapore', flag: '๐Ÿ‡ธ๐Ÿ‡ฌ' }, { name: 'Japan', flag: '๐Ÿ‡ฏ๐Ÿ‡ต' }, { name: 'South Korea', flag: '๐Ÿ‡ฐ๐Ÿ‡ท' }, { name: 'Malaysia', flag: '๐Ÿ‡ฒ๐Ÿ‡พ' }, // South Asia { name: 'India', flag: '๐Ÿ‡ฎ๐Ÿ‡ณ' }, { name: 'Nepal', flag: '๐Ÿ‡ณ๐Ÿ‡ต' }, { name: 'Sri Lanka', flag: '๐Ÿ‡ฑ๐Ÿ‡ฐ' }, // Middle East { name: 'UAE', flag: '๐Ÿ‡ฆ๐Ÿ‡ช' }, { name: 'Saudi Arabia', flag: '๐Ÿ‡ธ๐Ÿ‡ฆ' }, { name: 'Qatar', flag: '๐Ÿ‡ถ๐Ÿ‡ฆ' }, { name: 'Kuwait', flag: '๐Ÿ‡ฐ๐Ÿ‡ผ' }, // Africa { name: 'Nigeria', flag: '๐Ÿ‡ณ๐Ÿ‡ฌ' }, { name: 'South Africa', flag: '๐Ÿ‡ฟ๐Ÿ‡ฆ' }, { name: 'Kenya', flag: '๐Ÿ‡ฐ๐Ÿ‡ช' }, { name: 'Ghana', flag: '๐Ÿ‡ฌ๐Ÿ‡ญ' } ]); } // Get a random name based on country function getRandomNameForCountry(countryName) { const regionType = countryRegionMap[countryName] || 'westernNames'; const names = namesByRegion[regionType]; return names[Math.floor(Math.random() * names.length)]; } // Function to show random enrollment function showRandomEnrollment() { if (availableCourses.length === 0 || countryQueue.length === 0) { resetCountryQueue(); return; } const courseIndex = Math.floor(Math.random() * availableCourses.length); const course = availableCourses[courseIndex]; const countryIndex = Math.floor(Math.random() * countryQueue.length); const country = countryQueue[countryIndex]; // Get a name appropriate for the country const learner = getRandomNameForCountry(country.name); const timeAgo = Math.floor(Math.random() * 5) + 1; const message = `${learner.name} from ${country.flag} ${country.name} ${localizedStrings.enrolledIn} ${course.title}`; // Store country flag for muted notifications currentCountryFlag = country.flag; showEnrollmentNotification(message, `${timeAgo}m ${localizedStrings.ago}`, course.url, course.level); // Remove used country from queue countryQueue.splice(countryIndex, 1); if (countryQueue.length === 0) { resetCountryQueue(); } } // Fetch courses asynchronously after page load async function fetchCourses() { try { const response = await fetch('/Course/GetRandomCourseTitles'); if (response.ok) { availableCourses = await response.json(); console.log('Courses loaded successfully'); } } catch (error) { console.error('Error loading courses:', error); // Fallback to demo courses if fetch fails availableCourses = [ { id: 1, title: 'Advanced Diploma in Business Management', level: 'Advanced Level', url: '/Course/Details/1' }, { id: 2, title: 'Professional Certificate in Digital Marketing', level: 'Professional Level', url: '/Course/Details/2' }, { id: 3, title: 'Diploma in Project Management', level: 'Professional Level', url: '/Course/Details/3' }, { id: 4, title: 'Advanced Diploma in Disaster Health Management', level: 'Advanced Level', url: '/Course/Details/4' }, { id: 5, title: 'Certificate in Human Resource Management', level: 'Professional Level', url: '/Course/Details/5' }, { id: 6, title: 'Diploma in Supply Chain Management', level: 'Professional Level', url: '/Course/Details/6' } ]; } } // Load courses after page load window.addEventListener('load', fetchCourses); function showEnrollmentNotification(message, timeAgo, courseUrl, courseLevel) { const notification = document.getElementById('enrollmentNotification'); const notificationText = document.getElementById('notificationText'); const notificationTime = document.getElementById('notificationTime'); const courseLink = document.getElementById('courseLink'); const courseRating = document.getElementById('courseRating'); const courseLevelBadge = document.getElementById('courseLevelBadge'); const courseProgress = document.getElementById('courseProgress'); // Extract course title from the message const courseTitleMatch = message.match(new RegExp(`${localizedStrings.enrolledIn} (.+)$`)); currentCourseTitle = courseTitleMatch ? courseTitleMatch[1] : 'Course'; notificationText.textContent = message; notificationTime.textContent = timeAgo; courseLink.href = courseUrl; currentNotificationUrl = courseUrl; courseRating.textContent = generateRating(); courseLevelBadge.textContent = courseLevel; // Reset progress bar courseProgress.style.transition = 'none'; courseProgress.style.transform = 'scaleX(0)'; courseProgress.style.width = '0%'; // Show notification with enhanced animation notification.classList.remove('translate-y-full', 'opacity-0'); // Show appropriate notification content based on mute state if (isNotificationMuted) { document.getElementById('fullNotification').classList.add('hidden'); document.getElementById('mutedNotification').classList.remove('hidden'); document.getElementById('mutedCourseTitle').textContent = currentCourseTitle; document.getElementById('mutedCountryFlag').textContent = currentCountryFlag; document.getElementById('enrollmentNotification').classList.add('muted'); } else { document.getElementById('fullNotification').classList.remove('hidden'); document.getElementById('mutedNotification').classList.add('hidden'); document.getElementById('enrollmentNotification').classList.remove('muted'); } // Add bounce animation notification.animate([ { transform: 'translateY(0)' }, { transform: 'translateY(-10px)', offset: 0.1 }, { transform: 'translateY(5px)', offset: 0.3 }, { transform: 'translateY(-3px)', offset: 0.5 }, { transform: 'translateY(2px)', offset: 0.7 }, { transform: 'translateY(-1px)', offset: 0.9 }, { transform: 'translateY(0)' } ], { duration: 1000, easing: 'ease-out' }); // Start progress animation after a short delay setTimeout(() => { // Re-enable transition and start progress animation courseProgress.style.transition = 'all 7s linear'; courseProgress.style.width = '100%'; courseProgress.style.transform = 'scaleX(1)'; }, 100); // Hide after 7 seconds with fade out setTimeout(() => { notification.classList.add('translate-y-full', 'opacity-0'); // Reset progress bar when notification hides setTimeout(() => { courseProgress.style.transition = 'none'; courseProgress.style.width = '0%'; courseProgress.style.transform = 'scaleX(0)'; }, 500); }, 7000); } // Add click handler for the entire notification document.getElementById('enrollmentNotification').addEventListener('click', function(e) { if (currentNotificationUrl) { window.location.href = currentNotificationUrl; } }); // Prevent the click on the course link from triggering the notification click document.getElementById('courseLink').addEventListener('click', function(e) { e.stopPropagation(); }); // Show a notification every 25 seconds setInterval(() => { showRandomEnrollment(); }, 25000); // Show first notification after 3 seconds setTimeout(showRandomEnrollment, 3000); // Add mute/unmute functionality document.getElementById('muteNotification').addEventListener('click', function(e) { e.stopPropagation(); muteNotification(); }); document.getElementById('unmuteNotification').addEventListener('click', function(e) { e.stopPropagation(); unmuteNotification(); }); function muteNotification() { isNotificationMuted = true; document.getElementById('fullNotification').classList.add('hidden'); document.getElementById('mutedNotification').classList.remove('hidden'); document.getElementById('mutedCourseTitle').textContent = currentCourseTitle; document.getElementById('mutedCountryFlag').textContent = currentCountryFlag; document.getElementById('enrollmentNotification').classList.add('muted'); } function unmuteNotification() { isNotificationMuted = false; document.getElementById('fullNotification').classList.remove('hidden'); document.getElementById('mutedNotification').classList.add('hidden'); document.getElementById('enrollmentNotification').classList.remove('muted'); } </script> </body> </html>