generated from ttipo/project-base
docs: 5단계(실시간 새 메일 · 바탕화면 알림) 계약과 디자인
- 계약 2절 "실시간 알림": GET /api/mail-events(SSE) — state(+inboxUnread) · new-mail · ping(upstream) · end 이벤트, 직원마다 엔진 연결 하나 · 연결 5개 · 25초 ping · 토큰 만료 30초 전 end, 새 메일 판단(10분 넘게 앞선 메일 제외) · 5분 안전판, 클라이언트 규칙(브라우저마다 연결 하나 · fetch 로 읽기 · 다시 잇기 · 1분 확인과의 관계 · 바탕화면 알림 조건) - 엔진 확인 사실(Stalwart 0.16.27): EventSource 는 대리 접근으로 열린다, ping 은 30초보다 짧지 않다, EmailDelivery 는 초안에도 바뀐다, 스트림은 동시 요청 한도에 들지 않는다, 해석 못 하는 sinceState 는 400 notRequest - 디자인 캔버스 5단계 보드(SettingsNotify · MailRealtime)와 README "5단계" · "5단계 구현하며 정한 보완" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>실시간 · 바탕화면 알림 상태 모음</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<style>
|
||||
@font-face{font-family:'Pretendard';src:url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2-variations'),url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2');font-weight:45 920;font-style:normal;font-display:swap}
|
||||
body{margin:0}
|
||||
a{color:#0E7C86}a:hover{color:#0A5F67}
|
||||
:focus-visible{outline:2px solid #0E7C86;outline-offset:2px}
|
||||
.on-dark:focus-visible{outline-color:#9ED6DB}
|
||||
.ghost{background:transparent;color:#344054}
|
||||
.ghost:hover{background:#F2F4F7;color:#171C26}
|
||||
.bar-action{background:transparent;color:#0A5F67}
|
||||
.bar-action:hover{background:#E3F2F3}
|
||||
.bar-close{background:transparent;color:#667085}
|
||||
.bar-close:hover{background:#E3F2F3;color:#344054}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="width: 1440px; min-height: 1520px; box-sizing: border-box; padding: 48px; display: flex; flex-direction: column; gap: 28px; background: #F6F7F9; color: #171C26; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 13px; line-height: 1.5">
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 6px; max-width: 920px">
|
||||
<h1 style="margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -0.02em">실시간 새 메일 · 바탕화면 알림</h1>
|
||||
<p style="margin: 0; font-size: 13.5px; color: #4A5363">5단계에서 바뀌는 것들입니다. 메일 화면의 모양은 그대로이고, 새 메일이 1분을 기다리지 않고 바로 나타납니다. 바탕화면 알림은 설정 › 메일 › 알림에서 켜고, 「설정 · 알림」 보드에서 눌러 볼 수 있습니다.</p>
|
||||
</div>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">목록 위에서 한 번 권하기 — 알림을 아직 고르지 않았을 때</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">새 메일 알림 줄과 같은 높이 40 (밀도 예외) · 닫으면 다시 보이지 않는다</p>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 24px; align-items: start">
|
||||
<div style="display: flex; flex-direction: column; border: 1px solid #E6E8EC; border-radius: 10px; overflow: hidden; background: #FFFFFF">
|
||||
<div style="display: flex; align-items: center; gap: 10px; min-height: 52px; box-sizing: border-box; padding: 0 12px 0 16px; border-bottom: 1px solid #EEF0F3">
|
||||
<span style="font-size: 15px; font-weight: 700">받은편지함</span>
|
||||
<span style="font-size: 12px; color: #667085">전체 128 · 안 읽음 3</span>
|
||||
</div>
|
||||
<div role="region" aria-label="바탕화면 알림 권하기" style="display: flex; align-items: center; gap: 10px; height: 40px; box-sizing: border-box; padding: 0 4px 0 14px; background: #F3F8F8; border-bottom: 1px solid #E3EEEF; color: #0B3640">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#0A5F67" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
||||
<span style="flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap">바탕화면 알림을 켜 두면 다른 창을 보는 동안에도 새 메일을 알려 드립니다.</span>
|
||||
<button type="button" class="bar-action" style="flex: 0 0 auto; height: 36px; padding: 0 10px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">알림 켜기</button>
|
||||
<button type="button" class="bar-close" aria-label="닫기" title="닫기" style="flex: 0 0 auto; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; cursor: pointer"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<div style="display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 10px 16px; border-bottom: 1px solid #F2F4F7">
|
||||
<span style="font-weight: 700">박서준</span><span style="font-size: 12px; font-weight: 600; color: #344054">오후 2:42</span>
|
||||
<span style="font-weight: 700; color: #171C26">11월 납품분 견적서 보내 드립니다</span>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 10px 16px">
|
||||
<span style="color: #344054">이도윤</span><span style="font-size: 12px; color: #667085">오후 1:05</span>
|
||||
<span style="color: #4A5363">Re: 메일 서버 이전 일정 공유</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul style="margin: 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: #4A5363">
|
||||
<li>알림을 켜지도 닫지도 않은 사람에게 메일 화면에서 한 번만 보입니다(브라우저 · 사용자마다).</li>
|
||||
<li>[알림 켜기] → 브라우저가 묻습니다 → 허용하면 "바탕화면 알림을 켰습니다." 알림.</li>
|
||||
<li>[닫기]를 누르면 다시 보이지 않습니다 — 설정 › 알림에서 언제든 켤 수 있습니다.</li>
|
||||
<li>브라우저가 이미 막았거나 지원하지 않으면 보이지 않습니다.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; align-items: start">
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">바탕화면 알림 — 한 통</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">제목: 보낸 사람 · 내용: 메일 제목</p>
|
||||
</div>
|
||||
<div role="img" aria-label="한 통이 왔을 때의 바탕화면 알림 예" style="display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; border-radius: 10px; background: #FFFFFF; border: 1px solid #E3E5E8; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.16)">
|
||||
<div style="display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #667085">
|
||||
<span aria-hidden="true" style="display: inline-flex; width: 14px; height: 14px; border-radius: 3px; background: #0B3640"></span><span>Microsoft Edge</span><span style="margin-left: auto">지금</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 12px">
|
||||
<span aria-hidden="true" style="flex: 0 0 44px; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 10px; background: #0B3640"><img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="" width="34" height="12" style="display: block; width: 34px; height: auto"></span>
|
||||
<div style="min-width: 0; display: flex; flex-direction: column; gap: 2px">
|
||||
<span style="font-size: 13.5px; font-weight: 700">박서준</span>
|
||||
<span style="font-size: 13px; color: #344054">11월 납품분 견적서 보내 드립니다</span>
|
||||
<span style="font-size: 11.5px; color: #98A2B3">portal.arasystem.it.kr</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">누르면 웹메일 탭으로 와서 그 메일을 엽니다. 이름이 없는 보낸 사람은 주소를 씁니다.</p>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">여러 통이 한꺼번에</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">한 번에 묶어 하나만</p>
|
||||
</div>
|
||||
<div role="img" aria-label="여러 통이 왔을 때의 바탕화면 알림 예" style="display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; border-radius: 10px; background: #FFFFFF; border: 1px solid #E3E5E8; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.16)">
|
||||
<div style="display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #667085">
|
||||
<span aria-hidden="true" style="display: inline-flex; width: 14px; height: 14px; border-radius: 3px; background: #0B3640"></span><span>Microsoft Edge</span><span style="margin-left: auto">지금</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 12px">
|
||||
<span aria-hidden="true" style="flex: 0 0 44px; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 10px; background: #0B3640"><img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="" width="34" height="12" style="display: block; width: 34px; height: auto"></span>
|
||||
<div style="min-width: 0; display: flex; flex-direction: column; gap: 2px">
|
||||
<span style="font-size: 13.5px; font-weight: 700">새 메일 3통</span>
|
||||
<span style="font-size: 13px; color: #344054">박서준 · 이도윤 외 1명</span>
|
||||
<span style="font-size: 11.5px; color: #98A2B3">portal.arasystem.it.kr</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">누르면 받은편지함을 엽니다. 새 알림은 앞의 알림을 바꿔 써서 바탕화면에 쌓이지 않습니다.</p>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">메일 제목 숨김</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">설정에서 「메일 제목도 보이기」를 껐을 때</p>
|
||||
</div>
|
||||
<div role="img" aria-label="제목을 숨긴 바탕화면 알림 예" style="display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; border-radius: 10px; background: #FFFFFF; border: 1px solid #E3E5E8; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.16)">
|
||||
<div style="display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #667085">
|
||||
<span aria-hidden="true" style="display: inline-flex; width: 14px; height: 14px; border-radius: 3px; background: #0B3640"></span><span>Microsoft Edge</span><span style="margin-left: auto">지금</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 12px">
|
||||
<span aria-hidden="true" style="flex: 0 0 44px; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 10px; background: #0B3640"><img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="" width="34" height="12" style="display: block; width: 34px; height: auto"></span>
|
||||
<div style="min-width: 0; display: flex; flex-direction: column; gap: 2px">
|
||||
<span style="font-size: 13.5px; font-weight: 700">박서준</span>
|
||||
<span style="font-size: 13px; color: #344054">새 메일이 왔습니다</span>
|
||||
<span style="font-size: 11.5px; color: #98A2B3">portal.arasystem.it.kr</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">여러 통이면 "새 메일 3통" · "박서준 · 이도윤 외 1명" 그대로입니다(제목만 뺍니다).</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start">
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 12px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">언제 알리나</h2>
|
||||
<ul style="margin: 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 6px; color: #344054">
|
||||
<li><strong style="font-weight: 600">받은편지함에 새로 배달된 안 읽은 메일</strong>만 — 내가 보낸 메일 · 임시 저장 · 다른 메일 프로그램이 다른 메일함으로 옮긴 메일은 알리지 않습니다.</li>
|
||||
<li><strong style="font-weight: 600">웹메일 화면을 보고 있으면 알리지 않습니다</strong> — 목록 · 메일함 숫자 · 탭 제목 "(3)" 에 바로 보이므로. 다른 탭 · 다른 프로그램을 보고 있을 때만.</li>
|
||||
<li>웹메일 탭이 여러 개여도 <strong style="font-weight: 600">한 번</strong>만 알립니다(브라우저마다 연결 하나).</li>
|
||||
<li>운영체제의 방해 금지 · 집중 모드에서는 운영체제가 숨깁니다. 소리도 운영체제 설정을 따릅니다.</li>
|
||||
<li>웹메일 탭을 모두 닫으면 알리지 않습니다 — 탭을 닫아도 오는 알림은 다음 단계입니다.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 12px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">새 메일이 화면에 나타나는 때</h2>
|
||||
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap">
|
||||
<span style="padding: 6px 10px; border-radius: 8px; background: #F2F4F7; font-weight: 600">상대가 보냄</span>
|
||||
<span aria-hidden="true" style="color: #98A2B3">→</span>
|
||||
<span style="padding: 6px 10px; border-radius: 8px; background: #E3F2F3; color: #0A5F67; font-weight: 600">1초 안</span>
|
||||
<span aria-hidden="true" style="color: #98A2B3">→</span>
|
||||
<span style="padding: 6px 10px; border-radius: 8px; background: #F2F4F7; font-weight: 600">목록 · 메일함 숫자 · 탭 제목</span>
|
||||
</div>
|
||||
<p style="margin: 0; color: #344054">지금은 1분마다 확인해서 최대 1분 늦습니다. 화면 모양은 그대로이고, 목록을 내려 보고 있으면 지금처럼 "새 메일 N통 · 맨 위로" 줄이 뜹니다.</p>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #667085">실시간 연결이 끊기면 저절로 1분 확인으로 돌아가고 다시 잇습니다 — 화면에는 알리지 않습니다(설정 › 알림에서 연결 상태를 볼 수 있습니다).</p>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">설정 › 알림 — 브라우저가 막았을 때 · 지원하지 않을 때</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">켜기 칸 아래의 안내가 바뀐다</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; color: #98A2B3">
|
||||
<input type="checkbox" disabled style="width: 18px; height: 18px; margin: 0">
|
||||
<span style="font-weight: 600">새 메일이 오면 바탕화면 알림 보내기</span>
|
||||
</label>
|
||||
<p style="margin: 0 0 0 28px; display: flex; align-items: flex-start; gap: 6px; font-size: 12.5px; color: #B42318">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto; margin-top: 2px"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
|
||||
<span>브라우저가 이 사이트의 알림을 막고 있습니다. 주소창 왼쪽의 사이트 정보(자물쇠) › 알림을 「허용」으로 바꾼 뒤 이 화면을 새로 고쳐 주세요.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; color: #98A2B3">
|
||||
<input type="checkbox" disabled style="width: 18px; height: 18px; margin: 0">
|
||||
<span style="font-weight: 600">새 메일이 오면 바탕화면 알림 보내기</span>
|
||||
</label>
|
||||
<p style="margin: 0 0 0 28px; font-size: 12.5px; color: #667085">이 브라우저는 바탕화면 알림을 지원하지 않습니다. 새 메일은 그래도 바로 목록에 나타납니다.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">알림 문구</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">오른쪽 아래 · 화면 안 알림</p>
|
||||
</div>
|
||||
<div role="status" style="display: flex; align-items: center; gap: 10px; min-height: 44px; box-sizing: border-box; padding: 6px 14px; border-radius: 10px; background: #0B3640; color: #FFFFFF">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9FE0B5" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
||||
<span style="flex: 1 1 auto; font-weight: 500">바탕화면 알림을 켰습니다.</span>
|
||||
</div>
|
||||
<div role="alert" style="display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 14px; border-radius: 10px; background: #0B3640; color: #FFFFFF">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#FDA29B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
|
||||
<span style="flex: 1 1 auto; font-weight: 500">브라우저가 알림을 막고 있습니다. 푸는 방법은 설정 › 알림에 있습니다.</span>
|
||||
<a href="SettingsNotify.dc.html" class="on-dark" style="flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px; border-radius: 6px; color: #9ED6DB; font-weight: 600; text-decoration: none">설정 열기</a>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">목록 위 [알림 켜기] · 설정의 켜기 칸에서 브라우저가 묻고 난 뒤의 결과입니다. 「차단」을 누른 사람에게 브라우저는 다시 묻지 않습니다.</p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1520}}'>
|
||||
class Component extends DCLogic {
|
||||
renderVals() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,14 +1,15 @@
|
||||
# 웹메일 디자인 원본 (1~4단계)
|
||||
# 웹메일 디자인 원본 (1~5단계)
|
||||
|
||||
확정된 디자인 캔버스의 원본이다. 화면 구현의 기준으로 쓴다.
|
||||
|
||||
- 캔버스: https://claude.ai/artifact/WJvVsKvXepxn3p75CGJAr2 (확정본: 2026-10-28, 버전 23)
|
||||
- 캔버스: https://claude.ai/artifact/WJvVsKvXepxn3p75CGJAr2 (확정본: 2026-10-28, 버전 27)
|
||||
- 화면: `Login`(로그인) · `Main`(분할 보기: 메일함·목록·본문) · `MainList`(목록 보기: 게시판형 표) · `MainListRead`(목록 보기에서 연 메일)
|
||||
· `Compose`(메일 쓰기 — 서식 편집기) · `ComposeEditor`(메일 쓰기 · 편집기 상태: 포커스·툴바·메뉴·팝오버·인용·이미지 첨부)
|
||||
· `States`(오류·빈 상태·피드백 모음)
|
||||
· 2단계: `Settings`(설정 · 메일 서명) · `ComposeAssist`(메일 쓰기 · 임시 저장 · 받는 사람 자동 완성 · 서명) — 아래 "2단계"
|
||||
· 3단계: `Search`(메일 검색 · 분할 보기) · `BulkSelect`(여러 통 선택 · 목록 보기) · `ListStates`(새 메일 · 검색 · 여러 통 처리 상태) — 아래 "3단계"
|
||||
· 4단계: `SettingsAccount`(설정 · 비밀번호) · `SettingsVacation`(설정 · 부재중 자동 응답) · `MailboxManage`(메일함 관리 · 휴지통 비우기) · `MailActions4`(스팸 · 원문 · 오래 걸리는 처리) — 아래 "4단계"
|
||||
· 5단계: `SettingsNotify`(설정 · 알림) · `MailRealtime`(실시간 새 메일 · 바탕화면 알림 상태) — 아래 "5단계"
|
||||
- 파일 형식은 캔버스 전용(`<x-dc>` 마크업 + `DCLogic` 클래스)이다. 그대로 쓰지 말고 **구조·간격·색·문구의 기준**으로만 본다.
|
||||
`Compose` 의 툴바·메뉴는 눌러 볼 수 있는 시안이다 — 버튼 상태만 바뀌고 본문 글자에 서식이 입혀지지는 않는다.
|
||||
|
||||
@@ -309,6 +310,42 @@ API 와 서버 규칙은 계약 1절 "`PUT /api/auth/password`", 2절 "메일함
|
||||
- 알림 문구: "메일 2통을 스팸메일함으로 옮겼습니다." [되돌리기] · "메일 1통을 받은편지함으로 옮겼습니다 (스팸 아님)." [되돌리기] ·
|
||||
"‘협력사’ 메일함을 만들었습니다." · "‘거래처’ 메일함을 지웠습니다. 안의 메일 12통은 휴지통에 있습니다." · "휴지통을 비웠습니다 — 메일 21통." (비우기 · 지우기는 되돌리기 없음)
|
||||
|
||||
## 5단계 — 실시간 새 메일 · 바탕화면 알림 (2026-10-28 확정 — `SettingsNotify` · `MailRealtime`)
|
||||
|
||||
API 와 서버 규칙은 계약 2절 "실시간 알림".
|
||||
|
||||
### 설정 › 메일 › 알림
|
||||
|
||||
- 메뉴의 "메일" 묶음 끝에 「알림」(종 아이콘).
|
||||
- [x] 새 메일이 오면 바탕화면 알림 보내기(44). 켜면 브라우저가 허락을 묻는다. 칸 아래 안내(12.5px):
|
||||
묻기 전 "켜면 브라우저가 알림을 허락할지 한 번 묻습니다 — 「허용」을 눌러 주세요." · 허용됨 "이 브라우저에서 알림이 허용되어 있습니다."(#067647, 체크 아이콘) ·
|
||||
막힘(칸을 끄고 빨강 #B42318) "브라우저가 이 사이트의 알림을 막고 있습니다. 주소창 왼쪽의 사이트 정보(자물쇠) › 알림을 「허용」으로 바꾼 뒤 이 화면을 새로 고쳐 주세요." ·
|
||||
지원하지 않음 "이 브라우저는 바탕화면 알림을 지원하지 않습니다. 새 메일은 그래도 바로 목록에 나타납니다."
|
||||
- 알림에 보일 것: [x] 메일 제목도 보이기 — "끄면 보낸 사람 이름만 보입니다 — 화면을 다른 사람과 함께 보는 자리라면 꺼 두세요." (알림을 끄면 흐리게)
|
||||
- [시험 알림 보내기](보조 단추 44 · 종 아이콘) — 알림 "ARA 웹메일" / "알림이 잘 옵니다. 새 메일이 오면 이렇게 알려 드립니다."
|
||||
- 실시간 연결: ● 초록 "연결되어 있습니다 — 새 메일이 오면 바로 목록에 나타납니다." / 끊겼을 때 "연결할 수 없어 1분마다 확인합니다." (저절로 다시 잇는다)
|
||||
- 아래 안내 상자(바탕 #F3F8F8): 이 브라우저에만 적용 · 웹메일 탭이 하나라도 열려 있어야 · 웹메일 화면을 보고 있을 때는 보내지 않음.
|
||||
|
||||
### 목록 위에서 한 번 권하기
|
||||
|
||||
- 알림을 켜지도 닫지도 않은 사람에게 메일 화면의 목록 머리 아래에 40 줄(바탕 #F3F8F8 — 새 메일 알림 줄과 같은 높이, 밀도 예외):
|
||||
종 아이콘 + "바탕화면 알림을 켜 두면 다른 창을 보는 동안에도 새 메일을 알려 드립니다." [알림 켜기](강조 글자 굵게) [✕ 닫기].
|
||||
- [알림 켜기] → 브라우저가 묻는다 → 허용: 알림 "바탕화면 알림을 켰습니다." / 막힘: 오류 알림 "브라우저가 알림을 막고 있습니다. 푸는 방법은 설정 › 알림에 있습니다." [설정 열기].
|
||||
- [✕]는 다시 보이지 않는다(브라우저 · 사용자마다). 브라우저가 이미 막았거나 지원하지 않으면 보이지 않는다.
|
||||
|
||||
### 바탕화면 알림
|
||||
|
||||
- 모양은 운영체제 · 브라우저가 그린다 — 정하는 것은 제목 · 내용 · 아이콘(ARA 마크, 바탕 #0B3640 둥근 사각)뿐이다.
|
||||
- 한 통: 제목 = 보낸 사람(이름, 없으면 주소), 내용 = 메일 제목. 여러 통: "새 메일 3통" / "박서준 · 이도윤 외 1명". 제목 숨김: 내용 "새 메일이 왔습니다".
|
||||
- 새 알림은 앞의 알림을 바꿔 쓴다(쌓이지 않는다). 누르면 웹메일 탭으로 와서 그 메일을 연다(여러 통이면 받은편지함).
|
||||
- 받은편지함에 새로 배달된 안 읽은 메일만(내가 보낸 메일 · 임시 저장 · 다른 메일함으로 옮겨진 메일은 아님), 웹메일을 보고 있지 않을 때만(보이고 초점이 있는 탭이 없을 때), 탭이 여러 개여도 한 번.
|
||||
|
||||
### 실시간 반영
|
||||
|
||||
- 화면 모양은 그대로다 — 새 메일이 1초 안에 목록 · 메일함 숫자 · 탭 제목 "(N)" 에 나타난다(지금은 최대 1분). 목록을 내려 보고 있으면 지금처럼 "새 메일 N통 · 맨 위로" 줄.
|
||||
- 다른 탭을 보는 동안에도 탭 제목의 "(N)" 이 바로 바뀐다.
|
||||
- 실시간 연결이 끊기면 화면에는 알리지 않고 1분 확인으로 돌아간다(설정 › 알림의 연결 상태로 볼 수 있다).
|
||||
|
||||
## 구현하며 정한 보완 (2026-10-26 — 캔버스에는 아직 없다)
|
||||
|
||||
- 찾지 못한 첨부(보관 시간이 지난 업로드·지워진 원본)는 실패로 표시하고, 전달 원본에는 "빼기"만 둔다(다시 올릴 수 없다).
|
||||
@@ -402,3 +439,30 @@ API 와 서버 규칙은 계약 1절 "`PUT /api/auth/password`", 2절 "메일함
|
||||
- 목록 머리 「비우기」의 확인은 연 그 메일함만 비운다 — 확인 창이 열린 채 다른 메일함으로 가면(뒤로 가기 등) 창을 닫는다.
|
||||
- 서버가 처리 수 0 을 세 번 연달아 주면 멈추고 실패로 알린다(같은 요청을 끝없이 보내지 않게).
|
||||
- **스팸**: 「되돌리기」는 원래 메일함으로 옮기며 표시를 반대로 바꾼다 — 원래 아무 표시도 없던 메일은 "스팸 아님" 표시가 남는다(계약 2절 "스팸 · 원문").
|
||||
|
||||
### 5단계 구현하며 정한 보완 (2026-10-28 — 캔버스에는 아직 없다)
|
||||
|
||||
- **알림을 막았을 때의 알림**은 보드의 어두운 바탕 대신 기존 오류 알림 모양(흰 카드)을 쓴다. [설정 열기]는 브랜드 색.
|
||||
- **"웹메일을 보고 있음"** 은 같은 사용자로 로그인한 이 앱의 탭 가운데 보이고 초점이 있는 탭이 있다는 뜻이다 — 설정 화면을 보고 있어도 보내지 않는다.
|
||||
두 번째 모니터에 웹메일을 띄워 두고 다른 창에서 일하면 보낸다(권하기 문구 "다른 창을 보는 동안에도"와 맞게).
|
||||
- **설정 › 알림**
|
||||
- 허락은 했는데 알림을 꺼 둔 상태: 칸은 비우고 안내는 초록 "이 브라우저에서 알림이 허용되어 있습니다."(보드에 없는 상태).
|
||||
- 실시간을 쓸 수 없는 브라우저(Web Locks · BroadcastChannel · 스트림 읽기 가운데 하나라도 없음)는 바탕화면 알림도 "지원하지 않습니다"로 본다 — 알림은 실시간으로만 온다.
|
||||
- 연결 상태 글: 처음 잇는 중 "연결하는 중입니다…", 끊김 "연결할 수 없어 1분마다 확인합니다." 아래에 "저절로 다시 잇습니다. 회사 방화벽 · 프록시가 오래 열린 연결을 끊으면 이렇게 됩니다.",
|
||||
지원하지 않음 "이 브라우저는 실시간 연결을 지원하지 않습니다."
|
||||
- 주소는 `/settings/mail/notify`, 탭 제목은 "메일 알림"(머리글은 "알림").
|
||||
- 켜기 칸에서 허락을 받은 결과는 칸 아래 안내로만 보인다(화면 알림은 목록 위 권하기 줄에서만 — 설정 화면에서 [설정 열기]는 어색하다).
|
||||
- 연결이 끊긴 동안은 "연결할 수 없어 1분마다 확인합니다." 아래에 "연결될 때까지 바탕화면 알림은 오지 않습니다."를 더한다.
|
||||
- 알림을 만들 수 없는 브라우저(휴대폰 Chrome 은 `new Notification()` 을 막는다)는 처음 실패할 때 "지원하지 않습니다"로 바꾼다.
|
||||
- 한국어 안내 글은 낱말 가운데서 줄을 바꾸지 않는다(`word-break: keep-all`, 긴 주소는 `overflow-wrap: anywhere`).
|
||||
- **목록 위 권하기 줄**은 메일함 목록에만 둔다(검색 결과에는 두지 않는다). 줄이 사라지면 초점을 목록 칸으로 옮긴다.
|
||||
분할 보기의 좁은 목록 칸(384)에서는 짧은 글 "바탕화면 알림으로 새 메일 받기"를 쓴다(긴 글은 툴팁) — 긴 글은 잘려 끝까지 읽을 수 없었다.
|
||||
- **바탕화면 알림**
|
||||
- "외 N명"은 서버가 보낸 새 메일(최대 5통)에서 겹치지 않는 보낸 사람(주소 기준)으로 센다.
|
||||
- 시험 알림도 새 메일 알림과 같은 자리(tag)를 쓴다. 누르면 창만 앞으로 온다.
|
||||
- 알림을 눌렀을 때 받은편지함을 아직 모르면 메일함을 받아 본 뒤 열고, 그래도 모르면 메일 첫 화면으로 간다. 누르기 전에 로그아웃 · 다른 계정 로그인이 있었으면 이동하지 않는다.
|
||||
- 아이콘은 192px PNG(`frontend/src/assets/brand/notification-icon.png` — ARA 마크를 #0B3640 둥근 사각 가운데에).
|
||||
- 사용자가 웹메일로 돌아오면(어느 탭이든 보이고 초점이 생기면) 띄운 알림을 닫는다 — 알림 센터에 지난 알림이 남지 않게.
|
||||
- 허락을 묻는 동안 단추 · 칸은 눌러도 다시 묻지 않을 뿐 초점을 잃지 않는다(`aria-disabled`). 막힘 · 지원 안 함으로 칸이 꺼지면 초점을 안내 글로 옮긴다.
|
||||
- **탭 제목 "(N)"** 은 지금처럼 메일 화면에서만 붙인다(메일 밖 화면에는 받은편지함 수의 기준이 없다). 메일 밖에 있는 동안 생긴 바뀜은 남겨 두었다가 메일 화면으로 돌아오면 맞춘다.
|
||||
- **실시간 반영 시간**: 실시간이 부른 목록 맞추기는 1초 모아서 한 번 한다(한 통을 읽어도 바뀜이 오므로 — 연달은 바뀜에 목록을 여러 번 받지 않게). 그래서 새 메일은 "1초 안"이 아니라 2초 안팎에 목록에 나타난다.
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>설정 · 알림</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<style>
|
||||
@font-face{font-family:'Pretendard';src:url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2-variations'),url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2');font-weight:45 920;font-style:normal;font-display:swap}
|
||||
body{margin:0}
|
||||
a{color:#0E7C86}a:hover{color:#0A5F67}
|
||||
:focus-visible{outline:2px solid #0E7C86;outline-offset:2px}
|
||||
.ghost{background:transparent;color:#4A5363}
|
||||
.ghost:hover{background:#F2F4F7;color:#171C26}
|
||||
.secondary{background:#FFFFFF;color:#344054;border:1px solid #D0D5DD !important}
|
||||
.secondary:hover{background:#F8F9FB;color:#171C26}
|
||||
.secondary:disabled{background:#F8F9FB;color:#98A2B3;cursor:not-allowed}
|
||||
.menu-link{color:#344054}
|
||||
.menu-link:hover{background:#EEF0F3}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="position: relative; min-height: 100vh; display: flex; background: #FFFFFF; color: #171C26; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 13px; line-height: 1.5">
|
||||
|
||||
<nav aria-label="사내 시스템" style="flex: 0 0 72px; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 10px 0 12px; background: #0B3640">
|
||||
<a href="Main.dc.html" style="display: inline-flex; align-items: center; justify-content: center; width: 60px; min-height: 44px; border-radius: 10px; text-decoration: none">
|
||||
<img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="ARA SYSTEM" width="48" height="17" style="display: block; width: 48px; height: auto">
|
||||
</a>
|
||||
<ul style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px">
|
||||
<li>
|
||||
<a href="Main.dc.html" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
|
||||
<span>메일</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
|
||||
<span>캘린더</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>
|
||||
<span>파일</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path></svg>
|
||||
<span>ERP</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
|
||||
<span>주소록</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a href="Settings.dc.html" aria-current="page" style="margin-top: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; background: #155A64; color: #FFFFFF; font-size: 11px; font-weight: 600; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||
<span>설정</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div style="flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column">
|
||||
|
||||
<header style="display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; box-sizing: border-box; min-height: 56px; padding: 6px 12px 6px 20px; border-bottom: 1px solid #E6E8EC">
|
||||
<span style="font-size: 16px; font-weight: 700; letter-spacing: -0.01em">설정</span>
|
||||
<div style="flex: 1 1 280px; max-width: 520px; display: flex; align-items: center; gap: 8px; box-sizing: border-box; height: 40px; padding: 0 12px; border: 1px solid #8A94A3; border-radius: 8px; background: #FFFFFF">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#667085" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
||||
<input type="search" aria-label="통합 검색" placeholder="통합 검색" style="flex: 1 1 auto; min-width: 0; border: 0; background: transparent; font: inherit; color: #171C26">
|
||||
</div>
|
||||
<div style="margin-left: auto; display: flex; align-items: center; gap: 10px">
|
||||
<span aria-hidden="true" style="display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: #E3F2F3; color: #0A5F67; font-size: 13px; font-weight: 600">김</span>
|
||||
<div style="display: flex; flex-direction: column; line-height: 1.3">
|
||||
<span style="font-weight: 600">김아라</span>
|
||||
<span style="font-size: 12px; color: #667085">ara.kim@arasystem.it.kr</span>
|
||||
</div>
|
||||
<a href="Login.dc.html" style="display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 10px; border-radius: 8px; color: #4A5363; font-weight: 500; text-decoration: none">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
||||
<span>로그아웃</span>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div style="flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: stretch">
|
||||
|
||||
<nav aria-label="설정 메뉴" style="flex: 1 1 208px; box-sizing: border-box; display: flex; flex-direction: column; gap: 4px; padding: 14px 10px; background: #F8F9FB; border-right: 1px solid #E6E8EC">
|
||||
<p style="margin: 4px 10px 4px; font-size: 12px; font-weight: 600; color: #667085">계정</p>
|
||||
<ul style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px">
|
||||
<li><a href="SettingsAccount.dc.html" class="menu-link" style="display: flex; align-items: center; gap: 10px; min-height: 40px; box-sizing: border-box; padding: 0 10px; border-radius: 7px; font-weight: 500; text-decoration: none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
|
||||
<span>비밀번호</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
<p style="margin: 14px 10px 4px; font-size: 12px; font-weight: 600; color: #667085">메일</p>
|
||||
<ul style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px">
|
||||
<li><a href="Settings.dc.html" class="menu-link" style="display: flex; align-items: center; gap: 10px; min-height: 40px; box-sizing: border-box; padding: 0 10px; border-radius: 7px; font-weight: 500; text-decoration: none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
|
||||
<span>서명</span>
|
||||
</a></li>
|
||||
<li><a href="SettingsVacation.dc.html" class="menu-link" style="display: flex; align-items: center; gap: 10px; min-height: 40px; box-sizing: border-box; padding: 0 10px; border-radius: 7px; font-weight: 500; text-decoration: none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line><line x1="10" y1="14" x2="14" y2="18"></line><line x1="14" y1="14" x2="10" y2="18"></line></svg>
|
||||
<span>부재중 자동 응답</span>
|
||||
</a></li>
|
||||
<li><a href="#" aria-current="page" style="display: flex; align-items: center; gap: 10px; min-height: 40px; box-sizing: border-box; padding: 0 10px; border-radius: 7px; background: #E3F2F3; color: #0A5F67; font-weight: 600; text-decoration: none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
||||
<span>알림</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main style="flex: 999 1 560px; min-width: 0; box-sizing: border-box; display: flex; flex-direction: column">
|
||||
<div style="max-width: 800px; box-sizing: border-box; padding: 20px 32px 36px; display: flex; flex-direction: column; gap: 22px">
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||
<h1 style="margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em">알림</h1>
|
||||
<p style="margin: 0; color: #4A5363">새 메일은 1분을 기다리지 않고 바로 목록에 나타납니다. 다른 창을 보는 동안에도 알고 싶으면 바탕화면 알림을 켜 두세요.</p>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 6px">
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer">
|
||||
<input type="checkbox" checked="{{ on }}" onChange="{{ toggleOn }}" style="width: 18px; height: 18px; margin: 0; accent-color: #0E7C86; cursor: pointer">
|
||||
<span style="font-weight: 600">새 메일이 오면 바탕화면 알림 보내기</span>
|
||||
</label>
|
||||
<sc-if value="{{ askedNow }}" hint-placeholder-val="{{ false }}">
|
||||
<p role="status" style="margin: 0 0 0 28px; display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: #067647">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
||||
<span>이 브라우저에서 알림이 허용되어 있습니다.</span>
|
||||
</p>
|
||||
</sc-if>
|
||||
<sc-if value="{{ firstAsk }}" hint-placeholder-val="{{ true }}">
|
||||
<p style="margin: 0 0 0 28px; font-size: 12.5px; color: #667085">켜면 브라우저가 알림을 허락할지 한 번 묻습니다 — 「허용」을 눌러 주세요.</p>
|
||||
</sc-if>
|
||||
</div>
|
||||
|
||||
<fieldset disabled="{{ off }}" style="display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; border: 0">
|
||||
<legend style="margin: 0 0 4px; padding: 0; font-weight: 600; color: #171C26">알림에 보일 것</legend>
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer">
|
||||
<input type="checkbox" checked="{{ showSubject }}" onChange="{{ toggleSubject }}" style="width: 18px; height: 18px; margin: 0; accent-color: #0E7C86; cursor: pointer">
|
||||
<span>메일 제목도 보이기</span>
|
||||
</label>
|
||||
<p style="margin: 0 0 0 28px; font-size: 12.5px; color: #667085">끄면 보낸 사람 이름만 보입니다 — 화면을 다른 사람과 함께 보는 자리라면 꺼 두세요.</p>
|
||||
</fieldset>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px">
|
||||
<button type="button" class="secondary" disabled="{{ off }}" onClick="{{ test }}" style="display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; border: 0; border-radius: 8px; font: inherit; font-weight: 600; cursor: pointer">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
||||
<span>시험 알림 보내기</span>
|
||||
</button>
|
||||
<span style="font-size: 12.5px; color: #667085">바탕화면 오른쪽 아래(맥은 오른쪽 위)에 알림이 뜨면 됩니다.</span>
|
||||
</div>
|
||||
|
||||
<hr style="width: 100%; height: 1px; margin: 0; border: 0; background: #EEF0F3">
|
||||
|
||||
<section aria-labelledby="realtime-title" style="display: flex; flex-direction: column; gap: 8px">
|
||||
<h2 id="realtime-title" style="margin: 0; font-size: 14px; font-weight: 700">실시간 연결</h2>
|
||||
<p role="status" style="margin: 0; display: flex; align-items: center; gap: 8px">
|
||||
<span aria-hidden="true" style="width: 8px; height: 8px; border-radius: 50%; background: #12B76A"></span>
|
||||
<span>연결되어 있습니다 — 새 메일이 오면 바로 목록에 나타납니다.</span>
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #667085">연결할 수 없을 때는 "연결할 수 없어 1분마다 확인합니다."로 바뀌고, 저절로 다시 잇습니다. 회사 방화벽 · 프록시가 오래 열린 연결을 끊으면 이렇게 됩니다.</p>
|
||||
</section>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 6px; box-sizing: border-box; max-width: 620px; padding: 14px 16px; border-radius: 10px; background: #F3F8F8; color: #344054">
|
||||
<p style="margin: 0; display: flex; gap: 8px"><span aria-hidden="true">·</span><span>알림 설정은 <strong style="font-weight: 600">이 브라우저에만</strong> 적용됩니다. 다른 PC · 브라우저에서는 그곳에서 따로 켜 주세요.</span></p>
|
||||
<p style="margin: 0; display: flex; gap: 8px"><span aria-hidden="true">·</span><span>웹메일 탭이 하나라도 열려 있어야 알림이 옵니다. 탭을 모두 닫으면 오지 않습니다.</span></p>
|
||||
<p style="margin: 0; display: flex; gap: 8px"><span aria-hidden="true">·</span><span>웹메일 화면을 보고 있을 때는 바탕화면 알림을 보내지 않습니다 — 목록에 바로 보이므로.</span></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<sc-if value="{{ testShown }}" hint-placeholder-val="{{ false }}">
|
||||
<div role="img" aria-label="시험 알림 (운영체제가 그리는 모양의 예)" style="position: absolute; right: 24px; bottom: 24px; width: 364px; box-sizing: border-box; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; border-radius: 10px; background: #FFFFFF; border: 1px solid #E3E5E8; box-shadow: 0 14px 36px rgba(16, 24, 28, 0.22)">
|
||||
<div style="display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #667085">
|
||||
<span aria-hidden="true" style="display: inline-flex; width: 14px; height: 14px; border-radius: 3px; background: #0B3640"></span>
|
||||
<span>Microsoft Edge</span>
|
||||
<span style="margin-left: auto">지금</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 12px">
|
||||
<span aria-hidden="true" style="flex: 0 0 44px; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 10px; background: #0B3640">
|
||||
<img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="" width="34" height="12" style="display: block; width: 34px; height: auto">
|
||||
</span>
|
||||
<div style="min-width: 0; display: flex; flex-direction: column; gap: 2px">
|
||||
<span style="font-size: 13.5px; font-weight: 700">ARA 웹메일</span>
|
||||
<span style="font-size: 13px; color: #344054">알림이 잘 옵니다. 새 메일이 오면 이렇게 알려 드립니다.</span>
|
||||
<span style="font-size: 11.5px; color: #98A2B3">portal.arasystem.it.kr</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</sc-if>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":900}}'>
|
||||
class Component extends DCLogic {
|
||||
state = { on: false, showSubject: true, testShown: false };
|
||||
|
||||
renderVals() {
|
||||
const st = this.state;
|
||||
return {
|
||||
on: st.on,
|
||||
off: !st.on,
|
||||
askedNow: st.on,
|
||||
firstAsk: !st.on,
|
||||
showSubject: st.showSubject,
|
||||
testShown: st.on && st.testShown,
|
||||
toggleOn: () => this.setState({ on: !st.on, testShown: false }),
|
||||
toggleSubject: () => this.setState({ showSubject: !st.showSubject }),
|
||||
test: () => this.setState({ testShown: true }),
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -20,14 +20,17 @@
|
||||
"SettingsAccount.dc.html": { "x": 0, "y": 6640, "w": 1440, "h": 900, "title": "설정 · 비밀번호", "expand": "fill", "is_interactive": true },
|
||||
"SettingsVacation.dc.html": { "x": 1520, "y": 6640, "w": 1440, "h": 1060, "title": "설정 · 부재중 자동 응답", "expand": "fill", "is_interactive": true },
|
||||
"MailboxManage.dc.html": { "x": 3040, "y": 6640, "w": 1440, "h": 900, "title": "메일함 관리 · 휴지통 비우기", "expand": "fill", "is_interactive": true },
|
||||
"MailActions4.dc.html": { "x": 4560, "y": 6640, "w": 1440, "h": 1320, "title": "스팸 · 원문 · 오래 걸리는 처리 상태" }
|
||||
"MailActions4.dc.html": { "x": 4560, "y": 6640, "w": 1440, "h": 1320, "title": "스팸 · 원문 · 오래 걸리는 처리 상태" },
|
||||
"SettingsNotify.dc.html": { "x": 0, "y": 8560, "w": 1440, "h": 900, "title": "설정 · 알림", "expand": "fill", "is_interactive": true },
|
||||
"MailRealtime.dc.html": { "x": 1520, "y": 8560, "w": 1440, "h": 1520, "title": "실시간 새 메일 · 바탕화면 알림 상태" }
|
||||
},
|
||||
"order": ["Main.dc.html", "Login.dc.html", "Compose.dc.html", "States.dc.html", "MainList.dc.html", "MainListRead.dc.html", "ComposeEditor.dc.html", "Settings.dc.html", "ComposeAssist.dc.html", "Search.dc.html", "BulkSelect.dc.html", "ListStates.dc.html", "SettingsAccount.dc.html", "SettingsVacation.dc.html", "MailboxManage.dc.html", "MailActions4.dc.html"],
|
||||
"order": ["Main.dc.html", "Login.dc.html", "Compose.dc.html", "States.dc.html", "MainList.dc.html", "MainListRead.dc.html", "ComposeEditor.dc.html", "Settings.dc.html", "ComposeAssist.dc.html", "Search.dc.html", "BulkSelect.dc.html", "ListStates.dc.html", "SettingsAccount.dc.html", "SettingsVacation.dc.html", "MailboxManage.dc.html", "MailActions4.dc.html", "SettingsNotify.dc.html", "MailRealtime.dc.html"],
|
||||
"notes": {
|
||||
"flow": { "x": 0, "y": -300, "text": "arasystem 웹메일 — 1단계 화면 (로그인 → 메일함 → 쓰기)", "kind": "title1", "maxW": 4480 },
|
||||
"phase2": { "x": 0, "y": 2180, "text": "2단계 화면 — 임시 저장 · 받는 사람 자동 완성 · 서명 (2026-10-27 확정)", "kind": "title1", "maxW": 2960 },
|
||||
"phase3": { "x": 0, "y": 4180, "text": "3단계 화면 — 새 메일 · 검색 · 여러 통 처리 (2026-10-27 확정)", "kind": "title1", "maxW": 4480 },
|
||||
"phase4": { "x": 0, "y": 6340, "text": "4단계 화면 — 계정 · 메일 설정 (비밀번호 · 부재중 응답 · 메일함 관리 · 스팸 · 원문) — 2026-10-28 확정", "kind": "title1", "maxW": 6000 }
|
||||
"phase4": { "x": 0, "y": 6340, "text": "4단계 화면 — 계정 · 메일 설정 (비밀번호 · 부재중 응답 · 메일함 관리 · 스팸 · 원문) — 2026-10-28 확정", "kind": "title1", "maxW": 6000 },
|
||||
"phase5": { "x": 0, "y": 8260, "text": "5단계 화면 — 실시간 새 메일 · 바탕화면 알림 — 2026-10-28 확정", "kind": "title1", "maxW": 2960 }
|
||||
},
|
||||
"designSystems": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user