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(community): 마이 페이지 추가 #38

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
10 changes: 10 additions & 0 deletions apps/community/src/app/api/mock/users/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const user = {
name: '강민하',
phone: '010-0000-0000',
email: 'aics1204@kyonggi.ac.kr',
role: '학부생',
major: '컴퓨터공학부',
id: '201912000',
};

export { user };
5 changes: 5 additions & 0 deletions apps/community/src/app/api/mock/users/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { user } from './data';

export function GET() {
return Response.json({ data: user });
}
36 changes: 36 additions & 0 deletions apps/community/src/app/users/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { PageHeader } from '~/components/page-header';
import { UserCard } from '~/components/users/user-card';
import { UserList } from '~/components/users/user-list';
import { getUser } from './remotes';

// TODO: for mocking but will be replaced with a proper solution later
export const dynamic = 'force-dynamic';

export default async function UserPage() {
const { data } = await getUser();

const userDetails = [
{ title: '이름', value: data.name },
{ title: '학번', value: data.id },
{ title: '전화번호', value: data.phone },
{ title: '이메일', value: data.email },
{ title: '구분', value: data.role },
{ title: '전공', value: data.major },
];

return (
<>
<PageHeader
title="회원 정보"
description="등록한 회원 정보를 확인할 수 있어요."
/>
<UserCard>
{userDetails.map((detail) => (
<UserList key={detail.title} title={detail.title}>
<UserList.Row>{detail.value}</UserList.Row>
</UserList>
))}
</UserCard>
</>
);
}
17 changes: 17 additions & 0 deletions apps/community/src/app/users/remotes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MOCK_END_POINT } from '~/constants/api';
import { http } from '~/utils/http';

interface User {
id: string;
name: string;
phone: string;
email: string;
role: string;
major: string;
}

function getUser() {
return http.get<User>(MOCK_END_POINT.USERS);
}

export { type User, getUser };
27 changes: 27 additions & 0 deletions apps/community/src/components/users/user-card.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { themeVars } from '@aics-client/design-system/styles';
import { style } from '@vanilla-extract/css';

const cardWrapper = style({
display: 'flex',
flexDirection: 'column',
gap: themeVars.spacing.lg,
padding: themeVars.spacing.xl,
border: `1px solid ${themeVars.color.gray300}`,
borderRadius: themeVars.borderRadius.xl,
boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',
Copy link
Contributor

Choose a reason for hiding this comment

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

box-shadow를 토큰화 하는 건 어떨까요? 다른 분들의 의견이 궁금합니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

좋은생각같아요 ~ 다른 분들도 동의하시면 이번 PR에 반영해서 올리겠습니다 !
@gwansikk @wontory

Copy link
Member

Choose a reason for hiding this comment

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

동의합니다. 토큰화 된다면 더욱 편리하게 사용할 수 있을거 같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

해당 부분 추가했습니다 ~

});

const cardTitle = style({
marginBottom: themeVars.spacing.lg,
fontSize: themeVars.fontSize['2xl'],
fontWeight: themeVars.fontWeight.bold,
});

const cardContent = style({
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: themeVars.spacing.lg,
fontSize: themeVars.fontSize.lg,
});

export { cardWrapper, cardTitle, cardContent };
16 changes: 16 additions & 0 deletions apps/community/src/components/users/user-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as style from '~/components/users/user-card.css';

interface Props {
children: React.ReactNode;
}

function UserCard({ children }: Props) {
return (
<div className={style.cardWrapper}>
<h2 className={style.cardTitle}>내 프로필</h2>
<div className={style.cardContent}>{children}</div>
</div>
);
}

export { UserCard };
17 changes: 17 additions & 0 deletions apps/community/src/components/users/user-list.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { themeVars } from '@aics-client/design-system/styles';
import { style } from '@vanilla-extract/css';

const list = style({
margin: '1.5rem 0',
padding: 0,
});

const listTitle = style([
themeVars.textSize.xl,
{
fontWeight: themeVars.fontWeight.semibold,
marginBottom: 0,
},
]);

export { list, listTitle };
23 changes: 23 additions & 0 deletions apps/community/src/components/users/user-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as styles from '~/components/users/user-list.css';

interface Props {
title: string;
children: React.ReactNode;
}

function UserList({ title, children }: Props) {
Copy link
Member

Choose a reason for hiding this comment

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

UserList라는 이름은 명확하지 않다고 생각해요. 실제로는 유저 정보를 하나씩 표시해주고 있는데 UserList라고 명명하나 이유가 있나요?

Copy link
Member Author

@m2na7 m2na7 Dec 3, 2024

Choose a reason for hiding this comment

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

MyInfoField라는 이름으로 수정하여 역할을 명확히 했습니다. 좋은 의견 감사합니다 !

return (
<div>
<h3 className={styles.listTitle}>{title}</h3>
<ul className={styles.list}>{children}</ul>
</div>
);
}

function Row({ children }: { children: React.ReactNode }) {
return <li>{children}</li>;
}

UserList.Row = Row;

export { UserList };
Copy link
Member

Choose a reason for hiding this comment

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

<UserList key={detail.title} title={detail.title}>
  <UserList.Row>{detail.value}</UserList.Row>
</UserList>

컴파운드 패턴을 사용하신 이유가 궁금합니다. 실제 사용할때 위와 같이 이터레이션을 하고 있는데 Row를 여러 개 사용할 유즈-케이스가 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

초기 설계할 때 여러 Row를 가지는 리스트가 존재했어요.
이후에 변경되었고 패턴을 수정하지 않고 계속 사용했네요. 수정하겠습니다 ~!

1 change: 1 addition & 0 deletions apps/community/src/constants/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const MOCK_END_POINT = {
PROFESSORS: `${MOCK_BASE_URL}/professors`,
CLUB: `${MOCK_BASE_URL}/about/club`,
CONTACT: `${MOCK_BASE_URL}/about/contact`,
USERS: `${MOCK_BASE_URL}/users`,
} as const;

export { MOCK_BASE_URL, MOCK_END_POINT };