Explorar o código

update tag components and structures and use swr about tag

yuto-o %!s(int64=4) %!d(string=hai) anos
pai
achega
810e126aac

+ 41 - 56
packages/app/src/components/Sidebar/Tag.tsx

@@ -1,8 +1,11 @@
-import React, { FC, useState, useEffect } from 'react';
+import React, { FC, useState } from 'react';
 import { useTranslation } from 'react-i18next';
+
 import TagList from '../TagList';
 import TagCloudBox from '../TagCloudBox';
-import { apiGet } from '~/client/util/apiv1-client';
+
+import { useSWRxTagList } from '~/stores/tag';
+
 import { toastError } from '~/client/util/apiNotification';
 import { ITagDataHasId } from '~/interfaces/tag';
 
@@ -10,46 +13,39 @@ const LIMIT = 10;
 
 const Tag: FC = () => {
 
-  const [tagData, setTagData] = useState<ITagDataHasId[]>([]);
-  const [totalTags, setTotalTags] = useState<number>(0);
+  // const [tagData, setTagData] = useState<ITagDataHasId[]>([]);
+  // const [totalTags, setTotalTags] = useState<number>(0);
   const [isOnReload, setIsOnReload] = useState<boolean>(false);
+
+  const [offset, setOffset] = useState<number>(0);
+
+  const { data: tagDataList, mutate } = useSWRxTagList(LIMIT, offset);
+  const tagData: ITagDataHasId[] = tagDataList?.data || [];
+  const totalCount: number = tagDataList?.totalCount || 0;
+
   const { t } = useTranslation('');
 
-  const getTagList = async(selectPageNumber) => {
-    const offset = (selectPageNumber - 1) * LIMIT;
-    let res;
+  const getTagList = async(selectedPageNumber) => {
+    setOffset((selectedPageNumber - 1) * LIMIT);
 
     try {
-      res = await apiGet('/tags.list', { limit: LIMIT, offset });
+      mutate();
     }
     catch (error) {
       toastError(error);
     }
 
-    const tagData = res.data;
-
-    setTagData(tagData);
-    setTotalTags(res.totalCount);
-
+    setIsOnReload(false);
   };
 
   const onReload = () => {
-    getTagList(1);
+    setIsOnReload(true);
   };
 
-  useEffect(() => {
-    const f = async() => {
-      getTagList(1);
-    };
-    f();
-
-    setIsOnReload(false);
-  }, [isOnReload]);
 
   return (
-    <>
-
-      <div className="grw-sidebar-content-header p-3 d-flex">
+    <div className="grw-container-convertible px-4 mb-5 pb-5">
+      <div className="grw-sidebar-content-header py-3 d-flex">
         <h3 className="mb-0">{t('Tags')}</h3>
         <button
           type="button"
@@ -59,39 +55,28 @@ const Tag: FC = () => {
           <i className="icon icon-reload"></i>
         </button>
       </div>
+      <h2 className="my-3">{t('popular_tags')}</h2>
 
-
-      <div className="grw-container-convertible mb-5 pb-5">
-
-        <header className="py-0">
-          {/* total tags */}
-          <h2 className="my-3">人気のタグ</h2>
-        </header>
-
-        <div className="px-3 text-center">
-          <TagCloudBox tags={tagData} minSize={20} />
-
-        </div>
-
-
-        <div className="d-flex justify-content-center">
-          <button
-            className="btn btn-primary mt-1 mb-4 px-4"
-            type="button"
-            onClick={() => { window.location.href = '/tags' }}
-          >
-            {t('Check All tags')}
-          </button>
-        </div>
-        <TagList
-          tagData={tagData}
-          totalTags={totalTags}
-          limit={LIMIT}
-          isOnReload={isOnReload}
-          onHandlePagination={getTagList}
-        />
+      <div className="px-3 text-center">
+        <TagCloudBox tags={tagData} minSize={20} />
+      </div>
+      <div className="d-flex justify-content-center">
+        <button
+          className="btn btn-primary mt-3 mb-4 px-5"
+          type="button"
+          onClick={() => { window.location.href = '/tags' }}
+        >
+          {t('Check All tags')}
+        </button>
       </div>
-    </>
+      <TagList
+        tagData={tagData}
+        totalTags={totalCount}
+        limit={LIMIT}
+        isOnReload={isOnReload}
+        onHandlePagination={getTagList}
+      />
+    </div>
   );
 
 };

+ 2 - 8
packages/app/src/components/TagCloudBox.tsx

@@ -1,15 +1,9 @@
 import React, { FC } from 'react';
-
 import { TagCloud } from 'react-tagcloud';
-
-type Tag = {
-  _id: string,
-  name: string,
-  count: number,
-}
+import { ITagDataHasId } from '~/interfaces/tag';
 
 type Props = {
-  tags:Tag[],
+  tags:ITagDataHasId[],
   minSize?: number,
   maxSize?: number,
 }

+ 16 - 6
packages/app/src/components/TagList.tsx

@@ -1,28 +1,38 @@
 import React, {
-  FC, useState, useCallback,
+  FC, useState, useEffect, useCallback,
 } from 'react';
 import { useTranslation } from 'react-i18next';
 import PaginationWrapper from './PaginationWrapper';
 import { ITagDataHasId } from '~/interfaces/tag';
 
-
 type TagListProps = {
   tagData: ITagDataHasId[],
   totalTags: number,
   limit: number,
-  isOnReload: boolean,
-  onHandlePagination?: ((selectPageNumber:number) => void)
+  isOnReload?: boolean,
+  onHandlePagination?: ((selectedPageNumber:number) => void)
 }
 
-
 const TagList: FC<TagListProps> = (props:TagListProps) => {
   const [activePage, setActivePage] = useState<number>(1);
   const {
-    tagData, totalTags, limit, onHandlePagination,
+    tagData, totalTags, limit, isOnReload, onHandlePagination,
   } = props;
   const isTagExist: boolean = tagData.length > 0;
   const { t } = useTranslation('');
 
+
+  const reloadHandler = useCallback(() => {
+    if ((isOnReload != null && isOnReload) && onHandlePagination != null) {
+      onHandlePagination(activePage);
+    }
+  }, [isOnReload, onHandlePagination, activePage]);
+
+  useEffect(() => {
+    reloadHandler();
+  });
+
+
   const generateTagList = useCallback((tagData) => {
     return tagData.map((data) => {
       return (

+ 54 - 0
packages/app/src/components/TagPage.tsx

@@ -0,0 +1,54 @@
+import React, { FC, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import TagList from './TagList';
+import TagCloudBox from './TagCloudBox';
+
+import { useSWRxTagList } from '~/stores/tag';
+import { toastError } from '~/client/util/apiNotification';
+
+import { ITagDataHasId } from '~/interfaces/tag';
+
+
+const LIMIT = 10;
+
+const TagPage: FC = () => {
+
+  const [offset, setOffset] = useState<number>(0);
+
+  const { data: tagDataList, mutate } = useSWRxTagList(LIMIT, offset);
+  const tagData: ITagDataHasId[] = tagDataList?.data || [];
+  const totalCount: number = tagDataList?.totalCount || 0;
+
+  const { t } = useTranslation('');
+
+  const getTagList = async(selectedPageNumber) => {
+    setOffset((selectedPageNumber - 1) * LIMIT);
+
+    try {
+      mutate();
+    }
+    catch (error) {
+      toastError(error);
+    }
+
+  };
+
+  return (
+    <div className="grw-container-convertible mb-5 pb-5">
+      <h2 className="my-3">{`${t('Tags')}${totalCount}`}</h2>
+      <div className="px-3 text-center">
+        <TagCloudBox tags={tagData} minSize={20} />
+      </div>
+      <TagList
+        tagData={tagData}
+        totalTags={totalCount}
+        limit={LIMIT}
+        onHandlePagination={getTagList}
+      />
+    </div>
+  );
+
+};
+
+export default TagPage;

+ 24 - 0
packages/app/src/stores/tag.tsx

@@ -0,0 +1,24 @@
+import useSWR, { SWRResponse } from 'swr';
+import { ITagDataHasId } from '~/interfaces/tag';
+import { apiGet } from '~/client/util/apiv1-client';
+
+type ITagDataResponse = {
+  data: ITagDataHasId[],
+  totalCount: number,
+}
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+export const useSWRxTagList = (
+    limit: number,
+    offset: number,
+): SWRResponse<ITagDataResponse, Error> => {
+  return useSWR(
+    `/tags.list?limit=${limit}&offset=${offset}`,
+    endpoint => apiGet(endpoint).then((response: ITagDataResponse) => {
+      return {
+        data: response.data,
+        totalCount: response.totalCount,
+      };
+    }),
+  );
+};