From 90bf24c5ef0888f636decb1b100e7fee5aacf727 Mon Sep 17 00:00:00 2001 From: Kevin Kern Date: Tue, 27 Jan 2026 00:12:34 +0100 Subject: [PATCH 1/3] feat: add skill file viewer --- src/components/SkillCommentsPanel.tsx | 77 ++++++ src/components/SkillDetailPage.tsx | 354 ++------------------------ src/components/SkillDetailTabs.tsx | 115 +++++++++ src/components/SkillFilesPanel.tsx | 144 +++++++++++ src/components/skillDetailUtils.ts | 148 +++++++++++ src/styles.css | 47 ++++ 6 files changed, 556 insertions(+), 329 deletions(-) create mode 100644 src/components/SkillCommentsPanel.tsx create mode 100644 src/components/SkillDetailTabs.tsx create mode 100644 src/components/SkillFilesPanel.tsx create mode 100644 src/components/skillDetailUtils.ts diff --git a/src/components/SkillCommentsPanel.tsx b/src/components/SkillCommentsPanel.tsx new file mode 100644 index 0000000..3dbc7e1 --- /dev/null +++ b/src/components/SkillCommentsPanel.tsx @@ -0,0 +1,77 @@ +import { useMutation, useQuery } from 'convex/react' +import { useState } from 'react' +import { api } from '../../convex/_generated/api' +import type { Doc, Id } from '../../convex/_generated/dataModel' + +type SkillCommentsPanelProps = { + skillId: Id<'skills'> + isAuthenticated: boolean + me: Doc<'users'> | null +} + +export function SkillCommentsPanel({ skillId, isAuthenticated, me }: SkillCommentsPanelProps) { + const addComment = useMutation(api.comments.add) + const removeComment = useMutation(api.comments.remove) + const [comment, setComment] = useState('') + const comments = useQuery(api.comments.listBySkill, { skillId, limit: 50 }) as + | Array<{ comment: Doc<'comments'>; user: Doc<'users'> | null }> + | undefined + + return ( +
+

+ Comments +

+ {isAuthenticated ? ( +
{ + event.preventDefault() + if (!comment.trim()) return + void addComment({ skillId, body: comment.trim() }).then(() => setComment('')) + }} + className="comment-form" + > +