Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/kinde #4

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions actions/sendEmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export const sendEmail = async (formData: FormData) => {
let data;
try {
data = await resend.emails.send({
from: "Contact Form <[email protected]>",
to: "[email protected]",
subject: "Message from contact form",
from: "[email protected]",
to: "[email protected]",
subject: "Message from contact form - LINKE.de",
reply_to: senderEmail,
react: React.createElement(ContactFormEmail, {
message: message,
Expand Down
6 changes: 6 additions & 0 deletions app/api/auth/[kindeAuth]/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { handleAuth } from "@kinde-oss/kinde-auth-nextjs/server";

export async function GET(request, { params }) {
const endpoint = params.kindeAuth;
return handleAuth(request, endpoint);
}
14 changes: 14 additions & 0 deletions app/api/kindeSession/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// app/api/kindeSession/route.ts

import {getKindeServerSession} from "@kinde-oss/kinde-auth-nextjs/server";
import {NextResponse} from "next/server";

export async function GET() {
const {getUser, isAuthenticated, getPermissions, getOrganization} = getKindeServerSession();
const user = await getUser();
const authenticated = await isAuthenticated();
const permissions = await getPermissions();
const organization = await getOrganization();

return NextResponse.json({user, authenticated, permissions, organization});
}
Binary file modified app/favicon.ico
Binary file not shown.
39 changes: 27 additions & 12 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,38 @@ import Footer from "@/components/footer";
import ThemeSwitch from "@/components/theme-switch";
import ThemeContextProvider from "@/context/theme-context";
import { Toaster } from "react-hot-toast";

import { Analytics } from "@vercel/analytics/react";
const inter = Inter({ subsets: ["latin"] });

export const metadata = {
title: "Ricardo | Personal Portfolio",
description: "Ricardo is a full-stack developer with 8 years of experience.",
import { Metadata } from "next"; // if using TypeScript
export const metadata: Metadata = {
openGraph: {
title: "Markus | Murex Consultant",
description: "Markus is a Murex consultant with 20+ years of experience.",
url: "https://linke.de",
siteName: "Next.js",
images: [
{
url: "https://res.cloudinary.com/ddnfxz7wl/image/upload/f_auto,q_auto,w_800/v1/Linke.de/linke-website",
width: 800,
height: 600,
},
{
url: "https://res.cloudinary.com/ddnfxz7wl/image/upload/f_auto,q_auto,w_1800/v1/Linke.de/linke-website",
width: 1800,
height: 1600,
alt: "linke.de Website Screenshot",
},
],
locale: "en_US",
type: "website",
},
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className="!scroll-smooth">
<body
className={`${inter.className} bg-gray-50 text-gray-950 relative pt-28 sm:pt-36 dark:bg-gray-900 dark:text-gray-50 dark:text-opacity-90`}
>
<body className={`${inter.className} bg-gray-50 text-gray-950 relative pt-28 sm:pt-36 dark:bg-gray-900 dark:text-gray-50 dark:text-opacity-90`}>
<div className="bg-[#fbe2e3] absolute top-[-6rem] -z-10 right-[11rem] h-[31.25rem] w-[31.25rem] rounded-full blur-[10rem] sm:w-[68.75rem] dark:bg-[#946263]"></div>
<div className="bg-[#dbd7fb] absolute top-[-1rem] -z-10 left-[-35rem] h-[31.25rem] w-[50rem] rounded-full blur-[10rem] sm:w-[68.75rem] md:left-[-33rem] lg:left-[-28rem] xl:left-[-15rem] 2xl:left-[-5rem] dark:bg-[#676394]"></div>

Expand All @@ -37,6 +51,7 @@ export default function RootLayout({
<ThemeSwitch />
</ActiveSectionContextProvider>
</ThemeContextProvider>
<Analytics />
</body>
</html>
);
Expand Down
16 changes: 16 additions & 0 deletions app/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { authMiddleware } from "@kinde-oss/kinde-auth-nextjs/server";

export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!api|_next/static|_next/image|favicon.ico).*)",
],
};

export default authMiddleware;
2 changes: 2 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Intro from "@/components/intro";
import Projects from "@/components/projects";
import SectionDivider from "@/components/section-divider";
import Skills from "@/components/skills";
import UserProfile from "@/components/UserProfile";

export default function Home() {
return (
Expand All @@ -16,6 +17,7 @@ export default function Home() {
<Skills />
<Experience />
<Contact />
<UserProfile />
</main>
);
}
Binary file added app/protected/markus-linke-cv.pdf
Binary file not shown.
10 changes: 10 additions & 0 deletions app/sitemap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { MetadataRoute } from "next";

export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: "https://linke.de",
lastModified: new Date(),
},
];
}
22 changes: 22 additions & 0 deletions components/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { LogoutLink, getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { RegisterLink, LoginLink } from "@kinde-oss/kinde-auth-nextjs/server";

const UserProfile = async () => {
const { getUser, isAuthenticated } = getKindeServerSession();
const user = await getUser();
const loggedIn = await isAuthenticated();

return loggedIn ? (
<div>
<h2>{user.given_name}</h2>
<p>{user.email}</p>
<LogoutLink>Sign out</LogoutLink>
</div>
) : (
<small className="mb-2 block text-xs px-4 text-center text-gray-500">
<LoginLink>Sign in</LoginLink> or <RegisterLink>Sign up</RegisterLink>
</small>
);
};

export default UserProfile;
41 changes: 18 additions & 23 deletions components/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,29 @@ export default function About() {
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.175 }}
id="about"
>
id="about">
<SectionHeading>About me</SectionHeading>
<p className="mb-3">
After graduating with a degree in{" "}
<span className="font-medium">Accounting</span>, I decided to pursue my
passion for programming. I enrolled in a coding bootcamp and learned{" "}
<span className="font-medium">full-stack web development</span>.{" "}
<span className="italic">My favorite part of programming</span> is the
problem-solving aspect. I <span className="underline">love</span> the
feeling of finally figuring out a solution to a problem. My core stack
is{" "}
<span className="font-medium">
React, Next.js, Node.js, and MongoDB
</span>
. I am also familiar with TypeScript and Prisma. I am always looking to
learn new technologies. I am currently looking for a{" "}
<span className="font-medium">full-time position</span> as a software
developer.
With over two decades of extensive experience in the <span className="font-medium">global financial industry</span>, I have had the privilege of working with numerous major banks and financial
institutions across the world. My journey began in 1998, and since then, I have held positions at BGB, HBOS, ABN, RBC, SAC, BEAR, CS, ING, SEB, TALANX, NBC, and UOB.
</p>
<p className="mb-3">
My professional background has enabled me to serve Murex customers, including banks, hedge funds, asset managers, and insurance companies. I have also provided my expertise to consulting firms
such as Accenture and Exclian/Luxoft. Over the years, I have taken on a variety of roles, including System Architecture, Design and <span className="font-medium">Environment Management</span>,
Marketdata, Integration, Architect, EOD Refactoring, Datacenter Move, Cloud Migration, Support, <span className="font-medium">Tech Lead</span>, Scrum Master, Product Owner, Application Owner,
and Support Manager.
</p>
<p className="mb-3">
As a testament to my commitment to the Murex community, I founded the <span className="font-medium">Murex User Group</span>, which has grown into a thriving network of over 3,800 Murex
professionals worldwide. My passion for innovation and technology led me to design and develop TradeDB, a universal interface system for Murex that streamlines exchanges, trades, and static
data management. Additionally, I created MxENV, a system specifically designed to manage Murex environments, including development, testing, pre-production, and production stages. With a
proven track record in the financial sector and a strong dedication to the Murex community, I am excited to continue contributing to the growth and development of innovative financial
solutions worldwide.
</p>

<p>
<span className="italic">When I'm not coding</span>, I enjoy playing
video games, watching movies, and playing with my dog. I also enjoy{" "}
<span className="font-medium">learning new things</span>. I am currently
learning about{" "}
<span className="font-medium">history and philosophy</span>. I'm also
learning how to play the guitar.
<span className="italic">When I'm not working</span>, I enjoy travelling, watching movies, and programming. I also enjoy <span className="font-medium">learning new things</span>. I am
currently learning about <span className="font-medium">full stack development</span>.
</p>
</motion.section>
);
Expand Down
8 changes: 3 additions & 5 deletions components/contact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ export default function Contact() {
}}
viewport={{
once: true,
}}
>
}}>
<SectionHeading>Contact me</SectionHeading>

