-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(community): add userCard component * feat(community): add userList component * feat(community): add user page * fix(community): rename getUser function * feat(design-system): add box-shadow tokens * refactor(community): rename MyPage and related components for clarity * Update apps/community/src/app/my/page.tsx * feat(community): add list card component and implement edit functionality * feat(design-system): add outline variant to button component * feat(community): update MyInfoCard styles and button variants * feat(community): refactor MyInfoCard and improve edit functionality * feat(design-system): enhance input component styles for disabled and focus states * refactor(community): update export method of MyInfoCardList component * feat(community): split MyInfoCardList into two components --------- Co-authored-by: JaeguJaegu <[email protected]> Co-authored-by: Gwansik Kim <[email protected]>
- Loading branch information
1 parent
b96af6c
commit f20df13
Showing
15 changed files
with
336 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const myProfile = { | ||
name: '강민하', | ||
phone: '010-0000-0000', | ||
email: '[email protected]', | ||
role: '학부생', | ||
major: '컴퓨터공학부', | ||
id: '201912000', | ||
}; | ||
|
||
export { myProfile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { myProfile } from './data'; | ||
|
||
export function GET() { | ||
return Response.json({ data: myProfile }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { MyInfoEditableProfileCard } from '~/components/my/my-info-editable-profile-card'; | ||
import { MyInfoProfileCard } from '~/components/my/my-info-profile-card'; | ||
import { PageHeader } from '~/components/page-header'; | ||
import { getMyProfile } from './remotes'; | ||
|
||
// TODO: for mocking but will be replaced with a proper solution later | ||
export const dynamic = 'force-dynamic'; | ||
|
||
export default async function MyPage() { | ||
const { data } = await getMyProfile(); | ||
|
||
const userDetails = [ | ||
{ title: '이름', value: data.name }, | ||
{ title: '학번', value: data.id }, | ||
{ title: '구분', value: data.role }, | ||
{ title: '전공', value: data.major }, | ||
]; | ||
|
||
const userEditableDetails = [ | ||
{ title: '전화번호', value: data.phone }, | ||
{ title: '이메일', value: data.email }, | ||
]; | ||
|
||
return ( | ||
<> | ||
<PageHeader | ||
title="회원 정보" | ||
description="등록한 회원 정보를 확인할 수 있어요." | ||
/> | ||
<MyInfoProfileCard data={userDetails} /> | ||
<MyInfoEditableProfileCard data={userEditableDetails} /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 MyProfile { | ||
id: string; | ||
name: string; | ||
phone: string; | ||
email: string; | ||
role: string; | ||
major: string; | ||
} | ||
|
||
function getMyProfile() { | ||
return http.get<MyProfile>(MOCK_END_POINT.MY_PROFILE); | ||
} | ||
|
||
export { type MyProfile, getMyProfile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { screen, themeVars } from '@aics-client/design-system/styles'; | ||
import { style, styleVariants } from '@vanilla-extract/css'; | ||
|
||
const cardWrapper = style({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: themeVars.spacing.lg, | ||
marginBottom: themeVars.spacing.xl, | ||
padding: themeVars.spacing.xl, | ||
border: `1px solid ${themeVars.color.gray300}`, | ||
borderRadius: themeVars.borderRadius.xl, | ||
boxShadow: themeVars.boxShadow.md, | ||
}); | ||
|
||
const cardTitle = style({ | ||
marginBottom: themeVars.spacing.lg, | ||
fontSize: themeVars.fontSize.xl, | ||
fontWeight: themeVars.fontWeight.bold, | ||
}); | ||
|
||
const cardContent = styleVariants({ | ||
default: { | ||
display: 'grid', | ||
gridTemplateColumns: 'repeat(2, 1fr)', | ||
gap: themeVars.spacing.lg, | ||
}, | ||
singleColumn: { | ||
display: 'grid', | ||
gridTemplateColumns: '1fr', | ||
gap: themeVars.spacing.lg, | ||
}, | ||
}); | ||
|
||
const field = style({ | ||
margin: '1.5rem 0', | ||
}); | ||
|
||
const fieldTitle = style({ | ||
width: '6rem', | ||
fontSize: themeVars.fontSize.lg, | ||
fontWeight: themeVars.fontWeight.semibold, | ||
}); | ||
|
||
const editFieldWrapper = style({ | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'space-between', | ||
}); | ||
|
||
const editFieldContent = style({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: themeVars.spacing.lg, | ||
|
||
...screen.md({ | ||
display: 'flex', | ||
flexDirection: 'row', | ||
alignItems: 'center', | ||
justifyContent: 'space-between', | ||
}), | ||
}); | ||
|
||
const editField = style({ | ||
width: '15rem', | ||
|
||
...screen.md({ | ||
width: '20rem', | ||
}), | ||
}); | ||
|
||
const buttonWrapper = style({ | ||
display: 'flex', | ||
margin: '1rem 0', | ||
gap: themeVars.spacing.sm, | ||
}); | ||
|
||
export { | ||
cardWrapper, | ||
cardTitle, | ||
cardContent, | ||
field, | ||
fieldTitle, | ||
editFieldWrapper, | ||
editFieldContent, | ||
editField, | ||
buttonWrapper, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
'use client'; | ||
|
||
import { Button, Input } from '@aics-client/design-system'; | ||
import { useState } from 'react'; | ||
import * as styles from '~/components/my/my-info-card.css'; | ||
|
||
interface MyInfoCardProps { | ||
title: string; | ||
layout?: 'default' | 'singleColumn'; | ||
children: React.ReactNode; | ||
} | ||
|
||
interface MyInfoFieldProps { | ||
title: string; | ||
value: string; | ||
} | ||
|
||
interface MyInfoEditableFieldProps extends MyInfoFieldProps { | ||
onSave?: (value: string) => void; | ||
} | ||
|
||
function MyInfoCard({ title, children, layout = 'default' }: MyInfoCardProps) { | ||
return ( | ||
<div className={styles.cardWrapper}> | ||
<h2 className={styles.cardTitle}>{title}</h2> | ||
<div className={styles.cardContent[layout]}>{children}</div> | ||
</div> | ||
); | ||
} | ||
|
||
function MyInfoField({ title, value }: MyInfoFieldProps) { | ||
return ( | ||
<div> | ||
<h3 className={styles.fieldTitle}>{title}</h3> | ||
<p className={styles.field}>{value}</p> | ||
</div> | ||
); | ||
} | ||
|
||
function MyInfoEditableField({ | ||
title, | ||
value, | ||
onSave, | ||
}: MyInfoEditableFieldProps) { | ||
const [isEditing, setIsEditing] = useState(false); | ||
const [currentValue, setCurrentValue] = useState(value); | ||
|
||
const handleEditToggle = () => setIsEditing((prev) => !prev); | ||
const handleSave = () => { | ||
setIsEditing(false); | ||
onSave?.(currentValue); | ||
}; | ||
|
||
return ( | ||
<div className={styles.editFieldWrapper}> | ||
<div className={styles.editFieldContent}> | ||
<h3 className={styles.fieldTitle}>{title}</h3> | ||
<Input | ||
className={styles.editField} | ||
type="text" | ||
value={currentValue} | ||
placeholder={value} | ||
onChange={(e) => setCurrentValue(e.target.value)} | ||
disabled={!isEditing} | ||
/> | ||
</div> | ||
|
||
<div className={styles.buttonWrapper}> | ||
{isEditing ? ( | ||
<> | ||
<Button size="sm" color="outline" onClick={handleSave}> | ||
저장 | ||
</Button> | ||
<Button size="sm" color="outline" onClick={handleEditToggle}> | ||
취소 | ||
</Button> | ||
</> | ||
) : ( | ||
<Button size="sm" color="outline" onClick={handleEditToggle}> | ||
변경 | ||
</Button> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
MyInfoCard.Field = MyInfoField; | ||
MyInfoCard.EditableField = MyInfoEditableField; | ||
|
||
export { MyInfoCard }; |
32 changes: 32 additions & 0 deletions
32
apps/community/src/components/my/my-info-editable-profile-card.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use client'; | ||
|
||
import { MyInfoCard } from '~/components/my/my-info-card'; | ||
|
||
interface Props { | ||
data: { | ||
title: string; | ||
value: string; | ||
}[]; | ||
} | ||
|
||
function MyInfoEditableProfileCard({ data }: Props) { | ||
const handleSave = (field: string, value: string) => { | ||
// TODO: 필요한 서버 API 호출 로직 추가 | ||
console.log(`${field} 저장: ${value}`); | ||
}; | ||
|
||
return ( | ||
<MyInfoCard title="기본 정보" layout="singleColumn"> | ||
{data.map((detail) => ( | ||
<MyInfoCard.EditableField | ||
key={detail.title} | ||
title={detail.title} | ||
value={detail.value} | ||
onSave={(value) => handleSave(detail.title, value)} | ||
/> | ||
))} | ||
</MyInfoCard> | ||
); | ||
} | ||
|
||
export { MyInfoEditableProfileCard }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
'use client'; | ||
|
||
import { MyInfoCard } from '~/components/my/my-info-card'; | ||
|
||
interface Props { | ||
data: { | ||
title: string; | ||
value: string; | ||
}[]; | ||
} | ||
|
||
function MyInfoProfileCard({ data }: Props) { | ||
return ( | ||
<MyInfoCard title="내 프로필" layout="default"> | ||
{data.map((detail) => ( | ||
<MyInfoCard.Field | ||
key={detail.title} | ||
title={detail.title} | ||
value={detail.value} | ||
/> | ||
))} | ||
</MyInfoCard> | ||
); | ||
} | ||
|
||
export { MyInfoProfileCard }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.