From 8ce56cf7cfccb8f166dd4e07dbbce4b3285cd3a5 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 21 Dec 2024 22:10:18 +0100 Subject: [PATCH] Improve layout --- src/app/globals.css | 69 ++--- src/app/layout.tsx | 4 +- src/app/page.tsx | 416 +++++++++++++++++++++---------- src/components/search-result.tsx | 2 +- 4 files changed, 318 insertions(+), 173 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index b83bc98..97ee168 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,44 +3,45 @@ @tailwind utilities; body { - font-family: Arial, Helvetica, sans-serif; + font-family: Arial, Helvetica, sans-serif; } @layer base { - :root { - --background: 20 14.3% 4.1%; - --foreground: 60 9.1% 97.8%; - --card: 20 14.3% 4.1%; - --card-foreground: 60 9.1% 97.8%; - --popover: 20 14.3% 4.1%; - --popover-foreground: 60 9.1% 97.8%; - --primary: 20.5 90.2% 48.2%; - --primary-foreground: 60 9.1% 97.8%; - --secondary: 12 6.5% 15.1%; - --secondary-foreground: 60 9.1% 97.8%; - --muted: 12 6.5% 15.1%; - --muted-foreground: 24 5.4% 63.9%; - --accent: 12 6.5% 15.1%; - --accent-foreground: 60 9.1% 97.8%; - --destructive: 0 72.2% 50.6%; - --destructive-foreground: 60 9.1% 97.8%; - --border: 12 6.5% 15.1%; - --input: 12 6.5% 15.1%; - --ring: 20.5 90.2% 48.2%; - --chart-1: 220 70% 50%; - --chart-2: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-5: 340 75% 55%; - --radius: 1.5rem - } + :root { + --background: 0 0% 12%; + --foreground: 60 9.1% 97.8%; + --card: 0 0% 18%; + --card-foreground: 60 9.1% 97.8%; + --popover: 20 14.3% 4.1%; + --popover-foreground: 60 9.1% 97.8%; + --primary: 20.5 90.2% 48.2%; + --primary-foreground: 60 9.1% 97.8%; + --secondary: 12 6.5% 15.1%; + --secondary-foreground: 60 9.1% 97.8%; + --muted: 12 6.5% 15.1%; + --muted-foreground: 24 5.4% 63.9%; + --accent: 12 6.5% 15.1%; + --accent-foreground: 60 9.1% 97.8%; + --destructive: 0 72.2% 50.6%; + --destructive-foreground: 60 9.1% 97.8%; + --border: 12 6.5% 15.1%; + --input: 12 6.5% 15.1%; + --ring: 20.5 90.2% 48.2%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + --radius: 1.5rem + } } @layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } + * { + @apply border-border; + } + + body { + @apply bg-background text-foreground; + } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b3a379a..e8f4093 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -14,8 +14,8 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Markus Thielker", + description: "Full stack developer of Kotlin and Java backends with experience in Android, React and Angular frontend development", }; export default function RootLayout({ diff --git a/src/app/page.tsx b/src/app/page.tsx index 6ff108f..770cdd9 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,166 +7,310 @@ import Link from 'next/link'; import { SearchResult } from '@/components/search-result'; import { PublicUser } from '@/lib/github-user'; +const calculateAge = (birthdate: Date): number => { + const today = new Date(); + let age = today.getFullYear() - birthdate.getFullYear(); + const monthDiff = today.getMonth() - birthdate.getMonth(); + + // Adjust age if the birthday hasn't occurred yet this year + if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthdate.getDate())) { + age--; + } + + return age; +}; + +const getRepos = async (username: string) => { + let repos: any[] = []; + let page = 1; + let hasNextPage = true; + + while (hasNextPage) { + const response = await fetch(`https://api.github.com/users/${username}/repos?page=${page}&per_page=100`, { + headers: { + Accept: 'application/vnd.github+json', + }, + }); + const data = await response.json(); + + if (Array.isArray(data)) { + repos = repos.concat(data); + hasNextPage = data.length === 100; // Check if there are more pages + page++; + } else { + hasNextPage = false; // Stop if the response is not an array (likely an error) + } + } + + return repos; +}; + +const getLanguages = async (repo: any) => { + const response = await fetch(repo.languages_url, { + headers: { + Accept: 'application/vnd.github+json', + }, + }); + return await response.json(); +}; + +const accumulateLanguages = async (repos: any[]) => { + const languages: { [key: string]: number } = {}; + + for (const repo of repos) { + const repoLanguages = await getLanguages(repo); + for (const lang in repoLanguages) { + languages[lang] = (languages[lang] || 0) + repoLanguages[lang]; + } + } + + return languages; +}; + export default async function Home() { - const response = await fetch("https://api.github.com/users/markusthielker") - const profile = await response.json() as PublicUser + const profileResponse = await fetch('https://api.github.com/users/markusthielker'); + const profile = await profileResponse.json() as PublicUser; + + const username = 'markusthielker'; + const repos = await getRepos(username); + const languages = await accumulateLanguages(repos); + const totalBytes = Object.values(languages).reduce((sum, bytes) => sum + bytes, 0); + + const languagePercentages = Object.entries(languages) + .map(([lang, bytes]) => ({ + lang, + percent: (bytes / totalBytes) * 100, + })) + .sort((a, b) => b.percent - a.percent) + .slice(0, 5); + + const age = calculateAge(new Date('2001-03-04')); return ( -
+
{ /* search header */} -
+
- { /* input */} -
- Portrait of Markus Thielker - + Portrait of Markus Thielker + + { /* header content (centered) */} +
+
+ + { /* input */} + + + { /* tab navigation */} +
+ All + News + Images + Videos + Books + Web + Finances +
+ +
+
-
+ { /* personalised content (centered) */} +
+
- { /* heading */} -
-

