Skip to content

Commit

Permalink
update cv
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrenker committed Dec 5, 2023
1 parent 6306df0 commit 2018664
Show file tree
Hide file tree
Showing 14 changed files with 6,702 additions and 1,744 deletions.
2 changes: 2 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
},
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.398.0",
"@headlessui/react": "^1.7.17",
"@tabler/icons-react": "^2.42.0",
"@tailwindcss/aspect-ratio": "0.4.2",
"@tailwindcss/container-queries": "0.1.1",
"@tailwindcss/forms": "0.5.6",
Expand Down
43 changes: 43 additions & 0 deletions apps/web/src/app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { NextPage } from 'next';
import { SkillBar } from '../../components/SkillBar';

const AboutPage: NextPage= () => {
return (
<div className="container mx-auto p-4">
<h2 className="mb-6 text-center text-3xl font-bold">Empowering Your Projects with Expertise and Innovation</h2>

<div className="grid gap-4 md:grid-cols-2">

<div className="service-card rounded-lg border p-4 shadow-md transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold">Clean Web Development</h3>
<p>Specializing in creating scalable, maintainable web applications with a focus on clean code and efficient design. Experience in JavaScript, TypeScript, Node.js, React, and more, ensuring your projects are built with the latest and most reliable technologies.</p>
</div>

<div className="service-card rounded-lg border p-4 shadow-md transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold">Coaching</h3>
<p>Providing mentorship and guidance to development teams, focusing on skill enhancement, clean code practices, and efficient workflows. My approach to coaching is tailored to boost team capabilities and foster a culture of continuous learning and improvement.</p>
</div>

<div className="service-card rounded-lg border p-4 shadow-md transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold">Automation</h3>
<p>Advocating for robust automation strategies in development processes. Specialized in implementing CI/CD pipelines and infrastructure as code using AWS CDK, enhancing efficiency, reducing errors, and accelerating deployment cycles.</p>
</div>

<div className="service-card rounded-lg border p-4 shadow-md transition-shadow hover:shadow-lg">
<h3 className="mb-2 text-xl font-semibold">Agile Processes</h3>
<p>Expertise in optimizing agile methodologies for software development. Skilled in roles like Scrum Master and aiding in backlog maintenance, I help teams adopt true agility, improving software quality and delivery speed.</p>
</div>
</div>

<div>

<SkillBar level={70} skill="HTML" />
<SkillBar level={80} skill="CSS" />
<SkillBar level={90} skill="JavaScript" />

</div>
</div>
)
}

export default AboutPage;
2 changes: 1 addition & 1 deletion apps/web/src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import clsx from 'clsx';
import React, { Fragment } from 'react';
import type { SlateNode } from '../../../components/SlateRender';
import { SlateRender } from '../../../components/SlateRender';
import { getPost } from '../../../lib/blog/client';
import { getPost } from '../../../lib/hygraph/client';

export interface BlogPostPageProps {
params: {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NextPage } from 'next';
import Link from 'next/link';
import { getPosts } from '../../lib/blog/client';
import { getPosts } from '../../lib/hygraph/client';
import { formatBlogDateShort } from '../../lib/intl';
import type { SlateNode} from '../../components/SlateRender';
import { SlateRender } from '../../components/SlateRender';
Expand Down
18 changes: 18 additions & 0 deletions apps/web/src/app/cv/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable import/namespace -- in a hurry deploy */
/* eslint-disable @typescript-eslint/no-unsafe-assignment -- in a hurry deploy */
import React from 'react';
import * as icons from '@tabler/icons-react'

export interface IconProps {
name: string;
}

export const Icon: React.FC<IconProps> = ({name}) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- in a hurry deploy
// @ts-expect-error
const IconComponent = icons[`Icon${name}`];
if (!IconComponent) {
return null;
}
return <IconComponent />;
};
179 changes: 179 additions & 0 deletions apps/web/src/app/cv/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/* eslint-disable -- deploy */
import type { NextPage } from 'next';
import clsx from 'clsx';
import Image from 'next/image';
import { getProjects, getTechnologies } from '../../lib/hygraph/client';
import type { SlateNode} from '../../components/SlateRender';
import { SlateRender } from '../../components/SlateRender';
import { Icon } from './Icon';
import type { GetTechnologiesQuery } from '@/lib/hygraph/generated';

type Technology = GetTechnologiesQuery['technologies'][0];

const sortByProficiency = (a: Technology, b: Technology): number => {
const order = ['expert', 'advanced', 'intermediate', 'beginner'];
return order.indexOf(a.proficiency?.toLowerCase() ?? '') - order.indexOf(b.proficiency?.toLowerCase() ?? '');
}

