Refactor: Centralize portfolio configuration and simplify content for template usage#1
Refactor: Centralize portfolio configuration and simplify content for template usage#1
Conversation
- 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>
|
👋 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 New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
📝 WalkthroughWalkthroughCentralizes portfolio configuration data into a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Important Action Needed: IP Allowlist UpdateIf your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:
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. Comment |
There was a problem hiding this comment.
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.
| employmentPeriod: { | ||
| start: "01.2022", | ||
| end: "Present", // Omit end for present | ||
| }, |
There was a problem hiding this comment.
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.
| 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.
| period: { | ||
| start: "2024", | ||
| } |
There was a problem hiding this comment.
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.
| 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.
| 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; | ||
| } |
There was a problem hiding this comment.
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.
| 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.
Converted the portfolio into a reusable template.
src/config/portfolio.tsxas the single source of truth for user data.src/features/**/data/*.tsto export from the config.src/utils/string.tsto allow plain text phone/email (optional base64).welcome.mdxandslide-to-unlock.mdxas examples.PR created automatically by Jules for task 2150165971647175537 started by @Paranjayy
Summary by CodeRabbit
New Features
Improvements
Documentation