Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
84430b8
Improved about page
anurag2787 Sep 9, 2025
5d2da4b
Fix coderabbitai review
anurag2787 Sep 9, 2025
464d2c4
Fixed key
anurag2787 Sep 9, 2025
988066f
Fixed sonarqube issue
anurag2787 Sep 9, 2025
8479d0f
Merge branch 'main' into improve-about
kasya Sep 11, 2025
f91c9d8
Merge branch 'main' of github.com:anurag2787/Nest into improve-about
anurag2787 Sep 11, 2025
d646b20
Updated about page and added test
anurag2787 Sep 11, 2025
33b3173
Merge branch 'improve-about' of github.com:anurag2787/Nest into impro…
anurag2787 Sep 11, 2025
3f6de0a
Merge branch 'main' into improve-about
anurag2787 Sep 11, 2025
3d085a4
Merge branch 'main' into improve-about
kasya Sep 12, 2025
c09fd33
Merge branch 'main' into improve-about
kasya Sep 12, 2025
0249233
Merge branch 'main' into improve-about
kasya Sep 13, 2025
dbc2944
Merge branch 'main' into improve-about
kasya Sep 13, 2025
1ce9dc9
Merge branch 'main' into improve-about
kasya Sep 14, 2025
793ccbf
Merge branch 'main' into improve-about
kasya Sep 14, 2025
f563e5c
Merge branch 'main' of github.com:anurag2787/Nest into improve-about
anurag2787 Sep 15, 2025
0f983e8
Merge branch 'improve-about' of github.com:anurag2787/Nest into impro…
anurag2787 Sep 15, 2025
7fa1906
Moved get involved up
anurag2787 Sep 15, 2025
474d7cf
Merge branch 'main' into improve-about
kasya Sep 16, 2025
656856b
Update code
arkid15r Sep 27, 2025
4f040f7
Fix irregular gaps and tests. Update icons location.
kasya Sep 27, 2025
b9180e6
Fix typo
kasya Sep 27, 2025
0da3ec7
Update about data
kasya Sep 27, 2025
244bc08
Fix e2e tests
kasya Sep 27, 2025
c3aa10c
Merge branch 'main' into improve-about
kasya Sep 27, 2025
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
11 changes: 11 additions & 0 deletions frontend/__tests__/e2e/pages/About.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ test.describe('About Page', () => {

test('renders main sections correctly', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'About' })).toBeVisible()
await expect(page.getByRole('heading', { name: 'Project History', exact: true })).toBeVisible()
await expect(page.getByRole('heading', { name: 'History' })).toBeVisible()
await expect(page.getByRole('heading', { name: 'Leaders' })).toBeVisible()
await expect(page.getByRole('heading', { name: 'Roadmap' })).toBeVisible()
Expand Down Expand Up @@ -91,4 +92,14 @@ test.describe('About Page', () => {
test('breadcrumb renders correct segments on /about', async ({ page }) => {
await expectBreadCrumbsToBeVisible(page, ['Home', 'About'])
})

test('renders key features section', async ({ page }) => {
await expect(page.getByText('Key Features')).toBeVisible()
await expect(page.getByText('Advanced Search Capabilities')).toBeVisible()
})

test('renders project history timeline section', async ({ page }) => {
await expect(page.getByText('Project History')).toBeVisible()
await expect(page.getByText('Project Inception')).toBeVisible()
})
})
129 changes: 117 additions & 12 deletions frontend/__tests__/unit/pages/About.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,22 @@ jest.mock('@heroui/toast', () => ({
}))

