diff --git a/README.md b/README.md index f2beed1..2506dad 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ `egbim/index.html`의 목록 위에 작성·상세 모달을 여는 EG-BIM Q&A UI입니다. `SW문의_소스패키지`의 히어로·제품 탭·목록·모달 디자인을 적용하고, 기존 첨부·댓글·비밀글·작성자 권한·검색을 유지합니다. 회사 홈페이지의 헤더·메뉴·푸터는 포함하지 않습니다. 기존 `write.html`, `detail.html?id=...` 주소는 같은 목록의 모달로 연결됩니다. -EG-BIM을 우선 제공하며 TOVA·GAIA는 준비중 탭입니다. 원격지원은 `https://939.co.kr/saman/`으로 열립니다. UI 적용 범위·검증·남은 배포 확인은 [작업 목록](docs/qa-inquiry-ui-redesign-tasks.md)에 정리했습니다. +EG-BIM 탭만 가운데 표시하며 TOVA·GAIA는 오픈 전까지 숨깁니다. 원격지원은 `https://939.co.kr/saman/`으로 열립니다. UI 적용 범위·검증·남은 배포 확인은 [작업 목록](docs/qa-inquiry-ui-redesign-tasks.md)에 정리했습니다. 로그인부터 글 저장까지의 화면·처리 전이맵은 [`docs/qa-login-to-save-transition.md`](docs/qa-login-to-save-transition.md)에 정리했습니다. diff --git a/assets/inquiry/inquiry.css b/assets/inquiry/inquiry.css index c684ca4..c8f0878 100644 --- a/assets/inquiry/inquiry.css +++ b/assets/inquiry/inquiry.css @@ -10,8 +10,8 @@ .inquiry-hero p { font-size: 22px; line-height: 1.6; } .inquiry-workspace { position: relative; z-index: 1; width: min(1248px, 100%); padding: 0 24px; margin: -98px auto 120px; } .inquiry-tabs-shell { --inquiry-tab-curve: 28px; padding: 19px 32px 0; border-radius: 48px 48px 0 0; background: linear-gradient(180deg, #174b64a6, #082f43d9); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); box-shadow: inset 0 1px 0 #74c7f4b3, inset 0 0 0 1px #5fadd666, inset 0 8px 16px #ffffff12, 0 -18px 12px #0a2f4843; } -.inquiry-tabs { display: flex; gap: 60px; position: relative; isolation: isolate; } -.inquiry-tabs button { position: relative; flex: 1; min-width: 0; min-height: 76px; padding: 8px 12px 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; border: 0; border-radius: 34px 34px 0 0; color: #b9d4e0a6; background: transparent; cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease; } +.inquiry-tabs { display: flex; justify-content: center; gap: 60px; position: relative; isolation: isolate; } +.inquiry-tabs button { position: relative; flex: 0 1 340px; min-width: 0; min-height: 76px; padding: 8px 12px 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; border: 0; border-radius: 34px 34px 0 0; color: #b9d4e0a6; background: transparent; cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease; } .inquiry-tabs button:not([aria-selected="true"]):hover { color: #d6f0ff; background: #ffffff12; } .inquiry-tabs [aria-selected="true"] { z-index: 1; color: #00a2ef; background: linear-gradient(180deg, #e8f8ff 0%, #fff 58%); box-shadow: inset 0 2px 0 #ffffffb3, 0 -3px 10px #163f5b08; } /* Concave lower corners join the selected tab to the white board beneath it. */ @@ -119,7 +119,7 @@ html.inquiry-modal-open body { overflow: hidden !important; } .inquiry-workspace { margin: -96px auto 72px; padding: 0 16px; } .inquiry-tabs-shell { --inquiry-tab-curve: 13px; padding: 12px 13px 0; border-radius: 30px 30px 0 0; } .inquiry-tabs { gap: 5px; } - .inquiry-tabs button { min-height: 84px; padding: 8px 4px 12px; gap: 4px; border-radius: 22px 22px 0 0; } + .inquiry-tabs button { flex-basis: 200px; min-height: 84px; padding: 8px 4px 12px; gap: 4px; border-radius: 22px 22px 0 0; } .inquiry-tab-logo { width: 145px; max-width: 100%; height: 28px; } .inquiry-tab-logo img { height: auto; max-height: 28px; } .inquiry-tabs [data-service="egbim"] img { width: 49px; height: 25px; } diff --git a/docs/qa-inquiry-ui-redesign-tasks.md b/docs/qa-inquiry-ui-redesign-tasks.md index c6c2e76..1832b71 100644 --- a/docs/qa-inquiry-ui-redesign-tasks.md +++ b/docs/qa-inquiry-ui-redesign-tasks.md @@ -11,7 +11,7 @@ | --- | --- | | 작성·상세 표시 | 목록 위에 뜨는 페이지 내부 모달로 전환. 원본의 `` 방식 기준 | | 기존 주소 | 기존 작성·상세 주소 연결 유지 | -| 소프트웨어 | EG-BIM 우선 적용. TOVA·GAIA 탭은 준비중 표시 | +| 소프트웨어 | EG-BIM 탭만 가운데 표시. TOVA·GAIA 탭은 오픈 전까지 숨김 | | 디자인 적용 범위 | 문의 화면·작성·상세 영역. 홈페이지 헤더·전체 메뉴·푸터는 제외 | | 입력 중 닫기 | 입력 변경이 있으면 폐기 여부를 확인한 뒤 닫기 | | 원격지원 | `https://939.co.kr/saman/` 활성화. 원본처럼 새 창으로 열기 | @@ -27,7 +27,7 @@ | `SW문의_소스패키지/assets/js/inquiry.js` | 예시 게시물·공지 생성, 모달 열기/닫기, 미리보기 등록 안내 | 모달 UX를 참고하고 실제 데이터 처리는 기존 Q&A 로직으로 연결 | | `SW문의_소스패키지/assets/js/inquiry-copy.js` | 예시 데이터·상태명·KO/EN 미리보기 문구 | 실제 서비스 문구와 상태명으로 정리 | | `SW문의_소스패키지/assets/img/inquiry-hero.webp` | 스크린샷의 상단 배경 이미지 | 해당 자산 사용 | -| `SW문의_소스패키지/ko/{egbim,tova,gaia}/img/` | 제품 로고와 모바일용 EG-BIM 심볼 | 활성·준비중 탭에 사용 | +| `SW문의_소스패키지/ko/{egbim,tova,gaia}/img/` | 제품 로고와 모바일용 EG-BIM 심볼 | EG-BIM 탭과 추후 오픈할 숨긴 탭의 자산으로 보존 | | `SW문의_소스패키지/assets/js/common.js`, `baron-sso-*.js`, `_include/` | 홈페이지 메뉴·헤더·푸터와 별도 SSO 흐름에 의존 | Q&A의 기존 Worker SSO 유지. 필요한 디자인 자산만 반영 | | `egbim/app.js`, `src/index.js` | 실제 API·SSO·첨부·댓글·검색·작성자 버튼 처리 | 기능 이전의 기준 | @@ -43,7 +43,7 @@ - 반투명 배경의 제품 탭과 선택된 EG-BIM 탭의 곡선·로고·색상을 반영한다. - 홈페이지 헤더를 제외하므로 원본의 헤더 높이 보정용 상단 여백을 함께 조정한다. - 문의 내역 제목, 원격지원 버튼, 둥근 분류 필터·검색창, 표·페이지 이동·문의등록 버튼을 맞춘다. -- TOVA·GAIA는 준비중임을 표시하고 실제 목록 조회·등록 대상으로 선택되지 않도록 한다. +- TOVA·GAIA는 오픈 전까지 숨기고 EG-BIM 탭을 가운데 배치한다. - 실제 문의 데이터와 현행 검색·상태 표시를 사용한다. 예시 공지·예시 고객 데이터·미리보기 문구는 배포 화면에 넣지 않는다. ### 작성 모달 @@ -131,7 +131,7 @@ flowchart LR | 댓글 수정·삭제 | `PATCH/DELETE /api/feedbacks/{id}/comments/{commentId}` | 실제 댓글 ID와 작성자 연결 | | 완료 확인 | `POST /api/feedbacks/{id}/completion-confirmation` | 기존 완료 확인 처리 | -이번 범위에서 새 DB나 별도 업로드 API를 도입할 필요는 없다. TOVA·GAIA를 준비중으로 두므로 제품별 API 키·프로젝트·채널 설정 확대도 이번 작업의 선행 조건이 아니다. +이번 범위에서 새 DB나 별도 업로드 API를 도입할 필요는 없다. TOVA·GAIA를 숨겨 두므로 제품별 API 키·프로젝트·채널 설정 확대도 이번 작업의 선행 조건이 아니다. ## 7. 단계별 작업 목록 @@ -149,7 +149,7 @@ flowchart LR - [x] `UI-01` 문의 전용 스타일 범위를 정하고 기존 공통 버튼·폼·레이아웃과의 충돌을 정리한다. - [x] `UI-02` 히어로 이미지·제품 로고·필요한 폰트만 배포 자산으로 정리하고 상대 경로를 맞춘다. - [x] `UI-03` 목록의 히어로·곡선 탭·필터·검색창·표·페이지 이동·등록 버튼을 원본 기준으로 구성한다. -- [x] `UI-04` TOVA·GAIA 준비중 표기와 접근 가능한 비활성 탭 처리를 추가한다. +- [x] `UI-04` TOVA·GAIA를 숨기고 EG-BIM 탭을 데스크톱·모바일에서 가운데 배치한다. - [x] `UI-05` 원격지원 링크를 확정 주소로 연결하고 새 창 안내와 `noopener noreferrer`를 유지한다. - [x] `UI-06` 실제 데이터가 없는 예시 공지·예시 댓글 수·미리보기 문구를 제거한다. 댓글 수 배지가 필요하면 실제 API 제공값을 확인하고 연결하며, 행마다 댓글 API를 추가 호출하는 방식은 피한다. @@ -222,7 +222,7 @@ flowchart LR - [x] fuzzy 검색과 전체 페이지 수집·필터·페이지 이동을 유지한다. - [x] 입력 변경 후 닫기는 확인을 거치며, 닫기 취소 시 입력과 파일을 보존한다. - [x] 모달을 닫아도 목록 조건·위치가 유지되고 새 글·수정·삭제 결과가 반영된다. -- [x] TOVA·GAIA 준비중 표시와 확정된 원격지원 링크가 동작한다. +- [x] TOVA·GAIA 숨김·EG-BIM 탭 중앙 배치와 확정된 원격지원 링크가 동작한다. - [x] 예시 데이터·미리보기 전용 문구가 남지 않고 모바일·키보드 사용과 회귀 검증을 통과했다. diff --git a/egbim/index.html b/egbim/index.html index 98e1ca2..90a943f 100644 --- a/egbim/index.html +++ b/egbim/index.html @@ -1,5 +1,5 @@ -S/W 문의 | 바론컨설턴트 +S/W 문의 | 바론컨설턴트
@@ -15,11 +15,11 @@ BIM 모델 - - diff --git a/tests/browser/inquiry-ui.mjs b/tests/browser/inquiry-ui.mjs index abcd032..a46cb3d 100644 --- a/tests/browser/inquiry-ui.mjs +++ b/tests/browser/inquiry-ui.mjs @@ -63,7 +63,8 @@ try { const decide = accept => page.once('dialog',d=>accept?d.accept():d.dismiss()); await page.goto('https://qa.example.test/egbim/'); await page.waitForFunction(()=>document.querySelector('#resultCount').textContent==='총 15건'); - assert.equal(await page.locator('#tab-tova').isDisabled(),true);assert.equal(await page.locator('.inquiry-remote').getAttribute('href'),'https://939.co.kr/saman/'); + assert.equal(await page.locator('#tab-tova').isVisible(),false);assert.equal(await page.locator('#tab-gaia').isVisible(),false); + assert.equal(await page.locator('#tab-egbim').evaluate(e=>Math.abs(e.getBoundingClientRect().x+e.getBoundingClientRect().width/2-innerWidth/2)<1),true);assert.equal(await page.locator('.inquiry-remote').getAttribute('href'),'https://939.co.kr/saman/'); await page.screenshot({path:images+'/desktop-list.png',fullPage:true}); await page.locator('#query').fill('로그임');await page.locator('#searchForm').evaluate(f=>f.requestSubmit());assert.equal(await page.locator('#qaRows tr').count(),5); await page.locator('#qaRows tr a').first().click();await page.waitForSelector('#detailModal[open]');await close();assert.equal(await page.locator('#query').inputValue(),'로그임'); @@ -107,6 +108,7 @@ try { await page.locator('#writeButton').click();await page.locator('#category').selectOption('오류문의');await page.locator('#title').fill('JSON 등록');await page.locator('#content').fill('첨부 없이 등록');await page.locator('#qaForm').evaluate(f=>f.requestSubmit());await page.waitForFunction(()=>document.querySelector('[data-detail-title]')?.textContent==='JSON 등록');assert.match(mutations.at(-1).type,/application\/json/);assert.equal(mutations.filter(m=>m.url==='/api/feedbacks'&&m.method==='POST').length,3);await close(); await page.setViewportSize({width:390,height:844});await page.evaluate(()=>scrollTo(0,0));await page.screenshot({path:images+'/mobile-list.png',fullPage:true}); assert.equal(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth),true); + assert.equal(await page.locator('#tab-egbim').evaluate(e=>Math.abs(e.getBoundingClientRect().x+e.getBoundingClientRect().width/2-innerWidth/2)<1),true); await page.locator('#writeButton').click();assert.equal(await page.locator('.inquiry-form-grid').evaluate(e=>getComputedStyle(e).gridTemplateColumns.split(' ').length),1);await page.screenshot({path:images+'/mobile-write.png'}); assert.equal(await page.locator('#composeModal').evaluate(d=>d.scrollHeight>d.clientHeight),true);await close(); await page.locator('#qaRows tr a').first().evaluate(a=>a.click());await page.waitForSelector('#commentForm');await page.screenshot({path:images+'/mobile-detail.png'});assert.equal(await page.locator('#detailModal').evaluate(d=>d.getBoundingClientRect().right<=innerWidth),true);await close();