Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5e24a6d
Fix homepage container flexibility
OUMIMANDAL Aug 19, 2025
caea551
Restore pnpm-lock.yaml
OUMIMANDAL Aug 19, 2025
7e7c88e
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 19, 2025
026ee9a
refactor: fix layout duplication and styling issues
OUMIMANDAL Aug 19, 2025
305d246
Merge branch 'fix-homepage-container-flexibility' of https://github.c…
OUMIMANDAL Aug 19, 2025
8a73963
fix: merge duplicate :root block in globals.css
OUMIMANDAL Aug 19, 2025
8917f7c
fix: mark layout props as read-only
OUMIMANDAL Aug 19, 2025
3789e3d
fix: correctly mark RootLayout props as read-only
OUMIMANDAL Aug 19, 2025
5e0536e
refactor: unify dark-mode map-tiles filter under .dark class
OUMIMANDAL Aug 19, 2025
f565947
Merge branch 'main' into fix-homepage-container-flexibility
kasya Aug 20, 2025
37fa65b
refactor: remove redundant @media wrapper for .dark .map-tiles
OUMIMANDAL Aug 20, 2025
4b93f3e
Merge branch 'fix-homepage-container-flexibility' of https://github.c…
OUMIMANDAL Aug 20, 2025
adb2e32
refactor: use IssueMetadata across components to reduce duplication
OUMIMANDAL Aug 20, 2025
64ffd22
fix: rename tailwind.config.ts → .js to avoid import issues
OUMIMANDAL Aug 20, 2025
058cdd7
fix: rename tailwind.config.ts to .js to avoid import issues
OUMIMANDAL Aug 20, 2025
41d79c1
fix: restore tailwind.config.ts and fix CJS wrapper
OUMIMANDAL Aug 20, 2025
fdd40ea
chore: remove duplicate tailwind.config.js
OUMIMANDAL Aug 20, 2025
3419a80
fix: allow className in Footer and fix release link
OUMIMANDAL Aug 21, 2025
2e76459
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 25, 2025
891dd58
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 26, 2025
2cd43f6
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 26, 2025
d87feba
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 27, 2025
03f7dcc
Merge branch 'main' into fix-homepage-container-flexibility
kasya Aug 28, 2025
b952945
Bump github/codeql-action from 3.29.8 to 3.29.9 (#2064)
dependabot[bot] Aug 13, 2025
ec0d606
Resolve merge conflict in pnpm-lock.yaml
OUMIMANDAL Aug 21, 2025
23facd8
fix: resolve conflicts and update layout/tailwind
OUMIMANDAL Aug 27, 2025
558aa6f
chore: resolve merge conflicts
OUMIMANDAL Aug 27, 2025
48f79f1
Update pre-commit: add pyproject-fmt
arkid15r Aug 13, 2025
5892607
Add id field to graphql entities (#2045)
rudransh-shrivastava Aug 14, 2025
7352a18
Run make update
arkid15r Aug 14, 2025
df7aff0
test- inmproved test coverage of github internal nodes more than 80% …
trucodd Aug 15, 2025
c425484
Run make update
arkid15r Aug 15, 2025
6ee3cd5
Using default message
arkid15r Aug 16, 2025
dc5ed1d
removed leader and suggested leader, introduced entity_member model (…
abhayymishraa Aug 17, 2025
690fe21
Update entity member admin mixin
arkid15r Aug 17, 2025
f4d49ea
Using default message
arkid15r Aug 18, 2025
10082d5
Using default message
arkid15r Aug 19, 2025
f17b2e7
Using default message
dependabot[bot] Aug 19, 2025
e483c63
Bump github/codeql-action from 3.29.9 to 3.29.10 (#2099)
dependabot[bot] Aug 19, 2025
e625c12
fix: merge duplicate :root block in globals.css
OUMIMANDAL Aug 19, 2025
8b5e522
fix: mark layout props as read-only
OUMIMANDAL Aug 19, 2025
1117ef3
fix: correctly mark RootLayout props as read-only
OUMIMANDAL Aug 19, 2025
2f37ee0
refactor: unify dark-mode map-tiles filter under .dark class
OUMIMANDAL Aug 19, 2025
0bdde86
refactor: remove redundant @media wrapper for .dark .map-tiles
OUMIMANDAL Aug 20, 2025
ba63156
Fix #1882: Added test for RecentIssues Component (#2087)
anurag2787 Aug 20, 2025
c5e0993
Integrate Lighthouse CI (#2079)
rudransh-shrivastava Aug 20, 2025
b083a8a
refactor: use IssueMetadata across components to reduce duplication
OUMIMANDAL Aug 20, 2025
4bbc988
Using default message
OUMIMANDAL Aug 20, 2025
b0627fe
fix: rename tailwind.config.ts to .js to avoid import issues
OUMIMANDAL Aug 20, 2025
a735bd5
fix: restore tailwind.config.ts and fix CJS wrapper
OUMIMANDAL Aug 20, 2025
2f6d0e7
Using default message
OUMIMANDAL Aug 20, 2025
3fcd9f9
Using default message
OUMIMANDAL Aug 21, 2025
dc248c0
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 28, 2025
9641262
Merge branch 'main' into fix-homepage-container-flexibility
OUMIMANDAL Aug 29, 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
19 changes: 14 additions & 5 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
"lint": "eslint . --config eslint.config.mjs --fix --max-warnings=0",
"lint:check": "eslint . --config eslint.config.mjs --max-warnings=0",
"start": "next start",
"test:e2e": "npx playwright test",
"test:unit": "tsc --noEmit && NODE_OPTIONS='--experimental-vm-modules --no-warnings=DEP0040' jest"
"test": "pnpm test:unit",
"test:unit": "tsc --noEmit && cross-env NODE_OPTIONS=--experimental-vm-modules --no-warnings=DEP0040 jest",
"test:e2e": "playwright test",
"test:all": "pnpm test:unit && pnpm test:e2e"
Comment on lines +17 to +20
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

cross-env is used in scripts but not declared — tests will fail.

test:unit references cross-env, but it is missing from devDependencies. CI/local runs without a global install will error with “cross-env: command not found”.

Add cross-env to devDependencies:

   "devDependencies": {
+    "cross-env": "^7.0.3",
📝 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
"test": "pnpm test:unit",
"test:unit": "tsc --noEmit && cross-env NODE_OPTIONS=--experimental-vm-modules --no-warnings=DEP0040 jest",
"test:e2e": "playwright test",
"test:all": "pnpm test:unit && pnpm test:e2e"
// frontend/package.json
{
// …
"scripts": {
"test": "pnpm test:unit",
"test:unit": "tsc --noEmit && cross-env NODE_OPTIONS=--experimental-vm-modules --no-warnings=DEP0040 jest",
"test:e2e": "playwright test",
"test:all": "pnpm test:unit && pnpm test:e2e"
},
"devDependencies": {
"cross-env": "^7.0.3",
// …other devDependencies…
}
}
🤖 Prompt for AI Agents
In frontend/package.json around lines 15 to 18, the test:unit script uses
cross-env but cross-env is not listed in devDependencies causing CI/local runs
to fail with “cross-env: command not found”; add cross-env to devDependencies in
package.json (pick a stable version or use latest caret range), run your package
manager to install/update lockfile, and ensure CI pipeline installs
devDependencies so the script can run.

},
"dependencies": {
"@apollo/client": "^3.13.9",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-regular-svg-icons": "^6.7.2",
Expand Down Expand Up @@ -45,7 +46,6 @@
"dompurify": "^3.2.6",
"eslint-plugin-import": "^2.32.0",
"framer-motion": "^12.23.12",
"graphql": "^16.11.0",
"leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"lodash": "^4.17.21",
Expand All @@ -58,9 +58,12 @@
"react-apexcharts": "^1.7.0",
"react-dom": "^19.1.1",
"react-icons": "^5.5.0",


"react-router-dom": "^7.8.1",
"tailwind-merge": "^3.3.1",
"tailwindcss-animate": "^1.0.7"

},
"devDependencies": {
"@axe-core/react": "^4.10.2",
Expand All @@ -70,7 +73,11 @@
"@swc/core": "^1.13.3",
"@swc/jest": "^0.2.39",
"@tailwindcss/postcss": "^4.1.12",
Comment on lines 79 to 80
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Pick a single Jest transformer.

Both @swc/jest and ts-jest are present; using both can conflict. Prefer @swc/jest for speed, or keep ts-jest — but not both in config.

Run to see what your config uses:

If only one is referenced, remove the unused package.

Also applies to: 117-117


🏁 Script executed:

#!/bin/bash
rg -nP -C2 '(jest\.config|setupFiles|setupFilesAfterEnv|jest":\s*{)'
rg -nP -C3 '"transform"\s*:\s*{[^}]*}'
rg -nP -C2 '(ts-jest|@swc/jest)'

Length of output: 5414


Remove unused ts-jest dependency

transform in frontend/jest.config.ts only references @swc/jest, so ts-jest in package.json (line 117) isn’t used and should be removed.

🤖 Prompt for AI Agents
In frontend/package.json (noting the current diff at lines 78-79 and the unused
"ts-jest" entry around line 117), remove the "ts-jest" dependency entry from the
dependencies/devDependencies block so only @swc/jest remains; after editing, run
the package manager (npm/yarn/pnpm) to update node_modules and the lockfile to
keep manifests in sync.


"@testing-library/jest-dom": "^6.7.0",



"@testing-library/react": "^16.3.0",
"@types/jest": "^29.5.14",
"@types/leaflet": "^1.9.20",
Expand All @@ -83,6 +90,7 @@
"@typescript-eslint/eslint-plugin": "^8.40.0",
"@typescript-eslint/parser": "^8.40.0",
"autoprefixer": "^10.4.21",
"cross-env": "^10.0.0",
"eslint": "^9.33.0",
"eslint-config-next": "^15.4.7",
"eslint-config-prettier": "^10.1.8",
Expand All @@ -103,7 +111,8 @@
"prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.6.14",
"require-in-the-middle": "^7.5.2",
"tailwindcss": "^3.4.17",
"tailwindcss": "^4.1.12",
"tailwindcss-animate": "^1.0.7",
"ts-jest": "^29.4.1",
"ts-node": "^10.9.2",
"typescript": "~5.8.3",
Expand Down
1,081 changes: 307 additions & 774 deletions frontend/pnpm-lock.yaml

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions frontend/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ignoredBuiltDependencies:
- '@heroui/shared-utils'
- '@sentry/cli'
- core-js
- unrs-resolver
onlyBuiltDependencies:
- '@swc/core'
- '@tailwindcss/oxide'
- sharp
2 changes: 1 addition & 1 deletion frontend/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
plugins: {
"@tailwindcss/postcss": {},
autoprefixer: {},
tailwindcss: {},
},
}
10 changes: 2 additions & 8 deletions frontend/src/app/about/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import { Metadata } from 'next'
import React from 'react'
import { getStaticMetadata } from 'utils/metaconfig'

export const metadata: Metadata = getStaticMetadata('about', '/about')

export default function AboutLayout({ children }: { children: React.ReactNode }) {
return children
}
return children;
}
292 changes: 9 additions & 283 deletions frontend/src/app/about/page.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is going on here?! 👀
please clean this up and revert any unnecessary changes for any of these file.
I would not expect this fix to require sooo many changes.

Original file line number Diff line number Diff line change
@@ -1,285 +1,11 @@
'use client'
import { useQuery } from '@apollo/client'
import {
faCircleCheck,
faClock,
faUserGear,
faMapSigns,
faScroll,
faUsers,
faTools,
faArrowUpRightFromSquare,
} from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { Tooltip } from '@heroui/tooltip'
import upperFirst from 'lodash/upperFirst'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
import FontAwesomeIconWrapper from 'wrappers/FontAwesomeIconWrapper'
import { ErrorDisplay, handleAppError } from 'app/global-error'
import { GET_PROJECT_METADATA, GET_TOP_CONTRIBUTORS } from 'server/queries/projectQueries'
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 AnchorTitle from 'components/AnchorTitle'
import AnimatedCounter from 'components/AnimatedCounter'
import LoadingSpinner from 'components/LoadingSpinner'
import Markdown from 'components/MarkdownWrapper'
import SecondaryCard from 'components/SecondaryCard'
import TopContributorsList from 'components/TopContributorsList'
import UserCard from 'components/UserCard'

const leaders = {
arkid15r: 'CCSP, CISSP, CSSLP',
kasya: 'CC',
mamicidal: 'CISSP',
}
const projectKey = 'nest'

const About = () => {
const { data: projectMetadataResponse, error: projectMetadataRequestError } = useQuery(
GET_PROJECT_METADATA,
{
variables: { key: projectKey },
}
)

const { data: topContributorsResponse, error: topContributorsRequestError } = useQuery(
GET_TOP_CONTRIBUTORS,
{
variables: {
excludedUsernames: Object.keys(leaders),
hasFullName: true,
key: projectKey,
limit: 24,
},
}
)

const [projectMetadata, setProjectMetadata] = useState<Project | null>(null)
const [topContributors, setTopContributors] = useState<Contributor[]>([])

useEffect(() => {
if (projectMetadataResponse?.project) {
setProjectMetadata(projectMetadataResponse.project)
}

if (projectMetadataRequestError) {
handleAppError(projectMetadataRequestError)
}
}, [projectMetadataResponse, projectMetadataRequestError])

useEffect(() => {
if (topContributorsResponse?.topContributors) {
setTopContributors(topContributorsResponse.topContributors)
}

if (topContributorsRequestError) {
handleAppError(topContributorsRequestError)
}
}, [topContributorsResponse, topContributorsRequestError])

const isLoading =
!projectMetadataResponse ||
!topContributorsResponse ||
(projectMetadataRequestError && !projectMetadata) ||
(topContributorsRequestError && !topContributors)

if (isLoading) {
return <LoadingSpinner />
}

if (!projectMetadata || !topContributors) {
return (
<ErrorDisplay
statusCode={404}
title="Data not found"
message="Sorry, the page you're looking for doesn't exist"
/>
)
}

export default function AboutPage() {
return (
<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="mb-6 mt-4 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>
</div>
))}
</SecondaryCard>

<SecondaryCard icon={faArrowUpRightFromSquare} title={<AnchorTitle title="Leaders" />}>
<div className="flex w-full flex-col items-center justify-around overflow-hidden md:flex-row">
{Object.keys(leaders).map((username) => (
<div key={username}>
<LeaderData username={username} />
</div>
))}
</div>
</SecondaryCard>

{topContributors && (
<TopContributorsList
contributors={topContributors}
icon={faUsers}
maxInitialDisplay={12}
/>
)}

<SecondaryCard icon={faTools} title={<AnchorTitle title="Technologies & Tools" />}>
<div className="w-full">
<div className="grid w-full grid-cols-1 justify-center sm:grid-cols-2 lg:grid-cols-4 lg:pl-8">
{technologies.map((tech) => (
<div key={tech.section} className="mb-2">
<h3 className="mb-3 font-semibold text-blue-400">{tech.section}</h3>
<ul className="space-y-3">
{Object.entries(tech.tools).map(([name, details]) => (
<li key={name} className="flex flex-row items-center gap-2">
<Image
alt={`${name} icon`}
className="inline-block align-middle grayscale"
height={24}
src={details.icon}
width={24}
/>
<Link
href={details.url}
className="text-gray-600 hover:underline dark:text-gray-300"
target="_blank"
rel="noopener noreferrer"
>
{upperFirst(name)}
</Link>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</SecondaryCard>

{projectMetadata.recentMilestones.length > 0 && (
<SecondaryCard icon={faMapSigns} title={<AnchorTitle title="Roadmap" />}>
<div className="grid gap-4">
{[...projectMetadata.recentMilestones]
.filter((milestone) => milestone.state !== 'closed')
.sort((a, b) => (a.title > b.title ? 1 : -1))
.map((milestone, index) => (
<div
key={milestone.url || milestone.title || index}
className="flex items-center gap-4 overflow-hidden rounded-lg bg-gray-200 p-6 dark:bg-gray-700"
>
<div className="flex-1">
<Link
href={milestone.url}
target="_blank"
rel="noopener noreferrer"
className="inline-block"
>
<h3 className="mb-2 text-xl font-semibold text-blue-400">
{milestone.title}
<Tooltip
closeDelay={100}
content={
milestone.progress === 100
? 'Completed'
: milestone.progress > 0
? 'In Progress'
: 'Not Started'
}
id={`tooltip-state-${index}`}
delay={100}
placement="top"
showArrow
>
<span className="ml-4 inline-block text-gray-400">
<FontAwesomeIcon
icon={
milestone.progress === 100
? faCircleCheck
: milestone.progress > 0
? faUserGear
: faClock
}
/>
</span>
</Tooltip>
</h3>
</Link>
<p className="text-gray-600 dark:text-gray-300">{milestone.body}</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}>
<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} />+
</div>
<div className="text-gray-600 dark:text-gray-300">{stat.label}</div>
</SecondaryCard>
</div>
))}
</div>
</div>
<div className="p-8 font-sans">
<h1 className="text-3xl font-bold mb-4">About OWASP Nest</h1>
<p>
OWASP Nest is a platform to discover, engage, and contribute to OWASP
projects and initiatives. It serves as a central hub for the community.
</p>
</div>
)
}

const LeaderData = ({ username }: { username: string }) => {
const { data, loading, error } = useQuery(GET_LEADER_DATA, {
variables: { key: username },
})
const router = useRouter()

if (loading) return <p>Loading {username}...</p>
if (error) return <p>Error loading {username}'s data</p>

const user = data?.user

if (!user) {
return <p>No data available for {username}</p>
}

const handleButtonClick = (user: User) => {
router.push(`/members/${user.login}`)
}

return (
<UserCard
avatar={user.avatarUrl}
button={{
icon: <FontAwesomeIconWrapper icon="fa-solid fa-right-to-bracket" />,
label: 'View Profile',
onclick: () => handleButtonClick(user),
}}
className="h-64 w-40 bg-inherit"
company={user.company}
description={leaders[user.login]}
location={user.location}
name={user.name || username}
/>
)
}

export default About
);
}
Loading