Repository navigation
feat: 홈 화면 새 사건 버튼, 카테고리 모달, 서비스 정보 푸터 구현 #62
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 29 commits
6eb7ed6
f98f8f3
d959392
5a6643e
a04b781
6ab4d7e
24aed23
f67c9e9
2b194f9
e5188f7
f2154c6
47e7138
a31fe0e
f02cec2
e92b35f
804f450
fd1b1f3
8561f05
cca1afc
2afe223
cff2117
28c7139
200262e
692170e
80b320a
c5eed1d
b6f81f0
7937e2c
12871f4
9408df5
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,42 @@ | ||
| @use '@/styles/abstracts/variables' as v; | ||
| @use '@/styles/abstracts/mixins' as m; | ||
| @use '@/styles/abstracts/functions' as fn; | ||
|
|
||
| .box { | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| width: 100%; | ||
| background-color: var(--text-primary); | ||
| border-radius: 0; | ||
| padding: fn.r(20) fn.r(16) fn.r(20); | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| .logo { | ||
| display: block; | ||
| width: fn.r(66); | ||
| height: fn.r(19); | ||
| object-fit: contain; | ||
| } | ||
|
|
||
| .links { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: fn.r(10); | ||
| margin-top: fn.r(10); | ||
| } | ||
|
|
||
| .link { | ||
| @include m.text-caption; | ||
| color: v.$color-black-200; | ||
| text-decoration: none; | ||
| white-space: nowrap; | ||
| } | ||
|
|
||
| .copyright { | ||
| @include m.text-caption; | ||
| color: v.$color-black-400; | ||
| margin-top: fn.r(10); | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| text-align: center; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import Image from 'next/image' | ||
| import styles from './HomeServiceInfo.module.scss' | ||
|
|
||
| const LINKS = [ | ||
| { label: '서비스 소개', href: '#' }, | ||
| { label: '개인정보 처리방침', href: '#' }, | ||
| { label: '이용약관', href: '#' }, | ||
| { label: '고객문의', href: '#' }, | ||
|
Comment on lines
+4
to
+8
Contributor
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. 푸터 링크가 모두 임시 현재 클릭해도 유효한 페이지로 이동하지 않아 사용자가 서비스 정보/약관/문의에 접근할 수 없습니다. 출시 전 실제 경로로 교체가 필요합니다. Also applies to: 22-25 🤖 Prompt for AI Agents |
||
| ] | ||
|
|
||
| export default function HomeServiceInfo() { | ||
| return ( | ||
| <div className={styles.box}> | ||
| <Image | ||
| src="/images/common/logo.png" | ||
| alt="말해부엉" | ||
| width={66} | ||
| height={19} | ||
| className={styles.logo} | ||
| /> | ||
| <nav className={styles.links} aria-label="서비스 정보"> | ||
| {LINKS.map(({ label, href }) => ( | ||
| <a key={label} href={href} className={styles.link}> | ||
| {label} | ||
| </a> | ||
| ))} | ||
| </nav> | ||
| <p className={styles.copyright}>Copyright ⓒ 말해부엉. ALL Rights Reserved.</p> | ||
| </div> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| @use '@/styles/abstracts/variables' as v; | ||
| @use '@/styles/abstracts/mixins' as m; | ||
| @use '@/styles/abstracts/functions' as fn; | ||
|
|
||
| // ─── 새 사건 + 버튼 ───────────────────────────────────────── | ||
| .button { | ||
| position: fixed; | ||
| bottom: fn.r(81); | ||
| right: max(fn.r(16), calc((100vw - #{v.$container-max-width}) / 2 + #{fn.r(16)})); | ||
|
|
||
| display: flex; | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| align-items: center; | ||
| justify-content: center; | ||
| width: fn.r(115); | ||
| height: fn.r(48); | ||
|
|
||
| background-color: v.$color-black-700; | ||
| border: none; | ||
| border-radius: fn.r(100); | ||
| cursor: pointer; | ||
| z-index: 101; | ||
|
|
||
| @include m.text-title-s; | ||
| color: #ffffff; | ||
| white-space: nowrap; | ||
| } | ||
|
|
||
| // ─── 카테고리 선택 모달 ────────────────────────────────────── | ||
| .overlay { | ||
| position: fixed; | ||
| inset: 0; | ||
| // 페이지 배경을 불투명 베이스로 깔아 콘텐츠가 비치지 않게 하고, | ||
| // 그 위에 color-black-700 40% 틴트를 적용 | ||
| background-color: var(--bg-page); | ||
| background-image: linear-gradient(rgba(26, 29, 31, 0.4), rgba(26, 29, 31, 0.4)); | ||
| z-index: 200; | ||
| } | ||
|
|
||
| // 카테고리 박스 + X버튼 컨테이너 — 새 사건 + 버튼과 동일 위치 기준 | ||
| .panel { | ||
| position: absolute; | ||
| bottom: fn.r(81); | ||
| right: max(fn.r(16), calc((100vw - #{v.$container-max-width}) / 2 + #{fn.r(16)})); | ||
|
|
||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: flex-end; | ||
| gap: fn.r(16); | ||
| } | ||
|
|
||
| .categoryBox { | ||
| width: fn.r(133); | ||
| height: fn.r(176); | ||
| background-color: #ffffff; | ||
| border-radius: fn.r(12); | ||
| box-sizing: border-box; | ||
| padding: fn.r(20) fn.r(16); | ||
|
|
||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: fn.r(8); | ||
| } | ||
|
|
||
| .item { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: fn.r(9); | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .itemLabel { | ||
| @include m.text-body-m; | ||
| color: var(--text-primary); | ||
| } | ||
|
|
||
| .closeButton { | ||
| width: fn.r(48); | ||
| height: fn.r(48); | ||
| border-radius: 50%; | ||
| background-color: #ffffff; | ||
| border: none; | ||
| cursor: pointer; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| color: v.$color-black-700; | ||
| flex-shrink: 0; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| 'use client' | ||
|
|
||
| import { useState, useEffect } from 'react' | ||
| import CloseIcon from '@mui/icons-material/Close' | ||
| import CategoryIcon from '@/components/ui/CategoryIcon' | ||
| import type { CategoryGroup } from '@/types/common' | ||
| import styles from './NewCaseButton.module.scss' | ||
|
|
||
| const CATEGORY_ITEMS: { category: CategoryGroup; label: string }[] = [ | ||
| { category: 'romance', label: '연인관계' }, | ||
| { category: 'work', label: '직장관계' }, | ||
| { category: 'friend', label: '친구관계' }, | ||
| { category: 'family', label: '가족관계' }, | ||
| ] | ||
|
|
||
| // TODO: 새 사건 작성 페이지(/rooms/new 등) 생성 후 카테고리별 실제 경로로 교체 | ||
| // 현재는 페이지가 없어 '#'으로 임시 처리 | ||
| function getCategoryHref(_category: CategoryGroup): string { | ||
| return '#' | ||
| } | ||
|
Comment on lines
+16
to
+20
Contributor
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. 카테고리 선택 후 실제 생성 페이지로 이동하지 못합니다.
Also applies to: 41-43 🤖 Prompt for AI Agents |
||
|
|
||
| export default function NewCaseButton() { | ||
| const [isOpen, setIsOpen] = useState(false) | ||
|
|
||
| useEffect(() => { | ||
| document.body.style.overflow = isOpen ? 'hidden' : '' | ||
| return () => { document.body.style.overflow = '' } | ||
| }, [isOpen]) | ||
|
|
||
| return ( | ||
| <> | ||
| {isOpen && ( | ||
| <div | ||
| className={styles.overlay} | ||
| onClick={() => setIsOpen(false)} | ||
| role="dialog" | ||
| aria-modal="true" | ||
| > | ||
| <div className={styles.panel} onClick={(e) => e.stopPropagation()}> | ||
| <div className={styles.categoryBox}> | ||
| {CATEGORY_ITEMS.map(({ category, label }) => ( | ||
| <a key={category} href={getCategoryHref(category)} className={styles.item}> | ||
| <CategoryIcon category={category} /> | ||
| <span className={styles.itemLabel}>{label}</span> | ||
| </a> | ||
| ))} | ||
| </div> | ||
| <button | ||
| className={styles.closeButton} | ||
| onClick={() => setIsOpen(false)} | ||
| aria-label="카테고리 선택 닫기" | ||
| > | ||
| <CloseIcon style={{ width: 24, height: 24 }} /> | ||
| </button> | ||
| </div> | ||
| </div> | ||
| )} | ||
| {!isOpen && ( | ||
| <button | ||
| className={styles.button} | ||
| onClick={() => setIsOpen(true)} | ||
| aria-label="새 사건 작성" | ||
| > | ||
| 새 사건 + | ||
| </button> | ||
| )} | ||
| </> | ||
| ) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.