diff --git a/package-lock.json b/package-lock.json index 946dff1..14df2e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "react-dom": "~18.3.1", "react-icons": "^5.5.0", "react-loading": "^2.0.3", + "react-scroll": "^1.9.3", "react-scroll-parallax": "^3.4.5", "react-type-animation": "^3.2.0" }, @@ -27,6 +28,7 @@ "@types/node": "~22.1.0", "@types/react": "~18.3.3", "@types/react-dom": "~18.3.0", + "@types/react-scroll": "^1.8.10", "@typescript-eslint/eslint-plugin": "~8.0.0", "@typescript-eslint/parser": "~8.0.0", "autoprefixer": "~10.4.19", @@ -1019,6 +1021,16 @@ "@types/react": "*" } }, + "node_modules/@types/react-scroll": { + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/@types/react-scroll/-/react-scroll-1.8.10.tgz", + "integrity": "sha512-RD4Z7grbdNGOKwKnUBKar6zNxqaW3n8m9QSrfvljW+gmkj1GArb8AFBomVr6xMOgHPD3v1uV3BrIf01py57daQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", @@ -4025,6 +4037,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5032,6 +5050,20 @@ "react": ">=0.14.0" } }, + "node_modules/react-scroll": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/react-scroll/-/react-scroll-1.9.3.tgz", + "integrity": "sha512-xv7FXqF3k63aSLNu4/NjFvRNI0ge7DmmmsbeGarP7LZVAlJMSjUuW3dTtLxp1Afijyv0lS2qwC0GiFHvx1KBHQ==", + "license": "MIT", + "dependencies": { + "lodash.throttle": "^4.1.1", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^15.5.4 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^15.5.4 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-scroll-parallax": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/react-scroll-parallax/-/react-scroll-parallax-3.4.5.tgz", diff --git a/package.json b/package.json index fa42be9..c33278e 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "react-dom": "~18.3.1", "react-icons": "^5.5.0", "react-loading": "^2.0.3", + "react-scroll": "^1.9.3", "react-scroll-parallax": "^3.4.5", "react-type-animation": "^3.2.0" }, @@ -31,6 +32,7 @@ "@types/node": "~22.1.0", "@types/react": "~18.3.3", "@types/react-dom": "~18.3.0", + "@types/react-scroll": "^1.8.10", "@typescript-eslint/eslint-plugin": "~8.0.0", "@typescript-eslint/parser": "~8.0.0", "autoprefixer": "~10.4.19", diff --git a/public/Cloud1.png b/public/Cloud1.png deleted file mode 100644 index d51b19a..0000000 Binary files a/public/Cloud1.png and /dev/null differ diff --git a/public/Cloud2.png b/public/Cloud2.png deleted file mode 100644 index a2251f0..0000000 Binary files a/public/Cloud2.png and /dev/null differ diff --git a/public/Cloud3.png b/public/Cloud3.png deleted file mode 100644 index 34e2530..0000000 Binary files a/public/Cloud3.png and /dev/null differ diff --git a/public/KevinLoritsch_Resume.pdf b/public/KevinLoritsch_Resume.pdf new file mode 100644 index 0000000..aec2d6a Binary files /dev/null and b/public/KevinLoritsch_Resume.pdf differ diff --git a/public/backgroundLanding.svg b/public/backgroundLanding.svg deleted file mode 100644 index b456c17..0000000 --- a/public/backgroundLanding.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/public/experiences/acmLogo.png b/public/experiences/acmLogo.png deleted file mode 100644 index 35e478d..0000000 Binary files a/public/experiences/acmLogo.png and /dev/null differ diff --git a/public/experiences/acmLogo.webp b/public/experiences/acmLogo.webp new file mode 100644 index 0000000..3a6bfc3 Binary files /dev/null and b/public/experiences/acmLogo.webp differ diff --git a/public/experiences/ucrLogo.png b/public/experiences/ucrLogo.png deleted file mode 100644 index 33151cb..0000000 Binary files a/public/experiences/ucrLogo.png and /dev/null differ diff --git a/public/experiences/ucrLogo.svg b/public/experiences/ucrLogo.svg deleted file mode 100644 index a2c9f63..0000000 --- a/public/experiences/ucrLogo.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/public/experiences/ucrLogo.webp b/public/experiences/ucrLogo.webp index d58982d..885b0e5 100644 Binary files a/public/experiences/ucrLogo.webp and b/public/experiences/ucrLogo.webp differ diff --git a/public/landingMountains.svg b/public/landingMountains.svg deleted file mode 100644 index 323c1fa..0000000 --- a/public/landingMountains.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/projects/aviatr.png b/public/projects/aviatr.png deleted file mode 100644 index fa037f6..0000000 Binary files a/public/projects/aviatr.png and /dev/null differ diff --git a/public/projects/aviatr.webp b/public/projects/aviatr.webp new file mode 100644 index 0000000..6aad08e Binary files /dev/null and b/public/projects/aviatr.webp differ diff --git a/public/projects/chess.png b/public/projects/chess.png deleted file mode 100644 index 78b0372..0000000 Binary files a/public/projects/chess.png and /dev/null differ diff --git a/public/projects/chess.webp b/public/projects/chess.webp new file mode 100644 index 0000000..2eb8711 Binary files /dev/null and b/public/projects/chess.webp differ diff --git a/public/projects/finalTake.png b/public/projects/finalTake.png deleted file mode 100644 index 60d40dc..0000000 Binary files a/public/projects/finalTake.png and /dev/null differ diff --git a/public/projects/finalTake.webp b/public/projects/finalTake.webp new file mode 100644 index 0000000..770b989 Binary files /dev/null and b/public/projects/finalTake.webp differ diff --git a/public/projects/leap.png b/public/projects/leap.png deleted file mode 100644 index 6b4f5e3..0000000 Binary files a/public/projects/leap.png and /dev/null differ diff --git a/public/projects/leap.webp b/public/projects/leap.webp new file mode 100644 index 0000000..adcfb9a Binary files /dev/null and b/public/projects/leap.webp differ diff --git a/public/projects/ptso.png b/public/projects/ptso.png deleted file mode 100644 index 909f1d7..0000000 Binary files a/public/projects/ptso.png and /dev/null differ diff --git a/public/projects/ptso.webp b/public/projects/ptso.webp new file mode 100644 index 0000000..73bd265 Binary files /dev/null and b/public/projects/ptso.webp differ diff --git a/public/projects/squareRoot.png b/public/projects/squareRoot.png deleted file mode 100644 index 32265f4..0000000 Binary files a/public/projects/squareRoot.png and /dev/null differ diff --git a/public/projects/squareRoot.webp b/public/projects/squareRoot.webp new file mode 100644 index 0000000..36c9427 Binary files /dev/null and b/public/projects/squareRoot.webp differ diff --git a/public/projects/tree.png b/public/projects/tree.png deleted file mode 100644 index d07d92d..0000000 Binary files a/public/projects/tree.png and /dev/null differ diff --git a/public/projects/tree.webp b/public/projects/tree.webp new file mode 100644 index 0000000..8a0668a Binary files /dev/null and b/public/projects/tree.webp differ diff --git a/public/projects/ula.png b/public/projects/ula.png deleted file mode 100644 index 1688d75..0000000 Binary files a/public/projects/ula.png and /dev/null differ diff --git a/public/projects/ula.webp b/public/projects/ula.webp new file mode 100644 index 0000000..3b9808d Binary files /dev/null and b/public/projects/ula.webp differ diff --git a/src/app/components/Experiences.tsx b/src/app/components/Experiences.tsx index 9611b6d..b844657 100644 --- a/src/app/components/Experiences.tsx +++ b/src/app/components/Experiences.tsx @@ -1,10 +1,11 @@ import Header from "@/app/components/Header"; import Experience from "@/app/components/Experience"; import experienceItems from "@/data/ExperienceData"; +import { Element } from "react-scroll"; const Experiences = () => { return ( -
+
{experienceItems.map(({ image, name, entries }, i) => ( @@ -13,7 +14,7 @@ const Experiences = () => {
))}
- + ); }; export default Experiences; diff --git a/src/app/components/Footer.tsx b/src/app/components/Footer.tsx index d8e485f..0d73755 100644 --- a/src/app/components/Footer.tsx +++ b/src/app/components/Footer.tsx @@ -20,8 +20,8 @@ const Footer = () => { return (
-
© Kevin Loritsch
-
Last updated at: {lastCommit}
+

© Kevin Loritsch

+

Last updated at: {lastCommit}

); }; diff --git a/src/app/components/Landing.tsx b/src/app/components/Landing.tsx index 0e7f961..34233a8 100644 --- a/src/app/components/Landing.tsx +++ b/src/app/components/Landing.tsx @@ -1,6 +1,7 @@ "use client"; import Image from "next/image"; import Link from "next/link"; +import { Element } from "react-scroll"; import profilePicture from "@/public/profilePicture.webp"; @@ -9,28 +10,47 @@ import { socialLinks } from "@/data/SocialData"; const Landing = () => { return (
-
-
-
-

- Kevin Loritsch -

-

UCR Student and Software Engineer

- {socialLinks.map(({ link, icon: Icon }, i) => ( - - - - ))} + +
+
+
+

+ Kevin Loritsch +

+ +
+ {socialLinks.map(({ link, icon: Icon }, i) => ( + + + + ))} +
+

+ Hi! My name is Kevin, and I am a Computer Science student at UC + Riverside (Chancellor's Scholar, 4.0 GPA) with experience in + software engineering, research, and teaching. +

+

+ I'm interested in exploring work in algorithm design, AI, + research, and teaching. +

+
+
+ Kevin Loritsch +
- Kevin Loritsch
-
+
); }; diff --git a/src/app/components/Navbar.tsx b/src/app/components/Navbar.tsx index 4807863..a7a56f4 100644 --- a/src/app/components/Navbar.tsx +++ b/src/app/components/Navbar.tsx @@ -1,10 +1,11 @@ "use client"; import { motion } from "motion/react"; - -import Image from "next/image"; +import { Link as ScrollLink } from "react-scroll"; import Link from "next/link"; -import navbarItems from "@/data/NavbarData"; +import { useState, useEffect } from "react"; +import Image from "next/image"; +import navbarItems from "@/data/NavbarData"; import profilePicture from "@/public/profilePicture.webp"; const fadeIn = (delay = 0) => ({ @@ -20,18 +21,50 @@ const hoverAnimation = { }, }; +const use10vhAsPixels = () => { + const [pixels, setPixels] = useState(0); + + useEffect(() => { + const calculatePixels = () => { + const viewportHeight = window.innerHeight; + setPixels((viewportHeight / 100) * 10); + }; + + calculatePixels(); + window.addEventListener("resize", calculatePixels); + + return () => { + window.removeEventListener("resize", calculatePixels); + }; + }, []); + + return pixels; +}; + const Navbar = () => { + const pixels = use10vhAsPixels(); + return ( -
-
+
+ Kevin Loritsch

Kevin Loritsch

-
-
+ +
{navbarItems.map(({ name, link }, i) => ( - {name} + + {name} + ))} @@ -39,4 +72,5 @@ const Navbar = () => {
); }; + export default Navbar; diff --git a/src/app/components/Project.tsx b/src/app/components/Project.tsx index 20f002a..7971672 100644 --- a/src/app/components/Project.tsx +++ b/src/app/components/Project.tsx @@ -2,14 +2,29 @@ import Image, { StaticImageData } from "next/image"; import { motion } from "motion/react"; +import { IconType } from "react-icons"; + +interface techEntry { + icon: IconType; +} interface projectProps { image: StaticImageData; title: string; description: string; + date: string; + role: string; + techStack?: techEntry[]; } -const Project = ({ image, title, description }: projectProps) => { +const Project = ({ + image, + title, + description, + date, + role, + techStack, +}: projectProps) => { return (

{title}

@@ -39,12 +54,23 @@ const Project = ({ image, title, description }: projectProps) => { initial={{ opacity: 0 }} whileHover={{ opacity: 1 }} > -

{description}

+
+

{date}

+

{description}

+
-
Tech Stack
-
Role on Project
+
+ {techStack && + techStack.map(({ icon: Icon }, i) => ( +
+ +
+ ))} +
+ +
{role}
); diff --git a/src/app/components/Projects.tsx b/src/app/components/Projects.tsx index b4d7c32..6b3874f 100644 --- a/src/app/components/Projects.tsx +++ b/src/app/components/Projects.tsx @@ -1,22 +1,32 @@ import Header from "@/app/components/Header"; import Project from "@/app/components/Project"; import projectItems from "@/data/ProjectsData"; +import { Element } from "react-scroll"; const Projects = () => { return ( -
+
- {projectItems.map(({ image, title, description }, i) => ( -
- -
- ))} + {projectItems.map( + ({ image, title, date, description, role, techStack }, i) => ( +
+ +
+ ), + )}
-
+ ); }; export default Projects; diff --git a/src/data/ExperienceData.ts b/src/data/ExperienceData.ts index f0924eb..a474b42 100644 --- a/src/data/ExperienceData.ts +++ b/src/data/ExperienceData.ts @@ -1,6 +1,6 @@ import { StaticImageData } from "next/image"; -import ACMLogo from "@/public/experiences/acmLogo.png"; -import UCRLogo from "@/public/experiences/ucrLogo.png"; +import ACMLogo from "@/public/experiences/acmLogo.webp"; +import UCRLogo from "@/public/experiences/ucrLogo.webp"; interface DescriptionEntry { description: string; diff --git a/src/data/NavbarData.ts b/src/data/NavbarData.ts index 3ec438f..a2fc82b 100644 --- a/src/data/NavbarData.ts +++ b/src/data/NavbarData.ts @@ -4,10 +4,10 @@ interface navbarItem { } const navbarItems: navbarItem[] = [ - { name: "ABOUT ME", link: "/" }, - { name: "EXPERIENCE", link: "/meow" }, - { name: "PROJECTS", link: "/meow" }, - { name: "SKILLS", link: "/meow" }, + { name: "ABOUT ME", link: "home" }, + { name: "EXPERIENCE", link: "experiences" }, + { name: "PROJECTS", link: "projects" }, + // { name: "SKILLS", link: "experience" }, ]; export default navbarItems; diff --git a/src/data/ProjectsData.ts b/src/data/ProjectsData.ts index cf16538..8065c37 100644 --- a/src/data/ProjectsData.ts +++ b/src/data/ProjectsData.ts @@ -1,67 +1,240 @@ import { StaticImageData } from "next/image"; -import ULA from "@/public/projects/ula.png"; -import Tree from "@/public/projects/tree.png"; -import FinalTake from "@/public/projects/finalTake.png"; -import PTSO from "@/public/projects/ptso.png"; -import Chess from "@/public/projects/chess.png"; -import AviatR from "@/public/projects/aviatr.png"; -import Leap from "@/public/projects/leap.png"; -import SquareRoot from "@/public/projects/squareRoot.png"; +import ULA from "@/public/projects/ula.webp"; +import Tree from "@/public/projects/tree.webp"; +import FinalTake from "@/public/projects/finalTake.webp"; +import PTSO from "@/public/projects/ptso.webp"; +import Chess from "@/public/projects/chess.webp"; +import AviatR from "@/public/projects/aviatr.webp"; +import Leap from "@/public/projects/leap.webp"; +import SquareRoot from "@/public/projects/squareRoot.webp"; +import { IconType } from "react-icons"; +import { RiNextjsFill } from "react-icons/ri"; +import { FaReact, FaFigma } from "react-icons/fa"; +import { + SiTypescript, + SiTailwindcss, + SiPrettier, + SiShadcnui, +} from "react-icons/si"; +import { PiFileCpp } from "react-icons/pi"; + +interface techEntry { + icon: IconType; +} interface ProjectItem { image: StaticImageData; title: string; description: string; + date: string; + role: string; + techStack?: techEntry[]; } const projectItems: ProjectItem[] = [ { image: ULA, title: "ULA Website", + date: "September 2025", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Served as Scrum Master and Project Lead on behalf of ACM@UCR to develop UCR's Website for Undergraduate Learning Assistants.", + role: "Lead", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + ], }, { image: Tree, title: "Data Structures Website", + date: "In Progress", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Served as Scrum Master and Project Lead to develop a website to assist students with understanding elementary Data Structures. Contains visualizations of BSTs, AVL Trees, Heaps, and Sorting Algorithms.", + role: "Lead", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + { + icon: SiShadcnui, + }, + ], }, { image: PTSO, title: "PTSO Website", + date: "June 2025", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Served as Scrum Master and Project Lead on behalf of ACM@UCR to develop UCR's Website for the Pre-Therapy Student Organization.", + role: "Lead", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + ], }, { image: FinalTake, title: "Hackathon Game", + date: "April 2025", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Our submission for Citrus Hack 2025. Helped develop a game where the user is a Movie Studio Executive, and has to make decisions that balance their budget while being environmentally friendly.", + role: "Developer", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + { + icon: SiShadcnui, + }, + ], }, { - image: AviatR, - title: "Aviat'R Website", + image: Chess, + date: "November 2024", + title: "Parallelized Chess", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Developed parallelized AI chess engine implementing minimax with alpha-beta pruning. Optimized performance with pthreads, achieving 15x runtime improvement over sequential baseline", + role: "Personal Project", + techStack: [ + { + icon: PiFileCpp, + }, + ], }, + { - image: Chess, - title: "Parallelized Chess", + image: AviatR, + date: "December 2024", + title: "Aviat'R Website", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Served as Scrum Master and Project Lead on behalf of ACM@UCR to develop UCR's Website for Aviat'R.", + role: "Lead", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + ], }, + { image: Leap, title: "Leap Website", + date: "March 2025", description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Served as Scrum Master and Project Lead on behalf of ACM@UCR to develop UCR's Website for Loving our Emotions as Asian and Pacific !slanders.", + role: "Lead", + techStack: [ + { + icon: RiNextjsFill, + }, + { + icon: FaReact, + }, + { + icon: SiTypescript, + }, + { + icon: SiTailwindcss, + }, + { + icon: FaFigma, + }, + { + icon: SiPrettier, + }, + { + icon: SiShadcnui, + }, + ], }, { image: SquareRoot, - title: "Quick Magic Square Root", - description: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + date: "January 2025", + title: "Magic Square Root", + description: "Implemented the Magic Square Root Formula.", + role: "Personal Project", + techStack: [ + { + icon: PiFileCpp, + }, + ], }, ]; diff --git a/src/data/SocialData.ts b/src/data/SocialData.ts index 9cff0d2..d5b78d6 100644 --- a/src/data/SocialData.ts +++ b/src/data/SocialData.ts @@ -8,10 +8,10 @@ interface SocialLink { } const socialLinks: SocialLink[] = [ - { link: "/meow", icon: FaGithub }, - { link: "/meow", icon: FaLinkedin }, - { link: "/meow", icon: MdOutlineMarkEmailRead }, - { link: "/meow", icon: FaNewspaper }, + { link: "https://github.com/Kevinloritsch", icon: FaGithub }, + { link: "https://www.linkedin.com/in/kevin-loritsch/", icon: FaLinkedin }, + { link: "/KevinLoritsch_Resume.pdf", icon: FaNewspaper }, + { link: "mailto:klori003@ucr.edu", icon: MdOutlineMarkEmailRead }, ]; export { socialLinks };