You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by ak...@apache.org on 2022/12/24 01:26:21 UTC

[age-website] branch new-web updated: top contributors update (#112)

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

ako pushed a commit to branch new-web
in repository https://gitbox.apache.org/repos/asf/age-website.git


The following commit(s) were added to refs/heads/new-web by this push:
     new 666e0ad1 top contributors update (#112)
666e0ad1 is described below

commit 666e0ad173270a179977217e17cd7f249d50d702
Author: MJinH <97...@users.noreply.github.com>
AuthorDate: Fri Dec 23 17:26:16 2022 -0800

    top contributors update (#112)
    
    * top contributors update
    
    * medal update
    
    Co-authored-by: moon19960501@gmail.com <we...@gmail.com>
---
 src/api/issueStateManager.js                      | 154 ++++++--------------
 src/api/pullRequestStateManager.js                | 111 ++++-----------
 src/components/AgeContributors.js                 | 166 ++++++++++++----------
 src/components/ContributorsList.js                |   9 +-
 src/components/WeekContext.js                     |  13 ++
 src/components/styles/AgeContributors.module.scss |  19 ++-
 src/templates/index-page.js                       |   2 +-
 static/img/medal.jpg                              | Bin 0 -> 98433 bytes
 8 files changed, 195 insertions(+), 279 deletions(-)

diff --git a/src/api/issueStateManager.js b/src/api/issueStateManager.js
index 98097d67..b3b2ae05 100644
--- a/src/api/issueStateManager.js
+++ b/src/api/issueStateManager.js
@@ -1,116 +1,50 @@
+const getDates = (isLast) => {
+  let dates = [];
+  const currentDate = new Date();
 
-async function getViewerIssuesStateSetter(setIssueInfo) {
-    const response =  await fetch('https://api.github.com/repos/apache/age-viewer/issues?state=open',
-    {
-      method: 'GET',
-      headers: {
-        Accept: 'application/json',
-        'Content-Type': 'application/json',
-      },
-    }) 
-    if(response.ok) {
-      const res = await response.json();   
-      const issuers = [];
-      const currentDate = new Date();
-      res.map((info) => {
-         const createdDate = new Date(info.created_at);
-         const diffDate = currentDate.getTime() - createdDate.getTime();
-         if(info.html_url.includes("issues") && Math.abs(diffDate / (1000*60*60*24)) < 8) {
-            issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-         }
-      })
-      setIssueInfo(issuers);
-      return true;
-      
-    }
-  }
-  
-  async function getAgeIssuesStateSetter(setIssueInfo) {
-      const response =  await fetch('https://api.github.com/repos/apache/age/issues?state=open',
-      {
-        method: 'GET',
-        headers: {
-          Accept: 'application/json',
-          'Content-Type': 'application/json',
-        },
-      }) 
-      if(response.ok) {
-        const res = await response.json();   
-        const issuers = [];
-        const currentDate = new Date();
-        res.map((info) => {
-           const createdDate = new Date(info.created_at);
-           const diffDate = currentDate.getTime() - createdDate.getTime();
-           if(info.html_url.includes("issues") && Math.abs(diffDate / (1000*60*60*24)) < 8) {
-              issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-           }
-        })
-        setIssueInfo(issuers);
-        return true;
-        
-      }
-  }
-  
-  async function getVieweClosedrIssuesStateSetter(setIssueInfo) {
-      const response =  await fetch('https://api.github.com/repos/apache/age-viewer/issues?state=closed',
-      {
-        method: 'GET',
-        headers: {
-          Accept: 'application/json',
-          'Content-Type': 'application/json',
-        },
-      }) 
-      if(response.ok) {
-        const res = await response.json();   
-        const issuers = [];
-        const currentDate = new Date();
-        res.map((info) => {
-          const closedDate = new Date(info.closed_at);
-          const diffDate = currentDate.getTime() - closedDate.getTime();
-           if(info.html_url.includes("issues") && Math.abs(diffDate / (1000*60*60*24)) < 8) {
-              issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-           }
-        })
-        setIssueInfo(issuers);
-        return true;
-        
-      }
-  }
-  
-  async function getAgeClosedIssuesStateSetter(setIssueInfo) {
-      const response =  await fetch('https://api.github.com/repos/apache/age/issues?state=closed',
-      {
-        method: 'GET',
-        headers: {
-          Accept: 'application/json',
-          'Content-Type': 'application/json',
-        },
-      }) 
-      if(response.ok) {
-        const res = await response.json();   
-        const issuers = [];
-        const currentDate = new Date();
-        res.map((info) => {
-          const closedDate = new Date(info.closed_at);
-          const diffDate = currentDate.getTime() - closedDate.getTime();
-           if(info.html_url.includes("issues") && Math.abs(diffDate / (1000*60*60*24)) < 8) {
-              issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-           }
-        })
-        setIssueInfo(issuers);
-        return true;
-        
-      }
+  for(let i=0; i<7; i++) {
+    const lastWeek = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + (i - (currentDate.getDay() - 1)) - isLast);
+    const year = lastWeek.getFullYear();
+    const month = Number(lastWeek.getMonth()) + 1;
+    const day = lastWeek.getDate();
+
+    month = String(month).length === 1 ? '0' + month : month;
+    day = String(day).length === 1 ? '0' + day : day;
+    dates.push(year + '-' + month + '-' + day);
   }
-  
-  
+  return dates;
+}
+
+async function getIssuesStateSetter(setIssueInfo,repo,state) {
+  const response =  await fetch(`https://api.github.com/repos/apache/${repo}/issues?state=${state}`,
+  {
+    method: 'GET',
+    headers: {
+      Accept: 'application/json',
+      'Content-Type': 'application/json',
+    },
+  }) 
+  if(response.ok) {
+    const res = await response.json();   
+    const status = state === 'open' ? 'created_at' : 'closed_at'  
+    let issuers = [];
+    let lastWeeks = getDates(7);
+    let thisWeeks = getDates(0);
+    res.map((info) => {
+        if (info.html_url.includes("issues") && lastWeeks.includes(info[status].split('T')[0])) {
+        issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url, isLast: true});
+        } else if (info.html_url.includes("issues") && thisWeeks.includes(info[status].split('T')[0])) {
+        issuers.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url, isLast: false});
+        }
+    })
+    setIssueInfo(issuers);
+    return true;
     
-  const manager = {
-      getViewerIssuesStateSetter,
-      getAgeIssuesStateSetter,
-      getVieweClosedrIssuesStateSetter,
-      getAgeClosedIssuesStateSetter,
-  };
+  }
+}
+const manager = {
+  getIssuesStateSetter,
+};
   
   export default manager;
   
