Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/experiences/acmLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/experiences/ucrLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions public/experiences/ucrLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/experiences/ucrLogo.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions src/app/components/ErrorMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Link from "next/link";

interface ErrorMessage {
description: string;
}
const ErrorMessage = ({ description }: ErrorMessage) => {
return (
<div className="flex h-[80vh] flex-col items-center justify-center">
{description}
<Link
href="/"
className="rounded-md border-2 border-black bg-gray-200 p-2"
>
Please Return Home
</Link>
</div>
);
};
export default ErrorMessage;
56 changes: 56 additions & 0 deletions src/app/components/Experience.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"use client";

import Image, { StaticImageData } from "next/image";

interface DescriptionEntry {
description: string;
}

interface ExperienceEntry {
name: string;
date: string;
description: DescriptionEntry[];
}

interface experienceProps {
image: StaticImageData;
name: string;
entries: ExperienceEntry[];
}

const Experience = ({ image, name, entries }: experienceProps) => {
return (
<div className="mx-auto w-2/3">
<div className="flex w-full flex-row gap-4">
<div className="w-1/6">
<p className="text-center text-3xl font-bold">{name}</p>
<Image
src={image}
alt={name}
className="mx-auto aspect-square w-2/3 rounded-2xl shadow-xl"
/>
</div>
<div className="border-gray w-5/6 justify-center border-l-2">
{entries.map(({ name, date, description }, i) => (
<div key={i} className="relative flex flex-row py-2">
<div className="absolute -left-1.5 top-4 h-3 w-3 rounded-full bg-gray-500" />
<div className="mx-4">
<div className="flex flex-row justify-evenly">
<p className="mr-auto text-lg underline">{name}</p>
<p className="ml-auto text-gray-500">{date}</p>
</div>
<div>
{description.map(({ description }, i) => (
<p key={i}>{description}</p>
))}
</div>
</div>
</div>
))}
</div>
</div>
</div>
);
};

export default Experience;
19 changes: 19 additions & 0 deletions src/app/components/Experiences.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Header from "@/app/components/Header";
import Experience from "@/app/components/Experience";
import experienceItems from "@/data/ExperienceData";

const Experiences = () => {
return (
<div>
<Header title={"Experiences"} />
<div className="flex w-full flex-row flex-wrap justify-center">
{experienceItems.map(({ image, name, entries }, i) => (
<div key={i} className="w-full py-8">
<Experience image={image} name={name} entries={entries} />
</div>
))}
</div>
</div>
);
};
export default Experiences;
26 changes: 25 additions & 1 deletion src/app/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
"use client";
import { useEffect, useState } from "react";

