Skip to content
Open
42 changes: 23 additions & 19 deletions app/search/SearchPageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PageLayout } from '@/app/layouts/PageLayout';
import { MainPageHeader } from '@/components/ui/MainPageHeader';
import { Search as SearchIcon } from 'lucide-react';
import { FeedContent } from '@/components/Feed/FeedContent';
import { FeedViewProvider } from '@/contexts/FeedViewContext';

interface SearchPageContentProps {
readonly searchParams: {
Expand Down Expand Up @@ -157,25 +158,28 @@ export function SearchPageContent({ searchParams }: SearchPageContentProps) {

{/* Use FeedContent for consistent rendering and infinite scroll */}
{hasSearched && (
<FeedContent
entries={entries}
isLoading={isLoading}
isLoadingMore={isLoadingMore}
hasMore={hasMore}
loadMore={loadMore}
showGrantHeaders={true}
showReadMoreCTA={true}
hideActions={true}
noEntriesElement={
<SearchEmptyState
onSearch={handleSearch}
query={query}
filters={stagedFilters}
hasFilters={false}
onClearFilters={() => {}}
/>
}
/>
<FeedViewProvider value="search">
<FeedContent
entries={entries}
isLoading={isLoading}
isLoadingMore={isLoadingMore}
hasMore={hasMore}
loadMore={loadMore}
showGrantHeaders={true}
showReadMoreCTA={true}
hideActions={false}
showOnlyBookmark={true}
noEntriesElement={
<SearchEmptyState
onSearch={handleSearch}
query={query}
filters={stagedFilters}
hasFilters={false}
onClearFilters={() => {}}
/>
}
/>
</FeedViewProvider>
)}
</div>
</div>
Expand Down
61 changes: 34 additions & 27 deletions components/Feed/BaseFeedItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@ import { FeedItemActions } from '@/components/Feed/FeedItemActions';
import { CardWrapper } from './CardWrapper';
import { cn } from '@/utils/styles';
import Image from 'next/image';
import { stripHtml, truncateText } from '@/utils/stringUtils';
import { truncateText } from '@/utils/stringUtils';
import { TopicAndJournalBadge } from '@/components/ui/TopicAndJournalBadge';
import { useNavigation } from '@/contexts/NavigationContext';
import { Button } from '@/components/ui/Button';
import { ChevronDown } from 'lucide-react';
import { BountyInfoSummary } from '@/components/Bounty/BountyInfoSummary';
import { useRouter } from 'next/navigation';
import { BountyInfo } from '../Bounty/BountyInfo';
import { sanitizeHighlightHtml } from '@/components/Search/lib/htmlSanitizer';
import { Button } from '@/components/ui/Button';
import { ChevronDown } from 'lucide-react';

// Base interfaces for the modular components
export interface BaseFeedItemProps {
entry: FeedEntry;
href?: string;
className?: string;
showActions?: boolean;
showOnlyBookmark?: boolean;
showTooltips?: boolean;
maxLength?: number;
showHeader?: boolean;
Expand Down Expand Up @@ -170,7 +171,8 @@ export const ContentSection: FC<ContentSectionProps> = ({
setIsExpanded(!isExpanded);
};

// If we have highlighted HTML, render it (already truncated by backend)
// If we have highlighted HTML (from search service), render it as-is
// The search service is responsible for extending snippets to appropriate length
if (highlightedContent) {
return (
<div className={cn('text-sm text-gray-700', className)}>
Expand All @@ -183,29 +185,32 @@ export const ContentSection: FC<ContentSectionProps> = ({
);
}

// Default: render truncated plain text
return (
<div className={cn('text-sm text-gray-900 hidden md:!block leading-relaxed', className)}>
<p>{isExpanded ? content : truncateText(content, maxLength)}</p>
{isTextTruncated && (
<Button
variant="link"
size="sm"
onClick={handleToggleExpand}
className="flex items-center gap-0.5 mt-1 text-blue-500 p-0 h-auto text-sm font-medium"
>
{isExpanded ? 'Show less' : 'Read more'}
<ChevronDown
size={14}
className={cn(
'transition-transform duration-200',
isExpanded && 'transform rotate-180'
)}
/>
</Button>
)}
</div>
);
// Default: render truncated plain text with expand/collapse for non-search results
if (content) {
return (
<div className={cn('text-sm text-gray-900 hidden md:!block leading-relaxed', className)}>
<p>{isExpanded ? content : truncateText(content, maxLength)}</p>
{isTextTruncated && (
<Button
variant="link"
size="sm"
onClick={handleToggleExpand}
className="flex items-center gap-0.5 mt-1 text-blue-500 p-0 h-auto text-sm font-medium"
>
{isExpanded ? 'Show less' : 'Read more'}
<ChevronDown
size={14}
className={cn(
'transition-transform duration-200',
isExpanded && 'transform rotate-180'
)}
/>
</Button>
)}
</div>
);
}
return null;
};

export const ImageSection: FC<ImageSectionProps> = ({
Expand Down Expand Up @@ -284,6 +289,7 @@ export const BaseFeedItem: FC<BaseFeedItemProps> = ({
href,
className,
showActions = true,
showOnlyBookmark = false,
showTooltips = true,
maxLength,
showHeader = true,
Expand Down Expand Up @@ -443,6 +449,7 @@ export const BaseFeedItem: FC<BaseFeedItemProps> = ({
onFeedItemClick={onFeedItemClick}
bounties={showBountyInfo ? undefined : content.bounties}
hideReportButton={hideReportButton}
showOnlyBookmark={showOnlyBookmark}
/>
</div>
)}
Expand Down
3 changes: 3 additions & 0 deletions components/Feed/FeedContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface FeedContentProps {
activeTab?: FeedTab | FundingTab | TabType | string;
showBountyFooter?: boolean;
hideActions?: boolean;
showOnlyBookmark?: boolean;
isLoadingMore?: boolean;
noEntriesElement?: ReactNode;
maxLength?: number;
Expand Down Expand Up @@ -58,6 +59,7 @@ export const FeedContent: FC<FeedContentProps> = ({
activeTab,
showBountyFooter = true,
hideActions = false,
showOnlyBookmark = false,
isLoadingMore = false,
noEntriesElement,
maxLength,
Expand Down Expand Up @@ -155,6 +157,7 @@ export const FeedContent: FC<FeedContentProps> = ({
index={index}
showBountyFooter={showBountyFooter}
hideActions={hideActions}
showOnlyBookmark={showOnlyBookmark}
maxLength={maxLength}
showGrantHeaders={showGrantHeaders}
showFundraiseHeaders={showFundraiseHeaders}
Expand Down
3 changes: 3 additions & 0 deletions components/Feed/FeedEntryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface FeedEntryItemProps {
index: number;
showBountyFooter?: boolean;
hideActions?: boolean;
showOnlyBookmark?: boolean;
maxLength?: number;
showGrantHeaders?: boolean;
showFundraiseHeaders?: boolean;
Expand All @@ -51,6 +52,7 @@ export const FeedEntryItem: FC<FeedEntryItemProps> = ({
index,
showBountyFooter = true,
hideActions = false,
showOnlyBookmark = false,
maxLength,
showGrantHeaders = true,
showFundraiseHeaders = true,
Expand Down Expand Up @@ -204,6 +206,7 @@ export const FeedEntryItem: FC<FeedEntryItemProps> = ({
entry={entry}
href={href}
showActions={!hideActions}
showOnlyBookmark={showOnlyBookmark}
maxLength={maxLength}
onFeedItemClick={handleFeedItemClick}
highlights={highlights}
Expand Down
Loading