\ No newline at end of file
diff --git a/src/api/pullRequestStateManager.js b/src/api/pullRequestStateManager.js
index 074f8d22..db5ceed9 100644
--- a/src/api/pullRequestStateManager.js
+++ b/src/api/pullRequestStateManager.js
@@ -1,31 +1,22 @@
-
-async function getViewerPullRequestStateSetter(setPullRequestInfo) {
-    const response =  await fetch('https://api.github.com/repos/apache/age-viewer/pulls?state=open',
-    {
-      method: 'GET',
-      headers: {
-        Accept: 'application/json',
-        'Content-Type': 'application/json',
-      },
-    }) 
-    if(response.ok) {
-      const res = await response.json();   
-      const requestors = [];
-      const currentDate = new Date();
-      res.map((info) => {
-        const createdDate = new Date(info.created_at);
-        const diffDate = currentDate.getTime() - createdDate.getTime();
-        if(Math.abs(diffDate / (1000*60*60*24)) < 8) requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-      });
-
-      setPullRequestInfo(requestors);
-      return true;
-      
-    }
+const getDates = (isLast) => {
+  let dates = [];
+  const currentDate = new Date();
+
+  for(let i=0; i<7; i++) {
+    const lastWeek = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + (i - (currentDate.getDay() - 1)) - isLast);
+    const year = lastWeek.getFullYear();
+    const month = Number(lastWeek.getMonth()) + 1;
+    const day = lastWeek.getDate();
+
+    month = String(month).length === 1 ? '0' + month : month;
+    day = String(day).length === 1 ? '0' + day : day;
+    dates.push(year + '-' + month + '-' + day);
+  }
+  return dates;
 }
 
