Commit 16576be1 authored by Johnny's avatar Johnny

chore: polish MemoDetailSidebar for consistent structure and styles

parent 9628d3de
...@@ -13,6 +13,10 @@ interface Props { ...@@ -13,6 +13,10 @@ interface Props {
parentPage?: string; parentPage?: string;
} }
const SectionLabel = ({ children }: { children: React.ReactNode }) => (
<p className="text-xs font-medium text-muted-foreground/50 uppercase tracking-wider">{children}</p>
);
const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => { const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
const t = useTranslate(); const t = useTranslate();
const property = create(Memo_PropertySchema, memo.property || {}); const property = create(Memo_PropertySchema, memo.property || {});
...@@ -20,76 +24,76 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => { ...@@ -20,76 +24,76 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
const hasReferenceRelations = memo.relations.some((r) => r.type === MemoRelation_Type.REFERENCE); const hasReferenceRelations = memo.relations.some((r) => r.type === MemoRelation_Type.REFERENCE);
return ( return (
<aside className={cn("relative w-full h-auto max-h-screen overflow-auto flex flex-col justify-start items-start", className)}> <aside className={cn("relative w-full h-auto max-h-screen overflow-auto flex flex-col gap-5", className)}>
<div className="flex flex-col justify-start items-start w-full gap-4 h-auto shrink-0 flex-nowrap"> {hasReferenceRelations && (
{hasReferenceRelations && ( <div className="w-full space-y-2">
<div className="flex items-center gap-1.5">
<SectionLabel>{t("common.relations")}</SectionLabel>
<span className="text-xs text-muted-foreground/30">(Beta)</span>
</div>
<div className="relative w-full h-36 border border-border rounded-lg bg-muted overflow-hidden"> <div className="relative w-full h-36 border border-border rounded-lg bg-muted overflow-hidden">
<MemoRelationForceGraph className="w-full h-full" memo={memo} parentPage={parentPage} /> <MemoRelationForceGraph className="w-full h-full" memo={memo} parentPage={parentPage} />
<div className="absolute top-2 left-2 text-xs text-muted-foreground/60 font-medium gap-1 flex flex-row items-center">
<span>{t("common.relations")}</span>
<span className="text-xs opacity-60">(Beta)</span>
</div>
</div> </div>
)} </div>
)}
<div className="w-full space-y-1">
<SectionLabel>{t("common.created-at")}</SectionLabel>
<p className="text-sm text-foreground/70">{memo.createTime ? timestampDate(memo.createTime).toLocaleString() : "—"}</p>
</div>
{!isEqual(memo.createTime, memo.updateTime) && (
<div className="w-full space-y-1"> <div className="w-full space-y-1">
<p className="text-xs font-medium text-muted-foreground/60 uppercase tracking-wide px-1">{t("common.created-at")}</p> <SectionLabel>{t("common.last-updated-at")}</SectionLabel>
<p className="text-sm text-muted-foreground px-1">{memo.createTime ? timestampDate(memo.createTime).toLocaleString() : "-"}</p> <p className="text-sm text-foreground/70">{memo.updateTime ? timestampDate(memo.updateTime).toLocaleString() : "—"}</p>
</div> </div>
)}
{!isEqual(memo.createTime, memo.updateTime) && ( {hasSpecialProperty && (
<div className="w-full space-y-1"> <div className="w-full space-y-2">
<p className="text-xs font-medium text-muted-foreground/60 uppercase tracking-wide px-1">{t("common.last-updated-at")}</p> <SectionLabel>{t("common.properties")}</SectionLabel>
<p className="text-sm text-muted-foreground px-1">{memo.updateTime ? timestampDate(memo.updateTime).toLocaleString() : "-"}</p> <div className="flex flex-wrap gap-1.5">
{property.hasLink && (
<span className="inline-flex items-center gap-1.5 px-2 py-1 rounded-md border border-border/60 bg-muted/60 text-xs text-muted-foreground">
<LinkIcon className="w-3.5 h-3.5" />
{t("memo.links")}
</span>
)}
{property.hasTaskList && (
<span className="inline-flex items-center gap-1.5 px-2 py-1 rounded-md border border-border/60 bg-muted/60 text-xs text-muted-foreground">
<CheckCircleIcon className="w-3.5 h-3.5" />
{t("memo.to-do")}
</span>
)}
{property.hasCode && (
<span className="inline-flex items-center gap-1.5 px-2 py-1 rounded-md border border-border/60 bg-muted/60 text-xs text-muted-foreground">
<Code2Icon className="w-3.5 h-3.5" />
{t("memo.code")}
</span>
)}
</div> </div>
)} </div>
)}
{hasSpecialProperty && ( {memo.tags.length > 0 && (
<div className="w-full space-y-2"> <div className="w-full space-y-2">
<p className="text-xs font-medium text-muted-foreground/60 uppercase tracking-wide px-1">{t("common.properties")}</p> <div className="flex items-center gap-1.5">
<div className="w-full flex flex-row justify-start items-center gap-2 flex-wrap px-1"> <SectionLabel>{t("common.tags")}</SectionLabel>
{property.hasLink && ( <span className="text-xs text-muted-foreground/30">({memo.tags.length})</span>
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-muted/50 border border-border/50 rounded-md text-xs text-muted-foreground">
<LinkIcon className="w-3.5 h-3.5" />
<span>{t("memo.links")}</span>
</div>
)}
{property.hasTaskList && (
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-muted/50 border border-border/50 rounded-md text-xs text-muted-foreground">
<CheckCircleIcon className="w-3.5 h-3.5" />
<span>{t("memo.to-do")}</span>
</div>
)}
{property.hasCode && (
<div className="inline-flex items-center gap-1.5 px-2 py-1 bg-muted/50 border border-border/50 rounded-md text-xs text-muted-foreground">
<Code2Icon className="w-3.5 h-3.5" />
<span>{t("memo.code")}</span>
</div>
)}
</div>
</div> </div>
)} <div className="flex flex-wrap gap-1.5">
{memo.tags.map((tag) => (
{memo.tags.length > 0 && ( <span
<div className="w-full space-y-2"> key={tag}
<div className="flex flex-row justify-start items-center gap-1.5 px-1"> className="inline-flex items-center gap-1 px-1 rounded-md border border-border/60 bg-muted/60 text-sm text-muted-foreground hover:bg-muted hover:text-foreground/80 transition-colors cursor-pointer"
<p className="text-xs font-medium text-muted-foreground/60 uppercase tracking-wide">{t("common.tags")}</p> >
<span className="text-xs text-muted-foreground/40">({memo.tags.length})</span> <HashIcon className="w-3 h-3 opacity-50" />
</div> {tag}
<div className="w-full flex flex-row justify-start items-center flex-wrap gap-1.5 px-1"> </span>
{memo.tags.map((tag) => ( ))}
<div
key={tag}
className="inline-flex items-center gap-1 px-2 py-0.5 bg-muted/50 border border-border/50 rounded-md text-xs text-muted-foreground hover:bg-muted transition-colors cursor-pointer group"
>
<HashIcon className="w-3 h-3 opacity-40 group-hover:opacity-60 transition-opacity" />
<span className="opacity-80 group-hover:opacity-100 transition-opacity">{tag}</span>
</div>
))}
</div>
</div> </div>
)} </div>
</div> )}
</aside> </aside>
); );
}; };
......
...@@ -22,7 +22,7 @@ const MemoDetailSidebarDrawer = ({ memo, parentPage }: Props) => { ...@@ -22,7 +22,7 @@ const MemoDetailSidebarDrawer = ({ memo, parentPage }: Props) => {
return ( return (
<Sheet open={open} onOpenChange={setOpen}> <Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild> <SheetTrigger asChild>
<Button variant="ghost" className="bg-transparent! px-2"> <Button variant="ghost" size="sm" className="px-2">
<GanttChartIcon className="w-5 h-auto text-muted-foreground" /> <GanttChartIcon className="w-5 h-auto text-muted-foreground" />
</Button> </Button>
</SheetTrigger> </SheetTrigger>
......
...@@ -99,18 +99,6 @@ const MemoDetail = () => { ...@@ -99,18 +99,6 @@ const MemoDetail = () => {
{t("memo.comment.self")} {t("memo.comment.self")}
</h2> </h2>
<div className="relative mx-auto grow w-full min-h-full flex flex-col justify-start items-start gap-y-1"> <div className="relative mx-auto grow w-full min-h-full flex flex-col justify-start items-start gap-y-1">
{showCommentEditor && (
<div className="w-full mb-2">
<MemoEditor
cacheKey={`${memo.name}-${memo.updateTime}-comment`}
placeholder={t("editor.add-your-comment-here")}
parentMemoName={memo.name}
autoFocus
onConfirm={handleCommentCreated}
onCancel={() => setShowCommentEditor(false)}
/>
</div>
)}
{comments.length === 0 ? ( {comments.length === 0 ? (
showCreateCommentButton && ( showCreateCommentButton && (
<div className="w-full flex flex-row justify-center items-center py-6"> <div className="w-full flex flex-row justify-center items-center py-6">
...@@ -121,30 +109,40 @@ const MemoDetail = () => { ...@@ -121,30 +109,40 @@ const MemoDetail = () => {
</div> </div>
) )
) : ( ) : (
<> <div className="w-full flex flex-row justify-between items-center h-8 pl-3 mb-2">
<div className="w-full flex flex-row justify-between items-center h-8 pl-3 mb-2"> <div className="flex flex-row justify-start items-center">
<div className="flex flex-row justify-start items-center"> <MessageCircleIcon className="w-5 h-auto text-muted-foreground mr-1" />
<MessageCircleIcon className="w-5 h-auto text-muted-foreground mr-1" /> <span className="text-muted-foreground text-sm">{t("memo.comment.self")}</span>
<span className="text-muted-foreground text-sm">{t("memo.comment.self")}</span> <span className="text-muted-foreground text-sm ml-1">({comments.length})</span>
<span className="text-muted-foreground text-sm ml-1">({comments.length})</span>
</div>
{showCreateCommentButton && (
<Button variant="ghost" className="text-muted-foreground" onClick={handleShowCommentEditor}>
{t("memo.comment.write-a-comment")}
</Button>
)}
</div> </div>
{comments.map((comment) => ( {showCreateCommentButton && (
<MemoView <Button variant="ghost" className="text-muted-foreground" onClick={handleShowCommentEditor}>
key={`${comment.name}-${comment.displayTime}`} {t("memo.comment.write-a-comment")}
memo={comment} </Button>
parentPage={locationState?.from} )}
showCreator </div>
compact )}
/> {showCommentEditor && (
))} <div className="w-full mb-2">
</> <MemoEditor
cacheKey={`${memo.name}-${memo.updateTime}-comment`}
placeholder={t("editor.add-your-comment-here")}
parentMemoName={memo.name}
autoFocus
onConfirm={handleCommentCreated}
onCancel={() => setShowCommentEditor(false)}
/>
</div>
)} )}
{comments.map((comment) => (
<MemoView
key={`${comment.name}-${comment.displayTime}`}
memo={comment}
parentPage={locationState?.from}
showCreator
compact
/>
))}
</div> </div>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment