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
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.next
node_modules
out
coverage
dist
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
12 changes: 9 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,15 @@ export default function RootLayout({ children }: RootLayoutProps) {

<link rel="preconnect" href="https://fonts.googleapis.com" />

<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet"></link>
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="anonymous"
/>
<link
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap"
rel="stylesheet"
></link>

<link
rel="stylesheet"
Expand All @@ -78,4 +85,3 @@ export default function RootLayout({ children }: RootLayoutProps) {
</html>
);
}

1 change: 0 additions & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,3 @@ export default function HomePage() {
</div>
);
}

6 changes: 6 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTypescript from "eslint-config-next/typescript";

const eslintConfig = [...nextVitals, ...nextTypescript];

export default eslintConfig;
5 changes: 2 additions & 3 deletions features/blogs/BlogCard.module.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
.card {
max-width: 344px;
margin-top: 20px;
padding: 8px
padding: 8px;
}


.categoryChip {
margin: 4px 4px 4px 0px;
line-height: 1.8;
Expand All @@ -16,4 +15,4 @@

.button {
padding: 8px 16px;
}
}
4 changes: 1 addition & 3 deletions features/blogs/BlogCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React from "react";
import Card from "@mui/material/Card";
import CardActions from "@mui/material/CardActions";
import CardContent from "@mui/material/CardContent";
Expand Down Expand Up @@ -27,7 +27,6 @@ export default function BlogCard({
categories,
link,
}: BlogCardProps) {

return (
<Card variant="outlined" className={styles.card}>
<CardContent>
Expand Down Expand Up @@ -82,4 +81,3 @@ export default function BlogCard({
</Card>
);
}

3 changes: 1 addition & 2 deletions features/blogs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ export interface BlogSectionProps {
};
}

export interface BlogCardProps extends BlogItem {}
export type BlogCardProps = BlogItem;

export interface MediumFeedResponse {
items: BlogItem[];
}

2 changes: 1 addition & 1 deletion features/blogs/utils/fetchMediumFeed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import profileData from "@/features/profile/data/profileData"
import profileData from "@/features/profile/data/profileData";

import type { MediumFeedResponse } from "../types";

Expand Down
87 changes: 56 additions & 31 deletions features/profile/ProfileSection.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
$text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;

$text-shadow:
0.6px 2px 2px #323232,
0 0.8px 4px #323232;

.background {
position: relative;
Expand All @@ -16,27 +17,35 @@ $text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;
inset: 0;
background:
/* vertical orchid traces */
repeating-linear-gradient(90deg,
repeating-linear-gradient(
90deg,
rgba(214, 112, 218, 0.22) 0px,
rgba(214, 112, 218, 0.22) 0.8px,
transparent 0.8px,
transparent 80px),
transparent 80px
),
/* horizontal orchid-pink traces */
repeating-linear-gradient(0deg,
rgba(214, 112, 218, 0.18) 0px,
rgba(214, 112, 218, 0.18) 0.8px,
transparent 0.8px,
transparent 120px),
repeating-linear-gradient(
0deg,
rgba(214, 112, 218, 0.18) 0px,
rgba(214, 112, 218, 0.18) 0.8px,
transparent 0.8px,
transparent 120px
),
/* diagonal soft orchid glow lines */
repeating-linear-gradient(135deg,
rgba(214, 112, 218, 0.12) 0px,
rgba(214, 112, 218, 0.12) 0.8px,
transparent 0.8px,
transparent 160px);
mask-image: radial-gradient(circle at center,
rgba(0, 0, 0, 1) 45%,
rgba(0, 0, 0, 0.4) 70%,
transparent 100%);
repeating-linear-gradient(
135deg,
rgba(214, 112, 218, 0.12) 0px,
rgba(214, 112, 218, 0.12) 0.8px,
transparent 0.8px,
transparent 160px
);
mask-image: radial-gradient(
circle at center,
rgba(0, 0, 0, 1) 45%,
rgba(0, 0, 0, 0.4) 70%,
transparent 100%
);
opacity: 0.92;
pointer-events: none;

Expand All @@ -46,15 +55,24 @@ $text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;

@keyframes wire-shimmer {
0% {
background-position: 0 0, 0 0, 0 0;
background-position:
0 0,
0 0,
0 0;
}

50% {
background-position: 10px 0, 0 16px, -20px 20px;
background-position:
10px 0,
0 16px,
-20px 20px;
}

100% {
background-position: 0 0, 0 0, 0 0;
background-position:
0 0,
0 0,
0 0;
}
}

Expand All @@ -64,17 +82,25 @@ $text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;
position: absolute;
inset: -25%;
background:
radial-gradient(circle at 25% 30%,
radial-gradient(
circle at 25% 30%,
rgba(214, 112, 218, 0.35),
transparent 55%),
radial-gradient(circle at 70% 40%,
rgba(214, 112, 218, 0.30),
transparent 60%),
radial-gradient(circle at 50% 70%,
transparent 55%
),
radial-gradient(
circle at 70% 40%,
rgba(214, 112, 218, 0.3),
transparent 60%
),
radial-gradient(
circle at 50% 70%,
rgba(214, 112, 218, 0.28),
transparent 65%);
transparent 65%
);
filter: blur(80px);
animation: energy-drift 28s ease-in-out infinite alternate, glow-pulse 6s ease-in-out infinite alternate;
animation:
energy-drift 28s ease-in-out infinite alternate,
glow-pulse 6s ease-in-out infinite alternate;
pointer-events: none;
}

Expand Down Expand Up @@ -107,7 +133,6 @@ $text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;
}
}


