Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ NEXT_PUBLIC_JAZZ_PEER_URL="wss://"

RONIN_TOKEN=

SENTRY_DSN=
SENTRY_PROJECT=
NEXT_PUBLIC_SENTRY_DSN=
NEXT_PUBLIC_SENTRY_ORG=
NEXT_PUBLIC_SENTRY_PROJECT=

# IGNORE_BUILD_ERRORS=true
9 changes: 0 additions & 9 deletions web/app/api/sentry-example-api/route.ts

This file was deleted.

79 changes: 0 additions & 79 deletions web/app/sentry-example-page/page.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion web/components/custom/command-palette/command-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const createCommandGroups = (
icon: "Plus",
value: "Create New Link...",
label: "Create New Link...",
action: () => actions.navigateTo("/")
action: () => actions.navigateTo("/links?create=true")
}
]
},
Expand Down
14 changes: 6 additions & 8 deletions web/components/custom/learn-anything-onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export function LearnAnythingOnboarding() {
const [isFetching, setIsFetching] = useState(true)
const [isExisting, setIsExisting] = useState(false)

if (pathname === "/") return null

useEffect(() => {
const loadUser = async () => {
try {
Expand All @@ -41,10 +39,10 @@ export function LearnAnythingOnboarding() {
}
}

if (!hasVisited) {
if (!hasVisited && pathname !== "/") {
loadUser()
}
}, [hasVisited, setIsOpen])
}, [hasVisited, pathname, setIsOpen])

const handleClose = () => {
setIsOpen(false)
Expand All @@ -68,8 +66,8 @@ export function LearnAnythingOnboarding() {
<p className="font-medium">Existing Customer Notice</p>
<p>
We noticed you are an existing Learn Anything customer. We sincerely apologize for any broken experience
you may have encountered on the old website. We've been working hard on this new version, which
addresses previous issues and offers more features. As an early customer, you're locked in at the{" "}
you may have encountered on the old website. We&apos;ve been working hard on this new version, which
addresses previous issues and offers more features. As an early customer, you&apos;re locked in at the{" "}
<strong>$3</strong> price for our upcoming pro version. Thank you for your support!
</p>
</>
Expand All @@ -85,8 +83,8 @@ export function LearnAnythingOnboarding() {
<li>Update your learning status on a topic</li>
</ul>
<p>
If you have any questions, don't hesitate to reach out. Click on question mark button in the bottom right
corner and enter your message.
If you have any questions, don&apos;t hesitate to reach out. Click on question mark button in the bottom
right corner and enter your message.
</p>
</AlertDialogDescription>

Expand Down
98 changes: 53 additions & 45 deletions web/components/custom/sidebar/partial/link-section.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import React from "react"
import Link from "next/link"
import { usePathname, useRouter } from "next/navigation"
import { usePathname } from "next/navigation"
import { useAccount } from "@/lib/providers/jazz-provider"
import { cn } from "@/lib/utils"
import { PersonalLinkLists } from "@/lib/schema/personal-link"
import { useQueryState, parseAsStringLiteral } from "nuqs"
import { LEARNING_STATES } from "@/lib/constants"

export const LinkSection: React.FC<{ pathname: string }> = ({ pathname }) => {
const ALL_STATES = [{ label: "All", value: "all", icon: "List", className: "text-foreground" }, ...LEARNING_STATES]
const ALL_STATES_STRING = ALL_STATES.map(ls => ls.value)

interface LinkSectionProps {
pathname: string
}

export const LinkSection: React.FC<LinkSectionProps> = ({ pathname }) => {
const { me } = useAccount({
root: {
personalLinks: []
}
})

const linkCount = me?.root.personalLinks?.length || 0
const isActive = pathname === "/links"

if (!me) return null

const linkCount = me.root.personalLinks?.length || 0
const isActive = pathname === "/links"

return (
<div className="group/pages flex flex-col gap-px py-2">
<LinkSectionHeader linkCount={linkCount} isActive={isActive} />
Expand All @@ -34,20 +41,19 @@ interface LinkSectionHeaderProps {

const LinkSectionHeader: React.FC<LinkSectionHeaderProps> = ({ linkCount }) => {
const pathname = usePathname()
const [state] = useQueryState("state", parseAsStringLiteral(LEARNING_STATES.map(ls => ls.value)))
const isLinksActive = pathname.startsWith("/links") && !state
const [state] = useQueryState("state", parseAsStringLiteral(ALL_STATES_STRING))
const isLinksActive = pathname.startsWith("/links") && (!state || state === "all")

return (
<div className="flex gap-px rounded-md">
<div
className={cn(
"flex min-h-[30px] items-center gap-px rounded-md",
isLinksActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
>
<Link
href="/links"
className={cn(
"flex size-6 flex-1 items-center justify-start rounded-md px-2",
"focus-visible:outline-none focus-visible:ring-0",
isLinksActive
? "bg-accent text-accent-foreground items-center justify-center py-3"
: "hover:bg-accent hover:text-accent-foreground"
)}
className="flex flex-1 items-center justify-start rounded-md px-2 py-1 focus-visible:outline-none focus-visible:ring-0"
>
<p className="flex w-full items-center text-xs font-medium">
Links
Expand All @@ -66,24 +72,29 @@ const List: React.FC<ListProps> = ({ personalLinks }) => {
const pathname = usePathname()
const [state] = useQueryState("state", parseAsStringLiteral(LEARNING_STATES.map(ls => ls.value)))

const toLearnCount = personalLinks.filter(link => link?.learningState === "wantToLearn").length
const learningCount = personalLinks.filter(link => link?.learningState === "learning").length
const learnedCount = personalLinks.filter(link => link?.learningState === "learned").length

const isActive = (checkState: string) => {
return pathname === "/links" && state === checkState
const linkCounts = {
wantToLearn: personalLinks.filter(link => link?.learningState === "wantToLearn").length,
learning: personalLinks.filter(link => link?.learningState === "learning").length,
learned: personalLinks.filter(link => link?.learningState === "learned").length
}

const isActive = (checkState: string) => pathname === "/links" && state === checkState

return (
<div className="flex flex-col gap-px">
<ListItem
label="To Learn"
href="/links?state=wantToLearn"
count={toLearnCount}
count={linkCounts.wantToLearn}
isActive={isActive("wantToLearn")}
/>
<ListItem label="Learning" href="/links?state=learning" count={learningCount} isActive={isActive("learning")} />
<ListItem label="Learned" href="/links?state=learned" count={learnedCount} isActive={isActive("learned")} />
<ListItem
label="Learning"
href="/links?state=learning"
count={linkCounts.learning}
isActive={isActive("learning")}
/>
<ListItem label="Learned" href="/links?state=learned" count={linkCounts.learned} isActive={isActive("learned")} />
</div>
)
}
Expand All @@ -95,26 +106,23 @@ interface ListItemProps {
isActive: boolean
}

const ListItem: React.FC<ListItemProps> = ({ label, href, count, isActive }) => {
return (
<div className="group/reorder-page relative">
<div className="group/topic-link relative flex min-w-0 flex-1">
<Link
href={href}
className={cn(
"relative flex h-8 w-full items-center gap-2 rounded-md p-1.5 font-medium",
isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
>
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate text-sm">
<p className={cn("truncate opacity-95 group-hover/topic-link:opacity-100")}>{label}</p>
</div>
</Link>

{count > 0 && (
<span className="absolute right-2 top-1/2 z-[1] -translate-y-1/2 rounded p-1 text-sm">{count}</span>
const ListItem: React.FC<ListItemProps> = ({ label, href, count, isActive }) => (
<div className="group/reorder-page relative">
<div className="group/topic-link relative flex min-w-0 flex-1">
<Link
href={href}
className={cn(
"relative flex h-8 w-full items-center gap-2 rounded-md p-1.5 font-medium",
isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent hover:text-accent-foreground"
)}
</div>
>
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate text-sm">
<p className={cn("truncate opacity-95 group-hover/topic-link:opacity-100")}>{label}</p>
</div>
</Link>
{count > 0 && (
<span className="absolute right-2 top-1/2 z-[1] -translate-y-1/2 rounded p-1 text-sm">{count}</span>
)}
</div>
)
}
</div>
)
40 changes: 17 additions & 23 deletions web/components/custom/sidebar/partial/page-section.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React, { useMemo } from "react"
import { useAtom } from "jotai"
import { usePathname, useRouter } from "next/navigation"
import { useAccount } from "@/lib/providers/jazz-provider"
Expand All @@ -9,7 +9,6 @@ import { Button } from "@/components/ui/button"
import { LaIcon } from "@/components/custom/la-icon"
import { toast } from "sonner"
import Link from "next/link"
import { useEffect } from "react"
import {
DropdownMenu,
DropdownMenuContent,
Expand Down Expand Up @@ -54,14 +53,14 @@ export const PageSection: React.FC<{ pathname?: string }> = ({ pathname }) => {
}
})

const [sort, setSort] = useAtom(pageSortAtom)
const [show, setShow] = useAtom(pageShowAtom)

const pageCount = me?.root.personalPages?.length || 0
const isActive = pathname === "/pages"
const [sort] = useAtom(pageSortAtom)
const [show] = useAtom(pageShowAtom)

if (!me) return null

const pageCount = me.root.personalPages?.length || 0
const isActive = pathname === "/pages"

return (
<div className="group/pages flex flex-col gap-px py-2">
<PageSectionHeader pageCount={pageCount} isActive={isActive} />
Expand Down Expand Up @@ -142,24 +141,19 @@ interface PageListProps {
show: ShowOption
}

const PageList: React.FC<PageListProps> = ({ personalPages }) => {
const PageList: React.FC<PageListProps> = ({ personalPages, sort, show }) => {
const pathname = usePathname()

const [sortCriteria] = useAtom(pageSortAtom)
const [showCount] = useAtom(pageShowAtom)

const sortedPages = [...personalPages]
.sort((a, b) => {
switch (sortCriteria) {
case "title":
const sortedPages = useMemo(() => {
return [...personalPages]
.sort((a, b) => {
if (sort === "title") {
return (a?.title ?? "").localeCompare(b?.title ?? "")
case "recent":
return (b?.updatedAt?.getTime() ?? 0) - (a?.updatedAt?.getTime() ?? 0)
default:
return 0
}
})
.slice(0, showCount === 0 ? personalPages.length : showCount)
}
return (b?.updatedAt?.getTime() ?? 0) - (a?.updatedAt?.getTime() ?? 0)
})
.slice(0, show === 0 ? personalPages.length : show)
}, [personalPages, sort, show])

return (
<div className="flex flex-col gap-px">
Expand All @@ -185,7 +179,7 @@ const PageListItem: React.FC<PageListItemProps> = ({ page, isActive }) => (
{ "bg-accent text-accent-foreground": isActive }
)}
>
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate text-sm">
<div className="flex max-w-[calc(100%-1rem)] flex-1 items-center gap-1.5 truncate text-sm">
<LaIcon name="FileText" className="flex-shrink-0 opacity-60" />
<p className="truncate opacity-95 group-hover/sidebar-link:opacity-100">{page.title || "Untitled"}</p>
</div>
Expand Down
Loading