Skip to content
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
1 change: 1 addition & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference lib="dom" />

import "../src/index.css";
import "daleui/styles.css";
import type { Preview } from "@storybook/react-vite";
import { initialize, mswLoader } from "msw-storybook-addon";
import { useEffect } from "react";
Expand Down
191 changes: 186 additions & 5 deletions bun.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
},
"dependencies": {
"@apollo/client": "^3.13.8",
"daleui": "^0.0.6",
"graphql": "^16.11.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"devDependencies": {
"@chromatic-com/storybook": "^4.1.3",
Expand Down
1 change: 1 addition & 0 deletions src/certificate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import Certificate from "./pages/Certificate/Certificate";
import "./index.css";
import "daleui/styles.css";

createRoot(document.getElementById("root")!).render(
<StrictMode>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Card/Card.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@
margin-top: 20px;
}
}

.widthFull {
width: 100%;
}
67 changes: 31 additions & 36 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Card, Flex, Icon } from "daleui";
import type { Grade } from "../../api/services/types";
import GradeImage from "../GradeImage/GradeImage";
import Link from "../Link/Link";
import styles from "./Card.module.css";

interface CardProps {
Expand All @@ -10,42 +10,37 @@ interface CardProps {
grade: Grade;
}

export default function Card({ id, name, cohorts, grade }: CardProps) {
export default function CardComponent({ id, name, cohorts, grade }: CardProps) {
const cohortString = cohorts.join(", ");
return (
<article className={styles.item} aria-label={`${name}의 카드`}>
<GradeImage grade={grade} width={105} height={128} />

<section className={styles.content}>
<div className={styles.nameCohortWrapper}>
<section>
<div className={styles.iconWrapper}>
<img src="/github-icon-in-card.svg" alt="깃허브 아이콘" />
</div>
<span>{name}</span>
</section>

<section>
<div className={styles.iconWrapper}>
<img src="/flag-icon.svg" alt="깃발 아이콘" />
</div>
<span>{cohortString}기</span>
</section>
</div>

<section className={styles.links}>
<Link href={`/progress?member=${id}`} variant="primaryButton">
풀이 현황
</Link>
<Link
href={`/certificate?member=${id}`}
variant="primaryButton"
disabled={["SEED", "SPROUT", "LEAF"].includes(grade)}
>
수료증
</Link>
</section>
</section>
</article>
<Card id={id} tone="brand" outline={true}>
<Flex gap="16">
<GradeImage grade={grade} width={105} height={128} />
<Card.Body>
<Card.Title>
<Flex align="center" gap="4">
<Icon name="GitHub" size="lg" />
<span>{name}</span>
</Flex>
</Card.Title>
<Card.Description>
<Flex align="center" gap="4">
<div className={styles.iconWrapper}>
<img src="/flag-icon.svg" alt="깃발 아이콘" />
</div>
{cohortString}기
</Flex>
</Card.Description>
</Card.Body>
</Flex>
<Flex gap="16" justify="end" className={styles.widthFull}>
<Card.Link href={`/progress?member=${id}`} external>
풀이 현황
</Card.Link>
{!["SEED", "SPROUT", "LEAF"].includes(grade) && (
<Card.Link href={`/certificate?member=${id}`}>수료증</Card.Link>
)}
</Flex>
</Card>
);
}
104 changes: 39 additions & 65 deletions src/components/Footer/Footer.module.css
Original file line number Diff line number Diff line change
@@ -1,82 +1,56 @@
.footer {
background-color: var(--text-900);

padding: 81px 27px;

@media (min-width: 768px) {
display: flex;
flex-direction: column;
align-items: center;

padding: 172px 0 99px;
}

section {
display: flex;
row-gap: 61px;

flex-direction: column;

@media (min-width: 768px) {
width: 80%;
justify-content: space-between;

flex-direction: row;
}
}

p {
font-size: 14px;
line-height: 18px;
color: rgba(253, 253, 255, 0.75);
border-top: 1px solid rgba(253, 253, 255, 0.2);
margin-bottom: 0;

margin-top: 20px;
padding-top: 20px;
background-color: var(--colors-bg-solid-neutral);
color: var(--colors-fg-solid-neutral);
}

@media (min-width: 768px) {
width: 80%;
.footerTop {
padding: 32px;
display: flex;
flex-direction: column;
align-items: stretch;

margin-top: 43px;
padding-top: 48px;
}
@media (min-width: 1100px) {
flex-direction: row;
padding: 80px 32px 0 32px;
}
}

.leftMenu {
.footerTopLeftMenu {
display: flex;
vertical-align: middle;
row-gap: 10px;

flex-direction: column;
padding-left: 4px;

li {
a,
a:visited {
color: var(--bg-100);
}
align-items: start;
gap: 8px;
@media (min-width: 1100px) {
flex-direction: row;
gap: 40px;
}
}

@media (min-width: 768px) {
column-gap: 80px;
flex-direction: row;
align-items: center;
padding-left: 0px;
.footerTopRightMenu {
display: flex;
align-items: flex-end;
@media (max-width: 1100px) {
padding: 40px 16px;
border-bottom: 1px solid var(--colors-fg-solid-neutral);
}
}

.rightMenu {
.footerTopLabel {
font-size: var(--font-sizes-md);
font-weight: var(--font-weights-medium);
line-height: var(--line-heights-tight);
letter-spacing: var(--letter-spacings-balanced);
}

.footerBottom {
padding-bottom: 32px;
display: flex;
flex-direction: column;
align-items: center;
column-gap: 40px;

li {
a {
display: flex;
align-items: center;
justify-content: center;
}
gap: 16px;
@media (min-width: 1100px) {
flex-direction: row;
justify-content: space-between;
padding: 60px 32px 40px;
}
}
52 changes: 30 additions & 22 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Link from "../Link/Link";
import { Box, Link, Flex, HStack, Icon } from "daleui";
import styles from "./Footer.module.css";

export default function Footer() {
Expand Down Expand Up @@ -43,35 +43,43 @@ export default function Footer() {
];

return (
<footer className={styles.footer} aria-label="사이트 푸터">
<section>
<ul className={styles.leftMenu}>
{leftMenu.map(({ label, link }) => (
<li key={link}>
<Box as="footer" aria-label="사이트 푸터" className={styles.footer}>
<Flex className={styles.footerTop} align="end" justify="between">
<Flex direction="column" gap="16" align="start">
<span className={styles.footerTopLabel}>바로가기</span>
<HStack className={styles.footerTopLeftMenu}>
{leftMenu.map(({ label, link }) => (
<Link
variant="text"
key={label}
href={link}
target="_blank"
aria-label={label}
external
>
{label}
<Icon name="externalLink" size="md" />
</Link>
</li>
))}
</ul>

<ul className={styles.rightMenu}>
))}
</HStack>
</Flex>
<HStack gap="32" className={styles.footerTopRightMenu}>
{rightMenu.map(({ label, link, component }) => (
<li key={link}>
<Link href={link} target="_blank" aria-label={label}>
{component}
</Link>
</li>
<Link
key={label}
href={link}
target="_blank"
aria-label={label}
external
>
{component}
</Link>
))}
</ul>
</section>

<p>© 2024 DaleStudy. All rights reserved.</p>
</footer>
</HStack>
</Flex>
<HStack className={styles.footerBottom}>
<span>© 2024 DaleStudy. All rights reserved.</span>
<Icon name="sun" />
</HStack>
</Box>
);
}
77 changes: 2 additions & 75 deletions src/components/Header/Header.module.css
Original file line number Diff line number Diff line change
@@ -1,76 +1,3 @@
.headerWrapper {
display: flex;
position: fixed;
top: 0;
left: 0;
color: var(--text-900);
padding: 20px 0;
font-weight: var(--font-weight-medium);
width: 100%;
border-bottom: 1px solid var(--bg-300);
background-color: var(--bg-200);
z-index: var(--z-index-header);

& > div {
display: flex;
margin: 0 auto;
justify-content: space-between;
align-items: center;
width: 80%;
}
}

.logoLink {
display: flex;
gap: 10px;
align-items: center;
text-decoration: none;
padding: 10px 5px;
font-weight: var(--font-weight-medium);

span {
display: none;
@media only screen and (min-width: 768px) {
display: inline;
font-size: 20px;
}
}

svg {
width: 45px;
}

&:hover {
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
@media only screen and (min-width: 768px) {
box-shadow: none;
font-weight: var(--font-weight-bold);
}
}

&:active {
svg path {
fill: var(--text-900);
}

@media only screen and (min-width: 768px) {
svg path {
fill: url(#paint0_linear_278_133); /* Reset to original colour */
}
}

outline: 3px solid var(--primary);
outline-offset: 2px;
border-radius: 10px;
}

&:focus-visible {
outline: 3px solid var(--primary);
outline-offset: 2px;
border-radius: 10px;
}

&:active span {
color: var(--primary);
}
.header {
border-bottom: 1px solid var(--colors-fg-solid-neutral);
}
4 changes: 2 additions & 2 deletions src/components/Header/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ test("renders the page header", () => {

test("renders the link with correct href and accessible label", () => {
render(<Header />);
const linkElement = screen.getByRole("link", { name: /홈페이지로 이동/i });
expect(linkElement).toHaveAttribute("href", "http://www.dalestudy.com");
const linkElement = screen.getByRole("link", { name: /리더보드로 이동/i });
expect(linkElement).toHaveAttribute("href", "/");
});
Loading
Loading