-
-
Notifications
You must be signed in to change notification settings - Fork 0
Add documantation markdown cms #124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (17)
app/prism-languages.ts (1)
1-29
: PrismJS languages set up nicely. Loading the key languages and extending TypeScript is on point. Consider translating the Polish comment (Dodaj inne języki według potrzeb
) to English for consistency.components/docs/DocCopyEnhancer.tsx (3)
8-8
: Remove or translate non-English commentThe comment "już jest" should be in English for consistency.
- if (preEl.querySelector(".copy-btn")) return; // już jest + if (preEl.querySelector(".copy-btn")) return; // already exists
15-21
: Simplify string escaping in setTimeout callbackThe template string in setTimeout has unnecessary escaped quotes.
- btn.innerHTML = `<svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path d=\"M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z\"/></svg>Copy`; + btn.innerHTML = `<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>Copy`;
4-27
: Consider a more React-like approach for DOM manipulationWhile the current implementation works, using direct DOM manipulation in React can sometimes lead to issues. Consider using React refs and a more declarative approach:
"use client"; import { useEffect, useRef } from "react"; export default function DocCopyEnhancer() { const timeoutRef = useRef<NodeJS.Timeout | null>(null); useEffect(() => { const addCopyButtons = () => { document.querySelectorAll(".prose pre").forEach((pre) => { const preEl = pre as HTMLElement; if (preEl.querySelector(".copy-btn")) return; // already exists const btn = document.createElement("button"); btn.className = "copy-btn absolute top-3 right-4 z-10 flex items-center gap-1 rounded-md bg-[#23272e] text-gray-300 border border-gray-700 px-3 py-1 text-xs font-medium opacity-70 hover:opacity-100 hover:bg-[#181c23] hover:text-white transition-all shadow"; btn.innerHTML = `<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>Copy`; btn.type = "button"; btn.onclick = async () => { await navigator.clipboard.writeText(preEl.innerText); btn.innerHTML = `<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M5 13l4 4L19 7"/></svg>Copied!`; // Clear any existing timeout if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { btn.innerHTML = `<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>Copy`; timeoutRef.current = null; }, 1200); }; preEl.style.position = "relative"; preEl.appendChild(btn); }); }; // Run once on mount addCopyButtons(); // Clean up timeouts on unmount return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); return null; }components/docs/DocSearch.tsx (1)
13-88
: Nice search implementation with good user experienceThe search component works well with debouncing, loading indicators, and clear result presentation. Here are a few small suggestions:
- Consider showing a message when no results are found but the query is valid
- Add keyboard navigation support for the dropdown results
{results.length > 0 && ( <div className="absolute z-10 mt-2 w-full rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800"> {results.map((result) => ( <button key={result.path} onClick={() => { router.push(result.path); setQuery(""); setResults([]); }} className="w-full px-4 py-2 text-left hover:bg-gray-100 focus:outline-none dark:hover:bg-gray-700" > <div className="font-medium text-gray-900 dark:text-white"> {result.title} </div> <div className="text-sm text-gray-500 dark:text-gray-400"> {result.excerpt} </div> </button> ))} </div> )} + {query.length >= 2 && results.length === 0 && !isLoading && ( + <div className="absolute z-10 mt-2 w-full rounded-lg border border-gray-200 bg-white p-4 text-center text-sm text-gray-500 shadow-lg dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400"> + No results found + </div> + )}components/docs/DocSidebar.tsx (1)
34-34
: Remove redundant folder iconThis line adds a folder icon even though it's already handled in the hasChildren branch above.
- {hasChildren && <Folder className="mr-2 h-4 w-4" />}
content/docs/formatting.md (2)
8-8
: Minor grammar fix neededMissing "the" article before "formatting options".
-Below you can find all formatting options supported in our documentation system. +Below you can find all the formatting options supported in our documentation system.🧰 Tools
🪛 LanguageTool
[uncategorized] ~8-~8: You might be missing the article “the” here.
Context: ...atting Examples Below you can find all formatting options supported in our documentation ...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
1-99
: Great documentation examples!The formatting examples cover most common markdown features and custom components. It's very helpful for users.
Consider adding an example of a table, which is often useful in documentation:
## Tables | Header 1 | Header 2 | |----------|----------| | Cell 1 | Cell 2 | | Cell 3 | Cell 4 |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~8-~8: You might be missing the article “the” here.
Context: ...atting Examples Below you can find all formatting options supported in our documentation ...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
app/api/docs/search/route.ts (2)
12-56
: Consider adding search result limits.The search function works well for small to medium documentation sets, but could benefit from a result limit to prevent performance issues with large document collections.
async function searchInDirectory( dir: string, query: string, + maxResults: number = 20 ): Promise<SearchResult[]> { const results: SearchResult[] = []; const entries = await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); + // Stop searching if we've reached the maximum results + if (results.length >= maxResults) break; if (entry.isDirectory()) { const subResults = await searchInDirectory(fullPath, query); results.push(...subResults); + // Trim results if we've exceeded the maximum + if (results.length > maxResults) { + results.length = maxResults; + break; + } } else if (entry.isFile() && entry.name.endsWith(".md")) { // Rest of the code remains the same
36-41
: Simple excerpt generation.The excerpt creation works well, but consider adding a check for empty content to avoid empty excerpts.
const excerpt = markdownContent .split("\n") .slice(0, 3) .join(" ") - .substring(0, 150); + .substring(0, 150) || "No content available";app/docs/layout.tsx (2)
9-13
: Font configuration is simple.The Poppins font is configured with a single weight, which is efficient but might be limiting. Consider adding more weights if headers or emphasized text will use this font.
20-52
: Layout structure is clean and responsive.The documentation layout has a good responsive design with sidebar and main content areas.
- <div id="docs-navigation-buttons" className="flex w-full max-w-4xl justify-between"> - {/* Przyciski Next/Previous będą renderowane w page.tsx */} - </div> + <div id="docs-navigation-buttons" className="flex w-full max-w-4xl justify-between"> + {/* Next/Previous buttons will be rendered in page.tsx */} + </div>components/docs/AnimatedHeading.tsx (1)
4-68
: Good factory pattern for heading components.The createAnimatedHeading factory function efficiently generates heading components with consistent behavior.
Consider adding a fallback for browsers without clipboard API and translating the hardcoded text:
if (navigator.clipboard) { navigator.clipboard.writeText( window.location.origin + window.location.pathname + `#${headingId}` ); +} else { + // Fallback for browsers without clipboard API + const textArea = document.createElement('textarea'); + textArea.value = window.location.origin + window.location.pathname + `#${headingId}`; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); } // Later in the code: {copied && ( <span className="animate-fade-in ml-2 text-xs text-green-500"> - Skopiowano! + Copied! </span> )} // And change the aria-label: -aria-label="Kopiuj link do nagłówka" +aria-label="Copy link to heading"app/docs/[...slug]/page.tsx (1)
64-105
: Document rendering with MDX and navigation.The document rendering includes title, description, content with custom components, and navigation links.
Consider making the navigation links styling more consistent:
<a href={prev.path} - className="rounded-lg border border-gray-200 bg-gray-100 px-4 py-2 no-underline transition-colors hover:bg-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700" + className="rounded-lg border border-gray-200 bg-gray-100 px-4 py-2 no-underline transition-colors hover:bg-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700" > ← {prev.title} </a> // Later for next link: <a href={next.path} - className="rounded-lg bg-blue-600 px-4 py-2 text-white no-underline transition-colors hover:bg-blue-700" + className="rounded-lg border border-blue-600 bg-blue-600 px-4 py-2 text-white no-underline transition-colors hover:bg-blue-700" >components/docs/CodeTabs.tsx (3)
18-19
: Consider avoiding 'any' type.The type casting with
as any
makes your code less type-safe. Try using more specific types to improve type checking.- const Icon = (SIIcons as any)[iconName]; + const Icon = (SIIcons as Record<string, React.ComponentType<{ className: string, title: string, size: number }>>)[iconName];
11-25
: Add error handling for label formatting.The icon name formatting assumes valid inputs. Consider adding validation or error handling for edge cases.
function getLanguageIcon(label: string) { + if (!label) return <span className="mr-1">📄</span>; const iconName = "Si" + label .replace(/[^a-zA-Z0-9]/g, "") .toLowerCase() .replace(/^./, (c) => c.toUpperCase()); const Icon = (SIIcons as any)[iconName]; if (Icon) return <Icon className="mr-1" title={label} size={18} />; return ( <span className="mr-1" title={label}> 📄 </span> ); }
29-68
: Add aria labels for better accessibility.The tabs would benefit from additional ARIA attributes to improve screen reader experience.
return ( - <div className="my-6 overflow-hidden rounded-xl bg-gray-800 shadow"> + <div className="my-6 overflow-hidden rounded-xl bg-gray-800 shadow" role="region" aria-label="Code examples"> <TabGroup> <TabList className="flex space-x-1 px-2 pb-0 pl-4 pt-2">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
bun.lock
is excluded by!**/*.lock
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (27)
app/api/docs/search/route.ts
(1 hunks)app/docs/[...slug]/page.tsx
(1 hunks)app/docs/layout.tsx
(1 hunks)app/docs/page.tsx
(1 hunks)app/globals.css
(2 hunks)app/layout.tsx
(1 hunks)app/page.tsx
(1 hunks)app/prism-languages.ts
(1 hunks)app/prism-tomorrow.css
(1 hunks)app/projects/page.tsx
(2 hunks)app/team/page.tsx
(2 hunks)components/docs/Alert.tsx
(1 hunks)components/docs/AnimatedHeading.tsx
(1 hunks)components/docs/CodeTabs.tsx
(1 hunks)components/docs/DocCopyEnhancer.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/docs/sidebar-structure.ts
(1 hunks)components/footer/Footer.tsx
(1 hunks)components/header/Navbar.tsx
(1 hunks)components/team/Team.tsx
(1 hunks)content/docs/formatting.md
(1 hunks)content/docs/getting-started/installation.md
(1 hunks)content/docs/getting-started/introduction.md
(1 hunks)lib/mdx.ts
(1 hunks)package.json
(1 hunks)tailwind.config.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
app/projects/page.tsx (1)
components/header/hero/Hero.tsx (1)
Hero
(8-41)
app/team/page.tsx (1)
components/header/hero/Hero.tsx (1)
Hero
(8-41)
app/page.tsx (1)
components/header/hero/Hero.tsx (1)
Hero
(8-41)
app/docs/page.tsx (1)
components/SectionTitle.tsx (1)
SectionTitle
(3-24)
lib/mdx.ts (1)
components/docs/AnimatedHeading.tsx (4)
H1
(70-70)H2
(71-71)H3
(72-72)H4
(73-73)
components/docs/DocSidebar.tsx (1)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-28)
app/docs/[...slug]/page.tsx (2)
components/docs/sidebar-structure.ts (1)
docsStructure
(7-28)lib/mdx.ts (1)
components
(9-17)
🪛 LanguageTool
content/docs/formatting.md
[uncategorized] ~8-~8: You might be missing the article “the” here.
Context: ...atting Examples Below you can find all formatting options supported in our documentation ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
🔇 Additional comments (34)
tailwind.config.ts (1)
19-22
: Nice addition of typography plugin! Including@tailwindcss/typography
will give you great default prose styles for your markdown content.components/footer/Footer.tsx (1)
34-35
: Footer text split looks good. Breaking the line improves readability without changing meaning.app/prism-tomorrow.css (1)
1-124
: Prism Tomorrow theme is correctly applied. The CSS covers code and inline blocks with a consistent dark palette.app/projects/page.tsx (2)
3-3
: Importing the Hero component is correct. This aligns with the other pages in your app.
16-16
: Hero component added to main content. This will give the docs and projects pages a consistent look.app/page.tsx (1)
4-4
: Hero component added to home pageThis change adds the Hero component from the header/hero directory to the home page. This is part of moving the Hero from the global layout to individual pages, which is a good approach for more specific control.
Also applies to: 12-12
app/team/page.tsx (1)
3-3
: Hero component added to team pageThe addition of the Hero component to the team page matches the same pattern used on the home page, creating consistent UI across the site.
Also applies to: 13-13
app/layout.tsx (1)
11-11
: Added Prism language supportThe import of Prism language configuration supports syntax highlighting for the new documentation system, replacing the previous Hero component that's now in individual pages.
components/header/Navbar.tsx (1)
29-32
: Updated Documentation linkChanged the documentation link from external URL to internal path
/docs
, correctly updating theisExternal
flag to match. This connects to the new internal documentation system being added.components/team/Team.tsx (1)
100-101
: Looks good!Simple class order change that doesn't affect the visual appearance.
app/globals.css (4)
1-1
: Good addition for code highlightingAdding the Prism theme will help with syntax highlighting in the documentation.
6-12
: Nice font styling for code blocksConsistent font family helps make code more readable.
14-19
: Good font consistencyApplying the same fonts to all code elements keeps things looking uniform.
34-41
: Clean heading linksRemoving decoration from heading links gives a cleaner look in documentation.
app/docs/page.tsx (1)
4-52
: Good documentation landing page!Nice, clean documentation page with clear section links. The layout is responsive and has good dark mode support.
content/docs/getting-started/introduction.md (1)
1-51
: Well-structured introductionClear, organized content with good use of headings, lists, and code examples. This provides a helpful starting point for users.
components/docs/Alert.tsx (1)
1-20
: Clean alert component implementation!This alert component is well-structured with four different types (info, warning, danger, tip) and consistent styling for both light and dark modes. The component is simple and focused, making it easy to use in documentation.
components/docs/sidebar-structure.ts (1)
1-28
: Well-organized sidebar structure!The TypeScript interface and structure definition provide a clean way to organize documentation navigation. The hierarchy makes sense with main sections and child pages.
package.json (1)
14-36
: Appropriate dependencies for documentation systemAll the added dependencies support the documentation features described in the PR. The markdown processing, syntax highlighting, and UI libraries are current and work well together.
content/docs/getting-started/installation.md (1)
1-84
: Good installation guide with a few placeholders to updateThe installation instructions are clear, but there are some placeholders that should be updated before release:
- The repository URL is generic (line 22)
- Some linked pages at the end may not exist yet (lines 81-83)
- The guide mentions
next-contentlayer
which isn't in the package.json we reviewedCould you confirm if the linked pages exist and if
next-contentlayer
should be added to the dependencies?lib/mdx.ts (1)
1-27
: Well-structured MDX configurationThe component mappings and plugin setup look good. This provides a solid foundation for the documentation system.
You might want to consider adding some configuration for rehypePrism to specify which languages to support explicitly.
app/api/docs/search/route.ts (4)
1-5
: Imports look good.The necessary imports are included for handling API routes, file operations, path manipulation, and markdown parsing.
6-10
: Clean interface definition.The SearchResult interface clearly defines the structure of search results with title, path, and excerpt.
29-35
: Path normalization looks complex but correct.The path normalization logic correctly converts file system paths to URL paths for the documentation.
58-74
: Good error handling in the API route.The GET handler properly handles missing queries and search errors with appropriate responses.
app/docs/layout.tsx (2)
1-8
: Imports are appropriate.All necessary components for the documentation layout are properly imported.
15-18
: Good metadata for SEO.The page title and description are appropriately set for search engine optimization.
components/docs/AnimatedHeading.tsx (2)
1-3
: Client-side component with proper imports.The component is correctly marked as a client component with the necessary imports.
70-73
: Clean exports of heading components.The heading components are exported clearly using the factory function.
app/docs/[...slug]/page.tsx (4)
1-8
: Appropriate imports for document rendering.All necessary imports for file system operations, MDX rendering, and navigation are included.
9-28
: Utility function for flattening docs structure.The flattenDocs function works correctly to create a linear navigation structure from the nested sidebar.
36-51
: Good document fetching function.The getDocBySlug function properly handles file reading and parsing, with error handling.
53-63
: Clean page component setup with navigation.The DocPage component correctly handles missing documents and sets up previous/next navigation.
components/docs/CodeTabs.tsx (1)
77-79
: LGTM. Simple and effective component.The CodeTab component is clean and focused on its purpose of being a container for tab content.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
components/docs/sidebar-structure.ts (1)
7-15
: Good structure for the docs sidebarThis creates a clear hierarchy for the documentation. As the docs grow, you'll be able to easily add more sections and pages here.
Consider adding a brief comment explaining the purpose of this file for other developers who might work with it later.
app/globals.css (2)
6-12
: Nice font setup—could DRY it up.You’re repeating the same font list twice. Consider merging this block with the next to reduce duplication.
14-19
: Good catch for inline code styling—ditto on DRYness.This block and the one above share the same
font-family
. You could combine them into one selector.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (7)
app/globals.css
(2 hunks)app/layout.tsx
(2 hunks)components/docs/AnimatedHeading.tsx
(1 hunks)components/docs/sidebar-structure.ts
(1 hunks)content/docs/documentation-editors/markdown-guide.md
(1 hunks)lib/mdx.ts
(1 hunks)package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- content/docs/documentation-editors/markdown-guide.md
🚧 Files skipped from review as they are similar to previous changes (4)
- app/layout.tsx
- package.json
- components/docs/AnimatedHeading.tsx
- lib/mdx.ts
🔇 Additional comments (8)
components/docs/sidebar-structure.ts (1)
1-5
: Nice interface definition!The DocItem interface looks well-structured and clearly defines what a documentation item should contain.
app/globals.css (7)
1-1
: Check import path and load order.Make sure
prism-tomorrow.css
lives atapp/prism-tomorrow.css
and that the theme is applied correctly when your docs render.
34-41
: Good removal of heading link decoration.Clears underlines and shadows so headings stay clean.
43-51
: Solid table container styling.Borders, rounding, and shadow will make your tables pop.
58-65
: Table header cell styling looks great.Padding, uppercase, and spacing will improve readability.
67-71
: Body cell styling is solid.Consistent padding and borders make for neat rows.
79-81
: Dark mode header looks good.A darker header background improves contrast in dark mode.
83-86
: Dark mode cell borders and background are consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
components/docs/DocSidebar.tsx (1)
19-19
: Good fix for Tailwind class namingThe conditional class based on level is correctly implemented now, avoiding string interpolation that wouldn't work with Tailwind in production.
🧹 Nitpick comments (32)
components/docs/DynamicCommandsTable.tsx (2)
17-26
: Consider making the URL configurableThe GitHub URL is hardcoded, which might make it difficult to update later or use different URLs in different environments.
+const COMMANDS_URL = process.env.NEXT_PUBLIC_COMMANDS_URL || + "https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_commands_docs.json"; useEffect(() => { - fetch("https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_commands_docs.json") + fetch(COMMANDS_URL) .then((res) => {
44-51
: Use stable keys for better React performanceUsing array index as key may cause issues if the list order changes. Consider using the command name if it's unique.
-{commands.map((c, i) => ( - <tr key={i}> +{commands.map((c) => ( + <tr key={c.name}>components/docs/DynamicFeaturesTable.tsx (2)
16-25
: Consider making the URL configurableSimilar to the commands table, the GitHub URL is hardcoded. Making it configurable would improve flexibility.
+const FEATURES_URL = process.env.NEXT_PUBLIC_FEATURES_URL || + "https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_features_docs.json"; useEffect(() => { - fetch("https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_features_docs.json") + fetch(FEATURES_URL) .then((res) => {
42-52
: Use stable keys for better React performanceUsing array index as key may cause issues if the list order changes. Consider using the feature name if it's unique.
-{features.map((f, i) => ( - <tr key={i}> +{features.map((f) => ( + <tr key={f.name}>content/docs/eternalcore/introduction.md (1)
7-8
: Fix minor grammar issuesThere are two small grammar issues to address:
- Remove the comma before "that everyone needs"
- Add "The" before "Plugin includes" at the start of a sentence
-Plugin for minecraft servers that includes most basic functions and commands, that everyone needs. It's easy to use and configure. It's also very lightweight and fast. -Plugin includes full support for teleportation, warps, homes and chat management. +Plugin for minecraft servers that includes most basic functions and commands that everyone needs. It's easy to use and configure. It's also very lightweight and fast. +The plugin includes full support for teleportation, warps, homes and chat management.🧰 Tools
🪛 LanguageTool
[typographical] ~7-~7: Make sure that the comma (,) is correct. Do not use a comma before a dependent clause that starts with ‘that’.
Context: ...cludes most basic functions and commands, that everyone needs. It's easy to use and co...(COMMA_THAT_NOUN)
[uncategorized] ~7-~7: A determiner appears to be missing. Consider inserting it.
Context: ...e. It's also very lightweight and fast. Plugin includes full support for teleportation...(AI_EN_LECTOR_MISSING_DETERMINER)
content/docs/eternalcore/homes.md (2)
5-6
: Remove redundant textThe phrase "EternalCore Homes" appears twice in succession. Consider removing the duplicate at the beginning of line 6.
# 🏠 EternalCore Homes -EternalCore Homes is a feature that allows players to set their own homes and teleport to them. +This feature allows players to set their own homes and teleport to them.🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: This phrase is duplicated. You should probably use “EternalCore Homes” only once.
Context: ...-- title: EternalCore - Homes --- # 🏠 EternalCore Homes EternalCore Homes is a feature that allows players to set...(PHRASE_REPETITION)
9-9
: Refine grammarRemove the article "a" before "permission" since it's an uncountable noun in this context.
-It is possible to configure the maximum number of homes for a given permission. +It is possible to configure the maximum number of homes for given permissions.🧰 Tools
🪛 LanguageTool
[grammar] ~9-~9: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...nfigure the maximum number of homes for a given permission. ```yaml # Homes Section homes: # Ma...(A_UNCOUNTABLE_NOUN)
content/docs/eternalcombat/features.md (1)
15-15
: Fix grammarAdd "the" before "all features."
-EternalCombat allows you to customize your combat experience. You can find all features below. +EternalCombat allows you to customize your combat experience. You can find all the features below.🧰 Tools
🪛 LanguageTool
[uncategorized] ~15-~15: You might be missing the article “the” here.
Context: ...our combat experience. You can find all features below. - Combat duration, - Combat mes...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
content/docs/eternalcore/faq.md (3)
13-13
: Add "the" before file names-You can disable command in `commands.yml` file. +You can disable command in the `commands.yml` file.🧰 Tools
🪛 LanguageTool
[uncategorized] ~13-~13: You might be missing the article “the” here.
Context: ...## Solution: You can disable command incommands.yml
file. ### Example: ```yam...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
41-41
: Grammar improvementsSeveral grammar fixes needed in this sentence.
-I want to create in game title with timer, but it keeps flickering on users screen. +I want to create an in-game title with a timer, but it keeps flickering on users' screen.🧰 Tools
🪛 LanguageTool
[style] ~41-~41: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ... title from flickering? ### Problem: I want to create in game title with timer, but it...(REP_WANT_TO_VB)
[uncategorized] ~41-~41: Possible missing article found.
Context: ...ckering? ### Problem: I want to create in game title with timer, but it keeps fli...(AI_HYDRA_LEO_MISSING_AN)
[uncategorized] ~41-~41: You might be missing the article “a” here.
Context: ...em: I want to create in game title with timer, but it keeps flickering on users scree...(AI_EN_LECTOR_MISSING_DETERMINER_A)
[uncategorized] ~41-~41: It seems likely that a singular genitive (’s) apostrophe is missing.
Context: ... with timer, but it keeps flickering on users screen. ### Solution: You can use `tim...(AI_HYDRA_LEO_APOSTROPHE_S_XS)
44-44
: Add "the" before file names-You can use `times` key in configuration file. +You can use the `times` key in the configuration file.🧰 Tools
🪛 LanguageTool
[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...sers screen. ### Solution: You can usetimes
key in configuration file. ### E...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...## Solution: You can usetimes
key in configuration file. ### Example: ```yaml teleportT...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
content/docs/contribute/guide.md (4)
24-24
: Improve code example clarityRemove the curly braces from the URL placeholder to avoid confusion.
-git clone "{URL you just copied}" +git clone "URL-you-just-copied"
36-36
: Improve code example clarityThe branch name format in this example should match the one used in step 5.
-git checkout -b <your-new-branch-name> +git checkout -b your-new-branch-name
47-47
: Match branch name pattern with previous example-git push origin add-your-branch-name +git push origin your-new-branch-name
56-56
: Fix loose punctuationRemove the unexpected ":>" at the end of the sentence.
-You have successfully made a contribution to this project. :> +You have successfully made a contribution to this project!🧰 Tools
🪛 LanguageTool
[uncategorized] ~56-~56: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>(UNLIKELY_OPENING_PUNCTUATION)
components/docs/DocSidebar.tsx (1)
16-16
: Translate comments to EnglishUse English comments for better maintainability.
-// Styl głównej kategorii +// Main category style -// Styl podkategorii +// Subcategory styleAlso applies to: 28-28
content/docs/eternalcombat/installation.md (3)
9-9
: Capitalize and format “JAR” consistently
In the header it reads “jar” in plain text. For clarity and consistency, change to inline code or uppercase, e.g.:- ### Step 1: Download ⬇️ the plugin and place the jar in the `plugins` folder 📂 + ### Step 1: Download ⬇️ the plugin and place the `JAR` in the `plugins` folder 📂
16-16
: Add missing comma after the config path
Insert a comma after the path so the sentence reads more naturally:- In `plugins/EternalCombat/config.yml` you can configure the plugin to your liking. + In `plugins/EternalCombat/config.yml`, you can configure the plugin to your liking.🧰 Tools
🪛 LanguageTool
[uncategorized] ~16-~16: A comma might be missing here.
Context: ...mize the plugin to your needs. With any questions feel free to ask. ## ⚡ Upgrading 📝 **...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
33-33
: Use present tense for consistency
Change “experienced” to “experience” to match earlier notes:- 📝 **Note**: If you experienced problems after updating the plugin, use a configuration backup… + 📝 **Note**: If you experience problems after updating the plugin, use a configuration backup…🧰 Tools
🪛 LanguageTool
[uncategorized] ~33-~33: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
content/docs/eternalcore/installation.md (2)
9-9
: Capitalize and format “JAR” consistently
Change “jar” to inline code or uppercase for clarity:- ### Step 1: Download ⬇️ the plugin and place the jar in the `plugins` folder 📂 + ### Step 1: Download ⬇️ the plugin and place the `JAR` in the `plugins` folder 📂
30-30
: Use present tense for consistency
Adjust “experienced” to “experience” in the upgrade note:- 📝 **Note**: If you experienced problems after updating the plugin, use a configuration backup… + 📝 **Note**: If you experience problems after updating the plugin, use a configuration backup…🧰 Tools
🪛 LanguageTool
[uncategorized] ~30-~30: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
content/docs/eternalcore/using-api.md (7)
7-7
: Add missing article “the”
Make the intro smoother:- As part of open-source community, we support developers… + As part of the open-source community, we support developers…🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...# EternalCore Developer API As part of open-source community, we support developers...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
11-12
: Include “the” before key nouns
Improve clarity by adding “the”:- To use our work in your plugin, You need to install correct artifact for your project. To use latest release check… + To use our work in your plugin, you need to install the correct artifact for your project. To use the latest release, check…🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...e Kotlin, Gradle Groovy and SBT. To use latest release check [maven repository](https:...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
102-104
: Fix usage sentence grammar
Add comma and articles for readability:- To use our API you need to create instance of `EternalCoreAPI` class. You can do it by using `EternalCoreApiProvider.provide()` method. + To use our API, you need to create an instance of the `EternalCoreAPI` class. You can do this by calling the `EternalCoreApiProvider.provide()` method.🧰 Tools
🪛 LanguageTool
[uncategorized] ~103-~103: Possible missing comma found.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...Usage To use our API you need to create instance ofEternalCoreAPI
class. You can do i...(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance ofEternalCoreAPI
class. You can do it by ...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...lCoreAPIclass. You can do it by using
EternalCoreApiProvider.provide()` method...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
121-121
: Clarify example phrasing
Add “of” and “an” for idiomatic English:- Here is an example how to obtain instance of `AfkService`: + Here is an example of how to obtain an instance of `AfkService`:🧰 Tools
🪛 LanguageTool
[uncategorized] ~121-~121: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance ofAfkService
: ``...(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~121-~121: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance ofAfkService
: ```java public class ...(AI_EN_LECTOR_MISSING_DETERMINER_AN)
138-138
: Add comma and lowercase “you”
Improve flow and casing:- After that You can use examples shown below. + After that, you can use the examples shown below.🧰 Tools
🪛 LanguageTool
[typographical] ~138-~138: Consider adding a comma here.
Context: ... down theAfkService
to your classes. After that You can use examples shown below. Chec...(FOR_THAT_COMMA)
[uncategorized] ~138-~138: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is Af...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
159-159
: Clarify CatboyService example phrasing
Add “of” and “an” for consistency:- Here is an example how to obtain instance of `CatboyService`: + Here is an example of how to obtain an instance of `CatboyService`:🧰 Tools
🪛 LanguageTool
[uncategorized] ~159-~159: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance ofCatboyService
: ...(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~159-~159: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance ofCatboyService
: ```java public cla...(AI_EN_LECTOR_MISSING_DETERMINER_AN)
176-176
: Add comma and simplify wording
Improve readability:- Using the instance of `CatboyService` the User is able to mark players as catboys and give them unique feature provided by `EternalCore`. + Using the instance of `CatboyService`, you can mark players as catboys and give them a unique feature provided by `EternalCore`.🧰 Tools
🪛 LanguageTool
[uncategorized] ~176-~176: A comma might be missing here.
Context: ... } } ``` Using the instance ofCatboyService
the User is able to mark players as cat...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[style] ~176-~176: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...he instance ofCatboyService
the User is able to mark players as catboys and give them u...(BE_ABLE_TO)
[uncategorized] ~176-~176: Possible missing article found.
Context: ...o mark players as catboys and give them unique feature provided byEternalCore
. ```...(AI_HYDRA_LEO_MISSING_A)
[uncategorized] ~176-~176: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...players as catboys and give them unique feature provided byEternalCore
. ```java if ...(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
content/docs/documentation-editors/markdown-guide.md (1)
39-39
: Remove stray character
There’s an extra “a” after “websites:”:- Link to external websites:a + Link to external websites:content/docs/eternalcombat/using-api.md (3)
7-7
: Add missing article “the”
Smooth the opening sentence:- As part of open-source community, we support developers… + As part of the open-source community, we support developers…🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...PI --- # EternalCombat API As part of open-source community, we support developers...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
11-12
: Include “the” before key nouns
Clarify the dependency instructions:- To use our work in your plugin, You need to install correct artifact for your project. To use latest release check… + To use our work in your plugin, you need to install the correct artifact for your project. To use the latest release, check…🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
102-104
: Fix usage sentence grammar
Add comma and articles for readability:- To use our API you need to create instance of `EternalCombatAPI` class. You can do it by using `EternalCombatAPI.getInstance()` method. + To use our API, you need to create an instance of the `EternalCombatAPI` class. You can do this by calling the `EternalCombatAPI.getInstance()` method.🧰 Tools
🪛 LanguageTool
[uncategorized] ~103-~103: A comma might be missing here.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...Usage To use our API you need to create instance ofEternalCombatAPI
class. You can do...(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance ofEternalCombatAPI
class. You can do it b...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...ombatAPIclass. You can do it by using
EternalCombatAPI.getInstance()` method. ...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (24)
app/docs/[...slug]/page.tsx
(1 hunks)app/docs/layout.tsx
(1 hunks)app/prism-languages.ts
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/docs/DynamicCommandsTable.tsx
(1 hunks)components/docs/DynamicFeaturesTable.tsx
(1 hunks)components/docs/sidebar-structure.ts
(1 hunks)components/header/Navbar.tsx
(1 hunks)content/docs/contribute/guide.md
(1 hunks)content/docs/documentation-editors/markdown-guide.md
(1 hunks)content/docs/eternalcombat/features.md
(1 hunks)content/docs/eternalcombat/installation.md
(1 hunks)content/docs/eternalcombat/introduction.md
(1 hunks)content/docs/eternalcombat/using-api.md
(1 hunks)content/docs/eternalcore/faq.md
(1 hunks)content/docs/eternalcore/features.md
(1 hunks)content/docs/eternalcore/homes.md
(1 hunks)content/docs/eternalcore/installation.md
(1 hunks)content/docs/eternalcore/introduction.md
(1 hunks)content/docs/eternalcore/notifications.md
(1 hunks)content/docs/eternalcore/placeholders.md
(1 hunks)content/docs/eternalcore/using-api.md
(1 hunks)lib/mdx.ts
(1 hunks)package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- content/docs/eternalcombat/introduction.md
- content/docs/eternalcore/placeholders.md
- content/docs/eternalcore/features.md
- content/docs/eternalcore/notifications.md
🚧 Files skipped from review as they are similar to previous changes (6)
- app/prism-languages.ts
- components/header/Navbar.tsx
- app/docs/layout.tsx
- lib/mdx.ts
- package.json
- app/docs/[...slug]/page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
components/docs/DocSidebar.tsx (1)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-46)
🪛 LanguageTool
content/docs/contribute/guide.md
[uncategorized] ~56-~56: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>
(UNLIKELY_OPENING_PUNCTUATION)
content/docs/eternalcore/using-api.md
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...# EternalCore Developer API As part of open-source community, we support developers...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...e Kotlin, Gradle Groovy and SBT. To use latest release check [maven repository](https:...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: Possible missing comma found.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...
(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...Usage To use our API you need to create instance of EternalCoreAPI
class. You can do i...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance of EternalCoreAPI
class. You can do it by ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...lCoreAPIclass. You can do it by using
EternalCoreApiProvider.provide()` method...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~108-~108: You might be missing the article “an” here.
Context: ...iProvider.provide(); ``` After creating instance of api, the User gets access to various...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~121-~121: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance of AfkService
: ``...
(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~121-~121: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance of AfkService
: ```java public class ...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[typographical] ~138-~138: Consider adding a comma here.
Context: ... down the AfkService
to your classes. After that You can use examples shown below. Chec...
(FOR_THAT_COMMA)
[uncategorized] ~138-~138: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is Af...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~159-~159: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance of CatboyService
: ...
(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~159-~159: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance of CatboyService
: ```java public cla...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~176-~176: A comma might be missing here.
Context: ... } } ``` Using the instance of CatboyService
the User is able to mark players as cat...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[style] ~176-~176: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...he instance of CatboyService
the User is able to mark players as catboys and give them u...
(BE_ABLE_TO)
[uncategorized] ~176-~176: Possible missing article found.
Context: ...o mark players as catboys and give them unique feature provided by EternalCore
. ```...
(AI_HYDRA_LEO_MISSING_A)
[uncategorized] ~176-~176: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...players as catboys and give them unique feature provided by EternalCore
. ```java if ...
(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
content/docs/eternalcombat/using-api.md
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...PI --- # EternalCombat API As part of open-source community, we support developers...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: A comma might be missing here.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...Usage To use our API you need to create instance of EternalCombatAPI
class. You can do...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance of EternalCombatAPI
class. You can do it b...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...ombatAPIclass. You can do it by using
EternalCombatAPI.getInstance()` method. ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~108-~108: You might be missing the article “an” here.
Context: ...tProvider.provide(); ``` After creating instance of api, the User gets access to various...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~124-~124: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance of FightManager
: ...
(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~124-~124: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance of FightManager
: ```java public clas...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[typographical] ~140-~140: Consider adding a comma here.
Context: ...own the FightManager
to your classes. After that You can use examples shown below. Chec...
(FOR_THAT_COMMA)
[uncategorized] ~140-~140: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is in...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~142-~142: You might be missing the article “the” here.
Context: ...eck if the player is in combat by using FightManager
class. Example: ```java i...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~164-~164: You might be missing the article “the” here.
Context: ... the player enters the fight or extends duration of the fight. The second type is the `...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~167-~167: Possible missing article found.
Context: ...vent types by using @EventHandler
. In example below we check why the player was untag...
(AI_HYDRA_LEO_MISSING_THE)
[uncategorized] ~167-~167: Possible missing comma found.
Context: ...es by using @EventHandler
. In example below we check why the player was untagged. ...
(AI_HYDRA_LEO_MISSING_COMMA)
content/docs/eternalcombat/features.md
[uncategorized] ~15-~15: You might be missing the article “the” here.
Context: ...our combat experience. You can find all features below. - Combat duration, - Combat mes...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~22-~22: You might be missing the article “a” here.
Context: ... - Disable block placing in areas above certain height, - Add combat-log to other entit...
(AI_EN_LECTOR_MISSING_DETERMINER_A)
content/docs/eternalcombat/installation.md
[uncategorized] ~16-~16: A comma might be missing here.
Context: ...mize the plugin to your needs. With any questions feel free to ask. ## ⚡ Upgrading 📝 **...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~33-~33: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...
(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
content/docs/eternalcore/faq.md
[uncategorized] ~13-~13: You might be missing the article “the” here.
Context: ...## Solution: You can disable command in commands.yml
file. ### Example: ```yam...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[style] ~28-~28: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...oblem: I want to format text in chat. I want to style it, color it, etc. ### Solution:...
(REP_WANT_TO_VB)
[style] ~41-~41: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ... title from flickering? ### Problem: I want to create in game title with timer, but it...
(REP_WANT_TO_VB)
[uncategorized] ~41-~41: Possible missing article found.
Context: ...ckering? ### Problem: I want to create in game title with timer, but it keeps fli...
(AI_HYDRA_LEO_MISSING_AN)
[uncategorized] ~41-~41: You might be missing the article “a” here.
Context: ...em: I want to create in game title with timer, but it keeps flickering on users scree...
(AI_EN_LECTOR_MISSING_DETERMINER_A)
[uncategorized] ~41-~41: It seems likely that a singular genitive (’s) apostrophe is missing.
Context: ... with timer, but it keeps flickering on users screen. ### Solution: You can use `tim...
(AI_HYDRA_LEO_APOSTROPHE_S_XS)
[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...sers screen. ### Solution: You can use times
key in configuration file. ### E...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...## Solution: You can use times
key in configuration file. ### Example: ```yaml teleportT...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
content/docs/eternalcore/homes.md
[grammar] ~5-~5: This phrase is duplicated. You should probably use “EternalCore Homes” only once.
Context: ...-- title: EternalCore - Homes --- # 🏠 EternalCore Homes EternalCore Homes is a feature that allows players to set...
(PHRASE_REPETITION)
[grammar] ~9-~9: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...nfigure the maximum number of homes for a given permission. ```yaml # Homes Section homes: # Ma...
(A_UNCOUNTABLE_NOUN)
content/docs/eternalcore/installation.md
[uncategorized] ~30-~30: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...
(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
content/docs/eternalcore/introduction.md
[typographical] ~7-~7: Make sure that the comma (,) is correct. Do not use a comma before a dependent clause that starts with ‘that’.
Context: ...cludes most basic functions and commands, that everyone needs. It's easy to use and co...
(COMMA_THAT_NOUN)
[uncategorized] ~7-~7: A determiner appears to be missing. Consider inserting it.
Context: ...e. It's also very lightweight and fast. Plugin includes full support for teleportation...
(AI_EN_LECTOR_MISSING_DETERMINER)
🪛 markdownlint-cli2 (0.17.2)
content/docs/documentation-editors/markdown-guide.md
201-201: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🪛 Biome (1.9.4)
components/docs/DocSidebar.tsx
[error] 22-22: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (2)
components/docs/sidebar-structure.ts (1)
1-46
: Good sidebar structure!The documentation structure is well-organized with clear hierarchical sections. This makes navigation intuitive for users.
content/docs/eternalcombat/features.md (1)
11-11
: Note the TODO commentThere's a TODO comment to add a permissions table. Is this intended to be addressed in this PR or a future one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
🧹 Nitpick comments (45)
hooks/useNavigation.ts (1)
5-21
: Simple and effective navigation hook.This hook is well-structured and handles menu state nicely. The memoized callbacks are a good touch to prevent unnecessary re-renders.
Consider adding a brief comment to explain what this hook does for other developers.
+'/** + * Hook to manage navigation menu state + * @returns Object containing menu state and toggle functions + */ export const useNavigation = () => { const [isMenuOpen, setIsMenuOpen] = useState(false);components/docs/ui/AnimatedHeading.tsx (5)
58-60
: Consider translating or making messages configurableThe "Skopiowano!" message appears to be in Polish. Consider translating it to English or making these messages configurable for internationalization.
- <span className="animate-fade-in ml-2 text-xs text-green-500"> - Skopiowano! - </span> + <span className="animate-fade-in ml-2 text-xs text-green-500"> + Copied! + </span>
14-18
: Add fallback for browsers without clipboard APISome older browsers might not support the navigator.clipboard API. Consider adding a fallback method.
if (navigator.clipboard) { navigator.clipboard.writeText( window.location.origin + window.location.pathname + `#${headingId}` ); +} else { + // Fallback for browsers without clipboard API + const textArea = document.createElement("textarea"); + const url = window.location.origin + window.location.pathname + `#${headingId}`; + textArea.value = url; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + try { + document.execCommand("copy"); + } catch (err) { + console.error("Failed to copy URL: ", err); + } + document.body.removeChild(textArea); }
48-48
: Consider translating ARIA label to match UI languageThe aria-label is in Polish. If your interface is primarily in English, consider translating this for consistency.
- aria-label="Kopiuj link do nagłówka" + aria-label="Copy link to heading"
19-19
: Consider adding smooth scrolling for better UXSetting window.location.hash causes abrupt jumps. Consider using smooth scrolling for a better user experience.
- window.location.hash = headingId; + // Update URL without causing an abrupt jump + history.pushState(null, "", `#${headingId}`); + // Optional: Smooth scroll to the element + document.getElementById(headingId)?.scrollIntoView({ behavior: "smooth" });
35-53
: Extract duplicate styling to reduce redundancyThere's duplicate styling between the main span and the anchor tag. Consider extracting these styles to reduce redundancy.
+ const commonStyles = { + textDecoration: "none", + display: "flex", + alignItems: "center", + }; <span style={{ - textDecoration: "none", - display: "inline-flex", - alignItems: "center", + ...commonStyles, + display: "inline-flex", }} > {children} {id ? ( <> <a href={`#${id}`} onClick={handleCopy} className="underline-none ml-2 flex select-none items-center text-base text-gray-400 opacity-0 transition-opacity group-hover:opacity-100" aria-label="Kopiuj link do nagłówka" style={{ - textDecoration: "none", - display: "flex", - alignItems: "center", + ...commonStyles, }} >content/docs/eternalcore/homes.mdx (2)
5-6
: Avoid repetition in heading and first sentenceThe phrase "EternalCore Homes" is repeated in both the heading and first sentence. Consider rewording to avoid repetition.
# 🏠 EternalCore Homes -EternalCore Homes is a feature that allows players to set their own homes and teleport to them. +This feature allows players to set their own homes and teleport to them.🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: This phrase is duplicated. You should probably use “EternalCore Homes” only once.
Context: ...-- title: EternalCore - Homes --- # 🏠 EternalCore Homes EternalCore Homes is a feature that allows players to set...(PHRASE_REPETITION)
8-9
: Improve grammar in sentence about permissionsThe article 'a' is redundant when used with the uncountable noun 'permission'.
## 🔒 Homes limit per permission -It is possible to configure the maximum number of homes for a given permission. +It is possible to configure the maximum number of homes for given permissions.Alternatively:
## 🔒 Homes limit per permission -It is possible to configure the maximum number of homes for a given permission. +It is possible to configure the maximum number of homes for each permission.🧰 Tools
🪛 LanguageTool
[grammar] ~9-~9: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...nfigure the maximum number of homes for a given permission. ```yaml # Homes Section homes: # Ma...(A_UNCOUNTABLE_NOUN)
content/docs/contribute/guide.mdx (4)
56-56
: Consider using a more professional closingThe ":>" emoticon at the end seems informal for documentation. Consider using a more professional closing or removing it.
-You have successfully made a contribution to this project. :> +You have successfully made a contribution to this project!🧰 Tools
🪛 LanguageTool
[uncategorized] ~56-~56: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>(UNLIKELY_OPENING_PUNCTUATION)
11-14
: Fix punctuation consistency in listThe list has inconsistent punctuation. The last item ends with a period, but previous items don't.
- [ChatFormatter](https://github.com/EternalCodeTeam/ChatFormatter) - [EternalCore](https://github.com/EternalCodeTeam/EternalCore) - [GitCheck](https://github.com/EternalCodeTeam/GitCheck) -- [EternalCombat](https://github.com/EternalCodeTeam/EternalCombat). +- [EternalCombat](https://github.com/EternalCodeTeam/EternalCombat)
24-24
: Use a clearer example for the clone commandThe placeholder in quotes might confuse users. Consider using a more explicit example.
-git clone "{URL you just copied}" +git clone "https://github.com/yourusername/repository-name.git"
36-36
: Use a more descriptive branch name exampleThe current placeholder might not clearly indicate what format to use. Consider using a more practical example.
-git checkout -b <your-new-branch-name> +git checkout -b feature/add-new-functionalitycontent/docs/eternalcombat/features.mdx (2)
15-15
: Add "the" before "all features".For better readability, change "You can find all features below" to "You can find all the features below."
🧰 Tools
🪛 LanguageTool
[uncategorized] ~15-~15: You might be missing the article “the” here.
Context: ...our combat experience. You can find all features below. - Combat duration, - Combat mes...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
17-23
: Fix list formatting and grammar.The list of features ends with a comma and is missing an article in one item:
- - Disable block placing in areas above certain height, + - Disable block placing in areas above a certain heightAlso, consider ending the list with a period instead of a comma on the last item.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~22-~22: You might be missing the article “a” here.
Context: ... - Disable block placing in areas above certain height, - Add combat-log to other entit...(AI_EN_LECTOR_MISSING_DETERMINER_A)
components/docs/layout/DocSidebar.tsx (3)
16-17
: Translate Polish comments to English.The comment "Styl głównej kategorii" should be in English for consistency.
- // Styl głównej kategorii + // Main category style
22-22
: Use optional chaining for better code style.Replace the conditional check with optional chaining for cleaner code.
- {item.children && item.children.map((child) => renderDocItem(child, level + 1))} + {item.children?.map((child) => renderDocItem(child, level + 1))}🧰 Tools
🪛 Biome (1.9.4)
[error] 22-22: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
28-28
: Translate Polish comments to English.The comment "Styl podkategorii" should be in English for consistency.
- // Styl podkategorii + // Subcategory stylecomponents/ErrorBoundary.tsx (1)
25-27
: Consider enhanced error logging.For production environments, consider sending errors to a monitoring service instead of just logging to console.
components/docs/tables/DynamicFeaturesTable.tsx (3)
17-17
: Consider making the URL configurableThe GitHub URL is hardcoded. It would be better to move this to an environment variable or config file for easier maintenance.
42-44
: Avoid using index as key when possibleUsing array index as the key prop can cause issues if items are reordered or filtered. Try using a unique identifier from the data instead.
- <tr key={i}> + <tr key={f.name}>
47-49
: Add error handling for missing description dataThe code checks if description is an array but doesn't handle the case where it might be undefined or null.
- {Array.isArray(f.description) - ? f.description.map((d, j) => <div key={j}>{d}</div>) - : f.description} + {Array.isArray(f.description) + ? f.description.map((d, j) => <div key={j}>{d}</div>) + : f.description || "-"}content/docs/eternalcombat/installation.mdx (3)
16-16
: Add a comma for better readabilityAdd a comma after "With any questions" to improve the sentence flow.
-In `plugins/EternalCombat/config.yml` you can configure the plugin to your liking. There are many options available, so you can customize the plugin to your needs. With any questions feel free to ask. +In `plugins/EternalCombat/config.yml` you can configure the plugin to your liking. There are many options available, so you can customize the plugin to your needs. With any questions, feel free to ask.🧰 Tools
🪛 LanguageTool
[uncategorized] ~16-~16: A comma might be missing here.
Context: ...mize the plugin to your needs. With any questions feel free to ask. ## ⚡ Upgrading 📝 **...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
21-22
: Add a direct download linkConsider adding a direct link or more specific instructions on where to download the plugin.
-Download the latest version of EternalCombat from the project website. +Download the latest version of EternalCombat from [our GitHub releases page](https://github.com/EternalCodeTeam/EternalCombat/releases) or the project website.
33-33
: Fix verb tense for consistencyChange "experienced" to "experience" to match the conditional context.
-📝 **Note**: If you experienced problems after updating the plugin, use a configuration backup to restore the previous settings and avoid data loss. +📝 **Note**: If you experience problems after updating the plugin, use a configuration backup to restore the previous settings and avoid data loss.🧰 Tools
🪛 LanguageTool
[uncategorized] ~33-~33: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
components/docs/layout/DocSearch.tsx (3)
48-54
: Add accessibility attributes to the search inputThe search input should have accessibility attributes for better screen reader support.
<input type="text" value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search documentation..." + aria-label="Search documentation" + role="searchbox" className="w-full rounded-lg border border-gray-300 bg-white px-4 py-2 pl-10 text-sm shadow-sm transition-shadow focus:border-gray-400 focus:shadow-lg focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:focus:border-gray-500" />
58-79
: Add keyboard navigation supportThe search results should be navigable using keyboard (up/down arrows). This improves accessibility.
#!/bin/bash # Check for examples of keyboard navigation in search components rg -A 5 "keydown" --glob="*.tsx" | grep -i "arrow\|key" | head -n 10
33-36
: Display error message to the userThe error is logged to console but not shown to the user. Consider adding a user-friendly error message.
} catch (error) { console.error("Search failed:", error); setResults([]); + // Consider adding a user-facing error notification here } finally {
components/docs/ui/DocCopyEnhancer.tsx (1)
8-8
: Use English comments for better collaboration.The comment "już jest" should be in English for consistency and clarity.
- if (preEl.querySelector(".copy-btn")) return; // już jest + if (preEl.querySelector(".copy-btn")) return; // already existscontent/docs/eternalcore/notifications.mdx (2)
7-7
: Fix grammatical issue.The grammatical structure of this sentence needs adjustment.
-This plugin allows sending messages to different parts of Minecraft, including the chat, action bar, title, and subtitle. All messages can be formatted using [🔍 MiniMessages](https://docs.adventure.kyori.net/minimessage/format.html) or standard color codes. You can also use an online [🌐 message viewer](https://webui.adventure.kyori.net/) +This plugin allows sending messages to different parts of Minecraft, including the chat, action bar, title, and subtitle. All message types can be formatted using [🔍 MiniMessages](https://docs.adventure.kyori.net/minimessage/format.html) or standard color codes. You can also use an online [🌐 message viewer](https://webui.adventure.kyori.net/)🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...luding the chat, action bar, title, and subtitle. All messages can be formatted using [?...(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
149-149
: Fix verb form in heading.The verb "send" should be "sending" for grammatical correctness.
-#### Clear title/subtitle before send new +#### Clear title/subtitle before sending new🧰 Tools
🪛 LanguageTool
[uncategorized] ~149-~149: This verb may not be in the correct form. Consider using a different form for this context.
Context: ....#### Clear title/subtitle before send new
yaml # Clears the title and subt...(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
components/ui/Button.tsx (1)
48-50
: Consider extracting the spinner to a separate component.The loading spinner could be moved to its own component for reusability.
- {isLoading ? ( - <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" /> - ) : null} + {isLoading && <LoadingSpinner className="mr-2 h-4 w-4" />}Then create a separate component:
// components/ui/LoadingSpinner.tsx import { cn } from '@/lib/utils'; interface LoadingSpinnerProps { className?: string; } export const LoadingSpinner = ({ className }: LoadingSpinnerProps) => { return ( <div className={cn('animate-spin rounded-full border-2 border-current border-t-transparent', className)} /> ); };components/docs/ui/CodeTabs.tsx (1)
27-70
: Add validation for child components.The component doesn't check if children are actually CodeTab components.
export const CodeTabs: React.FC<CodeTabsProps> = ({ children }) => { + // Validate children + React.Children.forEach(children, (child) => { + if (!React.isValidElement(child) || child.type !== CodeTab) { + console.warn('CodeTabs children should be CodeTab components'); + } + }); + return ( <div className="my-6 overflow-hidden rounded-xl bg-gray-800 shadow">components/docs/tables/DynamicCommandsTable.tsx (1)
17-26
: Consider making the URL configurable.Hardcoding the GitHub URL could cause issues if the repository structure changes.
- fetch("https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_commands_docs.json") + const commandsUrl = process.env.NEXT_PUBLIC_COMMANDS_URL || "https://raw.githubusercontent.com/EternalCodeTeam/EternalCore/refs/heads/master/raw_commands_docs.json"; + fetch(commandsUrl)content/docs/eternalcore/using-api.mdx (4)
7-7
: Fix grammar in introduction.Add "the" before "open-source community" for correct grammar.
-As part of open-source community, we support developers who want to create their own plugins using our API. We provide a simple and easy to use API that allows you to create your own plugins using our API. +As part of the open-source community, we support developers who want to create their own plugins using our API. We provide a simple and easy to use API that allows you to create your own plugins using our API.🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: Possible missing article found.
Context: ...# EternalCore Developer API As part of open-source community, we support developers...(AI_HYDRA_LEO_MISSING_THE)
103-103
: Add missing comma.Need a comma after "To use our API".
-To use our API you need to create instance of `EternalCoreAPI` class. You can do it by using `EternalCoreApiProvider.provide()` method. +To use our API, you need to create instance of `EternalCoreAPI` class. You can do it by using `EternalCoreApiProvider.provide()` method.🧰 Tools
🪛 LanguageTool
[uncategorized] ~103-~103: Possible missing comma found.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...(AI_HYDRA_LEO_MISSING_COMMA)
108-108
: Fix article usage.Add "an" before "instance of api".
-After creating instance of api, the User gets access to various classes used in our plugin and methods. +After creating an instance of api, the User gets access to various classes used in our plugin and methods.🧰 Tools
🪛 LanguageTool
[uncategorized] ~108-~108: Possible missing article found.
Context: ...iProvider.provide(); ``` After creating instance of api, the User gets access to various...(AI_HYDRA_LEO_MISSING_AN)
176-176
: Fix grammar in feature description.Add "a" before "unique feature" and consider using "can" instead of "able to".
-Using the instance of `CatboyService` the User is able to mark players as catboys and give them unique feature provided by `EternalCore`. +Using the instance of `CatboyService` the User can mark players as catboys and give them a unique feature provided by `EternalCore`.🧰 Tools
🪛 LanguageTool
[style] ~176-~176: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...he instance ofCatboyService
the User is able to mark players as catboys and give them u...(BE_ABLE_TO)
[uncategorized] ~176-~176: Possible missing article found.
Context: ...o mark players as catboys and give them unique feature provided byEternalCore
. ```...(AI_HYDRA_LEO_MISSING_A)
content/docs/eternalcore/installation.mdx (2)
15-15
: Use en dash for version range.For numerical ranges, it's better to use an en dash.
-- Minecraft server (Spigot/Paper 1.8.8 - 1.20.x) +- Minecraft server (Spigot/Paper 1.8.8 – 1.20.x)🧰 Tools
🪛 LanguageTool
[typographical] ~15-~15: If you want to indicate numerical ranges or time ranges, consider using an en dash.
Context: ...s - Minecraft server (Spigot/Paper 1.8.8 - 1.20.x) - Java 8 or higher - Server rest...(DASH_RULE)
19-21
: Remove word repetition.There's a repetition of "download" that could be reworded.
-### Step 1: Download -1. Download the latest version of EternalCore from our [GitHub releases](https://github.com/EternalCodeTeam/EternalCore/releases) +### Step 1: Get the Plugin +1. Get the latest version of EternalCore from our [GitHub releases](https://github.com/EternalCodeTeam/EternalCore/releases)🧰 Tools
🪛 LanguageTool
[duplication] ~19-~19: Possible typo: you repeated a word.
Context: ...er - Server restart access ### Step 1: Download 1. Download the latest version of EternalCore from ...(ENGLISH_WORD_REPEAT_RULE)
content/docs/eternalcombat/using-api.mdx (6)
7-7
: Add missing article and hyphenate phrase
The phrase “As part of open-source community” should read “As part of the open-source community,” and it’s clearer to hyphenate “easy-to-use.”- As part of open-source community, we support developers who want to create their own plugins using our API. We provide a simple and easy to use API that allows you to create your own plugins using our API. + As part of the open-source community, we support developers who want to create their own plugins using our API. We provide a simple and easy-to-use API that allows you to create your own plugins using our API.🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...PI --- # EternalCombat API As part of open-source community, we support developers...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
11-12
: Add missing articles and punctuation
Insert “the” before “correct artifact” and “latest release,” and add commas for clarity.- To use our work in your plugin, You need to install correct artifact for your project. Our plugin supports Maven, Gradle Kotlin, Gradle Groovy and SBT. - To use latest release check [maven repository](https://repo.eternalcode.pl/#/releases/com/eternalcode/eternalcombat-api). + To use our work in your plugin, you need to install the correct artifact for your project. Our plugin supports Maven, Gradle Kotlin, Gradle Groovy, and SBT. + To use the latest release, check [maven repository](https://repo.eternalcode.pl/#/releases/com/eternalcode/eternalcombat-api).🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...e Kotlin, Gradle Groovy and SBT. To use latest release check [maven repository](https:...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
75-75
: Split sentence and add article
Add “the” before “dependency” and replace the comma with a semicolon to improve readability.- You must also add dependency inside `plugin.yml` or `paper-plugin.yml` file, this is required to load our plugin before your plugin, so they can access our API. + You must also add the dependency inside `plugin.yml` or `paper-plugin.yml` file; this is required to load our plugin before your plugin so they can access our API.
140-140
: Lowercase “you” and add comma
Change “After that You can use examples shown below.” to “After that, you can use the examples shown below.”- Then pass down the `FightManager` to your classes. After that You can use examples shown below. + Then pass down the `FightManager` to your classes. After that, you can use the examples shown below.🧰 Tools
🪛 LanguageTool
[typographical] ~140-~140: Consider adding a comma here.
Context: ...own theFightManager
to your classes. After that You can use examples shown below. Chec...(FOR_THAT_COMMA)
[uncategorized] ~140-~140: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is in...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
161-161
: Hyphenate header “Event-based API”
The header should read “## Event-based API” for consistency and clarity.- ## Event base API + ## Event-based API
167-167
: Add article and comma
Update “In example below we check why the player was untagged.” to “In the example below, we check why the player was untagged.”- You can access both event types by using `@EventHandler`. In example below we check why the player was untagged. + You can access both event types by using `@EventHandler`. In the example below, we check why the player was untagged.🧰 Tools
🪛 LanguageTool
[uncategorized] ~167-~167: You might be missing the article “the” here.
Context: ...vent types by using@EventHandler
. In example below we check why the player was untag...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~167-~167: A comma might be missing here.
Context: ...es by using@EventHandler
. In example below we check why the player was untagged. ...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (47)
app/api/docs/search/route.ts
(1 hunks)app/docs/[...slug]/page.tsx
(1 hunks)app/docs/layout.tsx
(1 hunks)app/docs/page.tsx
(1 hunks)app/globals.css
(2 hunks)app/layout.tsx
(3 hunks)components/ErrorBoundary.tsx
(1 hunks)components/docs/layout/DocSearch.tsx
(1 hunks)components/docs/layout/DocSidebar.tsx
(1 hunks)components/docs/tables/DynamicCommandsTable.tsx
(1 hunks)components/docs/tables/DynamicFeaturesTable.tsx
(1 hunks)components/docs/ui/Alert.tsx
(1 hunks)components/docs/ui/AnimatedHeading.tsx
(1 hunks)components/docs/ui/CodeTabs.tsx
(1 hunks)components/docs/ui/DocCopyEnhancer.tsx
(1 hunks)components/faq/Faq.tsx
(1 hunks)components/features/Features.tsx
(1 hunks)components/header/Navbar.tsx
(2 hunks)components/projects/Projects.tsx
(1 hunks)components/team/Team.tsx
(2 hunks)components/ui/Button.tsx
(1 hunks)components/ui/LoadingSpinner.tsx
(1 hunks)config/navigation.ts
(1 hunks)content/docs/contribute/guide.mdx
(1 hunks)content/docs/documentation-editors/markdown-guide.mdx
(1 hunks)content/docs/eternalcombat/features.mdx
(1 hunks)content/docs/eternalcombat/installation.mdx
(1 hunks)content/docs/eternalcombat/introduction.mdx
(1 hunks)content/docs/eternalcombat/using-api.mdx
(1 hunks)content/docs/eternalcore/faq.mdx
(1 hunks)content/docs/eternalcore/features.mdx
(1 hunks)content/docs/eternalcore/homes.mdx
(1 hunks)content/docs/eternalcore/installation.mdx
(1 hunks)content/docs/eternalcore/introduction.mdx
(1 hunks)content/docs/eternalcore/notifications.mdx
(1 hunks)content/docs/eternalcore/placeholders.mdx
(1 hunks)content/docs/eternalcore/using-api.mdx
(1 hunks)hooks/useNavigation.ts
(1 hunks)lib/docs/sidebar-structure.ts
(1 hunks)lib/mdx.ts
(1 hunks)lib/prism/prism-languages.ts
(1 hunks)lib/prism/prism-tomorrow.css
(1 hunks)lib/utils.ts
(1 hunks)mdx.d.ts
(1 hunks)next.config.mjs
(2 hunks)package.json
(1 hunks)types/navigation.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (16)
- components/projects/Projects.tsx
- components/faq/Faq.tsx
- components/features/Features.tsx
- content/docs/eternalcombat/introduction.mdx
- content/docs/eternalcore/placeholders.mdx
- types/navigation.ts
- lib/utils.ts
- config/navigation.ts
- lib/docs/sidebar-structure.ts
- lib/prism/prism-tomorrow.css
- content/docs/eternalcore/features.mdx
- content/docs/documentation-editors/markdown-guide.mdx
- lib/prism/prism-languages.ts
- components/docs/ui/Alert.tsx
- content/docs/eternalcore/faq.mdx
- mdx.d.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- components/team/Team.tsx
- components/header/Navbar.tsx
- app/docs/page.tsx
- app/api/docs/search/route.ts
- app/docs/layout.tsx
- app/globals.css
- package.json
- app/docs/[...slug]/page.tsx
- lib/mdx.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
components/docs/layout/DocSidebar.tsx (1)
lib/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-46)
app/layout.tsx (1)
components/ErrorBoundary.tsx (1)
ErrorBoundary
(15-51)
components/ui/Button.tsx (1)
lib/utils.ts (1)
cn
(4-6)
🪛 Biome (1.9.4)
components/docs/layout/DocSidebar.tsx
[error] 22-22: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 LanguageTool
content/docs/eternalcore/using-api.mdx
[uncategorized] ~7-~7: Possible missing article found.
Context: ...# EternalCore Developer API As part of open-source community, we support developers...
(AI_HYDRA_LEO_MISSING_THE)
[uncategorized] ~103-~103: Possible missing comma found.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...
(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~108-~108: Possible missing article found.
Context: ...iProvider.provide(); ``` After creating instance of api, the User gets access to various...
(AI_HYDRA_LEO_MISSING_AN)
[typographical] ~138-~138: Consider adding a comma here.
Context: ... down the AfkService
to your classes. After that You can use examples shown below. Chec...
(FOR_THAT_COMMA)
[style] ~176-~176: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...he instance of CatboyService
the User is able to mark players as catboys and give them u...
(BE_ABLE_TO)
[uncategorized] ~176-~176: Possible missing article found.
Context: ...o mark players as catboys and give them unique feature provided by EternalCore
. ```...
(AI_HYDRA_LEO_MISSING_A)
content/docs/contribute/guide.mdx
[uncategorized] ~56-~56: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>
(UNLIKELY_OPENING_PUNCTUATION)
content/docs/eternalcombat/using-api.mdx
[uncategorized] ~7-~7: You might be missing the article “the” here.
Context: ...PI --- # EternalCombat API As part of open-source community, we support developers...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~12-~12: You might be missing the article “the” here.
Context: ...e Kotlin, Gradle Groovy and SBT. To use latest release check [maven repository](https:...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: A comma might be missing here.
Context: ...ill not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...Usage To use our API you need to create instance of EternalCombatAPI
class. You can do...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance of EternalCombatAPI
class. You can do it b...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...ombatAPIclass. You can do it by using
EternalCombatAPI.getInstance()` method. ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~108-~108: You might be missing the article “an” here.
Context: ...tProvider.provide(); ``` After creating instance of api, the User gets access to various...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~124-~124: Possible missing preposition found.
Context: ...their own use cases. Here is an example how to obtain instance of FightManager
: ...
(AI_EN_LECTOR_MISSING_PREPOSITION)
[uncategorized] ~124-~124: You might be missing the article “an” here.
Context: ...cases. Here is an example how to obtain instance of FightManager
: ```java public clas...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[typographical] ~140-~140: Consider adding a comma here.
Context: ...own the FightManager
to your classes. After that You can use examples shown below. Chec...
(FOR_THAT_COMMA)
[uncategorized] ~140-~140: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is in...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~164-~164: You might be missing the article “the” here.
Context: ... the player enters the fight or extends duration of the fight. The second type is the `...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~167-~167: You might be missing the article “the” here.
Context: ...vent types by using @EventHandler
. In example below we check why the player was untag...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~167-~167: A comma might be missing here.
Context: ...es by using @EventHandler
. In example below we check why the player was untagged. ...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
content/docs/eternalcombat/features.mdx
[uncategorized] ~15-~15: You might be missing the article “the” here.
Context: ...our combat experience. You can find all features below. - Combat duration, - Combat mes...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~22-~22: You might be missing the article “a” here.
Context: ... - Disable block placing in areas above certain height, - Add combat-log to other entit...
(AI_EN_LECTOR_MISSING_DETERMINER_A)
content/docs/eternalcombat/installation.mdx
[uncategorized] ~16-~16: A comma might be missing here.
Context: ...mize the plugin to your needs. With any questions feel free to ask. ## ⚡ Upgrading 📝 **...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~33-~33: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...
(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
content/docs/eternalcore/homes.mdx
[grammar] ~5-~5: This phrase is duplicated. You should probably use “EternalCore Homes” only once.
Context: ...-- title: EternalCore - Homes --- # 🏠 EternalCore Homes EternalCore Homes is a feature that allows players to set...
(PHRASE_REPETITION)
[grammar] ~9-~9: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...nfigure the maximum number of homes for a given permission. ```yaml # Homes Section homes: # Ma...
(A_UNCOUNTABLE_NOUN)
content/docs/eternalcore/installation.mdx
[typographical] ~15-~15: If you want to indicate numerical ranges or time ranges, consider using an en dash.
Context: ...s - Minecraft server (Spigot/Paper 1.8.8 - 1.20.x) - Java 8 or higher - Server rest...
(DASH_RULE)
[duplication] ~19-~19: Possible typo: you repeated a word.
Context: ...er - Server restart access ### Step 1: Download 1. Download the latest version of EternalCore from ...
(ENGLISH_WORD_REPEAT_RULE)
[style] ~80-~80: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 1732 characters long)
Context: ...rnalCore plugin on your Minecraft server! 😊
(EN_EXCESSIVE_EXCLAMATION)
content/docs/eternalcore/introduction.mdx
[duplication] ~25-~25: Possible typo: you repeated a word.
Context: ...m** - Player teleportation - Random teleportation - Teleportation requests - Warp System - Create ...
(ENGLISH_WORD_REPEAT_RULE)
content/docs/eternalcore/notifications.mdx
[uncategorized] ~7-~7: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...luding the chat, action bar, title, and subtitle. All messages can be formatted using [?...
(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
[uncategorized] ~149-~149: This verb may not be in the correct form. Consider using a different form for this context.
Context: .... #### Clear title/subtitle before send new
yaml # Clears the title and subt...
(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
🔇 Additional comments (29)
hooks/useNavigation.ts (2)
1-4
: Good use of 'use client' directive.The directive correctly marks this component for client-side rendering, and your imports are clean and focused.
5-5
: Watch out for potential naming conflicts.Just be aware that 'useNavigation' is a common name that might also be used in navigation libraries like React Navigation. Consider a more specific name if you're using other navigation libraries.
components/ui/LoadingSpinner.tsx (1)
1-22
: Well-implemented accessible componentThis is a nicely implemented loading spinner with good accessibility attributes and size flexibility. Great job!
Consider these minor enhancements:
interface LoadingSpinnerProps { size?: 'sm' | 'md' | 'lg'; className?: string; + color?: string; + testId?: string; } -export const LoadingSpinner = ({ size = 'md', className = '' }: LoadingSpinnerProps) => { +export const LoadingSpinner = ({ + size = 'md', + className = '', + color = 'current', + testId = 'loading-spinner' +}: LoadingSpinnerProps) => { const sizes = { sm: 'h-4 w-4', md: 'h-6 w-6', lg: 'h-8 w-8', }; return ( <div className={`flex items-center justify-center ${className}`}> <div - className={`${sizes[size]} animate-spin rounded-full border-2 border-current border-t-transparent`} + className={`${sizes[size]} animate-spin rounded-full border-2 border-${color} border-t-transparent`} role="status" aria-label="Loading" + data-testid={testId} /> </div> ); };content/docs/eternalcore/introduction.mdx (2)
23-26
: The teleportation feature section looks good.The teleportation system features are well-organized and clearly explained.
🧰 Tools
🪛 LanguageTool
[duplication] ~25-~25: Possible typo: you repeated a word.
Context: ...m** - Player teleportation - Random teleportation - Teleportation requests - Warp System - Create ...(ENGLISH_WORD_REPEAT_RULE)
43-51
: Well-structured documentation links.The documentation sections with direct links to other pages are clear and helpful for navigation.
components/ErrorBoundary.tsx (2)
15-23
: Good implementation of error boundary.The error boundary component is well structured with proper state management and error handling.
29-49
: Clean fallback UI implementation.The fallback UI is well-designed with proper dark mode support and a "Try again" button for recovery.
components/docs/tables/DynamicFeaturesTable.tsx (1)
1-57
: The component works well and handles loading/error states nicelyThe table component is well structured with proper conditional rendering for loading, error, and empty states. The responsive design with overflow handling is a good practice.
app/layout.tsx (4)
11-12
: Good addition of Prism languages and ErrorBoundaryAdding syntax highlighting and error handling improves the user experience, especially for a documentation site.
20-39
: Great enhancement of metadataThe expanded metadata with OpenGraph and Twitter properties will improve SEO and social sharing. The template structure is also a nice touch.
53-60
: Good use of ErrorBoundaryWrapping the main content in an ErrorBoundary is a good practice to prevent the entire app from crashing when errors occur.
62-63
:❓ Verification inconclusive
Analytics components placement issue
Placing the Analytics and SpeedInsights components outside the body tag might cause issues. They should typically be inside the body.
🏁 Script executed:
#!/bin/bash # Check if the Next.js documentation recommends a specific placement for analytics components rg -A 2 -B 2 "Analytics.*body|body.*Analytics"Length of output: 48
We couldn’t find any docs linking Analytics placement with the
<body>
tag. Could you double-check in Next.js’ docs or your team’s standards if these components must live inside<body>
? Otherwise this looks fine here.content/docs/eternalcombat/installation.mdx (1)
1-44
: Well-structured installation guideThe documentation is clear, well-organized, and includes helpful emojis. The step-by-step instructions and warnings about potential issues are particularly useful.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~16-~16: A comma might be missing here.
Context: ...mize the plugin to your needs. With any questions feel free to ask. ## ⚡ Upgrading 📝 **...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~33-~33: This verb may not be in the correct tense. Consider changing the tense to fit the context better.
Context: ... after the update. 📝 Note: If you experienced problems after updating the plugin, use...(AI_EN_LECTOR_REPLACEMENT_VERB_TENSE)
components/docs/layout/DocSearch.tsx (1)
1-89
: Well-implemented search componentThe search component is well-structured with debounced input, loading indicators, and clear result display. The code is clean and follows good practices.
content/docs/eternalcore/notifications.mdx (1)
1-154
: Well-structured documentation with comprehensive examples.The documentation provides clear and thorough examples for all notification types, with progressive complexity.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~7-~7: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...luding the chat, action bar, title, and subtitle. All messages can be formatted using [?...(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
[uncategorized] ~149-~149: This verb may not be in the correct form. Consider using a different form for this context.
Context: ....#### Clear title/subtitle before send new
yaml # Clears the title and subt...(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
components/ui/Button.tsx (1)
1-57
: Well-structured button component with good variants.The Button component is well-designed with clear organization of styles, variants, and sizes. It properly handles different states and has good accessibility features.
components/docs/ui/CodeTabs.tsx (1)
1-80
: Good implementation of tabbed code interface.The component provides a clean and accessible way to show code examples in multiple languages. The tabs are well-styled and the code handles child components properly.
next.config.mjs (6)
2-7
: Correct imports for MDX support.All necessary packages for MDX support are properly imported.
13-25
: Good MDX configuration.The MDX setup includes appropriate remark and rehype plugins for enhanced markdown support.
57-62
: Proper experimental features configuration.The experimental settings correctly enable MDX support and configure file resolution extensions.
64-64
: Correct page extensions.Adding 'mdx' to page extensions is necessary for Next.js to recognize MDX files as pages.
65-74
: Good development configuration.The webpack watch options improve development experience with polling for file changes.
77-77
: Proper export configuration.The export correctly combines both bundle analyzer and MDX plugins.
components/docs/tables/DynamicCommandsTable.tsx (3)
1-3
: Correct client-side component setup.The "use client" directive and React imports are properly set up.
5-10
: Well-defined interface.The Command interface clearly defines the structure of command data with appropriate optional properties.
28-30
: Good loading and error states.The component correctly handles loading and error states for a better user experience.
content/docs/eternalcore/installation.mdx (3)
8-10
: Good use of Alert component.The info alert provides helpful context for users.
58-60
: Important warning about reloading.This warning about not using
/reload
is crucial information for server admins.
67-72
: Good support resources.The support section provides clear paths for getting help.
4f4ca27
to
3438429
Compare
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
…r with SVG folder icon, sticky search, and sticky sidebar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (7)
components/docs/DocSidebar.tsx (2)
32-32
: Good use of optional chainingThe optional chaining syntax is correctly implemented here, making the code safer. This addresses a previous review comment.
22-22
: Good fix for Tailwind class namingUsing conditional statements instead of string interpolation for Tailwind classes ensures proper compilation. This addresses a previous review comment.
app/globals.css (3)
53-56
: Table header colors need better contrastThe light background (#f8fafc) with white text will be hard to read. Choose a darker header background or darker text color.
73-75
: Zebra striping has no effectBoth regular and "even" rows have the same background color (#f8fafc), so no stripes will appear. Use different colors for alternating rows.
88-90
: Dark mode striping is also no-opSame issue in dark mode - all rows have the same background color. Please use two different shades.
components/docs/CodeTabs.tsx (1)
27-78
: 🛠️ Refactor suggestionAdd validation for child label props
Your component assumes all children have a label prop. This could cause errors if a child is missing the label.
export const CodeTabs: React.FC<CodeTabsProps> = ({ children }) => { + // Validate that children have label props + React.Children.forEach(children, (child) => { + if (React.isValidElement(child) && !child.props.label) { + console.warn('CodeTab component missing required "label" prop'); + } + }); return ( <div className="my-8 overflow-hidden rounded-2xl bg-gradient-to-br from-gray-800/80 via-gray-900/80 to-gray-800/60 ring-1 ring-white/10 backdrop-blur-md">content/docs/documentation-editors/markdown-guide.md (1)
220-226
: 🛠️ Refactor suggestionFix nested code-fence error in Basic Code Block
The code fences are misnested. It should be a single JavaScript block.
-```markdown -```javascript +```javascript function greet(name) { return `Hello, ${name}!`; } -``` -``` +```🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
226-226: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
🧹 Nitpick comments (12)
components/docs/Alert.tsx (3)
5-5
: Consider adding a default alert typeThe
type
prop is required, but it might be helpful to provide a default value (like "info") to make the component more flexible.
95-95
: Consider a more flexible text size classThe
prose-sm
class might make the alert text too small for some content. Consider usingprose
instead for better readability.- <div className={`prose-sm ${styles.text}`}>{children}</div> + <div className={`prose ${styles.text}`}>{children}</div>
83-86
: Add more semantic HTML for better accessibilityConsider using a more semantic HTML element like
aside
instead of a plaindiv
for the alert container, which would better represent its purpose as supplementary content.- <div + <aside className={`my-6 rounded-lg p-4 shadow-sm backdrop-blur-sm ${styles.container}`} >components/icons/arrow-down.tsx (1)
7-14
: Add accessibility attributes to the SVGThe SVG is missing accessibility attributes. Add
aria-hidden="true"
since this is likely a decorative icon used with text.<svg className={className} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" + aria-hidden="true" >
components/docs/DocSearch.tsx (1)
62-83
: Add "No results" message when search returns emptyWhen a search returns no results but the query is valid, it would be helpful to show a message indicating no results were found.
{results.length > 0 && ( <div className="absolute z-10 mt-2 w-full rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800"> {results.map((result) => ( <button key={result.path} onClick={() => { router.push(result.path); setQuery(""); setResults([]); }} className="w-full px-4 py-2 text-left hover:bg-gray-100 focus:outline-none dark:hover:bg-gray-700" > <div className="font-medium text-gray-900 dark:text-white"> {result.title} </div> <div className="text-sm text-gray-500 dark:text-gray-400"> {result.excerpt} </div> </button> ))} </div> )} + {query.length >= 2 && results.length === 0 && !isLoading && ( + <div className="absolute z-10 mt-2 w-full rounded-lg border border-gray-200 bg-white p-4 text-center shadow-lg dark:border-gray-700 dark:bg-gray-800"> + <p className="text-sm text-gray-500 dark:text-gray-400">No results found</p> + </div> + )}components/docs/DocSidebar.tsx (2)
38-51
: Add title attribute to links for longer namesFor links with potentially long titles that might get truncated, adding a title attribute would improve the user experience by showing the full name on hover.
<Link key={item.path} href={item.path} + title={item.title} className={`block rounded-lg transition-colors font-medium text-sm pl-4 py-1 ${ isActive ? "bg-gray-100 text-gray-900 dark:bg-gray-800 dark:text-white" : "text-gray-700 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800" }`} aria-current={isActive ? "page" : undefined} > {item.title} </Link>
16-52
: Consider extracting renderDocItem to a separate componentThe
renderDocItem
function is quite complex and could be extracted into a separate component for better maintainability and testing.components/docs/CodeTabs.tsx (2)
11-25
: Add type safety to icon selectionThe current icon selection uses a type cast with
as any
, which bypasses TypeScript's type checking.- const Icon = (SIIcons as any)[iconName]; + // Check if the icon exists in SIIcons + const Icon = Object.prototype.hasOwnProperty.call(SIIcons, iconName) + ? (SIIcons as Record<string, React.ComponentType<{ className: string, title: string, size: number }>>)[iconName] + : undefined;
32-58
: Extract tab rendering to a separate functionThe tab rendering logic is quite complex. Consider extracting it to a separate function for better readability.
export const CodeTabs: React.FC<CodeTabsProps> = ({ children }) => { + const renderTab = (child: React.ReactNode, idx: number) => { + if (React.isValidElement(child)) { + const label = child.props.label; + return ( + <Tab key={label + idx} as={React.Fragment}> + {({ selected }: { selected: boolean }) => ( + <button + className={`relative rounded-xl px-4 py-2 text-sm font-semibold transition-colors duration-150 focus:outline-none + ${ + selected + ? "bg-gray-700/60 text-white shadow-md" + : "text-gray-300 hover:text-white hover:bg-gray-700/60" + } + `} + type="button" + > + <span className="flex items-center gap-1"> + {getLanguageIcon(label)} + {label} + </span> + </button> + )} + </Tab> + ); + } + return null; + }; return ( <div className="my-8 overflow-hidden rounded-2xl bg-gradient-to-br from-gray-800/80 via-gray-900/80 to-gray-800/60 ring-1 ring-white/10 backdrop-blur-md"> <TabGroup> <TabList className="flex space-x-2 px-4 pt-4 pb-0"> - {React.Children.map(children, (child, idx) => { - if (React.isValidElement(child)) { - const label = child.props.label; - return ( - <Tab key={label + idx} as={React.Fragment}> - {({ selected }: { selected: boolean }) => ( - <button - className={`relative rounded-xl px-4 py-2 text-sm font-semibold transition-colors duration-150 focus:outline-none - ${ - selected - ? "bg-gray-700/60 text-white shadow-md" - : "text-gray-300 hover:text-white hover:bg-gray-700/60" - } - `} - type="button" - > - <span className="flex items-center gap-1"> - {getLanguageIcon(label)} - {label} - </span> - </button> - )} - </Tab> - ); - } - return null; - })} + {React.Children.map(children, renderTab)}content/docs/documentation-editors/markdown-guide.md (1)
39-39
: Fix typo in external links sectionThere's a stray "a" at the end of "Link to external websites:a"
-Link to external websites:a +Link to external websites:app/docs/[...slug]/page.tsx (2)
29-50
: Consider deeper nesting in flattenDocsYour function works for the current structure, but might not handle deeper nested documentation levels if they're added later.
function flattenDocs( structure: { title: string; path: string; children?: { title: string; path: string }[]; }[] ): { title: string; path: string }[] { const result: { title: string; path: string }[] = []; for (const item of structure) { if (item.children && item.children.length > 0) { for (const child of item.children) { + // Add recursive handling if child items could have children too result.push({ title: child.title, path: child.path }); } } else { result.push({ title: item.title, path: item.path }); } } return result; }
161-182
: Improve navigation accessibilityThe navigation links could use aria-labels for better accessibility.
{prev ? ( <a href={prev.path} className="rounded-lg border border-gray-200 bg-gray-100 px-4 py-2 no-underline transition-colors hover:bg-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700" + aria-label={`Previous page: ${prev.title}`} > ← {prev.title} </a> ) : ( <div /> )} {next ? ( <a href={next.path} className="rounded-lg bg-blue-600 px-4 py-2 text-white no-underline transition-colors hover:bg-blue-700" + aria-label={`Next page: ${next.title}`} > {next.title} → </a> ) : ( <div /> )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (12)
app/docs/[...slug]/page.tsx
(1 hunks)app/docs/layout.tsx
(1 hunks)app/globals.css
(2 hunks)components/docs/Alert.tsx
(1 hunks)components/docs/CodeTabs.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/header/Navbar.tsx
(2 hunks)components/icons/arrow-down.tsx
(1 hunks)components/icons/hamburger.tsx
(1 hunks)content/docs/documentation-editors/markdown-guide.md
(1 hunks)package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- components/icons/hamburger.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- package.json
- app/docs/layout.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
components/docs/DocSidebar.tsx (1)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-46)
components/header/Navbar.tsx (3)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)components/icons/hamburger.tsx (1)
Hamburger
(5-24)components/icons/new-window.tsx (1)
NewWindow
(3-20)
app/docs/[...slug]/page.tsx (2)
components/docs/sidebar-structure.ts (1)
docsStructure
(7-46)lib/mdx.ts (1)
components
(12-24)
🪛 markdownlint-cli2 (0.17.2)
content/docs/documentation-editors/markdown-guide.md
226-226: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🔇 Additional comments (23)
components/docs/Alert.tsx (1)
1-100
: LGTM! Well-structured alert componentThe alert component is well-implemented with comprehensive styling variations, dark mode support, and good icon integration. It will provide great visual cues in the documentation.
components/icons/arrow-down.tsx (1)
1-24
: LGTM! Clean icon implementationThis SVG icon component follows best practices with the use of currentColor for styling flexibility and proper viewBox setup.
components/docs/DocSearch.tsx (1)
1-92
: LGTM! Well-implemented search componentThe search component has good error handling, debouncing for API calls, and a clean UI with loading indicator. The structure is well-organized and follows React best practices.
components/docs/DocSidebar.tsx (1)
1-71
: LGTM! Well-structured sidebar with good accessibilityThe sidebar component is well-implemented with proper accessibility attributes, optimized rendering with useMemo, and good conditional styling for active items.
components/header/Navbar.tsx (7)
42-44
: Good memoization with useCallbackNice job memoizing the toggle function! This helps prevent unnecessary re-renders.
47-56
: Well implemented keyboard accessibilityGreat work adding the Escape key handler! This is an important accessibility feature that helps users close the menu easily.
58-67
: Good user experience with body scroll lockLocking the body scroll when the menu is open prevents the page from scrolling in the background, which improves user experience. The cleanup on unmount is also properly handled.
70-74
: Excellent accessibility attributesAdding proper ARIA roles and labels makes the navigation more accessible to screen readers.
97-116
: Nice menu toggle animationThe animated transition between hamburger and arrow icons provides good visual feedback.
119-154
: Smooth mobile menu animationsThe use of AnimatePresence and motion.div creates a polished user experience with smooth transitions.
157-173
: Well-structured navigation with proper external link handlingThe navigation links are well-organized with proper handling of external links (new tab, security attributes).
app/globals.css (3)
1-12
: Good code font consistencySetting consistent fonts for code blocks improves readability across the site.
34-41
: Clean heading link stylingRemoving text decoration from heading links improves readability while maintaining clickability.
92-98
: Nice fade-in animationThe fade-in animation with vertical movement creates a smooth entry effect.
content/docs/documentation-editors/markdown-guide.md (3)
6-8
: Good comprehensive documentationThis guide provides an excellent overview of all available markdown features in your documentation system.
153-213
: Well-structured alert examplesThe alert examples are clear and show different types and usage patterns. This will help documentation authors.
263-290
: Great interactive code tabs exampleThe CodeTabs example demonstrates how to show code in multiple languages, which is very useful for API documentation.
app/docs/[...slug]/page.tsx (6)
1-10
: Well-organized imports!All the necessary imports for handling markdown, file operations, and UI components are present and clearly organized.
11-27
: Clean interface definitionsThe interfaces for document metadata, content, and navigation are well-structured and make the code easy to understand.
79-85
: Clean navigation implementationThe navigation logic is simple and effective, handling edge cases properly.
87-112
: Good SEO metadata handlingThe metadata function properly handles SEO attributes including Open Graph and Twitter card data.
114-126
: Nice loading skeleton UIThe loading fallback provides a good user experience with the animation effect.
138-160
: Well-structured document renderingThe document layout with title, description, and content is clean and follows good semantic structure.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
content/docs/documentation-editors/markdown-guide.md (1)
216-222
: Fix nested code fence in Basic Code Block
The fences are misnested. Use a single JavaScript code fence:- ```markdown - ```javascript + ```javascript function greet(name) { return `Hello, ${name}!`; } - ``` - ``` + ```🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
222-222: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
🧹 Nitpick comments (4)
content/docs/documentation-editors/markdown-guide.md (4)
1-4
: Consider adding optional frontmatter fieldsGreat start! You might mention additional recommended fields like
slug
orsidebar_label
to improve navigation control.
10-15
: Use YAML in frontmatter code blockChange the code fence from
txt
toyaml
for correct syntax highlighting:- ```txt + ```yaml
35-35
: Fix typo in external links sectionRemove the stray
a
after "websites:":- Link to external websites:a + Link to external websites:
232-236
: Remove hidden characters before code fencesThe zero-width spaces before the backticks can prevent proper rendering. Update the fences like:
- ```javascript + ```javascript ... - ``` + ```Also applies to: 241-246, 250-253
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/docs/[...slug]/page.tsx
(1 hunks)content/docs/documentation-editors/markdown-guide.md
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- app/docs/[...slug]/page.tsx
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
content/docs/documentation-editors/markdown-guide.md
222-222: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
app/docs/[...slug]/page.tsx (1)
59-62
: Add path validation for securityYour code needs protection from path traversal attacks. Add checks to validate the slug.
🧹 Nitpick comments (3)
app/docs/[...slug]/page.tsx (3)
156-164
: Consider showing last modified dateShowing when a doc was last updated helps users know how fresh the content is. The data is already in
doc.meta.lastModified
.{doc.meta.description && ( <p className="mb-6 text-xl text-gray-600 dark:text-gray-400"> {doc.meta.description} </p> )} + {doc.meta.lastModified && ( + <p className="text-sm text-gray-500 dark:text-gray-400 mb-4"> + Last updated: {new Date(doc.meta.lastModified).toLocaleDateString()} + </p> + )}
165-173
: Add error boundary around MDX renderingWrap the MDX component in an error boundary to handle rendering errors gracefully.
<Suspense fallback={<LoadingFallback />}> + <ErrorBoundary fallback={<div className="p-4 text-red-500 border border-red-200 rounded">Error rendering markdown content</div>}> <MDXRemote source={doc.content} components={components} options={{ mdxOptions, }} /> + </ErrorBoundary> </Suspense>You'll need to add:
import { ErrorBoundary } from 'react-error-boundary';
176-193
: Improve navigation button accessibilityThe blue navigation button may have contrast issues. Consider increasing contrast or adding an aria-label.
{next ? ( <a href={next.path} + aria-label={`Next page: ${next.title}`} className="rounded-lg bg-blue-600 px-4 py-2 text-white no-underline transition-colors hover:bg-blue-700" > {next.title} → </a> ) : ( <div /> )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
app/docs/[...slug]/page.tsx
(1 hunks)app/docs/page.tsx
(1 hunks)components/docs/CodeTabs.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- app/docs/page.tsx
- components/docs/CodeTabs.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/docs/[...slug]/page.tsx (5)
app/docs/page.tsx (2)
dynamic
(5-5)revalidate
(6-6)app/page.tsx (1)
dynamic
(6-6)app/projects/page.tsx (1)
dynamic
(5-5)components/docs/sidebar-structure.ts (1)
docsStructure
(7-46)lib/mdx.ts (1)
components
(12-24)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (20)
content/docs/eternalcore/using-api.md (6)
1-3
: Add document metadata to frontmatter
Including fields likeauthor
,date
, orlastUpdated
in the YAML frontmatter helps readers know who wrote the doc and when it was last revised.
5-5
: Consider adding a Table of Contents
For a long API guide, a TOC at the top (or using a floating sidebar) can help readers quickly jump to sections.
7-7
: Fix grammar and reduce repetition
“As part of the open-source community, we support developers who want to create plugins with our API.”
This avoids “using our API” twice and adds the missing article.
11-11
: Clarify artifact installation sentence
Change to:
“To use the API in your plugin, install the correct artifact for your project.”
Also lowercase “You” to maintain sentence flow.🧰 Tools
🪛 LanguageTool
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
14-14
: Remove trailing colons in headings
Markdown style prefers no punctuation at the end of heading text. Please drop the:
from “### Add repository” and “### Add dependency”.Also applies to: 44-44
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
14-14: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
103-103
: Add missing articles and comma
Change to:
“To use our API, you need to create an instance of theEternalCoreAPI
class.”
This adds the comma and the missing “an”.🧰 Tools
🪛 LanguageTool
[typographical] ~103-~103: It seems that a comma is missing.
Context: ...ll not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...(IN_ORDER_TO_VB_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...sage To use our API you need to create instance ofEternalCoreAPI
class. You can do i...(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance ofEternalCoreAPI
class. You can do it by ...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...lCoreAPIclass. You can do it by using
EternalCoreApiProvider.provide()` method...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
app/notification-generator/form/SoundTab.tsx (2)
16-23
: Consider clarifying placeholder textThe placeholder "Np. ENTITY_PLAYER_LEVELUP" uses "Np." which might not be immediately clear to users. Consider using "e.g." or "Example:" for better clarity.
- placeholder="Np. ENTITY_PLAYER_LEVELUP" + placeholder="e.g. ENTITY_PLAYER_LEVELUP"
52-54
: Consider consistent placeholder formatSimilar to the sound field, consider using "e.g." instead of "Np." in the volume and pitch placeholders for consistency and clarity.
- placeholder="Np. 2.0" + placeholder="e.g. 2.0"- placeholder="Np. 1.0" + placeholder="e.g. 1.0"Also applies to: 60-62
app/notification-generator/components/SoundIndicator.tsx (1)
15-26
: Icon choice might be confusingThe SVG path shows a muted/crossed-out speaker icon, but this component appears when sound is playing. Consider using a regular speaker icon instead to match the actual state.
app/notification-generator/form/TitleTab.tsx (1)
15-29
: Missing error handling for title fieldsThe title and subtitle FormFields don't receive error props, while the timing fields do. Consider adding error handling for consistency if validation exists for these fields.
<FormField label="Title" name="title" value={notification.title} onChange={onChange} placeholder="Enter your title" + error={errors.title} /> <FormField label="Subtitle" name="subtitle" value={notification.subtitle} onChange={onChange} placeholder="Enter your subtitle" + error={errors.subtitle} />app/notification-generator/components/Title.tsx (1)
20-23
: Consider mobile responsivenessThe fixed text sizes (text-3xl, text-xl) might be too large on small screens. Consider using responsive text classes like
text-xl md:text-3xl
for better mobile experience.className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform text-center transition-opacity duration-500" style={{ opacity: titleOpacity }} > {title && ( <div - className="font-minecraft mb-2 text-3xl font-bold text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" + className="font-minecraft mb-2 text-xl md:text-3xl font-bold text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" > {parseMinecraftText(title)} </div> )} {subtitle && ( <div - className="font-minecraft text-xl text-gray-300 drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" + className="font-minecraft text-base md:text-xl text-gray-300 drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" >app/notification-generator/components/ActionBar.tsx (1)
28-42
: Consider extracting text styling to a reusable constant.The text shadow styling is quite complex and might be reused in other Minecraft-themed components. Consider extracting it to a shared constant for better maintainability.
+const MINECRAFT_TEXT_SHADOW = "2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 1px 1px #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000"; <span className="font-minecraft" style={{ color: "#fff", fontSize: "1.5rem", - textShadow: - "2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 1px 1px #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000", + textShadow: MINECRAFT_TEXT_SHADOW,app/notification-generator/components/ChatMessage.tsx (1)
20-37
: Consider extracting shared styling to reduce code duplication.The styling for both single-line and multiline message containers is nearly identical. You could extract the shared classes into a variable.
+ const messageStyle = "font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]"; + const containerStyle = { zIndex: 1, height: "32px", lineHeight: "32px" }; {message.includes("\n") ? ( message.split("\n").map((line, index) => ( <div key={index} - className="font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ zIndex: 1, height: "32px", lineHeight: "32px" }} + className={messageStyle} + style={containerStyle} > {parseMinecraftText(line)} </div> )) ) : ( <div - className="font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ zIndex: 1, height: "32px", lineHeight: "32px" }} + className={messageStyle} + style={containerStyle} > {parseMinecraftText(message)} </div> )}app/notification-generator/MinecraftPreview.tsx (1)
3-3
: Remove unused import.The
useMemo
import is not being used in this component.-import React, { useMemo } from "react"; +import React from "react";app/notification-generator/form/validation.ts (1)
31-58
: Consider making validateForm more generic.The validateForm function manually checks specific fields instead of iterating through all notification fields. This makes it less maintainable.
export const validateForm = ( notification: Record<string, string>, validateFieldFn: (field: FieldType, value: string) => string ): Record<string, string> => { const errors: Record<string, string> = {}; - if (notification.fadeIn) { - const error = validateFieldFn("fadeIn" as FieldType, notification.fadeIn); - if (error) errors.fadeIn = error; - } - - if (notification.stay) { - const error = validateFieldFn("stay" as FieldType, notification.stay); - if (error) errors.stay = error; - } - - if (notification.fadeOut) { - const error = validateFieldFn("fadeOut" as FieldType, notification.fadeOut); - if (error) errors.fadeOut = error; - } - - if (notification.sound) { - const error = validateFieldFn("sound" as FieldType, notification.sound); - if (error) errors.sound = error; - } + Object.entries(notification).forEach(([field, value]) => { + if (value) { + const error = validateFieldFn(field as FieldType, value); + if (error) errors[field] = error; + } + }); return errors; };content/docs/eternalcore/notifications.md (2)
168-168
: Fix grammar in heading.The heading has incorrect verb form.
-#### Clear title/subtitle before send new +#### Clear title/subtitle before sending new🧰 Tools
🪛 LanguageTool
[uncategorized] ~168-~168: This verb may not be in the correct form. Consider using a different form for this context.
Context: ....#### Clear title/subtitle before send new
yaml # Clears the title and sub...(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
81-81
: Remove trailing punctuation from heading.Markdown headings shouldn't end with colons.
-### Examples combining multiple notifications: +### Examples combining multiple notifications🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
81-81: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
app/notification-generator/NotificationForm.tsx (1)
12-12
: Unused import detected.The
validateForm
function is imported but never used in this component.-import { validateField, validateForm } from "./form/validation"; +import { validateField } from "./form/validation";app/parser/minecraftTextParser.tsx (1)
58-67
: Unused variables that serve no purpose.These variables are declared but never used in the parsing logic.
- let processedText = text; - let lastColor = ''; - let lastStyle = '';app/notification-generator/hooks.ts (1)
8-13
: Improve time format flexibilityThe parseTime function only accepts seconds format ("1.5s"). Consider supporting milliseconds and other common time formats for better usability.
const parseTime = useCallback((timeStr: string) => { if (!timeStr) return 0; - const match = timeStr.match(/^(\d+(\.\d+)?)s$/); + const match = timeStr.match(/^(\d+(\.\d+)?)(s|ms)?$/); if (!match) return 0; - return parseFloat(match[1]); + const value = parseFloat(match[1]); + const unit = match[3] || 's'; + return unit === 'ms' ? value / 1000 : value; }, []);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
public/fonts/Minecraftia-Regular.ttf
is excluded by!**/*.ttf
public/mc-bg.png
is excluded by!**/*.png
public/minecraft-bg.svg
is excluded by!**/*.svg
📒 Files selected for processing (62)
app/api/docs/search/route.ts
(1 hunks)app/api/og/route.tsx
(1 hunks)app/docs/[...slug]/page.tsx
(1 hunks)app/docs/page.tsx
(1 hunks)app/layout.tsx
(2 hunks)app/not-found.tsx
(1 hunks)app/notification-generator/MinecraftPreview.tsx
(1 hunks)app/notification-generator/MiniMessageInfoBox.tsx
(1 hunks)app/notification-generator/NotificationCode.tsx
(1 hunks)app/notification-generator/NotificationForm.tsx
(1 hunks)app/notification-generator/SoundInfoBox.tsx
(1 hunks)app/notification-generator/components/ActionBar.tsx
(1 hunks)app/notification-generator/components/BackgroundImage.tsx
(1 hunks)app/notification-generator/components/ChatMessage.tsx
(1 hunks)app/notification-generator/components/SoundIndicator.tsx
(1 hunks)app/notification-generator/components/Title.tsx
(1 hunks)app/notification-generator/form/ActionBarTab.tsx
(1 hunks)app/notification-generator/form/AdvancedTab.tsx
(1 hunks)app/notification-generator/form/ChatTab.tsx
(1 hunks)app/notification-generator/form/FormField.tsx
(1 hunks)app/notification-generator/form/SoundTab.tsx
(1 hunks)app/notification-generator/form/Tab.tsx
(1 hunks)app/notification-generator/form/TitleTab.tsx
(1 hunks)app/notification-generator/form/constants.ts
(1 hunks)app/notification-generator/form/validation.ts
(1 hunks)app/notification-generator/hooks.ts
(1 hunks)app/notification-generator/layout.tsx
(1 hunks)app/notification-generator/minecraft-font.css
(1 hunks)app/notification-generator/page.tsx
(1 hunks)app/notification-generator/types.ts
(1 hunks)app/page.tsx
(1 hunks)app/parser/minecraftTextParser.tsx
(1 hunks)app/prism-languages.ts
(1 hunks)app/providers.tsx
(1 hunks)components/Analytics.tsx
(1 hunks)components/CookieConsentModal.tsx
(1 hunks)components/OgImage.tsx
(1 hunks)components/SectionTitle.tsx
(1 hunks)components/SpeedInsights.tsx
(1 hunks)components/about/About.tsx
(3 hunks)components/docs/DocCopyEnhancer.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/ErrorBoundary.tsx
(1 hunks)components/docs/ui/AlertBox.tsx
(1 hunks)components/faq/Faq.tsx
(4 hunks)components/features/Features.tsx
(3 hunks)components/footer/Footer.tsx
(1 hunks)components/header/Navbar.tsx
(2 hunks)components/header/ToolsDropdown.tsx
(1 hunks)components/header/hero/Hero.tsx
(2 hunks)components/header/hero/button/BackgroundHeroButton.tsx
(1 hunks)components/header/hero/button/TransparentHeroButton.tsx
(1 hunks)content/docs/eternalcombat/using-api.md
(1 hunks)content/docs/eternalcore/notifications.md
(1 hunks)content/docs/eternalcore/using-api.md
(1 hunks)hooks/useCookieConsent.ts
(1 hunks)lib/mdx-config.mjs
(1 hunks)lib/mdx-config.ts
(1 hunks)lib/mdx.tsx
(1 hunks)lib/og-utils.ts
(1 hunks)next.config.mjs
(2 hunks)reset.d.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (10)
- reset.d.ts
- app/notification-generator/minecraft-font.css
- app/notification-generator/layout.tsx
- app/notification-generator/MiniMessageInfoBox.tsx
- app/notification-generator/SoundInfoBox.tsx
- lib/mdx-config.ts
- app/notification-generator/form/constants.ts
- lib/mdx-config.mjs
- app/notification-generator/components/BackgroundImage.tsx
- app/notification-generator/NotificationCode.tsx
🚧 Files skipped from review as they are similar to previous changes (27)
- app/not-found.tsx
- components/about/About.tsx
- components/SectionTitle.tsx
- components/SpeedInsights.tsx
- lib/og-utils.ts
- app/docs/page.tsx
- app/api/og/route.tsx
- components/Analytics.tsx
- app/prism-languages.ts
- components/OgImage.tsx
- app/providers.tsx
- components/features/Features.tsx
- components/header/hero/Hero.tsx
- components/header/hero/button/BackgroundHeroButton.tsx
- hooks/useCookieConsent.ts
- lib/mdx.tsx
- components/docs/ui/AlertBox.tsx
- app/api/docs/search/route.ts
- components/footer/Footer.tsx
- components/docs/DocCopyEnhancer.tsx
- components/CookieConsentModal.tsx
- components/docs/ErrorBoundary.tsx
- app/page.tsx
- content/docs/eternalcombat/using-api.md
- app/docs/[...slug]/page.tsx
- components/docs/DocSearch.tsx
- components/faq/Faq.tsx
🧰 Additional context used
🧬 Code Graph Analysis (15)
app/notification-generator/form/AdvancedTab.tsx (1)
app/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)
app/notification-generator/components/ChatMessage.tsx (1)
app/parser/minecraftTextParser.tsx (1)
parseMinecraftText
(3-175)
app/notification-generator/components/Title.tsx (1)
app/parser/minecraftTextParser.tsx (1)
parseMinecraftText
(3-175)
app/notification-generator/form/Tab.tsx (1)
app/notification-generator/types.ts (1)
TabType
(20-20)
components/header/ToolsDropdown.tsx (1)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)
app/notification-generator/page.tsx (4)
app/notification-generator/types.ts (1)
NotificationConfig
(1-14)app/notification-generator/NotificationForm.tsx (1)
NotificationForm
(19-135)app/notification-generator/NotificationCode.tsx (1)
NotificationCode
(9-91)app/notification-generator/MinecraftPreview.tsx (1)
MinecraftPreview
(13-67)
app/notification-generator/form/TitleTab.tsx (3)
app/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)app/notification-generator/form/FormField.tsx (1)
FormField
(18-97)app/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
app/notification-generator/form/validation.ts (1)
app/notification-generator/types.ts (1)
FieldType
(21-21)
app/notification-generator/MinecraftPreview.tsx (2)
app/notification-generator/types.ts (1)
MinecraftPreviewProps
(16-18)app/notification-generator/hooks.ts (2)
useTitleAnimation
(4-68)useSoundEffect
(70-83)
app/notification-generator/NotificationForm.tsx (8)
app/notification-generator/types.ts (3)
NotificationConfig
(1-14)TabType
(20-20)FieldType
(21-21)app/notification-generator/form/validation.ts (1)
validateField
(3-29)app/notification-generator/form/ChatTab.tsx (1)
ChatTab
(12-25)app/notification-generator/form/ActionBarTab.tsx (1)
ActionBarTab
(12-23)app/notification-generator/form/TitleTab.tsx (1)
TitleTab
(13-61)app/notification-generator/form/SoundTab.tsx (1)
SoundTab
(14-67)app/notification-generator/form/AdvancedTab.tsx (1)
AdvancedTab
(10-30)app/notification-generator/form/Tab.tsx (1)
Tab
(13-36)
app/notification-generator/form/FormField.tsx (1)
app/notification-generator/types.ts (1)
FieldType
(21-21)
components/header/hero/button/TransparentHeroButton.tsx (1)
components/icons/arrow-forward-hero.tsx (1)
ArrowForwardHeroIcon
(3-18)
app/notification-generator/form/ActionBarTab.tsx (3)
app/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)app/notification-generator/form/FormField.tsx (1)
FormField
(18-97)app/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
app/notification-generator/hooks.ts (1)
app/notification-generator/types.ts (1)
NotificationConfig
(1-14)
components/header/Navbar.tsx (4)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)components/icons/hamburger.tsx (1)
Hamburger
(5-24)components/icons/new-window.tsx (1)
NewWindow
(3-20)components/header/ToolsDropdown.tsx (1)
ToolsDropdown
(8-101)
🪛 LanguageTool
content/docs/eternalcore/using-api.md
[uncategorized] ~11-~11: You might be missing the article “the” here.
Context: ...ork in your plugin, You need to install correct artifact for your project. Our plugin s...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[typographical] ~103-~103: It seems that a comma is missing.
Context: ...ll not work!** ## 📝 Usage To use our API you need to create instance of `Eternal...
(IN_ORDER_TO_VB_COMMA)
[uncategorized] ~103-~103: You might be missing the article “an” here.
Context: ...sage To use our API you need to create instance of EternalCoreAPI
class. You can do i...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ... our API you need to create instance of EternalCoreAPI
class. You can do it by ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~103-~103: You might be missing the article “the” here.
Context: ...lCoreAPIclass. You can do it by using
EternalCoreApiProvider.provide()` method...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~109-~109: You might be missing the article “an” here.
Context: ...Provider.provide(); ``` After creating instance of api, the User gets access to various...
(AI_EN_LECTOR_MISSING_DETERMINER_AN)
[typographical] ~139-~139: Consider adding a comma here.
Context: ... down the AfkService
to your classes. After that You can use examples shown below. Chec...
(FOR_THAT_COMMA)
[uncategorized] ~139-~139: You might be missing the article “the” here.
Context: ...to your classes. After that You can use examples shown below. Check if the player is Af...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[style] ~177-~177: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...he instance of CatboyService
the User is able to mark players as catboys and give them u...
(BE_ABLE_TO)
content/docs/eternalcore/notifications.md
[uncategorized] ~168-~168: This verb may not be in the correct form. Consider using a different form for this context.
Context: .... #### Clear title/subtitle before send new
yaml # Clears the title and sub...
(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
🪛 markdownlint-cli2 (0.17.2)
content/docs/eternalcore/using-api.md
14-14: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
44-44: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
content/docs/eternalcore/notifications.md
81-81: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🔇 Additional comments (45)
next.config.mjs (5)
2-8
: MDX integration looks good!The MDX setup correctly imports the configuration and creates the wrapper with proper extension matching. This will enable markdown files to work as pages.
11-11
: Page extensions updated properly.Adding "md" and "mdx" extensions allows markdown files to be treated as Next.js pages, which is exactly what's needed for the documentation system.
40-42
: Good image optimization settings.The explicit formats and detailed size arrays will help optimize image loading across different devices. AVIF and WebP formats provide better compression than traditional formats.
44-59
: Solid performance and security configurations.These settings improve the app in several ways:
- Removes the X-Powered-By header for security
- Enables compression for faster loading
- Optimizes package imports for better bundle sizes
- Configures server actions with proper origin restrictions
62-62
: Export change aligns with MDX integration.Switching from the bundle analyzer wrapper to the MDX wrapper makes sense since MDX support is the main goal here.
components/header/hero/button/TransparentHeroButton.tsx (4)
8-11
: Animation setup looks good!The intersection observer configuration is well-structured with appropriate threshold and triggerOnce settings.
15-25
: Clean animation logic implementationThe useCallback and useEffect pattern properly handles the animation state changes. The dependency array is correct and the animation controls are used appropriately.
34-35
: Good accessibility improvementsThe aria-label provides clear context and the updated styling with hover states enhances user experience across light and dark modes.
37-40
: Nice touch with the animated iconThe ArrowForwardHeroIcon with hover translation creates a polished interactive feel. The aria-hidden attribute is correctly applied since the icon is decorative.
app/notification-generator/form/AdvancedTab.tsx (2)
5-8
: Well-defined component interfaceThe props interface is clear and properly typed, making the component easy to understand and use.
14-26
: Clean checkbox implementationThe form controls are properly linked with id/htmlFor, and the styling supports both light and dark themes. The onChange handler correctly passes the field name and boolean value.
app/notification-generator/form/ActionBarTab.tsx (2)
7-10
: Clear and focused component interfaceThe props interface is well-defined with proper typing, making the component's contract explicit.
14-22
: Good component compositionThe use of FormField for consistency and MiniMessageInfoBox for user guidance creates a helpful and cohesive user experience.
app/notification-generator/form/SoundTab.tsx (2)
26-45
: Well-implemented dropdown with helpful contextThe sound category dropdown is properly implemented with good styling and the help text clearly explains the user impact of the setting.
47-65
: Smart grid layout for related fieldsThe two-column grid for volume and pitch makes good use of space and groups related settings together logically.
app/notification-generator/components/SoundIndicator.tsx (2)
8-9
: Good conditional rendering pattern!The early return when
sound
is falsy orplaySound
is false is clean and efficient.
34-34
: Nice touch with displayName!Setting the displayName helps with debugging and React DevTools.
app/notification-generator/form/ChatTab.tsx (1)
12-25
: Clean and well-structured form tab!The component properly uses FormField for input handling and includes helpful guidance with MiniMessageInfoBox. The placeholder text clearly explains the multiline feature.
app/notification-generator/form/TitleTab.tsx (1)
31-58
: Good grid layout for timing fields!The 3-column grid layout works well for the related timing fields. The placeholder examples (e.g. "1s", "2s") are helpful for users.
app/notification-generator/components/Title.tsx (2)
17-17
: Good early return pattern!Clean conditional rendering when title shouldn't be shown.
24-37
: Nice conditional rendering and styling!The component properly checks for title/subtitle content before rendering, and the Minecraft-themed styling with drop shadows ensures good readability against backgrounds.
app/notification-generator/components/ActionBar.tsx (1)
1-52
: Great component structure and styling!The ActionBar component is well implemented with good performance optimization using React.memo and proper early return pattern. The Minecraft-themed styling with the complex text shadow creates the authentic game-like appearance.
components/header/ToolsDropdown.tsx (2)
1-101
: Excellent dropdown implementation with great accessibility!This component demonstrates excellent practices with proper event handling, accessibility attributes, keyboard navigation, and smooth animations. The click-outside detection and escape key handling work perfectly together.
51-53
: Great accessibility attributes!Perfect use of ARIA attributes for screen readers and assistive technologies. The
aria-haspopup
,aria-expanded
, andaria-controls
attributes provide excellent accessibility support.app/notification-generator/types.ts (1)
1-21
: Clean and well-structured type definitions!The interfaces and type aliases provide excellent TypeScript support for the notification generator. The NotificationConfig covers all necessary properties and the union types ensure type safety throughout the feature.
app/notification-generator/form/Tab.tsx (2)
1-36
: Nicely animated tab component!Great use of framer-motion for smooth animations and transitions. The conditional styling and active state indicator with layoutId create an excellent user experience. The component is clean and well-typed.
29-34
: Excellent use of layout animations!The layoutId="activeTab" creates smooth transitions when switching between tabs. This is a great pattern for animated tab indicators that provides professional polish to the UI.
app/notification-generator/components/ChatMessage.tsx (1)
8-9
: Good use of memoization and early return.The React.memo optimization and early return for empty messages are solid patterns.
app/notification-generator/MinecraftPreview.tsx (1)
13-16
: Good use of custom hooks for state management.The separation of title animation and sound effect logic into custom hooks makes the component clean and testable.
app/notification-generator/page.tsx (3)
29-99
: YAML generation logic looks solid with good fallback handling.The useEffect correctly regenerates YAML when notification state changes. The logic handles multiline chat messages, timing parameters, and sound configuration properly with sensible defaults.
101-104
: Simple and effective preview refresh mechanism.Using a key increment to force component re-render is a clean approach for triggering preview animations.
106-213
: Well-structured UI with comprehensive animations.The layout uses a responsive grid and motion components effectively. The animation timing and transitions create a smooth user experience.
content/docs/eternalcore/notifications.md (1)
1-175
: Excellent documentation with comprehensive examples.The documentation covers all notification types with clear syntax examples. The interactive generator link is a great addition for user experience.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~168-~168: This verb may not be in the correct form. Consider using a different form for this context.
Context: ....#### Clear title/subtitle before send new
yaml # Clears the title and sub...(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)
🪛 markdownlint-cli2 (0.17.2)
81-81: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
app/notification-generator/NotificationForm.tsx (3)
27-46
: Smart validation handling with performance optimization.The handleChange callback properly validates specific fields and clears errors when needed. Using useCallback prevents unnecessary re-renders.
49-65
: Clean reset functionality.The reset form callback properly clears both notification state and errors, returning to a clean initial state.
68-83
: Well-organized tab content rendering.The switch statement clearly maps each tab to its corresponding component, with proper error prop passing where needed.
app/parser/minecraftTextParser.tsx (1)
133-175
: Tag parsing function is well-designed but unreachable.The recursive tag parsing logic is solid and handles nested formatting correctly. However, it's currently unreachable due to the early return in the main loop.
app/notification-generator/hooks.ts (1)
70-83
: Clean and simple implementationThe sound effect hook is well-implemented with proper cleanup. The 1-second timeout provides good user feedback for sound triggers.
components/header/Navbar.tsx (4)
3-38
: Well-structured navigation setupThe NavLink interface and centralized NAV_LINKS array provide good type safety and maintainability. The separation of internal and external links is handled cleanly.
50-88
: Excellent accessibility and UX implementationThe event handling is comprehensive with proper cleanup, focus management, and body scroll locking. These features greatly improve the user experience and accessibility.
142-204
: Smooth and accessible mobile menuThe framer-motion animations create a polished user experience. The staggered list item animations and proper ARIA attributes make this both visually appealing and accessible.
206-242
: Consistent desktop navigation implementationThe desktop menu maintains consistency with the mobile version by sharing the same link data and styling patterns. External link handling is properly implemented with security attributes.
app/layout.tsx (3)
1-28
: Comprehensive font and build configurationThe expanded Poppins font configuration with multiple weights, swap display, and fallbacks provides excellent typography. The static generation with hourly revalidation is a good balance for performance.
30-108
: Excellent SEO and metadata setupThe metadata configuration is comprehensive with proper Open Graph, Twitter cards, and robot directives. The dynamic OG image generation and theme colors enhance the user experience across platforms.
116-150
: Well-structured and accessible layoutThe layout properly uses semantic HTML with accessibility attributes. The addition of cookie consent management, analytics, and documentation enhancements creates a complete user experience.
<AnimatePresence> | ||
{notification.actionbar && ( | ||
<div> | ||
<ActionBar message={notification.actionbar} /> | ||
</div> | ||
)} | ||
</AnimatePresence> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Missing positioning for ActionBar component.
The ActionBar is missing absolute positioning unlike other notification elements, which may cause layout issues.
<AnimatePresence>
{notification.actionbar && (
- <div>
+ <div className="absolute bottom-16 left-1/2 transform -translate-x-1/2">
<ActionBar message={notification.actionbar} />
</div>
)}
</AnimatePresence>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<AnimatePresence> | |
{notification.actionbar && ( | |
<div> | |
<ActionBar message={notification.actionbar} /> | |
</div> | |
)} | |
</AnimatePresence> | |
<AnimatePresence> | |
{notification.actionbar && ( | |
<div className="absolute bottom-16 left-1/2 transform -translate-x-1/2"> | |
<ActionBar message={notification.actionbar} /> | |
</div> | |
)} | |
</AnimatePresence> |
🤖 Prompt for AI Agents
In app/notification-generator/MinecraftPreview.tsx around lines 37 to 43, the
ActionBar component is missing absolute positioning, unlike other notification
elements. To fix this, wrap the ActionBar in a div with appropriate CSS styles
to apply absolute positioning, ensuring it aligns consistently with other
notification elements and prevents layout issues.
app/notification-generator/hooks.ts
Outdated
const fadeInInterval = setInterval(() => { | ||
setTitleOpacity((prev) => { | ||
if (prev >= 1) { | ||
clearInterval(fadeInInterval); | ||
return 1; | ||
} | ||
return prev + 0.1; | ||
}); | ||
}, fadeIn * 100); | ||
|
||
const stayTimeout = setTimeout(() => { | ||
const fadeOutInterval = setInterval(() => { | ||
setTitleOpacity((prev) => { | ||
if (prev <= 0) { | ||
clearInterval(fadeOutInterval); | ||
setShowTitle(false); | ||
return 0; | ||
} | ||
return prev - 0.1; | ||
}); | ||
}, fadeOut * 100); | ||
}, (fadeIn + stay) * 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix animation timing and cleanup issues
The animation has timing calculation problems and incomplete cleanup that could cause memory leaks.
const fadeInInterval = setInterval(() => {
setTitleOpacity((prev) => {
if (prev >= 1) {
clearInterval(fadeInInterval);
return 1;
}
return prev + 0.1;
});
-}, fadeIn * 100);
+}, (fadeIn * 1000) / 10);
const stayTimeout = setTimeout(() => {
+ let fadeOutInterval: NodeJS.Timeout;
- const fadeOutInterval = setInterval(() => {
+ fadeOutInterval = setInterval(() => {
setTitleOpacity((prev) => {
if (prev <= 0) {
clearInterval(fadeOutInterval);
setShowTitle(false);
return 0;
}
return prev - 0.1;
});
- }, fadeOut * 100);
+ }, (fadeOut * 1000) / 10);
}, (fadeIn + stay) * 1000);
return () => {
clearTimeout(stayTimeout);
clearInterval(fadeInInterval);
+ if (fadeOutInterval) clearInterval(fadeOutInterval);
};
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In app/notification-generator/hooks.ts around lines 28 to 49, the animation
timing calculations are inconsistent because fadeIn and fadeOut are multiplied
by 100 in setInterval but stay is multiplied by 1000 in setTimeout, causing
timing issues. Also, the intervals and timeouts are not cleared on component
unmount, risking memory leaks. Fix this by using consistent time units
(milliseconds) for all timers and ensure all intervals and timeouts are cleared
properly in a cleanup function, such as in a useEffect return callback.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
app/notification-generator/form/SoundTab.tsx (1)
64-86
: Consider adding validation for slider rangesThe slider fields are properly configured, but you might want to add client-side validation to ensure the volume (0.0-1.0) and pitch (0.5-2.0) ranges are enforced before passing to the parent component.
app/notification-generator/form/SliderField.tsx (1)
27-29
: Handle edge case for invalid initial valuesThe fallback to midpoint is good, but consider what happens if
min
ormax
are invalid numbers. This could cause NaN issues.const [sliderValue, setSliderValue] = useState<number>( - value ? parseFloat(value) : (min + max) / 2 + value && !isNaN(parseFloat(value)) ? parseFloat(value) : (min + max) / 2 );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
app/notification-generator/NotificationForm.tsx
(1 hunks)app/notification-generator/SoundInfoBox.tsx
(1 hunks)app/notification-generator/form/SliderField.tsx
(1 hunks)app/notification-generator/form/SoundDropdown.tsx
(1 hunks)app/notification-generator/form/SoundTab.tsx
(1 hunks)app/notification-generator/page.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- app/notification-generator/SoundInfoBox.tsx
- app/notification-generator/NotificationForm.tsx
- app/notification-generator/page.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
app/notification-generator/form/SoundDropdown.tsx
[error] 171-171: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 174-174: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 190-190: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 193-193: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🔇 Additional comments (5)
app/notification-generator/form/SoundTab.tsx (1)
21-30
: Good use of forwardRef pattern!The component correctly exposes the
stopSound
method through the ref, allowing parent components to control audio playback. The implementation is clean and follows React best practices.app/notification-generator/form/SliderField.tsx (2)
32-39
: Good value synchronization logicThe useEffect properly handles external value changes and bounds the value within the min/max range. This prevents invalid slider states.
75-84
: Nice animation for error messagesThe framer-motion animation provides smooth feedback when validation errors appear. Good user experience enhancement!
app/notification-generator/form/SoundDropdown.tsx (2)
157-217
: Good audio handling with proper cleanupThe audio playback logic properly handles volume/pitch validation, error cases, and cleanup. The fallback error messages provide good user feedback.
🧰 Tools
🪛 Biome (1.9.4)
[error] 171-171: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
[error] 174-174: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
[error] 190-190: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
[error] 193-193: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
104-113
: Smart fallback data strategyProviding default sounds when the API fails ensures the component remains functional. Good resilience approach!
let volumeValue = 1.0; // Default value | ||
if (typeof volume === "string") { | ||
const parsedVolume = parseFloat(volume); | ||
if (!isNaN(parsedVolume) && isFinite(parsedVolume)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix unsafe isFinite usage
Static analysis correctly identifies unsafe isFinite
usage. Use Number.isFinite
instead to avoid type coercion issues.
- if (!isNaN(parsedVolume) && isFinite(parsedVolume)) {
+ if (!isNaN(parsedVolume) && Number.isFinite(parsedVolume)) {
volumeValue = Math.min(Math.max(parsedVolume, 0), 1.0);
}
- } else if (typeof volume === "number" && isFinite(volume)) {
+ } else if (typeof volume === "number" && Number.isFinite(volume)) {
volumeValue = Math.min(Math.max(volume, 0), 1.0);
}
- if (!isNaN(parsedPitch) && isFinite(parsedPitch)) {
+ if (!isNaN(parsedPitch) && Number.isFinite(parsedPitch)) {
pitchValue = Math.min(Math.max(parsedPitch, 0.5), 2.0);
}
- } else if (typeof pitch === "number" && isFinite(pitch)) {
+ } else if (typeof pitch === "number" && Number.isFinite(pitch)) {
pitchValue = Math.min(Math.max(pitch, 0.5), 2.0);
}
Also applies to: 174-174, 190-190, 193-193
🧰 Tools
🪛 Biome (1.9.4)
[error] 171-171: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🤖 Prompt for AI Agents
In app/notification-generator/form/SoundDropdown.tsx at lines 171, 174, 190, and
193, replace all uses of the global isFinite function with Number.isFinite to
prevent unsafe type coercion. Update the conditions by changing
isFinite(parsedVolume) to Number.isFinite(parsedVolume) to ensure proper type
checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (13)
components/ui/AlertBox.tsx (3)
41-114
: Consider moving large configuration to separate file.The alertStyles object is quite large and makes the component file lengthy. Consider extracting it to a separate constants file for better maintainability.
// Create a new file: components/ui/AlertBox.constants.ts +export const alertStyles = { + // ... move the entire alertStyles object here +}; // Then import in AlertBox.tsx +import { alertStyles } from './AlertBox.constants'; -const alertStyles = { - // ... remove from here -};
128-138
: Default titles could be more descriptive.Some default titles like "Read this!" for warnings could be more specific and helpful to users.
- warning: "Read this!", + warning: "Warning",
155-156
: Remove extra blank lines.There are unnecessary blank lines that should be cleaned up.
const defaultTitle = defaultTitles[type]; - const ariaLabel = typeof title === "string" ? title : `${type} alert`;
components/ui/Dropdown.tsx (1)
61-61
: Move inline styles to CSS classes for better maintainability.The component uses several inline styles that could be moved to CSS classes:
- Button outline/boxShadow removal (line 61, 103)
- Scrollbar hiding styles (lines 83-89, 92-98)
Consider creating CSS utility classes for these common styles to improve maintainability and reduce code duplication.
Also applies to: 83-89, 92-98, 103-103
components/notification-generator/ActionBar.tsx (1)
10-47
: Consider extracting inline styles for better maintainability.The extensive inline styles work but make the component harder to maintain. Consider moving the complex styling to CSS classes or styled components.
+const actionBarStyles = { + container: { + bottom: "12%", + transform: "translateX(-50%)", + width: "100%", + textAlign: "center" as const, + pointerEvents: "none" as const, + zIndex: 10, + }, + text: { + color: "#fff", + fontSize: "1.5rem", + textShadow: "2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 1px 1px #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000", + fontWeight: "normal", + lineHeight: 1.2, + userSelect: "none" as const, + } +}; - style={{ - bottom: "12%", - transform: "translateX(-50%)", - width: "100%", - textAlign: "center", - pointerEvents: "none", - zIndex: 10, - background: "none", - border: "none", - boxShadow: "none", - padding: 0, - }} + style={actionBarStyles.container}components/notification-generator/ChatMessage.tsx (1)
20-37
: Consider extracting common styling to reduce duplication.The multiline and single line rendering have identical styling. Extract this to a common constant or component.
+const messageLineStyles = { + className: "font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]", + style: { zIndex: 1, height: "32px", lineHeight: "32px" } +}; +const MessageLine = ({ children }: { children: React.ReactNode }) => ( + <div {...messageLineStyles}> + {children} + </div> +); {message.includes("\n") ? ( message.split("\n").map((line, index) => ( - <div - key={index} - className="font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ zIndex: 1, height: "32px", lineHeight: "32px" }} - > + <MessageLine key={index}> {parseMinecraftText(line)} - </div> + </MessageLine> )) ) : ( - <div - className="font-minecraft relative px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ zIndex: 1, height: "32px", lineHeight: "32px" }} - > + <MessageLine> {parseMinecraftText(message)} - </div> + </MessageLine> )}components/notification-generator/form/FormField.tsx (1)
73-94
: Add IDs to error and help text for accessibility.Screen readers need these IDs to announce the messages properly.
{error ? ( <motion.p + id={`${name}-error`} className="text-xs text-red-500" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.1 }} > {error} </motion.p> ) : helpText ? ( <motion.p + id={`${name}-help`} className="text-xs text-gray-500 dark:text-gray-400" initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.1, delay: 0.1 }} > {helpText} </motion.p> ) : null}components/notification-generator/form/SoundDropdown.tsx (1)
65-126
: Consider extracting sound fetching to a custom hook.This would make the component more readable and the logic reusable.
The sound fetching logic could be moved to a custom hook like
useSoundData()
to separate concerns and make the component cleaner. Would you like me to create this refactor?components/notification-generator/MinecraftPreview.tsx (1)
29-65
: Consider adding wrapper positioning classesThe AnimatePresence blocks use basic div wrappers. Consider adding consistent positioning classes to improve layout predictability, especially for the ActionBar and Title components that might need specific positioning.
- {notification.actionbar && ( - <div> - <ActionBar message={notification.actionbar} /> - </div> - )} + {notification.actionbar && ( + <div className="absolute bottom-16 left-1/2 transform -translate-x-1/2"> + <ActionBar message={notification.actionbar} /> + </div> + )}components/notification-generator/minecraftTextParser.tsx (1)
59-62
: Remove unused variablesThese variables are declared but never used in the function.
- let processedText = text; - let lastColor = ''; - let lastStyle = '';components/notification-generator/form/validation.ts (1)
31-58
: Simplify validateForm functionThe function takes a
validateFieldFn
parameter but only uses the localvalidateField
. This makes the API more complex than needed.-export const validateForm = ( - notification: Record<string, string>, - validateFieldFn: (field: FieldType, value: string) => string -): Record<string, string> => { +export const validateForm = ( + notification: Record<string, string> +): Record<string, string> => { const errors: Record<string, string> = {}; if (notification.fadeIn) { - const error = validateFieldFn("fadeIn" as FieldType, notification.fadeIn); + const error = validateField("fadeIn", notification.fadeIn); if (error) errors.fadeIn = error; } // ... rest of the functioncomponents/notification-generator/form/SoundTab.tsx (2)
3-3
: Remove unused importsThe
useState
anduseEffect
imports are not used in this component.-import { useRef, forwardRef, useImperativeHandle, useState, useEffect } from "react"; +import { useRef, forwardRef, useImperativeHandle } from "react";
65-65
: Improve type safetyThe type casting here could be made safer by ensuring the field name is actually a valid FieldType.
-onChange={(name, value) => onChange(name as FieldType, value)} +onChange={(name: string, value: string) => { + if (name === 'volume' || name === 'pitch') { + onChange(name, value); + } +}}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
app/notification-generator/layout.tsx
(1 hunks)app/notification-generator/page.tsx
(1 hunks)app/privacy-policy/page.tsx
(1 hunks)components/header/polygon/PolygonLeft.tsx
(0 hunks)components/header/polygon/PolygonRight.tsx
(0 hunks)components/notification-generator/ActionBar.tsx
(1 hunks)components/notification-generator/BackgroundImage.tsx
(1 hunks)components/notification-generator/ChatMessage.tsx
(1 hunks)components/notification-generator/MinecraftPreview.tsx
(1 hunks)components/notification-generator/MiniMessageInfoBox.tsx
(1 hunks)components/notification-generator/NotificationCode.tsx
(1 hunks)components/notification-generator/NotificationForm.tsx
(1 hunks)components/notification-generator/SoundIndicator.tsx
(1 hunks)components/notification-generator/SoundInfoBox.tsx
(1 hunks)components/notification-generator/Title.tsx
(1 hunks)components/notification-generator/form/ActionBarTab.tsx
(1 hunks)components/notification-generator/form/AdvancedTab.tsx
(1 hunks)components/notification-generator/form/ChatTab.tsx
(1 hunks)components/notification-generator/form/FormField.tsx
(1 hunks)components/notification-generator/form/SliderField.tsx
(1 hunks)components/notification-generator/form/SoundDropdown.tsx
(1 hunks)components/notification-generator/form/SoundTab.tsx
(1 hunks)components/notification-generator/form/Tab.tsx
(1 hunks)components/notification-generator/form/TitleTab.tsx
(1 hunks)components/notification-generator/form/constants.ts
(1 hunks)components/notification-generator/form/validation.ts
(1 hunks)components/notification-generator/hooks.ts
(1 hunks)components/notification-generator/minecraft-font.css
(1 hunks)components/notification-generator/minecraftTextParser.tsx
(1 hunks)components/notification-generator/types.ts
(1 hunks)components/ui/AlertBox.tsx
(1 hunks)components/ui/Dropdown.tsx
(1 hunks)hooks/useCookieConsent.ts
(1 hunks)lib/cookie-utils.ts
(1 hunks)lib/mdx.tsx
(1 hunks)
💤 Files with no reviewable changes (2)
- components/header/polygon/PolygonRight.tsx
- components/header/polygon/PolygonLeft.tsx
✅ Files skipped from review due to trivial changes (7)
- components/notification-generator/types.ts
- components/notification-generator/SoundInfoBox.tsx
- components/notification-generator/minecraft-font.css
- components/notification-generator/BackgroundImage.tsx
- components/notification-generator/MiniMessageInfoBox.tsx
- components/notification-generator/form/constants.ts
- components/notification-generator/NotificationCode.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
- app/notification-generator/layout.tsx
- lib/cookie-utils.ts
- app/privacy-policy/page.tsx
- lib/mdx.tsx
- hooks/useCookieConsent.ts
- app/notification-generator/page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (14)
components/notification-generator/MinecraftPreview.tsx (2)
components/notification-generator/types.ts (1)
MinecraftPreviewProps
(16-18)components/notification-generator/hooks.ts (2)
useTitleAnimation
(4-68)useSoundEffect
(70-83)
components/notification-generator/form/ActionBarTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(18-97)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/notification-generator/ChatMessage.tsx (1)
components/notification-generator/minecraftTextParser.tsx (1)
parseMinecraftText
(3-175)
components/notification-generator/form/AdvancedTab.tsx (1)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)
components/notification-generator/form/FormField.tsx (1)
components/notification-generator/types.ts (1)
FieldType
(21-21)
components/notification-generator/Title.tsx (1)
components/notification-generator/minecraftTextParser.tsx (1)
parseMinecraftText
(3-175)
components/notification-generator/form/ChatTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(18-97)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/notification-generator/form/TitleTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(18-97)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/notification-generator/form/validation.ts (1)
components/notification-generator/types.ts (1)
FieldType
(21-21)
components/notification-generator/form/Tab.tsx (1)
components/notification-generator/types.ts (1)
TabType
(20-20)
components/notification-generator/hooks.ts (1)
components/notification-generator/types.ts (1)
NotificationConfig
(1-14)
components/ui/Dropdown.tsx (1)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)
components/ui/AlertBox.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/notification-generator/NotificationForm.tsx (8)
components/notification-generator/types.ts (3)
NotificationConfig
(1-14)TabType
(20-20)FieldType
(21-21)components/notification-generator/form/SoundTab.tsx (2)
SoundTabRef
(19-21)SoundTab
(23-86)components/notification-generator/form/validation.ts (1)
validateField
(3-29)components/notification-generator/form/ChatTab.tsx (1)
ChatTab
(12-25)components/notification-generator/form/ActionBarTab.tsx (1)
ActionBarTab
(12-23)components/notification-generator/form/TitleTab.tsx (1)
TitleTab
(13-61)components/notification-generator/form/AdvancedTab.tsx (1)
AdvancedTab
(10-30)components/notification-generator/form/Tab.tsx (1)
Tab
(13-36)
🪛 Biome (1.9.4)
components/notification-generator/form/SoundDropdown.tsx
[error] 172-172: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 175-175: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 191-191: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 194-194: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🔇 Additional comments (21)
components/ui/AlertBox.tsx (3)
1-18
: Good setup with proper imports and client directive.The imports are clean and all necessary dependencies are included. The "use client" directive is appropriate for this animated component.
19-39
: Well-defined types and interfaces.The AlertBoxType union and AlertBoxProps interface are comprehensive and well-documented. Good use of JSDoc comments for prop descriptions.
146-193
: Excellent component implementation with good accessibility.The component is well-implemented with proper memoization, smooth animations, and comprehensive accessibility features. The ARIA roles and labels are correctly applied for different alert types.
components/ui/Dropdown.tsx (2)
38-50
: Great implementation of outside click handling.The useEffect properly handles cleanup and uses mousedown event which is more reliable than click for this use case.
54-74
: Excellent accessibility implementation.The button has proper ARIA attributes (
aria-expanded
,aria-haspopup
) and the arrow animation provides good visual feedback.components/notification-generator/form/ActionBarTab.tsx (1)
12-23
: Clean and focused component implementation.The component has a clear single responsibility and uses proper TypeScript interfaces. The integration with FormField and MiniMessageInfoBox is well done.
components/notification-generator/form/AdvancedTab.tsx (1)
10-30
: Well-implemented form component with good accessibility.The checkbox implementation follows HTML best practices with proper label association and the TypeScript interfaces are correctly defined for boolean handling.
components/notification-generator/SoundIndicator.tsx (1)
8-32
: Excellent use of React.memo and clean conditional rendering.The memoization will prevent unnecessary re-renders, and the conditional rendering logic is clear and efficient. The inline SVG and proper displayName setting are good practices.
components/notification-generator/form/ChatTab.tsx (1)
1-25
: Clean and well-structured component!The implementation follows React best practices with proper TypeScript interfaces and clean imports. The component is simple and focused on a single responsibility.
components/notification-generator/Title.tsx (1)
1-44
: Good use of React.memo and clean conditional rendering.The component is well-structured with proper optimization. The text parsing integration looks solid and the styling approach is consistent.
components/notification-generator/form/TitleTab.tsx (1)
13-61
: Nice clean implementation!The component structure is clear and makes good use of the FormField component. The grid layout for timing fields is a nice touch.
components/notification-generator/MinecraftPreview.tsx (1)
13-16
: LGTM! Clean component structureThe component properly uses custom hooks and manages the notification preview state well. The separation of concerns between animation and sound logic is good.
components/notification-generator/NotificationForm.tsx (2)
47-66
: LGTM! Proper cleanup in reset functionGood implementation of the reset function with proper sound cleanup and state reset. The useCallback optimization is appropriate here.
27-45
: 🛠️ Refactor suggestionFix unnecessary re-renders in handleChange callback
The
errors
dependency in the useCallback will cause the function to recreate every time errors change, potentially causing unnecessary re-renders of child components.- }, [notification, setNotification, errors]); + }, [notification, setNotification]);The errors check inside can use the current errors state without needing it as a dependency.
Likely an incorrect or invalid review comment.
components/notification-generator/form/validation.ts (1)
15-19
:❓ Verification inconclusive
Verify sound validation regex
The current regex only allows uppercase letters and underscores, which might be too restrictive for Minecraft sound names. Consider if lowercase or other characters should be allowed.
🏁 Script executed:
#!/bin/bash # Check Minecraft sound naming conventions rg -A 5 -B 5 "sound.*[a-z]" --type=ts --type=tsxLength of output: 78
Review and adjust sound regex
The current regex in
components/notification-generator/form/validation.ts
only allows uppercase letters and underscores (plus an optional space). Minecraft sound event IDs are lowercase and often include dots and underscores (e.g.entity.cow.ambient
). Please update the pattern to allow lowercase letters, periods, and underscores or confirm that your sound names follow the existing format.• File: components/notification-generator/form/validation.ts
- Case
"sound"
: replace/^[A-Z_]+(\s+[A-Z_]+)?$/
with a regex that matches lowercase, dots, and underscores (for example:/^[a-z0-9_\.]+$/
).Simplify validateForm
The
validateForm
function’s signature currently takes an extra parameter that isn’t needed. Remove it and make sure all intended fields (including any you’ve added recently) are covered by the validation logic.components/notification-generator/form/SoundTab.tsx (1)
23-86
: Well-structured component implementationThe forwardRef pattern is correctly implemented with proper type definitions. The useImperativeHandle usage allows parent components to control sound playback effectively.
components/notification-generator/hooks.ts (1)
70-83
: Simple and effective sound hookThe useSoundEffect hook is well-implemented with proper cleanup and straightforward state management.
components/notification-generator/form/SliderField.tsx (4)
27-39
: Good initialization and bounds checkingThe component properly initializes the slider value and ensures it stays within bounds when props change.
42-46
: Efficient change handlingUsing useCallback here prevents unnecessary re-renders and the formatting to 2 decimals ensures consistent value display.
125-143
: Excellent accessibility implementationThe dropdown button properly uses ARIA attributes (
aria-expanded
,aria-haspopup
) and the animated chevron provides good visual feedback.
106-115
: Proper click-outside handlingThe event listener is correctly added and removed to prevent memory leaks, and the ref-based outside click detection works well.
let volumeValue = 1.0; | ||
if (typeof volume === "string") { | ||
const parsedVolume = parseFloat(volume); | ||
if (!isNaN(parsedVolume) && isFinite(parsedVolume)) { | ||
volumeValue = Math.min(Math.max(parsedVolume, 0), 1.0); | ||
} | ||
} else if (typeof volume === "number" && isFinite(volume)) { | ||
volumeValue = Math.min(Math.max(volume, 0), 1.0); | ||
} | ||
|
||
|
||
try { | ||
newAudio.volume = volumeValue; | ||
} catch (err) { | ||
console.error("Error setting volume:", err); | ||
newAudio.volume = 1.0; | ||
} | ||
|
||
|
||
let pitchValue = 1.0; | ||
if (typeof pitch === "string") { | ||
const parsedPitch = parseFloat(pitch); | ||
if (!isNaN(parsedPitch) && isFinite(parsedPitch)) { | ||
pitchValue = Math.min(Math.max(parsedPitch, 0.5), 2.0); | ||
} | ||
} else if (typeof pitch === "number" && isFinite(pitch)) { | ||
pitchValue = Math.min(Math.max(pitch, 0.5), 2.0); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace global isFinite with Number.isFinite.
Using the global version can cause unexpected type coercion.
let volumeValue = 1.0;
if (typeof volume === "string") {
const parsedVolume = parseFloat(volume);
- if (!isNaN(parsedVolume) && isFinite(parsedVolume)) {
+ if (!isNaN(parsedVolume) && Number.isFinite(parsedVolume)) {
volumeValue = Math.min(Math.max(parsedVolume, 0), 1.0);
}
- } else if (typeof volume === "number" && isFinite(volume)) {
+ } else if (typeof volume === "number" && Number.isFinite(volume)) {
volumeValue = Math.min(Math.max(volume, 0), 1.0);
}
// ...
let pitchValue = 1.0;
if (typeof pitch === "string") {
const parsedPitch = parseFloat(pitch);
- if (!isNaN(parsedPitch) && isFinite(parsedPitch)) {
+ if (!isNaN(parsedPitch) && Number.isFinite(parsedPitch)) {
pitchValue = Math.min(Math.max(parsedPitch, 0.5), 2.0);
}
- } else if (typeof pitch === "number" && isFinite(pitch)) {
+ } else if (typeof pitch === "number" && Number.isFinite(pitch)) {
pitchValue = Math.min(Math.max(pitch, 0.5), 2.0);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
let volumeValue = 1.0; | |
if (typeof volume === "string") { | |
const parsedVolume = parseFloat(volume); | |
if (!isNaN(parsedVolume) && isFinite(parsedVolume)) { | |
volumeValue = Math.min(Math.max(parsedVolume, 0), 1.0); | |
} | |
} else if (typeof volume === "number" && isFinite(volume)) { | |
volumeValue = Math.min(Math.max(volume, 0), 1.0); | |
} | |
try { | |
newAudio.volume = volumeValue; | |
} catch (err) { | |
console.error("Error setting volume:", err); | |
newAudio.volume = 1.0; | |
} | |
let pitchValue = 1.0; | |
if (typeof pitch === "string") { | |
const parsedPitch = parseFloat(pitch); | |
if (!isNaN(parsedPitch) && isFinite(parsedPitch)) { | |
pitchValue = Math.min(Math.max(parsedPitch, 0.5), 2.0); | |
} | |
} else if (typeof pitch === "number" && isFinite(pitch)) { | |
pitchValue = Math.min(Math.max(pitch, 0.5), 2.0); | |
} | |
let volumeValue = 1.0; | |
if (typeof volume === "string") { | |
const parsedVolume = parseFloat(volume); | |
if (!isNaN(parsedVolume) && Number.isFinite(parsedVolume)) { | |
volumeValue = Math.min(Math.max(parsedVolume, 0), 1.0); | |
} | |
} else if (typeof volume === "number" && Number.isFinite(volume)) { | |
volumeValue = Math.min(Math.max(volume, 0), 1.0); | |
} | |
try { | |
newAudio.volume = volumeValue; | |
} catch (err) { | |
console.error("Error setting volume:", err); | |
newAudio.volume = 1.0; | |
} | |
let pitchValue = 1.0; | |
if (typeof pitch === "string") { | |
const parsedPitch = parseFloat(pitch); | |
if (!isNaN(parsedPitch) && Number.isFinite(parsedPitch)) { | |
pitchValue = Math.min(Math.max(parsedPitch, 0.5), 2.0); | |
} | |
} else if (typeof pitch === "number" && Number.isFinite(pitch)) { | |
pitchValue = Math.min(Math.max(pitch, 0.5), 2.0); | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 172-172: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 175-175: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 191-191: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 194-194: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🤖 Prompt for AI Agents
In components/notification-generator/form/SoundDropdown.tsx between lines 169
and 197, replace all uses of the global isFinite function with Number.isFinite
to avoid unexpected type coercion. This means updating the checks that currently
use isFinite(volume) and isFinite(pitch) to use Number.isFinite(volume) and
Number.isFinite(pitch) respectively, ensuring more reliable type checking.
…erated yaml. Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (5)
package.json (3)
33-34
: Major React 19 upgrade requires compatibility verificationThe React 19 upgrade includes significant breaking changes that need to be addressed throughout the codebase.
59-59
: Next.js 15 upgrade requires breaking changes reviewThe Next.js 15 upgrade includes several breaking changes including async request APIs and caching behavior changes.
40-40
: Remove unused rehype-prism-plus dependencyThis dependency is not being used in the codebase and should be removed.
components/notification-generator/form/SoundDropdown.tsx (1)
181-184
: Replace global isFinite with Number.isFiniteThe global
isFinite
function can cause unexpected type coercion and should be replaced withNumber.isFinite
.Also applies to: 200-203
🧰 Tools
🪛 Biome (1.9.4)
[error] 181-181: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
[error] 184-184: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
components/notification-generator/minecraftTextParser.tsx (1)
88-94
:⚠️ Potential issueFix obfuscated text handling issue.
The obfuscated text handling still has the same issue flagged in previous reviews - it consumes the entire remaining string and prevents further parsing.
This prevents proper parsing of mixed formatting codes after obfuscated text. Consider applying the obfuscated style only to the appropriate text segment without early return.
🧹 Nitpick comments (5)
components/docs/AnimatedLayout.tsx (1)
10-10
: Remove unnecessary forwardRefThe component uses
forwardRef
but doesn't actually forward any ref. Since no ref is being used, you can simplify this to a regular function component.-const AnimatedLayout: React.FC<AnimatedLayoutProps> = ({ children }) => { +const AnimatedLayout = ({ children }: AnimatedLayoutProps) => {And remove the forwardRef wrapper entirely.
components/notification-generator/form/SoundDropdown.tsx (1)
21-22
: Consider making external URLs configurableHard-coding external URLs makes the component less flexible and harder to test. Consider making these configurable through props or environment variables.
+interface SoundDropdownProps { + value: string; + onChange: (value: string) => void; + volume?: number | string; + pitch?: number | string; + soundsJsonUrl?: string; + soundBaseUrl?: string; +} -const SOUNDS_JSON_URL = "https://raw.githubusercontent.com/InventivetalentDev/minecraft-assets/1.21.5/assets/minecraft/sounds.json"; -const SOUND_BASE_URL = "https://raw.githubusercontent.com/InventivetalentDev/minecraft-assets/1.21.5/assets/minecraft/sounds/";components/docs/DocCopyEnhancer.tsx (2)
67-181
: Consider a more consistent React approachThe component mixes React patterns (CopyButton component) with direct DOM manipulation. While functional, this creates inconsistency and makes the code harder to maintain.
Consider using React portals consistently or moving entirely to DOM manipulation. The current CopyButton component suggests you want a React approach, but it's not being used in the actual implementation.
105-108
: Extract SVG constants to reduce duplicationThe SVG code is repeated and hard-coded. Consider extracting these to constants for better maintainability.
+const COPY_SVG = '<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>'; +const CHECK_SVG = '<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M5 13l4 4L19 7"/></svg>'; - const icon = isCopied - ? '<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M5 13l4 4L19 7"/></svg>' - : '<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>'; + const icon = isCopied ? CHECK_SVG : COPY_SVG;app/notification-generator/page.tsx (1)
26-28
: Consider renaming the preview key for clarity.The
previewKey
variable name could be more descriptive to indicate its purpose as a re-render trigger.- const [previewKey, setPreviewKey] = useState(0); // Used to force re-render of preview + const [previewRefreshKey, setPreviewRefreshKey] = useState(0); // Used to force re-render of preview
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (24)
app/docs/layout.tsx
(1 hunks)app/minimessage-demo/page.tsx
(1 hunks)app/notification-generator/layout.tsx
(1 hunks)app/notification-generator/page.tsx
(1 hunks)components/docs/AnimatedHeading.tsx
(1 hunks)components/docs/AnimatedLayout.tsx
(1 hunks)components/docs/CodeTabs.tsx
(1 hunks)components/docs/DocCopyEnhancer.tsx
(1 hunks)components/docs/DocHeader.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/notification-generator/ActionBar.tsx
(1 hunks)components/notification-generator/ChatMessage.module.css
(1 hunks)components/notification-generator/ChatMessage.tsx
(1 hunks)components/notification-generator/MinecraftPreview.tsx
(1 hunks)components/notification-generator/NotificationCode.tsx
(1 hunks)components/notification-generator/NotificationForm.tsx
(1 hunks)components/notification-generator/Title.tsx
(1 hunks)components/notification-generator/form/SoundDropdown.tsx
(1 hunks)components/notification-generator/form/Tab.tsx
(1 hunks)components/notification-generator/hooks.ts
(1 hunks)components/notification-generator/minecraft-font.css
(1 hunks)components/notification-generator/minecraftTextParser.tsx
(1 hunks)package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- app/minimessage-demo/page.tsx
- components/notification-generator/ChatMessage.module.css
- app/notification-generator/layout.tsx
- components/docs/DocHeader.tsx
🚧 Files skipped from review as they are similar to previous changes (13)
- components/notification-generator/ChatMessage.tsx
- components/notification-generator/minecraft-font.css
- components/notification-generator/NotificationCode.tsx
- components/notification-generator/Title.tsx
- app/docs/layout.tsx
- components/notification-generator/NotificationForm.tsx
- components/notification-generator/MinecraftPreview.tsx
- components/docs/AnimatedHeading.tsx
- components/notification-generator/form/Tab.tsx
- components/notification-generator/ActionBar.tsx
- components/docs/CodeTabs.tsx
- components/notification-generator/hooks.ts
- components/docs/DocSearch.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
components/docs/DocCopyEnhancer.tsx (1)
lib/utils.ts (1)
cn
(9-11)
app/notification-generator/page.tsx (4)
components/notification-generator/types.ts (1)
NotificationConfig
(1-14)components/notification-generator/NotificationForm.tsx (1)
NotificationForm
(19-152)components/notification-generator/NotificationCode.tsx (1)
NotificationCode
(10-95)components/notification-generator/MinecraftPreview.tsx (1)
MinecraftPreview
(13-90)
components/docs/DocSidebar.tsx (2)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-56)lib/utils.ts (1)
cn
(9-11)
🪛 Biome (1.9.4)
components/notification-generator/form/SoundDropdown.tsx
[error] 181-181: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 184-184: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 200-200: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 203-203: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
components/notification-generator/minecraftTextParser.tsx
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 24-24: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🔇 Additional comments (3)
components/docs/DocSidebar.tsx (1)
1-190
: Excellent implementation of the documentation sidebar!The component demonstrates solid React best practices with proper memoization, accessibility features, and smooth animations. The hierarchical navigation structure works well with the documentation system.
app/notification-generator/page.tsx (2)
30-85
: YAML generation logic looks solid.The
generateYaml
function handles all notification types properly, including multiline chat messages and optional parameters with sensible defaults.
91-93
: Simple and effective preview refresh mechanism.Using a key increment to force re-render is a clean approach for triggering preview animations.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (3)
components/animations/AnimatedElement.tsx (2)
72-114
: Consider refactoring the large switch statement.The switch statement works but creates a lot of repetitive code. Consider using a dynamic approach to reduce duplication.
- switch (as) { - case "div": - return <motion.div {...commonProps}>{children}</motion.div>; - case "section": - return <motion.section {...commonProps}>{children}</motion.section>; - // ... many more cases - default: - return <motion.div {...commonProps}>{children}</motion.div>; - } + const MotionComponent = motion[as as keyof typeof motion] || motion.div; + return <MotionComponent {...commonProps}>{children}</MotionComponent>;This approach is cleaner and automatically supports all motion elements without manual case handling.
63-64
: Animation logic could be clearer.The conditional logic for interactive vs non-interactive animations is complex and hard to follow.
Consider simplifying with helper functions:
- initial: interactive ? "initial" : "hidden", - animate: inView ? (interactive ? "initial" : "visible") : (interactive ? "initial" : "hidden"), + initial: interactive ? "initial" : "hidden", + animate: interactive ? "initial" : (inView ? "visible" : "hidden"),Or extract to helper functions for better readability.
components/ui/button.tsx (1)
116-174
: Simplify the verbose prop spreading.The manual prop spreading is very long. Consider using destructuring and spread operator instead.
- const motionProps = { - ref, - className: buttonClasses, - whileHover: finalAnimationProps.hover, - whileTap: finalAnimationProps.tap, - transition: finalAnimationProps.transition, - disabled: isLoading || props.disabled, - type: props.type, - name: props.name, - value: props.value, - // ... many more lines - } as HTMLMotionProps<"button">; + return ( + <motion.button + ref={ref} + className={buttonClasses} + whileHover={finalAnimationProps.hover} + whileTap={finalAnimationProps.tap} + transition={finalAnimationProps.transition} + disabled={isLoading || props.disabled} + {...props} + > + {buttonContent} + </motion.button> + );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
app/docs/layout.tsx
(1 hunks)app/page.tsx
(1 hunks)components/AnimatedHome.tsx
(1 hunks)components/about/About.tsx
(1 hunks)components/animations/AnimatedContainer.tsx
(1 hunks)components/animations/AnimatedElement.tsx
(1 hunks)components/animations/AnimatedSection.tsx
(1 hunks)components/animations/AnimationUtils.tsx
(1 hunks)components/animations/index.ts
(1 hunks)components/docs/AnimatedHeading.tsx
(1 hunks)components/docs/DocHeader.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/faq/Faq.tsx
(2 hunks)components/features/Features.tsx
(1 hunks)components/header/ThemeSwitchButton.tsx
(1 hunks)components/header/hero/Hero.tsx
(1 hunks)components/header/hero/button/BackgroundHeroButton.tsx
(1 hunks)components/header/hero/button/TransparentHeroButton.tsx
(1 hunks)components/notification-generator/NotificationForm.tsx
(1 hunks)components/projects/ProjectButton.tsx
(1 hunks)components/team/Team.tsx
(3 hunks)components/ui/button.tsx
(1 hunks)components/ui/tab.tsx
(1 hunks)components/ui/tabs.tsx
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- components/animations/index.ts
- components/animations/AnimationUtils.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
- components/docs/AnimatedHeading.tsx
- components/header/ThemeSwitchButton.tsx
- app/docs/layout.tsx
- components/notification-generator/NotificationForm.tsx
- components/docs/DocHeader.tsx
- components/faq/Faq.tsx
- components/header/hero/Hero.tsx
🧰 Additional context used
🧬 Code Graph Analysis (10)
components/about/About.tsx (1)
components/icons/terminal-fill.tsx (1)
TerminalIcon
(3-18)
components/projects/ProjectButton.tsx (1)
components/icons/github.tsx (1)
GitHubIcon
(3-18)
components/header/hero/button/BackgroundHeroButton.tsx (1)
components/icons/people-group.tsx (1)
PeopleGroupIcon
(3-18)
components/ui/tab.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/ui/button.tsx (1)
Button
(192-192)
components/animations/AnimatedSection.tsx (1)
components/animations/AnimationUtils.tsx (5)
fadeInUp
(26-33)fadeInDown
(36-43)fadeInLeft
(46-53)fadeInRight
(56-63)fadeIn
(14-23)
components/animations/AnimatedElement.tsx (1)
components/animations/AnimationUtils.tsx (6)
fadeInUp
(26-33)fadeInDown
(36-43)fadeInLeft
(46-53)fadeInRight
(56-63)scaleAnimation
(85-95)fadeIn
(14-23)
components/ui/button.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/ui/tabs.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/ui/tab.tsx (1)
Tab
(98-98)
components/docs/DocSidebar.tsx (2)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-56)lib/utils.ts (1)
cn
(9-11)
components/features/Features.tsx (4)
components/icons/java.tsx (1)
JavaIcon
(3-34)components/icons/linux.tsx (1)
LinuxIcon
(3-48)components/icons/tab-new.tsx (1)
TabNew
(3-18)components/SectionTitle.tsx (1)
SectionTitle
(9-34)
🔇 Additional comments (16)
components/AnimatedHome.tsx (1)
1-25
: Nice clean animation wrapper!The component structure looks great. Good use of accessibility attributes and the animation setup follows best practices.
components/projects/ProjectButton.tsx (1)
3-13
: Good refactor to the Button component!The switch from motion.button to the custom Button component makes the code more consistent. The leftIcon prop and accessibility are properly maintained.
app/page.tsx (2)
8-19
: Great metadata setup!The metadata export looks comprehensive with title, description, canonical URL, and Open Graph image. Nice use of the generateOgImageMetadata utility.
21-22
: Clean component simplification!Moving the complexity to AnimatedHome keeps this page component nice and simple.
components/about/About.tsx (4)
6-6
: Good move to animation components!Using the centralized animation components makes the code cleaner and more consistent across the app.
14-19
: Nice accessibility improvement!Adding
aria-labelledby="about-heading"
makes the section more accessible for screen readers.
30-35
: Better image setup!The shadow styling and improved alt text "Software development team collaborating" makes this more descriptive and visually appealing.
39-76
: Well-structured animation timing!The staggered delays (0.2s for container, 0.1s stagger) create a nice cascading effect for the text elements.
components/team/Team.tsx (2)
9-183
: Nice animation refactor!Great job switching to the new animation wrapper components. The code is much cleaner and easier to maintain now.
96-96
: Clean headers syntaxcomponents/animations/AnimatedSection.tsx (1)
1-76
: Well-structured animation component!This component follows good practices with proper prop filtering and accessibility support. The intersection observer integration is clean.
components/ui/tabs.tsx (2)
23-108
: Excellent accessibility and animation implementation!The component properly handles ARIA roles, keyboard navigation, and smooth animations. The state management and callback patterns are well-implemented.
110-112
: Simple and effective memoization.The TabItem wrapper correctly uses React.memo for performance optimization while keeping the implementation clean.
components/docs/DocSidebar.tsx (1)
68-156
: Great component structure!The memoized component with proper accessibility attributes and animation variants is well implemented. The hover effects and layout animations add nice polish.
components/features/Features.tsx (1)
7-86
: Excellent refactor to animation components!This clean refactor replaces manual framer-motion logic with reusable animation components. The centralized feature data and alternating animation directions work well together.
components/ui/button.tsx (1)
26-95
: Well-designed button component!Great use of variants, proper accessibility support, and clean loading state handling. The animation logic is solid too.
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.h3> | ||
); | ||
} else if (as === "h4") { | ||
return ( | ||
<motion.h4 | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.h4> | ||
); | ||
} else if (as === "h5") { | ||
return ( | ||
<motion.h5 | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.h5> | ||
); | ||
} else if (as === "h6") { | ||
return ( | ||
<motion.h6 | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.h6> | ||
); | ||
} else if (as === "ul") { | ||
return ( | ||
<motion.ul | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.ul> | ||
); | ||
} else if (as === "ol") { | ||
return ( | ||
<motion.ol | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.ol> | ||
); | ||
} else if (as === "li") { | ||
return ( | ||
<motion.li | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.li> | ||
); | ||
} else { | ||
// Default to div if the element type is not supported | ||
return ( | ||
<motion.div | ||
ref={ref} | ||
className={className} | ||
variants={containerVariants} | ||
initial="hidden" | ||
animate={inView ? "visible" : "hidden"} | ||
{...props} | ||
> | ||
{children} | ||
</motion.div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Major refactor needed to reduce code repetition.
This approach creates 200+ lines of nearly identical code. Consider using dynamic element creation instead.
- // Use a type-safe approach with conditional rendering
- if (as === "div") {
- return (
- <motion.div
- ref={ref}
- className={className}
- variants={containerVariants}
- initial="hidden"
- animate={inView ? "visible" : "hidden"}
- {...props}
- >
- {children}
- </motion.div>
- );
- } else if (as === "section") {
- // ... many more similar blocks
+ const MotionComponent = motion[as] as any;
+
+ return (
+ <MotionComponent
+ ref={ref}
+ className={className}
+ variants={containerVariants}
+ initial="hidden"
+ animate={inView ? "visible" : "hidden"}
+ {...props}
+ >
+ {children}
+ </MotionComponent>
+ );
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (as === "div") { | |
return ( | |
<motion.div | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.div> | |
); | |
} else if (as === "section") { | |
return ( | |
<motion.section | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.section> | |
); | |
} else if (as === "article") { | |
return ( | |
<motion.article | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.article> | |
); | |
} else if (as === "main") { | |
return ( | |
<motion.main | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.main> | |
); | |
} else if (as === "header") { | |
return ( | |
<motion.header | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.header> | |
); | |
} else if (as === "footer") { | |
return ( | |
<motion.footer | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.footer> | |
); | |
} else if (as === "nav") { | |
return ( | |
<motion.nav | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.nav> | |
); | |
} else if (as === "aside") { | |
return ( | |
<motion.aside | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.aside> | |
); | |
} else if (as === "span") { | |
return ( | |
<motion.span | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.span> | |
); | |
} else if (as === "p") { | |
return ( | |
<motion.p | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.p> | |
); | |
} else if (as === "h1") { | |
return ( | |
<motion.h1 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h1> | |
); | |
} else if (as === "h2") { | |
return ( | |
<motion.h2 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h2> | |
); | |
} else if (as === "h3") { | |
return ( | |
<motion.h3 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h3> | |
); | |
} else if (as === "h4") { | |
return ( | |
<motion.h4 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h4> | |
); | |
} else if (as === "h5") { | |
return ( | |
<motion.h5 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h5> | |
); | |
} else if (as === "h6") { | |
return ( | |
<motion.h6 | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.h6> | |
); | |
} else if (as === "ul") { | |
return ( | |
<motion.ul | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.ul> | |
); | |
} else if (as === "ol") { | |
return ( | |
<motion.ol | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.ol> | |
); | |
} else if (as === "li") { | |
return ( | |
<motion.li | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.li> | |
); | |
} else { | |
// Default to div if the element type is not supported | |
return ( | |
<motion.div | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</motion.div> | |
); | |
} | |
const MotionComponent = motion[as] as any; | |
return ( | |
<MotionComponent | |
ref={ref} | |
className={className} | |
variants={containerVariants} | |
initial="hidden" | |
animate={inView ? "visible" : "hidden"} | |
{...props} | |
> | |
{children} | |
</MotionComponent> | |
); |
🤖 Prompt for AI Agents
In components/animations/AnimatedContainer.tsx around lines 52 to 313, the code
has excessive repetition with multiple if-else blocks rendering similar motion
elements for different tags. Refactor by dynamically creating the motion element
based on the "as" prop using a variable or a mapping, then render a single
motion component with the common props and children. This will drastically
reduce code duplication and improve maintainability.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (3)
components/notification-generator/form/FormField.tsx (1)
115-243
: The accessibility issues from the previous review are still present.The form fields still lack proper label association and ARIA attributes for screen readers.
package.json (1)
42-42
: Remove unused rehype-prism-plus dependencyAs noted in previous reviews, this package isn't used in your MDX config.
components/notification-generator/form/SoundDropdown.tsx (1)
179-179
: Use Number.isFinite instead of global isFiniteThe global isFinite can cause unexpected type coercion. Replace with Number.isFinite for safer type checking.
Also applies to: 182-182, 196-196, 199-199
🧰 Tools
🪛 Biome (1.9.4)
[error] 179-179: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.(lint/suspicious/noGlobalIsFinite)
🧹 Nitpick comments (13)
components/animations/AnimatedSection.tsx (1)
38-38
: Consider clarifying the triggerOnce logic.The condition
preserveAnimation ? true : triggerOnce
works correctly but could be clearer about the intended behavior.- triggerOnce: preserveAnimation ? true : triggerOnce, + triggerOnce: preserveAnimation || triggerOnce,components/notification-generator/form/FormField.tsx (2)
84-96
: Optimize state updates in color management.Multiple state updates can cause unnecessary re-renders. Consider batching them.
const addColor = () => { - setColors([...colors, "#000000"]); - setActiveColorIndex(colors.length); + setColors(prev => { + const newColors = [...prev, "#000000"]; + setActiveColorIndex(newColors.length - 1); + return newColors; + }); };
127-206
: Improve color picker positioning and cleanup.The color picker popup may overflow screen boundaries and needs better positioning logic.
Consider using a portal or proper dropdown positioning library to handle edge cases where the picker extends beyond the viewport.
app/api/docs/search-index/route.ts (4)
6-7
: Use English for commentsThe comment is in Polish - consider using English for better team collaboration.
-// Funkcja do rekurencyjnego wyszukiwania plików markdown w katalogu +// Function to recursively find markdown files in directory
23-24
: Use English for commentsThe comment should be in English for international teams.
-// Funkcja do generowania indeksu wyszukiwania +// Function to generate search index
35-39
: Improve text cleaning for excerptsThe current text cleaning is basic. Consider a more robust approach for better search results.
- const excerpt = markdownContent - .replace(/[#*`_~]/g, '') - .replace(/\n/g, ' ') - .trim() - .substring(0, 150); + const excerpt = markdownContent + .replace(/[#*`_~\[\]]/g, '') // Remove more markdown syntax + .replace(/!\[.*?\]\(.*?\)/g, '') // Remove images + .replace(/\[.*?\]\(.*?\)/g, '') // Remove links + .replace(/\s+/g, ' ') // Normalize whitespace + .trim() + .substring(0, 150);
25-26
: Consider adding performance optimizationsFor large documentation sets, this could be slow. Consider adding caching or incremental updates.
components/ui/tooltip.tsx (2)
20-22
: Consider making delay configurableThe 500ms delay is hardcoded but might not suit all use cases.
interface TooltipProps { children: React.ReactNode; content: string; + delay?: number; } export const Tooltip = ({ children, content, + delay = 500, }: TooltipProps) => { // ... const handleMouseEnter = () => { timeoutRef.current = setTimeout(() => { setIsVisible(true); - }, 500); + }, delay); };
59-59
: Complete or remove commented arrow codeThe commented tooltip arrow suggests incomplete implementation.
- {/* <div className="tooltip-arrow" data-popper-arrow></div> */}
components/docs/DocSearch.tsx (2)
89-89
: Improve type safety for Orama databaseUsing
any
type reduces type safety. Consider creating a proper type for the Orama database.-const [oramaDb, setOramaDb] = useState<any>(null); +const [oramaDb, setOramaDb] = useState<Awaited<ReturnType<typeof create>> | null>(null);
171-171
: Remove unnecessary dependency from useEffectThe
query
dependency causes extra effect runs sincedebouncedQuery
already handles the query changes.-}, [debouncedQuery, oramaDb, minQueryLength, query]); +}, [debouncedQuery, oramaDb, minQueryLength]);components/header/Navbar.tsx (2)
63-72
: Consider potential scroll lock conflictsBody scroll locking could conflict if multiple components try to control it simultaneously.
Consider using a shared scroll lock hook or library that handles multiple consumers:
+import { useScrollLock } from '@/hooks/useScrollLock'; + -useEffect(() => { - if (isMenuOpen) { - document.body.style.overflow = "hidden"; - } else { - document.body.style.overflow = "unset"; - } - return () => { - document.body.style.overflow = "unset"; - }; -}, [isMenuOpen]); +useScrollLock(isMenuOpen);
98-102
: Extract banner content for configurabilityThe hardcoded banner text should be configurable or moved to a separate component for easier management.
+const BANNER_CONFIG = { + show: true, + text: "We launched the new Notification generator, fully interactive and customizable!", + link: "/notification-generator", + linkText: "Check it out →" +}; + -<span className="font-semibold">We launched the new Notification generator, fully interactive and customizable!</span> +<span className="font-semibold">{BANNER_CONFIG.text}</span>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (19)
app/api/docs/search-index/route.ts
(1 hunks)app/docs/layout.tsx
(1 hunks)app/notification-generator/layout.tsx
(1 hunks)app/notification-generator/page.tsx
(1 hunks)components/animations/AnimatedSection.tsx
(1 hunks)components/docs/DocHeader.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/docs/ReadingTime.tsx
(1 hunks)components/header/Navbar.tsx
(2 hunks)components/icons/arrow-back.tsx
(1 hunks)components/icons/arrow-forward.tsx
(1 hunks)components/icons/close.tsx
(1 hunks)components/notification-generator/form/FormField.tsx
(1 hunks)components/notification-generator/form/SoundDropdown.tsx
(1 hunks)components/notification-generator/form/SoundTable.tsx
(1 hunks)components/notification-generator/form/TitleTab.tsx
(1 hunks)components/ui/tooltip.tsx
(1 hunks)package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- components/icons/close.tsx
🚧 Files skipped from review as they are similar to previous changes (8)
- app/notification-generator/layout.tsx
- components/docs/ReadingTime.tsx
- app/docs/layout.tsx
- components/notification-generator/form/TitleTab.tsx
- components/docs/DocHeader.tsx
- app/notification-generator/page.tsx
- components/docs/DocSidebar.tsx
- components/icons/arrow-forward.tsx
🧰 Additional context used
🧬 Code Graph Analysis (5)
components/ui/tooltip.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/animations/AnimatedSection.tsx (2)
components/docs/DocHeader.tsx (1)
fadeInUp
(12-24)components/animations/AnimationUtils.tsx (5)
fadeInUp
(26-33)fadeInDown
(36-43)fadeInLeft
(46-53)fadeInRight
(56-63)fadeIn
(14-23)
components/notification-generator/form/SoundTable.tsx (5)
components/notification-generator/form/SoundDropdown.tsx (1)
Sound
(15-20)components/ui/button.tsx (1)
Button
(192-192)components/icons/close.tsx (1)
CloseIcon
(3-18)components/icons/arrow-back.tsx (1)
ArrowBack
(3-18)components/icons/arrow-forward.tsx (1)
ArrowForward
(3-18)
components/header/Navbar.tsx (4)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)components/icons/hamburger.tsx (1)
Hamburger
(5-24)components/icons/new-window.tsx (1)
NewWindow
(3-20)components/header/ToolsDropdown.tsx (1)
ToolsDropdown
(8-101)
components/docs/DocSearch.tsx (3)
hooks/useDebounce.ts (1)
useDebounce
(3-17)hooks/useClickOutside.ts (1)
useClickOutside
(3-23)lib/utils.ts (1)
cn
(9-11)
🪛 Biome (1.9.4)
components/notification-generator/form/SoundDropdown.tsx
[error] 179-179: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 182-182: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 196-196: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 199-199: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🔇 Additional comments (14)
components/animations/AnimatedSection.tsx (6)
1-8
: Imports look good and well-organized.The component properly imports all necessary dependencies. Good use of the "use client" directive for Next.js.
9-21
: Interface is comprehensive and well-typed.The props interface covers all necessary configuration options with good TypeScript typing. Nice inclusion of accessibility props.
43-56
: Animation variant selection is clean and straightforward.The switch statement provides clear mapping between animation types and variants.
61-61
: Good practice filtering out non-DOM props.Properly prevents the
animationType
prop from reaching the DOM element.
63-65
: Memoization logic is well-implemented.The dependency array correctly handles the preserveAnimation behavior by re-memoizing only when pathname changes if preserveAnimation is enabled.
67-81
: Component rendering is well-structured.Good use of motion.section with proper prop spreading and conditional children rendering.
components/notification-generator/form/FormField.tsx (1)
23-34
: Well-structured component with good prop design.The component interface is clean and the default values are sensible.
components/icons/arrow-back.tsx (1)
1-18
: Clean icon implementation!The component follows good practices with proper TypeScript types, currentColor for theme support, and flexible prop spreading.
package.json (1)
32-32
: Unusual to include npm as a dependencyAdding npm as a runtime dependency is uncommon. Verify this is intentional and not meant for devDependencies.
components/docs/DocSearch.tsx (1)
252-266
: Great search result rendering logicThe conditional rendering handles all states properly - loading, results, and no results. The accessibility roles and animations enhance the user experience.
components/header/Navbar.tsx (3)
14-38
: Excellent navigation link structureThe NavLink interface and centralized NAV_LINKS array provide good type safety and maintainability. The external link handling is properly implemented.
50-60
: Good keyboard accessibility implementationThe Escape key handler with focus return follows accessibility best practices for modal-like interactions.
149-211
: Excellent mobile menu implementationThe animated mobile menu with proper ARIA attributes and focus management creates a great user experience. The integration of ToolsDropdown is seamless.
components/notification-generator/form/SoundTable.tsx (1)
173-330
: Nice table implementation!The component handles all the essentials well - search, sort, pagination, and visual feedback for selected items. Good UX touches like auto-focus and debounced search.
Signed-off-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
WalkthroughThis update introduces a wide range of new features and improvements. It adds a dynamic documentation system with search, animated navigation, and enhanced code highlighting. There’s a new notification generator tool styled after Minecraft, complete with a live preview and YAML code output. The site’s layout, metadata, and accessibility are improved, including cookie consent management and SEO enhancements. Animations are now handled through reusable components for smoother transitions. The documentation and team sections are more interactive, with better navigation and search. Several new icons, UI components, and markdown guides are included, making the site more user-friendly and visually appealing. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
app/api/docs/search-index/route.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by app/api/og/route.tsxOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by app/api/team/route.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 18
♻️ Duplicate comments (19)
components/ui/tooltip.tsx (1)
18-18
: Previous ID conflict issue resolved!The use of
useId()
properly addresses the hardcoded tooltip ID concern from earlier reviews.components/docs/DynamicFeaturesTable.tsx (3)
16-27
: Add error handling and caching for the fetch request.The current fetch implementation could be improved with better error handling and caching.
44-54
: Don't use array indices as React keys.Using array indices as keys can cause issues when the array changes. Use unique identifiers instead.
33-57
: Add accessibility attributes to the table.The table should include proper ARIA roles and attributes for better accessibility.
app/globals.css (3)
173-176
: Table header colors need better contrast.You set a very light background (
#f8fafc
) with white text—this will be hard to read. Please choose a darker header background or a darker text color.
193-195
: Zebra striping has no effect.You set the same background for all rows and even rows. Please adjust odd/even colors so the stripes actually show.
206-208
: Dark mode striping is also no-op.Same background for every row means no stripe. Please pick two shades for dark mode as well.
components/header/hero/button/BackgroundHeroButton.tsx (1)
30-37
:⚠️ Potential issueAnimation controls still not connected to Button
The animation setup looks good, but the Button component still isn't receiving the animation controls. You need to pass the
animate={controls}
andinitial={{ opacity: 0, y: 20 }}
props to make the animations work.<Button ref={ref} variant="primary" + animate={controls} + initial={{ opacity: 0, y: 20 }} leftIcon={<PeopleGroupIcon className="mb-[0.5px]" aria-hidden="true" />} aria-label="View our team" >content/docs/documentation-editors/markdown-guide.md (1)
222-230
: Fix the code block exampleThe nested code fences need fixing to show the correct example.
-````markdown -```javascript +```javascript function greet(name) { return `Hello, ${name}!`; } -``` -```` - -```` +```🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
230-230: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
components/docs/DocCopyEnhancer.tsx (2)
19-65
: React component looks good but isn't being usedThe
CopyButton
React component is well-implemented with proper accessibility attributes and animations, but it's not actually used anywhere in the component. The DOM manipulation approach below doesn't include these accessibility improvements.
103-109
: Missing accessibility attributes in DOM manipulationThe DOM-created buttons lack the accessibility improvements that exist in the unused React component above. The SVG icons don't have
aria-hidden="true"
and the button lacksaria-label
.const updateButtonState = (isCopied: boolean) => { copyStatesRef.current.set(preEl, isCopied); const icon = isCopied - ? '<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M5 13l4 4L19 7"/></svg>' - : '<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>'; + ? '<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M5 13l4 4L19 7"/></svg>' + : '<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M16 8v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8m4-4h6a2 2 0 0 1 2 2v2H4V6a2 2 0 0 1 2-2z"/></svg>'; button.innerHTML = `${icon}${isCopied ? "Copied!" : "Copy"}`; + button.setAttribute("aria-label", isCopied ? "Copied to clipboard" : "Copy code to clipboard"); };components/docs/CodeTabs.tsx (1)
79-84
: Add validation for missing label props.The component assumes all children have label props but doesn't validate this assumption.
Consider adding validation:
{React.Children.map(children, (child, idx) => { if (!React.isValidElement<CodeTabProps>(child)) return null; + if (!child.props.label) { + console.warn('CodeTab component missing required "label" prop'); + return null; + } const { label, disabled } = child.props;components/notification-generator/minecraftTextParser.tsx (3)
24-24
: Security risk with dangerouslySetInnerHTML.Using
dangerouslySetInnerHTML
with external content could allow XSS attacks if MiniMessage doesn't properly sanitize output.Consider validating or sanitizing the HTML output before rendering, or use a safer approach that doesn't rely on
dangerouslySetInnerHTML
.🧰 Tools
🪛 Biome (1.9.4)
[error] 24-24: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
33-33
: Fix regex control character warnings.Static analysis flags the control characters in the regex as problematic.
Escape the control characters properly:
- return input.replace(/\x00|\u0000|[\r\n\v\u2028\u2029]/g, ''); + return input.replace(/[\x00\u0000\r\n\v\u2028\u2029]/g, '');🧰 Tools
🪛 Biome (1.9.4)
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
88-94
: Obfuscated text handling needs fixing.The obfuscated text logic consumes the entire remaining string and returns early, preventing proper parsing of mixed formatting codes.
The current approach stops parsing when it hits obfuscated text, which breaks mixed formatting. Consider applying obfuscated styling without early return.
components/notification-generator/form/SoundTable.tsx (1)
58-58
:⚠️ Potential issueAdd proper typing for oramaDb
Using
any
skips TypeScript's safety checks. Import and use the proper Orama database type.- const [oramaDb, setOramaDb] = useState<any>(null); + const [oramaDb, setOramaDb] = useState<ReturnType<typeof create> | null>(null);app/docs/[...slug]/page.tsx (2)
65-85
:⚠️ Potential issueAdd path security validation
The slug parameter comes from user input and could contain path traversal attempts like
../
. Validate the slug before using it in file paths.const getDocBySlug = cache(async (slug: string[]): Promise<Doc | null> => { + // Validate slug to prevent path traversal + if (slug.some(segment => segment.includes('..') || segment.includes('/'))) { + console.error(`Invalid slug: ${slug.join('/')}`); + return null; + } const docsDirectory = path.join(process.cwd(), "content/docs"); const fullPath = path.join(docsDirectory, slug.join("/") + ".md");
52-58
: 🛠️ Refactor suggestionFix performance issue with spread in reducer
Using spread operators in reducers creates O(n²) complexity. Use push instead for better performance.
- return structure.reduce<{ title: string; path: string }[]>((acc, item) => { - if (item.children?.length) { - acc.push(...item.children); - } else { - acc.push({ title: item.title, path: item.path }); - } - return acc; - }, []); + const result: { title: string; path: string }[] = []; + structure.forEach((item) => { + if (item.children?.length) { + result.push(...item.children); + } else { + result.push({ title: item.title, path: item.path }); + } + }); + return result;components/docs/DocSearch.tsx (1)
234-316
: Missing keyboard navigation for search results.Users should be able to navigate results with arrow keys for better accessibility.
🧹 Nitpick comments (40)
components/notification-generator/BackgroundImage.tsx (1)
7-9
: Make background image decorative. Replace alt text with alt="" and add aria-hidden="true" so assistive tech skips it.components/icons/stop.tsx (1)
3-3
: Consider using named export for consistency.Other icon components in the project use named exports. Consider changing to
export function Stop
for consistency.components/icons/arrow-forward-hero.tsx (1)
5-11
: Add accessibility attributes to SVG icon.This SVG is decorative, so add
aria-hidden="true"
andfocusable="false"
to hide it from assistive tech.components/AnimatedHome.tsx (1)
11-18
: Use semanticmain
element for accessibility.Consider replacing
<motion.div>
with<motion.main>
to provide a proper page landmark.components/notification-generator/MiniMessageInfoBox.tsx (2)
1-1
: Use absolute import forAlertBox
.To match other components, import from
@/components/ui/AlertBox
.
6-6
: Use<strong>
instead of<b>
for semantics.Replace
<b>
with<strong>
around "MiniMessage" for better accessibility.components/notification-generator/SoundIndicator.tsx (1)
15-26
: Icon choice seems backwards for the use case.The SVG shows a muted speaker (with X) but this component displays when sound IS playing. Consider using a regular speaker icon instead.
<path fillRule="evenodd" - d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" + d="M10 3.5a1.5 1.5 0 00-1.5 1.5v10a1.5 1.5 0 003 0V5a1.5 1.5 0 00-1.5-1.5zM3.5 6A1.5 1.5 0 002 7.5v5A1.5 1.5 0 003.5 14h2.793l2.853 2.854A1 1 0 0011 16V4a1 1 0 00-1.854-.854L6.293 6H3.5z" clipRule="evenodd" />content/docs/contribute/guide.md (1)
67-67
: Consider standard punctuation.The ":>" emoticon might confuse readers. Consider using a standard emoji or exclamation mark instead.
-You have successfully made a contribution to this project. :> +You have successfully made a contribution to this project! 🎉🧰 Tools
🪛 LanguageTool
[uncategorized] ~67-~67: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>(UNLIKELY_OPENING_PUNCTUATION)
app/api/docs/search-index/route.ts (1)
23-49
: Verify the content directory path and improve excerpt cleaning.The search index generation has a few areas for improvement:
- The hardcoded
content/docs
path might not exist in all environments- The excerpt cleaning is basic and could miss markdown formatting
Consider this improvement for more robust excerpt cleaning:
- const excerpt = markdownContent - .replace(/[#*`_~]/g, '') - .replace(/\n/g, ' ') - .trim() - .substring(0, 150); + const excerpt = markdownContent + .replace(/```[\s\S]*?```/g, '') // Remove code blocks + .replace(/`[^`]+`/g, '') // Remove inline code + .replace(/[#*_~\[\]]/g, '') // Remove markdown symbols + .replace(/\s+/g, ' ') // Normalize whitespace + .trim() + .substring(0, 150);app/providers.tsx (1)
11-19
: Simplify the mount effect implementation.The mounting pattern correctly prevents hydration issues, but the
useCallback
wrapper forhandleMount
is unnecessary since it has no dependencies and only runs once.- const handleMount = useCallback(() => { - setMounted(true); - }, []); - - useEffect(() => { - handleMount(); - }, [handleMount]); + useEffect(() => { + setMounted(true); + }, []);components/OgImage.tsx (1)
10-37
: Consider improving the alt text for better accessibility.The metadata generation is well-structured, but the alt text could be more descriptive than just the title to better serve screen reader users.
- alt: title, + alt: subtitle ? `${title}: ${subtitle}` : `Open Graph image for ${title}`,app/prism-tomorrow.css (1)
5-6
: Consider using CSS custom properties for theme colors.The repeated background color
#181c23
could be defined as a CSS custom property to improve maintainability and theme consistency.+:root { + --prism-bg: #181c23; + --prism-bg-alt: #23272e; +} + code[class*="language-"], pre[class*="language-"] { color: #ccc; - background: #181c23 !important; + background: var(--prism-bg) !important;Also applies to: 30-30, 35-35, 42-42
components/SpeedInsights.tsx (1)
8-8
: Consider hydration safety for initial state.The initial state uses
canLoadAnalytics()
which might differ between server and client, potentially causing hydration mismatches.Consider initializing with
false
and updating in useEffect:-const [shouldLoad, setShouldLoad] = useState(canLoadAnalytics()); +const [shouldLoad, setShouldLoad] = useState(false); + +useEffect(() => { + setShouldLoad(canLoadAnalytics()); +}, []);components/notification-generator/NotificationCode.tsx (1)
12-41
: Consider simplifying animation complexity.The component has many nested motion elements with individual timing controls. This might impact performance and could feel overwhelming to users.
Consider grouping animations or using fewer motion wrappers:
-<motion.pre - className="overflow-x-auto rounded-md bg-gray-100 p-4 font-mono text-sm dark:bg-gray-900" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.3, delay: 0.1 }} -> - <motion.code - className="text-gray-800 dark:text-gray-200" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.3, delay: 0.2 }} - > - {yamlCode} - </motion.code> -</motion.pre> +<pre className="overflow-x-auto rounded-md bg-gray-100 p-4 font-mono text-sm dark:bg-gray-900"> + <code className="text-gray-800 dark:text-gray-200"> + {yamlCode} + </code> +</pre>components/header/hero/button/TransparentHeroButton.tsx (1)
8-11
: Consider using triggerOnce: true for better UX.The animation will retrigger every time the element enters/exits the viewport, which might be distracting for users scrolling back and forth.
const { ref, inView } = useInView({ - triggerOnce: false, + triggerOnce: true, threshold: 0.1, });components/notification-generator/ActionBar.tsx (1)
12-43
: Consider moving inline styles to CSS classes.The extensive inline styling works but could be cleaner as CSS classes or styled components for better maintainability.
+const actionBarStyles = { + container: "absolute left-1/2 pointer-events-none z-10", + text: "font-minecraft text-white text-2xl" +}; <div - className="absolute left-1/2" - style={{ - bottom: "12%", - transform: "translateX(-50%)", - // ... other styles - }} + className={actionBarStyles.container} + style={{ bottom: "12%", transform: "translateX(-50%)" }} >components/docs/DynamicCommandsTable.tsx (1)
18-20
: Consider making the API URL configurable.The hardcoded GitHub URL works but could be moved to an environment variable or config for easier maintenance.
components/header/ToolsDropdown.tsx (1)
55-60
: Focus management could be more robust.The setTimeout approach works but isn't ideal for focus management.
- setTimeout(() => dropdownRef.current?.querySelector("a")?.focus(), 0); + requestAnimationFrame(() => dropdownRef.current?.querySelector("a")?.focus());components/notification-generator/ChatMessage.tsx (1)
34-66
: Simplify the conditional rendering logic.The code duplicates styling between multiline and single line cases. Consider extracting the common styling.
+ const messageStyle = { + position: 'relative' as const, + zIndex: 1, + minHeight: 32, + lineHeight: '32px', + whiteSpace: 'pre-line' as const, + wordBreak: 'break-word' as const, + }; + const MessageDiv = ({ children, style = {} }: { children: React.ReactNode, style?: React.CSSProperties }) => ( + <div + className="font-minecraft px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" + style={{ ...messageStyle, ...style }} + > + {children} + </div> + ); {message.includes("\n") ? ( - <div style={{ position: 'relative', zIndex: 1, width: '100%' }}> + <div style={{ position: 'relative', zIndex: 1, width: '100%' }}> {message.split("\n").map((line, index) => ( - <div - key={index} - className="font-minecraft px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ - display: 'block', - minHeight: 32, - lineHeight: '32px', - whiteSpace: 'pre-line', - wordBreak: 'break-word', - }} - > + <MessageDiv key={index} style={{ display: 'block' }}> <MinecraftText text={line} /> - </div> + </MessageDiv> ))} </div> ) : ( - <div - className="font-minecraft px-4 text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]" - style={{ - position: 'relative', - zIndex: 1, - minHeight: 32, - lineHeight: '32px', - whiteSpace: 'pre-line', - wordBreak: 'break-word', - }} - > + <MessageDiv> <MinecraftText text={message} /> - </div> + </MessageDiv> )}components/docs/ReadingTime.tsx (1)
15-18
: Add input validation for edge cases.The calculation works well but could handle empty content more gracefully.
const calculateReadingTime = (text: string, wordsPerMinute: number): number => { + if (!text || text.trim().length === 0) return 1; const words = text.trim().split(/\s+/).length; return Math.ceil(words / wordsPerMinute); };
components/docs/DocHeader.tsx (1)
12-50
: Consider reusing existing animation variants.The animation variants are well-crafted but duplicate similar ones in
AnimationUtils.tsx
. Consider importing from the centralized animation utilities to maintain consistency.-export const fadeInUp = { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { - type: "spring", - stiffness: 100, - damping: 15, - mass: 0.8 - } - } -}; +import { fadeInUp, staggerContainer } from "@/components/animations/AnimationUtils";content/docs/eternalcombat/installation.md (1)
40-40
: Fix grammar in heading.Change "Backup" to "Back up" as this is the verb form.
-1. **Backup Your Configuration** +1. **Back up Your Configuration**🧰 Tools
🪛 LanguageTool
[grammar] ~40-~40: The word ‘Backup’ is a noun. Do you mean the verb “Back up”?
Context: ...🔄 Upgrading ### Upgrade Process 1. Backup Your Configuration ```bash cp ...(SENT_START_BACKUP)
components/ui/AlertBox.tsx (1)
41-114
: Consider refactoring the repetitive style patterns.The
alertStyles
object has a lot of repeated patterns. You could create a helper function to generate styles for each type, reducing code duplication.+const createAlertStyle = (color: string, role: string) => ({ + container: `bg-${color}-500/10 border border-${color}-500/20 dark:bg-${color}-500/10 dark:border-${color}-500/20`, + icon: `text-${color}-500 dark:text-${color}-400`, + text: `text-${color}-800 dark:text-${color}-200`, + title: `text-${color}-900 dark:text-${color}-100`, + role, +});app/notification-generator/page.tsx (2)
30-85
: Consider breaking down the YAML generation logic.The
generateYaml
function handles many different cases and could be split into smaller, focused functions for better maintainability.+const formatChatSection = (chat: string) => { + if (!chat) return []; + if (chat.includes("\n")) { + const lines = chat.split("\n"); + return ["chat:", ...lines.map(line => ` - "${line}"`)]; + } + return [`chat: "${chat}"`]; +}; +const formatTimesSection = (fadeIn: string, stay: string, fadeOut: string) => { + if (!fadeIn && !stay && !fadeOut) return []; + const times = `${fadeIn || "0s"} ${stay || "0s"} ${fadeOut || "0s"}`; + return [`times: "${times}"`]; +};
108-209
: Consider creating reusable animation components.There are many similar motion.div components with repeated animation configurations. You could create reusable animated wrapper components.
+const AnimatedCard = ({ children, delay = 0, direction = "up", ...props }) => ( + <motion.div + initial={{ opacity: 0, y: direction === "up" ? 20 : -20 }} + animate={{ opacity: 1, y: 0 }} + transition={{ duration: 0.4, delay }} + {...props} + > + {children} + </motion.div> +);components/notification-generator/form/validation.ts (1)
15-18
: Consider making sound validation more flexible.The regex
^[A-Z_]+(\s+[A-Z_]+)?$
might be too restrictive. Minecraft sounds can have different formats and namespaces.- if (value && !/^[A-Z_]+(\s+[A-Z_]+)?$/.test(value)) { + if (value && !/^[a-zA-Z0-9_:]+(\s+[a-zA-Z0-9_:]+)*$/.test(value)) { return "Invalid sound format"; }components/team/Team.tsx (1)
190-194
: Clean up unused motion propertiesThe motion.div has some unnecessary style properties that aren't needed with the new animation approach.
<motion.div className="text-center text-gray-500 dark:text-gray-400" variants={cardVariants} initial="hidden" animate="visible" - style={{ background: "transparent", boxShadow: "none", border: "none", padding: 0, cursor: "pointer" }} + style={{ cursor: "pointer" }} >components/CookiePreferencesMenu.tsx (1)
127-143
: Consider user feedback for the Save buttonThe Save button closes the modal but doesn't provide feedback about what was saved. Users might be confused about whether their preferences were actually saved.
<button onClick={() => setIsOpen(false)} className="inline-flex flex-1 items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700" > - Save + Save Preferences </button>Consider adding a brief "Settings saved!" toast message for better user feedback.
app/docs/layout.tsx (2)
74-74
: Replace Polish comment with English.The comment should be in English to maintain code consistency and readability for all team members.
- {/* Przyciski Next/Previous będą renderowane w page.tsx */} + {/* Next/Previous buttons will be rendered in page.tsx */}
66-66
: Move inline style to CSS class.The inline
minHeight
style should be moved to Tailwind classes for better maintainability.- <AnimatedSection animationType="fadeUp" className="w-full" style={{ minHeight: '60vh' }}> + <AnimatedSection animationType="fadeUp" className="w-full min-h-[60vh]">components/notification-generator/hooks.ts (1)
40-42
: Consider smoother animation steps.The fixed 0.1 opacity increment might cause jerky animations for short fade durations. Consider using dynamic steps based on duration.
- return prev + 0.1; + return Math.min(prev + (1 / (fadeIn * 10)), 1);components/CookieConsentModal.tsx (1)
43-48
: Add aria-label for better accessibility.The close button should have an accessible label for screen readers.
<button onClick={() => setIsOpen(false)} className="ml-4 text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" + aria-label="Close cookie consent modal" >
components/ui/tabs.tsx (2)
63-63
: Make the key more uniqueUsing
${label}-${idx}
could cause React key warnings if you have duplicate labels. Consider using a more unique approach.- key={`${label}-${idx}`} + key={`tab-${idx}`}
110-114
: Remove unnecessary memoizationThe
TabItem
component just returns its children without any processing. The memoization adds overhead without benefit.-export const TabItem = React.memo(function TabItem({ children }: TabItemProps) { - return <>{children}</>; -}); - -TabItem.displayName = "TabItem"; +export const TabItem: React.FC<TabItemProps> = ({ children }) => { + return <>{children}</>; +};components/notification-generator/form/SoundTable.tsx (1)
41-386
: Consider splitting this large componentThis component handles search, sorting, pagination, and playback all in one place. Breaking it into smaller components would make it easier to maintain.
Consider extracting:
- SearchBar component (lines 257-278)
- SoundTableHeader component (lines 282-298)
- PaginationControls component (lines 356-383)
components/animations/AnimationUtils.tsx (1)
66-76
: Optimize stagger timingThe stagger delay of 0.15s might feel slow for user interaction. Consider reducing it to 0.1s for snappier animations.
export const staggerContainer: Variants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { - staggerChildren: 0.15, + staggerChildren: 0.1, ease: "easeInOut", duration: 0.5 } } };components/animations/AnimatedElement.tsx (1)
72-114
: Consider dynamic tag renderingThe large switch statement could be simplified using dynamic rendering.
-switch (as) { - case "div": - return <motion.div {...commonProps}>{children}</motion.div>; - case "section": - return <motion.section {...commonProps}>{children}</motion.section>; - // ... all other cases - default: - return <motion.div {...commonProps}>{children}</motion.div>; -} +const MotionComponent = motion[as] || motion.div; +return <MotionComponent {...commonProps}>{children}</MotionComponent>;components/notification-generator/form/SliderField.tsx (1)
71-72
: Consider making gradient colors customizableThe gradient colors are hardcoded. You could accept them as optional props for more flexibility.
interface SliderFieldProps { label: string; name: string; value: string; onChange: (name: string, value: string) => void; min: number; max: number; step: number; error?: string; + activeColor?: string; + inactiveColor?: string; }components/ui/Dropdown.tsx (1)
61-61
: Remove inline stylesThe inline styles for outline and boxShadow could be handled with Tailwind classes for consistency.
-style={{ outline: "none", boxShadow: "none" }} +className="... focus:outline-none focus:ring-0"Also applies to: 103-103
components/docs/DocSearch.tsx (1)
127-127
: Replaceany
with proper type for better type safety.Using
any
reduces type safety benefits. Consider using the proper Orama type.- const [oramaDb, setOramaDb] = useState<any>(null); + const [oramaDb, setOramaDb] = useState<Awaited<ReturnType<typeof create>> | null>(null);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
bun.lock
is excluded by!**/*.lock
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
public/fonts/Minecraftia-Regular.ttf
is excluded by!**/*.ttf
public/mc-bg.png
is excluded by!**/*.png
📒 Files selected for processing (107)
.eslintrc.json
(1 hunks)app/api/docs/search-index/route.ts
(1 hunks)app/api/og/route.tsx
(1 hunks)app/api/team/route.ts
(1 hunks)app/docs/[...slug]/page.tsx
(1 hunks)app/docs/layout.tsx
(1 hunks)app/docs/page.tsx
(1 hunks)app/globals.css
(2 hunks)app/layout.tsx
(2 hunks)app/not-found.tsx
(1 hunks)app/notification-generator/layout.tsx
(1 hunks)app/notification-generator/page.tsx
(1 hunks)app/page.tsx
(1 hunks)app/prism-languages.ts
(1 hunks)app/prism-tomorrow.css
(1 hunks)app/privacy-policy/page.tsx
(1 hunks)app/projects/page.tsx
(1 hunks)app/providers.tsx
(1 hunks)app/team/page.tsx
(1 hunks)components/Analytics.tsx
(1 hunks)components/AnimatedHome.tsx
(1 hunks)components/CookieConsentModal.tsx
(1 hunks)components/CookiePreferencesMenu.tsx
(1 hunks)components/OgImage.tsx
(1 hunks)components/SectionTitle.tsx
(1 hunks)components/SpeedInsights.tsx
(1 hunks)components/about/About.tsx
(1 hunks)components/animations/AnimatedContainer.tsx
(1 hunks)components/animations/AnimatedElement.tsx
(1 hunks)components/animations/AnimatedSection.tsx
(1 hunks)components/animations/AnimationUtils.tsx
(1 hunks)components/animations/index.ts
(1 hunks)components/docs/AnimatedHeading.tsx
(1 hunks)components/docs/AnimatedLayout.tsx
(1 hunks)components/docs/CodeBlock.tsx
(1 hunks)components/docs/CodeTabs.tsx
(1 hunks)components/docs/DocCopyEnhancer.tsx
(1 hunks)components/docs/DocHeader.tsx
(1 hunks)components/docs/DocSearch.tsx
(1 hunks)components/docs/DocSidebar.tsx
(1 hunks)components/docs/DynamicCommandsTable.tsx
(1 hunks)components/docs/DynamicFeaturesTable.tsx
(1 hunks)components/docs/EditOnGitHub.tsx
(1 hunks)components/docs/ErrorBoundary.tsx
(1 hunks)components/docs/Inline.tsx
(1 hunks)components/docs/ReadingTime.tsx
(1 hunks)components/docs/ShortLink.tsx
(1 hunks)components/docs/sidebar-structure.ts
(1 hunks)components/faq/Faq.tsx
(2 hunks)components/features/Features.tsx
(1 hunks)components/footer/Footer.tsx
(1 hunks)components/header/Navbar.tsx
(2 hunks)components/header/ThemeSwitchButton.tsx
(1 hunks)components/header/ToolsDropdown.tsx
(1 hunks)components/header/hero/Hero.tsx
(1 hunks)components/header/hero/button/BackgroundHeroButton.tsx
(1 hunks)components/header/hero/button/TransparentHeroButton.tsx
(1 hunks)components/header/hero/terminal/TerminalTab.tsx
(1 hunks)components/header/polygon/PolygonLeft.tsx
(0 hunks)components/header/polygon/PolygonRight.tsx
(0 hunks)components/icons/arrow-back.tsx
(1 hunks)components/icons/arrow-down.tsx
(1 hunks)components/icons/arrow-forward-hero.tsx
(1 hunks)components/icons/arrow-forward.tsx
(1 hunks)components/icons/close.tsx
(1 hunks)components/icons/hamburger.tsx
(1 hunks)components/icons/play.tsx
(1 hunks)components/icons/stop.tsx
(1 hunks)components/notification-generator/ActionBar.tsx
(1 hunks)components/notification-generator/BackgroundImage.tsx
(1 hunks)components/notification-generator/ChatMessage.module.css
(1 hunks)components/notification-generator/ChatMessage.tsx
(1 hunks)components/notification-generator/MinecraftPreview.tsx
(1 hunks)components/notification-generator/MiniMessageInfoBox.tsx
(1 hunks)components/notification-generator/NotificationCode.tsx
(1 hunks)components/notification-generator/NotificationForm.tsx
(1 hunks)components/notification-generator/SoundIndicator.tsx
(1 hunks)components/notification-generator/SoundInfoBox.tsx
(1 hunks)components/notification-generator/Title.tsx
(1 hunks)components/notification-generator/form/ActionBarTab.tsx
(1 hunks)components/notification-generator/form/AdvancedTab.tsx
(1 hunks)components/notification-generator/form/ChatTab.tsx
(1 hunks)components/notification-generator/form/FormField.tsx
(1 hunks)components/notification-generator/form/SliderField.tsx
(1 hunks)components/notification-generator/form/SoundTab.tsx
(1 hunks)components/notification-generator/form/SoundTable.tsx
(1 hunks)components/notification-generator/form/Tab.tsx
(1 hunks)components/notification-generator/form/TitleTab.tsx
(1 hunks)components/notification-generator/form/constants.ts
(1 hunks)components/notification-generator/form/validation.ts
(1 hunks)components/notification-generator/hooks.ts
(1 hunks)components/notification-generator/minecraft-font.css
(1 hunks)components/notification-generator/minecraftTextParser.tsx
(1 hunks)components/notification-generator/types.ts
(1 hunks)components/projects/ProjectButton.tsx
(1 hunks)components/projects/ProjectItem.tsx
(1 hunks)components/team/Team.tsx
(3 hunks)components/ui/AlertBox.tsx
(1 hunks)components/ui/Dropdown.tsx
(1 hunks)components/ui/button.tsx
(1 hunks)components/ui/tab.tsx
(1 hunks)components/ui/tabs.tsx
(1 hunks)components/ui/tooltip.tsx
(1 hunks)content/docs/contribute/guide.md
(1 hunks)content/docs/documentation-editors/markdown-guide.md
(1 hunks)content/docs/eternalcombat/features.md
(1 hunks)content/docs/eternalcombat/installation.md
(1 hunks)
⛔ Files not processed due to max files limit (23)
- content/docs/eternalcombat/introduction.md
- content/docs/eternalcombat/using-api.md
- content/docs/eternalcore/faq.md
- content/docs/eternalcore/features.md
- content/docs/eternalcore/homes.md
- content/docs/eternalcore/installation.md
- content/docs/eternalcore/introduction.md
- content/docs/eternalcore/notifications.md
- content/docs/eternalcore/placeholders.md
- content/docs/eternalcore/using-api.md
- hooks/useClickOutside.ts
- hooks/useCookieConsent.ts
- hooks/useDebounce.ts
- lib/cookie-utils.ts
- lib/mdx-config.mjs
- lib/mdx.tsx
- lib/og-utils.ts
- lib/utils.ts
- next-sitemap.config.js
- next.config.mjs
- package.json
- reset.d.ts
- tailwind.config.ts
💤 Files with no reviewable changes (2)
- components/header/polygon/PolygonRight.tsx
- components/header/polygon/PolygonLeft.tsx
🧰 Additional context used
🧬 Code Graph Analysis (42)
components/notification-generator/SoundInfoBox.tsx (1)
components/ui/AlertBox.tsx (1)
AlertBox
(140-187)
app/docs/page.tsx (4)
app/layout.tsx (2)
dynamic
(18-18)revalidate
(19-19)app/docs/[...slug]/page.tsx (2)
dynamic
(22-22)revalidate
(23-23)app/page.tsx (1)
dynamic
(5-5)app/projects/page.tsx (1)
dynamic
(6-6)
components/ui/tooltip.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/OgImage.tsx (1)
lib/og-utils.ts (1)
generateOgImageUrl
(2-28)
components/notification-generator/ChatMessage.tsx (1)
components/notification-generator/minecraftTextParser.tsx (1)
MinecraftText
(8-29)
components/notification-generator/form/AdvancedTab.tsx (1)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)
components/notification-generator/MinecraftPreview.tsx (2)
components/notification-generator/types.ts (1)
MinecraftPreviewProps
(16-18)components/notification-generator/hooks.ts (2)
useTitleAnimation
(4-72)useSoundEffect
(74-93)
components/docs/Inline.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/Analytics.tsx (1)
lib/cookie-utils.ts (1)
canLoadAnalytics
(44-47)
components/docs/EditOnGitHub.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/icons/github.tsx (1)
GitHubIcon
(3-18)
components/notification-generator/form/TitleTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(23-311)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/notification-generator/MiniMessageInfoBox.tsx (1)
components/ui/AlertBox.tsx (1)
AlertBox
(140-187)
components/docs/ShortLink.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/header/ToolsDropdown.tsx (1)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)
components/notification-generator/form/ChatTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(23-311)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/notification-generator/ActionBar.tsx (1)
components/notification-generator/minecraftTextParser.tsx (1)
MinecraftText
(8-29)
app/notification-generator/layout.tsx (3)
app/layout.tsx (1)
metadata
(47-108)app/docs/layout.tsx (1)
metadata
(19-41)app/page.tsx (1)
metadata
(8-19)
components/notification-generator/Title.tsx (1)
components/notification-generator/minecraftTextParser.tsx (1)
MinecraftText
(8-29)
components/notification-generator/form/ActionBarTab.tsx (3)
components/notification-generator/types.ts (2)
NotificationConfig
(1-14)FieldType
(21-21)components/notification-generator/form/FormField.tsx (1)
FormField
(23-311)components/notification-generator/MiniMessageInfoBox.tsx (1)
MiniMessageInfoBox
(3-18)
components/header/hero/button/TransparentHeroButton.tsx (1)
components/icons/arrow-forward-hero.tsx (1)
ArrowForwardHeroIcon
(3-18)
components/notification-generator/form/Tab.tsx (1)
components/notification-generator/types.ts (1)
TabType
(20-20)
components/notification-generator/hooks.ts (1)
components/notification-generator/types.ts (1)
NotificationConfig
(1-14)
components/ui/AlertBox.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/docs/DocCopyEnhancer.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/ui/tabs.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/ui/tab.tsx (1)
Tab
(74-74)
components/docs/ReadingTime.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/docs/DocSidebar.tsx (2)
components/docs/sidebar-structure.ts (2)
DocItem
(1-5)docsStructure
(7-56)lib/utils.ts (1)
cn
(9-11)
components/SpeedInsights.tsx (1)
lib/cookie-utils.ts (1)
canLoadAnalytics
(44-47)
components/ui/tab.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/ui/button.tsx (1)
Button
(192-192)
components/docs/DocHeader.tsx (1)
components/animations/AnimationUtils.tsx (2)
fadeInUp
(26-33)staggerContainer
(66-76)
app/docs/[...slug]/page.tsx (9)
app/layout.tsx (2)
dynamic
(18-18)revalidate
(19-19)app/docs/page.tsx (2)
dynamic
(4-4)revalidate
(5-5)components/docs/sidebar-structure.ts (1)
docsStructure
(7-56)components/docs/DocHeader.tsx (1)
DocHeader
(52-101)components/docs/ReadingTime.tsx (1)
ReadingTime
(20-42)components/docs/ShortLink.tsx (1)
ShortLink
(13-83)components/docs/EditOnGitHub.tsx (1)
EditOnGitHub
(11-32)components/docs/ErrorBoundary.tsx (1)
ErrorBoundary
(14-54)lib/mdx.tsx (1)
components
(11-34)
components/notification-generator/form/validation.ts (1)
components/notification-generator/types.ts (1)
FieldType
(21-21)
components/docs/AnimatedHeading.tsx (1)
components/docs/DocHeader.tsx (1)
fadeDownScale
(26-39)
components/ui/button.tsx (1)
lib/utils.ts (1)
cn
(9-11)
components/notification-generator/form/FormField.tsx (2)
components/notification-generator/types.ts (1)
FieldType
(21-21)components/ui/button.tsx (1)
Button
(192-192)
components/docs/CodeTabs.tsx (2)
lib/utils.ts (1)
cn
(9-11)components/notification-generator/form/Tab.tsx (1)
Tab
(13-45)
components/animations/AnimatedElement.tsx (1)
components/animations/AnimationUtils.tsx (6)
fadeInUp
(26-33)fadeInDown
(36-43)fadeInLeft
(46-53)fadeInRight
(56-63)scaleAnimation
(85-95)fadeIn
(14-23)
components/ui/Dropdown.tsx (1)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)
components/footer/Footer.tsx (4)
components/icons/round-tiktok.tsx (1)
TikTokIcon
(3-18)components/icons/youtube.tsx (1)
YouTubeIcon
(3-18)components/icons/github.tsx (1)
GitHubIcon
(3-18)components/icons/discord.tsx (1)
DiscordIcon
(3-18)
components/animations/AnimationUtils.tsx (1)
components/docs/DocHeader.tsx (2)
fadeInUp
(12-24)staggerContainer
(41-50)
components/animations/AnimatedSection.tsx (2)
components/animations/AnimationUtils.tsx (5)
fadeInUp
(26-33)fadeInDown
(36-43)fadeInLeft
(46-53)fadeInRight
(56-63)fadeIn
(14-23)components/docs/DocHeader.tsx (1)
fadeInUp
(12-24)
components/header/Navbar.tsx (4)
components/icons/arrow-down.tsx (1)
ArrowDown
(5-24)components/icons/hamburger.tsx (1)
Hamburger
(5-24)components/icons/new-window.tsx (1)
NewWindow
(3-20)components/header/ToolsDropdown.tsx (1)
ToolsDropdown
(8-101)
🪛 LanguageTool
content/docs/contribute/guide.md
[uncategorized] ~67-~67: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>
(UNLIKELY_OPENING_PUNCTUATION)
content/docs/eternalcombat/installation.md
[grammar] ~40-~40: The word ‘Backup’ is a noun. Do you mean the verb “Back up”?
Context: ...🔄 Upgrading ### Upgrade Process 1. Backup Your Configuration ```bash cp ...
(SENT_START_BACKUP)
content/docs/documentation-editors/markdown-guide.md
[uncategorized] ~19-~19: Loose punctuation mark.
Context: ...Available frontmatter fields: - title
: The page title (required) - `descriptio...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.17.2)
content/docs/documentation-editors/markdown-guide.md
230-230: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🪛 Biome (1.9.4)
components/notification-generator/form/SoundTab.tsx
[error] 177-177: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 180-180: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 195-195: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
[error] 198-198: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
components/notification-generator/minecraftTextParser.tsx
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 33-33: Unexpected control character in a regular expression.
Control characters are unusual and potentially incorrect inputs, so they are disallowed.
(lint/suspicious/noControlCharactersInRegex)
[error] 24-24: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🔇 Additional comments (159)
components/SectionTitle.tsx (3)
3-7
: Good interface structure!The
SectionTitleProps
interface is well-defined with clear types and the optionalid
property adds flexibility for navigation purposes.
15-18
: Clean conditional id implementation.The conditional
id
attribute works correctly - React will omit the attribute whenid
is undefined, keeping the DOM clean.
25-28
: Nice accessibility improvement!The
aria-label
provides helpful context for screen readers by connecting the description to its title. This follows good accessibility practices..eslintrc.json (1)
2-2
: Use of core web vitals preset looks good. Good to see we’re using the focused Next.js rules.components/icons/arrow-back.tsx (1)
1-19
: Nice icon component. Clean implementation with props spread.components/icons/arrow-down.tsx (1)
1-24
: ArrowDown icon looks good. Straightforward SVG component.components/notification-generator/BackgroundImage.tsx (1)
4-14
: Good memoized background component. Using React.memo and Next/Image for performance is smart.components/header/hero/terminal/TerminalTab.tsx (1)
34-34
: Tab label updated to match branding. Removing "Terminal" simplifies the title nicely.app/api/team/route.ts (1)
3-3
: Good cleanup!Removing the redundant comment makes the code cleaner since
3600
clearly represents one hour in seconds.components/notification-generator/SoundInfoBox.tsx (1)
1-11
: Clean and simple component!Nice straightforward implementation that provides clear user guidance for the sound selection feature.
app/team/page.tsx (3)
3-4
: Good additions!Adding the Hero component and OG metadata generation follows the consistent pattern used across other pages.
8-11
: Nice metadata enhancement!The OG image metadata will improve social sharing previews with proper title and subtitle.
17-17
: Perfect placement!The Hero component is properly positioned above the Team component in the layout.
components/icons/play.tsx (1)
1-18
: Well-crafted icon component!Good implementation with proper props handling and
currentColor
for theming support. The SVG structure is clean and follows React best practices.components/projects/ProjectItem.tsx (1)
79-81
: Good image optimization practices!The priority loading for the first two items and quality settings follow Next.js best practices for performance.
app/projects/page.tsx (3)
3-4
: Good additions for improved UX and SEO.Adding the Hero component and OG metadata generation enhances both user experience and social sharing.
12-15
: Proper metadata implementation.The OG image metadata generation follows the established pattern and improves social media previews.
21-21
: Hero component placement looks good.Positioning the Hero component above the main content is the right approach for visual hierarchy.
components/icons/close.tsx (1)
3-18
: Well-implemented icon component.Clean SVG structure with proper TypeScript typing and flexible prop handling. The close icon is clearly recognizable.
components/notification-generator/form/constants.ts (1)
2-14
: Looks good.Constant provides clear options for sound categories.
components/notification-generator/ChatMessage.module.css (1)
1-20
: Styles look good.Scrollbar styling is consistent and cross-browser.
components/docs/Inline.tsx (1)
1-24
: Clean implementation for inline styling!The component is well-structured with proper TypeScript interfaces, comprehensive light/dark theme support, and good extensibility through the optional className prop.
components/projects/ProjectButton.tsx (1)
7-13
: Good refactor to use the standardized Button component!The transition from framer-motion to the custom Button component aligns well with the UI standardization efforts. The implementation is clean and maintains all necessary functionality.
app/not-found.tsx (1)
4-33
: Well-designed 404 page with good UX!The component provides a clear, accessible error page with helpful navigation options. The responsive design and dark mode support are implemented correctly.
components/icons/hamburger.tsx (1)
1-24
: Simple and effective hamburger icon component!The implementation is clean with proper TypeScript typing and flexible styling through className. The SVG structure follows standard practices and will work well across different themes.
app/notification-generator/layout.tsx (2)
1-24
: Comprehensive metadata setup looks good!The SEO and social media metadata is well-structured with proper Open Graph and Twitter card configurations. The keywords and descriptions are relevant to the notification generator tool.
26-36
: Simple and effective layout component.The layout provides appropriate spacing and constraints for the notification generator page. The styling classes create good visual hierarchy.
app/docs/page.tsx (2)
4-5
: Good use of static generation with revalidation.The static generation settings match other pages in the project and provide appropriate caching for a redirect page.
7-9
: Clean redirect implementation.The redirect to the introduction page provides a good default entry point for the documentation section.
app/prism-languages.ts (2)
1-31
: Excellent language coverage for documentation.The comprehensive set of Prism language imports covers all major programming languages and tools likely needed for documentation. The organized import groups make the code easy to maintain.
33-38
: Well-crafted TypeScript language definition.The TypeScript customization properly extends JavaScript and includes comprehensive keyword and builtin type patterns that will provide accurate syntax highlighting.
components/animations/index.ts (1)
1-4
: Clean barrel export pattern.This index file properly centralizes the animation components and utilities, making them easy to import throughout the codebase.
components/docs/AnimatedLayout.tsx (2)
12-32
: Well-structured animation layout with good timing.The nested motion divs create a nice layered animation effect. The spring parameters and delay provide smooth, natural-feeling transitions for documentation content.
6-8
: Clean TypeScript interface.The props interface is simple and properly typed for the component's needs.
components/notification-generator/SoundIndicator.tsx (1)
8-10
: Clean conditional rendering logic.Good use of early return and React.memo for performance optimization.
content/docs/contribute/guide.md (1)
1-67
: Excellent contribution guide.Clear step-by-step instructions that are beginner-friendly. Good structure and practical examples throughout.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~67-~67: Loose punctuation mark.
Context: ...ly made a contribution to this project. :>(UNLIKELY_OPENING_PUNCTUATION)
components/docs/ErrorBoundary.tsx (2)
23-29
: Proper error boundary implementation.Correct use of both lifecycle methods for catching and logging errors.
34-48
: User-friendly error UI design.Good use of progressive disclosure with collapsible technical details. Clear messaging and proper dark mode support.
components/header/ThemeSwitchButton.tsx (2)
12-14
: Good performance optimization.Using useCallback prevents unnecessary re-renders when the component updates.
26-29
: Nice accessibility improvements.Adding aria-hidden to icons and dynamic aria-label makes this more screen reader friendly.
app/api/docs/search-index/route.ts (2)
6-21
: The recursive file search looks good and is safe.The function properly handles directory traversal and file filtering for markdown files.
51-62
: Good error handling in the API route.The try-catch structure properly handles errors and returns appropriate HTTP status codes.
components/icons/arrow-forward.tsx (1)
3-18
: The spread props issue has been fixed.The component now properly spreads
{...props}
to the SVG element, addressing the previous review concern. The implementation looks good with proper TypeScript typing.components/docs/EditOnGitHub.tsx (3)
1-9
: Clean imports and well-defined interface.The TypeScript interface is properly defined with required and optional props.
15-15
: Good security practice with URL encoding.Using
encodeURIComponent
for the file path prevents potential security issues with special characters.
17-32
: Excellent accessibility and styling implementation.The component includes proper ARIA attributes, security attributes for external links, and good styling with dark mode support.
components/Analytics.tsx (4)
7-8
: Good initialization with consent checking.The component properly initializes state based on current consent status.
10-12
: Proper use of useCallback for performance.The callback is memoized to prevent unnecessary re-renders.
14-24
: Comprehensive event listening for consent changes.The component listens to both storage events and custom consent events, ensuring it responds to consent changes from any source.
26-29
: Privacy-compliant conditional rendering.The component only loads analytics when consent is given, which is the correct approach for privacy compliance.
components/notification-generator/form/ActionBarTab.tsx (1)
1-23
: Clean and well-structured component implementation.The component follows React best practices with proper TypeScript typing and clear separation of concerns. The interface correctly uses shared types and the component renders appropriate child components for the action bar functionality.
app/providers.tsx (1)
25-34
: Good theme provider configuration.The new theme provider props properly enable system theme detection and disable transitions to prevent flash effects. This integrates well with the theming system.
components/notification-generator/Title.tsx (1)
11-42
: Well-implemented component with good performance optimizations.The component effectively uses
React.memo
for performance and includes proper conditional rendering. The integration withMinecraftText
follows established patterns, and the styling approach with absolute positioning and opacity transitions works well for the Minecraft notification display.components/notification-generator/form/TitleTab.tsx (3)
7-11
: Well-designed interface with proper error handling.The props interface correctly extends shared types and includes error handling support, enabling proper validation feedback in the form.
31-61
: Smart layout and configuration for timing fields.The grid layout for timing fields is visually clean, and disabling editor buttons for these fields makes sense since they expect time format strings (e.g., "1s") rather than rich text content.
13-64
: Comprehensive form tab implementation.The component provides a complete interface for title configuration with proper separation between text content fields and timing parameters. The integration with validation and user guidance components creates a good user experience.
components/notification-generator/form/AdvancedTab.tsx (1)
1-30
: LGTM! Clean and accessible checkbox implementation.The component correctly handles the titleHide boolean field with proper accessibility attributes and dark mode styling.
components/OgImage.tsx (1)
39-42
: Component returns null - confirm this is intentional.The component renders nothing but serves as a metadata utility. This pattern works but consider adding a comment explaining the purpose.
+// This component is used for metadata generation only and doesn't render any UI export default function OgImage({ title, subtitle, image }: OgImageProps) { return null; }
components/docs/CodeBlock.tsx (1)
1-24
: Excellent code block implementation with performance and accessibility in mind.The use of memo, proper prop inheritance, and comprehensive accessibility attributes make this a solid component for the documentation system.
components/notification-generator/form/ChatTab.tsx (1)
1-25
: Clean and well-structured form tab component.The integration with FormField and inclusion of helpful guidance through MiniMessageInfoBox creates a good user experience for chat message input.
app/page.tsx (3)
1-3
: Clean import organization.The imports are well-organized and follow Next.js conventions. The addition of metadata types and OG image generation shows good SEO planning.
8-19
: Well-structured metadata implementation.The metadata configuration includes proper SEO elements with canonical URL and Open Graph image generation. This will improve social sharing and search engine visibility.
21-23
: Good component abstraction.Moving to a single AnimatedHome component simplifies the page structure while maintaining functionality. This follows the single responsibility principle nicely.
app/api/og/route.tsx (2)
5-5
: Good choice for edge runtime.Using edge runtime for image generation improves performance and reduces cold start times.
105-108
: Good error handling implementation.The error handling properly logs issues and returns appropriate HTTP status codes.
components/docs/sidebar-structure.ts (2)
1-5
: Well-designed interface.The DocItem interface is clean and properly typed. The optional children property makes it flexible for nested navigation.
7-56
: Excellent documentation organization.The structure is logically organized by product areas and follows consistent URL patterns. This will make navigation intuitive for users.
app/prism-tomorrow.css (2)
3-24
: Comprehensive base styling.The base styles cover all essential properties with proper browser compatibility and good defaults for code presentation.
45-117
: Well-organized token styling.The token colors create a cohesive dark theme with good contrast. The color choices help distinguish different code elements effectively.
components/SpeedInsights.tsx (1)
14-24
: Well-implemented event listener management.Good use of proper cleanup functions and memoized callbacks. The dual event listeners for both storage changes and custom consent events ensure the component stays synchronized.
components/notification-generator/NotificationCode.tsx (1)
63-91
: Good use of staggered animations for list items.The step-by-step instructions with individual animation delays create a nice progressive reveal effect. The content is clear and helpful.
components/header/hero/button/TransparentHeroButton.tsx (1)
15-32
: Excellent refactoring addressing previous review feedback.The animation controls are now properly connected, and the component uses the new Button component with improved styling and accessibility. The hover effects and icon usage look great.
app/privacy-policy/page.tsx (3)
12-19
: Well-structured content organization.Good use of semantic HTML with proper heading hierarchy and clear prose styling. The content clearly explains the organization's identity and purpose.
89-96
: Proper external link security.Good use of security attributes on external links to prevent potential security issues.
131-159
: Excellent use of AlertBox for contact information.The contact details are well-presented using the AlertBox component, making them easily discoverable. Email and Discord links are properly formatted with good hover states.
components/notification-generator/minecraft-font.css (1)
1-23
: Well-structured font implementation!The font face definition and CSS classes are properly set up with good performance optimizations like
font-display: swap
and comprehensive unicode range coverage.components/notification-generator/ActionBar.tsx (1)
8-9
: Good performance optimization and null handling!Using
React.memo
and early return for empty messages is a smart approach.components/docs/DynamicCommandsTable.tsx (1)
17-28
: Solid data fetching with good error handling!The fetch logic properly handles errors and loading states, making the component reliable.
components/ui/tooltip.tsx (2)
20-31
: Nice hover delay and cleanup handling!The 500ms delay prevents accidental tooltip triggers, and the timeout cleanup prevents memory leaks.
44-63
: Smooth animations with proper accessibility!The Framer Motion animations are subtle and the ARIA attributes make the tooltip accessible to screen readers.
components/header/ToolsDropdown.tsx (4)
14-31
: Good event handling pattern!The click outside detection is well implemented with proper cleanup in the useEffect.
34-44
: Escape key handling looks solid.Clean implementation of keyboard event handling with proper listener management.
48-71
: Excellent accessibility implementation!Great use of ARIA attributes and keyboard navigation support.
72-98
: Nice animation and menu structure.The framer-motion implementation is clean and the menu structure follows accessibility best practices.
app/globals.css (4)
1-1
: Good modular approach with CSS imports.Clean separation of Prism theme from main styles.
6-139
: Comprehensive syntax highlighting styles.The Prism integration looks well-structured with proper token colors and line number support.
210-222
: Nice animation implementation.The fadein animation with cubic-bezier timing looks smooth and well-crafted.
228-237
: Toast icon positioning fixes look good.Proper handling of toast notification icon layout with flexbox.
components/notification-generator/MinecraftPreview.tsx (3)
1-16
: Great component structure!Nice use of custom hooks and clean separation between different notification types. The memoization setup will help with performance.
18-57
: Smart performance optimization with useMemoEach notification component is properly memoized with the right dependencies. This prevents unnecessary re-renders when other parts of the notification config change.
59-90
: Good accessibility and stylingThe component has proper ARIA attributes and maintains a 16:9 aspect ratio. The AnimatePresence wrapping each component enables smooth transitions.
components/docs/ShortLink.tsx (3)
28-34
: Memory leak issue resolved!Great fix! The cleanup function in useEffect properly clears the timeout when the component unmounts, addressing the previous memory leak concern.
36-51
: Solid async handlingThe copy function handles loading states well and includes proper error handling. The clipboard API usage is correct.
53-82
: Good accessibility and user feedbackThe button states clearly show loading, success, and default states with proper ARIA labels. Users get clear visual feedback for each action.
components/notification-generator/form/Tab.tsx (1)
17-44
: Accessibility improvements implemented!Perfect! The tab now includes all the proper ARIA attributes mentioned in previous reviews. The
role="tab"
,aria-selected
, andtabIndex
handling will make this work great with screen readers and keyboard navigation.components/docs/ReadingTime.tsx (1)
20-42
: Well-implemented reading time component.The component follows React best practices with memo optimization, good accessibility, and clean prop interface. The default 200 WPM is reasonable for technical documentation.
components/docs/DocHeader.tsx (1)
52-101
: Clean and accessible header component.The component structure is excellent with proper conditional rendering, good accessibility, and smooth animations. The layout handles optional props well.
components/header/hero/Hero.tsx (2)
7-7
: Good adoption of animation abstractions.The import statement shows proper integration with the centralized animation system.
11-69
: Excellent refactor to animation components.The conversion from direct framer-motion to animation abstractions is clean and maintains the same visual behavior while improving code organization. The accessibility attributes and semantic structure are preserved.
content/docs/eternalcombat/installation.md (1)
1-92
: Comprehensive and well-structured documentation.The installation guide covers all necessary steps with clear instructions, proper prerequisites, upgrade procedures, and helpful troubleshooting. The Alert component usage for community links is appropriate.
🧰 Tools
🪛 LanguageTool
[grammar] ~40-~40: The word ‘Backup’ is a noun. Do you mean the verb “Back up”?
Context: ...🔄 Upgrading ### Upgrade Process 1. Backup Your Configuration ```bash cp ...(SENT_START_BACKUP)
components/about/About.tsx (1)
6-77
: Nice animation refactor!The switch to centralized animation components makes the code cleaner and more maintainable. Good accessibility improvements too!
components/docs/DocSidebar.tsx (1)
1-207
: Well-built sidebar component!Great implementation with smooth animations, proper accessibility attributes, and correct active state handling for nested items. The performance optimizations with React.memo are a nice touch.
components/ui/AlertBox.tsx (1)
154-186
: Nice animation and accessibility implementation!The component has smooth animations and proper accessibility features. The layout animation, ARIA roles, and screen reader considerations are well implemented.
components/notification-generator/types.ts (1)
1-21
: Clean and well-structured type definitions!The interfaces are clear and provide good type safety for the notification generator. The union types will help prevent runtime errors.
app/notification-generator/page.tsx (1)
91-93
: Good use of key prop for preview re-rendering!Using the
previewKey
to force re-rendering of the preview component is a clean solution for the replay functionality.components/notification-generator/form/validation.ts (1)
3-29
: Well-structured validation logic!The function handles different field types appropriately and provides clear error messages. The early return for empty values is a good practice.
components/docs/DocCopyEnhancer.tsx (1)
172-177
: Good cleanup handlingThe cleanup logic properly disconnects the observer and clears the copy states map. This prevents potential memory leaks.
components/docs/AnimatedHeading.tsx (2)
32-44
: Clipboard error handling looks goodThe error handling with try-catch properly addresses the previous review feedback about clipboard failures.
76-96
: Accessibility is well implementedThe button includes proper
aria-label
,title
, and the status message hasaria-live="polite"
for screen readers. This addresses the previous accessibility concerns.components/team/Team.tsx (2)
9-11
: Good refactoring to centralized animationsUsing the new animation wrappers creates better consistency across components and centralizes animation logic.
40-44
: Nice touch with the blue hover effectThe new blue hover color (
#2563eb
) for social icons creates better visual feedback than the previous gray.components/CookiePreferencesMenu.tsx (2)
15-25
: Good accessibility on the settings buttonThe fixed-position button has proper
aria-label
and smooth animations. The positioning works well for user access.
60-66
: Smart approach for necessary cookiesMaking necessary cookies always checked and disabled is the right approach for GDPR compliance.
app/docs/layout.tsx (2)
11-17
: Good font configuration with proper fallbacks.The Poppins font setup includes appropriate weights, subsets, and fallback fonts for better performance and accessibility.
19-41
: Comprehensive metadata setup for SEO.The metadata configuration covers all essential elements including Open Graph, Twitter cards, and proper robot directives.
components/ui/tab.tsx (2)
15-27
: Well-structured component with proper TypeScript patterns.Good use of
forwardRef
and clean prop destructuring with proper defaults.
48-68
: Clean animation implementation.The single render path eliminates the duplication issue from previous reviews. The motion.div for the active tab indicator is properly implemented with good animation settings.
components/notification-generator/hooks.ts (3)
7-8
: Good use of refs for cleanup management.Using refs to track intervals and timeouts ensures proper cleanup and addresses the previous memory leak concerns.
10-15
: Robust time parsing with validation.The regex pattern correctly validates time format (e.g., "1.5s") and provides fallback for invalid inputs.
58-61
: Proper cleanup implementation.The cleanup function correctly clears both intervals and timeouts, preventing memory leaks.
components/CookieConsentModal.tsx (3)
16-22
: Smart conditional rendering logic.The modal only displays when consent is uninitialized and matches default state, preventing unnecessary prompts.
81-87
: Correct implementation for necessary cookies.Properly disabling the necessary cookies checkbox while keeping it checked ensures users understand these cannot be opted out.
26-31
: Smooth animation with proper positioning.The framer-motion animation provides good user experience with appropriate easing and positioning.
components/notification-generator/NotificationForm.tsx (4)
34-46
: Great validation approach!The validation logic properly handles specific fields and clears errors when needed. The field list check ensures only relevant fields get validated.
48-66
: Solid reset functionality.Good use of refs to stop sound playback and proper state cleanup. The callback dependency array is correct.
87-98
: Clean tab rendering with good performance.Using useMemo for tab generation is smart, and the capitalization logic works well for display labels.
112-119
: Excellent accessibility implementation.Proper ARIA attributes including
role="tablist"
,aria-label
, and semantic structure make this very accessible.components/footer/Footer.tsx (4)
13-23
: Well-designed TypeScript interfaces.Clean interface design that clearly separates link properties and section structure. The optional
isExternal
flag is a nice touch.
153-184
: Excellent data-driven rendering.Smart conditional rendering based on
isExternal
flag with proper security attributes (target="_blank"
andrel="noopener noreferrer"
).
121-124
: Good accessibility enhancement.Adding
role="contentinfo"
to the footer is the right approach for screen readers.
192-192
: Smart dynamic copyright year.Using
new Date().getFullYear()
prevents the copyright from becoming outdated.components/docs/CodeTabs.tsx (2)
23-44
: Robust icon mapping with good fallback.The dynamic icon name generation is clever, and the emoji fallback ensures something always renders. The memoization helps performance.
107-119
: Smooth shared layout animation.Using
layoutId="activeTab"
creates nice tab transition effects. The spring animation settings look good.components/notification-generator/minecraftTextParser.tsx (1)
36-51
: Clean legacy to MiniMessage conversion.The mapping table is comprehensive and the conversion logic handles the formatting codes properly.
components/animations/AnimatedContainer.tsx (1)
59-96
: Great job fixing the code repetition!The dynamic component approach with the mapping is much cleaner than having multiple if-else blocks. This makes the code easier to maintain.
components/features/Features.tsx (1)
7-84
: Nice refactoring with the animation components!The code is much cleaner with the new animation abstractions. The alternating fadeLeft/fadeRight animations based on index is a nice touch.
components/animations/AnimatedSection.tsx (4)
1-8
: Good client directive and importsThe imports are well-organized and all necessary dependencies are included.
9-21
: Comprehensive interface designThe props interface covers all animation customization needs with good defaults and accessibility support.
43-56
: Clean animation variant selectionThe switch statement clearly maps animation types to their variants.
67-81
: Solid component renderingThe motion.section implementation correctly handles all props and animation states.
components/animations/AnimationUtils.tsx (2)
6-11
: Good shared spring configurationUsing a consistent spring configuration across animations ensures uniform feel.
85-112
: Well-designed interactive animationsThe scale and page transition variants are well-configured for smooth user interactions.
components/ui/button.tsx (3)
7-24
: Good type definitionsThe interfaces are comprehensive and well-structured for button customization.
45-60
: Complete variant and size systemThe styling system covers all common button needs with proper dark mode support.
88-95
: Good content composition logicThe button content handling with loading state and icons is well-implemented.
components/animations/AnimatedElement.tsx (1)
8-19
: Well-designed flexible interfaceThe props support both animation customization and HTML tag flexibility.
components/notification-generator/form/SoundTab.tsx (1)
68-129
: Good error handling with fallback sounds!Nice implementation with the fallback sound list when the remote fetch fails. This ensures the feature remains functional even when the external resource is unavailable.
components/faq/Faq.tsx (2)
3-11
: Great refactoring to use reusable animation components!Moving from direct
framer-motion
usage to the abstracted animation components improves consistency across the codebase and makes animations easier to maintain.
75-112
: Excellent accessibility improvements!The addition of ARIA attributes (
aria-expanded
,aria-controls
,aria-labelledby
) makes the FAQ accordion much more accessible for screen reader users.app/docs/[...slug]/page.tsx (1)
186-196
: Great job adding the ErrorBoundary!The MDX content is now properly wrapped in an ErrorBoundary, preventing page crashes if there are rendering errors. This addresses the previous review feedback nicely.
components/header/Navbar.tsx (1)
126-146
: Great accessibility improvements!The menu toggle button has proper ARIA attributes and the animated icon transition is smooth.
content/docs/eternalcombat/features.md (1)
1-97
: Nice documentation structure!The features documentation is well-organized with clear sections and proper markdown formatting.
components/notification-generator/form/FormField.tsx (1)
1-311
: Great job implementing the accessibility improvements!The form field component has proper ARIA attributes, input validation, and a nice rich text editing experience.
app/layout.tsx (6)
1-16
: Nice privacy-focused approach!Moving analytics to local components for consent management is a great choice.
18-19
: Good performance setup!Static generation with hourly updates is a solid choice for documentation sites.
21-28
: Smart font loading!The preload and swap settings will help avoid layout shifts. Good fallback choices too.
30-39
: Great mobile setup!Allowing zoom up to 5x is good for accessibility. Theme colors matching the design is a nice touch.
42-108
: Excellent SEO setup!Really thorough metadata configuration. The dynamic OG images will make sharing look professional.
116-147
: Clean layout structure!Love the accessibility touches - the main content landmark and skip navigation support are great additions.
<Image | ||
src={image} | ||
alt="EternalCode Logo" | ||
width={120} | ||
height={120} | ||
style={{ marginRight: "20px" }} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify Image component compatibility with edge runtime.
The Next.js Image component may not work properly in edge runtime. Consider using a regular img tag or verify compatibility.
🏁 Script executed:
#!/bin/bash
# Check if Next.js Image component works in edge runtime
rg -A 5 -B 5 "Image.*edge.*runtime|edge.*runtime.*Image"
Length of output: 58
Could you check which Image
you’re using in this edge route? Let’s verify the import source:
🏁 Script executed:
#!/bin/bash
# Show how Image is imported in the OG route
rg "import .*Image" -n app/api/og/route.tsx
# Check if @vercel/og is in use
rg "@vercel/og" -n app/api/og/route.tsx
Length of output: 211
Use a plain <img>
tag in the OG edge function
The Next.js Image
component isn’t supported inside an edge‐based OG handler. Swap it out for a standard <img>
to avoid runtime errors.
- File: app/api/og/route.tsx (lines 42–48)
- Replace:
With:
<Image src={image} alt="EternalCode Logo" width={120} height={120} style={{ marginRight: "20px" }} />
<img src={image} alt="EternalCode Logo" width={120} height={120} style={{ marginRight: "20px" }} />
🤖 Prompt for AI Agents
In app/api/og/route.tsx around lines 42 to 48, the Next.js Image component is
used inside an edge runtime OG handler, which is not supported and can cause
runtime errors. Replace the <Image> component with a standard <img> tag, keeping
the same src, alt, width, height, and style attributes to ensure compatibility
with the edge environment.
{commands.map((c, i) => ( | ||
<tr key={i}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use unique keys instead of array index.
Using array index as React key can cause rendering issues when the list changes.
-{commands.map((c, i) => (
- <tr key={i}>
+{commands.map((c) => (
+ <tr key={c.name}>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{commands.map((c, i) => ( | |
<tr key={i}> | |
{commands.map((c) => ( | |
<tr key={c.name}> |
🤖 Prompt for AI Agents
In components/docs/DynamicCommandsTable.tsx around lines 46 to 47, the React
list items use the array index as the key, which can cause rendering issues when
the list changes. Replace the array index key with a unique and stable
identifier from the command object, such as an ID or a unique property, to
ensure consistent and correct rendering.
{message.split("\n").map((line, index) => ( | ||
<div | ||
key={index} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid using array index as key.
Using array indices as keys can cause rendering issues when the array changes.
- {message.split("\n").map((line, index) => (
- <div key={index}>
+ {message.split("\n").map((line, index) => (
+ <div key={`line-${index}-${line.slice(0, 10)}`}>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{message.split("\n").map((line, index) => ( | |
<div | |
key={index} | |
{message.split("\n").map((line, index) => ( | |
- <div key={index}> | |
+ <div key={`line-${index}-${line.slice(0, 10)}`}> | |
{line} | |
</div> | |
))} |
🤖 Prompt for AI Agents
In components/notification-generator/ChatMessage.tsx around lines 36 to 38, the
code uses the array index as the key in the map function, which can cause
rendering issues when the array changes. To fix this, generate a unique and
stable key for each line, such as by using a hash of the line content combined
with the index or another unique identifier, instead of just the index.
|
||
### External Links | ||
|
||
Link to external websites:a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the typo
Remove the extra "a" at the end of line 36.
-Link to external websites:a
+Link to external websites:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Link to external websites:a | |
Link to external websites: |
🤖 Prompt for AI Agents
In content/docs/documentation-editors/markdown-guide.md at line 36, there is an
extra "a" character at the end of the line after "Link to external websites:".
Remove this trailing "a" to correct the typo.
``` | ||
```` | ||
|
||
```` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove empty code block
This empty code block should be removed as it's not serving any purpose.
-````
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
230-230: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In content/docs/documentation-editors/markdown-guide.md at line 230, there is an
empty code block consisting of only backticks that serves no purpose. Remove
this empty code block entirely to clean up the markdown content.
initial: interactive ? "initial" : "hidden", | ||
animate: inView ? (interactive ? "initial" : "visible") : (interactive ? "initial" : "hidden"), | ||
whileHover: interactive ? "hover" : undefined, | ||
whileTap: interactive ? "tap" : undefined, | ||
transition: { delay }, | ||
...filteredProps, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix interactive animation logic
The animation states for interactive mode are incorrect. Interactive elements should still animate in/out of view.
const commonProps = {
ref,
className,
variants: animationVariant,
- initial: interactive ? "initial" : "hidden",
- animate: inView ? (interactive ? "initial" : "visible") : (interactive ? "initial" : "hidden"),
+ initial: "hidden",
+ animate: inView ? "visible" : "hidden",
whileHover: interactive ? "hover" : undefined,
whileTap: interactive ? "tap" : undefined,
transition: { delay },
...filteredProps,
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
initial: interactive ? "initial" : "hidden", | |
animate: inView ? (interactive ? "initial" : "visible") : (interactive ? "initial" : "hidden"), | |
whileHover: interactive ? "hover" : undefined, | |
whileTap: interactive ? "tap" : undefined, | |
transition: { delay }, | |
...filteredProps, | |
}; | |
const commonProps = { | |
ref, | |
className, | |
variants: animationVariant, | |
initial: "hidden", | |
animate: inView ? "visible" : "hidden", | |
whileHover: interactive ? "hover" : undefined, | |
whileTap: interactive ? "tap" : undefined, | |
transition: { delay }, | |
...filteredProps, | |
}; |
🤖 Prompt for AI Agents
In components/animations/AnimatedElement.tsx around lines 63 to 69, the
animation logic for interactive elements is incorrect because it prevents them
from animating in and out of view. Update the logic so that interactive elements
use "visible" when inView is true and "hidden" when false, instead of always
using "initial". This will ensure interactive elements animate properly when
entering and leaving the viewport.
let volumeValue = 1.0; | ||
if (typeof notification.volume === "string") { | ||
const parsedVolume = parseFloat(notification.volume); | ||
if (!isNaN(parsedVolume) && isFinite(parsedVolume)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace isFinite
with Number.isFinite
for safer type checking
The isFinite
function can cause unexpected behavior due to type coercion. Use Number.isFinite
instead for more predictable results.
- if (!isNaN(parsedVolume) && isFinite(parsedVolume)) {
+ if (!isNaN(parsedVolume) && Number.isFinite(parsedVolume)) {
- } else if (typeof notification.volume === "number" && isFinite(notification.volume)) {
+ } else if (typeof notification.volume === "number" && Number.isFinite(notification.volume)) {
- if (!isNaN(parsedPitch) && isFinite(parsedPitch)) {
+ if (!isNaN(parsedPitch) && Number.isFinite(parsedPitch)) {
- } else if (typeof notification.pitch === "number" && isFinite(notification.pitch)) {
+ } else if (typeof notification.pitch === "number" && Number.isFinite(notification.pitch)) {
Also applies to: 180-180, 195-195, 198-198
🧰 Tools
🪛 Biome (1.9.4)
[error] 177-177: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.
See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.
(lint/suspicious/noGlobalIsFinite)
🤖 Prompt for AI Agents
In components/notification-generator/form/SoundTab.tsx at lines 177, 180, 195,
and 198, replace all uses of the global isFinite function with Number.isFinite
to avoid type coercion issues. This change ensures safer and more predictable
type checking by using the Number object's isFinite method.
{options.map((option) => ( | ||
<div | ||
key={option.value} | ||
className="block w-full px-4 py-2 text-left text-gray-900 transition-colors duration-150 hover:bg-blue-50 hover:text-blue-700 focus:bg-blue-100 focus:text-blue-700 dark:text-white dark:hover:bg-gray-800 dark:hover:text-blue-400 dark:focus:bg-gray-800 dark:focus:text-blue-400 rounded-md outline-none cursor-pointer" | ||
onClick={() => { | ||
onChange(option.value); | ||
setIsOpen(false); | ||
}} | ||
> | ||
{option.label} | ||
</div> | ||
))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add keyboard navigation support
The dropdown options need keyboard accessibility for arrow key navigation and better focus management.
<div
key={option.value}
className="block w-full px-4 py-2 text-left text-gray-900 transition-colors duration-150 hover:bg-blue-50 hover:text-blue-700 focus:bg-blue-100 focus:text-blue-700 dark:text-white dark:hover:bg-gray-800 dark:hover:text-blue-400 dark:focus:bg-gray-800 dark:focus:text-blue-400 rounded-md outline-none cursor-pointer"
+ tabIndex={0}
+ role="option"
+ aria-selected={option.value === value}
onClick={() => {
onChange(option.value);
setIsOpen(false);
}}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ onChange(option.value);
+ setIsOpen(false);
+ }
+ }}
>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{options.map((option) => ( | |
<div | |
key={option.value} | |
className="block w-full px-4 py-2 text-left text-gray-900 transition-colors duration-150 hover:bg-blue-50 hover:text-blue-700 focus:bg-blue-100 focus:text-blue-700 dark:text-white dark:hover:bg-gray-800 dark:hover:text-blue-400 dark:focus:bg-gray-800 dark:focus:text-blue-400 rounded-md outline-none cursor-pointer" | |
onClick={() => { | |
onChange(option.value); | |
setIsOpen(false); | |
}} | |
> | |
{option.label} | |
</div> | |
))} | |
{options.map((option) => ( | |
<div | |
key={option.value} | |
className="block w-full px-4 py-2 text-left text-gray-900 transition-colors duration-150 hover:bg-blue-50 hover:text-blue-700 focus:bg-blue-100 focus:text-blue-700 dark:text-white dark:hover:bg-gray-800 dark:hover:text-blue-400 dark:focus:bg-gray-800 dark:focus:text-blue-400 rounded-md outline-none cursor-pointer" | |
tabIndex={0} | |
role="option" | |
aria-selected={option.value === value} | |
onClick={() => { | |
onChange(option.value); | |
setIsOpen(false); | |
}} | |
onKeyDown={(e) => { | |
if (e.key === 'Enter' || e.key === ' ') { | |
onChange(option.value); | |
setIsOpen(false); | |
} | |
}} | |
> | |
{option.label} | |
</div> | |
))} |
🤖 Prompt for AI Agents
In components/notification-generator/form/SliderField.tsx around lines 154 to
165, the dropdown options lack keyboard navigation support. Enhance
accessibility by adding keyboard event handlers to allow arrow key navigation
between options and proper focus management. Implement onKeyDown handlers to
move focus up and down the list with arrow keys, and ensure options are
focusable by adding tabIndex attributes. This will improve usability for
keyboard users.
<div className="w-full bg-[#f0f1f2] dark:bg-[#1F2A37] text-gray-800 dark:text-white text-center py-2 px-4 text-sm font-medium flex items-center justify-center gap-2 z-[60] border-b border-gray-200 dark:border-gray-700"> | ||
<span className="inline-block bg-white/60 dark:bg-white/10 rounded px-2 py-0.5 mr-2 text-xs font-bold uppercase tracking-wide text-blue-700 dark:text-blue-300">New</span> | ||
<span className="font-semibold">We launched the new Notification generator, fully interactive and customizable!</span> | ||
<a href="/notification-generator" className="ml-2 text-blue-700 dark:text-blue-300 font-semibold underline underline-offset-2 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors">Check it out →</a> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Make notification banner dynamic
The notification content is hardcoded. Consider making it configurable or dismissible for better user experience.
You could:
- Store notification state in a context or prop
- Add a dismiss button with close functionality
- Make the content configurable through props or CMS
🤖 Prompt for AI Agents
In components/header/Navbar.tsx around lines 98 to 102, the notification banner
content is hardcoded, limiting flexibility and user control. Refactor the
component to accept notification content as props or from context to make it
configurable. Add a dismiss button that updates state to hide the banner when
clicked, storing this state locally or in context to persist dismissal. This
will make the notification dynamic and improve user experience.
<style> | ||
{` | ||
.absolute::-webkit-scrollbar { | ||
display: none; | ||
} | ||
`} | ||
</style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Move embedded styles to CSS
The embedded <style>
tag isn't the best approach. Consider using Tailwind utilities or CSS modules instead.
-<style>
- {`
- .absolute::-webkit-scrollbar {
- display: none;
- }
- `}
-</style>
Add to your global CSS or use Tailwind's scrollbar utilities:
/* In your global CSS */
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
Then add the class to your dropdown div.
🤖 Prompt for AI Agents
In components/ui/Dropdown.tsx around lines 92 to 98, the embedded <style> tag
hiding the scrollbar should be removed. Instead, move the scrollbar hiding
styles to a global CSS file or use Tailwind's utilities by defining a class like
"scrollbar-hide" with the provided CSS rules. Then, apply this "scrollbar-hide"
class to the dropdown container div to achieve the same effect without inline
styles.
No description provided.