This is an automated email from the ASF dual-hosted git repository.

shuai pushed a commit to branch feat/1.4.0/personal
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git


The following commit(s) were added to refs/heads/feat/1.4.0/personal by this 
push:
     new 48f9546f fix: bages detail add userCard conponent
48f9546f is described below

commit 48f9546fb6dc1ef19858f0b7d4ae1b56af3747ce
Author: shuai <[email protected]>
AuthorDate: Mon Aug 12 16:26:31 2024 +0800

    fix: bages detail add userCard conponent
---
 ui/src/common/interface.ts                         | 14 +++-
 .../Detail/components/HeaderLoader/index.tsx       | 16 ++--
 .../Badges/Detail/components/UserCard/index.tsx    | 97 ++++++++++++++++++++++
 ui/src/pages/Badges/Detail/index.tsx               | 28 ++-----
 ui/src/pages/Badges/index.tsx                      |  1 -
 ui/src/services/client/badges.ts                   |  4 +-
 ui/src/services/client/personal.ts                 |  8 +-
 7 files changed, 134 insertions(+), 34 deletions(-)

diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts
index 789109d2..45f957c2 100644
--- a/ui/src/common/interface.ts
+++ b/ui/src/common/interface.ts
@@ -761,9 +761,21 @@ export interface BadgeDetailListReq {
   page: number;
   page_size: number;
   badge_id: string;
+  username?: string | null;
+}
+
+export interface BadgeDetailListItem {
+  created_at: number;
+  author_user_info: UserInfoBase;
+  object_type: string;
+  object_id: string;
+  url_title: string;
+  question_id: string;
+  answer_id: string;
+  comment_id: string;
 }
 
 export interface BadgeDetailListRes {
   count: number;
-  list: BadgeInfo[];
+  list: BadgeDetailListItem[];
 }
