Skip to content

Commit 356e376

Browse files
committed
add country ranks to the profile page
1 parent bf83fcb commit 356e376

File tree

27 files changed

+239
-111
lines changed

27 files changed

+239
-111
lines changed

app/badge/[[...login]]/components/preview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const Preview: FC<LoginFormProps> = ({ githubLogin, githubId }) => {
1010

1111
return (
1212
<div className="flex flex-grow items-start justify-center">
13-
<div className="flex flex-col max-w-lg min-w-xs border-border border-1 rounded-lg p-6 gap-3">
13+
<div className="flex flex-col max-w-lg min-w-xs border-1 rounded-lg p-6 gap-3">
1414
<p className="text-xs">devwizard/README.md</p>
1515
<p className="text-lg font-semibold">Hi, I&apos;m devwizard 👋</p>
1616
<p>

app/components/country-ranking-section.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const CountryRankingSection = async () => {
2222
Curious how you rank at home? Explore country-specific leaderboards to see the top developers in your nation,
2323
track your own standing, and celebrate local talent as it rises on the global stage.
2424
</div>
25-
<div className="grid grid-cols-[repeat(auto-fit,minmax(405px,1fr))] gap-4">
25+
<div className="grid grid-cols-[repeat(auto-fit,minmax(364px,1fr))] gap-4">
2626
{countrySummaries.slice(0, 2).map((countrySummary) => (
2727
<CountryCard key={countrySummary.country} countrySummary={countrySummary} />
2828
))}

app/components/global-ranking-section.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const GlobalRankingSection = () => {
1010
dynamic leaderboards and find out how you measure up against developers worldwide.
1111
</div>
1212
<div className="flex flex-col md:flex-row gap-4">
13-
<Card className="flex-grow border-border gap-4">
13+
<Card className="flex-grow gap-4">
1414
<CardHeader>
1515
<CardTitle>Star ranking</CardTitle>
1616
<CardDescription>
@@ -21,7 +21,7 @@ export const GlobalRankingSection = () => {
2121
<Link href="/by/stars/1">View</Link>
2222
</CardFooter>
2323
</Card>
24-
<Card className="flex-grow border-border gap-4">
24+
<Card className="flex-grow gap-4">
2525
<CardHeader>
2626
<CardTitle>Contribution ranking</CardTitle>
2727
<CardDescription>
@@ -32,7 +32,7 @@ export const GlobalRankingSection = () => {
3232
<Link href="/by/contributions/1">View</Link>
3333
</CardFooter>
3434
</Card>
35-
<Card className="flex-grow border-border gap-4">
35+
<Card className="flex-grow gap-4">
3636
<CardHeader>
3737
<CardTitle>Follower ranking</CardTitle>
3838
<CardDescription>Rank is based on the number of followers the user has on GitHub</CardDescription>

app/country/[name]/[rankingType]/[page]/loading.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { Skeleton } from '@/components/ui/skeleton';
22

33
export default function Loading() {
44
return (
5-
<div className="grid grid-cols-[repeat(auto-fit,minmax(364px,1fr))] gap-4">
6-
{Array.from({ length: 12 }).map((_, index) => (
7-
<Skeleton key={index} className="h-52 w-full" />
8-
))}
5+
<div className="flex flex-col gap-4">
6+
<Skeleton className="h-5 w-full" />
7+
<Skeleton className="h-5 w-full" />
98
</div>
109
);
1110
}

app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import MainImage from './main-image';
1010
export default function Home() {
1111
return (
1212
<>
13-
<div className="border-b border-border bg-linear-45 from-background to-80% to-landing-page-gradient-start-color">
13+
<div className="border-b bg-linear-45 from-background to-80% to-landing-page-gradient-start-color">
1414
<Header />
1515
<Page>
1616
<div className="flex flex-col md:flex-row gap-4 grow items-center">

app/profile/[login]/components/profile-card.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import { FC, ReactNode } from 'react';
1+
import { FC, PropsWithChildren, ReactNode } from 'react';
22

33
import { Card, CardAction, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
44
import { cn } from '@/lib/utils';
55

6+
export const ProfileCardsGrid: FC<PropsWithChildren> = ({ children }) => {
7+
return <div className="grid gap-6 grid-cols-[repeat(auto-fit,minmax(320px,1fr))]">{children}</div>;
8+
};
9+
610
type ProfileCardProps = {
711
title?: string | null;
812
children: ReactNode;
@@ -11,16 +15,7 @@ type ProfileCardProps = {
1115
};
1216

1317
export const ProfileCard: FC<ProfileCardProps> = ({ children, className }) => {
14-
return (
15-
<Card
16-
className={cn(
17-
'border-0 md:border-2 border-border p-0 md:p-4 min-w-xs flex-grow basis-0 shadow-none md:shadow-sm gap-4',
18-
className,
19-
)}
20-
>
21-
{children}
22-
</Card>
23-
);
18+
return <Card className={cn('w-full border-2 p-3 md:p-4 shadow-none md:shadow-sm gap-4', className)}>{children}</Card>;
2419
};
2520

2621
type ProfileCardHeaderProps = {

app/profile/[login]/components/ranks-overview.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ import { ProfileSummaryQuery } from '@/types/generated/graphql';
77
import { ProfileCard, ProfileCardActions, ProfileCardContent, ProfileCardHeader } from './profile-card';
88

99
type RanksOverviewProps = {
10-
ranksData: NonNullable<ProfileSummaryQuery['user']>['rankGlobal'];
11-
login: string;
10+
ranksData:
11+
| NonNullable<ProfileSummaryQuery['user']>['rankGlobal']
12+
| NonNullable<ProfileSummaryQuery['user']>['rankCountry'];
13+
title: string;
14+
detailsLink: string;
1215
};
1316

14-
export const RanksOverview: FC<RanksOverviewProps> = ({ ranksData, login }) => {
17+
export const RanksOverview: FC<RanksOverviewProps> = ({ ranksData, title, detailsLink }) => {
1518
return (
1619
<ProfileCard>
17-
<ProfileCardHeader>Ranks</ProfileCardHeader>
20+
<ProfileCardHeader>{title}</ProfileCardHeader>
1821
<ProfileCardContent>
1922
<div className="flex items-center">
2023
⭐&nbsp;&nbsp;Stars rank:&nbsp;
@@ -35,7 +38,7 @@ export const RanksOverview: FC<RanksOverviewProps> = ({ ranksData, login }) => {
3538
</div>
3639
</ProfileCardContent>
3740
<ProfileCardActions>
38-
<Link href={`/profile/${login}/ranks`}>View Details</Link>
41+
<Link href={detailsLink}>View Details</Link>
3942
</ProfileCardActions>
4043
</ProfileCard>
4144
);

app/profile/[login]/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async function ProfileLayoutAwaitParams({ children, params }: ProfileLayoutProps
4545
<>
4646
<Header login={login} />
4747
<TabsBar className="mb-4">
48-
<Tab href={`/profile/${login}`} active>
48+
<Tab href={`/profile/${login}`} exact>
4949
Overview
5050
</Tab>
5151
<Tab href={`/profile/${login}/ranks`}>Ranks</Tab>

app/profile/[login]/loading.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Skeleton } from '@/components/ui/skeleton';
22

3+
import { ProfileCardsGrid } from './components/profile-card';
34
import {
45
AvatarAndNameContainer,
56
AvatarContainer,
@@ -28,10 +29,10 @@ export default function Loading() {
2829
</DetailsContainer>
2930
</LeftColumnContainer>
3031
<div className="flex-grow flex flex-col gap-6">
31-
<div className="flex flex-col md:flex-row flex-wrap gap-6">
32-
<Skeleton className="h-[150px] grow min-w-xs rounded-xl" />
33-
<Skeleton className="h-[150px] grow min-w-xs rounded-xl" />
34-
</div>
32+
<ProfileCardsGrid>
33+
<Skeleton className="h-[150px] rounded-xl" />
34+
<Skeleton className="h-[150px] rounded-xl" />
35+
</ProfileCardsGrid>
3536
</div>
3637
</PageContainer>
3738
);

app/profile/[login]/page.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { unstable_cacheLife as cacheLife, unstable_cacheTag as cacheTag } from '
55
import { notFound } from 'next/navigation';
66

77
import { LayoutLeftColumn } from './components/layout-left-column';
8+
import { ProfileCardsGrid } from './components/profile-card';
89
import { ProfileTimeline } from './components/profile-timeline';
910
import { RanksOverview } from './components/ranks-overview';
1011
import { RepositoriesOverview } from './components/repositories-overiview';
@@ -50,8 +51,15 @@ export default async function Profile({ params }: { params: Promise<{ login: str
5051
return (
5152
<LayoutLeftColumn user={user}>
5253
<div className="flex-grow flex flex-col gap-6">
53-
<div className="flex flex-col md:flex-row flex-wrap gap-6">
54-
<RanksOverview ranksData={user.rankGlobal} login={login} />
54+
<ProfileCardsGrid>
55+
<RanksOverview title="Global Ranks" ranksData={user.rankGlobal} detailsLink={`/profile/${login}/ranks`} />
56+
{user.rankCountry && (
57+
<RanksOverview
58+
title={`Ranks in ${user.country}`}
59+
ranksData={user.rankCountry}
60+
detailsLink={`/profile/${login}/ranks/country`}
61+
/>
62+
)}
5563
<RepositoriesOverview
5664
topRepoStars={user.repositories?.[0]?.stargazerCount ?? 0}
5765
contributedRepoCount={user.contributedRepoCount}
@@ -60,7 +68,7 @@ export default async function Profile({ params }: { params: Promise<{ login: str
6068
c={user.c}
6169
login={login}
6270
/>
63-
</div>
71+
</ProfileCardsGrid>
6472
<div>
6573
<ProfileTimeline timeline={user.timeline} firstSeenAt={user.firstSeenAt} />
6674
</div>

0 commit comments

Comments
 (0)