From f188933700f6df52a1f52692493faaeea9e791b9 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 17:37:39 +0700 Subject: [PATCH 01/13] Create interface for contexts --- lib/context.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/context.ts b/lib/context.ts index 9b7662405..53372755c 100644 --- a/lib/context.ts +++ b/lib/context.ts @@ -1,6 +1,11 @@ import { createContext } from 'react'; -export const AuthContext = createContext({ +interface IAuthContext { + token: string; + origin: string; +} + +export const AuthContext = createContext({ token: '', origin: '', }); @@ -9,9 +14,11 @@ export function getLoginUrl(origin: string) { return `/api/oauth/authorize?redirect_uri=${encodeURIComponent(origin)}`; } -export const ThemeContext = createContext<{ +interface IThemeContext { theme: string; setTheme?: (theme: string) => void; -}>({ +} + +export const ThemeContext = createContext({ theme: '', }); From ec245c09c95ddc6a4d5b17bfbd06ef0e8d0f0455 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 17:48:04 +0700 Subject: [PATCH 02/13] Put getLoginUrl in AuthContext --- components/CommentBox.tsx | 4 ++-- components/ReactButtons.tsx | 4 ++-- components/Widget.tsx | 4 ++-- lib/context.ts | 10 ++++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/components/CommentBox.tsx b/components/CommentBox.tsx index d4e32bd3e..531e46f9f 100644 --- a/components/CommentBox.tsx +++ b/components/CommentBox.tsx @@ -1,7 +1,7 @@ import { MarkdownIcon } from '@primer/octicons-react'; import { ChangeEvent, useCallback, useContext, useEffect, useState } from 'react'; import { adaptComment, adaptReply, handleCommentClick, processCommentBody } from '../lib/adapter'; -import { AuthContext, getLoginUrl } from '../lib/context'; +import { AuthContext } from '../lib/context'; import { IComment, IReply, IUser } from '../lib/types/adapter'; import { resizeTextArea } from '../lib/utils'; import { addDiscussionComment } from '../services/github/addDiscussionComment'; @@ -34,7 +34,7 @@ export default function CommentBox({ const [isLoading, setIsLoading] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [isReplyOpen, setIsReplyOpen] = useState(false); - const { token, origin } = useContext(AuthContext); + const { token, origin, getLoginUrl } = useContext(AuthContext); const loginUrl = getLoginUrl(origin); const isReply = !!replyToId; diff --git a/components/ReactButtons.tsx b/components/ReactButtons.tsx index 1314e0515..aec0f6ddd 100644 --- a/components/ReactButtons.tsx +++ b/components/ReactButtons.tsx @@ -1,6 +1,6 @@ import { SmileyIcon } from '@primer/octicons-react'; import { useCallback, useContext, useState } from 'react'; -import { AuthContext, getLoginUrl } from '../lib/context'; +import { AuthContext } from '../lib/context'; import { useComponentVisible } from '../lib/hooks'; import { IReactionGroups } from '../lib/types/adapter'; import { Reactions } from '../lib/reactions'; @@ -47,7 +47,7 @@ export default function ReactButtons({ const [current, setCurrent] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [ref, isOpen, setIsOpen] = useComponentVisible(false); - const { token, origin } = useContext(AuthContext); + const { token, origin, getLoginUrl } = useContext(AuthContext); const loginUrl = getLoginUrl(origin); const togglePopover = useCallback(() => setIsOpen(!isOpen), [isOpen, setIsOpen]); diff --git a/components/Widget.tsx b/components/Widget.tsx index 96c5aa9e0..4b00b38d2 100644 --- a/components/Widget.tsx +++ b/components/Widget.tsx @@ -1,7 +1,7 @@ import { NextRouter, useRouter } from 'next/router'; import { useCallback, useState } from 'react'; import Giscus from '../components/Giscus'; -import { AuthContext } from '../lib/context'; +import { AuthContext, getLoginUrl } from '../lib/context'; import { useIsMounted } from '../lib/hooks'; import { createDiscussion } from '../services/giscus/createDiscussion'; import { getToken } from '../services/giscus/token'; @@ -74,7 +74,7 @@ export default function Widget({ router.isReady && (!session || token) && !isFetchingToken && repo && (term || number); return ready ? ( - + string; +} + +export function getLoginUrl(origin: string) { + return `/api/oauth/authorize?redirect_uri=${encodeURIComponent(origin)}`; } export const AuthContext = createContext({ token: '', origin: '', + getLoginUrl, }); -export function getLoginUrl(origin: string) { - return `/api/oauth/authorize?redirect_uri=${encodeURIComponent(origin)}`; -} - interface IThemeContext { theme: string; setTheme?: (theme: string) => void; From 402e56f4ec66522a86e3d3bcfbf088696a88100a Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 19:13:04 +0700 Subject: [PATCH 03/13] Create ConfigContext --- lib/context.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/context.ts b/lib/context.ts index 83604c44f..2cb6c2234 100644 --- a/lib/context.ts +++ b/lib/context.ts @@ -24,3 +24,17 @@ interface IThemeContext { export const ThemeContext = createContext({ theme: '', }); + +interface IConfigContext { + repo: string; + term: string; + number: number; + reactionsEnabled: boolean; +} + +export const ConfigContext = createContext({ + repo: '', + term: '', + number: 0, + reactionsEnabled: true, +}); From a7cb776be22e66c589a296a92f1156d06e9a023c Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 19:29:36 +0700 Subject: [PATCH 04/13] Lift all query param-related behavior to widget page --- components/Widget.tsx | 36 ++++++++++-------------------------- pages/widget.tsx | 25 +++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/components/Widget.tsx b/components/Widget.tsx index 4b00b38d2..c0468bcd4 100644 --- a/components/Widget.tsx +++ b/components/Widget.tsx @@ -1,50 +1,35 @@ -import { NextRouter, useRouter } from 'next/router'; import { useCallback, useState } from 'react'; import Giscus from '../components/Giscus'; import { AuthContext, getLoginUrl } from '../lib/context'; -import { useIsMounted } from '../lib/hooks'; import { createDiscussion } from '../services/giscus/createDiscussion'; import { getToken } from '../services/giscus/token'; interface IWidgetProps { + origin: string; + session: string; repo: string; - term?: string; - number?: number; + term: string; + number: number; repoId: string; categoryId: string; - description?: string; - reactionsEnabled?: boolean; -} - -function getSession(router: NextRouter) { - const session = router.query.session as string; - if (session) { - const query = { ...router.query }; - delete query.session; - const url = { pathname: router.pathname, query }; - const options = { scroll: false, shallow: true }; - router.replace(url, undefined, options); - } - return session || ''; + description: string; + reactionsEnabled: boolean; } export default function Widget({ + origin, + session, repo, term, number, repoId, categoryId, description, - reactionsEnabled = true, + reactionsEnabled, }: IWidgetProps) { - const router = useRouter(); - const isMounted = useIsMounted(); const [token, setToken] = useState(''); const [isFetchingToken, setIsFetchingToken] = useState(false); - const session = getSession(router); - const origin = (router.query.origin as string) || (isMounted ? location.href : ''); - const handleDiscussionCreateRequest = async () => createDiscussion(repo, { repositoryId: repoId, @@ -70,8 +55,7 @@ export default function Widget({ .catch((err) => handleError(err?.message)); } - const ready = - router.isReady && (!session || token) && !isFetchingToken && repo && (term || number); + const ready = (!session || token) && !isFetchingToken && repo && (term || number); return ready ? ( diff --git a/pages/widget.tsx b/pages/widget.tsx index d594ba52f..fe85db9ff 100644 --- a/pages/widget.tsx +++ b/pages/widget.tsx @@ -1,13 +1,32 @@ import Head from 'next/head'; -import { useRouter } from 'next/router'; +import { NextRouter, useRouter } from 'next/router'; import { useContext } from 'react'; import Widget from '../components/Widget'; import { ThemeContext } from '../lib/context'; +import { useIsMounted } from '../lib/hooks'; -export default function Home() { +function popSession(router: NextRouter) { + const session = router.query.session as string; + if (session) { + const query = { ...router.query }; + delete query.session; + const url = { pathname: router.pathname, query }; + const options = { scroll: false, shallow: true }; + router.replace(url, undefined, options); + } + return session || ''; +} + +export default function WidgetPage() { const router = useRouter(); + const isMounted = useIsMounted(); const { theme } = useContext(ThemeContext); + if (!router.isReady) return null; + + const origin = (router.query.origin as string) || (isMounted ? location.href : ''); + const session = popSession(router); + const repo = router.query.repo as string; const term = router.query.term as string; const number = +router.query.number; @@ -24,6 +43,8 @@ export default function Home() {
Date: Sat, 5 Jun 2021 19:47:01 +0700 Subject: [PATCH 05/13] Use ConfigContext in Widget and Giscus components --- components/Giscus.tsx | 16 +++------------- components/Widget.tsx | 13 ++++--------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/components/Giscus.tsx b/components/Giscus.tsx index 1b5c5a0b1..d9cd5f91e 100644 --- a/components/Giscus.tsx +++ b/components/Giscus.tsx @@ -1,5 +1,5 @@ import { useCallback, useContext } from 'react'; -import { AuthContext } from '../lib/context'; +import { AuthContext, ConfigContext } from '../lib/context'; import { Reactions, updateDiscussionReaction } from '../lib/reactions'; import { useDiscussions } from '../services/giscus/discussions'; import Comment from './Comment'; @@ -7,23 +7,13 @@ import CommentBox from './CommentBox'; import ReactButtons from './ReactButtons'; interface IGiscusProps { - repo: string; - term?: string; - number?: number; - reactionsEnabled: boolean; onDiscussionCreateRequest?: () => Promise; onError?: (message: string) => void; } -export default function Giscus({ - repo, - term, - number, - reactionsEnabled, - onDiscussionCreateRequest, - onError, -}: IGiscusProps) { +export default function Giscus({ onDiscussionCreateRequest, onError }: IGiscusProps) { const { token } = useContext(AuthContext); + const { repo, term, number, reactionsEnabled } = useContext(ConfigContext); const query = { repo, term, number }; const backComments = useDiscussions(query, token, { last: 15 }); diff --git a/components/Widget.tsx b/components/Widget.tsx index c0468bcd4..c8760acf9 100644 --- a/components/Widget.tsx +++ b/components/Widget.tsx @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react'; import Giscus from '../components/Giscus'; -import { AuthContext, getLoginUrl } from '../lib/context'; +import { AuthContext, ConfigContext, getLoginUrl } from '../lib/context'; import { createDiscussion } from '../services/giscus/createDiscussion'; import { getToken } from '../services/giscus/token'; @@ -59,14 +59,9 @@ export default function Widget({ return ready ? ( - + + + ) : null; } From 36020106dbeb5616af4691fc5eb657374427f4e4 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 20:38:44 +0700 Subject: [PATCH 06/13] Add category in search query --- lib/types/common.ts | 1 + pages/api/discussions/index.ts | 1 + services/github/getDiscussion.ts | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/types/common.ts b/lib/types/common.ts index 8a3dd750e..f5890520c 100644 --- a/lib/types/common.ts +++ b/lib/types/common.ts @@ -9,4 +9,5 @@ export interface DiscussionQuery { repo: string; term: string; number: number; + category: string; } diff --git a/pages/api/discussions/index.ts b/pages/api/discussions/index.ts index 84bc48cb5..576f0a690 100644 --- a/pages/api/discussions/index.ts +++ b/pages/api/discussions/index.ts @@ -11,6 +11,7 @@ async function get(req: NextApiRequest, res: NextApiResponse { - const { repo, term, number, ...pagination } = params; - const query = `repo:${repo} in:title ${term}`; + const { repo, term, number, category, ...pagination } = params; + const categoryQuery = category ? `category:${JSON.stringify(category)}` : ''; + const query = `repo:${repo} ${categoryQuery} in:title ${term}`; const gql = GET_DISCUSSION_QUERY(number ? 'number' : 'term'); return fetch(GITHUB_GRAPHQL_API_URL, { From 8e7a2a71382cf84e434fbe79f87f673d74c2e881 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 20:42:10 +0700 Subject: [PATCH 07/13] Add category in props --- components/Giscus.tsx | 4 ++-- components/Widget.tsx | 4 +++- lib/context.ts | 2 ++ pages/widget.tsx | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/components/Giscus.tsx b/components/Giscus.tsx index d9cd5f91e..301a2ca9a 100644 --- a/components/Giscus.tsx +++ b/components/Giscus.tsx @@ -13,8 +13,8 @@ interface IGiscusProps { export default function Giscus({ onDiscussionCreateRequest, onError }: IGiscusProps) { const { token } = useContext(AuthContext); - const { repo, term, number, reactionsEnabled } = useContext(ConfigContext); - const query = { repo, term, number }; + const { repo, term, number, category, reactionsEnabled } = useContext(ConfigContext); + const query = { repo, term, category, number }; const backComments = useDiscussions(query, token, { last: 15 }); const { diff --git a/components/Widget.tsx b/components/Widget.tsx index c8760acf9..3893c0dbc 100644 --- a/components/Widget.tsx +++ b/components/Widget.tsx @@ -10,6 +10,7 @@ interface IWidgetProps { repo: string; term: string; number: number; + category: string; repoId: string; categoryId: string; description: string; @@ -22,6 +23,7 @@ export default function Widget({ repo, term, number, + category, repoId, categoryId, description, @@ -59,7 +61,7 @@ export default function Widget({ return ready ? ( - + diff --git a/lib/context.ts b/lib/context.ts index 2cb6c2234..489e9db85 100644 --- a/lib/context.ts +++ b/lib/context.ts @@ -29,6 +29,7 @@ interface IConfigContext { repo: string; term: string; number: number; + category: string; reactionsEnabled: boolean; } @@ -36,5 +37,6 @@ export const ConfigContext = createContext({ repo: '', term: '', number: 0, + category: '', reactionsEnabled: true, }); diff --git a/pages/widget.tsx b/pages/widget.tsx index fe85db9ff..4aabdc05d 100644 --- a/pages/widget.tsx +++ b/pages/widget.tsx @@ -29,6 +29,7 @@ export default function WidgetPage() { const repo = router.query.repo as string; const term = router.query.term as string; + const category = router.query.category as string; const number = +router.query.number; const repoId = router.query.repoId as string; const categoryId = router.query.categoryId as string; @@ -48,6 +49,7 @@ export default function WidgetPage() { repo={repo} term={term} number={number} + category={category} repoId={repoId} categoryId={categoryId} description={description} From d1b9510be441a2d9b7cd91848fe6d7093fa9652c Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 21:17:35 +0700 Subject: [PATCH 08/13] Add category in client script --- client.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client.ts b/client.ts index e3585d6a1..627133411 100644 --- a/client.ts +++ b/client.ts @@ -51,6 +51,7 @@ params.theme = attributes.theme; params.reactionsEnabled = attributes.reactionsEnabled || '1'; params.repo = attributes.repo; params.repoId = attributes.repoId; +params.category = attributes.category || ''; params.categoryId = attributes.categoryId; params.description = ogDescriptionMeta ? ogDescriptionMeta.content : ''; From 6086f112244eac32903cd470b229170c04baf717 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 5 Jun 2021 21:18:38 +0700 Subject: [PATCH 09/13] Move category selection to after mapping --- components/Configuration.tsx | 52 ++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/components/Configuration.tsx b/components/Configuration.tsx index 2264810ed..2219a4181 100644 --- a/components/Configuration.tsx +++ b/components/Configuration.tsx @@ -200,32 +200,6 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co )} -

Discussion Category

-

- Choose the discussion category where new discussions will be created. This is only used for - discussion creation and does not affect how giscus searches for - discussions. -

- -

Page ↔️ Discussions Mapping

Choose the mapping between the embedding page and the embedded discussion.

@@ -263,6 +237,32 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co ))}
+

Discussion Category

+

+ Choose the discussion category where new discussions will be created. This is only used for + discussion creation and does not affect how giscus searches for + discussions. +

+ +

Features

Choose whether specific features should be enabled.

From 13bbd769e8e40d540238a5b37c48e3faedc8e3f4 Mon Sep 17 00:00:00 2001 From: sage Date: Sun, 6 Jun 2021 09:01:19 +0700 Subject: [PATCH 10/13] Add category toggle in Configuration component --- components/Configuration.tsx | 38 ++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/components/Configuration.tsx b/components/Configuration.tsx index 2219a4181..1a21a396c 100644 --- a/components/Configuration.tsx +++ b/components/Configuration.tsx @@ -105,7 +105,9 @@ interface ConfigurationProps { export default function Configuration({ directConfig, onDirectConfigChange }: ConfigurationProps) { const [repository, setRepository] = useState(''); const [repositoryId, setRepositoryId] = useState(''); + const [category, setCategory] = useState(''); const [categoryId, setCategoryId] = useState(''); + const [useCategory, setUseCategory] = useState(true); const [error, setError] = useState(false); const [categories, setCategories] = useState([]); const [mapping, setMapping] = useState('pathname'); @@ -116,6 +118,7 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co setError(false); setRepositoryId(''); setCategoryId(''); + setCategory(''); setCategories([]); if (dRepository) { getCategories(dRepository) @@ -238,17 +241,16 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co

Discussion Category

-

- Choose the discussion category where new discussions will be created. This is only used for - discussion creation and does not affect how giscus searches for - discussions. -

+

Choose the discussion category where new discussions will be created.

+ {mapping !== 'number' ? ( +
+ setUseCategory(event.target.checked)} + > + +

+ When searching for a matching discussion, giscus will only search in this category. +

+
+ ) : null}

Features

Choose whether specific features should be enabled.

@@ -325,6 +344,13 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co data-repo-id={'"'} {repositoryId || '[ENTER REPO ID HERE]'} {'"\n '} + {useCategory ? ( + <> + data-category={'"'} + {category || '[ENTER CATEGORY NAME HERE]'} + {'"\n '} + + ) : null} data-category-id={'"'} {categoryId || '[ENTER CATEGORY ID HERE]'} {'"\n '} From 526dd52bf30cc0e22b4434f26baf0160c827c917 Mon Sep 17 00:00:00 2001 From: sage Date: Sun, 6 Jun 2021 10:08:23 +0700 Subject: [PATCH 11/13] Use object state for config data --- components/Configuration.tsx | 149 +++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 59 deletions(-) diff --git a/components/Configuration.tsx b/components/Configuration.tsx index 1a21a396c..66c1c52da 100644 --- a/components/Configuration.tsx +++ b/components/Configuration.tsx @@ -1,12 +1,41 @@ import { CheckIcon, ClippyIcon, SyncIcon, XIcon } from '@primer/octicons-react'; -import { useEffect, useState } from 'react'; +import { ReactNode, useEffect, useState } from 'react'; import { handleClipboardCopy } from '../lib/adapter'; import { useDebounce } from '../lib/hooks'; import { ICategory } from '../lib/types/adapter'; import { themeOptions } from '../lib/variables'; import { getCategories } from '../services/giscus/categories'; -const mappingOptions = [ +interface IDirectConfig { + theme: string; + reactionsEnabled: boolean; +} + +interface IConfigurationProps { + directConfig: IDirectConfig; + onDirectConfigChange: ( + key: keyof IDirectConfig, + value: IDirectConfig[keyof IDirectConfig], + ) => void; +} + +type Mapping = 'pathname' | 'url' | 'title' | 'og:title' | 'specific' | 'number'; + +interface IConfig { + repository: string; + repositoryId: string; + mapping: Mapping; + term: string; + category: string; + categoryId: string; + useCategory: boolean; +} + +const mappingOptions: Array<{ + value: Mapping; + label: ReactNode; + description: ReactNode; +}> = [ { value: 'pathname', label: ( @@ -92,38 +121,28 @@ function ClipboardCopy() { ); } -interface DirectConfig { - theme: string; - reactionsEnabled: boolean; -} - -interface ConfigurationProps { - directConfig: DirectConfig; - onDirectConfigChange: (key: keyof DirectConfig, value: DirectConfig[keyof DirectConfig]) => void; -} - -export default function Configuration({ directConfig, onDirectConfigChange }: ConfigurationProps) { - const [repository, setRepository] = useState(''); - const [repositoryId, setRepositoryId] = useState(''); - const [category, setCategory] = useState(''); - const [categoryId, setCategoryId] = useState(''); - const [useCategory, setUseCategory] = useState(true); +export default function Configuration({ directConfig, onDirectConfigChange }: IConfigurationProps) { + const [config, setConfig] = useState({ + repository: '', + repositoryId: '', + mapping: 'pathname', + term: '', + category: '', + categoryId: '', + useCategory: true, + }); const [error, setError] = useState(false); const [categories, setCategories] = useState([]); - const [mapping, setMapping] = useState('pathname'); - const [term, setTerm] = useState(''); - const dRepository = useDebounce(repository); + const dRepository = useDebounce(config.repository); useEffect(() => { setError(false); - setRepositoryId(''); - setCategoryId(''); - setCategory(''); + setConfig((current) => ({ ...current, repositoryId: '', category: '', categoryId: '' })); setCategories([]); if (dRepository) { getCategories(dRepository) .then(({ repositoryId, categories }) => { - setRepositoryId(repositoryId); + setConfig((current) => ({ ...current, repositoryId })); setCategories(categories); }) .catch(() => { @@ -168,14 +187,16 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co setRepository(event.target.value)} + value={config.repository} + onChange={(event) => + setConfig((current) => ({ ...current, repository: event.target.value })) + } type="text" className="my-2 px-[12px] py-[5px] min-w-[75%] sm:min-w-[50%] form-control border rounded-md placeholder-gray-500" placeholder="owner/repo" /> - {error || (repositoryId && !categories.length) ? ( + {error || (config.repositoryId && !categories.length) ? ( <>

@@ -183,7 +204,7 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co met.

- ) : repositoryId && categories.length ? ( + ) : config.repositoryId && categories.length ? ( <>

@@ -192,7 +213,7 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co ) : ( <> - {!error && !repositoryId && dRepository ? ( + {!error && !config.repositoryId && dRepository ? ( ) : null}

@@ -214,25 +235,30 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co type="radio" name="mapping" value={value} - checked={mapping === value} - onChange={(event) => { - setTerm(''); - setMapping(event.target.value); - }} + checked={config.mapping === value} + onChange={(event) => + setConfig((current) => ({ + ...current, + term: '', + mapping: event.target.value as Mapping, + })) + } />

{description}

- {['specific', 'number'].includes(mapping) && mapping === value ? ( + {['specific', 'number'].includes(config.mapping) && config.mapping === value ? ( setTerm(event.target.value)} - type={mapping === 'number' ? 'number' : 'text'} + value={config.term} + onChange={(event) => + setConfig((current) => ({ ...current, term: event.target.value })) + } + type={config.mapping === 'number' ? 'number' : 'text'} className="px-[12px] py-[5px] mt-4 form-control border rounded-md placeholder-gray-500 min-w-[75%] sm:min-w-[50%]" placeholder={ - mapping === 'number' ? 'Enter discussion number here' : 'Enter term here' + config.mapping === 'number' ? 'Enter discussion number here' : 'Enter term here' } /> ) : null} @@ -246,16 +272,19 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co name="category" id="category" disabled={!categories.length} - value={categoryId} - onChange={(event) => { - setCategoryId(event.target.value); - setCategory(event.target.selectedOptions[0]?.textContent.substr(3)); - }} + value={config.categoryId} + onChange={(event) => + setConfig((current) => ({ + ...current, + category: event.target.selectedOptions[0]?.textContent.substr(3), + categoryId: event.target.value, + })) + } className={`px-[12px] py-[5px] pr-6 min-w-[200px] border rounded-md appearance-none bg-no-repeat form-control form-select color-border-primary color-bg-primary${ - !categoryId ? ' color-text-secondary' : '' + !config.categoryId ? ' color-text-secondary' : '' }`} > - {categories.map(({ id, emoji, name }) => ( @@ -264,14 +293,16 @@ export default function Configuration({ directConfig, onDirectConfigChange }: Co ))} - {mapping !== 'number' ? ( + {config.mapping !== 'number' ? (
setUseCategory(event.target.checked)} + checked={config.useCategory} + value={config.category} + onChange={(event) => + setConfig((current) => ({ ...current, useCategory: event.target.checked })) + } >