diff --git a/ui/src/pages/Badges/Detail/components/HeaderLoader/index.tsx 
b/ui/src/pages/Badges/Detail/components/HeaderLoader/index.tsx
index df0c9204..d56432e8 100644
--- a/ui/src/pages/Badges/Detail/components/HeaderLoader/index.tsx
+++ b/ui/src/pages/Badges/Detail/components/HeaderLoader/index.tsx
@@ -22,23 +22,23 @@ import { Card } from 'react-bootstrap';
 const Index = () => {
   return (
     <Card className="mb-4 placeholder-glow">
-      <Card.Body className="d-flex">
+      <Card.Body className="d-block d-sm-flex">
         <div
-          className="placeholder me-3"
+          className="placeholder me-3 flex-shrink-0"
           style={{ width: '96px', height: '96px' }}
         />
 
-        <div>
-          <div className="placeholder h5" />
-          <div className="placeholder" />
-          <div className="placeholder" />
+        <div className="w-100 mt-3 mt-sm-0">
+          <div className="placeholder h5 w-25" />
+          <div className="placeholder w-100" />
+          <div className="placeholder w-75" />
 
           <div className="placeholder mt-2 w-50" />
 
           <div className="small mt-2">
-            <span className="placeholder" style={{ width: '100px' }} />
+            <span className="placeholder" style={{ width: '80px' }} />
 
-            <span className="placeholder ms-2" style={{ width: '100px' }} />
+            <span className="placeholder ms-2" style={{ width: '80px' }} />
           </div>
         </div>
       </Card.Body>
diff --git a/ui/src/pages/Badges/Detail/components/UserCard/index.tsx 
b/ui/src/pages/Badges/Detail/components/UserCard/index.tsx
new file mode 100644
index 00000000..d874ceb9
--- /dev/null
+++ b/ui/src/pages/Badges/Detail/components/UserCard/index.tsx
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { memo, FC } from 'react';
+import { Link } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+
+import classnames from 'classnames';
+
+import { Avatar } from '@/components';
+import { formatCount } from '@/utils';
+
+interface Props {
+  data: any;
+  className?: string;
+}
+
+const Index: FC<Props> = ({ data, className = '' }) => {
+  const { t } = useTranslation('translation', { keyPrefix: 'badges' });
+  return (
+    <div className={classnames('d-flex', className)}>
+      {data?.status !== 'deleted' ? (
+        <Link to={`/users/${data?.username}`}>
+          <Avatar
+            avatar={data?.avatar}
+            size="40px"
+            className="me-2 d-none d-md-block"
+            searchStr="s=96"
+            alt={data?.display_name}
+          />
+
+          <Avatar
+            avatar={data?.avatar}
+            size="24px"
+            className="me-2 d-block d-md-none"
+            searchStr="s=48"
+            alt={data?.display_name}
+          />
+        </Link>
+      ) : (
+        <>
+          <Avatar
+            avatar={data?.avatar}
+            size="40px"
+            className="me-2 d-none d-md-block"
+            searchStr="s=96"
+            alt={data?.display_name}
+          />
+
+          <Avatar
+            avatar={data?.avatar}
+            size="24px"
+            className="me-2 d-block d-md-none"
+            searchStr="s=48"
+            alt={data?.display_name}
+          />
+        </>
+      )}
+      <div className="small text-secondary d-flex flex-row flex-md-column 
align-items-center align-items-md-start">
+        <div className="me-1 me-md-0 d-flex align-items-center">
+          {data?.status !== 'deleted' ? (
+            <Link
+              to={`/users/${data?.username}`}
+              className="me-1 text-break name-ellipsis"
+              style={{ maxWidth: '100px' }}>
+              {data?.display_name}
+            </Link>
+          ) : (
+            <span className="me-1 text-break">{data?.display_name}</span>
+          )}
+        </div>
+        <div className="text-secondary">
+          {formatCount(data?.rank)}{' '}
+          {t('x_reputation', { keyPrefix: 'personal' })}
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default memo(Index);
diff --git a/ui/src/pages/Badges/Detail/index.tsx 
b/ui/src/pages/Badges/Detail/index.tsx
index 3e8513ae..42487db3 100644
--- a/ui/src/pages/Badges/Detail/index.tsx
+++ b/ui/src/pages/Badges/Detail/index.tsx
@@ -23,7 +23,7 @@ import { Link, useParams, useSearchParams } from 
'react-router-dom';
 
 // import classnames from 'classnames';
 
-import { Avatar, FormatTime, Pagination, Empty } from '@/components';
+import { FormatTime, Pagination, Empty } from '@/components';
 import { usePageTags, useSkeletonControl } from '@/hooks';
 // import { formatCount } from '@/utils';
 import { useGetBadgeInfo, useBadgeDetailList } from '@/services';
@@ -31,6 +31,7 @@ import { useGetBadgeInfo, useBadgeDetailList } from 
'@/services';
 import BadgeDetail from './components/Badge';
 import Loader from './components/Loader';
 import HeaderLoader from './components/HeaderLoader';
+import UserCard from './components/UserCard';
 
 const Index = () => {
   const { t } = useTranslation('translation', { keyPrefix: 'badges' });
@@ -46,6 +47,7 @@ const Index = () => {
     badge_id,
     page,
     page_size: pageSize,
+    username: urlSearchParams.get('username') || null,
   });
 
   const { isSkeletonShow } = useSkeletonControl(isDetailLoading);
@@ -65,36 +67,20 @@ const Index = () => {
       <h3 className="mb-4">{t('title')}</h3>
       {isHeaderLoading ? <HeaderLoader /> : <BadgeDetail data={badgeInfo} />}
       <Row>
-        <Loader />
         {isSkeletonShow ? (
           <Loader />
         ) : (
           badges?.list?.map((item) => {
             return (
-              <Col sm={12} md={6} lg={3} key={item.id} className="mb-4">
+              <Col sm={12} md={6} lg={3} key={item.object_id} className="mb-4">
                 <FormatTime
-                  time={1722397094672}
+                  time={item.created_at}
                   preFix={t('awarded')}
                   className="small mb-1 d-block"
                 />
-                <div className="d-flex align-items-center">
-                  <Link to="/user">
-                    <Avatar size="40px" avatar="" alt="" />
-                  </Link>
-                  <div className="small ms-2">
-                    <Link
-                      to="/user"
-                      className="lh-1 name-ellipsis"
-                      style={{ maxWidth: '200px' }}>
-                      username
-                    </Link>
-                    <div className="text-secondary">
-                      980 {t('x_reputation', { keyPrefix: 'personal' })}
-                    </div>
-                  </div>
-                </div>
+                <UserCard data={item.author_user_info} />
                 <Link to="/question" className="mt-1 d-block">
-                  How to `go test` all tests in my project?
+                  {item.url_title}
                 </Link>
               </Col>
             );
diff --git a/ui/src/pages/Badges/index.tsx b/ui/src/pages/Badges/index.tsx
index 39628062..d37f5d9a 100644
--- a/ui/src/pages/Badges/index.tsx
+++ b/ui/src/pages/Badges/index.tsx
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 import { useTranslation } from 'react-i18next';
 
 import { CardBadge } from '@/components';
diff --git a/ui/src/services/client/badges.ts b/ui/src/services/client/badges.ts
index c3a7bba2..476f85d1 100644
--- a/ui/src/services/client/badges.ts
+++ b/ui/src/services/client/badges.ts
@@ -52,7 +52,9 @@ export const useGetBadgeInfo = (id: string) => {
 
 export const useBadgeDetailList = (params: Type.BadgeDetailListReq) => {
   const { data, error, mutate } = useSWR<Type.BadgeDetailListRes, Error>(
-    `/answer/api/v1/badge/awards/page?${qs.stringify(params)}`,
+    `/answer/api/v1/badge/awards/page?${qs.stringify(params, {
+      skipNulls: true,
+    })}`,
     request.instance.get,
   );
   return {
diff --git a/ui/src/services/client/personal.ts 
b/ui/src/services/client/personal.ts
index 339f1e60..fbf38938 100644
--- a/ui/src/services/client/personal.ts
+++ b/ui/src/services/client/personal.ts
@@ -66,7 +66,7 @@ export const usePersonalTop = (username: string, tabName: 
string) => {
 };
 
 export const usePersonalListByTabName = (params: ListReq, tabName: string) => {
-  let apiUrl = '';
+  let apiUrl: string | null = '';
   if (tabName === 'answers') {
     apiUrl = '/answer/api/v1/personal/answer/page';
   }
@@ -89,10 +89,14 @@ export const usePersonalListByTabName = (params: ListReq, 
tabName: string) => {
     delete params.username;
     apiUrl = '/answer/api/v1/personal/vote/page';
   }
+  if (tabName === 'badges') {
+    delete params.order;
+    apiUrl = '/answer/api/v1/badge/user/awards';
+  }
 
   const queryParams = qs.stringify(params, { skipNulls: true });
   const { data, error, mutate } = useSWR<ListRes, Error>(
-    tabName !== 'overview' ? `${apiUrl}?${queryParams}` : null,
+    tabName !== 'review' ? `${apiUrl}?${queryParams}` : null,
     request.instance.get,
   );
 

Reply via email to