.profileContainer {
padding: 50px 0;
}
Expand Down Expand Up @@ -160,4 +185,4 @@ $text-shadow: 0.6px 2px 2px #323232, 0 0.8px 4px #323232;
text-align: center;
justify-content: center;
}
}
}
20 changes: 3 additions & 17 deletions features/profile/ProfileSection.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
"use client";

import {
Container,
Grid,
Typography,
} from "@mui/material";
import { Container, Grid, Typography } from "@mui/material";

import SocialLinkButton from "./SocialLinkButton";
import profileData from "./data/profileData";
Expand All @@ -19,16 +15,11 @@ import styles from "./ProfileSection.module.scss";
*/
export default function ProfileSection() {
return (
<Grid
container
alignItems="center"
className={styles.background}
>
<Grid container alignItems="center" className={styles.background}>
<Grid size={{ xs: 12 }} className={styles.profileContainer}>
<Container>
<Grid container>
<Grid size={12} className={styles.contentContainer}>

<Typography variant="h2" className={styles.name}>
{profileData.name}
</Typography>
Expand All @@ -40,14 +31,9 @@ export default function ProfileSection() {
>
{profileData.about}
</Typography>

</Grid>

<Grid
container
size={12}
className={styles.avatarContainer}
>
<Grid container size={12} className={styles.avatarContainer}>
<div className={styles.socialContainer}>
{profileData.links.map((linkData, index) => (
<SocialLinkButton
Expand Down
1 change: 0 additions & 1 deletion features/profile/SocialLinkButton.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
margin-right: 12px !important;
margin-top: 18px !important;
}

17 changes: 14 additions & 3 deletions features/profile/SocialLinkButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ import type { SocialLinkButtonProps } from "./types";
* @remarks Styled using FAB and custom SCSS.
* @public
*/
export default function SocialLinkButton({ icon: Icon, link, label }: SocialLinkButtonProps) {
export default function SocialLinkButton({
icon: Icon,
link,
label,
}: SocialLinkButtonProps) {
return (
<Fab color="primary" variant="extended" size="medium" className={styles.fab} component="a" href={link}
<Fab
color="primary"
variant="extended"
size="medium"
className={styles.fab}
component="a"
href={link}
target="_blank"
rel="noopener noreferrer">
rel="noopener noreferrer"
>
<Icon size="28px" style={{ marginRight: "4px" }} />
{label}
</Fab>
Expand Down
10 changes: 4 additions & 6 deletions features/profile/data/profileData.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { FaGithub, FaLinkedin, FaMedium } from "react-icons/fa";
import { IconType } from "react-icons";

import type { ProfileData } from "../types";
import { getProfileAbout } from "../utils/getProfileAbout";

const profileData: ProfileData = {
name: "Suvansh Rana",
avatar: "./avatar-v3.jpg",
about:
"Full-stack software engineer with 4.5+ years of experience working with the MERN stack, focused on clean code, performance, and real-world products.",
about: getProfileAbout(),

meta: {
title: "Suvansh Rana's portfolio",
Expand Down Expand Up @@ -36,17 +35,16 @@ const profileData: ProfileData = {
{
icon: FaLinkedin,
link: "https://linkedin.com/in/suvnshr",
label: "LinkedIn"
label: "LinkedIn",
},
{
icon: FaMedium,
link: "https://medium.com/@suvnshr",
label: "Medium"
label: "Medium",
},
],
mediumFeedURL:
"https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/@suvnshr",
};

export default profileData;

32 changes: 32 additions & 0 deletions features/profile/utils/getProfileAbout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { intervalToDuration } from "date-fns";

// Keep this as a UTC date to avoid timezone drift in month/day boundaries.
const EXPERIENCE_START_DATE = new Date(Date.UTC(2021, 5, 28));

const getExperienceDuration = (
startDate: Date,
currentDate: Date = new Date(),
): string => {
// date-fns gives a calendar-aware split into years/months.
const duration = intervalToDuration({
start: startDate,
end: currentDate,
});
const years = duration.years ?? 0;
const months = duration.months ?? 0;

const durationParts: string[] = [];

if (years > 0) {
durationParts.push(`${years} year${years === 1 ? "" : "s"}`);
}

if (months > 0 || years === 0) {
durationParts.push(`${months} month${months === 1 ? "" : "s"}`);
}

return durationParts.join(" ");
};

export const getProfileAbout = (): string =>
`Software engineer with ${getExperienceDuration(EXPERIENCE_START_DATE)} of experience building real-world, performance-driven web applications.`;
1 change: 0 additions & 1 deletion features/projects/ProjectCard.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@
.button {
padding: 8px 16px;
}

1 change: 0 additions & 1 deletion features/projects/data/projectData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,3 @@ const projectData: Project[] = [
];

export default projectData;

3 changes: 1 addition & 2 deletions features/projects/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ export interface Project {
githubLink: string;
}

export interface ProjectCardProps extends Project {}

export type ProjectCardProps = Project;
Loading
Loading