<p className="text-gray-700 -mt-6 dark:text-white/80">
Please contact me directly at{" "}
<a className="underline" href="mailto:[email protected]">
[email protected]
[email protected]
</a>{" "}
or through this form.
</p>
Expand All @@ -50,8 +49,7 @@ export default function Contact() {
}

toast.success("Email sent successfully!");
}}
>
}}>
<input
className="h-14 px-4 rounded-lg borderBlack dark:bg-white dark:bg-opacity-80 dark:focus:bg-opacity-100 transition-all dark:outline-none"
name="senderEmail"
Expand Down
13 changes: 5 additions & 8 deletions components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ import React from "react";
export default function Footer() {
return (
<footer className="mb-10 px-4 text-center text-gray-500">
<small className="mb-2 block text-xs">
&copy; 2030 Ricardo. All rights reserved.
</small>
<p className="text-xs">
<span className="font-semibold">About this website:</span> built with
React & Next.js (App Router & Server Actions), TypeScript, Tailwind CSS,
Framer Motion, React Email & Resend, Vercel hosting.
</p>
<small className="mb-2 block text-xs">&copy; 2023 Markus. All rights reserved.</small>
{/* <p className="text-xs">
<span className="font-semibold">About this website:</span> built with React & Next.js (App Router & Server Actions), TypeScript, Tailwind CSS, Framer Motion, React Email & Resend, Vercel
hosting.
</p> */}
</footer>
);
}
58 changes: 19 additions & 39 deletions components/intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ export default function Intro() {
const { setActiveSection, setTimeOfLastClick } = useActiveSectionContext();

return (
<section
ref={ref}
id="home"
className="mb-28 max-w-[50rem] text-center sm:mb-0 scroll-mt-[100rem]"
>
<section ref={ref} id="home" className="mb-28 max-w-[50rem] text-center sm:mb-0 scroll-mt-[100rem]">
<div className="flex items-center justify-center">
<div className="relative">
<motion.div
Expand All @@ -28,11 +24,11 @@ export default function Intro() {
transition={{
type: "tween",
duration: 0.2,
}}
>
}}>
<Image
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?fit=crop&w=368&h=368&q=100"
alt="Ricardo portrait"
// src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?fit=crop&w=368&h=368&q=100"
src="https://res.cloudinary.com/ddnfxz7wl/image/upload/q_auto/f_auto/w_368/h_368/v1696167175/Linke.de/markus.jpg"
alt="Markus portrait"
width="192"
height="192"
quality="95"
Expand All @@ -50,23 +46,15 @@ export default function Intro() {
stiffness: 125,
delay: 0.1,
duration: 0.7,
}}
>
}}>
👋
</motion.span>
</div>
</div>

