feat: Enhance task filtering, smart scheduling, audit logs and translations
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-12-17 14:26:54 +01:00
parent 9819d8db0b
commit 2579df0b89
32 changed files with 2219 additions and 456 deletions
+22 -6
View File
@@ -46,8 +46,8 @@ import { cn } from "@/lib/utils";
import { formatDistanceToNow } from "date-fns";
import { de } from "date-fns/locale";
import { useToast } from "@/hooks/use-toast";
// import ReactMarkdown from "react-markdown";
// import remarkGfm from "remark-gfm";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
// Types
type Conversation = {
@@ -63,6 +63,22 @@ type Message = {
createdAt: string;
};
const preprocessMarkdown = (text: string) => {
if (!text) return "";
// 1. Ensure newlines before headers (###), horizontal rules (---), and list items
let processed = text
.replace(/([^\n])\n(#{1,6}\s)/g, '$1\n\n$2') // Header
.replace(/([^\n])\n(\*{3,}|-{3,}|_{3,})/g, '$1\n\n$2') // HR
.replace(/([^\n])\n(- |\* |\d+\. )/g, '$1\n\n$2'); // Lists
// 2. Ensure code blocks have newlines before/after
processed = processed.replace(/([^\n])```/g, '$1\n```');
processed = processed.replace(/```([^\n])/g, '```\n$1');
return processed;
};
const TypewriterMessage = ({ content, onComplete }: { content: string, onComplete?: () => void }) => {
const [displayedContent, setDisplayedContent] = useState("");
const indexRef = useRef(0);
@@ -93,8 +109,8 @@ const TypewriterMessage = ({ content, onComplete }: { content: string, onComplet
return (
<div className="prose prose-sm dark:prose-invert max-w-none break-words">
{/* <ReactMarkdown remarkPlugins={[remarkGfm]}>{displayedContent}</ReactMarkdown> */}
{displayedContent}
<ReactMarkdown remarkPlugins={[remarkGfm]}>{preprocessMarkdown(displayedContent)}</ReactMarkdown>
{/* {displayedContent} */}
</div>
);
};
@@ -618,8 +634,8 @@ export default function AiChatPage() {
<TypewriterMessage content={msg.content} onComplete={() => scrollToBottom()} />
) : (
<div className="prose prose-sm dark:prose-invert max-w-none break-words">
{/* <ReactMarkdown remarkPlugins={[remarkGfm]}>{msg.content}</ReactMarkdown> */}
{msg.content}
<ReactMarkdown remarkPlugins={[remarkGfm]}>{preprocessMarkdown(msg.content)}</ReactMarkdown>
{/* {msg.content} */}
</div>
)
) : (