8000 fixed responsiveness issue in chapters page by M-ayank2005 · Pull Request #1453 · OWASP/Nest · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fixed responsiveness issue in chapters page #1453

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
163 changes: 61 additions & 102 deletions frontend/src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { Tooltip } from '@heroui/tooltip'
import Link from 'next/link'
import { useState, useEffect } from 'react'
import { CardProps } from 'types/card'
import { desktopViewMinWidth } from 'utils/constants'
import { Icons } from 'utils/data'
import { getSocialIcon } from 'utils/urlIconMappings'
import { cn } from 'utils/utility'
import FontAwesomeIconWrapper from 'wrappers/FontAwesomeIconWrapper'
import ContributorAvatar from 'components/ContributorAvatar'
import ActionButton from './ActionButton'
import DisplayIcon from './DisplayIcon'
import Markdown from './MarkdownWrapper'

// Initial check for mobile screen size
const isMobileInitial = typeof window !== 'undefined' && window.innerWidth < desktopViewMinWidth

const Card = ({
title,
Expand All @@ -29,21 +24,10 @@ const Card = ({
social,
tooltipLabel,
}: CardProps) => {
const [isMobile, setIsMobile] = useState(isMobileInitial)

// Resize listener to adjust display based on screen width
useEffect(() => {
const checkMobile = () => {
const mobile = window.innerWidth < desktopViewMinWidth
setIsMobile(mobile)
}
window.addEventListener('resize', checkMobile)
return () => window.removeEventListener('resize', checkMobile)
}, [])

return (
<div className="mx-auto mb-2 mt-4 flex w-full max-w-[95%] flex-col items-start rounded-md border border-border bg-white px-4 pb-4 pl-4 dark:bg-[#212529] md:max-w-6xl">
<div className="mt-2 flex w-full flex-col items-start gap-4 pt-2 sm:flex-col sm:gap-4 md:pt-0">
<div className="mx-auto mb-2 mt-4 flex w-full max-w-[95%] flex-col items-start rounded-md border border-border bg-white p-4 dark:bg-[#212529] md:max-w-6xl">
{/* Card Header with Badge and Title */}
<div className="w-full">
<div className="flex items-center gap-3">
{/* Display project level badge (if available) */}
{level && (
Expand All @@ -56,9 +40,7 @@ const Card = ({
showArrow
>
<span
className={cn(
'flex h-8 w-8 items-center justify-center rounded-full text-xs shadow'
)}
className="flex h-8 w-8 min-w-8 items-center justify-center rounded-full text-xs shadow"
style={{ backgroundColor: level.color }}
>
<FontAwesomeIconWrapper icon={level.icon} className="text-white" />
Expand All @@ -68,7 +50,7 @@ const Card = ({
{/* Project title and link */}
<Link href={url} target="_blank" rel="noopener noreferrer" className="flex-1">
<h1
className="max-w-full break-words text-base font-semibold text-blue-400 sm:break-normal sm:text-lg lg:text-2xl"
className="max-w-full break-words text-base font-semibold text-blue-400 hover:text-blue-600 sm:break-normal sm:text-lg lg:text-2xl"
style={{
transition: 'color 0.3s ease',
}}
Expand All @@ -77,9 +59,10 @@ const Card = ({
</h1>
</Link>
</div>

{/* Icons associated with the project */}
{icons && Object.keys(Icons).some((key) => icons[key]) ? (
<div className="-ml-1.5 flex flex-grow">
{icons && Object.keys(Icons).some((key) => icons[key]) && (
<div className="mt-3 flex flex-wrap">
{Object.keys(Icons).map((key, index) =>
icons[key] ? (
<DisplayIcon
Expand All @@ -90,93 +73,69 @@ const Card = ({
) : null
)}
</div>
) : null}
)}
</div>
{/* Link to project name if provided */}

{/* Project name link (if provided) */}
{projectName && (
<Link href={projectLink || ''} rel="noopener noreferrer" className="mt-2 font-medium">
<Link
href={projectLink | 10000 | ''}
target="_blank"
rel="noopener noreferrer"
className="mt-3 font-medium text-gray-700 hover:text-blue-500 dark:text-gray-300"
>
{projectName}
</Link>
)}
{/* Render project summary using Markdown */}
<Markdown content={summary} className="py-2 pr-4 text-gray-600 dark:text-gray-300" />
<div
className={
social && social.length > 0
? 'flex w-full flex-col gap-2 pr-4'
: 'flex w-full items-center justify-between'
}
>
{/* Render top contributors as avatars */}
<div className="mt-3 flex w-full flex-wrap items-center gap-2">
{topContributors?.map((contributor, index) => (
<ContributorAvatar
key={contributor.login || `contributor-${index}`}
contributor={contributor}
uniqueKey={index.toString()}
/>
))}
</div>
{!social || social.length === 0 ? (
<div
className={cn(
'mt-3 flex items-center pr-4',
isMobile && 'mt-4 w-full justify-end pr-4'
)}
>

{/* Project summary */}
<Markdown content={summary} className="mt-2 w-full text-gray-600 dark:text-gray-300" />

{/* Bottom section with social links, contributors and action button */}
<div className="mt-4 w-full">
{/* Social icons section */}
{social && social.length > 0 && (
<div className="mb-3 flex">
<div className="flex flex-wrap gap-3">
{social.map((item) => (
<Link
key={`${item.title}-${item.url}`}
href={item.url}
target="_blank"
rel="noopener noreferrer"
className="transition-colors"
>
<FontAwesomeIcon
icon={getSocialIcon(item.url)}
className="h-5 w-5 text-blue-500 hover:text-gray-600 dark:hover:dark:text-gray-400"
/>
</Link>
))}
</div>
</div>
)}

{/* Flexible bottom row with contributors and action button */}
<div className="flex w-full flex-col space-y-3 sm:flex-row sm:items-center sm:justify-between sm:space-y-0">
{/* Contributors section */}
<div className="flex flex-wrap items-center gap-2">
{topContributors?.map((contributor, index) => (
<ContributorAvatar
key={contributor.login || `contributor-${index}`}
contributor={contributor}
uniqueKey={index.toString()}
/>
))}
</div>

{/* Action Button */}
<div className="flex sm:justify-end">
<ActionButton tooltipLabel={tooltipLabel} url={button.url} >
{button.icon}
{button.label}
</ActionButton>
</div>
) : (
<div
className={cn(
'flex w-full flex-wrap items-center justify-between gap-6',
isMobile && 'items-start'
)}
>
<div
className={cn('flex w-full items-center justify-between', isMobile && 'flex-wrap')}
>
{/* Render social links if available */}
{social && social.length > 0 && (
<div id="social" className="mt-2 flex flex-row gap-1">
{social.map((item) => (
<Tooltip
key={`${item.title}-${item.url}`}
content={item.title}
id={`social-tooltip-${item.title}`}
placement="bottom"
delay={100}
closeDelay={100}
showArrow
>
<Link
href={item.url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2"
>
<FontAwesomeIcon
icon={getSocialIcon(item.url)}
className="h-5 w-5 transition-transform duration-300 hover:scale-110 hover:text-blue-400"
6BFF />
</Link>
</Tooltip>
))}
</div>
)}
{/* Action Button */}
<div className="flex items-center">
<ActionButton tooltipLabel={tooltipLabel} url={button.url} >
{button.icon}
{button.label}
</ActionButton>
</div>
</div>
</div>
)}
</div>
</div>
</div>
)
Expand Down
0