const Footer = () => {
return <div className="w-full py-8 text-center">© Kevin Loritsch</div>;
const [lastCommit, setLastCommit] = useState<string | null>(null);
useEffect(() => {
const fetchCommits = async () => {
try {
const res = await fetch(
"https://api.github.com/repos/Kevinloritsch/kevinloritsch.github.io",
);
const data = await res.json();
setLastCommit(data.updated_at);
} catch (err) {
console.error("Failed to fetch last commit: ", err);
}
};
fetchCommits();
}, []);

return (
<div className="border-gray mx-auto h-[10vh] w-2/3 border-t-2 py-8 text-center">
<div className="pt-2 text-center">© Kevin Loritsch</div>
<div>Last updated at: {lastCommit}</div>
</div>
);
};
export default Footer;
2 changes: 1 addition & 1 deletion src/app/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const hoverAnimation = {

const Navbar = () => {
return (
<div className="mx-8 flex h-[10vh] justify-evenly">
<div className="fixed left-0 top-0 z-50 flex h-[10vh] justify-evenly bg-white px-8 shadow-xl">
<div className="flex w-1/2 flex-row items-center gap-4 text-left">
<Image src={profilePicture} alt="Kevin Loritsch" className="w-1/12" />
<p className="font-bold">Kevin Loritsch</p>
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface projectProps {
description: string;
}

const Projects = ({ image, title, description }: projectProps) => {
const Project = ({ image, title, description }: projectProps) => {
return (
<div className="mx-8">
<p className="text-center text-xl font-bold">{title}</p>
Expand Down Expand Up @@ -50,4 +50,4 @@ const Projects = ({ image, title, description }: projectProps) => {
);
};

export default Projects;
export default Project;
3 changes: 2 additions & 1 deletion src/app/error.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use client";
import ErrorMessage from "@/app/components/ErrorMessage";

const Error = () => {
return <div>Error</div>;
return <ErrorMessage description={"500 Error Not Found"} />;
};

export default Error;
4 changes: 3 additions & 1 deletion src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import ErrorMessage from "@/app/components/ErrorMessage";

const NotFound = () => {
return <div>fix this before you fix the meowing</div>;
return <ErrorMessage description={"404 Page Not Found"} />;
};

export default NotFound;
2 changes: 2 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"use client";
import Landing from "@/app/components/Landing";
import About from "@/app/components/About";
import Experiences from "@/app/components/Experiences";
import Projects from "@/app/components/Projects";

const Home = () => {
return (
<div>
<Landing />
<About />
<Experiences />
<Projects />
</div>
);
Expand Down
122 changes: 122 additions & 0 deletions src/data/ExperienceData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { StaticImageData } from "next/image";
import ACMLogo from "@/public/experiences/acmLogo.png";
import UCRLogo from "@/public/experiences/ucrLogo.png";

interface DescriptionEntry {
description: string;
}

interface ExperienceEntry {
name: string;
date: string;
description: DescriptionEntry[];
}

interface ExperienceItem {
image: StaticImageData;
name: string;
entries: ExperienceEntry[];
}

const experienceItems: ExperienceItem[] = [
{
image: UCRLogo,
name: "UCR",
entries: [
{
name: "Computer Science Education Research Assistant",
date: "May 2025 - Present",
description: [
{
description:
"• Authored abstract and poster presentation analyzing 500+ student-created study sheets to assess impact on learning outcomes and academic performance",
},
{
description:
"• Engineered end-to-end data pipeline using Python, Pandas, Matplotlib, and Scikit-Learn to extract, clean, and analyze study behaviors",
},
{
description:
"• Collaborated on research methodology design, defining classification schema for categorizing study materials",
},
],
},
{
name: "Undergraduate Learning Assistant",
date: "Oct 2024 - Present",
description: [
{
description:
"• Facilitated instruction in foundational C++ courses through weekly labs and 1:1 tutoring, reinforcing concepts in pointers, data structures, and debugging",
},
{
description:
"• Delivered 12+ hours/week of student support, improving retention and performance for classes of 100+ students",
},
{
description:
"• Enhanced programming proficiency by guiding students through coding assignments and debugging strategies",
},
],
},
{
name: "Data Structures and Algorithms Grader",
date: "Oct 2024 - Present",
description: [
{
description:
"• Evaluated 13+ programming assignments for 500+ students in C++ data structures and algorithms",
},
{
description:
"• Held weekly office hours to clarify core concepts such as B-Trees, graph theory, and asymptotic analysis",
},
{
description:
"• Managed 5-person dev team building a class learning platform, from Figma prototype to deployment",
},
],
},
],
},
{
image: ACMLogo,
name: "ACM@UCR",
entries: [
{
name: "Spark Lead",
date: "June 2024 - Present",
description: [
{
description:
"• Directed front end development projects, coordinating with on campus organizations to transform design",
},
{
description:
"• Led teams of 10+ students as Scrum Master, facilitating sprint planning, code reviews, and AGILE development",
},
{
description:
"• Delivered production-ready websites using React, Tailwind, and HTML",
},
],
},
{
name: "VP External Affairs",
date: "May 2025 - Present",
description: [
{
description:
"• Launched outreach initiatives including weekly tabling, coding workshops, and mentorship programs",
},
{
description:
"• Designed peer mentorship program pairing 25+ first-year students with experienced ACM mentors",
},
],
},
],
},
];

export default experienceItems;
Loading