const CVPage: NextPage = async () => {
const projects = await getProjects();
const technologies = await getTechnologies();
return (
<div className="prose container mx-auto [&_h2]:m-0 [&_h3]:m-0 [&_p]:m-0">
<section className="flex break-inside-avoid flex-wrap gap-4">
<figure className={clsx([
'm-0 text-center',
'print:flex print:gap-16 print:text-start',
])}
>
<picture className={clsx([
'inline-block h-[200px] overflow-hidden rounded-full ring ring-zinc-900 dark:ring-zinc-50',
'print:h-auto print:rounded-none print:ring-0',
])}
>
<Image
alt="Profile picture of Martin Trenker, consultant and web developer"
className="m-0"
height={200}
src="/me.png"
unoptimized
width={200}
/>
</picture>
<figcaption className="flex flex-col gap-4">
<h1
className={clsx([
'm-0 text-3xl font-semibold',
])}
>
Hi, my name is Martin.
</h1>
<h2 className={clsx([
'm-0 text-2xl',
])}
>
I&apos;m a web development expert based in Munich.
</h2>
</figcaption>
</figure>
<p>
As a teenager, I became interested in creating websites and engaging with the developer community. This was during the early stages of the Internet and the Web. In those days, table designs and frames were the norm, and I became an advocate for accessible and semantic markup and CSS.
</p>
<p>
Shortly after successfully finishing my apprenticeship for IT-System-Kaufmann at Deutsche Telekom, I decided to take the leap and start my own consulting business.
</p>
<p>
Since 2008, I have had the pleasure of working with a diverse mix of teams on various products, and I strive to share my insights and experiences with clients and their teams. My goal is to enable developers to create web solutions that are quick to deliver, easy to maintain, and fun to work with.
</p>
<article>
<h3>Clean Code</h3>
<p>
Technical debt costs time, money, talent, motivation, and morale. Clean code is the foundation for a maintainable and sustainable codebase, and I can help teams identify the right tools and processes to achieve this.
</p>
</article>
<article>
<h3>Agile Mindset</h3>
<p>
Allowing teams to self-organize and become autonomous is the secret of high performers. With my experience in agile methodologies, I can help teams to overcome obstacles and excel in their work.
</p>
</article>
<article>
<h3>Automation</h3>
<p>
Knowing what and when to automate can sometimes be the difference between success and failure. I have experienced many successes and failures and want to share the lessons with my peers.
</p>
</article>
<article>
<h3>Coach and Mentor</h3>
<p>
There are no shortcuts to experience, but there are ways to accelerate the learning process. I can support teams in adopting a learning culture that allows personal and team growth without sacrificing output.
</p>
</article>
</section>
<section className="break-inside-avoid break-after-page py-10">
<h2 className="!mb-5">Methodologies</h2>
<h3>Scrum / Kanban</h3>
<p className="!mb-5">
Having worked with Scrum since 2008, I often filled in for scrum-master or was a valued sparing partner for scrum-masters.
Optimizing processes and observing the theory of constraints play out in various ways depending on project and team dynamics is something I genuinely enjoy and am eager to continue developing with my clients.
</p>
<h2 className="!mb-5">Technologies</h2>
<div className="flex flex-wrap items-center justify-evenly gap-2">
{technologies.sort(sortByProficiency).map((technology) => (
<div
className="flex grow items-center gap-2 rounded border border-zinc-900 px-2 py-1 print:p-1"
key={technology.name}
>
<Icon name={technology.iconName!} />
<div>
<h4 className="m-0 flex-initial font-semibold">
{technology.name}
</h4>
<p className="m-0 flex-initial text-sm">
{technology.proficiency}
</p>
</div>
</div>
))}
</div>
</section>
<section>
<h2>Projects</h2>
{projects.reverse().map((project) => {
const overview: SlateNode[] = project.overview?.raw.children ?? [];
const details: SlateNode[] = project.details?.raw.children ?? [];
const startYear = new Date(project.startDate as string).getFullYear();
const endYear = new Date(project.endDate as string).getFullYear();
return (
<article
className={clsx(
'my-4 flex break-inside-avoid flex-col p-10',
)}
key={project.id }
>
<h3 className="m-0 flex-initial font-semibold">
{project.title}
</h3>
<div className="flex items-center justify-between gap-6">
<h4 className="m-0 flex-initial font-semibold">
{project.client?.name}
</h4>
<hr className="my-0 block h-px w-full flex-1 border-b border-zinc-700 print:border-zinc-900" />
<time dateTime={`${new Date(project.startDate as string).getFullYear()}`}>
{startYear === endYear ? startYear : `${startYear} - ${endYear}`}
</time>
</div>
<h5 className="m-0 font-semibold uppercase tracking-widest">
{project.role}
</h5>
<SlateRender value={overview} />
<SlateRender value={details} />
{project.technologies.length > 0 && (
<>
<h6 className="font-bold">Technologies</h6>
<div className="flex flex-wrap gap-2">
{project.technologies.map((technology) => (
<span
className={clsx(
'flex items-center gap-2',
'rounded-md bg-zinc-900 px-2 py-1 text-sm text-zinc-50',
'print:px-1 print:text-black'
)}
key={technology.name}
>
<Icon name={technology.iconName as string} />
{technology.name}
</span>
))}
</div>
</>
)}
</article>
);
})}
</section>
</div>
)
}

export default CVPage;
14 changes: 10 additions & 4 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,22 @@ const Home: React.FC = () => (
return (
<article className="my-4 flex break-inside-avoid flex-col" key={project.id}>
<div className="flex items-center justify-between gap-6">
<h4 className="m-0 flex-initial font-semibold">{project.company ? project.company : project.industry}</h4>
<h4 className="m-0 flex-initial font-semibold">
{project.company ? project.company : project.industry?.en}
</h4>
<hr className="my-0 block h-px w-full flex-1 border-b border-zinc-700 print:border-zinc-900" />
<time dateTime={`${new Date(project.startDate).getFullYear()}`}>
{startYear === endYear ? startYear : `${startYear} - ${endYear}`}
</time>
</div>
<h5 className="m-0 font-semibold uppercase tracking-widest">{project.title}</h5>
<p className="m-0 flex-1 tracking-wide">{project.description}</p>
<h5 className="m-0 font-semibold uppercase tracking-widest">
{project.title.en}
</h5>
<p className="m-0 flex-1 tracking-wide">
{project.description.en}
</p>
<ul className="m-2 pl-4">
{project.highlights.length > 0 && project.highlights.map((highlight) => (
{project.highlights.en.length > 0 && project.highlights.en.map((highlight) => (
<li className="my-0 tracking-wide" key={highlight}>{highlight}</li>
))}
</ul>
Expand Down

0 comments on commit 2018664

Please sign in to comment.