1
0
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-12-12 20:46:52 +01:00

refactor: components struture

This commit is contained in:
2024-07-31 11:41:39 +02:00
parent ceeeb2f9c5
commit b5c50728de
72 changed files with 122 additions and 114 deletions

View File

@@ -0,0 +1,51 @@
"use client"
import Image from "next/image"
import { useMemo } from "react"
import { Link } from "../../Design/Link/Link"
import { useTheme } from "../../Layout/Header/SwitchTheme"
import type { SkillName } from "./skills"
import { skills } from "./skills"
export interface SkillItemProps {
skillName: SkillName
}
export const SkillItem: React.FC<SkillItemProps> = (props) => {
const { skillName } = props
const skill = skills[skillName]
const { theme } = useTheme()
const skillImage = useMemo(() => {
if (typeof skill.image === "string") {
return skill.image
}
if (theme === "light") {
return skill.image.light
}
return skill.image.dark
}, [skill.image, theme])
return (
<li>
<Link
href={skill.link}
className="mx-2 max-w-xl flex-col items-center justify-center text-center"
target="_blank"
isExternal={false}
>
<Image
className="inline size-16"
quality={100}
width={64}
height={64}
alt={`Logo of ${skillName}`}
src={skillImage}
/>
<p className="mt-1 font-semibold">{skillName}</p>
</Link>
</li>
)
}

View File

@@ -0,0 +1,16 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Skills as SkillsComponent } from "./Skills"
const meta = {
title: "Home/Skills",
component: SkillsComponent,
} satisfies Meta<typeof SkillsComponent>
export default meta
type Story = StoryObj<typeof meta>
export const Skills: Story = {
args: {},
}

View File

@@ -0,0 +1,45 @@
import { useTranslations } from "next-intl"
import { Section, SectionTitle } from "../../Layout/Section/Section"
import { SkillItem } from "./SkillItem"
import { SkillsSection } from "./SkillsSection"
export interface SkillsProps {}
export const Skills: React.FC<SkillsProps> = () => {
const t = useTranslations()
return (
<Section verticalSpacing horizontalSpacing id="skills">
<SectionTitle>{t("home.skills.title")}</SectionTitle>
<SkillsSection title={t("home.skills.programming-languages")}>
<SkillItem skillName="TypeScript" />
<SkillItem skillName="Python" />
<SkillItem skillName="C/C++" />
<SkillItem skillName="PHP" />
</SkillsSection>
<SkillsSection title={t("home.skills.frontend")}>
<SkillItem skillName="HTML" />
<SkillItem skillName="CSS" />
<SkillItem skillName="Tailwind CSS" />
<SkillItem skillName="React.js (+ Next.js)" />
</SkillsSection>
<SkillsSection title={t("home.skills.backend")}>
<SkillItem skillName="Laravel" />
<SkillItem skillName="Node.js" />
<SkillItem skillName="Fastify" />
<SkillItem skillName="PostgreSQL" />
</SkillsSection>
<SkillsSection title={t("home.skills.software-tools")}>
<SkillItem skillName="GNU/Linux" />
<SkillItem skillName="Arch Linux" />
<SkillItem skillName="Visual Studio Code" />
<SkillItem skillName="Git" />
<SkillItem skillName="Docker" />
</SkillsSection>
</Section>
)
}

View File

@@ -0,0 +1,25 @@
import { Typography } from "../../Design/Typography/Typography"
import { SectionContent } from "../../Layout/Section/Section"
export interface SkillsSectionProps extends React.PropsWithChildren {
title: string
}
export const SkillsSection: React.FC<SkillsSectionProps> = (props) => {
const { title, children } = props
return (
<section className="mb-12">
<SectionContent shadowContainer className="mx-auto w-full px-4 py-6">
<Typography
variant="h4"
as="h3"
className="mb-6 border-b border-black pb-3 dark:border-white"
>
{title}
</Typography>
<ul className="flex list-none flex-wrap justify-around">{children}</ul>
</SectionContent>
</section>
)
}

View File

@@ -0,0 +1,115 @@
export interface Skill {
link: string
image: string | { [key: string]: string }
}
export const skills = {
JavaScript: {
link: "https://developer.mozilla.org/docs/Web/JavaScript",
image: "/images/skills/JavaScript.webp",
},
TypeScript: {
link: "https://www.typescriptlang.org/",
image: "/images/skills/TypeScript.webp",
},
Python: {
link: "https://www.python.org/",
image: "/images/skills/Python.webp",
},
"C/C++": {
link: "https://isocpp.org/",
image: "/images/skills/C-Cpp.webp",
},
PHP: {
link: "https://www.php.net/",
image: "/images/skills/PHP.webp",
},
Laravel: {
link: "https://laravel.com/",
image: "/images/skills/Laravel.webp",
},
Dart: {
link: "https://dart.dev/",
image: "/images/skills/Dart.webp",
},
Flutter: {
link: "https://flutter.dev/",
image: "/images/skills/Flutter.webp",
},
HTML: {
link: "https://developer.mozilla.org/docs/Web/HTML",
image: "/images/skills/HTML.webp",
},
CSS: {
link: "https://developer.mozilla.org/docs/Web/CSS",
image: "/images/skills/CSS.webp",
},
"Tailwind CSS": {
link: "https://tailwindcss.com/",
image: "/images/skills/TailwindCSS.webp",
},
SASS: {
link: "https://sass-lang.com/",
image: "/images/skills/SASS.svg",
},
"React.js (+ Next.js)": {
link: "https://reactjs.org/",
image: "/images/skills/ReactJS.webp",
},
"Node.js": {
link: "https://nodejs.org/",
image: "/images/skills/NodeJS.webp",
},
Fastify: {
link: "https://www.fastify.io/",
image: {
light: "/images/skills/Fastify-light.webp",
dark: "/images/skills/Fastify-dark.webp",
},
},
Prisma: {
link: "https://www.prisma.io/",
image: {
light: "/images/skills/Prisma-light.webp",
dark: "/images/skills/Prisma-dark.webp",
},
},
PostgreSQL: {
link: "https://www.postgresql.org/",
image: "/images/skills/PostgreSQL.webp",
},
MySQL: {
link: "https://www.mysql.com/",
image: "/images/skills/MySQL.webp",
},
Strapi: {
link: "https://strapi.io/",
image: "/images/skills/Strapi.webp",
},
"Visual Studio Code": {
link: "https://code.visualstudio.com/",
image: "/images/skills/VisualStudioCode.webp",
},
Git: {
link: "https://git-scm.com/",
image: "/images/skills/Git.webp",
},
Ubuntu: {
link: "https://ubuntu.com/",
image: "/images/skills/Ubuntu.webp",
},
"Arch Linux": {
link: "https://archlinux.org/",
image: "/images/skills/ArchLinux.webp",
},
"GNU/Linux": {
link: "https://www.gnu.org/",
image: "/images/skills/GNU-Linux.webp",
},
Docker: {
link: "https://www.docker.com/",
image: "/images/skills/Docker.webp",
},
} as const
export type SkillName = keyof typeof skills