-async function getAgePullRequestStateSetter(setPullRequestInfo) {
-    const response =  await fetch('https://api.github.com/repos/apache/age/pulls?state=open',
+async function getPullRequestStateSetter(setPullRequestInfo,repo,state) {
+    const response =  await fetch(`https://api.github.com/repos/apache/${repo}/pulls?state=${state}`,
     {
       method: 'GET',
       headers: {
@@ -34,13 +25,17 @@ async function getAgePullRequestStateSetter(setPullRequestInfo) {
       },
     }) 
     if(response.ok) {
-      const res = await response.json();   
-      const requestors = [];
-      const currentDate = new Date();
+      const res = await response.json();
+      const status = state === 'open' ? 'created_at' : 'merged_at'  
+      let requestors = [];
+      let lastWeeks = getDates(7);
+      let thisWeeks = getDates(0);
       res.map((info) => {
-        const createdDate = new Date(info.created_at);
-        const diffDate = currentDate.getTime() - createdDate.getTime();
-        if(Math.abs(diffDate / (1000*60*60*24)) < 8) requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
+        if (info[status] && lastWeeks.includes(info[status].split('T')[0])) {
+          requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url, isLast: true});
+         } else if (info[status] && thisWeeks.includes(info[status].split('T')[0])) {
+          requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url, isLast: false});
+         }
       });
 
       setPullRequestInfo(requestors);
@@ -48,58 +43,8 @@ async function getAgePullRequestStateSetter(setPullRequestInfo) {
       
     }
 }
-
-async function getViewerClosedPullRequestStateSetter(setPullRequestInfo) {
-    const response =  await fetch('https://api.github.com/repos/apache/age-viewer/pulls?state=closed',
-    {
-      method: 'GET',
-      headers: {
-        Accept: 'application/json',
-        'Content-Type': 'application/json',
-      },
-    }) 
-    if(response.ok) {
-      const res = await response.json();   
-      const requestors = [];
-      const currentDate = new Date();
-      res.map((info) => {
-        const closedDate = new Date(info.closed_at);
-        const diffDate = currentDate.getTime() - closedDate.getTime();
-        if(info.merged_at && Math.abs(diffDate / (1000*60*60*24)) < 8) requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-      });
-      setPullRequestInfo(requestors);
-      return true;
-    }
-}
-
-async function getAgeClosedPullRequestStateSetter(setPullRequestInfo) {
-    const response =  await fetch('https://api.github.com/repos/apache/age/pulls?state=closed',
-    {
-      method: 'GET',
-      headers: {
-        Accept: 'application/json',
-        'Content-Type': 'application/json',
-      },
-    }) 
-    if(response.ok) {
-      const res = await response.json();   
-      const requestors = [];
-      const currentDate = new Date();
-      res.map((info) => {
-        const closedDate = new Date(info.closed_at);
-        const diffDate = currentDate.getTime() - closedDate.getTime();
-        if(info.merged_at && Math.abs(diffDate / (1000*60*60*24)) < 8) requestors.push({login:info.user.login, avatar: info.user.avatar_url, html: info.user.html_url});
-      });
-      setPullRequestInfo(requestors);
-      return true;
-    }
-}
-
 const manager = {
-    getViewerPullRequestStateSetter,
-    getAgePullRequestStateSetter,
-    getViewerClosedPullRequestStateSetter,
-    getAgeClosedPullRequestStateSetter,
+    getPullRequestStateSetter,
 };
 
 export default manager;
diff --git a/src/components/AgeContributors.js b/src/components/AgeContributors.js
index 0c59a939..a6945c25 100644
--- a/src/components/AgeContributors.js
+++ b/src/components/AgeContributors.js
@@ -4,6 +4,7 @@ import pullRequestManager from '../api/pullRequestStateManager'
 import * as styles from './styles/AgeContributors.module.scss';
 import { Spin } from 'antd';
 import ContributorsList from './ContributorsList';