jest.mock('utils/aboutData', () => ({
aboutText: [
'This is a test paragraph about the project.',
'This is another paragraph about the project history.',
missionContent: {
mission: 'Test mission statement',
whoItsFor: 'Test target audience description',
},
keyFeatures: [
{ title: 'Feature 1', description: 'Feature 1 description' },
{ title: 'Feature 2', description: 'Feature 2 description' },
],
getInvolvedContent: {
description: 'Get involved description',
ways: ['Way 1', 'Way 2'],
callToAction: 'Test call to action',
},
projectHistory: [
{ year: '2023', title: 'Test Event 1', description: 'Test description 1' },
{ year: '2024', title: 'Test Event 2', description: 'Test description 2' },
],
technologies: [
{
Expand Down Expand Up @@ -138,20 +151,49 @@ describe('About Component', () => {
jest.clearAllMocks()
})

test('renders project history correctly', async () => {
test('renders key features section correctly', async () => {
await act(async () => {
render(<About />)
})

const keyFeaturesSection = screen.getByText('Key Features').closest('div')
expect(keyFeaturesSection).toBeInTheDocument()

expect(screen.getByText('Feature 1')).toBeInTheDocument()
expect(screen.getByText('Feature 2')).toBeInTheDocument()
expect(screen.getAllByTestId('feature-description')).toHaveLength(2)
expect(screen.getByText('Feature 1 description')).toBeInTheDocument()
expect(screen.getByText('Feature 2 description')).toBeInTheDocument()
})

test('renders get involved section correctly', async () => {
await act(async () => {
render(<About />)
})

const getInvolvedSection = screen.getByText('Get Involved').closest('div')
expect(getInvolvedSection).toBeInTheDocument()

expect(screen.getByText('Get involved description')).toBeInTheDocument()
expect(screen.getByText('Way 1')).toBeInTheDocument()
expect(screen.getByText('Way 2')).toBeInTheDocument()
expect(screen.getByText('Test call to action')).toBeInTheDocument()
})

test('renders project history timeline correctly', async () => {
await act(async () => {
render(<About />)
})

const historySection = screen.getByText('History').closest('div')
expect(historySection).toBeInTheDocument()
const projectHistorySection = screen.getByText('Project History').closest('div')
expect(projectHistorySection).toBeInTheDocument()

const markdownContents = await screen.findAllByTestId('markdown-content')
expect(markdownContents.length).toBe(2)
expect(markdownContents[0].textContent).toBe('This is a test paragraph about the project.')
expect(markdownContents[1].textContent).toBe(
'This is another paragraph about the project history.'
)
expect(screen.getByText('Test Event 1')).toBeInTheDocument()
expect(screen.getByText('Test Event 2')).toBeInTheDocument()
expect(screen.getByText('Test description 1')).toBeInTheDocument()
expect(screen.getByText('Test description 2')).toBeInTheDocument()
expect(screen.getByText('2023')).toBeInTheDocument()
expect(screen.getByText('2024')).toBeInTheDocument()
})

test('renders leaders section with three leaders', async () => {
Expand Down Expand Up @@ -579,4 +621,67 @@ describe('About Component', () => {
})
})
})

test('renders mission and who its for sections correctly', async () => {
await act(async () => {
render(<About />)
})

const missionSection = screen.getByText('Mission').closest('div')
expect(missionSection).toBeInTheDocument()
expect(screen.getByText('Test mission statement')).toBeInTheDocument()

const whoItsForSection = screen.getByText("Who It's For").closest('div')
expect(whoItsForSection).toBeInTheDocument()
expect(screen.getByText('Test target audience description')).toBeInTheDocument()
})

test('renders mission section', async () => {
await act(async () => {
render(<About />)
})
expect(screen.getByText('Mission')).toBeInTheDocument()
expect(screen.getByText('Test mission statement')).toBeInTheDocument()
})

test("renders 'Who It's For' section", async () => {
await act(async () => {
render(<About />)
})
expect(screen.getByText("Who It's For")).toBeInTheDocument()
expect(screen.getByText(/Test target audience description/)).toBeInTheDocument()
})

test('renders key features section', async () => {
await act(async () => {
render(<About />)
})
expect(screen.getByText('Key Features')).toBeInTheDocument()
expect(screen.getByText('Feature 1')).toBeInTheDocument()
expect(screen.getByText('Feature 2')).toBeInTheDocument()
expect(screen.getByText('Feature 1 description')).toBeInTheDocument()
expect(screen.getByText('Feature 2 description')).toBeInTheDocument()
})

test('renders get involved section', async () => {
await act(async () => {
render(<About />)
})
expect(screen.getByText('Get Involved')).toBeInTheDocument()
expect(screen.getByText('Get involved description')).toBeInTheDocument()
expect(screen.getByText('Way 1')).toBeInTheDocument()
expect(screen.getByText('Way 2')).toBeInTheDocument()
expect(screen.getByText('Test call to action')).toBeInTheDocument()
})

test('renders project history timeline section', async () => {
await act(async () => {
render(<About />)
})
expect(screen.getByText('Project History')).toBeInTheDocument()
expect(screen.getByText('Test Event 1')).toBeInTheDocument()
expect(screen.getByText('Test Event 2')).toBeInTheDocument()
expect(screen.getByText('Test description 1')).toBeInTheDocument()
expect(screen.getByText('Test description 2')).toBeInTheDocument()
})
})
80 changes: 68 additions & 12 deletions frontend/src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
faClock,
faUserGear,
faMapSigns,
faScroll,
faUsers,
faTools,
faArrowUpRightFromSquare,
Expand All @@ -24,7 +23,13 @@ import { GET_LEADER_DATA } from 'server/queries/userQueries'
import type { Contributor } from 'types/contributor'
import type { Project } from 'types/project'
import type { User } from 'types/user'
import { aboutText, technologies } from 'utils/aboutData'
import {
technologies,
missionContent,
keyFeatures,
getInvolvedContent,
projectHistory,
} from 'utils/aboutData'
import AnchorTitle from 'components/AnchorTitle'
import AnimatedCounter from 'components/AnimatedCounter'
import LoadingSpinner from 'components/LoadingSpinner'
Expand Down Expand Up @@ -107,14 +112,27 @@ const About = () => {
<div className="min-h-screen p-8 text-gray-600 dark:bg-[#212529] dark:text-gray-300">
<div className="mx-auto max-w-6xl">
<h1 className="mt-4 mb-6 text-4xl font-bold">About</h1>
<SecondaryCard icon={faScroll} title={<AnchorTitle title="History" />}>
{aboutText.map((text) => (
<div key={text} className="mb-4">
<div key={text}>
<Markdown content={text} />
<div className="grid gap-6 md:grid-cols-2">
<SecondaryCard icon={faMapSigns} title={<AnchorTitle title="Mission" />}>
<p className="text-gray-600 dark:text-gray-300">{missionContent.mission}</p>
</SecondaryCard>

<SecondaryCard icon={faUsers} title={<AnchorTitle title="Who It's For" />}>
<p className="text-gray-600 dark:text-gray-300">{missionContent.whoItsFor}</p>
</SecondaryCard>
</div>

<SecondaryCard icon={faCircleCheck} title={<AnchorTitle title="Key Features" />}>
<div className="grid gap-4 md:grid-cols-2">
{keyFeatures.map((feature) => (
<div key={feature.title} className="rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
<h3 className="mb-2 text-lg font-semibold text-blue-400">{feature.title}</h3>
<p data-testid="feature-description" className="text-gray-600 dark:text-gray-300">
{feature.description}
</p>
</div>
</div>
))}
))}
</div>
</SecondaryCard>

<SecondaryCard icon={faArrowUpRightFromSquare} title={<AnchorTitle title="Leaders" />}>
Expand Down Expand Up @@ -216,22 +234,60 @@ const About = () => {
</Tooltip>
</h3>
</Link>
<p className="text-gray-600 dark:text-gray-300">{milestone.body}</p>
<p
data-testid="milestone-description"
className="text-gray-600 dark:text-gray-300"
>
{milestone.body}
</p>
</div>
</div>
))}
</div>
</SecondaryCard>
)}

<SecondaryCard icon={faUsers} title={<AnchorTitle title="Get Involved" />}>
<p className="mb-4 text-gray-600 dark:text-gray-300">{getInvolvedContent.description}</p>
<ul className="mb-6 list-inside list-disc space-y-2">
{getInvolvedContent.ways.map((way) => (
<li key={way} className="text-gray-600 dark:text-gray-300">
{way}
</li>
))}
</ul>
<Markdown content={getInvolvedContent.callToAction} />
</SecondaryCard>

<SecondaryCard icon={faClock} title={<AnchorTitle title="Project History" />}>
<div className="space-y-6">
{projectHistory.map((milestone, index) => (
<div key={`${milestone.year}-${milestone.title}`} className="relative pl-10">
{index !== projectHistory.length - 1 && (
<div className="absolute top-6 left-[7px] h-full w-0.5 bg-blue-400"></div>
)}
<div
aria-hidden="true"
className="absolute top-2 left-0 h-4 w-4 rounded-full bg-blue-400"
></div>
<div className="pt-1">
<h3 className="text-lg font-semibold text-blue-400">{milestone.year}</h3>
<h4 className="mb-1 font-medium">{milestone.title}</h4>
<p className="text-gray-600 dark:text-gray-300">{milestone.description}</p>
</div>
</div>
))}
</div>
</SecondaryCard>

<div className="grid gap-6 md:grid-cols-4">
{[
{ label: 'Forks', value: projectMetadata.forksCount },
{ label: 'Stars', value: projectMetadata.starsCount },
{ label: 'Contributors', value: projectMetadata.contributorsCount },
{ label: 'Open Issues', value: projectMetadata.issuesCount },
].map((stat, index) => (
<div key={index}>
].map((stat) => (
<div key={stat.label}>
<SecondaryCard className="text-center">
<div className="mb-2 text-3xl font-bold text-blue-400">
<AnimatedCounter end={Math.floor(stat.value / 10) * 10} duration={2} />+
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/types/about.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface KeyFeature {
title: string
description: string
}

export interface ProjectHistory {
year: string
title: string
description: string
}

export interface GetInvolved {
description: string
ways: string[]
callToAction: string
}

export interface MissionContent {
mission: string
whoItsFor: string
}
Loading