diff --git a/web/.env.example b/web/.env.example index f06d9024c..bae601e65 100644 --- a/web/.env.example +++ b/web/.env.example @@ -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 \ No newline at end of file diff --git a/web/app/api/sentry-example-api/route.ts b/web/app/api/sentry-example-api/route.ts deleted file mode 100644 index f486f3d1d..000000000 --- a/web/app/api/sentry-example-api/route.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NextResponse } from "next/server"; - -export const dynamic = "force-dynamic"; - -// A faulty API route to test Sentry's error monitoring -export function GET() { - throw new Error("Sentry Example API Route Error"); - return NextResponse.json({ data: "Testing Sentry Error..." }); -} diff --git a/web/app/sentry-example-page/page.tsx b/web/app/sentry-example-page/page.tsx deleted file mode 100644 index dd38d0459..000000000 --- a/web/app/sentry-example-page/page.tsx +++ /dev/null @@ -1,79 +0,0 @@ -"use client"; - -import Head from "next/head"; -import * as Sentry from "@sentry/nextjs"; - -export default function Page() { - return ( -
- - Sentry Onboarding - - - -
-

- - - -

- -

Get started by sending us a sample error:

- - -

- Next, look for the error on the{" "} - Issues Page. -

-

- For more information, see{" "} - - https://docs.sentry.io/platforms/javascript/guides/nextjs/ - -

-
-
- ); -} diff --git a/web/components/custom/command-palette/command-data.ts b/web/components/custom/command-palette/command-data.ts index 2a36b5151..ac3f4cb17 100644 --- a/web/components/custom/command-palette/command-data.ts +++ b/web/components/custom/command-palette/command-data.ts @@ -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") } ] }, diff --git a/web/components/custom/learn-anything-onboarding.tsx b/web/components/custom/learn-anything-onboarding.tsx index 619d9a5a0..405f0e419 100644 --- a/web/components/custom/learn-anything-onboarding.tsx +++ b/web/components/custom/learn-anything-onboarding.tsx @@ -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 { @@ -41,10 +39,10 @@ export function LearnAnythingOnboarding() { } } - if (!hasVisited) { + if (!hasVisited && pathname !== "/") { loadUser() } - }, [hasVisited, setIsOpen]) + }, [hasVisited, pathname, setIsOpen]) const handleClose = () => { setIsOpen(false) @@ -68,8 +66,8 @@ export function LearnAnythingOnboarding() {

Existing Customer Notice

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'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{" "} $3 price for our upcoming pro version. Thank you for your support!

