diff --git a/Project-Website.code-workspace b/Project-Website.code-workspace new file mode 100644 index 0000000..4d1d8d4 --- /dev/null +++ b/Project-Website.code-workspace @@ -0,0 +1,41 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.tabSize": 2, + "editor.rulers": [80], + "files.associations": { + "*.css": "tailwindcss" + }, + "tailwindCSS.includeLanguages": { + "typescript": "javascript", + "typescriptreact": "javascript" + }, + "emmet.includeLanguages": { + "javascript": "javascriptreact", + "typescript": "typescriptreact" + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/node_modules": true + } + }, + "extensions": { + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "bradlc.vscode-tailwindcss", + "dsznajder.es7-react-js-snippets", + "ms-vscode.vscode-typescript-next" + ] + } +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 0af6fc8..fe5dbe8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,19 +1,23 @@ +import React from "react"; import "./App.css"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import { ContentFrameBox } from "./components/ContentFrameBox"; -import { Route, createRoutesFromElements, RouterProvider, createHashRouter } from "react-router-dom"; import { DataSec } from "./components/dataSec"; import { ImPrint } from "./components/imprint"; +import { LanguageProvider } from "./context/LanguageContext"; -const router = createHashRouter( - createRoutesFromElements( - - }> - }> - }> - - ) -) +function App() { + return ( + + + + } /> + } /> + } /> + + + + ); +} -export default function App() { - return ; -} \ No newline at end of file +export default App; \ No newline at end of file diff --git a/src/components/ContentFrame.tsx b/src/components/ContentFrame.tsx index 5ebf196..3a9d496 100644 --- a/src/components/ContentFrame.tsx +++ b/src/components/ContentFrame.tsx @@ -1,23 +1,28 @@ -import React, { ReactNode } from "react"; +import React from "react"; +import { useLanguage } from "../context/LanguageContext"; +import { translations } from "../translations/translations"; interface Props { - title: ReactNode; - descriptive_text: ReactNode; + projectKey: string; link: string; } -export default function ContentFrame({ title, descriptive_text, link }: Props) { +export default function ContentFrame({ projectKey, link }: Props) { + const { language } = useLanguage(); + const project = translations[language].projects[projectKey as keyof typeof translations[typeof language]["projects"]]; + const { toProject } = translations[language].common; + return (
-
{title}
+
{project.title}
-

{descriptive_text}

+

{project.description}



- To {title} + {toProject} {project.title}
diff --git a/src/components/ContentFrameBox.tsx b/src/components/ContentFrameBox.tsx index 07ff1fe..bb47363 100644 --- a/src/components/ContentFrameBox.tsx +++ b/src/components/ContentFrameBox.tsx @@ -1,165 +1,112 @@ import { NavLink } from "react-router-dom"; import ContentFrame from "./ContentFrame"; +import { LanguageSelector } from "./LanguageSelector"; +import { useLanguage } from "../context/LanguageContext"; +import { translations } from "../translations/translations"; export function ContentFrameBox() { + const { language } = useLanguage(); + const { privacy, imprint } = translations[language].navigation; + return (
-
-
-
Tom DevTech
-
-
- - - - - - - - - - - - - - - - - - - - -
-
- - Privacy - - - Imprint - -

-
+ +
+
+
Tom DevTech
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+ + {privacy} + + + {imprint} + +

+
+
); } diff --git a/src/components/LanguageSelector.tsx b/src/components/LanguageSelector.tsx new file mode 100644 index 0000000..7981fc3 --- /dev/null +++ b/src/components/LanguageSelector.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useLanguage } from '../context/LanguageContext'; + +export const LanguageSelector: React.FC = () => { + const { language, setLanguage } = useLanguage(); + + return ( +
+
+ + +
+
+ ); +}; \ No newline at end of file diff --git a/src/context/LanguageContext.tsx b/src/context/LanguageContext.tsx new file mode 100644 index 0000000..73d7f02 --- /dev/null +++ b/src/context/LanguageContext.tsx @@ -0,0 +1,45 @@ +import React, { createContext, useContext, useState, ReactNode, useEffect } from 'react'; + +type Language = 'de' | 'en'; + +interface LanguageContextType { + language: Language; + setLanguage: () => void; +} + +const LanguageContext = createContext(undefined); + +export const LanguageProvider: React.FC<{ children: ReactNode }> = ({ children }) => { + // Get initial language from localStorage or default to 'de' + const [language, setLanguageState] = useState(() => { + const savedLanguage = localStorage.getItem('language'); + return (savedLanguage === 'en' || savedLanguage === 'de') ? savedLanguage : 'de'; + }); + + const setLanguage = (newLanguage: Language) => { + setLanguageState(newLanguage); + localStorage.setItem('language', newLanguage); + }; + + // Update language based on browser settings on first load + useEffect(() => { + const browserLang = navigator.language.toLowerCase(); + if (!localStorage.getItem('language')) { + setLanguage(browserLang.startsWith('de') ? 'de' : 'en'); + } + }, []); + + return ( + + {children} + + ); +}; + +export const useLanguage = () => { + const context = useContext(LanguageContext); + if (context === undefined) { + throw new Error('useLanguage must be used within a LanguageProvider'); + } + return context; +}; \ No newline at end of file diff --git a/src/translations/translations.ts b/src/translations/translations.ts new file mode 100644 index 0000000..b901610 --- /dev/null +++ b/src/translations/translations.ts @@ -0,0 +1,184 @@ +export const translations = { + de: { + projects: { + robert: { + title: "Robert Assistent", + description: "Treffen Sie Robert, Ihren hilfsbereiten Assistenten mit einer Vielzahl von Tools, einschließlich einer Galerie, einem Musikplayer und mehr. Er ist nicht nur in der Lage, Sie mit Witzen zu unterhalten, sondern verfügt auch über ein eingebautes Hilfemenü." + }, + colourChanger: { + title: "Colour Changer", + description: "Dieses Programm ermöglicht es Ihnen, mit verschiedenen Farben für GUIs zu experimentieren. Sie können hexadezimale Werte eingeben oder aus einer Reihe von Farbnamen wählen." + }, + unilexika: { + title: "Unilexika", + description: "Dient als kleines Notizbuch zum Speichern und Lesen von Textdateien." + }, + updatedUnilexika: { + title: "Aktualisiertes Unilexika", + description: "Die aktualisierte Version ermöglicht jetzt das Bearbeiten bestehender Einträge, nicht nur das Lesen." + }, + listApp: { + title: "List App", + description: "Diese App ist für Benutzer gedacht, die schnellen und kostenlosen Zugang zu Websites suchen, auf denen sie Bücher kostenlos herunterladen können. Allerdings müssen die 'Entwickleroptionen' für die Installation aktiviert sein." + }, + linkApp: { + title: "Link App", + description: "Mit dieser App können Sie Links speichern, löschen und optional bearbeiten. Letztendlich dient die App dem Zweck, Websites einfach zu speichern und darauf zuzugreifen." + }, + penAndPaper: { + title: "Pen and Paper Storage System", + description: "Diese Anwendung ist exklusiv für Windows und ermöglicht es Benutzern, Daten über Charaktere und Geschichten mit dem JSON-Speichersystem zu erstellen, zu bearbeiten und zu löschen." + }, + portfolio: { + title: "Portfolio Website", + description: "Meine alte (und erste) Website als Prototyp. Erstellt, um alle Projekte besser organisiert und prägnant zu präsentieren." + }, + arrayProject: { + title: "Array Project", + description: "Dieses Projekt ist ein beispielhaftes Programm, das zeigen soll, wie Elemente in Arrays mit Dimensionen von 1 bis 3 im Allgemeinen gelesen, gelöscht und modifiziert werden." + }, + icAutodocker: { + title: "IC-Autodocker", + description: "Ein interaktives Docker-Explorationstool, um spielerisch alle Funktionalitäten zu erkunden und zu experimentieren." + }, + icAutodockerPython: { + title: "IC-Autodocker Python Package", + description: "Vollständiges Python-Paket von IC-Autodocker, ohne GUI." + }, + website: { + title: "Website", + description: "Neue Portfolio-Website, die meine Projekte als Softwareentwickler präsentiert. Erstellt mit React und Tailwind CSS." + }, + gradeCalculator: { + title: "Grade Calculator", + description: "Berechnen Sie Ihren Universitätsnotendurchschnitt mit diesem kleinen Programm mit grafischer Benutzeroberfläche." + }, + pythonCourse: { + title: "Python 3 Kurs", + description: "Ein selbst erstellter Python 3-Kurs zum Erlernen der Grundlagen der Programmiersprache und zum Beherrschen verwandter Konzepte." + }, + apiPictureGenerator: { + title: "API Picture Generator", + description: "Generiert Bilder mit einer API. Für ein verbessertes Benutzererlebnis wurde eine grafische Benutzeroberfläche mit PyQT5 erstellt." + }, + exampleLibrary: { + title: "Example Library", + description: "Dieses Projekt ist eine umfassende Code-Beispielbibliothek, die Java, Python, Ruby, C/C++ und Webentwicklung (HTML, CSS, JavaScript mit React) abdeckt." + }, + learnProgramming: { + title: "Learn Programming", + description: "Das Repository ist eine kuratierte Sammlung von Websites und Plattformen, die Tutorials, Kurse und Informationen anbieten, um Einzelpersonen beim Erlernen und Verbessern ihrer Programmierkenntnisse zu helfen." + }, + simpleAIChatBot: { + title: "Simple AI Chat Bot", + description: "Eine einfache lokale KI, die Ihre priorisierten Ordner scannt und eine Markdown-Dokumentationsdatei erstellt." + }, + aiAPI: { + title: "AI API", + description: "Ein Beispiel-API-Projekt für die Interaktion mit einem lokalen Modell, die Verwaltung von Modellen und die Handhabung der Autorisierung." + }, + workTimeManagement: { + title: "Work Time Management", + description: "Das Work Time Management-System ermöglicht es Unternehmen, Arbeitszeiten von Mitarbeitern effizient zu verfolgen, zu verwalten und zu analysieren, um Produktivität und Compliance zu gewährleisten." + } + }, + navigation: { + privacy: "Datenschutz", + imprint: "Impressum" + }, + common: { + toProject: "Zum Projekt" + } + }, + en: { + projects: { + robert: { + title: "Robert Assistant", + description: "Meet Robert, your helpful assistant with a wide range of tools, including a gallery, a music player, and more. He's not only capable of entertaining you with jokes but also comes with a built-in help menu." + }, + colourChanger: { + title: "Colour Changer", + description: "This program allows you to experiment with various colors for GUIs. You can input hexadecimal values or choose from a range of color names." + }, + unilexika: { + title: "Unilexika", + description: "Serves as a small notebook for storing and reading text files." + }, + updatedUnilexika: { + title: "Updated Unilexika", + description: "The updated version now allows editing existing entries, not just reading them." + }, + listApp: { + title: "List App", + description: "This app is designed for users who seek quick and free access to websites where they can download books for free. However, 'Developer Options' must be enabled for the installation." + }, + linkApp: { + title: "Link App", + description: "Using this app, you can store, delete, and optionally edit links. Ultimately, the app serves the purpose of easily saving and accessing websites." + }, + penAndPaper: { + title: "Pen and Paper Storage System", + description: "This application is exclusive to Windows and allows users to create, edit, and delete data about characters and stories using the JSON storage system." + }, + portfolio: { + title: "Portfolio Website", + description: "My old (and first) website as a prototype. Created to showcase all projects in a better organized and concise manner." + }, + arrayProject: { + title: "Array Project", + description: "This project is an exemplary program aimed at illustrating how elements in arrays, with dimensions ranging from 1 to 3, are read, deleted, and modified in general." + }, + icAutodocker: { + title: "IC-Autodocker", + description: "An interactive Docker exploration tool to playfully approach and experiment with all functionalities." + }, + icAutodockerPython: { + title: "IC-Autodocker Python Package", + description: "Full-featured Python package of IC-Autodocker, excluding the GUI." + }, + website: { + title: "Website", + description: "New portfolio website showcasing my projects as a software developer. Built with React and Tailwind CSS." + }, + gradeCalculator: { + title: "Grade Calculator", + description: "Calculate your university grade point average with this small program featuring a graphical user interface." + }, + pythonCourse: { + title: "Python 3 Course", + description: "A self-created Python 3 course for learning the fundamentals of the programming language and mastering related concepts." + }, + apiPictureGenerator: { + title: "API Picture Generator", + description: "Generates images using an API. For enhanced user experience, a graphical interface was created using PyQT5." + }, + exampleLibrary: { + title: "Example Library", + description: "This project is a comprehensive code sample library covering Java, Python, Ruby, C/C++, and Web Development (HTML, CSS, JavaScript with React)." + }, + learnProgramming: { + title: "Learn Programming", + description: "The repository is a curated collection of websites and platforms offering tutorials, courses, and information to help individuals learn and enhance their programming skills." + }, + simpleAIChatBot: { + title: "Simple AI Chat Bot", + description: "A simple local AI that scans your prioritized folders and creates a markdown documentation file." + }, + aiAPI: { + title: "AI API", + description: "A sample API project for interacting with a local model, managing models, and handling authorization." + }, + workTimeManagement: { + title: "Work Time Management", + description: "The Work Time Management system enables companies to efficiently track, manage, and analyze employee working hours, ensuring productivity and compliance." + } + }, + navigation: { + privacy: "Privacy", + imprint: "Imprint" + }, + common: { + toProject: "To Project" + } + } +}; \ No newline at end of file