File size: 3,283 Bytes
aa2e6af | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | import React from 'react';
import { format } from 'date-fns';
import { Layers3 } from 'lucide-react';
import type { TPrompt, TPromptGroup } from 'librechat-data-provider';
import { useLocalize } from '~/hooks';
import { Tag } from '~/components/ui';
import { cn } from '~/utils';
const PromptVersions = ({
prompts,
group,
selectionIndex,
setSelectionIndex,
}: {
prompts: TPrompt[];
group?: TPromptGroup;
selectionIndex: React.SetStateAction<number>;
setSelectionIndex: React.Dispatch<React.SetStateAction<number>>;
}) => {
const localize = useLocalize();
return (
<>
<h2 className="mb-4 flex gap-2 text-base font-semibold dark:text-gray-200">
<Layers3 className="icon-lg text-green-500" />
{localize('com_ui_versions')}
</h2>
<ul className="flex flex-col gap-3">
{prompts.map((prompt: TPrompt, index: number) => {
const tags: string[] = [];
if (index === 0) {
tags.push('latest');
}
if (prompt._id === group?.productionId) {
tags.push('production');
}
return (
<li
key={index}
className={cn(
'relative cursor-pointer rounded-lg border p-4 dark:border-gray-600 dark:bg-transparent',
index === selectionIndex ? 'bg-gray-100 dark:bg-gray-700' : 'bg-white',
)}
onClick={() => setSelectionIndex(index)}
>
<p className="font-bold dark:text-gray-200">
{localize('com_ui_version_var', `${prompts.length - index}`)}
</p>
<p className="absolute right-4 top-5 whitespace-nowrap text-xs text-gray-600 dark:text-gray-400">
{format(new Date(prompt.createdAt), 'yyyy-MM-dd HH:mm')}
</p>
{tags.length > 0 && (
<span className="flex flex-wrap gap-1 text-sm">
{tags.map((tag, i) => {
return (
<Tag
key={`${tag}-${i}`}
label={tag}
className={cn(
'w-fit border border-transparent bg-blue-100 text-blue-500 dark:border-blue-500 dark:bg-transparent dark:text-blue-500',
tag === 'production' &&
'bg-green-100 text-green-500 dark:border-green-500 dark:bg-transparent dark:text-green-500',
)}
labelClassName="flex m-0 justify-center gap-1"
LabelNode={
tag === 'production' ? (
<div className="flex items-center ">
<span className="slow-pulse h-[0.4rem] w-[0.4rem] rounded-full bg-green-400" />
</div>
) : null
}
/>
);
})}
</span>
)}
{group?.authorName && (
<p className="text-xs text-gray-600 dark:text-gray-400">by {group.authorName}</p>
)}
</li>
);
})}
</ul>
</>
);
};
export default PromptVersions;
|