Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : create aside component #81

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
191 changes: 191 additions & 0 deletions src/components/Aside/Aside.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
aside {
position: sticky;
top: 87px;
width: 250px;
height: calc(100vh - 40px);
overflow-y: auto;
align-items: center;
}

.cohort {
display: flex;
justify-content: flex-end;
}

.container {
top: 230px;
left: 20px;
width: 250px;
padding: 20px 35px;
background-color: var(--bg-200);
border-radius: 10px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}

.profile {
position: relative;
text-align: center;
margin-bottom: 25px;
}

.avatar {
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}

.avatar img {
position: absolute;
width: 70px;
height: 70px;
border-radius: 50%;
}

.progress-circle {
width: 90px;
height: 90px;
border-radius: 50%;
background: conic-gradient(
from 180deg,
var(--secondary) 0%,
var(--primary) var(--progress),
var(--bg-200) var(--progress)
);
}

.progress-text {
position: absolute;
bottom: -20px;
left: 50%;
transform: translateX(-50%);
font-size: 14px;
font-weight: bold;
color: var(--text-secondary);
}

.username {
font-size: 14px;
color: var(--text-secondary);
}

.currentStatus {
display: flex;
justify-content: center;
margin-bottom: 35px;
padding-bottom: 31px;
border-bottom: 2px solid #846de9;
}

.currentStatus img {
width: 64px;
height: 64px;
}

.taskCounts {
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 50px;
margin-bottom: 35px;
gap: 35px;
font-size: 20px;
font-weight: var(--font-weight-bold);
}

.task {
display: flex;
flex-direction: column;
align-items: center;
font-size: 14px;
font-weight: bold;
gap: 5px;
}

.easy {
color: #1cbaba;
}

.medium {
color: #ffb700;
}

.hard {
color: #f63737;
}

.gradientText {
background: linear-gradient(to right, #24faca, #846de9);
color: transparent;
background-clip: text;
font-size: 17px;
}

.solidText {
font-size: 13px;
}

.returnButtonLink {
display: block;
width: 80%;
padding: 10px 0;
border: 1px solid var(--primary);
border-radius: 10px;
color: var(--primary) !important;
font-size: 14px;
text-align: center;
margin-top: 20px;
margin-left: auto;
margin-right: auto;

&:hover {
background-color: var(--primary);
color: white !important;
}

&:active {
font-weight: var(--font-weight-bold);
color: var(--primary) !important;
background-color: white;
text-decoration: underline;
}
}

.problemButtonLink {
display: block;
padding: 10px 0;
background-color: var(--primary);
border: 1px solid var(--primary);
border-radius: 10px;
color: white !important;
font-size: 14px;
font-weight: bold;
text-align: center;
margin-top: 20px;
margin-left: auto;
margin-right: auto;

&:hover {
background-color: var(--tertiary);
color: white !important;
}

&:active {
background-color: var(--primary);
font-weight: var(--font-weight-bold);
text-decoration: underline;
}
}

.githubLinkWrapper {
margin-top: 10px;

.githubLink {
margin-top: 10px;
align-items: center;
img {
transform: translateY(8px);
}
}
}
47 changes: 47 additions & 0 deletions src/components/Aside/Aside.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Meta, StoryObj } from "@storybook/react";
import Aside from "./Aside";
import { Grade } from "../../api/services/common/types.ts";

const meta = {
component: Aside,
} satisfies Meta<typeof Aside>;

export default meta;

export const Default: StoryObj<typeof meta> = {
args: {
githubUsername: "testuser",
easyProgress: "5/10",
mediumProgress: "8/10",
hardProgress: "3/5",
solvedTasks: 16,
totalTasks: 25,
profile_url: "https://example.com/profile.jpg", // Provide a valid URL or mock
cohort: 3,
grade: Grade.SMALL_TREE, // Assign an appropriate grade here
},
};

export const HighProgress: StoryObj<typeof meta> = {
args: {
...Default.args,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/DaleStudy/leaderboard/pull/72/files#r1845802404
달레님 리뷰개선안인데요. meta에서 args를 선언해주면 매번 초기화를 안할 수 있어요!

solvedTasks: 28,
totalTasks: 30,
easyProgress: "10/10",
mediumProgress: "10/10",
hardProgress: "8/10",
grade: Grade.BIG_TREE, // Higher grade for more progress
},
};

export const NoTasks: StoryObj<typeof meta> = {
args: {
...Default.args,
easyProgress: "0/0",
mediumProgress: "0/0",
hardProgress: "0/0",
solvedTasks: 0,
totalTasks: 0,
grade: Grade.SEED, // Minimal grade due to no tasks solved
},
};
63 changes: 63 additions & 0 deletions src/components/Aside/Aside.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { test, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import Aside from "./Aside";
import { Grade } from "../../api/services/common/types.ts";

test("renders the Aside component", () => {
render(
<Aside
githubUsername="testuser"
easyProgress="10/15"
mediumProgress="5/10"
hardProgress="2/5"
solvedTasks={17}
totalTasks={30}
profile_url="https://example.com/profile.jpg"
cohort={3}
grade={Grade.SMALL_TREE}
/>,
);

const aside = screen.getByRole("complementary");
expect(aside).toBeInTheDocument();
});

test("displays the username", () => {
render(
<Aside
githubUsername="testuser"
easyProgress="10/15"
mediumProgress="5/10"
hardProgress="2/5"
solvedTasks={17}
totalTasks={30}
profile_url="https://example.com/profile.jpg"
cohort={3}
grade={Grade.SMALL_TREE}
/>,
);

const username = screen.getByText(/testuser/i);
expect(username).toBeInTheDocument();
});

test("renders the button link with the text", () => {
render(
<Aside
githubUsername="testuser"
easyProgress="10/15"
mediumProgress="5/10"
hardProgress="2/5"
solvedTasks={17}
totalTasks={30}
profile_url="https://example.com/profile.jpg"
cohort={3}
grade={Grade.SMALL_TREE}
/>,
);

const buttonLink = screen.getByRole("link", {
name: /리더보드로 돌아가기/i,
});
expect(buttonLink).toBeInTheDocument();
});
Loading