-
Notifications
You must be signed in to change notification settings - Fork 4
[Feat] 이용약관 및 개인정보처리방침 모달, 페이지 구현 #162
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
Changes from 10 commits
d7e19f3
2b90d5a
235820f
4a403e8
2a2fb47
405f84b
7ba628d
4ad1dda
4e6ad76
aa3002f
3eb508f
421908a
dd9b4f9
2ff1fc6
06667ad
0f6e5dd
4658aea
6919883
b246e98
6649060
7b0c65a
ad92565
7d20951
c563804
9a94bbd
e50c4b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| import { style } from "@vanilla-extract/css"; | ||
| import { recipe } from "@vanilla-extract/recipes"; | ||
|
|
||
| import { themeVars } from "@/app/styles"; | ||
|
|
||
| export const wrapper = style({ | ||
| width: "40rem", | ||
| paddingBottom: "1.6rem", | ||
| }); | ||
|
|
||
| export const modalHeader = style({ | ||
| width: "100%", | ||
| position: "relative", | ||
| display: "flex", | ||
| justifyContent: "center", | ||
| alignItems: "center", | ||
| padding: "1.6rem", | ||
| borderBottom: `1px solid ${themeVars.color.normal}`, | ||
| ...themeVars.fontStyles.hline_b_18, | ||
| }); | ||
|
|
||
| export const buttonWrapper = style({ | ||
| position: "absolute", | ||
| right: "1.6rem", | ||
| width: "2.4rem", | ||
| height: "2.4rem", | ||
| }); | ||
|
|
||
| export const modalCotent = style({ | ||
| display: "flex", | ||
| flexDirection: "column", | ||
| gap: "2.4rem", | ||
| textAlign: "left", | ||
| height: "28rem", | ||
| padding: "2rem 3rem", | ||
| marginBottom: "2rem", | ||
| overflowY: "auto", | ||
|
|
||
| selectors: { | ||
| "&::-webkit-scrollbar": { | ||
| width: "1.2rem", | ||
| }, | ||
| "&::-webkit-scrollbar-thumb": { | ||
| backgroundColor: themeVars.color.gray300, | ||
| height: "50px", | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| borderRadius: "100px", | ||
| backgroundClip: "padding-box", | ||
| border: `4px solid transparent`, | ||
| }, | ||
| "&::-webkit-scrollbar-track": { | ||
| backgroundColor: "transparent", | ||
| margin: "0.8rem 1.2rem", | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| export const title = style({ | ||
| color: themeVars.color.gray800, | ||
| ...themeVars.fontStyles.body_b_14, | ||
| fontWeight: 600, | ||
| marginBottom: "0.8rem", | ||
| }); | ||
|
|
||
| export const subTitle = style({ | ||
| color: themeVars.color.gray800, | ||
| ...themeVars.fontStyles.cap_m_12, | ||
| fontWeight: 500, | ||
| }); | ||
|
|
||
| export const content = style({ | ||
| display: "flex", | ||
| flexDirection: "column", | ||
| color: themeVars.color.gray500, | ||
| ...themeVars.fontStyles.cap_m_12, | ||
| fontWeight: 500, | ||
| whiteSpace: "pre-wrap", | ||
| }); | ||
|
Comment on lines
+57
to
+77
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major fontStyles와 개별
As per coding guidelines " Also applies to: 79-101, 152-154 🤖 Prompt for AI Agents |
||
|
|
||
| export const textStyle = recipe({ | ||
| base: { | ||
| color: themeVars.color.gray800, | ||
| }, | ||
| variants: { | ||
| type: { | ||
| title1: { | ||
| ...themeVars.fontStyles.body_b_16, | ||
| fontWeight: 700, | ||
| }, | ||
| title2: { | ||
| ...themeVars.fontStyles.body_b_14, | ||
| }, | ||
| title3: { | ||
| ...themeVars.fontStyles.body_r_14, | ||
| fontWeight: 400, | ||
| }, | ||
| }, | ||
| }, | ||
| defaultVariants: { | ||
| type: "title1", | ||
| }, | ||
| }); | ||
|
|
||
| export const flexColumn = recipe({ | ||
| base: { | ||
| display: "flex", | ||
| flexDirection: "column", | ||
| }, | ||
| variants: { | ||
| gap: { | ||
| 8: { gap: "0.8rem" }, | ||
| 16: { gap: "1.6rem" }, | ||
| 24: { gap: "2.4rem" }, | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| export const tableWrapper = style({ | ||
| width: "100%", | ||
| overflowX: "auto", | ||
| selectors: { | ||
| "&::-webkit-scrollbar": { | ||
| display: "none", | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| export const table = style({ | ||
| width: "max-content", | ||
| minWidth: "100%", | ||
| borderCollapse: "collapse", | ||
| }); | ||
|
|
||
| export const tCell = style({ | ||
| minWidth: "10rem", | ||
| maxWidth: "25rem", | ||
| padding: "0.8rem", | ||
| border: `1px solid ${themeVars.color.gray200}`, | ||
| fontWeight: 400, | ||
| verticalAlign: "top", | ||
| wordBreak: "keep-all", | ||
| }); | ||
|
|
||
| export const thead = style({ | ||
| backgroundColor: themeVars.color.gray100, | ||
| }); | ||
|
|
||
| export const th = style({ | ||
| whiteSpace: "nowrap", | ||
| padding: "1rem 0.8rem", | ||
| }); | ||
|
|
||
| export const tableText = style({ | ||
| fontWeight: 400, | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import { Button, Modal } from "@/shared/ui"; | ||
|
|
||
| import * as styles from "./policy-modal.css"; | ||
| import { PrivacyPolicyContent } from "./privacy-policy-content"; | ||
| import { UsePolicyContent } from "./use-policy-content"; | ||
|
|
||
| interface modalProps { | ||
| type: "USE" | "PRIVACY"; | ||
| onClose: () => void; | ||
| } | ||
|
|
||
| export const PolicyModal = ({ type, onClose }: modalProps) => { | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| return ( | ||
| <div className={styles.wrapper}> | ||
| <div className={styles.modalHeader}> | ||
| <div>{type === "USE" ? "이용약관" : "개인정보처리방침"}</div> | ||
| <div className={styles.buttonWrapper}> | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| <Modal.XButton /> | ||
| </div> | ||
| </div> | ||
| <Modal.Content> | ||
| <div className={styles.modalCotent}> | ||
| {type === "USE" ? <UsePolicyContent /> : <PrivacyPolicyContent />} | ||
| </div> | ||
| </Modal.Content> | ||
| <Modal.Buttons> | ||
| <Button variant="primary" size="full" onClick={onClose}> | ||
| 확인 | ||
| </Button> | ||
| </Modal.Buttons> | ||
| </div> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| import { | ||
| TERMS_OF_PRIVACY_INFO, | ||
| type Article, | ||
| type Section, | ||
| } from "@/shared/config"; | ||
|
|
||
| import * as styles from "./policy-modal.css"; | ||
|
|
||
| export const PrivacyPolicyContent = () => { | ||
| return ( | ||
| <div className={`${styles.content} ${styles.flexColumn({ gap: 24 })}`}> | ||
| {/** 개인정보처리방침 타이틀 */} | ||
| <div className={styles.flexColumn({ gap: 16 })}> | ||
| <div> | ||
| <h3 className={styles.textStyle()}>{TERMS_OF_PRIVACY_INFO.title}</h3> | ||
| <p>{TERMS_OF_PRIVACY_INFO.date}</p> | ||
| </div> | ||
| <p>{TERMS_OF_PRIVACY_INFO.description}</p> | ||
| </div> | ||
| {/** 조항 리스트 (ex. 1. 개인정보의 수집 및 이용) */} | ||
| {TERMS_OF_PRIVACY_INFO.sections.map((section: Section) => ( | ||
| <section className={styles.flexColumn({ gap: 8 })}> | ||
| {/* 조항 타이틀 및 설명 */} | ||
| <div> | ||
| <h4 className={styles.textStyle({ type: "title2" })}> | ||
| {section.title} | ||
| </h4> | ||
| <p>{section.description}</p> | ||
| </div> | ||
| {/** 조항 상세설명 */} | ||
| <div className={styles.flexColumn({ gap: 16 })}> | ||
| {section.articles?.map((article: Article) => ( | ||
| <article className={styles.flexColumn({ gap: 8 })}> | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| {/** 조항 상세설명의 타이틀 (ex. 가. 회원가입 및 계정 관리) */} | ||
| {article.title && ( | ||
| <p className={styles.textStyle({ type: "title3" })}> | ||
| {article.title} | ||
| </p> | ||
| )} | ||
| <div> | ||
| {article.content && ( | ||
| <div> | ||
| {/* 줄글 형태의 컨텐츠 */} | ||
| {"text" in article.content && ( | ||
| <div>{article.content.text}</div> | ||
| )} | ||
| {/* 테이블 형태의 컨텐츠 */} | ||
| {"table" in article.content && ( | ||
| <div className={`${styles.tableWrapper}`}> | ||
| <table className={`${styles.table} ${styles.tCell}`}> | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| <thead className={styles.thead}> | ||
| <tr> | ||
| {article.content.table.header.map( | ||
| (th, thIdx) => ( | ||
| <th | ||
| key={thIdx} | ||
| className={`${styles.tCell} ${styles.th}`} | ||
| > | ||
| {th} | ||
| </th> | ||
| ) | ||
| )} | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| {article.content.table.rows.map((row, rowIdx) => ( | ||
| <tr key={rowIdx}> | ||
| {row.map((td, tdIdx) => ( | ||
| <td key={tdIdx} className={styles.tCell}> | ||
| {td} | ||
| </td> | ||
| ))} | ||
| </tr> | ||
| ))} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| )} | ||
| </div> | ||
| )} | ||
| </div> | ||
| </article> | ||
| ))} | ||
| </div> | ||
| {/** 조항 추가사항 */} | ||
| {section.alert && <div>{section.alert}</div>} | ||
| </section> | ||
| ))} | ||
| </div> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { TERMS_OF_USE, type Chapters, type Chapter } from "@/shared/config"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as styles from "./policy-modal.css"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const UsePolicyContent = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return TERMS_OF_USE.map((policy: Chapters) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <section key={policy.chapterTitle}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h2 className={styles.title}>{policy.chapterTitle}</h2> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {policy.chapter.map((chapter: Chapter) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <article key={chapter.title}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {chapter.title && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <h3 className={styles.subTitle}>{chapter.title}</h3> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className={styles.content}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {chapter.contents.map((content) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p>{content}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React 두 가지 문제가 있어요:
🔧 제안하는 수정 사항- {policy.chapter.map((chapter: Chapter) => (
- <article key={chapter.title}>
+ {policy.chapter.map((chapter: Chapter, chapterIdx: number) => (
+ <article key={chapter.title || `chapter-${chapterIdx}`}>
{chapter.title && (
<h3 className={styles.subTitle}>{chapter.title}</h3>
)}
<div className={styles.content}>
- {chapter.contents.map((content) => (
- <p>{content}</p>
+ {chapter.contents.map((content, contentIdx) => (
+ <p key={contentIdx}>{content}</p>
))}
</div>
</article>
))}🤖 Prompt for AI Agents
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기 {chapter.contents.map((content, idx) => (
<p key={idx}>{content}</p>
))}작은 부분이긴 한데 map 렌더링은 한 번씩 다 맞춰두면 이후에 warning 잡기가 편한 것 같습니다!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 꺄호 key를 넣는다고 다 넣었는데 누락된 부분이 있었네요!!!!!!!!!!!!! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </article> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+5
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 컴포넌트 구조가 잘 구현되어 있어요! 시맨틱 HTML 태그( 한 가지 작은 개선 포인트: Line 11과 Line 17에서 ♻️ 변수명 구분 제안- {policy.chapter.map((chapter: Chapter, idx) => (
- <article key={idx}>
+ {policy.chapter.map((chapter: Chapter, chapterIdx) => (
+ <article key={chapterIdx}>
{chapter.title && (
<h3 className={styles.subTitle}>{chapter.title}</h3>
)}
<div className={styles.content}>
- {chapter.contents.map((content, idx) => (
- <p key={idx}>{content}</p>
+ {chapter.contents.map((content, contentIdx) => (
+ <p key={contentIdx}>{content}</p>
))}
</div>
</article>
))}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
스타일 식별자 오탈자(
modalCotent) 정리 권장modalCotent는modalContent오탈자로 보입니다. 사용처까지 함께 정리하면 검색성과 유지보수성이 좋아집니다.🤖 Prompt for AI Agents