Markus Thielker

-

Software Engineer

-
+ { /* heading */} +
+

Markus Thielker

+

Software Engineer

+
- { /* card grid */} -
-
+ { /* card grid */} +
+
- { /* images */} - -
- Portrait of Markus Thielker -
-
- Portrait of Markus Thielker -
-
- Portrait of Markus Thielker -
-
+ { /* images */} + +
+ Portrait of Markus Thielker +
+
+ Portrait of Markus Thielker +
+
+ Portrait of Markus Thielker +
+
- { /* GitHub */} - - - -
- GitHub - GitHub -
-
-
- {profile.name} - {profile.followers} Followers + { /* GitHub */} + + + +
+ GitHub + GitHub
- {profile.bio} -
+
+
+ {profile.name} + {profile.followers} Followers +
+ {profile.bio} +
+ + + + + { /* age */} + + + + Age + + + + 23 Jahre + 04. März 2001 - - { /* age */} - - - - Age - - - - 23 Jahre - 04. März 2001 - - + { /* employer */} + + + + Employer + + + + None + Open for work + + - { /* employer */} - - - - Employer - - - - Looking for employment - - + { /* TODO */} + + + + Employer + + + + { + languagePercentages && +
    + {Object.entries(languagePercentages).map(([lang, percent]) => ( +
  • + {lang}: {percent as unknown as string} % +
  • + ))} +
+ } +
+
+
+
- { /* TODO */} - + { /* default content (centered) */} +
- -
-
+ { /* search results column */} +
- { /* search results */} -
-
- - - - -
-
+ + + + + + + + +
+ + { /* person info column */} +
+ Info + + Markus Thielker ist ein {age} Jahre alter Software Engineer aus Neu-Ulm, Deutschland. + Er entwickelt, nach einiger Jahre Android App Entwicklung, webbasierte Sofwtare. Dabei + verwendet er vorranig Next.js und Angular. + +
+ Degree: None + Experience: 2.5 years + Pets: One dog + Favorite Tech: Next.js & Kotlin +
+
+ +
diff --git a/src/components/search-result.tsx b/src/components/search-result.tsx index f18172f..7550f69 100644 --- a/src/components/search-result.tsx +++ b/src/components/search-result.tsx @@ -43,7 +43,7 @@ export function SearchResult(
{title} - {description} + {description}
{ links && links.length > 0 &&