Files
supabase/apps/studio/components/interfaces/Support/DocsSuggestions.tsx
Ali Waseem efdfb11f93 fix: Add intro text above suggested support articles (#46654)
Adds a short intro line above the suggested support articles list in the
new support case form so it's clearer that the items are clickable
links. Resolves FE-3548.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Documentation suggestions now include a short introductory message
above results and place recommendations inside a clearer grouped
container with improved spacing, enhancing readability while preserving
subtle dimming for older suggestions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-05 08:42:00 -06:00

94 lines
2.7 KiB
TypeScript

import { useDocsSearch, type DocsSearchResult } from 'common'
import { Book, Github, Loader2 } from 'lucide-react'
import { cn } from 'ui'
import { useChangedSync } from '@/hooks/misc/useChanged'
import { DOCS_URL } from '@/lib/constants'
function useDocsSuggestions(subject: string) {
const { handleDocsSearchDebounced, resetSearch, searchState } = useDocsSearch()
const trimmedSubject = subject.trim()
const subjectChanged = useChangedSync(trimmedSubject)
if (subjectChanged && trimmedSubject) {
handleDocsSearchDebounced(trimmedSubject)
} else if (subjectChanged && !trimmedSubject) {
resetSearch()
}
return searchState
}
interface DocsSuggestionsProps {
searchString: string
}
export function DocsSuggestions({ searchString }: DocsSuggestionsProps) {
const searchState = useDocsSuggestions(searchString)
const results =
'results' in searchState
? searchState.results
: 'staleResults' in searchState
? searchState.staleResults
: []
const resultsStale = searchState.status === 'loading'
return (
<>
{searchState.status === 'loading' && <DocsSuggestions_Loading />}
{results.length > 0 && <DocsSuggestions_Results results={results} isStale={resultsStale} />}
</>
)
}
function DocsSuggestions_Loading() {
return (
<div className="flex items-center gap-2 text-sm text-foreground-light">
<Loader2 className="animate-spin" size={14} />
<span>Searching for relevant resources...</span>
</div>
)
}
interface DocsSuggestions_ResultsProps {
results: DocsSearchResult[]
isStale: boolean
}
function DocsSuggestions_Results({ results, isStale }: DocsSuggestions_ResultsProps) {
return (
<div>
<p className="text-sm text-foreground-light">
Below are some articles that might help with your issue
</p>
<ul
className={cn(
'flex flex-col gap-y-0.5 py-1 transition-opacity duration-200',
isStale ? 'opacity-50' : 'opacity-100'
)}
>
{results.slice(0, 5).map((page) => {
return (
<li key={page.id} className="flex items-center gap-x-1">
{page.type === 'github-discussions' ? (
<Github size={16} className="text-foreground-muted" />
) : (
<Book size={16} className="text-foreground-muted" />
)}
<a
href={page.type === 'github-discussions' ? page.path : `${DOCS_URL}${page.path}`}
target="_blank"
rel="noreferrer"
className="text-sm text-foreground-light hover:text-foreground transition"
>
{page.title}
</a>
</li>
)
})}
</ul>
</div>
)
}