Skip to content

Commit

Permalink
Add support for i18n
Browse files Browse the repository at this point in the history
Add German language
  • Loading branch information
Luc1412 committed Feb 3, 2025
1 parent efeaaeb commit be2b7ef
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 114 deletions.
155 changes: 72 additions & 83 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
'use client'

import React from "react";
import React, {ReactNode} from "react";
import organizationData from "@/data/users.json";
import {User} from "@/types/organizationTypes";
import {Link} from "@heroui/link";
import {ScrollShadow} from "@heroui/scroll-shadow";
import {OrganizationBox} from "@/components/organizationBox";
import {NavigationBar} from "@/components/navigationBar";
import {useTranslations} from "next-intl";
import RichText from "@/components/richText";
import {Footer} from "@/components/footer";

const organizations = organizationData as User[];

export default function Home() {
const t = useTranslations('HomePage');

return (
<main className="flex flex-col min-h-screen bg-gray-100">
Expand All @@ -19,84 +23,62 @@ export default function Home() {

<div className="container mx-auto px-4 py-8 flex-grow">
<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">About eduMFA</h2>
<h2 className="text-2xl font-bold mb-4">{t('aboutTitle')}</h2>
<p className="text-gray-700">
eduMFA is a comprehensive authentication system that enhances existing applications with
multi-factor authentication, significantly improving security. Originally forked from
privacyIDEA version 3.9.2, eduMFA has evolved into a robust solution deeply integrated with
Shibboleth, making
it particularly suited for academic and research environments. It supports various
authentication methods, including OTP devices, challenge-response mechanisms, SSH keys, and the
cutting-edge Passkeys technology.
</p>
<p className="text-gray-700 mt-2">
Running on Linux and entirely open-source under the AGPLv3 license, eduMFA offers a flexible and
powerful plugin system. This allows for seamless integration with various identity management
systems and applications, extending its functionality to meet diverse authentication needs. All
features of eduMFA can be used free of charge.
<RichText>
{(tags) => t.rich('aboutContent', tags)}
</RichText>
</p>
</section>

<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">Key Features and Goals</h2>
<ul className="list-disc list-inside text-gray-700">
<li>Multi-factor authentication support for enhanced security</li>
<li>Deep integration with Shibboleth for academic and research environments</li>
<li>Support for modern authentication methods, including Passkeys</li>
<li>Easy migration path from privacyIDEA and other authentication systems</li>
<li>Continuous development based on the scientific community&apos;s requirements</li>
<li>Focus on using and maintaining up-to-date, current software components</li>
<li>Support for the latest Python versions (currently Python 3.8 to 3.12)</li>
<li>Official support for container deployment, enabling seamless scaling in Kubernetes
clusters
</li>
<li>eduMFA Authenticator App for push notifications</li>
</ul>
<h2 className="text-2xl font-bold mb-4">{t('featuresTitle')}</h2>
<div className="text-gray-700">
<RichText>
{(tags) => t.rich('featuresContent',
{
...tags,
minPyVersion: '3.9',
maxPyVersion: '3.13'
}
)}
</RichText>
</div>

</section>

<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">Why Choose eduMFA?</h2>
<h2 className="text-2xl font-bold mb-4">{t('reasonTitle')}</h2>
<p className="text-gray-700">
eduMFA provides robust protection against hacking attacks for IT services in academic networks
and beyond. By enabling multi-factor authentication, it renders traditional username-password
combinations obsolete. The &apos;Passkeys&apos; method, a key focus of eduMFA, securely stores
authentication keys, accessible only through additional methods like biometric scans or PINs.
This approach offers strong resistance to phishing attacks, allows synchronization between
compatible devices, and delivers a seamless user experience without compromising on security.
</p>
<p className="text-gray-700 mt-2">
Already in use at several universities across Europe, including institutions in Germany, Czech
Republic, and Norway, eduMFA is continuously evolving to meet the dynamic
needs of the scientific and broader IT community. Its commitment to using current, up-to-date
software ensures that users always have access to the latest security features and improvements.
<RichText>
{(tags) => t.rich('reasonContent', tags)}
</RichText>
</p>
</section>

<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">Support and Development</h2>
<p className="text-gray-700">
eduMFA benefits from a strong support network and an active development community:
</p>
<ul className="list-disc list-inside text-gray-700 mt-2">
<li>Commercial support, consulting, implementation, 2nd-level support, and managed services are
available from trusted companies like DAASI International, GWDG, and Ssystems.
</li>
<li>The development team includes contributors from leading institutions such as Freie
Universität Berlin, GWDG, Hochschule München, and University of Bamberg.
</li>
<li>This collaborative approach ensures that eduMFA remains at the forefront of authentication
technology, addressing real-world needs in academic and research environments.
</li>
<li>A <Link href="https://www.listserv.dfn.de/sympa/info/edumfa-users" isExternal
showAnchorIcon>user mailing list</Link> is available for community support and
discussions.
</li>
<li>Issues and feature requests can be submitted on the GitHub repository.</li>
</ul>
<h2 className="text-2xl font-bold mb-4">{t('supportTitle')}</h2>
<div className="text-gray-700">
<RichText>
{(tags) => t.rich('supportContent',
{
...tags,
userMailingListLink: (content: ReactNode) =>
<Link
href="https://www.listserv.dfn.de/sympa/info/edumfa-users"
isExternal
showAnchorIcon
>
{content}
</Link>
}
)}
</RichText>
</div>
</section>

<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">Organizations Using eduMFA</h2>
<h2 className="text-2xl font-bold mb-4">{t('orgTitle')}</h2>
<ScrollShadow className="max-h-96">
<div
className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4 p-4">
Expand All @@ -106,35 +88,42 @@ export default function Home() {
</div>
</ScrollShadow>
<p className="text-gray-500 mt-2 text-sm italic">
Is your organization using eduMFA? <Link
href="https://github.com/eduMFA/Web/issues/new?labels=organization&title=%5BOrg%5D+&template=manage_organization.yml"
isExternal>Add it to the list</Link>.
{t.rich('orgFooter', {
addOrgLink: (content: ReactNode) =>
<Link
href="https://github.com/eduMFA/Web/issues/new?labels=organization&title=%5BOrg%5D+&template=manage_organization.yml"
isExternal
showAnchorIcon
>
{content}
</Link>
})}
</p>
</section>

<section className="mb-8">
<h2 className="text-2xl font-bold mb-4">Installation</h2>
<p className="text-gray-700">
The system is written in Python, uses Flask as the web framework, and an SQL database as the
datastore.
Installation is straightforward, providing a lean installation process.
</p>
<br/>
<h2 className="text-2xl font-bold mb-4">{t('installTitle')}</h2>
<p className="text-gray-700">
You can learn more about the installation process in the <Link
href="https://edumfa.readthedocs.io/en/latest/installation/index.html" isExternal
showAnchorIcon>documentation</Link>.
<RichText>
{(tags) => t.rich('installContent',
{
...tags,
documentationLink: (content: ReactNode) =>
<Link
href="https://edumfa.readthedocs.io/en/latest/installation/index.html"
isExternal
showAnchorIcon
>
{content}
</Link>
}
)}
</RichText>
</p>
</section>
</div>

<footer className="bg-gray-800 text-white py-4">
<div className="container mx-auto px-4 text-center">
<p>&copy; 2024 eduMFA. All rights reserved.</p>
<Link href="https://www.fu-berlin.de/en/redaktion/impressum/"
className="text-white hover:text-gray-300">Imprint</Link>
</div>
</footer>
<Footer/>
</main>
);
}
16 changes: 10 additions & 6 deletions app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
'use client'

import {HeroUIProvider} from "@heroui/system"
import React from "react";
import {NextIntlClientProvider} from "next-intl";
import {getMessages} from "next-intl/server";

export async function Providers({children}: { children: React.ReactNode }) {
const messages = await getMessages();

export function Providers({children}: { children: React.ReactNode }) {
return (
<HeroUIProvider>
{children}
</HeroUIProvider>
<NextIntlClientProvider messages={messages}>
<HeroUIProvider>
{children}
</HeroUIProvider>
</NextIntlClientProvider>
)
}
21 changes: 21 additions & 0 deletions components/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Link} from "@heroui/link";
import React from "react";
import {useTranslations} from "next-intl";

export const Footer: React.FC = () => {
const t = useTranslations('Footer');

return (
<footer className="bg-gray-800 text-white py-4">
<div className="container mx-auto px-4 text-center">
<p>{t('copyright')}</p>
<Link
href="https://www.fu-berlin.de/en/redaktion/impressum/"
className="text-white hover:text-gray-300"
>
{t('imprint')}
</Link>
</div>
</footer>
)
}
19 changes: 11 additions & 8 deletions components/navigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ import {
import React from "react";
import Image from "next/image";
import {Link} from "@heroui/link";
import {useTranslations} from "next-intl";

export const NavigationBar: React.FC = () => {
const t = useTranslations('NavigationBar');

const [isMenuOpen, setIsMenuOpen] = React.useState(false);

const menuLinks = {
"Github": "https://github.com/eduMFA/eduMFA/",
"Documentation": "https://edumfa.readthedocs.io/",
"Mailing List": "https://www.listserv.dfn.de/sympa/info/edumfa-users"
github: "https://github.com/eduMFA/eduMFA/",
documentation: "https://edumfa.readthedocs.io/",
mailingList: "https://www.listserv.dfn.de/sympa/info/edumfa-users"
}

return (
Expand Down Expand Up @@ -57,25 +60,25 @@ export const NavigationBar: React.FC = () => {
/>
</Link>
</NavbarBrand>
{Object.entries(menuLinks).map(([label, link], index) => (
{Object.entries(menuLinks).map(([labelKey, link], index) => (
<NavbarItem key={index}>
<Link isExternal color="foreground" href={link}>
{label}
{t(labelKey)}
</Link>
</NavbarItem>
))}
</NavbarContent>

<NavbarMenu>
{Object.entries(menuLinks).map(([label, link], index) => (
<NavbarMenuItem key={`${label}-${index}`}>
{Object.entries(menuLinks).map(([labelKey, link], index) => (
<NavbarMenuItem key={index}>
<Link
isExternal
href={link}
color="foreground"
className="w-full"
>
{label}
{t(labelKey)}
</Link>
</NavbarMenuItem>
))}
Expand Down
Loading

0 comments on commit be2b7ef

Please sign in to comment.