active path sidebar

This commit is contained in:
marshennikovaolga
2024-09-06 13:07:41 +03:00
parent 2551a49f95
commit 3014116b56
4 changed files with 44 additions and 20 deletions

View File

@@ -3,11 +3,10 @@ import Link from "next/link"
import { usePathname } from "next/navigation"
import { useAccount } from "@/lib/providers/jazz-provider"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { LaIcon } from "@/components/custom/la-icon"
import { PersonalLinkLists } from "@/lib/schema/personal-link"
export const LinkSection: React.FC = () => {
export const LinkSection: React.FC<{ pathname: string }> = ({ pathname }) => {
const { me } = useAccount({
root: {
personalLinks: []
@@ -15,12 +14,13 @@ export const LinkSection: React.FC = () => {
})
const linkCount = me?.root.personalLinks?.length || 0
const isActive = pathname === "/"
if (!me) return null
return (
<div className="group/pages flex flex-col gap-px py-2">
<LinkSectionHeader linkCount={linkCount} />
<LinkSectionHeader linkCount={linkCount} isActive={isActive} />
<List personalLinks={me.root.personalLinks} />
</div>
)
@@ -28,18 +28,22 @@ export const LinkSection: React.FC = () => {
interface LinkSectionHeaderProps {
linkCount: number
isActive: boolean
}
const LinkSectionHeader: React.FC<LinkSectionHeaderProps> = ({ linkCount }) => (
const LinkSectionHeader: React.FC<LinkSectionHeaderProps> = ({ linkCount, isActive }) => (
<div
className={cn("flex min-h-[30px] items-center gap-px rounded-md", "hover:bg-accent hover:text-accent-foreground")}
className={cn(
"flex min-h-[30px] items-center gap-px rounded-md",
isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
>
<Link
href="/"
className={cn(
"size-6 flex-1 items-center justify-start rounded-md px-2 py-1",
"focus-visible:outline-none focus-visible:ring-0",
"hover:bg-accent hover:text-accent-foreground"
isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
>
<p className="flex items-center text-xs font-medium">
@@ -83,7 +87,6 @@ const ListItem: React.FC<ListItemProps> = ({ label, href, count, isActive }) =>
)}
>
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate text-sm">
<LaIcon name="Link" className="flex-shrink-0 opacity-60" />
<p className={cn("truncate opacity-95 group-hover/topic-link:opacity-100")}>{label}</p>
</div>
</Link>

View File

@@ -46,20 +46,32 @@ const SHOWS: Option<ShowOption>[] = [
const pageSortAtom = atomWithStorage<SortOption>("pageSort", "title")
const pageShowAtom = atomWithStorage<ShowOption>("pageShow", 5)
export const PageSection: React.FC = () => {
const { me } = useAccount({ root: { personalPages: [] } })
export const PageSection: React.FC<{ pathname?: string }> = ({ pathname }) => {
const { me } = useAccount({
root: {
personalPages: []
}
})
const [sort, setSort] = useAtom(pageSortAtom)
const [show, setShow] = useAtom(pageShowAtom)
const pageCount = me?.root.personalPages?.length || 0
const isActive = pathname ? pathname.startsWith("/pages") : false
if (!me) return null
return (
<div className="group/pages flex flex-col gap-px py-2">
<PageSectionHeader pageCount={pageCount} />
{me?.root.personalPages && <PageList personalPages={me.root.personalPages} />}
<PageSectionHeader pageCount={pageCount} isActive={isActive} />
<PageList personalPages={me.root.personalPages} sort={sort} show={show} />
</div>
)
}
interface PageSectionHeaderProps {
pageCount: number
isActive: boolean
}
const PageSectionHeader: React.FC<PageSectionHeaderProps> = ({ pageCount }) => (
@@ -121,6 +133,8 @@ const NewPageButton: React.FC = () => {
interface PageListProps {
personalPages: PersonalPageLists
sort: SortOption
show: ShowOption
}
const PageList: React.FC<PageListProps> = ({ personalPages }) => {
@@ -250,4 +264,4 @@ const ShowAllForm: React.FC = () => {
</DropdownMenuContent>
</DropdownMenu>
)
}
}

View File

@@ -8,7 +8,7 @@ import { LaIcon } from "@/components/custom/la-icon"
import { ListOfTopics } from "@/lib/schema"
import { LEARNING_STATES, LearningStateValue } from "@/lib/constants"
export const TopicSection: React.FC = () => {
export const TopicSection: React.FC<{ pathname: string }> = ({ pathname }) => {
const { me } = useAccount({
root: {
topicsWantToLearn: [],
@@ -22,11 +22,13 @@ export const TopicSection: React.FC = () => {
(me?.root.topicsLearning?.length || 0) +
(me?.root.topicsLearned?.length || 0)
const isActive = pathname.startsWith("/topics")
if (!me) return null
return (
<div className="group/pages flex flex-col gap-px py-2">
<TopicSectionHeader topicCount={topicCount} />
<TopicSectionHeader topicCount={topicCount} isActive={isActive} />
<List
topicsWantToLearn={me.root.topicsWantToLearn}
topicsLearning={me.root.topicsLearning}
@@ -38,11 +40,15 @@ export const TopicSection: React.FC = () => {
interface TopicSectionHeaderProps {
topicCount: number
isActive: boolean
}
const TopicSectionHeader: React.FC<TopicSectionHeaderProps> = ({ topicCount }) => (
const TopicSectionHeader: React.FC<TopicSectionHeaderProps> = ({ topicCount, isActive }) => (
<div
className={cn("flex min-h-[30px] items-center gap-px rounded-md", "hover:bg-accent hover:text-accent-foreground")}
className={cn(
"flex min-h-[30px] items-center gap-px rounded-md",
isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
>
<Button
variant="ghost"
@@ -131,4 +137,4 @@ const ListItem: React.FC<ListItemProps> = ({ label, value, href, count, isActive
</div>
</div>
)
}
}

View File

@@ -109,6 +109,7 @@ const LogoAndSearch: React.FC = React.memo(() => {
LogoAndSearch.displayName = "LogoAndSearch"
const SidebarContent: React.FC = React.memo(() => {
const pathname = usePathname()
return (
<>
<nav className="bg-background relative flex h-full w-full shrink-0 flex-col">
@@ -117,9 +118,9 @@ const SidebarContent: React.FC = React.memo(() => {
</div>
<div tabIndex={-1} className="relative mb-0.5 mt-1.5 flex grow flex-col overflow-y-auto rounded-md px-3">
<div className="h-2 shrink-0" />
<LinkSection />
<PageSection />
<TopicSection />
<LinkSection pathname={pathname} />
<PageSection pathname={pathname} />
<TopicSection pathname={pathname} />
</div>
</nav>
<ProfileSection />