<motion.h1
className="mb-10 mt-4 px-4 text-2xl font-medium !leading-[1.5] sm:text-4xl"
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
>
<span className="font-bold">Hello, I'm Ricardo.</span> I'm a{" "}
<span className="font-bold">full-stack developer</span> with{" "}
<span className="font-bold">8 years</span> of experience. I enjoy
building <span className="italic">sites & apps</span>. My focus is{" "}
<span className="underline">React (Next.js)</span>.
<motion.h1 className="mb-10 mt-4 px-4 text-2xl font-medium !leading-[1.5] sm:text-4xl" initial={{ opacity: 0, y: 100 }} animate={{ opacity: 1, y: 0 }}>
<span className="font-bold">Hello, I'm Markus.</span> I'm a <span className="font-bold">Murex Consultant</span> with <span className="font-bold">20+ years</span> of experience. I enjoy
managing <span className="italic">complex applications and environments</span>. My focus is on all technical aspects of a <span className="underline">Murex implementation</span>.
</motion.h1>

<motion.div
Expand All @@ -75,42 +63,34 @@ export default function Intro() {
animate={{ opacity: 1, y: 0 }}
transition={{
delay: 0.1,
}}
>
}}>
<Link
href="#contact"
className="group bg-gray-900 text-white px-7 py-3 flex items-center gap-2 rounded-full outline-none focus:scale-110 hover:scale-110 hover:bg-gray-950 active:scale-105 transition"
onClick={() => {
setActiveSection("Contact");
setTimeOfLastClick(Date.now());
}}
>
Contact me here{" "}
<BsArrowRight className="opacity-70 group-hover:translate-x-1 transition" />
}}>
Contact me here <BsArrowRight className="opacity-70 group-hover:translate-x-1 transition" />
</Link>

<a
className="group bg-white px-7 py-3 flex items-center gap-2 rounded-full outline-none focus:scale-110 hover:scale-110 active:scale-105 transition cursor-pointer borderBlack dark:bg-white/10"
href="/CV.pdf"
download
>
Download CV{" "}
<HiDownload className="opacity-60 group-hover:translate-y-1 transition" />
href="/markus-linke-cv.pdf"
download>
Download CV <HiDownload className="opacity-60 group-hover:translate-y-1 transition" />
</a>

<a
className="bg-white p-4 text-gray-700 hover:text-gray-950 flex items-center gap-2 rounded-full focus:scale-[1.15] hover:scale-[1.15] active:scale-105 transition cursor-pointer borderBlack dark:bg-white/10 dark:text-white/60"
href="https://linkedin.com"
href="https://linkedin.com/in/linke"
target="_blank"
>
download>
<BsLinkedin />
</a>

<a
className="bg-white p-4 text-gray-700 flex items-center gap-2 text-[1.35rem] rounded-full focus:scale-[1.15] hover:scale-[1.15] hover:text-gray-950 active:scale-105 transition cursor-pointer borderBlack dark:bg-white/10 dark:text-white/60"
href="https://github.com"
target="_blank"
>
href="https://github.com/linmar"
target="_blank">
<FaGithubSquare />
</a>
</motion.div>
Expand Down
Loading