v1.4.4: 메인 화면 커버 미리보기·오버레이 줄바꿈 수정

- 설정 미리보기를 HomeHero와 동일한 오버레이로 표시하고 편집 모드에서 크게 보이도록 조정
- 오버레이 본문 줄바꿈이 홈·미리보기에서 보이도록 whitespace-pre-line 적용
This commit is contained in:
2026-05-21 19:01:17 +09:00
parent 9e5728074a
commit 8f53210756
4 changed files with 23 additions and 26 deletions

View File

@@ -47,7 +47,7 @@ const hasOverlay = computed(() => Boolean(props.title?.trim() || props.text?.tri
</h2>
<p
v-if="text"
class="home-hero__text max-w-[32rem] text-sm leading-relaxed text-white/85"
class="home-hero__text max-w-[32rem] whitespace-pre-line text-sm leading-relaxed text-white/85"
>
{{ text }}
</p>

View File

@@ -635,7 +635,7 @@ components/content/
- 관리자 사이트 설정 UI는 `/admin/settings`에서 제공한다. Ghost Admin과 유사하게 **전체 화면**으로 표시하며, 좌측 내비와 우측 본문을 **한 덩어리로 중앙 정렬**(`max-w` 래퍼, 본문 카드 영역은 약 760px 상한)하고, 페이지 배경은 밝은 회색·본문 열은 흰색으로 구분한다. 우측 본문을 스크롤하면 현재 보이는 구역에 맞춰 좌측 메뉴 활성 배경을 갱신한다. **우측 상단 고정** 닫기 버튼과 `Escape` 키로 설정 화면을 닫으며, 브라우저 히스토리가 있으면 `뒤로 가기`, 없으면 `/admin`으로 이동한다. 타임존·게시물 Import/Export는 현재 **메뉴·안내 카드만** 제공하고 저장 API는 연결하지 않는다. **스팸 필터**는 가입 금지 닉네임을 저장한다. **블로그 제목·설명** 카드는 기본적으로 사이트 이름·설명을 읽기 전용으로 보여 주고, `편집`을 눌렀을 때만 입력 필드·미리보기·저장/취소가 나타난다. 제목·설명 편집 중 `Escape`는 설정 닫기 대신 편집 취소로 동작한다. **POST 설정**·**어나운스 바**는 읽기 모드에서도 토글 UI를 비활성화 상태로 보여 준다.
- 사이트 설정은 `site_settings` 테이블의 단일 레코드로 관리한다.
- 관리자는 사이트 이름, 설명, 사이트 URL, 로고 이미지, 저작권 문구를 수정할 수 있다.
- **메인 화면**(`home_cover_image_url`, `home_cover_title`, `home_cover_text`): 홈(`/`) 상단 720px 커버 배너. 이미지가 있을 때만 `HomeHero`를 표시하며, 제목·짧은 본문은 이미지 왼쪽 하단 그라데이션 오버레이로 겹친다. 관리자 UI에서는 커버 파일 업로드·제목·본문을 편집한 뒤 **저장** 한 번에 `PUT /admin/api/settings`로 반영한다. 파일 업로드 API는 디스크에만 올리고 URL을 돌려준다(가로 720px WebP, `/uploads/system/home-cover-YYYYMM-random.webp`).
- **메인 화면**(`home_cover_image_url`, `home_cover_title`, `home_cover_text`): 홈(`/`) 상단 720px 커버 배너. 이미지가 있을 때만 `HomeHero`를 표시하며, 제목·짧은 본문은 이미지 왼쪽 하단 그라데이션 오버레이로 겹친다. 오버레이 본문은 textarea에서 입력한 줄바꿈(`\n`)을 저장·표시하며, `HomeHero` 본문은 `whitespace-pre-line`으로 여러 줄을 렌더링한다. 관리자 UI에서는 커버 파일 업로드·제목·본문을 편집한 뒤 **저장** 한 번에 `PUT /admin/api/settings`로 반영한다. 읽기·편집 미리보기는 실제 `HomeHero` 컴포넌트를 사용해 긴 본문도 공개 화면과 같은 오버레이 폭(`max-w-[32rem]`)과 줄바꿈으로 확인한다. 파일 업로드 API는 디스크에만 올리고 URL을 돌려준다(가로 720px WebP, `/uploads/system/home-cover-YYYYMM-random.webp`).
- **POST 설정**(`show_post_updated_at`): 발행 후 본문·메타 수정이 있을 때 관리자 글 목록·공개 글 상세에 수정 시각 보조 줄을 표시할지 여부.
- **가입 금지 닉네임**(`signup_blocked_usernames`, JSON 문자열): 회원가입·회원 프로필 닉네임 변경 시 닉네임에 목록 단어가 포함되면 거부한다(대소문자 무시, 부분 일치). 안내 문구는 `{단어}은 사용할 수 없는 단어입니다.` 형식이다. 기본값: `admin`, `master`, `zenn`, `sori`, `sori.studio`.
- **어나운스 바**(`announcement_enabled`, `announcement_text`, `announcement_url`, `announcement_background_color`): `announcement_enabled`가 true이고 문구가 비어 있지 않으면 공개 레이아웃(`default`·`post`) 헤더 위에 전체 너비 배너를 표시한다. `announcement_url`이 있으면 문구를 링크로 감싼다(내부 `/…` 또는 `http(s)://`). 배경색은 `#15171a`·`#ffffff`·`#ff4f2e` 중 하나. 방문자는 **이번 방문 동안 닫기**(X, `sessionStorage`) 또는 **7일간 보지 않기**(`localStorage`, 만료 시각 저장)를 선택할 수 있다. 공지 내용이 바뀌어 `updatedAt`이 달라지면 다시 노출된다.

View File

@@ -2,6 +2,10 @@
## v1.4.3
- `HomeHero`: 오버레이 본문 줄바꿈(`\n`)이 미리보기·홈에서도 보이도록 `whitespace-pre-line` 적용.
- 관리자 설정: 메인 화면 커버 편집 모드에서도 미리보기를 버튼 영역과 분리해 카드 폭 기준으로 크게 표시.
- 관리자 설정: 메인 화면 커버 미리보기를 실제 `HomeHero` 오버레이 구조로 표시해 긴 텍스트 줄바꿈도 공개 화면과 동일하게 확인하도록 수정.
- 관리자 설정: 메인 화면 커버 이미지 미리보기에서 이미지 폭만 360px로 제한되어 오른쪽이 비어 보이던 표시 문제 수정.
- 배포 TODO: 다음달 작업 대상으로 PostgreSQL·업로드 파일 백업/복구 시스템 설계 및 구현 항목 추가.
- 관리자 레이아웃: 공개 다크모드가 글쓰기 에디터 입력에 영향을 주지 않도록 라이트 폼 보정 스코프 축소.
- 관리자 레이아웃: 대시보드 메뉴를 `/admin` 활성 링크로 연결.

View File

@@ -1328,24 +1328,16 @@ onBeforeUnmount(() => {
v-if="!editHomeCover"
class="admin-settings-screen__home-cover-readonly grid gap-4 border-t border-[#eceff2] pt-5 text-sm"
>
<div v-if="form.homeCoverImageUrl" class="overflow-hidden rounded-lg border border-[#e6e8eb]">
<img
class="aspect-[720/215] w-full max-w-[360px] object-cover"
:src="form.homeCoverImageUrl"
alt="메인 화면 커버 미리보기"
>
<div v-if="form.homeCoverImageUrl" class="admin-settings-screen__home-cover-preview w-full max-w-[720px] overflow-hidden rounded-lg border border-[#e6e8eb]">
<HomeHero
:image-url="form.homeCoverImageUrl"
:title="form.homeCoverTitle"
:text="form.homeCoverText"
/>
</div>
<p v-else class="text-[#657080]">
등록된 커버 이미지가 없습니다. 상단 배너는 표시되지 않습니다.
</p>
<div v-if="form.homeCoverTitle || form.homeCoverText" class="grid gap-1">
<p v-if="form.homeCoverTitle" class="font-semibold text-[#15171a]">
{{ form.homeCoverTitle }}
</p>
<p v-if="form.homeCoverText" class="text-[#657080]">
{{ form.homeCoverText }}
</p>
</div>
</div>
<div v-else class="admin-settings-screen__home-cover-edit grid gap-6 border-t border-[#eceff2] pt-5">
@@ -1357,16 +1349,6 @@ onBeforeUnmount(() => {
<p class="mt-1 max-w-md text-sm leading-relaxed text-[#657080]">
가로 720px WebP로 변환해 미리 불러옵니다. 제목·본문과 함께 저장 버튼을 눌러야 사이트에 반영됩니다.
</p>
<div
v-if="form.homeCoverImageUrl"
class="mt-3 overflow-hidden rounded-lg border border-[#e6e8eb]"
>
<img
class="aspect-[720/215] w-full max-w-[360px] object-cover"
:src="form.homeCoverImageUrl"
alt="커버 미리보기"
>
</div>
</div>
<div class="flex shrink-0 flex-wrap gap-2">
<button
@@ -1397,6 +1379,17 @@ onBeforeUnmount(() => {
>
</div>
<div
v-if="form.homeCoverImageUrl"
class="admin-settings-screen__home-cover-preview w-full max-w-[720px] overflow-hidden rounded-lg border border-[#e6e8eb]"
>
<HomeHero
:image-url="form.homeCoverImageUrl"
:title="form.homeCoverTitle"
:text="form.homeCoverText"
/>
</div>
<label class="admin-settings-screen__field grid gap-2 text-sm">
<span class="font-medium text-[#3f4650]">오버레이 제목</span>
<input