Spaces:
Build error
Build error
import { Badge } from "~/components/ui/badge" | |
import { ScrollArea } from "~/components/ui/scroll-area" | |
import type { AnswersQuery } from "~/generated/graphql" | |
import { cn } from "~/lib/utils" | |
type AnswerListProps = { | |
items: NonNullable<NonNullable<AnswersQuery["answers"]>["answers"]> | |
} | |
export function AnswerList({ items }: AnswerListProps) { | |
return ( | |
<ScrollArea className="h-screen"> | |
{0 < items.length ? ( | |
<div className="flex flex-col gap-2 p-4 pt-0"> | |
{items.map((item) => ( | |
<div | |
key={item.docId} | |
className={cn( | |
"flex flex-col items-start gap-5 rounded-lg border p-3 text-left text-sm transition-all hover:bg-accent", | |
)} | |
> | |
<div className="flex w-full flex-col gap-1"> | |
<div className="flex items-center"> | |
<div className="flex items-center gap-2"> | |
<div className="font-semibold">{item.question}</div> | |
</div> | |
</div> | |
</div> | |
<article className="prose prose-sm max-w-none"> | |
<div | |
className="whitespace-pre-line" | |
/* biome-ignore lint/security/noDangerouslySetInnerHtml: */ | |
dangerouslySetInnerHTML={{ | |
__html: unsafeConvertToAnchorTag(item.answer), | |
}} | |
/> | |
</article> | |
{(item.categoryMajor ?? | |
item.categoryMinor ?? | |
item.categoryMedium) && ( | |
<div className="flex text-xs items-center gap-2"> | |
{item.categoryMajor && ( | |
<Badge variant={"default"}>{item.categoryMajor}</Badge> | |
)} | |
{item.categoryMedium && ( | |
<Badge variant={"secondary"}>{item.categoryMedium}</Badge> | |
)} | |
</div> | |
)} | |
</div> | |
))} | |
</div> | |
) : ( | |
<div className="pt-4 md:pt-8 text-center text-muted-foreground text-sm leading-6"> | |
<p className="mb-2">ใใณใ:</p> | |
<ul> | |
<li>ๅ ็ซฅๆๅฝใฎ็ณ่ซๆ้ใๆใใฆใใ ใใ</li> | |
<li>ใใคใใณใใผใซใผใใซ่จ่ผใใใฆใใ้ปๅญ่จผๆๆธใจใฏ๏ผ</li> | |
<li>ๅนด้ใฏใใใคใใใใใใใใๅใๅใใพใใ๏ผ</li> | |
</ul> | |
</div> | |
)} | |
</ScrollArea> | |
) | |
} | |
// FIXME: This function is not safe. It should be replaced with a safer | |
// implementation. | |
function unsafeConvertToAnchorTag(inputText: string) { | |
const regex = /<([^,]+),(http[^>]+)>/g | |
return inputText.replace(regex, (_match, text, url) => { | |
const escapedText = text | |
.replace(/&/g, "&") | |
.replace(/</g, "<") | |
.replace(/>/g, ">") | |
.replace(/"/g, """) | |
return `<a target="_brank" href="${url.trim()}">${escapedText.trim()}</a>` | |
}) | |
} | |