Enhance navigation and page layouts for improved user experience
- Added a new navigation link for "Journii" in the navigation component. - Updated the layout of multiple pages including antifp, development, eap, privacy, terms, and uptime to enhance visual appeal and organization. - Introduced hero sections with engaging visuals and improved typography for better readability. - Enhanced table of contents and key highlights sections for clearer navigation and information presentation. - Improved styling consistency across pages with backdrop blur effects and responsive design adjustments.
This commit is contained in:
403
src/i18n/translations.journii.ts
Normal file
403
src/i18n/translations.journii.ts
Normal file
@@ -0,0 +1,403 @@
|
||||
export const supportedLanguages = ['en', 'nl', 'de', 'fr'] as const;
|
||||
export type SupportedLanguage = typeof supportedLanguages[number];
|
||||
|
||||
interface JourniiTranslation {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
description: string;
|
||||
status: string;
|
||||
features: {
|
||||
title: string;
|
||||
fuel: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
maintenance: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
analytics: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
multi: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
customization: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
design: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
};
|
||||
progress: {
|
||||
completed: string;
|
||||
inProgress: string;
|
||||
planned: string;
|
||||
};
|
||||
roadmap: {
|
||||
title: string;
|
||||
phase1: {
|
||||
title: string;
|
||||
items: string[];
|
||||
};
|
||||
phase2: {
|
||||
title: string;
|
||||
items: string[];
|
||||
};
|
||||
phase3: {
|
||||
title: string;
|
||||
items: string[];
|
||||
};
|
||||
};
|
||||
tech: {
|
||||
title: string;
|
||||
desc: string;
|
||||
};
|
||||
cta: {
|
||||
title: string;
|
||||
desc: string;
|
||||
github: string;
|
||||
updates: string;
|
||||
};
|
||||
}
|
||||
|
||||
const translations: Record<SupportedLanguage, JourniiTranslation> = {
|
||||
en: {
|
||||
title: "Journii - Smart Vehicle Tracking",
|
||||
subtitle: "Your Complete Vehicle Management Companion",
|
||||
description: "Journii is a comprehensive mobile app designed to help you track, manage, and optimize your vehicle's performance. From fuel efficiency monitoring to maintenance scheduling, we're building the ultimate tool for modern vehicle owners.",
|
||||
status: "Currently in Development",
|
||||
features: {
|
||||
title: "What We're Building",
|
||||
fuel: {
|
||||
title: "Smart Fuel Tracking",
|
||||
desc: "Log fuel purchases, track efficiency trends, and get insights into your vehicle's consumption patterns with beautiful charts and analytics."
|
||||
},
|
||||
maintenance: {
|
||||
title: "Maintenance Management",
|
||||
desc: "Schedule services, track repairs, store receipts, and never miss important maintenance milestones for your vehicles."
|
||||
},
|
||||
analytics: {
|
||||
title: "Advanced Analytics",
|
||||
desc: "Visualize your vehicle data with interactive charts, efficiency trends, and cost breakdowns to make informed decisions."
|
||||
},
|
||||
multi: {
|
||||
title: "Multi-Vehicle Support",
|
||||
desc: "Manage multiple vehicles from a single app - cars, motorcycles, trucks, or electric vehicles, each with tailored tracking."
|
||||
},
|
||||
customization: {
|
||||
title: "Flexible Settings",
|
||||
desc: "Choose your preferred units (metric/imperial), currency, fuel efficiency formats, and themes to match your needs."
|
||||
},
|
||||
design: {
|
||||
title: "Modern Design",
|
||||
desc: "Beautiful, intuitive interface with smooth animations, gradient designs, and a responsive layout that works on any device."
|
||||
}
|
||||
},
|
||||
progress: {
|
||||
completed: "✅ Completed",
|
||||
inProgress: "🚧 In Progress",
|
||||
planned: "📋 Planned"
|
||||
},
|
||||
roadmap: {
|
||||
title: "Development Roadmap",
|
||||
phase1: {
|
||||
title: "Phase 1: Core Features",
|
||||
items: [
|
||||
"Vehicle management and profiles",
|
||||
"Fuel log tracking with efficiency calculations",
|
||||
"Basic maintenance scheduling",
|
||||
"Data export functionality",
|
||||
"Multi-language support (EN, NL, DE, FR)"
|
||||
]
|
||||
},
|
||||
phase2: {
|
||||
title: "Phase 2: Enhanced Experience",
|
||||
items: [
|
||||
"Advanced analytics and reporting",
|
||||
"Photo attachments for logs",
|
||||
"Trip tracking with GPS",
|
||||
"Reminder notifications",
|
||||
"Dark/light theme support"
|
||||
]
|
||||
},
|
||||
phase3: {
|
||||
title: "Phase 3: Smart Features",
|
||||
items: [
|
||||
"Predictive maintenance suggestions",
|
||||
"Fuel price tracking and alerts",
|
||||
"Social features and sharing",
|
||||
"Integration with vehicle APIs",
|
||||
"Cloud backup and sync"
|
||||
]
|
||||
}
|
||||
},
|
||||
tech: {
|
||||
title: "Built With Modern Technology",
|
||||
desc: "Journii is being developed using React Native for cross-platform compatibility, ensuring a native experience on both iOS and Android devices."
|
||||
},
|
||||
cta: {
|
||||
title: "Stay Updated",
|
||||
desc: "Journii is currently in active development. Follow our progress and be among the first to know when it launches.",
|
||||
github: "View on GitHub",
|
||||
updates: "Get Updates"
|
||||
}
|
||||
},
|
||||
|
||||
nl: {
|
||||
title: "Journii - Slimme Voertuig Tracking",
|
||||
subtitle: "Jouw Complete Voertuigbeheer Companion",
|
||||
description: "Journii is een uitgebreide mobiele app ontworpen om je te helpen bij het bijhouden, beheren en optimaliseren van de prestaties van je voertuig. Van brandstofefficiëntie monitoring tot onderhoudsplanning, we bouwen het ultieme hulpmiddel voor moderne voertuigeigenaren.",
|
||||
status: "Momenteel in Ontwikkeling",
|
||||
features: {
|
||||
title: "Wat We Bouwen",
|
||||
fuel: {
|
||||
title: "Slimme Brandstof Tracking",
|
||||
desc: "Log brandstofaankopen, volg efficiëntietrends en krijg inzicht in de verbruikspatronen van je voertuig met mooie grafieken en analyses."
|
||||
},
|
||||
maintenance: {
|
||||
title: "Onderhoudsbeheer",
|
||||
desc: "Plan services, houd reparaties bij, bewaar bonnetjes en mis nooit belangrijke onderhoudsmoment voor je voertuigen."
|
||||
},
|
||||
analytics: {
|
||||
title: "Geavanceerde Analytics",
|
||||
desc: "Visualiseer je voertuigdata met interactieve grafieken, efficiëntietrends en kostenopstellingen om weloverwogen beslissingen te nemen."
|
||||
},
|
||||
multi: {
|
||||
title: "Multi-Voertuig Ondersteuning",
|
||||
desc: "Beheer meerdere voertuigen vanuit één app - auto's, motorfietsen, vrachtwagens of elektrische voertuigen, elk met aangepaste tracking."
|
||||
},
|
||||
customization: {
|
||||
title: "Flexibele Instellingen",
|
||||
desc: "Kies je voorkeursunits (metrisch/imperiaal), valuta, brandstofefficiëntieformaten en thema's die bij je behoeften passen."
|
||||
},
|
||||
design: {
|
||||
title: "Modern Design",
|
||||
desc: "Mooie, intuïtieve interface met vloeiende animaties, gradiëntontwerpen en een responsieve lay-out die op elk apparaat werkt."
|
||||
}
|
||||
},
|
||||
progress: {
|
||||
completed: "✅ Voltooid",
|
||||
inProgress: "🚧 In Uitvoering",
|
||||
planned: "📋 Gepland"
|
||||
},
|
||||
roadmap: {
|
||||
title: "Ontwikkelingsroadmap",
|
||||
phase1: {
|
||||
title: "Fase 1: Kernfuncties",
|
||||
items: [
|
||||
"Voertuigbeheer en profielen",
|
||||
"Brandstoflog tracking met efficiëntieberekeningen",
|
||||
"Basis onderhoudsplanning",
|
||||
"Data export functionaliteit",
|
||||
"Meertalige ondersteuning (EN, NL, DE, FR)"
|
||||
]
|
||||
},
|
||||
phase2: {
|
||||
title: "Fase 2: Verbeterde Ervaring",
|
||||
items: [
|
||||
"Geavanceerde analyses en rapportage",
|
||||
"Foto bijlagen voor logs",
|
||||
"Rit tracking met GPS",
|
||||
"Herinneringsmeldingen",
|
||||
"Donker/licht thema ondersteuning"
|
||||
]
|
||||
},
|
||||
phase3: {
|
||||
title: "Fase 3: Slimme Features",
|
||||
items: [
|
||||
"Voorspellende onderhoudssuggesties",
|
||||
"Brandstofprijs tracking en alerts",
|
||||
"Sociale functies en delen",
|
||||
"Integratie met voertuig API's",
|
||||
"Cloud backup en synchronisatie"
|
||||
]
|
||||
}
|
||||
},
|
||||
tech: {
|
||||
title: "Gebouwd Met Moderne Technologie",
|
||||
desc: "Journii wordt ontwikkeld met React Native voor cross-platform compatibiliteit, wat zorgt voor een native ervaring op zowel iOS als Android apparaten."
|
||||
},
|
||||
cta: {
|
||||
title: "Blijf op de Hoogte",
|
||||
desc: "Journii is momenteel in actieve ontwikkeling. Volg onze voortgang en wees een van de eersten die het weet wanneer het wordt gelanceerd.",
|
||||
github: "Bekijk op GitHub",
|
||||
updates: "Ontvang Updates"
|
||||
}
|
||||
},
|
||||
|
||||
de: {
|
||||
title: "Journii - Intelligente Fahrzeugverfolgung",
|
||||
subtitle: "Ihr Kompletter Fahrzeugmanagement-Begleiter",
|
||||
description: "Journii ist eine umfassende mobile App, die entwickelt wurde, um Ihnen beim Verfolgen, Verwalten und Optimieren der Leistung Ihres Fahrzeugs zu helfen. Von der Kraftstoffeffizienz-Überwachung bis zur Wartungsplanung bauen wir das ultimative Tool für moderne Fahrzeugbesitzer.",
|
||||
status: "Derzeit in Entwicklung",
|
||||
features: {
|
||||
title: "Was Wir Bauen",
|
||||
fuel: {
|
||||
title: "Intelligente Kraftstoffverfolgung",
|
||||
desc: "Protokollieren Sie Kraftstoffkäufe, verfolgen Sie Effizienztrends und erhalten Sie Einblicke in die Verbrauchsmuster Ihres Fahrzeugs mit schönen Diagrammen und Analysen."
|
||||
},
|
||||
maintenance: {
|
||||
title: "Wartungsmanagement",
|
||||
desc: "Planen Sie Services, verfolgen Sie Reparaturen, speichern Sie Belege und verpassen Sie nie wichtige Wartungsmeilensteine für Ihre Fahrzeuge."
|
||||
},
|
||||
analytics: {
|
||||
title: "Erweiterte Analytik",
|
||||
desc: "Visualisieren Sie Ihre Fahrzeugdaten mit interaktiven Diagrammen, Effizienztrends und Kostenaufschlüsselungen, um fundierte Entscheidungen zu treffen."
|
||||
},
|
||||
multi: {
|
||||
title: "Multi-Fahrzeug-Unterstützung",
|
||||
desc: "Verwalten Sie mehrere Fahrzeuge aus einer einzigen App - Autos, Motorräder, Lastwagen oder Elektrofahrzeuge, jedes mit maßgeschneiderter Verfolgung."
|
||||
},
|
||||
customization: {
|
||||
title: "Flexible Einstellungen",
|
||||
desc: "Wählen Sie Ihre bevorzugten Einheiten (metrisch/imperial), Währung, Kraftstoffeffizienzformate und Themes, die Ihren Bedürfnissen entsprechen."
|
||||
},
|
||||
design: {
|
||||
title: "Modernes Design",
|
||||
desc: "Schöne, intuitive Benutzeroberfläche mit glatten Animationen, Farbverläufen und einem responsiven Layout, das auf jedem Gerät funktioniert."
|
||||
}
|
||||
},
|
||||
progress: {
|
||||
completed: "✅ Abgeschlossen",
|
||||
inProgress: "🚧 In Bearbeitung",
|
||||
planned: "📋 Geplant"
|
||||
},
|
||||
roadmap: {
|
||||
title: "Entwicklungsroadmap",
|
||||
phase1: {
|
||||
title: "Phase 1: Kernfunktionen",
|
||||
items: [
|
||||
"Fahrzeugverwaltung und Profile",
|
||||
"Kraftstoffprotokoll-Verfolgung mit Effizienzberechnungen",
|
||||
"Grundlegende Wartungsplanung",
|
||||
"Datenexport-Funktionalität",
|
||||
"Mehrsprachige Unterstützung (EN, NL, DE, FR)"
|
||||
]
|
||||
},
|
||||
phase2: {
|
||||
title: "Phase 2: Verbesserte Erfahrung",
|
||||
items: [
|
||||
"Erweiterte Analytik und Berichterstattung",
|
||||
"Foto-Anhänge für Protokolle",
|
||||
"Fahrtverfolgung mit GPS",
|
||||
"Erinnerungsbenachrichtigungen",
|
||||
"Dunkel/Hell Theme-Unterstützung"
|
||||
]
|
||||
},
|
||||
phase3: {
|
||||
title: "Phase 3: Intelligente Funktionen",
|
||||
items: [
|
||||
"Vorausschauende Wartungsvorschläge",
|
||||
"Kraftstoffpreis-Verfolgung und Warnungen",
|
||||
"Soziale Funktionen und Teilen",
|
||||
"Integration mit Fahrzeug-APIs",
|
||||
"Cloud-Backup und Synchronisation"
|
||||
]
|
||||
}
|
||||
},
|
||||
tech: {
|
||||
title: "Mit Moderner Technologie Gebaut",
|
||||
desc: "Journii wird mit React Native für plattformübergreifende Kompatibilität entwickelt und gewährleistet eine native Erfahrung auf iOS- und Android-Geräten."
|
||||
},
|
||||
cta: {
|
||||
title: "Bleiben Sie Auf Dem Laufenden",
|
||||
desc: "Journii befindet sich derzeit in aktiver Entwicklung. Verfolgen Sie unseren Fortschritt und gehören Sie zu den Ersten, die erfahren, wann es startet.",
|
||||
github: "Auf GitHub Ansehen",
|
||||
updates: "Updates Erhalten"
|
||||
}
|
||||
},
|
||||
|
||||
fr: {
|
||||
title: "Journii - Suivi Intelligent de Véhicule",
|
||||
subtitle: "Votre Compagnon Complet de Gestion de Véhicule",
|
||||
description: "Journii est une application mobile complète conçue pour vous aider à suivre, gérer et optimiser les performances de votre véhicule. Du monitoring de l'efficacité carburant à la planification de maintenance, nous construisons l'outil ultime pour les propriétaires de véhicules modernes.",
|
||||
status: "Actuellement en Développement",
|
||||
features: {
|
||||
title: "Ce Que Nous Construisons",
|
||||
fuel: {
|
||||
title: "Suivi Intelligent du Carburant",
|
||||
desc: "Enregistrez les achats de carburant, suivez les tendances d'efficacité et obtenez des insights sur les modèles de consommation de votre véhicule avec de beaux graphiques et analyses."
|
||||
},
|
||||
maintenance: {
|
||||
title: "Gestion de la Maintenance",
|
||||
desc: "Planifiez les services, suivez les réparations, stockez les reçus et ne manquez jamais les jalons de maintenance importants pour vos véhicules."
|
||||
},
|
||||
analytics: {
|
||||
title: "Analyses Avancées",
|
||||
desc: "Visualisez les données de votre véhicule avec des graphiques interactifs, des tendances d'efficacité et des répartitions de coûts pour prendre des décisions éclairées."
|
||||
},
|
||||
multi: {
|
||||
title: "Support Multi-Véhicules",
|
||||
desc: "Gérez plusieurs véhicules depuis une seule app - voitures, motos, camions ou véhicules électriques, chacun avec un suivi adapté."
|
||||
},
|
||||
customization: {
|
||||
title: "Paramètres Flexibles",
|
||||
desc: "Choisissez vos unités préférées (métrique/impérial), devise, formats d'efficacité carburant et thèmes qui correspondent à vos besoins."
|
||||
},
|
||||
design: {
|
||||
title: "Design Moderne",
|
||||
desc: "Belle interface intuitive avec des animations fluides, des designs en dégradé et une mise en page responsive qui fonctionne sur n'importe quel appareil."
|
||||
}
|
||||
},
|
||||
progress: {
|
||||
completed: "✅ Terminé",
|
||||
inProgress: "🚧 En Cours",
|
||||
planned: "📋 Planifié"
|
||||
},
|
||||
roadmap: {
|
||||
title: "Feuille de Route de Développement",
|
||||
phase1: {
|
||||
title: "Phase 1: Fonctionnalités Principales",
|
||||
items: [
|
||||
"Gestion des véhicules et profils",
|
||||
"Suivi des journaux de carburant avec calculs d'efficacité",
|
||||
"Planification de maintenance de base",
|
||||
"Fonctionnalité d'export de données",
|
||||
"Support multilingue (EN, NL, DE, FR)"
|
||||
]
|
||||
},
|
||||
phase2: {
|
||||
title: "Phase 2: Expérience Améliorée",
|
||||
items: [
|
||||
"Analyses avancées et rapports",
|
||||
"Pièces jointes photo pour les journaux",
|
||||
"Suivi de voyage avec GPS",
|
||||
"Notifications de rappel",
|
||||
"Support thème sombre/clair"
|
||||
]
|
||||
},
|
||||
phase3: {
|
||||
title: "Phase 3: Fonctionnalités Intelligentes",
|
||||
items: [
|
||||
"Suggestions de maintenance prédictive",
|
||||
"Suivi des prix du carburant et alertes",
|
||||
"Fonctionnalités sociales et partage",
|
||||
"Intégration avec les APIs de véhicules",
|
||||
"Sauvegarde cloud et synchronisation"
|
||||
]
|
||||
}
|
||||
},
|
||||
tech: {
|
||||
title: "Construit Avec la Technologie Moderne",
|
||||
desc: "Journii est développé en utilisant React Native pour la compatibilité multi-plateforme, garantissant une expérience native sur les appareils iOS et Android."
|
||||
},
|
||||
cta: {
|
||||
title: "Restez Informé",
|
||||
desc: "Journii est actuellement en développement actif. Suivez nos progrès et soyez parmi les premiers à savoir quand il sera lancé.",
|
||||
github: "Voir sur GitHub",
|
||||
updates: "Recevoir les Mises à Jour"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function getJourniiTranslation(lang: string): JourniiTranslation {
|
||||
if (supportedLanguages.includes(lang as SupportedLanguage)) {
|
||||
return translations[lang as SupportedLanguage];
|
||||
}
|
||||
return translations.en;
|
||||
}
|
@@ -58,6 +58,11 @@ export const getHeaderData = (lang = 'en') => {
|
||||
href: getPermalink('/eap', 'page', lang),
|
||||
isHashLink: false,
|
||||
},
|
||||
{
|
||||
text: 'Journii',
|
||||
href: getPermalink('/journii', 'page', lang),
|
||||
isHashLink: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@@ -26,43 +26,146 @@ const metadata = {
|
||||
---
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<div class="max-w-3xl mx-auto px-4 py-8 backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow">
|
||||
<h1 class="text-3xl font-bold mb-4">{t.title}</h1>
|
||||
<p class="mb-4">
|
||||
<a href="https://greasyfork.org/en/scripts/534570-anti-fingerprinting-shield-plus" target="_blank" rel="noopener noreferrer" class="text-blue-600 underline">{t.viewOnGreasyFork}</a>
|
||||
</p>
|
||||
<p class="mb-6 text-lg">
|
||||
{t.summary}
|
||||
</p>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-red-50/80 to-orange-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">🛡️</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-red-600 to-orange-600 bg-clip-text text-transparent">
|
||||
{t.title}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
{t.summary}
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a
|
||||
href="https://greasyfork.org/en/scripts/534570-anti-fingerprinting-shield-plus"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-6 py-3 bg-gradient-to-r from-red-600 to-orange-600 text-white rounded-lg font-semibold hover:from-red-700 hover:to-orange-700 transition-all shadow-lg"
|
||||
>
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
||||
</svg>
|
||||
{t.viewOnGreasyFork}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<figure class="mb-8">
|
||||
<Image src={antifpSettingsImg} alt="Screenshot of Anti-Fingerprinting Shield Plus settings panel with all privacy options enabled" class="rounded shadow-lg border border-gray-200 mx-auto" />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">This screenshot shows the settings panel for Anti-Fingerprinting Shield Plus, where all fingerprinting protection options are enabled.</figcaption>
|
||||
</figure>
|
||||
<!-- Description -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<p class="text-lg text-gray-700 dark:text-slate-200 leading-relaxed text-center">
|
||||
{t.summary}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{t.features.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{t.features.items.map((item) => (
|
||||
<li class="text-gray-700 dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<!-- Screenshot Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<h2 class="text-2xl font-bold text-center mb-6">Settings Panel Overview</h2>
|
||||
<figure class="mb-6">
|
||||
<Image
|
||||
src={antifpSettingsImg}
|
||||
alt="Screenshot of Anti-Fingerprinting Shield Plus settings panel with all privacy options enabled"
|
||||
class="rounded-xl shadow-lg border border-gray-200 mx-auto max-w-full h-auto"
|
||||
/>
|
||||
<figcaption class="text-center text-gray-500 dark:text-slate-400 text-sm mt-4 italic">
|
||||
This screenshot shows the settings panel for Anti-Fingerprinting Shield Plus, where all fingerprinting protection options are enabled.
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{t.howToInstall}</h2>
|
||||
<ol class="list-decimal list-inside mb-8 space-y-2">
|
||||
<li>{t.step1}</li>
|
||||
<li>{t.step2}</li>
|
||||
<li>{t.step3}</li>
|
||||
<li>{t.step4}</li>
|
||||
</ol>
|
||||
<!-- Features Grid -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-3xl font-bold text-center mb-8">{t.features.title}</h2>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
{t.features.items.map((item, index) => (
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="flex items-start">
|
||||
<div class="text-2xl mr-4 mt-1">
|
||||
{index === 0 ? '🔒' :
|
||||
index === 1 ? '📊' :
|
||||
index === 2 ? '🎭' :
|
||||
index === 3 ? '🌐' :
|
||||
index === 4 ? '⚡' :
|
||||
index === 5 ? '🛠️' : '🔧'}
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{t.notes.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{t.notes.items.map((item) => (
|
||||
<li class="text-gray-700 dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<!-- Installation Guide -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-blue-50/80 to-purple-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 mb-12">
|
||||
<div class="text-center mb-6">
|
||||
<div class="text-4xl mb-4">📦</div>
|
||||
<h2 class="text-2xl font-bold mb-4">{t.howToInstall}</h2>
|
||||
</div>
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<ol class="space-y-4">
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">1</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{t.step1}</p>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">2</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{t.step2}</p>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">3</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{t.step3}</p>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">4</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{t.step4}</p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-600 italic">{t.targetAudience}</p>
|
||||
<p class="mt-4 text-gray-600">{t.moreDetails}</p>
|
||||
<!-- Important Notes -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">⚠️</div>
|
||||
<h2 class="text-2xl font-bold">{t.notes.title}</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-1 gap-4">
|
||||
{t.notes.items.map((item, index) => (
|
||||
<div class="flex items-start p-4 bg-yellow-50/50 dark:bg-yellow-900/20 rounded-lg border-l-4 border-yellow-500">
|
||||
<div class="text-yellow-600 dark:text-yellow-400 mr-3 mt-1">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Target Audience & More Info -->
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6">
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-3xl mb-2">👥</div>
|
||||
<h3 class="text-xl font-bold">Who Is This For?</h3>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 italic text-center">
|
||||
{t.targetAudience}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-purple-50/80 to-pink-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6">
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-3xl mb-2">📚</div>
|
||||
<h3 class="text-xl font-bold">Learn More</h3>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-center">
|
||||
{t.moreDetails}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
@@ -108,101 +108,191 @@ const formatDate = (dateString) => {
|
||||
const year = date.getFullYear();
|
||||
return `${day}-${month}-${year}`;
|
||||
};
|
||||
|
||||
// Calculate some stats from contribution data
|
||||
const totalContributions = Object.values(contributionData).reduce((sum, count) => sum + count, 0);
|
||||
const contributionDays = Object.keys(contributionData).length;
|
||||
const averagePerDay = contributionDays > 0 ? (totalContributions / contributionDays).toFixed(1) : 0;
|
||||
---
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<h1 class="text-xl sm:text-2xl md:text-4xl font-bold mb-4">{t.development.pageTitle || 'Development Progress'}</h1>
|
||||
{/* Collapsible Intro */}
|
||||
<CollapsibleIntro text={t.development.intro} client:visible />
|
||||
{/* Contribution Calendar */}
|
||||
<div class="mb-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">👨💻</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-green-600 to-blue-600 bg-clip-text text-transparent">
|
||||
{t.development.pageTitle || 'Development Progress'}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
Live development activity and code contributions from the 365DevNet ecosystem
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Collapsible Intro -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 mb-8">
|
||||
<CollapsibleIntro text={t.development.intro} client:visible />
|
||||
</div>
|
||||
|
||||
<!-- Stats Overview -->
|
||||
<div class="grid md:grid-cols-3 gap-6 mb-8">
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-teal-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">📈</div>
|
||||
<h3 class="font-bold mb-2">Total Contributions</h3>
|
||||
<p class="text-2xl font-bold text-green-600 dark:text-green-400">{totalContributions}</p>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">This year</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-blue-50/80 to-purple-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🗓️</div>
|
||||
<h3 class="font-bold mb-2">Active Days</h3>
|
||||
<p class="text-2xl font-bold text-blue-600 dark:text-blue-400">{contributionDays}</p>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Days with commits</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-purple-50/80 to-pink-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">⚡</div>
|
||||
<h3 class="font-bold mb-2">Daily Average</h3>
|
||||
<p class="text-2xl font-bold text-purple-600 dark:text-purple-400">{averagePerDay}</p>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Commits per active day</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contribution Calendar -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 mb-8">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📊</div>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold">Contribution Activity</h2>
|
||||
<p class="text-gray-600 dark:text-slate-300">Development activity over time</p>
|
||||
</div>
|
||||
</div>
|
||||
<ContributionCalendar data={contributionData} client:visible />
|
||||
</div>
|
||||
<div class="space-y-8">
|
||||
<section>
|
||||
<h2 class="text-2xl font-semibold mb-4">{t.development.latestCommits || 'Latest Commits'}</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">Showing contributions for user <b>Richard</b> (all repositories).</p>
|
||||
{Array.isArray(userCommits) && userCommits.length > 0 ? (
|
||||
<div class="space-y-4">
|
||||
{userCommits.map((commit) => (
|
||||
<div class="bg-white/40 dark:bg-slate-800/40 backdrop-blur-md p-6 rounded-2xl shadow-lg hover:shadow-xl transition-shadow duration-200 border border-gray-200 dark:border-slate-800 flex flex-col gap-4 md:flex-row md:items-stretch md:gap-8 mb-6">
|
||||
<div class="flex-1">
|
||||
<h3 class="font-semibold text-lg md:text-xl text-gray-900 dark:text-white mb-1">{commit.message.split('\n')[0] || 'No message'}</h3>
|
||||
{/* Format commit description with bullet points on new lines */}
|
||||
{commit.message ? (
|
||||
(() => {
|
||||
const lines = commit.message.split('\n');
|
||||
const bullets = lines.filter(line => line.trim().startsWith('- '));
|
||||
if (bullets.length > 0) {
|
||||
// Render as a list if there are bullet points
|
||||
return (
|
||||
<ul class="text-sm text-gray-600 dark:text-gray-300 list-disc ml-5">
|
||||
{lines.map((line, idx) =>
|
||||
line.trim().startsWith('- ')
|
||||
? <li key={idx}>{line.trim().slice(2)}</li>
|
||||
: line.trim() !== '' && <li key={idx} class="list-none pl-0">{line}</li>
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
} else {
|
||||
// Render as a paragraph if no bullet points
|
||||
return <p class="text-sm text-gray-600 dark:text-gray-300">{commit.message}</p>;
|
||||
}
|
||||
})()
|
||||
) : null}
|
||||
</div>
|
||||
{/* Desktop commit info card */}
|
||||
<div class="hidden md:flex flex-col items-end min-w-[180px] bg-gray-50 dark:bg-slate-800 rounded-xl px-5 py-3 mt-4 md:mt-0 md:ml-8 shadow border border-gray-200 dark:border-gray-700">
|
||||
<span class="text-base font-semibold text-gray-800 dark:text-gray-200 mb-1">{commit.date ? formatDate(commit.date) : ''}</span>
|
||||
{commit.author && (
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 mb-2">{commit.author === 'becarta' ? 'Richard Bergsma' : commit.author}</span>
|
||||
)}
|
||||
{commit.repo && (
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 mb-2">
|
||||
<a href={commit.repo_url} target="_blank" rel="noopener">{commit.repo}</a>
|
||||
</span>
|
||||
)}
|
||||
{commit.sha && (
|
||||
<a href={commit.compare_url} target="_blank" rel="noopener" class="block mt-1 text-right">
|
||||
<span class="text-xs text-gray-500 dark:text-gray-300 block">Commit:</span>
|
||||
<code class="px-3 py-1 rounded-full bg-blue-50 dark:bg-blue-900 border border-blue-200 dark:border-blue-700 font-mono text-xs text-blue-700 dark:text-blue-300 hover:bg-blue-100 dark:hover:bg-blue-800 transition-colors cursor-pointer block">
|
||||
{commit.sha.slice(0, 7)}
|
||||
</code>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
{/* Mobile commit info area, visually separated and two rows with left/right alignment */}
|
||||
<div class="md:hidden border-t border-gray-200 dark:border-gray-700 pt-3 px-3 bg-gray-50 dark:bg-slate-800 rounded-b-xl text-xs text-gray-700 dark:text-gray-300">
|
||||
<div class="flex flex-row justify-between items-center mb-1 gap-3">
|
||||
<span class="font-semibold">{commit.date ? formatDate(commit.date) : ''}</span>
|
||||
{commit.author && (
|
||||
<span>{commit.author === 'becarta' ? 'Richard Bergsma' : commit.author}</span>
|
||||
|
||||
<!-- Latest Commits Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">💻</div>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold">{t.development.latestCommits || 'Latest Commits'}</h2>
|
||||
<p class="text-gray-600 dark:text-slate-300">
|
||||
Showing contributions for user <span class="font-semibold text-blue-600 dark:text-blue-400">Richard</span> (all repositories)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{Array.isArray(userCommits) && userCommits.length > 0 ? (
|
||||
<div class="space-y-4">
|
||||
{userCommits.map((commit, index) => (
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-white/50 to-gray-50/50 dark:from-slate-800/50 dark:to-slate-900/50 rounded-xl shadow-sm hover:shadow-md transition-all duration-200 border border-gray-200/50 dark:border-slate-700/50 overflow-hidden">
|
||||
<div class="p-6">
|
||||
<div class="flex flex-col gap-4 md:flex-row md:items-start md:gap-6">
|
||||
<!-- Commit Number Badge -->
|
||||
<div class="flex-shrink-0">
|
||||
<div class="w-8 h-8 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-full flex items-center justify-center text-sm font-bold">
|
||||
{index + 1}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<h3 class="font-semibold text-lg text-gray-900 dark:text-white mb-2 break-words">
|
||||
{commit.message.split('\n')[0] || 'No message'}
|
||||
</h3>
|
||||
|
||||
{/* Format commit description with bullet points on new lines */}
|
||||
{commit.message && commit.message.split('\n').length > 1 && (
|
||||
(() => {
|
||||
const lines = commit.message.split('\n').slice(1);
|
||||
const bullets = lines.filter(line => line.trim().startsWith('- '));
|
||||
if (bullets.length > 0) {
|
||||
return (
|
||||
<ul class="text-sm text-gray-600 dark:text-gray-300 list-disc ml-5 space-y-1">
|
||||
{lines.map((line, idx) =>
|
||||
line.trim().startsWith('- ')
|
||||
? <li key={idx} class="break-words">{line.trim().slice(2)}</li>
|
||||
: line.trim() !== '' && <li key={idx} class="list-none pl-0 break-words">{line}</li>
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
} else {
|
||||
const description = lines.filter(line => line.trim() !== '').join(' ');
|
||||
return description && (
|
||||
<p class="text-sm text-gray-600 dark:text-gray-300 break-words">{description}</p>
|
||||
);
|
||||
}
|
||||
})()
|
||||
)}
|
||||
|
||||
<!-- Repository Info -->
|
||||
{commit.repo && (
|
||||
<div class="flex items-center mt-3 text-sm text-gray-500 dark:text-gray-400">
|
||||
<div class="text-lg mr-2">📂</div>
|
||||
<a
|
||||
href={commit.repo_url}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
|
||||
>
|
||||
{commit.repo}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div class="flex flex-row justify-between items-center gap-3">
|
||||
{commit.repo && (
|
||||
<span>
|
||||
<a href={commit.repo_url} target="_blank" rel="noopener">{commit.repo}</a>
|
||||
</span>
|
||||
)}
|
||||
{commit.sha && (
|
||||
<a href={commit.compare_url} target="_blank" rel="noopener">
|
||||
<span class="sr-only">Commit:</span>
|
||||
<code class="px-3 py-1 rounded-full bg-blue-50 dark:bg-blue-900 border border-blue-200 dark:border-blue-700 font-mono text-xs text-blue-700 dark:text-blue-300 hover:bg-blue-100 dark:hover:bg-blue-800 transition-colors cursor-pointer max-w-[130px] overflow-x-auto whitespace-nowrap block">
|
||||
{commit.sha.slice(0, 7)}
|
||||
</code>
|
||||
</a>
|
||||
)}
|
||||
|
||||
<!-- Commit Info Sidebar -->
|
||||
<div class="flex-shrink-0 md:min-w-[200px]">
|
||||
<div class="bg-gray-50/80 dark:bg-slate-800/80 rounded-lg p-4 space-y-3">
|
||||
{/* Date */}
|
||||
<div class="flex items-center text-sm">
|
||||
<div class="text-gray-500 dark:text-gray-400 mr-2">📅</div>
|
||||
<span class="font-medium text-gray-700 dark:text-gray-200">
|
||||
{commit.date ? formatDate(commit.date) : 'Unknown date'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Author */}
|
||||
{commit.author && (
|
||||
<div class="flex items-center text-sm">
|
||||
<div class="text-gray-500 dark:text-gray-400 mr-2">👤</div>
|
||||
<span class="text-gray-600 dark:text-gray-300">
|
||||
{commit.author === 'becarta' ? 'Richard Bergsma' : commit.author}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Commit Hash */}
|
||||
{commit.sha && (
|
||||
<div class="flex items-center text-sm">
|
||||
<div class="text-gray-500 dark:text-gray-400 mr-2">🔗</div>
|
||||
<a
|
||||
href={commit.compare_url}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="group"
|
||||
>
|
||||
<code class="px-2 py-1 rounded bg-blue-50 dark:bg-blue-900/50 border border-blue-200 dark:border-blue-700 font-mono text-xs text-blue-700 dark:text-blue-300 group-hover:bg-blue-100 dark:group-hover:bg-blue-800/50 transition-colors">
|
||||
{commit.sha.slice(0, 8)}
|
||||
</code>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p class="text-gray-600 dark:text-gray-400">Unable to fetch commit history at this time.</p>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div class="text-center py-12">
|
||||
<div class="text-4xl mb-4">🤷♂️</div>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-lg">
|
||||
Unable to fetch commit history at this time.
|
||||
</p>
|
||||
<p class="text-gray-500 dark:text-gray-500 text-sm mt-2">
|
||||
Please check back later or contact support if the issue persists.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
@@ -25,98 +25,272 @@ const metadata = {
|
||||
---
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<div class="max-w-3xl mx-auto px-4 py-8 backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow">
|
||||
<h1 class="text-3xl font-bold mb-4">{eap.title}</h1>
|
||||
<p class="mb-6 text-lg">{eap.intro}</p>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">🛡️</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-green-600 to-blue-600 bg-clip-text text-transparent">
|
||||
{eap.title}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
{eap.intro}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.whatItDoes.title}</h2>
|
||||
<ul class="list-disc list-inside mb-4 space-y-2">
|
||||
{eap.whatItDoes.items.map((item) => (
|
||||
<li class="text-gray-700 dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<figure class="mb-8">
|
||||
<Image src={eap.screenshots.mainImg} alt={eap.whatItDoes.screenshot} class="rounded shadow-lg border border-gray-200 mx-auto" width={800} height={450} />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">{eap.whatItDoes.screenshot}</figcaption>
|
||||
</figure>
|
||||
<!-- What It Does Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">⚡</div>
|
||||
<h2 class="text-2xl font-bold">{eap.whatItDoes.title}</h2>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-8">
|
||||
{eap.whatItDoes.items.map((item, index) => (
|
||||
<div class="flex items-start p-4 bg-green-50/50 dark:bg-green-900/20 rounded-lg border-l-4 border-green-500">
|
||||
<div class="text-green-600 dark:text-green-400 mr-3 mt-1">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.howItWorks.title}</h2>
|
||||
<ol class="list-decimal list-inside mb-8 space-y-2">
|
||||
{eap.howItWorks.steps.map((step) => (
|
||||
<li>{step}</li>
|
||||
))}
|
||||
</ol>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.privacy.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{eap.privacy.items.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.notDo.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{eap.notDo.items.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.trustedBlocked.title}</h2>
|
||||
<ol class="list-decimal list-inside mb-8 space-y-2">
|
||||
{eap.trustedBlocked.steps.map((step) => (
|
||||
<li>{step}</li>
|
||||
))}
|
||||
</ol>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.safeBrowsing.title}</h2>
|
||||
<p class="mb-2">{eap.safeBrowsing.content}</p>
|
||||
<a href={eap.safeBrowsing.reportLink} target="_blank" rel="noopener noreferrer" class="text-blue-600 underline">{eap.safeBrowsing.report}</a>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.audience.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{eap.audience.items.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.requirements.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{eap.requirements.items.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.troubleshooting.title}</h2>
|
||||
<strong>{eap.troubleshooting.notFlagged}</strong>
|
||||
<ul class="list-disc list-inside mb-4 ml-4">
|
||||
{eap.troubleshooting.notFlaggedReasons.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<strong>{eap.troubleshooting.falsePositive}</strong>
|
||||
<ul class="list-disc list-inside mb-8 ml-4">
|
||||
{eap.troubleshooting.falsePositiveReasons.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">{eap.updates.title}</h2>
|
||||
<ul class="list-disc list-inside mb-8 space-y-2">
|
||||
{eap.updates.features.map((item) => (
|
||||
<li class="dark:text-slate-200">{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h2 class="text-2xl font-semibold mb-4">Screenshots</h2>
|
||||
<div class="mb-8 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<figure>
|
||||
<Image src={eap.screenshots.settingsImg} alt={eap.screenshots.settings} class="rounded shadow-lg border border-gray-200 mx-auto" width={800} height={450} />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">{eap.screenshots.settings}</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<Image src={eap.screenshots.popupImg} alt={eap.screenshots.popup} class="rounded shadow-lg border border-gray-200 mx-auto" width={800} height={450} />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">{eap.screenshots.popup}</figcaption>
|
||||
<figure class="rounded-xl overflow-hidden shadow-lg max-w-2xl mx-auto">
|
||||
<Image
|
||||
src={eap.screenshots.mainImg}
|
||||
alt={eap.whatItDoes.screenshot}
|
||||
class="w-full h-auto object-cover"
|
||||
width={800}
|
||||
height={450}
|
||||
/>
|
||||
<figcaption class="bg-gray-50 dark:bg-slate-800 py-3 text-center text-gray-600 dark:text-slate-300 text-sm">
|
||||
{eap.whatItDoes.screenshot}
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<!-- How It Works Section -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-blue-50/80 to-purple-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 mb-12">
|
||||
<div class="text-center mb-6">
|
||||
<div class="text-4xl mb-4">🔧</div>
|
||||
<h2 class="text-2xl font-bold mb-4">{eap.howItWorks.title}</h2>
|
||||
</div>
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<ol class="space-y-4">
|
||||
{eap.howItWorks.steps.map((step, index) => (
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{step}</p>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Privacy & Security Grid -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-12">
|
||||
<!-- Privacy Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">🔒</div>
|
||||
<h2 class="text-xl font-bold">{eap.privacy.title}</h2>
|
||||
</div>
|
||||
<ul class="space-y-3">
|
||||
{eap.privacy.items.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-green-500 mr-2 mt-1">✓</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- What It Doesn't Do Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">🚫</div>
|
||||
<h2 class="text-xl font-bold">{eap.notDo.title}</h2>
|
||||
</div>
|
||||
<ul class="space-y-3">
|
||||
{eap.notDo.items.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-red-500 mr-2 mt-1">✗</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trusted Sites Section -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-orange-50/80 to-red-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 mb-12">
|
||||
<div class="text-center mb-6">
|
||||
<div class="text-4xl mb-4">⚙️</div>
|
||||
<h2 class="text-2xl font-bold mb-4">{eap.trustedBlocked.title}</h2>
|
||||
</div>
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<ol class="space-y-4">
|
||||
{eap.trustedBlocked.steps.map((step, index) => (
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 w-8 h-8 bg-orange-600 text-white rounded-full flex items-center justify-center font-bold text-sm mr-4 mt-1">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{step}</p>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Safe Browsing Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-3xl mr-4">🌐</div>
|
||||
<h2 class="text-2xl font-bold">{eap.safeBrowsing.title}</h2>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 mb-4">{eap.safeBrowsing.content}</p>
|
||||
<a
|
||||
href={eap.safeBrowsing.reportLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
</svg>
|
||||
{eap.safeBrowsing.report}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Target Audience & Requirements Grid -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-12">
|
||||
<!-- Target Audience -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-purple-50/80 to-pink-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">👥</div>
|
||||
<h2 class="text-xl font-bold">{eap.audience.title}</h2>
|
||||
</div>
|
||||
<ul class="space-y-2">
|
||||
{eap.audience.items.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-purple-500 mr-2 mt-1">•</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Requirements -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-cyan-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">📋</div>
|
||||
<h2 class="text-xl font-bold">{eap.requirements.title}</h2>
|
||||
</div>
|
||||
<ul class="space-y-2">
|
||||
{eap.requirements.items.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-cyan-500 mr-2 mt-1">•</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Troubleshooting Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🔧</div>
|
||||
<h2 class="text-2xl font-bold">{eap.troubleshooting.title}</h2>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<!-- Not Flagged -->
|
||||
<div class="p-4 bg-yellow-50/50 dark:bg-yellow-900/20 rounded-lg border-l-4 border-yellow-500">
|
||||
<h3 class="font-bold text-yellow-800 dark:text-yellow-200 mb-3">
|
||||
{eap.troubleshooting.notFlagged}
|
||||
</h3>
|
||||
<ul class="space-y-2 text-sm">
|
||||
{eap.troubleshooting.notFlaggedReasons.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-yellow-600 dark:text-yellow-400 mr-2 mt-1">•</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- False Positive -->
|
||||
<div class="p-4 bg-red-50/50 dark:bg-red-900/20 rounded-lg border-l-4 border-red-500">
|
||||
<h3 class="font-bold text-red-800 dark:text-red-200 mb-3">
|
||||
{eap.troubleshooting.falsePositive}
|
||||
</h3>
|
||||
<ul class="space-y-2 text-sm">
|
||||
{eap.troubleshooting.falsePositiveReasons.map((item) => (
|
||||
<li class="flex items-start">
|
||||
<div class="text-red-600 dark:text-red-400 mr-2 mt-1">•</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Updates Section -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-green-50/80 to-teal-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🚀</div>
|
||||
<h2 class="text-2xl font-bold">{eap.updates.title}</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
{eap.updates.features.map((item) => (
|
||||
<div class="flex items-start p-3 bg-green-50/50 dark:bg-green-900/20 rounded-lg">
|
||||
<div class="text-green-600 dark:text-green-400 mr-3 mt-1">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Screenshots Section -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8">
|
||||
<h2 class="text-2xl font-bold text-center mb-8">Screenshots</h2>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<figure class="rounded-xl overflow-hidden shadow-lg">
|
||||
<Image
|
||||
src={eap.screenshots.settingsImg}
|
||||
alt={eap.screenshots.settings}
|
||||
class="w-full h-auto"
|
||||
width={800}
|
||||
height={450}
|
||||
/>
|
||||
<figcaption class="bg-gray-50 dark:bg-slate-800 px-4 py-3 text-center text-gray-600 dark:text-slate-300 text-sm">
|
||||
{eap.screenshots.settings}
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
<figure class="rounded-xl overflow-hidden shadow-lg">
|
||||
<Image
|
||||
src={eap.screenshots.popupImg}
|
||||
alt={eap.screenshots.popup}
|
||||
class="w-full h-auto"
|
||||
width={800}
|
||||
height={450}
|
||||
/>
|
||||
<figcaption class="bg-gray-50 dark:bg-slate-800 px-4 py-3 text-center text-gray-600 dark:text-slate-300 text-sm">
|
||||
{eap.screenshots.popup}
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
199
src/pages/[lang]/journii.astro
Normal file
199
src/pages/[lang]/journii.astro
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
export const prerender = true;
|
||||
|
||||
import Layout from '~/layouts/PageLayout.astro';
|
||||
import { getJourniiTranslation, supportedLanguages } from '~/i18n/translations.journii';
|
||||
import Image from '~/components/common/Image.astro';
|
||||
// Import images when available
|
||||
// import journiiHomeImg from '~/assets/images/journii-home.png';
|
||||
// import journiiAnalyticsImg from '~/assets/images/journii-analytics.png';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return supportedLanguages.map((lang) => ({
|
||||
params: { lang },
|
||||
}));
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
if (!supportedLanguages.includes(lang)) {
|
||||
return Astro.redirect('/en/journii');
|
||||
}
|
||||
|
||||
const t = getJourniiTranslation(lang);
|
||||
|
||||
const metadata = {
|
||||
title: t.title,
|
||||
description: t.description,
|
||||
};
|
||||
---
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-blue-50/80 to-purple-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">🚗</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
|
||||
{t.title}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
{t.subtitle}
|
||||
</p>
|
||||
<div class="inline-flex items-center px-4 py-2 bg-orange-100 dark:bg-orange-900/30 text-orange-800 dark:text-orange-200 rounded-full text-sm font-medium">
|
||||
🚧 {t.status}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<p class="text-lg text-gray-700 dark:text-slate-200 leading-relaxed">
|
||||
{t.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Features Grid -->
|
||||
<div class="mb-12">
|
||||
<h2 class="text-3xl font-bold text-center mb-8">{t.features.title}</h2>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">🚗</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.fuel.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.fuel.desc}</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">🔧</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.maintenance.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.maintenance.desc}</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">📊</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.analytics.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.analytics.desc}</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">🚙</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.multi.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.multi.desc}</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">⚙️</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.customization.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.customization.desc}</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 hover:shadow-lg transition-shadow">
|
||||
<div class="text-2xl mb-3">✨</div>
|
||||
<h3 class="text-xl font-semibold mb-3">{t.features.design.title}</h3>
|
||||
<p class="text-gray-600 dark:text-slate-300">{t.features.design.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Development Roadmap -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 mb-12">
|
||||
<h2 class="text-3xl font-bold text-center mb-8">{t.roadmap.title}</h2>
|
||||
<div class="space-y-8">
|
||||
<!-- Phase 1 -->
|
||||
<div class="border-l-4 border-green-500 pl-6">
|
||||
<h3 class="text-xl font-semibold text-green-700 dark:text-green-400 mb-3">
|
||||
{t.progress.completed} {t.roadmap.phase1.title}
|
||||
</h3>
|
||||
<ul class="space-y-2">
|
||||
{t.roadmap.phase1.items.map((item) => (
|
||||
<li class="flex items-center text-gray-700 dark:text-slate-200">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Phase 2 -->
|
||||
<div class="border-l-4 border-orange-500 pl-6">
|
||||
<h3 class="text-xl font-semibold text-orange-700 dark:text-orange-400 mb-3">
|
||||
{t.progress.inProgress} {t.roadmap.phase2.title}
|
||||
</h3>
|
||||
<ul class="space-y-2">
|
||||
{t.roadmap.phase2.items.map((item) => (
|
||||
<li class="flex items-center text-gray-700 dark:text-slate-200">
|
||||
<span class="text-orange-500 mr-2">🔄</span>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Phase 3 -->
|
||||
<div class="border-l-4 border-blue-500 pl-6">
|
||||
<h3 class="text-xl font-semibold text-blue-700 dark:text-blue-400 mb-3">
|
||||
{t.progress.planned} {t.roadmap.phase3.title}
|
||||
</h3>
|
||||
<ul class="space-y-2">
|
||||
{t.roadmap.phase3.items.map((item) => (
|
||||
<li class="flex items-center text-gray-700 dark:text-slate-200">
|
||||
<span class="text-blue-500 mr-2">📋</span>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Technology Section -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-purple-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 mb-12">
|
||||
<div class="text-center">
|
||||
<div class="text-4xl mb-4">⚡</div>
|
||||
<h2 class="text-2xl font-bold mb-4">{t.tech.title}</h2>
|
||||
<p class="text-gray-700 dark:text-slate-200 max-w-2xl mx-auto">
|
||||
{t.tech.desc}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Screenshots Section (when available) -->
|
||||
<!--
|
||||
<div class="mb-12">
|
||||
<h2 class="text-3xl font-bold text-center mb-8">App Preview</h2>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<figure>
|
||||
<Image src={journiiHomeImg} alt="Journii home screen showing vehicle dashboard" class="rounded-xl shadow-lg border border-gray-200" />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">Home dashboard with vehicle overview</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<Image src={journiiAnalyticsImg} alt="Journii analytics screen showing fuel efficiency charts" class="rounded-xl shadow-lg border border-gray-200" />
|
||||
<figcaption class="text-center text-gray-500 text-sm mt-2">Analytics dashboard with fuel efficiency trends</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- Call to Action -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-blue-600/90 to-purple-600/90 rounded-xl shadow-lg p-8 text-center text-white">
|
||||
<h2 class="text-3xl font-bold mb-4">{t.cta.title}</h2>
|
||||
<p class="text-lg mb-6 opacity-90">
|
||||
{t.cta.desc}
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a
|
||||
href="https://github.com/yourusername/journii"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-6 py-3 bg-white/20 hover:bg-white/30 rounded-lg font-semibold transition-colors"
|
||||
>
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
|
||||
</svg>
|
||||
{t.cta.github}
|
||||
</a>
|
||||
<a
|
||||
href="#newsletter"
|
||||
class="inline-flex items-center px-6 py-3 bg-white text-blue-600 hover:bg-gray-100 rounded-lg font-semibold transition-colors"
|
||||
>
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-5 5-5-5h5v-12"></path>
|
||||
</svg>
|
||||
{t.cta.updates}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
@@ -27,17 +27,18 @@ const metadata = {
|
||||
|
||||
// Table of Contents items
|
||||
const tocItems = [
|
||||
{ id: 'introduction', title: 'Introduction' },
|
||||
{ id: 'data-collection', title: 'Data Collection Policy' },
|
||||
{ id: 'cookie-usage', title: 'Cookie & Storage Usage' },
|
||||
{ id: 'sessionstorage', title: 'SessionStorage Usage' },
|
||||
{ id: 'localstorage', title: 'LocalStorage Usage' },
|
||||
{ id: 'clear-preferences', title: 'How to Clear Your Preferences' },
|
||||
{ id: 'user-rights', title: 'Your Rights (GDPR & Dutch Law)' },
|
||||
{ id: 'data-security', title: 'Data Security' },
|
||||
{ id: 'third-party', title: 'Third-Party Websites' },
|
||||
{ id: 'changes', title: 'Changes to Privacy Policy' },
|
||||
{ id: 'contact', title: 'Contact Information' },
|
||||
{ id: 'introduction', title: 'Introduction', icon: '📋' },
|
||||
{ id: 'data-collection', title: 'Data Collection Policy', icon: '🔒' },
|
||||
{ id: 'cookie-usage', title: 'Cookie & Storage Usage', icon: '🍪' },
|
||||
{ id: 'sessionstorage', title: 'SessionStorage Usage', icon: '⏱️' },
|
||||
{ id: 'localstorage', title: 'LocalStorage Usage', icon: '💾' },
|
||||
{ id: 'clear-preferences', title: 'How to Clear Your Preferences', icon: '🧹' },
|
||||
{ id: 'user-rights', title: 'Your Rights (GDPR & Dutch Law)', icon: '⚖️' },
|
||||
{ id: 'data-security', title: 'Data Security', icon: '🛡️' },
|
||||
{ id: 'third-party', title: 'Third-Party Websites', icon: '🔗' },
|
||||
{ id: 'changes', title: 'Changes to Privacy Policy', icon: '📝' },
|
||||
{ id: 'children-privacy', title: 'Children\'s Privacy', icon: '👶' },
|
||||
{ id: 'contact', title: 'Contact Information', icon: '📧' },
|
||||
];
|
||||
|
||||
// Helper function to parse and format heartbeat times in UTC
|
||||
@@ -45,18 +46,6 @@ function parseAndFormatTime(rawTime) {
|
||||
const dt = DateTime.fromFormat(rawTime, 'yyyy-MM-dd HH:mm:ss.SSS', { zone: 'utc' });
|
||||
return dt.isValid ? dt.toFormat('dd-LL-yyyy, HH:mm:ss \"UTC\"') : 'Invalid DateTime UTC';
|
||||
}
|
||||
|
||||
// Example usage: format all heartbeats in all lists
|
||||
// (Assume apiData is your fetched API data)
|
||||
// const apiData = { heartbeatList: { ... } };
|
||||
// const formattedHeartbeatList = Object.fromEntries(
|
||||
// Object.entries(apiData.heartbeatList).map(([key, arr]) => [
|
||||
// key,
|
||||
// arr.map(hb => ({ ...hb, formattedTime: parseAndFormatTime(hb.time) }))
|
||||
// ])
|
||||
// );
|
||||
//
|
||||
// Now, for each heartbeat, use hb.formattedTime for display in UTC.
|
||||
---
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
@@ -80,205 +69,382 @@ function parseAndFormatTime(rawTime) {
|
||||
}}
|
||||
/>
|
||||
|
||||
<!-- Hero Widget -->
|
||||
<Hero id="hero" title={t.footer.privacyPolicy} isDark={false}>
|
||||
<Fragment slot="subtitle"> Last updated: 07 June 2025 </Fragment>
|
||||
</Hero>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-blue-50/80 to-green-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">🔐</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-green-600 bg-clip-text text-transparent">
|
||||
{t.footer.privacyPolicy}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
Transparent data practices and your privacy rights
|
||||
</p>
|
||||
<div class="inline-flex items-center px-4 py-2 bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 rounded-full text-sm font-medium">
|
||||
📅 Last updated: 07 June 2025
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Widget -->
|
||||
<div class="mx-auto px-4 sm:px-6 py-4 max-w-4xl">
|
||||
<!-- Table of Contents -->
|
||||
<div class="bg-gray-50 dark:bg-slate-800 p-5 rounded-lg mb-10">
|
||||
<h2 class="text-xl font-bold mb-3">Table of Contents</h2>
|
||||
<ul class="space-y-2">
|
||||
{
|
||||
tocItems.map((item) => (
|
||||
<li>
|
||||
<a href={`#${item.id}`} class="text-blue-600 dark:text-blue-400 hover:underline">
|
||||
{item.title}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📚</div>
|
||||
<h2 class="text-2xl font-bold">Table of Contents</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
{tocItems.map((item) => (
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
class="flex items-center p-3 rounded-lg hover:bg-blue-50 dark:hover:bg-slate-800 transition-colors"
|
||||
>
|
||||
<span class="text-xl mr-3">{item.icon}</span>
|
||||
<span class="text-blue-600 dark:text-blue-400 hover:underline text-sm">
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Key Highlights -->
|
||||
<div class="grid md:grid-cols-3 gap-6 mb-12">
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🚫</div>
|
||||
<h3 class="font-bold mb-2">No Personal Data</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">We don't collect or store any personal information</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-purple-50/80 to-pink-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🍪</div>
|
||||
<h3 class="font-bold mb-2">Essential Cookies Only</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Only for language preference and consent</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-orange-50/80 to-red-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🛡️</div>
|
||||
<h3 class="font-bold mb-2">GDPR Compliant</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Full compliance with EU privacy laws</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Privacy Policy Content -->
|
||||
<div
|
||||
class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg backdrop-blur-sm bg-white/15 dark:bg-slate-900/30 p-6 rounded-lg border border-gray-200 dark:border-slate-800"
|
||||
>
|
||||
<h2 id="introduction" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">1. Introduction</h2>
|
||||
<p>
|
||||
This Privacy Policy explains how we handle information when you visit our website. We are committed to
|
||||
protecting your privacy and complying with applicable data protection laws, including the General Data
|
||||
Protection Regulation (GDPR).
|
||||
</p>
|
||||
<p>
|
||||
We value transparency and want you to understand what information we collect, why we collect it, and how we use
|
||||
it. This policy applies to all visitors to our website.
|
||||
</p>
|
||||
<h2 id="data-collection" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">2. Data Collection Policy</h2>
|
||||
<p>
|
||||
<strong>We do not collect or store any personal user data.</strong> Our website is designed to provide information
|
||||
without requiring you to submit any personal information.
|
||||
</p>
|
||||
<p>
|
||||
The only data stored is your preferences for language and theme settings, which are stored locally on your
|
||||
device using browser technologies (cookies and LocalStorage) and are never transmitted to our servers. More
|
||||
details about this are provided in the sections below.
|
||||
</p>
|
||||
<p>We do not:</p>
|
||||
<ul>
|
||||
<li>
|
||||
Collect your name, email address, or other contact information unless you voluntarily provide it through our
|
||||
contact form
|
||||
</li>
|
||||
<li>Track your browsing behavior</li>
|
||||
<li>Use analytics services that collect personal data</li>
|
||||
<li>Use advertising or marketing tracking technologies</li>
|
||||
<li>Share any information with third parties</li>
|
||||
<li>Store your preferences on our servers</li>
|
||||
</ul>
|
||||
<p>
|
||||
If you choose to contact us using our contact form, the information you provide (such as your name and email
|
||||
address) will only be used to respond to your inquiry and will not be stored longer than necessary for that
|
||||
purpose. <strong>Contact form submissions are deleted after your inquiry is resolved and are never used for marketing or shared with third parties.</strong>
|
||||
</p>
|
||||
<h2 id="cookie-usage" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">3. Cookie & Storage Usage</h2>
|
||||
<p>
|
||||
<strong>Our website uses cookies strictly for essential functionality.</strong> These cookies are necessary for the
|
||||
proper functioning of our website and do not collect any personal information.
|
||||
</p>
|
||||
<p>Details about the cookies we use:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Name:</strong> preferredLanguage
|
||||
<ul>
|
||||
<li><strong>Purpose:</strong> Remembers your language preference (e.g., English, Dutch, German, French)</li>
|
||||
<li><strong>Data stored:</strong> Only the language code (e.g., "en", "nl", "de", "fr")</li>
|
||||
<li><strong>Duration:</strong> 365 days</li>
|
||||
<li><strong>Type:</strong> First-party cookie (not shared with any third parties)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Name:</strong> cookieConsentAccepted
|
||||
<ul>
|
||||
<li><strong>Purpose:</strong> Remembers that you have acknowledged our cookie notice</li>
|
||||
<li><strong>Data stored:</strong> A simple "true" value</li>
|
||||
<li><strong>Duration:</strong> 365 days</li>
|
||||
<li><strong>Type:</strong> First-party cookie and LocalStorage item (not shared with any third parties)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
In addition to cookies, we also use LocalStorage to store certain preferences. Details about this are provided
|
||||
in the next section.
|
||||
</p>
|
||||
<p>
|
||||
We do not use any tracking, analytics, or third-party cookies. No personal information is collected through our
|
||||
cookies or LocalStorage.
|
||||
</p>
|
||||
<h2 id="sessionstorage" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">4. SessionStorage Usage</h2>
|
||||
<p>
|
||||
We use your browser's sessionStorage to temporarily store certain non-personal data that helps improve performance and user experience. This data is never sent to our servers and is automatically deleted as soon as you close your browser tab or window. No personal or identifying information is ever stored in sessionStorage.
|
||||
</p>
|
||||
<p><strong>The following key may be stored:</strong></p>
|
||||
<ul>
|
||||
<li><strong>uptimeStatusCache</strong>: Temporarily caches the latest system status data for performance. Deleted when you close your browser tab or window.</li>
|
||||
</ul>
|
||||
<h2 id="localstorage" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">5. LocalStorage Usage</h2>
|
||||
<p>
|
||||
<strong>Our website uses your browser's localStorage to remember certain preferences and UI states. The following keys may be stored:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>preferredLanguage</strong>: Remembers your language preference (e.g., "en", "nl").</li>
|
||||
<li><strong>cookieConsentAccepted</strong>: Remembers that you have accepted our cookie notice.</li>
|
||||
<li><strong>devnet-intro-collapsed</strong>: Remembers if you have collapsed the introduction section.</li>
|
||||
</ul>
|
||||
<p>Data stored in localStorage remains on your device indefinitely unless you manually clear it via your browser settings or our website removes it.</p>
|
||||
<h2 id="clear-preferences" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">6. How to Clear Your Preferences</h2>
|
||||
<p>
|
||||
If you wish to reset your language or theme settings, you can clear your browser's cookies and LocalStorage
|
||||
data. Here's how to do it in common browsers:
|
||||
</p>
|
||||
<p>
|
||||
<strong>Chrome:</strong>
|
||||
</p>
|
||||
<ol>
|
||||
<li>Click the three dots in the top-right corner</li>
|
||||
<li>Select "Settings"</li>
|
||||
<li>Go to "Privacy and security"</li>
|
||||
<li>Click "Clear browsing data"</li>
|
||||
<li>Select "Cookies and other site data" and "Cached images and files"</li>
|
||||
<li>Click "Clear data"</li>
|
||||
</ol>
|
||||
<p>
|
||||
<strong>Firefox:</strong>
|
||||
</p>
|
||||
<ol>
|
||||
<li>Click the three lines in the top-right corner</li>
|
||||
<li>Select "Settings"</li>
|
||||
<li>Go to "Privacy & Security"</li>
|
||||
<li>Under "Cookies and Site Data," click "Clear Data"</li>
|
||||
<li>Ensure "Cookies and Site Data" is checked</li>
|
||||
<li>Click "Clear"</li>
|
||||
</ol>
|
||||
<p>
|
||||
<strong>Safari:</strong>
|
||||
</p>
|
||||
<ol>
|
||||
<li>Click "Safari" in the top menu</li>
|
||||
<li>Select "Preferences"</li>
|
||||
<li>Go to the "Privacy" tab</li>
|
||||
<li>Click "Manage Website Data"</li>
|
||||
<li>Find our website and click "Remove" or "Remove All"</li>
|
||||
</ol>
|
||||
<p>
|
||||
After clearing your browser data, your language will reset to the default (English) and your theme will reset to
|
||||
the system default.
|
||||
</p>
|
||||
<h2 id="user-rights" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">7. Your Rights (GDPR & Dutch Law)</h2>
|
||||
<p>Under the GDPR and Dutch law, you have the right to:</p>
|
||||
<ul>
|
||||
<li>Be informed about data collection and storage (this policy).</li>
|
||||
<li>Access, correct, or delete your data (not applicable, as we store no personal data).</li>
|
||||
<li>Lodge a complaint with the Dutch DPA (Autoriteit Persoonsgegevens) if you believe your rights are violated. For more information or to lodge a complaint, visit <a href="https://autoriteitpersoonsgegevens.nl/" target="_blank" rel="noopener">Autoriteit Persoonsgegevens</a>.</li>
|
||||
</ul>
|
||||
<h2 id="data-security" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">8. Data Security</h2>
|
||||
<p>
|
||||
We take appropriate technical and organizational measures to ensure the security of any information transmitted
|
||||
to us. However, please be aware that no method of transmission over the internet or method of electronic storage
|
||||
is 100% secure.
|
||||
</p>
|
||||
<p>
|
||||
Our website uses HTTPS encryption to ensure that any communication between your browser and our website is
|
||||
secure.
|
||||
</p>
|
||||
<h2 id="third-party" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">9. Third-Party Websites</h2>
|
||||
<p>
|
||||
Our website may contain links to other websites that are not operated by us. If you click on a third-party link,
|
||||
you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every
|
||||
site you visit.
|
||||
</p>
|
||||
<p>
|
||||
We have no control over and assume no responsibility for the content, privacy policies, or practices of any
|
||||
third-party sites or services.
|
||||
</p>
|
||||
<h2 id="changes" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">10. Changes to Privacy Policy</h2>
|
||||
<p>
|
||||
We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy
|
||||
Policy on this page and updating the "Last updated" date at the top of this page.
|
||||
</p>
|
||||
<p>
|
||||
You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are
|
||||
effective when they are posted on this page.
|
||||
</p>
|
||||
<h2 id="contact" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">11. Contact Information</h2>
|
||||
<p>For privacy questions, contact <a href="mailto:info@365devnet.eu">info@365devnet.eu</a>.<br />
|
||||
Company name: 365devnet<br />
|
||||
KvK number: 97226270</p>
|
||||
<h2 class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">12. Children's Privacy</h2>
|
||||
<p>Our website and services are not intended for children under 16. We do not knowingly collect personal data from children.</p>
|
||||
<div class="space-y-8">
|
||||
|
||||
<!-- Introduction -->
|
||||
<div id="introduction" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📋</div>
|
||||
<h2 class="text-2xl font-bold">1. Introduction</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
This Privacy Policy explains how we handle information when you visit our website. We are committed to
|
||||
protecting your privacy and complying with applicable data protection laws, including the General Data
|
||||
Protection Regulation (GDPR).
|
||||
</p>
|
||||
<p>
|
||||
We value transparency and want you to understand what information we collect, why we collect it, and how we use
|
||||
it. This policy applies to all visitors to our website.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Collection -->
|
||||
<div id="data-collection" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🔒</div>
|
||||
<h2 class="text-2xl font-bold">2. Data Collection Policy</h2>
|
||||
</div>
|
||||
<div class="bg-green-50/50 dark:bg-green-900/20 rounded-lg p-6 border-l-4 border-green-500 mb-6">
|
||||
<p class="font-bold text-green-800 dark:text-green-200 text-lg mb-2">
|
||||
We do not collect or store any personal user data.
|
||||
</p>
|
||||
<p class="text-green-700 dark:text-green-300">
|
||||
Our website is designed to provide information without requiring you to submit any personal information.
|
||||
</p>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
The only data stored is your preferences for language and theme settings, which are stored locally on your
|
||||
device using browser technologies (cookies and LocalStorage) and are never transmitted to our servers.
|
||||
</p>
|
||||
<div class="bg-yellow-50/50 dark:bg-yellow-900/20 rounded-lg p-6 border-l-4 border-yellow-500 mt-4 mb-6">
|
||||
<h3 class="font-bold text-yellow-800 dark:text-yellow-200 mb-3">Contact Form Submissions</h3>
|
||||
<p class="text-yellow-700 dark:text-yellow-300 mb-0">
|
||||
If you choose to contact us using our contact form, the information you provide (such as your name and email address) will only be used to respond to your inquiry and will not be stored longer than necessary for that purpose. <strong>Contact form submissions are deleted after your inquiry is resolved and are never used for marketing or shared with third parties.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<p><strong>We do not:</strong></p>
|
||||
<div class="grid md:grid-cols-2 gap-4 not-prose">
|
||||
{[
|
||||
"Collect your name, email address, or other contact information",
|
||||
"Track your browsing behavior",
|
||||
"Use analytics services that collect personal data",
|
||||
"Use advertising or marketing tracking technologies",
|
||||
"Share any information with third parties",
|
||||
"Store your preferences on our servers"
|
||||
].map((item) => (
|
||||
<div class="flex items-start p-3 bg-red-50/50 dark:bg-red-900/20 rounded-lg">
|
||||
<div class="text-red-500 mr-3 mt-1">✗</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cookie Usage -->
|
||||
<div id="cookie-usage" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🍪</div>
|
||||
<h2 class="text-2xl font-bold">3. Cookie & Storage Usage</h2>
|
||||
</div>
|
||||
<div class="bg-blue-50/50 dark:bg-blue-900/20 rounded-lg p-6 border-l-4 border-blue-500 mb-6">
|
||||
<p class="font-bold text-blue-800 dark:text-blue-200 mb-2">
|
||||
Our website uses cookies strictly for essential functionality.
|
||||
</p>
|
||||
<p class="text-blue-700 dark:text-blue-300">
|
||||
These cookies are necessary for the proper functioning of our website and do not collect any personal information.
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="p-6 bg-gray-50/50 dark:bg-slate-800/50 rounded-lg">
|
||||
<h3 class="font-bold mb-3 flex items-center">
|
||||
<span class="text-xl mr-2">🌐</span>
|
||||
preferredLanguage
|
||||
</h3>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li><strong>Purpose:</strong> Remembers your language preference</li>
|
||||
<li><strong>Data:</strong> Language code (e.g., "en", "nl")</li>
|
||||
<li><strong>Duration:</strong> 365 days</li>
|
||||
<li><strong>Type:</strong> First-party cookie</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="p-6 bg-gray-50/50 dark:bg-slate-800/50 rounded-lg">
|
||||
<h3 class="font-bold mb-3 flex items-center">
|
||||
<span class="text-xl mr-2">✅</span>
|
||||
cookieConsentAccepted
|
||||
</h3>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li><strong>Purpose:</strong> Remembers cookie notice acknowledgment</li>
|
||||
<li><strong>Data:</strong> Simple "true" value</li>
|
||||
<li><strong>Duration:</strong> 365 days</li>
|
||||
<li><strong>Type:</strong> First-party cookie + LocalStorage</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Browser Storage Sections -->
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<!-- SessionStorage -->
|
||||
<div id="sessionstorage" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 scroll-mt-20">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">⏱️</div>
|
||||
<h2 class="text-xl font-bold">4. SessionStorage Usage</h2>
|
||||
</div>
|
||||
<div class="prose prose-sm dark:prose-invert max-w-none">
|
||||
<p>Temporarily stores non-personal data for performance. Automatically deleted when you close your browser tab.</p>
|
||||
<div class="p-3 bg-yellow-50/50 dark:bg-yellow-900/20 rounded-lg mt-4">
|
||||
<p class="font-medium">uptimeStatusCache</p>
|
||||
<p class="text-xs text-gray-600 dark:text-slate-400">System status cache for performance</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LocalStorage -->
|
||||
<div id="localstorage" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 scroll-mt-20">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="text-2xl mr-3">💾</div>
|
||||
<h2 class="text-xl font-bold">5. LocalStorage Usage</h2>
|
||||
</div>
|
||||
<div class="prose prose-sm dark:prose-invert max-w-none">
|
||||
<p>Stores preferences and UI states locally on your device.</p>
|
||||
<div class="space-y-2 mt-4">
|
||||
{['preferredLanguage', 'cookieConsentAccepted', 'devnet-intro-collapsed'].map((key) => (
|
||||
<div class="p-2 bg-blue-50/50 dark:bg-blue-900/20 rounded text-xs">
|
||||
<code class="font-medium">{key}</code>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clear Preferences Guide -->
|
||||
<div id="clear-preferences" class="backdrop-blur-sm bg-gradient-to-r from-orange-50/80 to-red-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🧹</div>
|
||||
<h2 class="text-2xl font-bold">6. How to Clear Your Preferences</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
{[
|
||||
{
|
||||
browser: 'Chrome',
|
||||
icon: '🟡',
|
||||
steps: [
|
||||
'Click three dots (top-right)',
|
||||
'Select "Settings"',
|
||||
'Go to "Privacy and security"',
|
||||
'Click "Clear browsing data"',
|
||||
'Select cookies and cached data',
|
||||
'Click "Clear data"'
|
||||
]
|
||||
},
|
||||
{
|
||||
browser: 'Firefox',
|
||||
icon: '🦊',
|
||||
steps: [
|
||||
'Click three lines (top-right)',
|
||||
'Select "Settings"',
|
||||
'Go to "Privacy & Security"',
|
||||
'Click "Clear Data"',
|
||||
'Check "Cookies and Site Data"',
|
||||
'Click "Clear"'
|
||||
]
|
||||
},
|
||||
{
|
||||
browser: 'Safari',
|
||||
icon: '🧭',
|
||||
steps: [
|
||||
'Click "Safari" in top menu',
|
||||
'Select "Preferences"',
|
||||
'Go to "Privacy" tab',
|
||||
'Click "Manage Website Data"',
|
||||
'Find our site and "Remove"'
|
||||
]
|
||||
}
|
||||
].map((browser) => (
|
||||
<div class="p-4 bg-white/50 dark:bg-slate-800/50 rounded-lg">
|
||||
<h3 class="font-bold mb-3 flex items-center">
|
||||
<span class="text-xl mr-2">{browser.icon}</span>
|
||||
{browser.browser}
|
||||
</h3>
|
||||
<ol class="text-xs space-y-1">
|
||||
{browser.steps.map((step, index) => (
|
||||
<li class="flex items-start">
|
||||
<span class="bg-orange-500 text-white rounded-full w-4 h-4 flex items-center justify-center text-xs mr-2 mt-0.5 flex-shrink-0">
|
||||
{index + 1}
|
||||
</span>
|
||||
<span>{step}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Remaining sections with similar styling... -->
|
||||
<!-- GDPR Rights -->
|
||||
<div id="user-rights" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">⚖️</div>
|
||||
<h2 class="text-2xl font-bold">7. Your Rights (GDPR & Dutch Law)</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>Under the GDPR and Dutch law, you have the right to:</p>
|
||||
<div class="grid md:grid-cols-1 gap-4 not-prose">
|
||||
{[
|
||||
"Be informed about data collection and storage (this policy)",
|
||||
"Access, correct, or delete your data (not applicable, as we store no personal data)",
|
||||
"Lodge a complaint with the Dutch DPA (Autoriteit Persoonsgegevens)"
|
||||
].map((item) => (
|
||||
<div class="flex items-start p-4 bg-blue-50/50 dark:bg-blue-900/20 rounded-lg border-l-4 border-blue-500">
|
||||
<div class="text-blue-600 dark:text-blue-400 mr-3 mt-1">⚖️</div>
|
||||
<p class="text-gray-700 dark:text-slate-200">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p class="mt-4">
|
||||
For more information or to lodge a complaint, visit{' '}
|
||||
<a href="https://autoriteitpersoonsgegevens.nl/" target="_blank" rel="noopener" class="text-blue-600 dark:text-blue-400 underline">
|
||||
Autoriteit Persoonsgegevens
|
||||
</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Security -->
|
||||
<div id="data-security" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🛡️</div>
|
||||
<h2 class="text-2xl font-bold">8. Data Security</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
We take appropriate technical and organizational measures to ensure the security of any information transmitted
|
||||
to us. However, please be aware that no method of transmission over the internet or method of electronic storage
|
||||
is 100% secure.
|
||||
</p>
|
||||
<div class="bg-green-50/50 dark:bg-green-900/20 rounded-lg p-6 border-l-4 border-green-500 mt-4">
|
||||
<p class="text-green-800 dark:text-green-200 mb-0">
|
||||
<strong>HTTPS Encryption:</strong> Our website uses HTTPS encryption to ensure that any communication between your browser and our website is secure.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Third-Party Websites -->
|
||||
<div id="third-party" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🔗</div>
|
||||
<h2 class="text-2xl font-bold">9. Third-Party Websites</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
Our website may contain links to other websites that are not operated by us. If you click on a third-party link,
|
||||
you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every
|
||||
site you visit.
|
||||
</p>
|
||||
<div class="bg-orange-50/50 dark:bg-orange-900/20 rounded-lg p-6 border-l-4 border-orange-500 mt-4">
|
||||
<p class="text-orange-800 dark:text-orange-200 mb-0">
|
||||
<strong>No Responsibility:</strong> We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Changes to Privacy Policy -->
|
||||
<div id="changes" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📝</div>
|
||||
<h2 class="text-2xl font-bold">10. Changes to Privacy Policy</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy
|
||||
Policy on this page and updating the "Last updated" date at the top of this page.
|
||||
</p>
|
||||
<div class="bg-blue-50/50 dark:bg-blue-900/20 rounded-lg p-6 border-l-4 border-blue-500 mt-4">
|
||||
<p class="text-blue-800 dark:text-blue-200 mb-0">
|
||||
<strong>Stay Informed:</strong> You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Children's Privacy -->
|
||||
<div id="children-privacy" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">👶</div>
|
||||
<h2 class="text-2xl font-bold">11. Children's Privacy</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
Our website and services are not intended for children under 16. We do not knowingly collect personal data from children.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact & Company Info -->
|
||||
<div id="contact" class="backdrop-blur-sm bg-gradient-to-r from-blue-600/90 to-purple-600/90 rounded-xl shadow-lg p-8 text-center text-white scroll-mt-20">
|
||||
<div class="text-4xl mb-4">📧</div>
|
||||
<h2 class="text-2xl font-bold mb-4">12. Contact Information</h2>
|
||||
<div class="max-w-md mx-auto space-y-2">
|
||||
<p>For privacy questions, contact <a href="mailto:info@365devnet.eu" class="underline hover:text-blue-200">info@365devnet.eu</a></p>
|
||||
<p><strong>Company:</strong> 365devnet</p>
|
||||
<p><strong>KvK number:</strong> 97226270</p>
|
||||
<p><strong>Location:</strong> Netherlands</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
@@ -24,16 +24,16 @@ const metadata = {
|
||||
description: 'Terms and Conditions for our website, outlining user rights, responsibilities, and legal information.',
|
||||
};
|
||||
|
||||
// Table of Contents items
|
||||
// Table of Contents items with icons
|
||||
const tocItems = [
|
||||
{ id: 'scope', title: 'Scope of Services' },
|
||||
{ id: 'user-rights', title: 'User Rights & Responsibilities' },
|
||||
{ id: 'intellectual-property', title: 'Intellectual Property' },
|
||||
{ id: 'liability', title: 'Limitation of Liability' },
|
||||
{ id: 'governing-law', title: 'Governing Law' },
|
||||
{ id: 'cookies', title: 'Cookie Usage' },
|
||||
{ id: 'changes', title: 'Changes to Terms' },
|
||||
{ id: 'contact', title: 'Contact Information' },
|
||||
{ id: 'scope', title: 'Scope of Services', icon: '🎯' },
|
||||
{ id: 'user-rights', title: 'User Rights & Responsibilities', icon: '👤' },
|
||||
{ id: 'intellectual-property', title: 'Intellectual Property', icon: '©️' },
|
||||
{ id: 'liability', title: 'Limitation of Liability', icon: '⚖️' },
|
||||
{ id: 'governing-law', title: 'Governing Law', icon: '🏛️' },
|
||||
{ id: 'cookies', title: 'Cookie Usage', icon: '🍪' },
|
||||
{ id: 'changes', title: 'Changes to Terms', icon: '📝' },
|
||||
{ id: 'contact', title: 'Contact Information', icon: '📧' },
|
||||
];
|
||||
---
|
||||
|
||||
@@ -59,112 +59,287 @@ const tocItems = [
|
||||
}}
|
||||
/>
|
||||
|
||||
<!-- Hero Widget -->
|
||||
<Hero id="hero" title={t.footer.terms} isDark={false}>
|
||||
<Fragment slot="subtitle"> Last updated: 07 June 2025 </Fragment>
|
||||
</Hero>
|
||||
<div class="max-w-4xl mx-auto px-4 py-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center mb-12 backdrop-blur-sm bg-gradient-to-br from-purple-50/80 to-blue-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-2xl p-8 shadow-lg">
|
||||
<div class="text-6xl mb-4">📋</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-purple-600 to-blue-600 bg-clip-text text-transparent">
|
||||
{t.footer.terms}
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-300 mb-6 max-w-2xl mx-auto">
|
||||
Legal framework and guidelines for using our website
|
||||
</p>
|
||||
<div class="inline-flex items-center px-4 py-2 bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200 rounded-full text-sm font-medium">
|
||||
📅 Last updated: 07 June 2025
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Important Notice -->
|
||||
<div class="backdrop-blur-sm bg-gradient-to-r from-orange-50/80 to-red-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 mb-12">
|
||||
<div class="flex items-center">
|
||||
<div class="text-3xl mr-4">⚠️</div>
|
||||
<div>
|
||||
<h2 class="text-lg font-bold mb-2">Important Notice</h2>
|
||||
<p class="text-gray-700 dark:text-slate-200">
|
||||
Please read these terms and conditions carefully before using our website. By accessing or using our website,
|
||||
you agree to be bound by these terms and conditions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Widget -->
|
||||
<div class="mx-auto px-4 sm:px-6 py-4 max-w-4xl">
|
||||
<!-- Table of Contents -->
|
||||
<div class="bg-gray-50 dark:bg-slate-800 p-5 rounded-lg mb-10">
|
||||
<h2 class="text-xl font-bold mb-3">Table of Contents</h2>
|
||||
<ul class="space-y-2">
|
||||
{
|
||||
tocItems.map((item) => (
|
||||
<li>
|
||||
<a href={`#${item.id}`} class="text-blue-600 dark:text-blue-400 hover:underline">
|
||||
{item.title}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 mb-12">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📚</div>
|
||||
<h2 class="text-2xl font-bold">Table of Contents</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
{tocItems.map((item) => (
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
class="flex items-center p-3 rounded-lg hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors"
|
||||
>
|
||||
<span class="text-xl mr-3">{item.icon}</span>
|
||||
<span class="text-purple-600 dark:text-purple-400 hover:underline text-sm">
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Key Highlights -->
|
||||
<div class="grid md:grid-cols-3 gap-6 mb-12">
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-green-50/80 to-teal-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🌐</div>
|
||||
<h3 class="font-bold mb-2">Informational Use</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Content for general information purposes only</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-blue-50/80 to-purple-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🏛️</div>
|
||||
<h3 class="font-bold mb-2">Dutch Law</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Governed by Dutch law and GDPR compliance</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-gradient-to-br from-orange-50/80 to-red-50/80 dark:from-slate-800/80 dark:to-slate-900/80 rounded-xl shadow p-6 text-center">
|
||||
<div class="text-3xl mb-3">🔒</div>
|
||||
<h3 class="font-bold mb-2">Your Rights</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-300">Clear user rights and responsibilities</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Terms Content -->
|
||||
<div
|
||||
class="prose prose-lg max-w-4xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg backdrop-blur-sm bg-white/15 dark:bg-slate-900/30 p-6 rounded-lg border border-gray-200 dark:border-slate-800"
|
||||
>
|
||||
<p>
|
||||
Please read these terms and conditions carefully before using our website. By accessing or using our website,
|
||||
you agree to be bound by these terms and conditions.
|
||||
</p>
|
||||
<div class="space-y-8">
|
||||
|
||||
<!-- Scope of Services -->
|
||||
<div id="scope" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🎯</div>
|
||||
<h2 class="text-2xl font-bold">1. Scope of Services</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
Our website provides information about our professional services, expertise, and industry insights. The content
|
||||
on this website is for general informational purposes only and does not constitute professional advice.
|
||||
</p>
|
||||
<div class="bg-blue-50/50 dark:bg-blue-900/20 rounded-lg p-4 border-l-4 border-blue-500 mt-4">
|
||||
<p class="text-blue-800 dark:text-blue-200 mb-0">
|
||||
<strong>Important:</strong> We may update, modify, or remove content at any time without notice.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="scope" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">1. Scope of Services</h2>
|
||||
<p>
|
||||
Our website provides information about our professional services, expertise, and industry insights. The content
|
||||
on this website is for general informational purposes only and does not constitute professional advice. We may
|
||||
update, modify, or remove content at any time without notice.
|
||||
</p>
|
||||
<!-- User Rights & Responsibilities -->
|
||||
<div id="user-rights" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">👤</div>
|
||||
<h2 class="text-2xl font-bold">2. User Rights & Responsibilities</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p class="mb-6">When using our website, you agree to:</p>
|
||||
<div class="grid md:grid-cols-2 gap-4 not-prose">
|
||||
{[
|
||||
{
|
||||
type: 'do',
|
||||
text: 'Use the website in accordance with these terms and all applicable laws'
|
||||
},
|
||||
{
|
||||
type: 'do',
|
||||
text: 'Respect intellectual property rights and terms of use'
|
||||
},
|
||||
{
|
||||
type: 'dont',
|
||||
text: 'Use the website in any way that could damage or impair our services'
|
||||
},
|
||||
{
|
||||
type: 'dont',
|
||||
text: 'Attempt to gain unauthorized access to any part of the website'
|
||||
},
|
||||
{
|
||||
type: 'dont',
|
||||
text: 'Use any automated means to access or collect data from the website'
|
||||
},
|
||||
{
|
||||
type: 'dont',
|
||||
text: 'Use the website to transmit any harmful code or material'
|
||||
}
|
||||
].map((item) => (
|
||||
<div class={`flex items-start p-4 rounded-lg ${
|
||||
item.type === 'do'
|
||||
? 'bg-green-50/50 dark:bg-green-900/20 border-l-4 border-green-500'
|
||||
: 'bg-red-50/50 dark:bg-red-900/20 border-l-4 border-red-500'
|
||||
}`}>
|
||||
<div class={`mr-3 mt-1 ${
|
||||
item.type === 'do' ? 'text-green-500' : 'text-red-500'
|
||||
}`}>
|
||||
{item.type === 'do' ? '✓' : '✗'}
|
||||
</div>
|
||||
<p class="text-gray-700 dark:text-slate-200 text-sm">{item.text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="user-rights" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">2. User Rights & Responsibilities</h2>
|
||||
<p>When using our website, you agree to:</p>
|
||||
<ul>
|
||||
<li>Use the website in accordance with these terms and conditions and all applicable laws and regulations</li>
|
||||
<li>Not use the website in any way that could damage, disable, overburden, or impair our services</li>
|
||||
<li>
|
||||
Not attempt to gain unauthorized access to any part of the website or any system or network connected to the
|
||||
website
|
||||
</li>
|
||||
<li>Not use any automated means to access or collect data from the website</li>
|
||||
<li>Not use the website to transmit any harmful code or material</li>
|
||||
</ul>
|
||||
<!-- Intellectual Property -->
|
||||
<div id="intellectual-property" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">©️</div>
|
||||
<h2 class="text-2xl font-bold">3. Intellectual Property</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
All content on this website, including but not limited to text, graphics, logos, images, audio clips, digital
|
||||
downloads, and data compilations, is the property of the website owner or its content suppliers and is protected
|
||||
by Dutch and international copyright laws.
|
||||
</p>
|
||||
<div class="bg-purple-50/50 dark:bg-purple-900/20 rounded-lg p-6 border-l-4 border-purple-500 mt-6">
|
||||
<h3 class="font-bold text-purple-800 dark:text-purple-200 mb-3">Permitted Use</h3>
|
||||
<p class="text-purple-700 dark:text-purple-300 mb-0">
|
||||
You may view, download, and print content from this website for your personal, non-commercial use, provided that
|
||||
you do not modify the content and that you retain all copyright and other proprietary notices.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="intellectual-property" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">3. Intellectual Property</h2>
|
||||
<p>
|
||||
All content on this website, including but not limited to text, graphics, logos, images, audio clips, digital
|
||||
downloads, and data compilations, is the property of the website owner or its content suppliers and is protected
|
||||
by Dutch and international copyright laws.
|
||||
</p>
|
||||
<p>
|
||||
You may view, download, and print content from this website for your personal, non-commercial use, provided that
|
||||
you do not modify the content and that you retain all copyright and other proprietary notices.
|
||||
</p>
|
||||
<!-- Limitation of Liability -->
|
||||
<div id="liability" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">⚖️</div>
|
||||
<h2 class="text-2xl font-bold">4. Limitation of Liability</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<div class="bg-yellow-50/50 dark:bg-yellow-900/20 rounded-lg p-6 border-l-4 border-yellow-500 mb-6">
|
||||
<h3 class="font-bold text-yellow-800 dark:text-yellow-200 mb-3">⚠️ Important Legal Notice</h3>
|
||||
<p class="text-yellow-700 dark:text-yellow-300 mb-0">
|
||||
To the fullest extent permitted by applicable law, we exclude all representations, warranties, and conditions
|
||||
relating to our website and the use of this website.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
We will not be liable for any direct, indirect, or consequential loss or damage arising under these terms and
|
||||
conditions or in connection with our website, including any loss of profit, contracts, business, goodwill, data,
|
||||
income, revenue, or anticipated savings.
|
||||
</p>
|
||||
<div class="bg-green-50/50 dark:bg-green-900/20 rounded-lg p-4 border-l-4 border-green-500 mt-4">
|
||||
<p class="text-green-800 dark:text-green-200 mb-0">
|
||||
<strong>Exception:</strong> This does not exclude our liability for death or personal injury resulting from
|
||||
negligence, fraudulent misrepresentation, or any other liability which cannot be excluded under applicable law.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="liability" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">4. Limitation of Liability</h2>
|
||||
<p>
|
||||
To the fullest extent permitted by applicable law, we exclude all representations, warranties, and conditions
|
||||
relating to our website and the use of this website. We will not be liable for any direct, indirect, or
|
||||
consequential loss or damage arising under these terms and conditions or in connection with our website, whether
|
||||
arising in tort, contract, or otherwise, including, without limitation, any loss of profit, contracts, business,
|
||||
goodwill, data, income, revenue, or anticipated savings.
|
||||
</p>
|
||||
<p>
|
||||
This does not exclude or limit our liability for death or personal injury resulting from our negligence, nor our
|
||||
liability for fraudulent misrepresentation or misrepresentation as to a fundamental matter, nor any other
|
||||
liability which cannot be excluded or limited under applicable law.
|
||||
</p>
|
||||
<!-- Governing Law -->
|
||||
<div id="governing-law" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🏛️</div>
|
||||
<h2 class="text-2xl font-bold">5. Governing Law</h2>
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="p-6 bg-blue-50/50 dark:bg-blue-900/20 rounded-lg border-l-4 border-blue-500">
|
||||
<h3 class="font-bold text-blue-800 dark:text-blue-200 mb-3">🇳🇱 Dutch Law</h3>
|
||||
<p class="text-blue-700 dark:text-blue-300 text-sm">
|
||||
These terms are governed by Dutch law and the GDPR. Disputes will be handled by Dutch courts.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 bg-green-50/50 dark:bg-green-900/20 rounded-lg border-l-4 border-green-500">
|
||||
<h3 class="font-bold text-green-800 dark:text-green-200 mb-3">🛡️ Consumer Rights</h3>
|
||||
<p class="text-green-700 dark:text-green-300 text-sm">
|
||||
If you are a consumer, you will benefit from any mandatory provisions of the law of the country in which you are resident.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="governing-law" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">5. Governing Law</h2>
|
||||
<p>
|
||||
These terms are governed by Dutch law and the GDPR. Disputes will be handled by Dutch courts. If you are a consumer, you will benefit from any mandatory provisions of the law of the country in which you are resident. Nothing in these terms and conditions affects your rights as a consumer to rely on such mandatory provisions of local law.
|
||||
</p>
|
||||
<!-- Cookie Usage -->
|
||||
<div id="cookies" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">🍪</div>
|
||||
<h2 class="text-2xl font-bold">6. Cookie Usage</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>Our website uses two essential cookies:</p>
|
||||
<div class="grid md:grid-cols-2 gap-4 not-prose mt-4">
|
||||
<div class="p-4 bg-gray-50/50 dark:bg-slate-800/50 rounded-lg">
|
||||
<h3 class="font-bold mb-2 flex items-center">
|
||||
<span class="text-lg mr-2">🌐</span>
|
||||
preferredLanguage
|
||||
</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-400">Stores your language preference</p>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-50/50 dark:bg-slate-800/50 rounded-lg">
|
||||
<h3 class="font-bold mb-2 flex items-center">
|
||||
<span class="text-lg mr-2">✅</span>
|
||||
cookieConsentAccepted
|
||||
</h3>
|
||||
<p class="text-sm text-gray-600 dark:text-slate-400">Stores your cookie consent</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-blue-50/50 dark:bg-blue-900/20 rounded-lg p-4 border-l-4 border-blue-500 mt-6">
|
||||
<p class="text-blue-800 dark:text-blue-200 mb-0">
|
||||
<strong>No tracking:</strong> No tracking, analytics, or third-party cookies are used. No personal data is collected.
|
||||
</p>
|
||||
</div>
|
||||
<p class="mt-4">
|
||||
For more information about how we use cookies and other browser storage technologies, please see our{' '}
|
||||
<a href="/en/privacy" class="text-blue-600 dark:text-blue-400 underline">Privacy Policy</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="cookies" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">6. Cookie Usage</h2>
|
||||
<p>
|
||||
Our website uses two essential cookies:
|
||||
<ul>
|
||||
<li><strong>preferredLanguage</strong>: Stores your language preference.</li>
|
||||
<li><strong>cookieConsentAccepted</strong>: Stores your cookie consent.</li>
|
||||
</ul>
|
||||
No tracking, analytics, or third-party cookies are used. No personal data is collected.
|
||||
</p>
|
||||
<p>For more information about how we use cookies and other browser storage technologies, please see our <a href="/en/privacy">Privacy Policy</a>.</p>
|
||||
<!-- Changes to Terms -->
|
||||
<div id="changes" class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-8 scroll-mt-20">
|
||||
<div class="flex items-center mb-6">
|
||||
<div class="text-3xl mr-4">📝</div>
|
||||
<h2 class="text-2xl font-bold">7. Changes to Terms</h2>
|
||||
</div>
|
||||
<div class="prose prose-lg dark:prose-invert max-w-none">
|
||||
<p>
|
||||
We may revise these terms and conditions at any time by amending this page. You are expected to check this page
|
||||
from time to time to take notice of any changes we make, as they are legally binding on you.
|
||||
</p>
|
||||
<div class="bg-orange-50/50 dark:bg-orange-900/20 rounded-lg p-4 border-l-4 border-orange-500 mt-4">
|
||||
<p class="text-orange-800 dark:text-orange-200 mb-0">
|
||||
<strong>Stay informed:</strong> Some provisions may also be superseded by notices published elsewhere on our website.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="changes" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">7. Changes to Terms</h2>
|
||||
<p>
|
||||
We may revise these terms and conditions at any time by amending this page. You are expected to check this page
|
||||
from time to time to take notice of any changes we make, as they are legally binding on you. Some of the
|
||||
provisions contained in these terms and conditions may also be superseded by provisions or notices published
|
||||
elsewhere on our website.
|
||||
</p>
|
||||
|
||||
<h2 id="contact" class="scroll-mt-20 text-2xl font-bold mt-8 mb-4">8. Contact</h2>
|
||||
<p>For legal questions, contact <a href="mailto:info@365devnet.eu">info@365devnet.eu</a>.<br />
|
||||
Company name: 365devnet<br />
|
||||
KvK number: 97226270<br />
|
||||
Based in the Netherlands.</p>
|
||||
<!-- Contact Information -->
|
||||
<div id="contact" class="backdrop-blur-sm bg-gradient-to-r from-purple-600/90 to-blue-600/90 rounded-xl shadow-lg p-8 text-center text-white scroll-mt-20">
|
||||
<div class="text-4xl mb-4">📧</div>
|
||||
<h2 class="text-2xl font-bold mb-4">8. Contact</h2>
|
||||
<div class="max-w-md mx-auto space-y-2">
|
||||
<p><strong>Email:</strong> <a href="mailto:info@365devnet.eu" class="underline hover:text-purple-200">info@365devnet.eu</a></p>
|
||||
<p><strong>Company:</strong> 365devnet</p>
|
||||
<p><strong>KvK number:</strong> 97226270</p>
|
||||
<p><strong>Location:</strong> Netherlands</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
@@ -40,9 +40,14 @@ if (!currentLang) {
|
||||
}
|
||||
|
||||
const t = getTranslation(currentLang);
|
||||
|
||||
const metadata = {
|
||||
title: t.uptime.title || 'System Status & Uptime',
|
||||
description: t.uptime.subtitle || 'Real-time status monitoring of 365DevNet services and infrastructure',
|
||||
};
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<Layout metadata={metadata}>
|
||||
<main class="relative max-w-7xl mx-auto px-4 sm:px-6 py-12">
|
||||
<div class="relative">
|
||||
<div class="text-center mb-5">
|
||||
@@ -51,5 +56,44 @@ const t = getTranslation(currentLang);
|
||||
</div>
|
||||
<UptimeStatus />
|
||||
</div>
|
||||
|
||||
<!-- Compact Status Legend -->
|
||||
<div class="backdrop-blur-sm bg-white/70 dark:bg-slate-900/70 rounded-xl shadow p-6 mb-8 mt-8">
|
||||
<h3 class="text-lg font-semibold mb-4">Status Legend</h3>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 bg-green-500 rounded-full mr-2"></div>
|
||||
<span class="text-sm font-medium">Operational</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 bg-yellow-500 rounded-full mr-2"></div>
|
||||
<span class="text-sm font-medium">Degraded</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div>
|
||||
<span class="text-sm font-medium">Outage</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-3 h-3 bg-gray-500 rounded-full mr-2"></div>
|
||||
<span class="text-sm font-medium">Maintenance</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Minimal Footer Info -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-8">
|
||||
<div class="backdrop-blur-sm bg-blue-50/50 dark:bg-blue-900/20 rounded-lg p-4 border-l-4 border-blue-500">
|
||||
<h4 class="font-semibold text-blue-800 dark:text-blue-200 mb-1">🔄 Updates</h4>
|
||||
<p class="text-sm text-blue-700 dark:text-blue-300">
|
||||
Status checks every 30 minutes with automatic refresh
|
||||
</p>
|
||||
</div>
|
||||
<div class="backdrop-blur-sm bg-green-50/50 dark:bg-green-900/20 rounded-lg p-4 border-l-4 border-green-500">
|
||||
<h4 class="font-semibold text-green-800 dark:text-green-200 mb-1">📧 Support</h4>
|
||||
<p class="text-sm text-green-700 dark:text-green-300">
|
||||
Contact <a href="mailto:info@365devnet.eu" class="underline hover:text-green-600 dark:hover:text-green-400">info@365devnet.eu</a> for issues
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
</Layout>
|
Reference in New Issue
Block a user