Skip to content

Refactor: Centralize portfolio configuration and simplify content for template usage#1

Open
Paranjayy wants to merge 1 commit intomainfrom
refactor/template-cleanup-2150165971647175537
Open

Refactor: Centralize portfolio configuration and simplify content for template usage#1
Paranjayy wants to merge 1 commit intomainfrom
refactor/template-cleanup-2150165971647175537

Conversation

@Paranjayy
Copy link
Copy Markdown
Owner

@Paranjayy Paranjayy commented Feb 3, 2026

Converted the portfolio into a reusable template.

  1. Created src/config/portfolio.tsx as the single source of truth for user data.
  2. Refactored src/features/**/data/*.ts to export from the config.
  3. Updated src/utils/string.ts to allow plain text phone/email (optional base64).
  4. Deleted personal blog posts/components, keeping welcome.mdx and slide-to-unlock.mdx as examples.
  5. Verified with build and visual check.

PR created automatically by Jules for task 2150165971647175537 started by @Paranjayy

Summary by CodeRabbit

  • New Features

    • Added centralized portfolio configuration system for managing profile, social links, tech stack, experiences, projects, testimonials, awards, certifications, bookmarks, and sponsors data.
  • Improvements

    • Enhanced email and phone number decoding logic with improved error handling and fallback mechanisms for better reliability.
  • Documentation

    • Removed multiple blog content articles from the repository.

- Centralize portfolio data in `src/config/portfolio.tsx`
- Replace personal data with placeholders
- Update utilities to support plain text inputs
- Clean up blog posts and components, keeping examples
- Refactor data adapters to use centralized config

Co-authored-by: Paranjayy <120307516+Paranjayy@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

Centralizes portfolio configuration data into a new PORTFOLIO_DATA constant in src/config/portfolio.tsx, then refactors multiple feature modules to reference this centralized source instead of maintaining inline data. Additionally removes 16 MDX blog content files and adds error-handling improvements to email/phone decoding utilities.

Changes

Cohort / File(s) Summary
Central Portfolio Config
src/config/portfolio.tsx
New configuration file exporting PORTFOLIO_DATA constant containing strongly-typed user profile, social links, tech stack, experiences, projects, testimonials, awards, certifications, bookmarks, and sponsors.
Data Layer Refactoring
src/features/portfolio/data/*, src/features/sponsors/data.tsx
Ten files refactored to source data from centralized PORTFOLIO_DATA instead of inline arrays: awards, bookmarks, certifications, experiences, projects, social-links, tech-stack, testimonials, user, and sponsors.
Blog Content Removal
src/features/blog/content/*
Sixteen MDX blog post files deleted including component documentation (apple-hello-effect, scroll-fade-effect, testimonials-marquee, work-experience-component, react-wheel-picker), setup guides (awesome-terminal, consent-manager, uptime-kuma), feature announcements, and brand/portfolio-related posts.
Utility Enhancements
src/utils/string.ts
Added error handling and fast-path checks to decodeEmail() and decodePhoneNumber() functions to gracefully handle invalid inputs and skip unnecessary decoding attempts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A rabbit hops with glee,
Central config's the key!
Data once scattered and spread,
Now unified instead.
Old blogs fade to rest,
As the portfolio's refreshed! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: centralizing portfolio configuration into a single source of truth and simplifying content for template usage, which is the core objective of this PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/template-cleanup-2150165971647175537

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Reviews will stop working after February 8, 2026 if the new IP is not added to your allowlist.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/config/portfolio.tsx`:
- Around line 147-149: The project period start value is using "2024" but the
Project type requires "MM.YYYY"; update the period.start value in the project
object (property period.start) to the documented "MM.YYYY" format (e.g.,
"01.2024" or the correct month for that project) so formatting/sorting logic
using the Project type works correctly.
- Around line 122-125: The employmentPeriod object currently sets end: "Present"
which violates the “omit for present” contract and can break consumers expecting
MM.YYYY or undefined; update the employmentPeriod for the ongoing role by
removing the end property (or setting it to undefined) instead of using the
string "Present" so employmentPeriod.start remains "01.2022" and
employmentPeriod.end is absent/undefined to indicate an active role.

In `@src/utils/string.ts`:
- Around line 13-26: The decodePhoneNumber function currently attempts atob for
any string with letters and can return garbage for vanity numbers like
"CALLME12"; change it to first check the input against a strict base64 pattern
(e.g. only A-Za-z0-9+/ with optional padding) before calling atob, then validate
the decoded result contains only valid phone characters (digits, spaces, +,
parentheses, dashes, optional "ext"/"x") and reasonable length; only return the
decoded value if both the base64 gate and the decoded-content validation pass,
otherwise return the original phone string, preserving the existing try/catch
around atob to handle decode errors.

Comment thread src/config/portfolio.tsx
Comment on lines +122 to +125
employmentPeriod: {
start: "01.2022",
end: "Present", // Omit end for present
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align employmentPeriod.end with the “omit for present” contract.
Line 124 sets end: "Present" even though the inline guidance says to omit it for ongoing roles. This can break date parsing/sorting if consumers expect MM.YYYY or undefined.

🔧 Suggested fix
           employmentPeriod: {
             start: "01.2022",
-            end: "Present", // Omit end for present
           },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
employmentPeriod: {
start: "01.2022",
end: "Present", // Omit end for present
},
employmentPeriod: {
start: "01.2022",
},
🤖 Prompt for AI Agents
In `@src/config/portfolio.tsx` around lines 122 - 125, The employmentPeriod object
currently sets end: "Present" which violates the “omit for present” contract and
can break consumers expecting MM.YYYY or undefined; update the employmentPeriod
for the ongoing role by removing the end property (or setting it to undefined)
instead of using the string "Present" so employmentPeriod.start remains
"01.2022" and employmentPeriod.end is absent/undefined to indicate an active
role.

Comment thread src/config/portfolio.tsx
Comment on lines +147 to +149
period: {
start: "2024",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the documented "MM.YYYY" format for project period.
Line 148 uses "2024" but the Project type expects "MM.YYYY", which can break formatting/sorting logic.

🔧 Suggested fix
       period: {
-        start: "2024",
+        start: "01.2024",
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
period: {
start: "2024",
}
period: {
start: "01.2024",
}
🤖 Prompt for AI Agents
In `@src/config/portfolio.tsx` around lines 147 - 149, The project period start
value is using "2024" but the Project type requires "MM.YYYY"; update the
period.start value in the project object (property period.start) to the
documented "MM.YYYY" format (e.g., "01.2024" or the correct month for that
project) so formatting/sorting logic using the Project type works correctly.

Comment thread src/utils/string.ts
Comment on lines 13 to +26
export function decodePhoneNumber(phone: string) {
return atob(phone);
try {
// fast check: if it looks like a phone number (digits, +, spaces, parens, dashes) and is not obviously base64
// But base64 can have + and / and digits.
// However, phone numbers usually don't have letters. Base64 usually does.
if (/[a-zA-Z]/.test(phone) && !/[@.]/.test(phone)) {
// has letters, likely base64 (unless it's an extension like "ext").
// But if it fails atob, we return original.
return atob(phone);
}
return phone;
} catch {
return phone;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid mis-decoding vanity phone numbers that happen to be valid base64.
A string like CALLME12 can decode to garbage without throwing, returning corrupted data. Add a base64 gate and validate decoded output before returning it.

🛠️ Proposed fix
 export function decodePhoneNumber(phone: string) {
   try {
-    // fast check: if it looks like a phone number (digits, +, spaces, parens, dashes) and is not obviously base64
-    // But base64 can have + and / and digits.
-    // However, phone numbers usually don't have letters. Base64 usually does.
-    if (/[a-zA-Z]/.test(phone) && !/[@.]/.test(phone)) {
-       // has letters, likely base64 (unless it's an extension like "ext").
-       // But if it fails atob, we return original.
-       return atob(phone);
-    }
-    return phone;
+    const looksLikeBase64 =
+      /^[A-Za-z0-9+/]+={0,2}$/.test(phone) && phone.length % 4 === 0;
+    if (looksLikeBase64) {
+      const decoded = atob(phone);
+      // Only accept decoded values that still look like a phone number.
+      if (/^[\d+()\s-]+$/.test(decoded)) return decoded;
+    }
+    return phone;
   } catch {
     return phone;
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function decodePhoneNumber(phone: string) {
return atob(phone);
try {
// fast check: if it looks like a phone number (digits, +, spaces, parens, dashes) and is not obviously base64
// But base64 can have + and / and digits.
// However, phone numbers usually don't have letters. Base64 usually does.
if (/[a-zA-Z]/.test(phone) && !/[@.]/.test(phone)) {
// has letters, likely base64 (unless it's an extension like "ext").
// But if it fails atob, we return original.
return atob(phone);
}
return phone;
} catch {
return phone;
}
export function decodePhoneNumber(phone: string) {
try {
const looksLikeBase64 =
/^[A-Za-z0-9+/]+={0,2}$/.test(phone) && phone.length % 4 === 0;
if (looksLikeBase64) {
const decoded = atob(phone);
// Only accept decoded values that still look like a phone number.
if (/^[\d+()\s-]+$/.test(decoded)) return decoded;
}
return phone;
} catch {
return phone;
}
}
🤖 Prompt for AI Agents
In `@src/utils/string.ts` around lines 13 - 26, The decodePhoneNumber function
currently attempts atob for any string with letters and can return garbage for
vanity numbers like "CALLME12"; change it to first check the input against a
strict base64 pattern (e.g. only A-Za-z0-9+/ with optional padding) before
calling atob, then validate the decoded result contains only valid phone
characters (digits, spaces, +, parentheses, dashes, optional "ext"/"x") and
reasonable length; only return the decoded value if both the base64 gate and the
decoded-content validation pass, otherwise return the original phone string,
preserving the existing try/catch around atob to handle decode errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant