79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import { useMemo } from 'react'
|
|
import { ChevronDown } from 'lucide-react'
|
|
import { cn } from '@/lib'
|
|
import { useChatInitStore } from '@/features/chat/stores/useChatInitStore'
|
|
|
|
interface Props {
|
|
isOpen: boolean
|
|
setIsOpen: (isOpen: boolean) => void
|
|
}
|
|
|
|
export function MDInformation({ isOpen, setIsOpen }: Props) {
|
|
const { quotation_memo } = useChatInitStore()
|
|
|
|
const memoArray = useMemo(() => {
|
|
if (!quotation_memo?.trim()) return []
|
|
return quotation_memo
|
|
.split(/\r?\n+/)
|
|
.map((s) => s.trim())
|
|
.filter(Boolean)
|
|
}, [quotation_memo])
|
|
|
|
if (memoArray.length === 0) return null
|
|
|
|
return (
|
|
<section className="w-full">
|
|
<button
|
|
type="button"
|
|
aria-expanded={isOpen}
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex w-full items-center justify-between border-b border-border pb-2"
|
|
>
|
|
<span className="text-[11px] font-bold tracking-wide text-neutral-60">MD 안내사항</span>
|
|
<ChevronDown
|
|
size={16}
|
|
className={cn('text-neutral-50 transition-transform duration-300', !isOpen && '-rotate-90')}
|
|
/>
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<div className="max-h-[220px] animate-fade-in overflow-y-auto pt-3">
|
|
<div className="flex flex-col gap-2 break-keep">
|
|
{memoArray.map((item, i) => (
|
|
<div key={i} className="flex items-start gap-2 text-sm text-neutral-70">
|
|
<span className="shrink-0 text-neutral-50">•</span>
|
|
<div className="flex-1 whitespace-pre-wrap">{linkText(item)}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</section>
|
|
)
|
|
}
|
|
|
|
function linkText(text: string) {
|
|
const urlRegex = /(https?:\/\/[^\s]+)/g
|
|
const isUrl = (s: string) => /^https?:\/\/[^\s]+$/.test(s)
|
|
const parts = text.split(urlRegex)
|
|
return (
|
|
<div className="text-sm text-neutral-70">
|
|
{parts.map((part, i) =>
|
|
isUrl(part) ? (
|
|
<a
|
|
key={i}
|
|
href={part}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block text-brand-600 underline transition-all hover:brightness-95"
|
|
>
|
|
상품 사이트로 이동
|
|
</a>
|
|
) : (
|
|
<span key={i}>{i > 0 && isUrl(parts[i - 1]) ? part.replace(/^(\s)/, '') : part}</span>
|
|
),
|
|
)}
|
|
</div>
|
|
)
|
|
}
|