+import WeekContext from './WeekContext';
 
 const Contributors = () => {
     const [ageIssueInfo, setAgeIssueInfo] = useState([]);
@@ -21,120 +22,117 @@ const Contributors = () => {
     const [viewerTopContributors, setViewerTopContributors] = useState({});
     const [ageTopContributors, setAgeTopContributors] = useState([]);
 
+    const [viewerLastTCAV, setViewerLastTCAV] = useState({});
+    const [ageLastTCAV, setAgeLastTCAV] = useState({});
+    const [viewerLastTC, setViewerLastTC] = useState({});
+    const [ageLastTC, setAgeLastTC] = useState({});
     const [isLoading, setLoadingYn] = useState(true);
 
     useEffect(() => {
-        issueManager.getViewerIssuesStateSetter(setViewerIssueInfo).then((res) => {
+        issueManager.getIssuesStateSetter(setViewerIssueInfo,'age-viewer','open').then((res) => {
             if (res) {
-                issueManager.getVieweClosedrIssuesStateSetter(setViewerClosedIsInfo).then((res) => {})
+                issueManager.getIssuesStateSetter(setViewerClosedIsInfo,'age-viewer','closed').then((res) => {})
             }
         })
-        issueManager.getAgeIssuesStateSetter(setAgeIssueInfo).then((res) => {
+        issueManager.getIssuesStateSetter(setAgeIssueInfo,'age','open').then((res) => {
             if (res) {
-                issueManager.getAgeClosedIssuesStateSetter(setAgeClosedIssueInfo).then((res) => {})
+                issueManager.getIssuesStateSetter(setAgeClosedIssueInfo,'age','closed').then((res) => {})
             }
         })
-        pullRequestManager.getViewerPullRequestStateSetter(setViewerPullRequestInfo).then((res) => {
+        pullRequestManager.getPullRequestStateSetter(setViewerPullRequestInfo,'age-viewer','open').then((res) => {
             if (res) {
-                pullRequestManager.getAgePullRequestStateSetter(setAgePullRequestInfo).then((res) => {})
+                pullRequestManager.getPullRequestStateSetter(setAgePullRequestInfo,'age','open').then((res) => {})
             }
         })
-        pullRequestManager.getViewerClosedPullRequestStateSetter(setViewerClosedPRInfo).then((res) => {
+        pullRequestManager.getPullRequestStateSetter(setViewerClosedPRInfo,'age-viewer','closed').then((res) => {
             if (res) {
-                pullRequestManager.getAgeClosedPullRequestStateSetter(setAgeClosedPRInfo).then((res) => {})
+                pullRequestManager.getPullRequestStateSetter(setAgeClosedPRInfo,'age','closed').then((res) => {})
             }
         })
 
     }, []);
 
     useEffect(() => {
-        if(viewerIssueInfo.length > 1 || viewerPullRequestInfo.length > 1 || viewerClosedPRInfo.length > 1) {
-            const points = {}
-            const avatars = {}
-            viewerPullRequestInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 100;
-            })
-            viewerClosedPRInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
+        const viewerPts = {}
+        const viewerAvt = {}
+        const viewerLWPT = {}
+        const viewerLWAV = {}
+
+        const agePts = {}
+        const ageAvt = {}
+        const ageLWPT = {}
+        const ageLWAV = {}
+
+        const getPoints = (infos,point,ctrs,avts,lwctrs,lwavts) => {
+            infos.forEach((info) => {
+                if(!info.isLast) {
+                    if (!ctrs[info.login]) {
+                        ctrs[info.login] = 0
+                        avts[info.login] = {avatar: info.avatar, html: info.html};
+                    }
+                    ctrs[info.login] += point;
                 }
-                points[info.login] += 100;
-            })
-            viewerIssueInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
+                if(info.isLast) {
+                    if (!lwctrs[info.login]) {
+                        lwctrs[info.login] = 0
+                        lwavts[info.login] = {avatar: info.avatar, html: info.html};
+                    }
+                    lwctrs[info.login] += point;
                 }
-                points[info.login] += 50;
             })
-            viewerClosedIsInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 50;
+        }
+
+        if(viewerIssueInfo.length > 1 || viewerPullRequestInfo.length > 1 || viewerClosedPRInfo.length > 1 || viewerClosedIsInfo.length > 1) {
+            getPoints(viewerPullRequestInfo,100,viewerPts,viewerAvt,viewerLWPT,viewerLWAV);
+            getPoints(viewerClosedPRInfo,100,viewerPts,viewerAvt,viewerLWPT,viewerLWAV);
+            getPoints(viewerIssueInfo,50,viewerPts,viewerAvt,viewerLWPT,viewerLWAV);
+            getPoints(viewerClosedIsInfo,50,viewerPts,viewerAvt,viewerLWPT,viewerLWAV);
+            const thisTotalPoints = Object.keys(viewerPts).sort(function(x,y) {
+                return viewerPts[y] - viewerPts[x];
             })
-            const totalPoints = Object.keys(points).sort(function(x,y) {
-                return points[y] - points[x];
+            const lastTotalPoints = Object.keys(viewerLWPT).sort(function(x,y) {
+                return viewerLWPT[y] - viewerLWPT[x];
             })
-            if (totalPoints.length < 5) {
-                const tempV = [null,null,null,null,null]
-                tempV.forEach((i) => totalPoints.push(i))
+            if (thisTotalPoints.length < 5) {
+                const tempV = [null,null,null,null,null];
+                tempV.forEach((i) => thisTotalPoints.push(i));
             }
-            setViewerTopContributors(totalPoints.slice(0,5));
-            setViewerAvatar(avatars);
+            if (lastTotalPoints.length < 1) {
+                lastTotalPoints.push(null);
+            }
+            setViewerTopContributors(thisTotalPoints.slice(0,5));
+            setViewerAvatar(viewerAvt);
+            setViewerLastTC(lastTotalPoints.slice(0,1));
+            setViewerLastTCAV(viewerLWAV);
         }
 
-        if(ageIssueInfo.length > 1 || agePullRequestInfo.length > 1 || ageClosedPRInfo.length > 1) {
-            const points = {}
-            const avatars = {}
-            agePullRequestInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 100;
-            })
-            ageClosedPRInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 100;
+        if(ageIssueInfo.length > 1 || agePullRequestInfo.length > 1 || ageClosedPRInfo.length > 1 || ageClosedIssueInfo.length > 1) {
+            getPoints(agePullRequestInfo,100,agePts,ageAvt,ageLWPT,ageLWAV);
+            getPoints(ageClosedPRInfo,100,agePts,ageAvt,ageLWPT,ageLWAV);
+            getPoints(ageIssueInfo,50,agePts,ageAvt,ageLWPT,ageLWAV);
+            getPoints(ageClosedIssueInfo,50,agePts,ageAvt,ageLWPT,ageLWAV);
+            const totalPoints = Object.keys(agePts).sort(function(x,y) {
+                return agePts[y] - agePts[x];
             })
-            ageIssueInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 50;
-            })
-            ageClosedIssueInfo.forEach((info) => {
-                if(!points[info.login]) {
-                    points[info.login] = 0
-                    avatars[info.login] = {avatar: info.avatar, html: info.html};
-                }
-                points[info.login] += 50;
-            })
-            const totalPoints = Object.keys(points).sort(function(x,y) {
-                return points[y] - points[x];
+            const lastTotalPoints = Object.keys(ageLWPT).sort(function(x,y) {
+                return ageLWPT[y] - ageLWPT[x];
             })
             if (totalPoints.length < 5) {
                 const tempV = [null,null,null,null,null]
                 tempV.forEach((i) => totalPoints.push(i))
             }
+            if (lastTotalPoints.length < 1) {
+                lastTotalPoints.push(null);
+            }
             setAgeTopContributors(totalPoints.slice(0,5));
-            setAgeAvatar(avatars);
+            setAgeAvatar(ageAvt);
+            setAgeLastTC(lastTotalPoints.slice(0,1));
+            setAgeLastTCAV(ageLWAV);
         }
 
-        if(viewerTopContributors.length > 1 || ageTopContributors.length > 1) setLoadingYn(false);
+        if(viewerTopContributors.length > 1 && ageTopContributors.length > 1) setLoadingYn(false);
 
-    }, [viewerPullRequestInfo,agePullRequestInfo,ageClosedPRInfo])
+    }, [viewerClosedIsInfo,ageClosedIssueInfo,agePullRequestInfo,ageClosedPRInfo])
 
     return (
         <>
@@ -151,14 +149,24 @@ const Contributors = () => {
                     </div>
                     <div className={styles.root}>
                         <div className={styles.Contributors}>
+                            <WeekContext text={"Previous Week's Top Contributor"} last={true}/>
+                            {ageLastTC?.map((user,index) => (
+                                <ContributorsList index={index} user={user} avatar={ageLastTCAV[user]?.avatar} html={ageLastTCAV[user]?.html} last={true} />
+                            ))}
+                            <WeekContext text={"Current Week"} last={false}/>
                             {ageTopContributors.length > 1 && ageTopContributors?.map((user,index) => (
-                                <ContributorsList index={index} user={user} avatar={ageAvatar[user]?.avatar} html={ageAvatar[user]?.html} />
+                                <ContributorsList index={index} user={user} avatar={ageAvatar[user]?.avatar} html={ageAvatar[user]?.html} last={false} />
                             ))}
                         </div>  
                         <div className={styles.Separator}></div>
                         <div className={styles.Contributors}>
+                            <WeekContext text={"Previous Week's Top Contributor"} last={true}/>
+                            {viewerLastTC?.map((user,index) => (
+                                <ContributorsList index={index} user={user} avatar={viewerLastTCAV[user]?.avatar} html={viewerLastTCAV[user]?.html} last={true} />
+                            ))}
+                            <WeekContext text={"Current Week"} last={false}/>
                             {viewerTopContributors.length > 1 && viewerTopContributors?.map((user,index) => (
-                                <ContributorsList index={index} user={user} avatar={viewerAvatar[user]?.avatar} html={viewerAvatar[user]?.html} />
+                                <ContributorsList index={index} user={user} avatar={viewerAvatar[user]?.avatar} html={viewerAvatar[user]?.html} last={false} />
                             ))}
                         </div>
                     </div>
diff --git a/src/components/ContributorsList.js b/src/components/ContributorsList.js
index 9415aea6..8e64c17a 100644
--- a/src/components/ContributorsList.js
+++ b/src/components/ContributorsList.js
@@ -1,12 +1,13 @@
 import React from 'react';
 import * as styles from './styles/AgeContributors.module.scss';
+import medalImage from '../../static/img/medal.jpg'
 
-const ContributorsList = ({ index, user, avatar, html }) => {
+const ContributorsList = ({ index, user, avatar, html, last }) => {
     return (
-        <div className={styles.Users}>
+        <div className={styles.Users} style={last ? {paddingBottom: "0"} : {paddingBottom: "1.5rem"}}>
             <div className={styles.Rank}>
-                <p>{index+1}</p>
-                <a href={html}><img className={styles.Avatar} src={avatar}></img></a>
+                {last ? <img src={medalImage}></img> : <p>{index+1}</p>}
+                <a href={html} style={avatar ? {visibility: "visible"} : {visibility: "hidden"}}><img className={styles.Avatar} src={avatar}></img></a>
             </div>
             <div className={styles.User}>
                 <p>{user}</p>
diff --git a/src/components/WeekContext.js b/src/components/WeekContext.js
new file mode 100644
index 00000000..a6991a33
--- /dev/null
+++ b/src/components/WeekContext.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import * as styles from './styles/AgeContributors.module.scss';
+
+const WeekContext = ({ text, last }) => {
+    return (
+        <div className={styles.Weeks} style={last ? {color: '#483D8B'} : {color: '#B8145A'}}>
+            <p>{text}</p>
+        </div>
+    )
+}
+
+
+export default WeekContext;
\ No newline at end of file
diff --git a/src/components/styles/AgeContributors.module.scss b/src/components/styles/AgeContributors.module.scss
index 3c894344..1b10babf 100644
--- a/src/components/styles/AgeContributors.module.scss
+++ b/src/components/styles/AgeContributors.module.scss
@@ -13,7 +13,7 @@
   opacity: 1;
   .Contributors {
     width: 100%;
-    padding: 0.5rem 1rem;
+    padding: 0.5rem 0.8rem;
     border: 0.25rem solid $thirdColor;
     border-radius: 1.625rem;
     box-shadow: 0rem 0rem 1.5rem #cf0e5330;
@@ -45,8 +45,14 @@
         justify-content: center;
         >p {
             margin: 0;
+            width: 40px;
+            height: 40px;
+        }
+        >img {
+          width: 40px;
+          height: 35px;
+          object-fit: contain;
         }
-
         .Avatar {
             border-radius: 50%;
             object-fit: contain;
@@ -67,6 +73,15 @@
         }
     }
   }
+  .Weeks {
+    text-align: center;
+    padding: 1rem;
+    >p {
+      font-size: 1.88rem;
+      font-weight: bold;
+      margin: 0;
+    }
+  }
 }
 
 .Repos {
diff --git a/src/templates/index-page.js b/src/templates/index-page.js
index ce429967..113ffad7 100644
--- a/src/templates/index-page.js
+++ b/src/templates/index-page.js
@@ -167,7 +167,7 @@ export const IndexPageTemplate = ({
           <Ageinfos />
           <hr style={{ border: 'solid 1px #9F1A61', margin: '2rem 0', opacity: '0.2' }} />
           <div className={styles.content}>
-            <h2>Top Contributors for the Past 7 Days</h2>
+            <h2>Top GitHub Contributors</h2>
             <p></p>
             <AgeContributors />
           </div>
diff --git a/static/img/medal.jpg b/static/img/medal.jpg
new file mode 100644
index 00000000..8c74d052
Binary files /dev/null and b/static/img/medal.jpg differ