@@ -85,8 +83,8 @@ export function LearnAnythingOnboarding() {
  • Update your learning status on a topic
  • - 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't hesitate to reach out. Click on question mark button in the bottom + right corner and enter your message.

    diff --git a/web/components/custom/sidebar/partial/link-section.tsx b/web/components/custom/sidebar/partial/link-section.tsx index a469aaf2f..0b568943e 100644 --- a/web/components/custom/sidebar/partial/link-section.tsx +++ b/web/components/custom/sidebar/partial/link-section.tsx @@ -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 = ({ 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 (
    @@ -34,20 +41,19 @@ interface LinkSectionHeaderProps { const LinkSectionHeader: React.FC = ({ 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 ( -
    +

    Links @@ -66,24 +72,29 @@ const List: React.FC = ({ 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 (

    - - + +
    ) } @@ -95,26 +106,23 @@ interface ListItemProps { isActive: boolean } -const ListItem: React.FC = ({ label, href, count, isActive }) => { - return ( -
    -
    - -
    -

    {label}

    -
    - - - {count > 0 && ( - {count} +const ListItem: React.FC = ({ label, href, count, isActive }) => ( +
    +
    + + > +
    +

    {label}

    +
    + + {count > 0 && ( + {count} + )}
    - ) -} +
    +) diff --git a/web/components/custom/sidebar/partial/page-section.tsx b/web/components/custom/sidebar/partial/page-section.tsx index 2a0edad1d..4b9daf28a 100644 --- a/web/components/custom/sidebar/partial/page-section.tsx +++ b/web/components/custom/sidebar/partial/page-section.tsx @@ -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" @@ -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, @@ -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 (
    @@ -142,24 +141,19 @@ interface PageListProps { show: ShowOption } -const PageList: React.FC = ({ personalPages }) => { +const PageList: React.FC = ({ 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 (
    @@ -185,7 +179,7 @@ const PageListItem: React.FC = ({ page, isActive }) => ( { "bg-accent text-accent-foreground": isActive } )} > -
    +

    {page.title || "Untitled"}

    diff --git a/web/components/routes/link/LinkRoute.tsx b/web/components/routes/link/LinkRoute.tsx index e5bde331a..62e5f8a9a 100644 --- a/web/components/routes/link/LinkRoute.tsx +++ b/web/components/routes/link/LinkRoute.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useState, useCallback, useRef } from "react" import { LinkHeader } from "@/components/routes/link/header" import { LinkList } from "@/components/routes/link/list" import { LinkManage } from "@/components/routes/link/manage" -import { useQueryState } from "nuqs" +import { parseAsBoolean, useQueryState } from "nuqs" import { atom, useAtom } from "jotai" import { LinkBottomBar } from "./bottom-bar" import { commandPaletteOpenAtom } from "@/components/custom/command-palette/command-palette" @@ -14,6 +14,7 @@ export const isDeleteConfirmShownAtom = atom(false) export function LinkRoute(): React.ReactElement { const [nuqsEditId] = useQueryState("editId") const [activeItemIndex, setActiveItemIndex] = useState(null) + const [isInCreateMode] = useQueryState("create", parseAsBoolean) const [isCommandPaletteOpen] = useAtom(commandPaletteOpenAtom) const [isDeleteConfirmShown] = useAtom(isDeleteConfirmShownAtom) const [disableEnterKey, setDisableEnterKey] = useState(false) @@ -32,7 +33,7 @@ export function LinkRoute(): React.ReactElement { }, []) useEffect(() => { - if (isDeleteConfirmShown || isCommandPaletteOpen) { + if (isDeleteConfirmShown || isCommandPaletteOpen || isInCreateMode) { setDisableEnterKey(true) if (timeoutRef.current) { clearTimeout(timeoutRef.current) @@ -47,7 +48,7 @@ export function LinkRoute(): React.ReactElement { clearTimeout(timeoutRef.current) } } - }, [isDeleteConfirmShown, isCommandPaletteOpen, handleCommandPaletteClose]) + }, [isDeleteConfirmShown, isCommandPaletteOpen, isInCreateMode, handleCommandPaletteClose]) return (
    diff --git a/web/components/routes/link/bottom-bar.tsx b/web/components/routes/link/bottom-bar.tsx index 995c7ad0f..b51e41904 100644 --- a/web/components/routes/link/bottom-bar.tsx +++ b/web/components/routes/link/bottom-bar.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from "react" +import React, { useCallback, useEffect, useRef } from "react" import { motion, AnimatePresence } from "framer-motion" import { icons } from "lucide-react" import { Button } from "@/components/ui/button" @@ -6,8 +6,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip import { getSpecialShortcut, formatShortcut, isMacOS } from "@/lib/utils" import { LaIcon } from "@/components/custom/la-icon" import { useAtom } from "jotai" -import { linkShowCreateAtom } from "@/store/link" -import { useQueryState } from "nuqs" +import { parseAsBoolean, useQueryState } from "nuqs" import { useConfirm } from "@omit/react-confirm-dialog" import { useAccount, useCoState } from "@/lib/providers/jazz-provider" import { PersonalLink } from "@/lib/schema" @@ -48,9 +47,8 @@ ToolbarButton.displayName = "ToolbarButton" export const LinkBottomBar: React.FC = () => { const [editId, setEditId] = useQueryState("editId") + const [createMode, setCreateMode] = useQueryState("create", parseAsBoolean) const [, setGlobalLinkFormExceptionRefsAtom] = useAtom(globalLinkFormExceptionRefsAtom) - const [showCreate, setShowCreate] = useAtom(linkShowCreateAtom) - const { me } = useAccount({ root: { personalLinks: [] } }) const personalLink = useCoState(PersonalLink, editId as ID) @@ -67,6 +65,13 @@ export const LinkBottomBar: React.FC = () => { const { deleteLink } = useLinkActions() const confirm = useConfirm() + const handleCreateMode = useCallback(() => { + setEditId(null) + setTimeout(() => { + setCreateMode(prev => !prev) + }, 100) + }, [setEditId, setCreateMode]) + useEffect(() => { setGlobalLinkFormExceptionRefsAtom([ overlayRef, @@ -81,7 +86,7 @@ export const LinkBottomBar: React.FC = () => { }, [setGlobalLinkFormExceptionRefsAtom]) const handleDelete = async (e: React.MouseEvent) => { - if (!personalLink) return + if (!personalLink || !me) return const result = await confirm({ title: `Delete "${personalLink.title}"?`, @@ -106,7 +111,6 @@ export const LinkBottomBar: React.FC = () => { }) if (result) { - if (!me) return deleteLink(me, personalLink) setEditId(null) } @@ -114,24 +118,19 @@ export const LinkBottomBar: React.FC = () => { useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { - if (isMacOS()) { - if (event.ctrlKey && event.metaKey && event.key.toLowerCase() === "n") { - event.preventDefault() - setShowCreate(true) - } - } else { - // For Windows, we'll use Ctrl + Win + N - // Note: The Windows key is not directly detectable in most browsers - if (event.ctrlKey && event.key.toLowerCase() === "n" && (event.metaKey || event.altKey)) { - event.preventDefault() - setShowCreate(true) - } + const isCreateShortcut = isMacOS() + ? event.ctrlKey && event.metaKey && event.key.toLowerCase() === "n" + : event.ctrlKey && event.key.toLowerCase() === "n" && (event.metaKey || event.altKey) + + if (isCreateShortcut) { + event.preventDefault() + handleCreateMode() } } window.addEventListener("keydown", handleKeyDown) return () => window.removeEventListener("keydown", handleKeyDown) - }, [setShowCreate]) + }, [handleCreateMode]) const shortcutKeys = getSpecialShortcut("expandToolbar") const shortcutText = formatShortcut(shortcutKeys) @@ -172,11 +171,11 @@ export const LinkBottomBar: React.FC = () => { exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.1 }} > - {showCreate && setShowCreate(true)} />} - {!showCreate && ( + {createMode && } + {!createMode && ( setShowCreate(true)} + onClick={handleCreateMode} tooltip={`New Link (${shortcutText})`} ref={plusBtnRef} /> diff --git a/web/components/routes/link/list.tsx b/web/components/routes/link/list.tsx index ac68e6bc2..67a0154a5 100644 --- a/web/components/routes/link/list.tsx +++ b/web/components/routes/link/list.tsx @@ -166,13 +166,11 @@ const LinkList: React.FC = ({ activeItemIndex, setActiveItemIndex return newIndex }) - } else if (e.key === "Enter" && !disableEnterKey) { + } else if (e.key === "Enter" && !disableEnterKey && activeItemIndex !== null) { e.preventDefault() - if (activeItemIndex !== null) { - const activeLink = sortedLinks[activeItemIndex] - if (activeLink) { - setEditId(activeLink.id) - } + const activeLink = sortedLinks[activeItemIndex] + if (activeLink) { + setEditId(activeLink.id) } } } diff --git a/web/components/routes/link/manage.tsx b/web/components/routes/link/manage.tsx index 7c15da06c..438ea9066 100644 --- a/web/components/routes/link/manage.tsx +++ b/web/components/routes/link/manage.tsx @@ -1,25 +1,24 @@ "use client" import React from "react" -import { linkShowCreateAtom } from "@/store/link" -import { useAtom } from "jotai" import { useKey } from "react-use" import { LinkForm } from "./partials/form/link-form" import { motion, AnimatePresence } from "framer-motion" +import { parseAsBoolean, useQueryState } from "nuqs" interface LinkManageProps {} const LinkManage: React.FC = () => { - const [showCreate, setShowCreate] = useAtom(linkShowCreateAtom) + const [createMode, setCreateMode] = useQueryState("create", parseAsBoolean) - const handleFormClose = () => setShowCreate(false) + const handleFormClose = () => setCreateMode(false) const handleFormFail = () => {} useKey("Escape", handleFormClose) return ( - {showCreate && ( + {createMode && ( = ({ "relative cursor-default outline-none", "grid grid-cols-[auto_1fr_auto] items-center gap-x-2 py-2 max-lg:px-4 sm:px-5 sm:py-2", { - "bg-muted-foreground/10": isActive, + "bg-muted-foreground/5": isActive, "hover:bg-muted/50": !isActive } )} @@ -148,7 +148,11 @@ export const LinkItem: React.FC = ({
    - {personalLink.topic && {personalLink.topic.prettyName}} + {personalLink.topic && ( + + {personalLink.topic.prettyName} + + )}
    ) diff --git a/web/components/routes/page/detail/PageDetailRoute.tsx b/web/components/routes/page/detail/PageDetailRoute.tsx index 4aa7a6859..1e10b1805 100644 --- a/web/components/routes/page/detail/PageDetailRoute.tsx +++ b/web/components/routes/page/detail/PageDetailRoute.tsx @@ -18,8 +18,8 @@ import { TopicSelector } from "@/components/custom/topic-selector" import { Button } from "@/components/ui/button" import { LaIcon } from "@/components/custom/la-icon" import { useConfirm } from "@omit/react-confirm-dialog" -import { toast } from "sonner" import { useRouter } from "next/navigation" +import { usePageActions } from "../hooks/use-page-actions" const TITLE_PLACEHOLDER = "Untitled" @@ -59,7 +59,9 @@ export function PageDetailRoute({ pageId }: { pageId: string }) { const isMobile = useMedia("(max-width: 770px)") const page = useCoState(PersonalPage, pageId as ID) const router = useRouter() + const { deletePage } = usePageActions() const confirm = useConfirm() + DeleteEmptyPage(pageId) const handleDelete = async () => { @@ -73,19 +75,8 @@ export function PageDetailRoute({ pageId }: { pageId: string }) { }) if (result && me?.root.personalPages) { - try { - const index = me.root.personalPages.findIndex(item => item?.id === pageId) - if (index === -1) { - toast.error("Page not found.") - return - } - - me.root.personalPages.splice(index, 1) - toast.success("Page deleted.", { position: "bottom-right" }) - router.replace("/") - } catch (error) { - console.error("Delete operation fail", { error }) - } + deletePage(me, pageId as ID) + router.push("/pages") } } @@ -210,7 +201,7 @@ const DetailPageForm = ({ page }: { page: PersonalPage }) => { const titleEditor = useEditor({ immediatelyRender: false, - autofocus: true, + autofocus: false, extensions: [ FocusClasses, Paragraph, @@ -254,7 +245,13 @@ const DetailPageForm = ({ page }: { page: PersonalPage }) => { useEffect(() => { isTitleInitialMount.current = true isContentInitialMount.current = true - }, []) + + if (!page.title) { + titleEditor?.commands.focus() + } else { + contentEditorRef.current?.editor?.commands.focus() + } + }, [page.title, titleEditor, contentEditorRef]) return (
    diff --git a/web/components/routes/page/hooks/use-page-actions.ts b/web/components/routes/page/hooks/use-page-actions.ts new file mode 100644 index 000000000..986ea3d8b --- /dev/null +++ b/web/components/routes/page/hooks/use-page-actions.ts @@ -0,0 +1,36 @@ +import { useCallback } from "react" +import { toast } from "sonner" +import { LaAccount, PersonalPage } from "@/lib/schema" +import { ID } from "jazz-tools" + +export const usePageActions = () => { + const deletePage = useCallback((me: LaAccount, pageId: ID): void => { + if (!me.root?.personalPages) return + + const index = me.root.personalPages.findIndex(item => item?.id === pageId) + if (index === -1) { + toast.error("Page not found") + return + } + + const page = me.root.personalPages[index] + if (!page) { + toast.error("Page data is invalid") + return + } + + try { + me.root.personalPages.splice(index, 1) + + toast.success("Page deleted", { + position: "bottom-right", + description: `${page.title} has been deleted.` + }) + } catch (error) { + console.error("Failed to delete page", error) + toast.error("Failed to delete page") + } + }, []) + + return { deletePage } +} diff --git a/web/instrumentation.ts b/web/instrumentation.ts index 7f317a037..610b52145 100644 --- a/web/instrumentation.ts +++ b/web/instrumentation.ts @@ -1,5 +1,9 @@ +import * as Sentry from "@sentry/nextjs" + export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") { await import("./sentry.server.config") } } + +export const onRequestError = Sentry.captureRequestError diff --git a/web/next.config.mjs b/web/next.config.mjs index ba15307db..e0d5e7454 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -46,9 +46,8 @@ export default withSentryConfig(nextConfig, { // For all available options, see: // https://github.com/getsentry/sentry-webpack-plugin#options - org: "learn-anything", - project: process.env.SENTRY_PROJECT, - sentryUrl: "https://sentry.io/", + org: process.env.NEXT_PUBLIC_SENTRY_ORG, + project: process.env.NEXT_PUBLIC_SENTRY_PROJECT, // Only print logs for uploading source maps in CI silent: !process.env.CI, @@ -64,7 +63,7 @@ export default withSentryConfig(nextConfig, { enabled: true }, - // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. + // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. // This can increase your server load as well as your hosting bill. // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- // side errors will fail. diff --git a/web/package.json b/web/package.json index 4aeca69cd..278aa010a 100644 --- a/web/package.json +++ b/web/package.json @@ -36,7 +36,7 @@ "@radix-ui/react-toggle": "^1.1.0", "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", - "@sentry/nextjs": "^8.29.0", + "@sentry/nextjs": "^8.30.0", "@tanstack/react-virtual": "^3.10.7", "@tiptap/core": "^2.6.6", "@tiptap/extension-blockquote": "^2.6.6", @@ -105,7 +105,7 @@ "zsa-react": "^0.2.2" }, "devDependencies": { - "@ronin/learn-anything": "^0.0.0-3451915138150", + "@ronin/learn-anything": "^0.0.0-3451954511456", "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.1", "@types/jest": "^29.5.12", diff --git a/web/sentry.client.config.ts b/web/sentry.client.config.ts index 27056a387..a6e4ad986 100644 --- a/web/sentry.client.config.ts +++ b/web/sentry.client.config.ts @@ -5,7 +5,7 @@ import * as Sentry from "@sentry/nextjs" Sentry.init({ - dsn: process.env.SENTRY_DSN, + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, // Add optional integrations for additional features integrations: [Sentry.replayIntegration()], diff --git a/web/sentry.server.config.ts b/web/sentry.server.config.ts index 501766806..fe0b3c684 100644 --- a/web/sentry.server.config.ts +++ b/web/sentry.server.config.ts @@ -5,7 +5,7 @@ import * as Sentry from "@sentry/nextjs" Sentry.init({ - dsn: process.env.SENTRY_DSN, + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. tracesSampleRate: 1, diff --git a/web/store/link.ts b/web/store/link.ts index 6596857c2..5ad5c59ff 100644 --- a/web/store/link.ts +++ b/web/store/link.ts @@ -2,7 +2,6 @@ import { atom } from "jotai" import { atomWithStorage } from "jotai/utils" export const linkSortAtom = atomWithStorage("sort", "manual") -export const linkShowCreateAtom = atom(false) export const linkEditIdAtom = atom(null) export const linkLearningStateSelectorAtom = atom(false) export const linkOpenPopoverForIdAtom = atom(null)