Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(about): move to custom page #436

Merged
merged 2 commits into from
Jan 7, 2025

Conversation

darenmalfait
Copy link
Owner

@darenmalfait darenmalfait commented Jan 7, 2025

Summary by CodeRabbit

  • New Features

    • Added a comprehensive About page with sections for professional background, personal interests, skills, and call-to-action.
    • Introduced new reusable components for FAQ, Hero CTA, Keywords, Skills, and Split layouts.
    • Enhanced localization support with English and Dutch translations for the About page.
  • Documentation

    • Added detailed metadata and content descriptions for the About page.
  • Refactor

    • Simplified hero and page component structures.
    • Improved component modularity and reusability.

Copy link

vercel bot commented Jan 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nerdfish-be ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 7, 2025 8:23am

Copy link

coderabbitai bot commented Jan 7, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/web/src/app/[locale]/about/page.tsx

Oops! Something went wrong! :(

ESLint: 9.17.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@nerdfish/config' imported from /eslint.config.js
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

Walkthrough

The pull request introduces significant changes to the website's structure, focusing on the "About" page implementation. The existing localized "About" page has been removed and replaced with a new component that provides a more comprehensive and structured approach to displaying personal and professional information. New components for various sections, such as skills, hero, FAQ, and split layouts, have been created. Additionally, internationalization (i18n) dictionaries have been updated with detailed content for both English and Dutch locales.

Changes

File Change Summary
apps/web/src/app/[locale]/(tina)/about/page.tsx Deleted localized "About" page with previous implementation
apps/web/src/app/[locale]/about/page.tsx New "About" page with comprehensive sections, metadata generation, and localized content
apps/web/src/app/components/faq.tsx Added FAQ component with FAQItem and FAQ implementations
apps/web/src/app/components/hero.tsx Added HeroCTA component for call-to-action functionality
apps/web/src/app/components/keyword-list.tsx Added Keyword and KeywordList components for displaying keywords
apps/web/src/app/components/skills.tsx Added SkillItem and Skills components for displaying professional skills
apps/web/src/app/components/split.tsx Added SplitImage, SplitContent, and Split components for layout management
packages/i18n/dictionaries/en.json Added comprehensive "About" page content for English locale
packages/i18n/dictionaries/nl.json Added comprehensive "About" page content for Dutch locale
packages/design-system/components/arrow-link.tsx Updated ArrowLinkProps interface and ArrowLink/BackLink components for improved flexibility
packages/design-system/components/section.tsx Added optional as property to cta in SectionHeaderProps for enhanced customization

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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

🧹 Nitpick comments (9)
apps/web/src/app/components/keyword-list.tsx (2)

10-25: Consider removing redundant aria-label

The aria-label is currently set to the same value as the visible text content, which is redundant and may cause screen readers to announce the text twice.

-			aria-label={children}

29-37: Make Marquee animation parameters configurable

The component has hardcoded values for pauseOnHover, duration, and repeat which might not suit all use cases. Consider making these configurable through props while keeping the current values as defaults.

-			<Marquee pauseOnHover duration={20000} repeat={5} {...props}>
+			<Marquee
+				pauseOnHover
+				duration={props.duration ?? 20000}
+				repeat={props.repeat ?? 5}
+				{...props}
+			>
apps/web/src/app/components/faq.tsx (1)

33-35: Consider extracting prose classes to a constant

The component uses multiple prose-related classes that could be extracted to a constant for better maintainability.

const PROSE_CLASSES = 'prose prose-xl pt-md text-primary text-xl'

// Usage
<AccordionContent className={PROSE_CLASSES}>
apps/web/src/app/components/skills.tsx (2)

2-17: Consider lazy loading icons to improve initial bundle size

The component imports all icons upfront, which could impact the initial bundle size. Consider lazy loading icons using dynamic imports.

const iconMap = {
  javascript: () => import('@repo/design-system/lib/icons').then(m => m.JavascriptIcon),
  // ... other icons
}

// Usage with React.lazy and Suspense
const IconComponent = React.lazy(async () => {
  const IconModule = await iconMap[skill]()
  return { default: IconModule }
})

21-36: Add type safety for skill mapping

The skill mapping could be more type-safe by ensuring all skills from the schema have corresponding icons.

type Skill = typeof skills[number];

// Ensure type safety by checking if all skills have icons
type SkillIconMapType = Record<Skill, React.ElementType>;
const hasAllSkills = (map: Partial<SkillIconMapType>): map is SkillIconMapType => {
  return skills.every(skill => skill in map);
};

const skillIconMap = {
  javascript: JavascriptIcon,
  // ... other mappings
};

if (!hasAllSkills(skillIconMap)) {
  throw new Error('Missing icon mappings for some skills');
}
apps/web/src/app/[locale]/about/page.tsx (1)

93-107: Consider dynamic skill items loading

Instead of hardcoding skill items, consider loading them from a configuration file or CMS for easier maintenance.

-				<Skills>
-					<SkillItem skill="javascript" />
-					<SkillItem skill="react" />
-					<SkillItem skill="node" />
-					<SkillItem skill="tailwind" />
-					<SkillItem skill="next" />
-					<SkillItem skill="sanity" />
-					<SkillItem skill="webflow" />
-					<SkillItem skill="typescript" />
-					<SkillItem skill="vscode" />
-					<SkillItem skill="css" />
-					<SkillItem skill="html" />
-					<SkillItem skill="git" />
-					<SkillItem skill="figma" />
-				</Skills>
+				<Skills>
+					{skills.map(skill => (
+						<SkillItem key={skill} skill={skill} />
+					))}
+				</Skills>
packages/i18n/dictionaries/en.json (1)

137-137: Fix extra spaces in CTA subtitle

There are unnecessary spaces in the CTA subtitle text.

-				"subtitle": "Custom websites and applications tailored to help your business grow and       stand out.",
+				"subtitle": "Custom websites and applications tailored to help your business grow and stand out.",
packages/i18n/dictionaries/nl.json (2)

136-138: Remove extra spaces in subtitle text.

There are unnecessary spaces after "bedrijf te laten groeien en" which should be removed for consistency.

-				"subtitle": "Aangepaste websites en applicaties op maat om uw bedrijf te laten groeien en       op te vallen.",
+				"subtitle": "Aangepaste websites en applicaties op maat om uw bedrijf te laten groeien en op te vallen.",

146-146: Remove extra spaces in subtitle text.

There are unnecessary spaces after "plugins, features, animaties".

-				"subtitle": "HTML, CSS, JS, het bouwen van kleine, middelgrote en grote webapplicaties met JavaScript libraries, frameworks, aangepaste plugins, features, animaties       en het coderen van interactieve layouts. Ik heb ook full-stack developer ervaring en bovenal heb ik een grote interesse in leren en ben ik niet bang om nieuwe talen en uitdagingen aan te gaan.",
+				"subtitle": "HTML, CSS, JS, het bouwen van kleine, middelgrote en grote webapplicaties met JavaScript libraries, frameworks, aangepaste plugins, features, animaties en het coderen van interactieve layouts. Ik heb ook full-stack developer ervaring en bovenal heb ik een grote interesse in leren en ben ik niet bang om nieuwe talen en uitdagingen aan te gaan.",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f542052 and 6d680e0.

📒 Files selected for processing (10)
  • apps/web/src/app/[locale]/(tina)/about/page.tsx (0 hunks)
  • apps/web/src/app/[locale]/about/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/page.tsx (2 hunks)
  • apps/web/src/app/components/faq.tsx (1 hunks)
  • apps/web/src/app/components/hero.tsx (2 hunks)
  • apps/web/src/app/components/keyword-list.tsx (1 hunks)
  • apps/web/src/app/components/skills.tsx (1 hunks)
  • apps/web/src/app/components/split.tsx (1 hunks)
  • packages/i18n/dictionaries/en.json (1 hunks)
  • packages/i18n/dictionaries/nl.json (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/src/app/[locale]/(tina)/about/page.tsx
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Lint
  • GitHub Check: E2E
  • GitHub Check: TypeCheck
🔇 Additional comments (7)
apps/web/src/app/components/hero.tsx (1)

81-94: Well-structured component implementation!

The HeroCTA component effectively combines MagnetButton and Link with proper type inheritance and consistent styling. The addition of ArrowRightIcon enhances the visual feedback.

apps/web/src/app/[locale]/about/page.tsx (1)

31-56: Comprehensive metadata implementation!

The metadata generation is well-structured with proper handling of localization, SEO fields, and canonical/alternate URLs.

apps/web/src/app/[locale]/page.tsx (1)

75-75: Clean refactor using the new HeroCTA component!

The replacement of the custom button implementation with HeroCTA improves consistency and reduces code duplication.

packages/i18n/dictionaries/en.json (1)

126-169: Well-structured and comprehensive translations!

The about page translations are thorough and well-organized, covering all necessary sections with detailed content.

packages/i18n/dictionaries/nl.json (3)

127-130: LGTM! Well-structured SEO metadata.

The metadata section provides comprehensive SEO-friendly content with clear value propositions and proper keyword usage.


149-168: LGTM! Well-balanced personal and professional content.

The content effectively combines personal interests with professional expertise, and includes appropriate alt text for images.


126-169: Verify translation consistency with English version.

Let's ensure all keys in the about section are properly translated from English.

✅ Verification successful

Dutch translations are properly implemented

All keys are properly structured and content is correctly translated to Dutch, with appropriate preservation of technical terms.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare structure of English and Dutch about page translations
# and check for potential English text in Dutch translations

# First, extract and format the about section from both files
echo "Extracting and comparing translation structures..."

# Extract about section keys from both files
rg -A 50 '"about": \{' packages/i18n/dictionaries/en.json > en_about.txt
rg -A 50 '"about": \{' packages/i18n/dictionaries/nl.json > nl_about.txt

# Compare structure (keys should match)
diff <(grep -o '"[^"]*":' en_about.txt | sort) <(grep -o '"[^"]*":' nl_about.txt | sort)

# Check for common English words in Dutch translations
echo "Checking for potential untranslated content..."
rg -i '\b(the|and|or|with|in|on|at|to|for|of|by)\b' packages/i18n/dictionaries/nl.json

Length of output: 4610


Script:

#!/bin/bash
# Description: Compare structure of English and Dutch translations with improved handling

# Extract and compare about section keys
echo "Comparing translation structures..."
jq -r '.about | .. | select(objects) | keys[]' packages/i18n/dictionaries/en.json | sort > en_keys.txt
jq -r '.about | .. | select(objects) | keys[]' packages/i18n/dictionaries/nl.json | sort > nl_keys.txt
diff en_keys.txt nl_keys.txt

# Show any keys present in English but missing in Dutch
echo -e "\nKeys in English missing from Dutch:"
comm -23 en_keys.txt nl_keys.txt

# Show any extra keys in Dutch not in English
echo -e "\nExtra keys in Dutch not in English:"
comm -13 en_keys.txt nl_keys.txt

Length of output: 729

apps/web/src/app/components/faq.tsx Show resolved Hide resolved
apps/web/src/app/components/split.tsx Show resolved Hide resolved
apps/web/src/app/components/skills.tsx Show resolved Hide resolved
Copy link

@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: 0

🧹 Nitpick comments (7)
packages/design-system/components/arrow-link.tsx (2)

72-75: Consider improving ref type safety.

The implementation is good, but there's room for improvement in type safety.

Consider using forwardRef and proper generic types to avoid the as any type assertion:

import { forwardRef } from 'react'

const ArrowLink = forwardRef<HTMLElement, ArrowLinkProps>(({
  children,
  direction = 'right',
  className,
  href,
  as,
  ...props
}, ref) => {
  const Tag = as ? motion(as) : href ? motion(Link) : motion.span
  const [, state] = useElementState()
  
  return (
    <Tag
      {...props}
      href={href ?? '#'}
      className={cx(
        'space-x-md text-primary inline-flex cursor-pointer items-center text-left text-lg font-bold !no-underline transition focus:outline-none',
        className,
      )}
      ref={ref}
      animate={state}
    >
      {/* ... rest of the component ... */}
    </Tag>
  )
})
ArrowLink.displayName = 'ArrowLink'

110-111: Maintain consistency in ref handling.

Similar to ArrowLink, BackLink would benefit from improved ref handling.

Consider applying the same forwardRef pattern to BackLink for consistency:

const BackLink = forwardRef<HTMLElement, { href: string } & Pick<ArrowLinkProps, 'className' | 'children' | 'as'>>(({
  href,
  className,
  children,
  as,
  ...props
}, ref) => {
  const [, state] = useElementState()
  const Tag = as ? motion(as) : href ? motion(Link) : motion.span
  
  return (
    <Tag
      {...props}
      href={href}
      className={cx(
        'text-primary flex space-x-4 focus:outline-none',
        className,
      )}
      ref={ref}
      animate={state}
    >
      {/* ... rest of the component ... */}
    </Tag>
  )
})
BackLink.displayName = 'BackLink'

Also applies to: 114-114

apps/web/src/app/[locale]/about/page.tsx (3)

74-86: Consider making image paths configurable.

The image path /uploads/about/daren-mountains.JPG is hardcoded. Consider moving it to the translations or a configuration file for better maintainability.

-						src="/uploads/about/daren-mountains.JPG"
+						src={t('professional.image.src')}

87-109: Consider making skills data-driven.

The skills list is currently hardcoded. Consider moving it to the translations or a separate configuration file for better maintainability and easier updates.

Example approach:

const skills = t('my-toolbox.skills', { returnObjects: true }) as string[];
return (
  <Skills>
    {skills.map(skill => (
      <SkillItem key={skill} skill={skill} />
    ))}
  </Skills>
);

137-143: Consider making testimonial filters configurable.

The testimonial filter is hardcoded to ['colleague', 'client']. Consider moving this to the translations or a configuration file for better maintainability.

-					filter={{
-						type: ['colleague', 'client'],
-					}}
+					filter={{
+						type: t('testimonials.filter.types', { returnObjects: true }),
+					}}
packages/i18n/dictionaries/en.json (1)

138-138: Fix extra whitespace in CTA subtitle.

The CTA subtitle contains extra whitespace characters that should be removed.

-				"subtitle": "Custom websites and applications tailored to help your business grow and       stand out.",
+				"subtitle": "Custom websites and applications tailored to help your business grow and stand out.",
packages/i18n/dictionaries/nl.json (1)

138-138: Fix extra whitespace in CTA subtitle.

The CTA subtitle contains extra whitespace characters that should be removed.

-				"subtitle": "Aangepaste websites en applicaties op maat om uw bedrijf te laten groeien en       op te vallen.",
+				"subtitle": "Aangepaste websites en applicaties op maat om uw bedrijf te laten groeien en op te vallen.",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d680e0 and 0d6f985.

📒 Files selected for processing (5)
  • apps/web/src/app/[locale]/about/page.tsx (1 hunks)
  • packages/design-system/components/arrow-link.tsx (2 hunks)
  • packages/design-system/components/section.tsx (2 hunks)
  • packages/i18n/dictionaries/en.json (1 hunks)
  • packages/i18n/dictionaries/nl.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: TypeCheck
  • GitHub Check: Lint
  • GitHub Check: E2E
🔇 Additional comments (8)
packages/design-system/components/section.tsx (2)

77-77: LGTM! Good use of polymorphic component pattern.

The addition of as?: React.ElementType to the cta object follows React's best practices for polymorphic components.


99-101: LGTM! Proper prop forwarding.

Clean implementation of forwarding the as prop to ArrowLink component.

packages/design-system/components/arrow-link.tsx (1)

64-64: LGTM! Type definition follows React conventions.

The as?: React.ElementType type is correctly defined for polymorphic component support.

apps/web/src/app/[locale]/about/page.tsx (5)

1-57: LGTM! Well-structured metadata implementation.

The metadata generation follows Next.js best practices with proper handling of:

  • Internationalized titles and descriptions
  • SEO metadata with OpenGraph image
  • Canonical URLs and language alternates

59-73: LGTM! Clean Hero section implementation.

The Hero section is well-structured with proper translation handling and clear call-to-action.


110-122: LGTM! Clean implementation of the Personal section.

The section follows the same consistent structure as the Professional section.


123-129: LGTM! Well-structured CTA implementation.

The CTA section is cleanly implemented with proper translation handling.


130-136: Consider validating the blog count parameter.

The BlogOverview component receives a hardcoded count of 2. Consider validating this parameter to ensure it's within acceptable bounds.

@darenmalfait darenmalfait merged commit 008f4cb into main Jan 7, 2025
3 checks passed
@darenmalfait darenmalfait deleted the refactor/migrate-about-to-custom-page branch January 7, 2025 08:33
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