From 2876da4072e1421a5a6865bd80f8f28dd3a30bd8 Mon Sep 17 00:00:00 2001
From: JOYCEQL <1449239013@qq.com>
Date: Thu, 26 Feb 2026 01:48:53 +0800
Subject: [PATCH] refactor: remove redundant 'use client' directives from
numerous components.
---
src/app/app/dashboard/ai/page.tsx | 1 -
src/app/app/dashboard/client.tsx | 1 -
src/app/app/dashboard/resumes/page.tsx | 1 -
src/app/app/dashboard/settings/page.tsx | 1 -
src/app/app/dashboard/templates/page.tsx | 1 -
src/app/app/workbench/[id]/page.tsx | 6 +-
src/app/providers.tsx | 1 -
src/components/editor/EditPanel.tsx | 1 -
src/components/editor/EditorHeader.tsx | 1 -
src/components/editor/Field.tsx | 1 -
src/components/editor/SidePanel.tsx | 1 -
src/components/editor/basic/BasicPanel.tsx | 1 -
.../editor/education/EducationItem.tsx | 1 -
.../editor/education/EducationPanel.tsx | 1 -
.../editor/experience/ExperienceItem.tsx | 1 -
.../editor/experience/ExperiencePanel.tsx | 1 -
.../editor/grammar/GrammarCheckDrawer.tsx | 1 -
src/components/editor/layout/LayoutItem.tsx | 1 -
.../editor/layout/LayoutSetting.tsx | 1 -
src/components/editor/project/ProjectItem.tsx | 1 -
src/components/editor/skills/SkillPanel.tsx | 1 -
src/components/home/FAQSection.tsx | 1 -
src/components/home/FeaturesSection.tsx | 1 -
src/components/home/GoDashboard.tsx | 1 -
src/components/home/LandingHeader.tsx | 1 -
.../home/client/AnimatedFeature.tsx | 1 -
src/components/home/client/MenuToggle.tsx | 1 -
src/components/home/client/MobileMenu.tsx | 1 -
.../home/client/ScrollBackground.tsx | 1 -
src/components/home/client/ScrollHeader.tsx | 1 -
src/components/mobile/MobileWorkbench.tsx | 2 +-
src/components/preview/CustomSection.tsx | 1 -
src/components/preview/EducationSection.tsx | 1 -
src/components/preview/ExperienceSection.tsx | 1 -
.../preview/IframeTemplateViewer.tsx | 1 -
src/components/preview/PreviewDock.tsx | 17 +++-
src/components/preview/ProjectSection.tsx | 1 -
src/components/preview/SectionTitle.tsx | 1 -
src/components/preview/SkillPanel.tsx | 1 -
src/components/preview/index.tsx | 1 -
src/components/shared/GitHubStars.tsx | 1 -
src/components/shared/GithubContribution.tsx | 1 -
src/components/shared/LanguageSwitch.tsx | 1 -
src/components/shared/Logo.tsx | 1 -
src/components/shared/PdfExport.tsx | 1 -
src/components/shared/PhotoConfigDrawer.tsx | 1 -
src/components/shared/PhotoSelector.tsx | 1 -
src/components/shared/ScrollToTop.tsx | 1 -
src/components/shared/TemplateSheet.tsx | 1 -
src/components/shared/ThemeModal.tsx | 1 -
src/components/shared/ThemeToggle.tsx | 1 -
src/components/shared/ai/AIPolishDialog.tsx | 1 -
.../shared/rich-editor/RichEditor.tsx | 1 -
src/components/ui/accordion.tsx | 1 -
src/components/ui/alert-dialog.tsx | 1 -
src/components/ui/calendar.tsx | 1 -
src/components/ui/color-picker.tsx | 1 -
src/components/ui/command.tsx | 1 -
src/components/ui/dialog.tsx | 1 -
src/components/ui/drawer.tsx | 1 -
src/components/ui/dropdown-menu.tsx | 1 -
src/components/ui/hover-card.tsx | 1 -
src/components/ui/label.tsx | 1 -
src/components/ui/popover.tsx | 1 -
src/components/ui/resizable.tsx | 1 -
src/components/ui/scroll-area.tsx | 1 -
src/components/ui/select.tsx | 1 -
src/components/ui/separator.tsx | 1 -
src/components/ui/sheet.tsx | 1 -
src/components/ui/sidebar.tsx | 1 -
src/components/ui/slider.tsx | 1 -
src/components/ui/sonner.tsx | 1 -
src/components/ui/switch.tsx | 1 -
src/components/ui/tabs.tsx | 1 -
src/components/ui/tooltip.tsx | 1 -
src/components/ui/unified-date-input.tsx | 1 -
.../ui/unified-date-range-input.tsx | 1 -
src/routes/app/dashboard.tsx | 1 +
src/routes/app/preview-template/$id.tsx | 1 +
src/store/useGrammarStore.ts | 99 +++++++++++++++----
80 files changed, 99 insertions(+), 101 deletions(-)
diff --git a/src/app/app/dashboard/ai/page.tsx b/src/app/app/dashboard/ai/page.tsx
index ad4820f..1e61a55 100644
--- a/src/app/app/dashboard/ai/page.tsx
+++ b/src/app/app/dashboard/ai/page.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useState, useEffect } from "react";
import { useTranslations } from "@/i18n/compat/client";
import { ExternalLink } from "lucide-react";
diff --git a/src/app/app/dashboard/client.tsx b/src/app/app/dashboard/client.tsx
index 3f1b766..2e6d13d 100644
--- a/src/app/app/dashboard/client.tsx
+++ b/src/app/app/dashboard/client.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useEffect, useState } from "react";
import { IconResumes, IconTemplates, IconSettings, IconAI } from "@/components/shared/icons/SidebarIcons";
import { usePathname, useRouter } from "@/lib/navigation";
diff --git a/src/app/app/dashboard/resumes/page.tsx b/src/app/app/dashboard/resumes/page.tsx
index 381b465..4b63351 100644
--- a/src/app/app/dashboard/resumes/page.tsx
+++ b/src/app/app/dashboard/resumes/page.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useEffect } from "react";
import { useTranslations, useLocale } from "@/i18n/compat/client";
import { useRouter } from "@/lib/navigation";
diff --git a/src/app/app/dashboard/settings/page.tsx b/src/app/app/dashboard/settings/page.tsx
index c5ef535..c812a00 100644
--- a/src/app/app/dashboard/settings/page.tsx
+++ b/src/app/app/dashboard/settings/page.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useState, useEffect } from "react";
import { Folder, Trash2 } from "lucide-react";
import { useTranslations } from "@/i18n/compat/client";
diff --git a/src/app/app/dashboard/templates/page.tsx b/src/app/app/dashboard/templates/page.tsx
index a2b0901..ed68cef 100644
--- a/src/app/app/dashboard/templates/page.tsx
+++ b/src/app/app/dashboard/templates/page.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useState, useRef } from "react";
import { useTranslations } from "@/i18n/compat/client";
import { motion } from "framer-motion";
diff --git a/src/app/app/workbench/[id]/page.tsx b/src/app/app/workbench/[id]/page.tsx
index b1fee5f..ece3503 100644
--- a/src/app/app/workbench/[id]/page.tsx
+++ b/src/app/app/workbench/[id]/page.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useState, useEffect, memo } from "react";
import { motion, AnimatePresence } from "framer-motion";
@@ -344,7 +343,10 @@ export default function Home() {
defaultSize={panelSizes?.[2]}
className="bg-gray-100"
>
-
+
{
- if (!resumeContentRef.current) return;
-
if (!checkConfiguration()) {
return;
}
try {
- const text = resumeContentRef.current.innerText;
+ const previewContent =
+ resumeContentRef.current || document.getElementById("resume-preview");
+ if (!previewContent) {
+ toast.error(t("grammarCheck.errorToast"));
+ return;
+ }
+
+ const text = previewContent.innerText?.trim();
+ if (!text) {
+ toast.error(t("grammarCheck.errorToast"));
+ return;
+ }
+
await checkGrammar(text);
} catch (error) {
toast.error(t("grammarCheck.errorToast"));
diff --git a/src/components/preview/ProjectSection.tsx b/src/components/preview/ProjectSection.tsx
index ffd60b2..fd0beb3 100644
--- a/src/components/preview/ProjectSection.tsx
+++ b/src/components/preview/ProjectSection.tsx
@@ -1,4 +1,3 @@
-"use client";
import React from "react";
import { motion, AnimatePresence } from "framer-motion";
diff --git a/src/components/preview/SectionTitle.tsx b/src/components/preview/SectionTitle.tsx
index fdabc5b..1c09690 100644
--- a/src/components/preview/SectionTitle.tsx
+++ b/src/components/preview/SectionTitle.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useMemo } from "react";
import { GlobalSettings } from "@/types/resume";
import { useResumeStore } from "@/store/useResumeStore";
diff --git a/src/components/preview/SkillPanel.tsx b/src/components/preview/SkillPanel.tsx
index 191ce26..73b2212 100644
--- a/src/components/preview/SkillPanel.tsx
+++ b/src/components/preview/SkillPanel.tsx
@@ -1,4 +1,3 @@
-"use client";
import { motion } from "framer-motion";
import SectionTitle from "./SectionTitle";
import { GlobalSettings } from "@/types/resume";
diff --git a/src/components/preview/index.tsx b/src/components/preview/index.tsx
index 7561792..1672da3 100644
--- a/src/components/preview/index.tsx
+++ b/src/components/preview/index.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useEffect, useMemo, useState, useRef } from "react";
import throttle from "lodash/throttle";
diff --git a/src/components/shared/GitHubStars.tsx b/src/components/shared/GitHubStars.tsx
index 961f506..651d56f 100644
--- a/src/components/shared/GitHubStars.tsx
+++ b/src/components/shared/GitHubStars.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useEffect, useState } from "react";
import { Star } from "lucide-react";
import { motion } from "framer-motion";
diff --git a/src/components/shared/GithubContribution.tsx b/src/components/shared/GithubContribution.tsx
index f141bdd..745b8b8 100644
--- a/src/components/shared/GithubContribution.tsx
+++ b/src/components/shared/GithubContribution.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
diff --git a/src/components/shared/LanguageSwitch.tsx b/src/components/shared/LanguageSwitch.tsx
index 4ed49c4..a9f4772 100644
--- a/src/components/shared/LanguageSwitch.tsx
+++ b/src/components/shared/LanguageSwitch.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useLocale } from "@/i18n/compat/client";
import { useLocation, useNavigate } from "@tanstack/react-router";
import { Languages } from "lucide-react";
diff --git a/src/components/shared/Logo.tsx b/src/components/shared/Logo.tsx
index 552217c..e98f18c 100644
--- a/src/components/shared/Logo.tsx
+++ b/src/components/shared/Logo.tsx
@@ -1,4 +1,3 @@
-"use client";
import React from "react";
import Image from "@/lib/image";
diff --git a/src/components/shared/PdfExport.tsx b/src/components/shared/PdfExport.tsx
index e152b1d..d82ed3b 100644
--- a/src/components/shared/PdfExport.tsx
+++ b/src/components/shared/PdfExport.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useState, useRef } from "react";
import { useTranslations } from "@/i18n/compat/client";
import {
diff --git a/src/components/shared/PhotoConfigDrawer.tsx b/src/components/shared/PhotoConfigDrawer.tsx
index 3806f03..903a5a7 100644
--- a/src/components/shared/PhotoConfigDrawer.tsx
+++ b/src/components/shared/PhotoConfigDrawer.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useState, useRef, useEffect } from "react";
import { motion } from "framer-motion";
import { Upload, X } from "lucide-react";
diff --git a/src/components/shared/PhotoSelector.tsx b/src/components/shared/PhotoSelector.tsx
index c644229..82164aa 100644
--- a/src/components/shared/PhotoSelector.tsx
+++ b/src/components/shared/PhotoSelector.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useState } from "react";
import { Settings2, Image, EyeOff, Eye } from "lucide-react";
import { Button } from "@/components/ui/button";
diff --git a/src/components/shared/ScrollToTop.tsx b/src/components/shared/ScrollToTop.tsx
index 0039d75..5787325 100644
--- a/src/components/shared/ScrollToTop.tsx
+++ b/src/components/shared/ScrollToTop.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useState, useEffect, useRef } from "react";
import { ArrowUp } from "lucide-react";
import { Button } from "@/components/ui/button";
diff --git a/src/components/shared/TemplateSheet.tsx b/src/components/shared/TemplateSheet.tsx
index 1cabea9..9e97482 100644
--- a/src/components/shared/TemplateSheet.tsx
+++ b/src/components/shared/TemplateSheet.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useEffect, useRef, useState } from "react";
import { Layout, PanelsLeftBottom } from "lucide-react";
import { motion } from "framer-motion";
diff --git a/src/components/shared/ThemeModal.tsx b/src/components/shared/ThemeModal.tsx
index bc0d5c3..ac5ed2a 100644
--- a/src/components/shared/ThemeModal.tsx
+++ b/src/components/shared/ThemeModal.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useState } from "react";
import { motion } from "framer-motion";
diff --git a/src/components/shared/ThemeToggle.tsx b/src/components/shared/ThemeToggle.tsx
index bf9c1a0..a9d72c5 100644
--- a/src/components/shared/ThemeToggle.tsx
+++ b/src/components/shared/ThemeToggle.tsx
@@ -1,4 +1,3 @@
-"use client";
import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";
diff --git a/src/components/shared/ai/AIPolishDialog.tsx b/src/components/shared/ai/AIPolishDialog.tsx
index 2afcda9..84aa862 100644
--- a/src/components/shared/ai/AIPolishDialog.tsx
+++ b/src/components/shared/ai/AIPolishDialog.tsx
@@ -1,4 +1,3 @@
-"use client";
import { useEffect, useState, useRef } from "react";
import { Loader2, Sparkles } from "lucide-react";
import { toast } from "sonner";
diff --git a/src/components/shared/rich-editor/RichEditor.tsx b/src/components/shared/rich-editor/RichEditor.tsx
index 03b9d49..d313555 100644
--- a/src/components/shared/rich-editor/RichEditor.tsx
+++ b/src/components/shared/rich-editor/RichEditor.tsx
@@ -1,4 +1,3 @@
-"use client";
import React, { useEffect } from "react";
import { useEditor, EditorContent } from "@tiptap/react";
import { useTranslations } from "@/i18n/compat/client";
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
index 2f55a32..a9f78b1 100644
--- a/src/components/ui/accordion.tsx
+++ b/src/components/ui/accordion.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx
index 25e7b47..f49ac77 100644
--- a/src/components/ui/alert-dialog.tsx
+++ b/src/components/ui/alert-dialog.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx
index 2f02434..eb1d091 100644
--- a/src/components/ui/calendar.tsx
+++ b/src/components/ui/calendar.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
diff --git a/src/components/ui/color-picker.tsx b/src/components/ui/color-picker.tsx
index 0c8c497..167ab16 100644
--- a/src/components/ui/color-picker.tsx
+++ b/src/components/ui/color-picker.tsx
@@ -1,4 +1,3 @@
-"use client";
import { forwardRef, useMemo, useState } from "react";
import { HexColorPicker } from "react-colorful";
diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx
index ace9b53..ad2e807 100644
--- a/src/components/ui/command.tsx
+++ b/src/components/ui/command.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import { type DialogProps } from "@radix-ui/react-dialog"
diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx
index af8d0a5..01013bd 100644
--- a/src/components/ui/dialog.tsx
+++ b/src/components/ui/dialog.tsx
@@ -1,4 +1,3 @@
-"use client";
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
diff --git a/src/components/ui/drawer.tsx b/src/components/ui/drawer.tsx
index 6a0ef53..d15a69d 100644
--- a/src/components/ui/drawer.tsx
+++ b/src/components/ui/drawer.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx
index 0fc4c0e..6421c83 100644
--- a/src/components/ui/dropdown-menu.tsx
+++ b/src/components/ui/dropdown-menu.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
diff --git a/src/components/ui/hover-card.tsx b/src/components/ui/hover-card.tsx
index e54d91c..79e061d 100644
--- a/src/components/ui/hover-card.tsx
+++ b/src/components/ui/hover-card.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx
index 5341821..a44cd78 100644
--- a/src/components/ui/label.tsx
+++ b/src/components/ui/label.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
index a0ec48b..0910077 100644
--- a/src/components/ui/popover.tsx
+++ b/src/components/ui/popover.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
diff --git a/src/components/ui/resizable.tsx b/src/components/ui/resizable.tsx
index f4bc558..a3b1c2d 100644
--- a/src/components/ui/resizable.tsx
+++ b/src/components/ui/resizable.tsx
@@ -1,4 +1,3 @@
-"use client"
import { GripVertical } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"
diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx
index 0b4a48d..3f73997 100644
--- a/src/components/ui/scroll-area.tsx
+++ b/src/components/ui/scroll-area.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx
index cbe5a36..4911962 100644
--- a/src/components/ui/select.tsx
+++ b/src/components/ui/select.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx
index 12d81c4..658f0cf 100644
--- a/src/components/ui/separator.tsx
+++ b/src/components/ui/separator.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx
index a37f17b..15ad757 100644
--- a/src/components/ui/sheet.tsx
+++ b/src/components/ui/sheet.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index 23ab98e..4579e9f 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -1,4 +1,3 @@
-"use client";
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
diff --git a/src/components/ui/slider.tsx b/src/components/ui/slider.tsx
index c31c2b3..7ebcc1e 100644
--- a/src/components/ui/slider.tsx
+++ b/src/components/ui/slider.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"
diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx
index 452f4d9..6dc449e 100644
--- a/src/components/ui/sonner.tsx
+++ b/src/components/ui/sonner.tsx
@@ -1,4 +1,3 @@
-"use client"
import { useTheme } from "next-themes"
import { Toaster as Sonner } from "sonner"
diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx
index bc69cf2..ee1f4b8 100644
--- a/src/components/ui/switch.tsx
+++ b/src/components/ui/switch.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as SwitchPrimitives from "@radix-ui/react-switch"
diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx
index 26eb109..ffb5beb 100644
--- a/src/components/ui/tabs.tsx
+++ b/src/components/ui/tabs.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx
index 30fc44d..3de65cd 100644
--- a/src/components/ui/tooltip.tsx
+++ b/src/components/ui/tooltip.tsx
@@ -1,4 +1,3 @@
-"use client"
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
diff --git a/src/components/ui/unified-date-input.tsx b/src/components/ui/unified-date-input.tsx
index aa3aab7..1bc4c3f 100644
--- a/src/components/ui/unified-date-input.tsx
+++ b/src/components/ui/unified-date-input.tsx
@@ -1,4 +1,3 @@
-"use client";
import { DateInput } from "@heroui/date-input";
import { HeroUIProvider } from "@heroui/react";
diff --git a/src/components/ui/unified-date-range-input.tsx b/src/components/ui/unified-date-range-input.tsx
index 2455d42..ff3a1cf 100644
--- a/src/components/ui/unified-date-range-input.tsx
+++ b/src/components/ui/unified-date-range-input.tsx
@@ -1,4 +1,3 @@
-"use client";
import { DateInput } from "@heroui/date-input";
import { HeroUIProvider } from "@heroui/react";
diff --git a/src/routes/app/dashboard.tsx b/src/routes/app/dashboard.tsx
index 6b27459..0fd920f 100644
--- a/src/routes/app/dashboard.tsx
+++ b/src/routes/app/dashboard.tsx
@@ -5,6 +5,7 @@ export const Route = createFileRoute("/app/dashboard")({
head: () => ({
meta: [{ name: "robots", content: "noindex,nofollow" }]
}),
+ ssr: false,
component: DashboardRouteLayout
});
diff --git a/src/routes/app/preview-template/$id.tsx b/src/routes/app/preview-template/$id.tsx
index 4e626bd..17c6bc9 100644
--- a/src/routes/app/preview-template/$id.tsx
+++ b/src/routes/app/preview-template/$id.tsx
@@ -2,5 +2,6 @@ import { createFileRoute } from '@tanstack/react-router'
import IframeTemplateViewer from '../../../components/preview/IframeTemplateViewer'
export const Route = createFileRoute('/app/preview-template/$id')({
+ ssr: false,
component: IframeTemplateViewer,
})
diff --git a/src/store/useGrammarStore.ts b/src/store/useGrammarStore.ts
index 5eed195..f9b29a9 100644
--- a/src/store/useGrammarStore.ts
+++ b/src/store/useGrammarStore.ts
@@ -28,6 +28,55 @@ interface GrammarStore {
dismissError: (index: number) => void;
}
+const markSingleError = (
+ marker: Mark,
+ error: GrammarError,
+ options?: { selected?: boolean; activeIndex?: number }
+) => {
+ const keyword = (error.text || "").trim();
+ if (!keyword) return;
+
+ let hasMarked = false;
+ marker.mark(keyword, {
+ separateWordSearch: false,
+ acrossElements: true,
+ className: cn(
+ "grammar-error",
+ error.type,
+ options?.selected && options?.activeIndex !== undefined && `active-${options.activeIndex}`
+ ),
+ filter: () => {
+ if (hasMarked) return false;
+ hasMarked = true;
+ return true;
+ }
+ });
+};
+
+const getPreviewScrollContainer = (element: HTMLElement): HTMLElement | null => {
+ const containers = Array.from(
+ document.querySelectorAll('[data-preview-scroll-container="true"]')
+ );
+
+ for (const container of containers) {
+ if (container.contains(element)) {
+ return container;
+ }
+ }
+
+ let current: HTMLElement | null = element.parentElement;
+ while (current) {
+ const style = window.getComputedStyle(current);
+ const canScrollY = /(auto|scroll)/.test(style.overflowY);
+ if (canScrollY && current.scrollHeight > current.clientHeight) {
+ return current;
+ }
+ current = current.parentElement;
+ }
+
+ return null;
+};
+
export const useGrammarStore = create((set, get) => ({
isChecking: false,
errors: [],
@@ -104,9 +153,8 @@ export const useGrammarStore = create((set, get) => ({
const marker = new Mark(preview);
marker.unmark();
grammarErrors.errors.forEach((error: GrammarError) => {
- marker.mark(error.context || error.text || "", {
- className: "bg-yellow-200 dark:bg-yellow-900",
- });
+ // 仅标注错误片段,避免整句/全局模糊匹配造成误高亮
+ markSingleError(marker, error);
});
}
} catch (parseError) {
@@ -143,21 +191,36 @@ export const useGrammarStore = create((set, get) => ({
marker.unmark();
errors.forEach((err, i) => {
- marker.mark(err.context || err.text || "", {
- className: cn(
- "bg-yellow-200 dark:bg-yellow-900",
- i === index && "bg-green-200 dark:bg-green-900"
- ),
+ markSingleError(marker, err, {
+ selected: i === index,
+ activeIndex: index
});
});
const marks = preview.querySelectorAll("mark");
const selectedMark = marks[index];
if (selectedMark) {
- selectedMark.scrollIntoView({
- behavior: "smooth",
- block: "center",
- });
+ const scrollContainer = getPreviewScrollContainer(selectedMark as HTMLElement);
+
+ if (scrollContainer) {
+ const containerRect = scrollContainer.getBoundingClientRect();
+ const markRect = selectedMark.getBoundingClientRect();
+ const currentTop = scrollContainer.scrollTop;
+ const nextTop =
+ currentTop +
+ (markRect.top - containerRect.top) -
+ scrollContainer.clientHeight / 2 +
+ markRect.height / 2;
+ const maxTop = Math.max(
+ 0,
+ scrollContainer.scrollHeight - scrollContainer.clientHeight
+ );
+
+ scrollContainer.scrollTo({
+ top: Math.max(0, Math.min(nextTop, maxTop)),
+ behavior: "smooth"
+ });
+ }
}
},
dismissError: (index: number) => {
@@ -171,14 +234,10 @@ export const useGrammarStore = create((set, get) => ({
const marker = new Mark(preview);
marker.unmark();
newErrors.forEach((error, i) => {
- marker.mark(error.context || error.text || "", {
- className: cn(
- "bg-yellow-200 dark:bg-yellow-900",
- state.selectedErrorIndex === i && "bg-green-200 dark:bg-green-900"
- // 注意:selectedErrorIndex 可能因为删除而需要调整,这里简化处理,稍后在选中逻辑中可能需要优化
- // 为了保持一致性,最好是重新选中当前索引或重置选中
- )
- });
+ markSingleError(marker, error, {
+ selected: state.selectedErrorIndex === i,
+ activeIndex: state.selectedErrorIndex ?? undefined
+ });
});
}