Skip to content

feat: add portfolio template inspired by Bechir Lahoueg (#3907)#4158

Open
anjalikumari45 wants to merge 1 commit into
anurag3407:mainfrom
anjalikumari45:fix/issue-2124
Open

feat: add portfolio template inspired by Bechir Lahoueg (#3907)#4158
anjalikumari45 wants to merge 1 commit into
anurag3407:mainfrom
anjalikumari45:fix/issue-2124

Conversation

@anjalikumari45

@anjalikumari45 anjalikumari45 commented Jun 17, 2026

Copy link
Copy Markdown

User description

Description

Implements a new modern, dark-themed developer portfolio template inspired by Bechir Lahoueg's minimalist design (https://www.bechirlahoueg.tech).

The component is fully integrated with the custom usePortfolio hook, safely destructuring user profile details, experience milestones, core skills, and featured projects with robust fallbacks. Built using Tailwind CSS to ensure a fully fluid, sleek layout across mobile, tablet, and desktop viewports.

Type of Change

  • New feature
  • Bug fix
  • Documentation update
  • Performance improvement
  • Other (describe)

Related Issue

Fixes #3907

Testing

  • Unit tests pass
  • Tested Locally
  • New tests added

Screenshots (MANDATORY for UI/UX changes)

  • Attached Screenshots or Screen Recordings (showing before and after)
    (Note: Remember to drag and drop your screenshots/recordings here before submitting!)

Checklist

  • Code follows project style guidelines
  • Self-reviewed my code
  • Added comments where necessary
  • Updated documentation
  • No new warnings generated

CodeAnt-AI Description

Add a dark-themed portfolio template with built-in fallback content

What Changed

  • Added a new portfolio page layout with a dark, modern look, sticky navigation, and section links for About, Projects, Experience, and Skills
  • Shows a complete personal profile section, featured projects, work history, and skills in a responsive layout that works across screen sizes
  • Displays clear placeholder text when portfolio data is missing, so the page still loads cleanly instead of appearing empty

Impact

✅ Clearer portfolio preview when profile data is incomplete
✅ Smoother mobile and desktop viewing
✅ Fewer blank sections on first load

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features
    • Added a new portfolio template with a sticky header, about section, and responsive sections for projects, experience, and skills.
    • Projects display in a grid layout with descriptions and technology tags.
    • Experience renders as a timeline with role and company details.
    • Skills display as customizable chips.

@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

@anjalikumari45 is attempting to deploy a commit to the Anurag Mishra's projects Team on Vercel.

A member of the Team first needs to authorize it.

@codeant-ai

codeant-ai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new React component InspiredBechirLahoueg in a new template directory. The component reads from usePortfolio() context with fallback defaults and renders a full portfolio layout: sticky header, About hero, Projects grid, Experience timeline, Skills chips, and a footer with the current year.

Changes

InspiredBechirLahoueg Portfolio Template

Layer / File(s) Summary
Data wiring and fallbacks
frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx
Imports React and usePortfolio, destructures portfolioData, and establishes fallback profile fields and empty arrays for projects, experiences, and skills when context data is absent.
Page wrapper and About hero
frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx
Renders the sticky header/nav outer wrapper and the About/intro hero section, conditionally displaying profile.name, profile.role, and profile.bio with string fallbacks.
Projects, Experience, Skills sections and footer
frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx
Renders a responsive Projects grid with optional per-project technology tags; an Experience timeline list showing role, company, and duration; a Skills section with chips supporting both string and { name } object entries; a footer displaying the current year and profile name; and the default export.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

type:feature, portfolio-template, level:intermediate, quality:clean, size:L

Poem

🐇 A new template hops into view,
Cards and chips in a palette so true,
Projects line up in a grid so neat,
Skills and timelines — what a feat!
The footer ticks with each passing year,
Bechir's style, now rendered right here! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add portfolio template inspired by Bechir Lahoueg (#3907)' clearly and specifically summarizes the main change—adding a new portfolio template component.
Linked Issues check ✅ Passed The implementation meets primary coding requirements: creates component at correct file path, integrates usePortfolio hook, provides responsive design with Tailwind CSS, and handles fallbacks for missing data.
Out of Scope Changes check ✅ Passed The changeset is entirely scoped to implementing the new portfolio template component as specified in issue #3907; no unrelated modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Jun 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`:
- Line 8: The profile fallback on line 8 only handles the case when the entire
profile is missing, but does not protect against individual fields like name,
role, or bio being undefined or null. This causes runtime errors when
profile.name.split(...) is called on line 18 and when rendering profile.name on
line 33 and profile.role on line 124. Modify the profile object initialization
to normalize each field individually by providing fallback default values for
name, role, and bio properties, ensuring each field has a guaranteed string
value even if the parent data.profile object exists but contains null or
undefined values.
- Around line 58-60: The condition checking proj.technologies only validates
truthiness but not that it is an array, which will cause a crash if technologies
is a truthy non-array value like a string or object when calling map(). Update
the conditional statement to use Array.isArray(proj.technologies) in addition to
the truthy check to ensure technologies is verified as an array before calling
.map() on line 60.
- Line 112: The ternary operator checking typeof skill === 'object' needs to
guard against null values, since null is technically an object type in
JavaScript and will cause an error when attempting to access skill.name. Modify
the condition to explicitly check that skill is not null before treating it as
an object with a name property, ensuring the code handles null entries safely
without throwing an error when skill.name is accessed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b287f191-bcc0-4af6-add6-6e90b93cd53f

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9c7ef and 9f1efcc.

📒 Files selected for processing (1)
  • frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx

const { portfolioData: data } = usePortfolio();

// Fallback structural data if context is initially empty
const profile = data?.profile || { name: 'Your Name', role: 'Full Stack Developer', bio: 'Crafting digital experiences.' };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize profile fields before rendering string operations.

Line 8 only falls back when data.profile is fully missing. If data.profile exists but name is undefined/null, Line 18 can throw on profile.name.split(...), and Lines 33/124 also render unsafe values.

Suggested fix
-  const profile = data?.profile || { name: 'Your Name', role: 'Full Stack Developer', bio: 'Crafting digital experiences.' };
+  const profile = {
+    name: 'Your Name',
+    role: 'Full Stack Developer',
+    bio: 'Crafting digital experiences.',
+    ...(data?.profile ?? {}),
+  };

Also applies to: 18-18, 33-33, 124-124

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`
at line 8, The profile fallback on line 8 only handles the case when the entire
profile is missing, but does not protect against individual fields like name,
role, or bio being undefined or null. This causes runtime errors when
profile.name.split(...) is called on line 18 and when rendering profile.name on
line 33 and profile.role on line 124. Modify the profile object initialization
to normalize each field individually by providing fallback default values for
name, role, and bio properties, ensuring each field has a guaranteed string
value even if the parent data.profile object exists but contains null or
undefined values.

Comment on lines +58 to +60
{proj.technologies && (
<div className="flex flex-wrap gap-2 pt-4 border-t border-zinc-900">
{proj.technologies.map((tech, tIdx) => (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard technologies as an array before calling .map().

At Line 58, a truthy non-array value (e.g., string/object) will pass the condition and crash at Line 60 (map is not a function).

Suggested fix
-                  {proj.technologies && (
+                  {Array.isArray(proj.technologies) && proj.technologies.length > 0 && (
                     <div className="flex flex-wrap gap-2 pt-4 border-t border-zinc-900">
📝 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
{proj.technologies && (
<div className="flex flex-wrap gap-2 pt-4 border-t border-zinc-900">
{proj.technologies.map((tech, tIdx) => (
{Array.isArray(proj.technologies) && proj.technologies.length > 0 && (
<div className="flex flex-wrap gap-2 pt-4 border-t border-zinc-900">
{proj.technologies.map((tech, tIdx) => (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`
around lines 58 - 60, The condition checking proj.technologies only validates
truthiness but not that it is an array, which will cause a crash if technologies
is a truthy non-array value like a string or object when calling map(). Update
the conditional statement to use Array.isArray(proj.technologies) in addition to
the truthy check to ensure technologies is verified as an array before calling
.map() on line 60.

key={idx}
className="bg-[#121214] border border-zinc-800 text-zinc-300 px-4 py-2 rounded-lg text-sm font-medium hover:text-white hover:border-zinc-700 transition"
>
{typeof skill === 'object' ? skill.name : skill}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle null skill entries safely in the object branch.

Line 112 treats any object as { name }, but null is also an object in JS and will throw on skill.name.

Suggested fix
-                  {typeof skill === 'object' ? skill.name : skill}
+                  {skill && typeof skill === 'object' ? skill.name : skill}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`
at line 112, The ternary operator checking typeof skill === 'object' needs to
guard against null values, since null is technically an object type in
JavaScript and will cause an error when attempting to access skill.name. Modify
the condition to explicitly check that skill is not null before treating it as
an object with a name property, ensuring the code handles null entries safely
without throwing an error when skill.name is accessed.

@@ -0,0 +1,130 @@
import React from 'react';
import { usePortfolio } from '../../../../context/PortfolioContext';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: This import points to frontend/src/context/PortfolioContext, but that module does not exist in the current codebase, so the template will fail to build/load with a module resolution error. Update the import to an existing module or refactor the template to use the same data source pattern as other templates. [import error]

Severity Level: Critical 🚨
- ❌ Any consumer importing this template hits module-not-found error.
- ⚠️ Blocks integrating the new Bechir-inspired portfolio template.
Steps of Reproduction ✅
1. Open `frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`
and note the import at line 2: `import { usePortfolio } from
'../../../../context/PortfolioContext';`.

2. Inspect the context directory `frontend/src/context` (listing shows only
`AuthContext.js`, `AuthProvider.jsx`, `SidebarContext.js`, `SocketContext.js`,
`SocketProvider.jsx`, `ThemeContext.js`, `ThemeProvider.jsx`; no `PortfolioContext.*` file
exists).

3. A global search for `PortfolioContext` and `usePortfolio` across
`/workspace/career-pilot` finds references only in this new template file, with no
corresponding hook or context definition.

4. When any page (for example, a new entry in `frontend/src/pages/TemplateGallery.jsx` or
`frontend/src/App.jsx`) imports `InspiredBechirLahoueg` and the frontend is built or `npm
run dev` is started, the bundler will attempt to resolve
`../../../../context/PortfolioContext` and fail with a "Module not found: Can't resolve
'../../../../context/PortfolioContext'" error, preventing the app (or that route) from
loading.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx
**Line:** 2:2
**Comment:**
	*Import Error: This import points to `frontend/src/context/PortfolioContext`, but that module does not exist in the current codebase, so the template will fail to build/load with a module resolution error. Update the import to an existing module or refactor the template to use the same data source pattern as other templates.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

{/* Header/Nav */}
<header className="sticky top-0 z-50 backdrop-blur-md bg-[#0a0a0c]/70 border-b border-zinc-800/50 px-6 py-4 flex justify-between items-center">
<div className="text-xl font-bold bg-gradient-to-r from-purple-400 to-indigo-500 bg-clip-text text-transparent">
{profile.name.split(' ')[0]}.dev

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: profile only falls back when the entire object is missing; if profile exists but name is undefined/null, calling .split will throw and crash rendering. Add a safe fallback for name before splitting (or guard with optional chaining/default string). [null pointer]

Severity Level: Major ⚠️
- ❌ Portfolio template crashes when profile.name is missing/invalid.
- ⚠️ Breaks any route that mounts this new template.
Steps of Reproduction ✅
1. In `frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx`,
observe `profile` initialization at lines 7–11: `const profile = data?.profile || { name:
'Your Name', ... };` followed by the header label at line 18: `{profile.name.split('
')[0]}.dev`.

2. Because the fallback only applies when `data.profile` is falsy, any truthy
`data.profile` object without a valid `name` (e.g., `{ role: 'Dev' }` or `{ name: null }`)
will be used as-is, leaving `profile.name` as `undefined` or `null`.

3. When this component is rendered in a route (e.g., after being imported into
`frontend/src/App.jsx` similarly to `ChatbotPortfolio` or into
`frontend/src/pages/TemplateGallery.jsx` like `LiquidGlass`) and the `usePortfolio`
context supplies a `portfolioData.profile` lacking a valid string `name`, React will
execute `profile.name.split(' ')` during render.

4. At that point, the browser throws a `TypeError` such as "Cannot read properties of
undefined (reading 'split')", causing the entire Inspired Bechir Lahoueg template (and
potentially the enclosing route) to fail to render.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/portfolio/templates/Inspired_Bechir_Lahoueg/index.jsx
**Line:** 18:18
**Comment:**
	*Null Pointer: `profile` only falls back when the entire object is missing; if `profile` exists but `name` is `undefined`/`null`, calling `.split` will throw and crash rendering. Add a safe fallback for `name` before splitting (or guard with optional chaining/default string).

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

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

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add portfolio template: inspired by Bechir Lahoueg

1 participant