1- import React , { useState , useEffect , useRef } from 'react' ;
2- import AssistantModal from './AssistantModal' ; // Import the AssistantModal component for the chatbot.
3- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ; // Import the FontAwesomeIcon component.
4- import { faChevronDown } from '@fortawesome/free-solid-svg-icons' ; // Import the icon.
1+ import React , { useState , useEffect , useRef , lazy , Suspense , MouseEvent } from 'react' ;
2+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
3+ import { faChevronDown } from '@fortawesome/free-solid-svg-icons' ;
54import { useDoc } from '@docusaurus/plugin-content-docs/client' ;
6- import { useLocation } from "@docusaurus/router" ; // Import for location detection.
5+ import { useLocation } from "@docusaurus/router" ;
6+
7+ // Lazy-load AssistantModal
8+ const AssistantModal = lazy ( ( ) => import ( './AssistantModal' ) ) ;
79
810const SupportDropdownMenu : React . FC = ( ) => {
9- const [ isOpen , setIsOpen ] = useState ( false ) ; // For dropdown visibility
10- const [ isModalOpen , setIsModalOpen ] = useState ( false ) ; // For modal visibility
11- const [ storedUrl , setStoredUrl ] = useState < string | null > ( null ) ; // For storing the URL
12- const dropdownRef = useRef < HTMLDivElement > ( null ) ;
11+ const [ isOpen , setIsOpen ] = useState < boolean > ( false ) ;
12+ const [ isModalOpen , setIsModalOpen ] = useState < boolean > ( false ) ;
13+ const [ storedUrl , setStoredUrl ] = useState < string | null > ( null ) ;
14+ const dropdownRef = useRef < HTMLDivElement | null > ( null ) ;
1315 const location = useLocation ( ) ;
1416
1517 // Get document metadata from Docusaurus.
1618 const { metadata } = useDoc ( ) ;
17- const docTitle = metadata ?. title || "Issue with documentation page" ; // Use document title or fallback.
19+ const docTitle : string = metadata ?. title || "Issue with documentation page" ;
1820
1921 // Detect the language based on the URL path.
20- const isJapanese = location . pathname . startsWith ( "/ja-jp" ) ;
22+ const isJapanese : boolean = location . pathname . startsWith ( "/ja-jp" ) ;
2123
2224 useEffect ( ( ) => {
23- // Store the current URL in localStorage when the component first mounts.
24- const currentUrl = `https://scalardb.scalar-labs.com${ location . pathname } ` ;
25- localStorage . setItem ( "currentUrl" , currentUrl ) ;
26-
27- // Retrieve stored URL (if available).
28- const savedUrl = localStorage . getItem ( "currentUrl" ) ;
29- if ( savedUrl ) {
30- setStoredUrl ( savedUrl ) ;
25+ if ( typeof window !== "undefined" ) {
26+ const currentUrl = `https://scalardb.scalar-labs.com${ location . pathname } ` ;
27+ localStorage . setItem ( "currentUrl" , currentUrl ) ;
28+
29+ const savedUrl = localStorage . getItem ( "currentUrl" ) ;
30+ if ( savedUrl ) {
31+ setStoredUrl ( savedUrl ) ;
32+ }
3133 }
3234 } , [ location ] ) ;
3335
3436 const toggleDropdown = ( ) => {
3537 setIsOpen ( ( prev ) => ! prev ) ;
3638 } ;
3739
38- const openModal = ( event : React . MouseEvent ) => {
39- event . preventDefault ( ) ; // Prevent default anchor behavior.
40+ const openModal = ( event : MouseEvent < HTMLAnchorElement > ) => {
41+ event . preventDefault ( ) ;
4042 setIsModalOpen ( true ) ;
4143 setIsOpen ( false ) ;
4244 } ;
@@ -46,23 +48,23 @@ const SupportDropdownMenu: React.FC = () => {
4648 } ;
4749
4850 const handleSupportClick = ( ) => {
49- // Get the stored URL or fall back to the current URL.
50- const finalUrl = storedUrl || `https://scalardb.scalar-labs.com${ location . pathname } ` ;
51- const reportUrl = `https://support.scalar-labs.com/hc/ja/requests/new?ticket_form_id=8641483507983&tf_11847415366927=${ encodeURIComponent ( finalUrl ) } ` ;
51+ if ( typeof window !== "undefined" ) {
52+ const finalUrl = storedUrl || `https://scalardb.scalar-labs.com${ location . pathname } ` ;
53+ const reportUrl = `https://support.scalar-labs.com/hc/ja/requests/new?ticket_form_id=8641483507983&tf_11847415366927=${ encodeURIComponent ( finalUrl ) } ` ;
5254
53- // Open the support link in a new tab.
54- window . open ( reportUrl , "_blank" ) ;
55+ window . open ( reportUrl , "_blank" ) ;
56+ }
5557 } ;
5658
57- // Generate GitHub issue URL dynamically.
58- const repoUrl = "https://github.com/scalar-labs/docs-scalardb/issues/new" ;
59- const issueTitle = encodeURIComponent (
60- isJapanese ? `フィードバック: \`${ docTitle } \` ページ` : `Feedback: \`${ docTitle } \` page`
61- ) ;
59+ const githubIssueUrl : string = typeof window !== "undefined" ? ( ( ) => {
60+ const repoUrl = "https://github.com/scalar-labs/docs-scalardb/issues/new" ;
61+ const issueTitle = encodeURIComponent (
62+ isJapanese ? `フィードバック: \`${ docTitle } \` ページ` : `Feedback: \`${ docTitle } \` page`
63+ ) ;
6264
63- const issueBody = encodeURIComponent (
64- isJapanese
65- ? `**ドキュメントページの URL:** ${ window . location . href . replace ( / # .* $ / , '' ) }
65+ const issueBody = encodeURIComponent (
66+ isJapanese
67+ ? `**ドキュメントページの URL:** ${ window . location . href . replace ( / # .* $ / , '' ) }
6668
6769## 期待される動作
6870
@@ -80,7 +82,7 @@ const SupportDropdownMenu: React.FC = () => {
8082
8183該当する場合は、スクリーンショットを添付してください。
8284`
83- : `**Documentation page URL:** ${ window . location . href . replace ( / # .* $ / , '' ) }
85+ : `**Documentation page URL:** ${ window . location . href . replace ( / # .* $ / , '' ) }
8486
8587## Expected behavior
8688
@@ -98,13 +100,13 @@ If the issue is reproducible, please list the steps to reproduce it.
98100
99101If applicable, add screenshots to help explain your problem.
100102`
101- ) ;
103+ ) ;
102104
103- const githubIssueUrl = `${ repoUrl } ?title=${ issueTitle } &body=${ issueBody } &labels=documentation` ;
105+ return `${ repoUrl } ?title=${ issueTitle } &body=${ issueBody } &labels=documentation` ;
106+ } ) ( ) : "#" ;
104107
105- // Close dropdown when clicking outside of it.
106108 useEffect ( ( ) => {
107- function handleClickOutside ( event : MouseEvent ) {
109+ function handleClickOutside ( event : MouseEvent | Event ) {
108110 if ( dropdownRef . current && ! dropdownRef . current . contains ( event . target as Node ) ) {
109111 setIsOpen ( false ) ;
110112 }
@@ -151,7 +153,11 @@ If applicable, add screenshots to help explain your problem.
151153 </ div >
152154 ) }
153155
154- { isModalOpen && < AssistantModal isOpen = { isModalOpen } onClose = { closeModal } /> }
156+ { isModalOpen && (
157+ < Suspense fallback = { < div > Loading...</ div > } >
158+ < AssistantModal isOpen = { isModalOpen } onClose = { closeModal } />
159+ </ Suspense >
160+ ) }
155161 </ div >
156162 ) ;
157163} ;
0 commit comments