Lompat ke konten

Daftar notifikasi

Dipakai ketika orang yang membuka aplikasi setelah beberapa hari harus menelusuri apa yang terjadi dan memisahkan yang sudah dibaca dari yang belum.

Contoh layar

Pratinjau langsung

Sumber

<script>document.body.className="dc-bleed"</script>
<div class="dc-nt">
  <header class="dc-nt__top">
    <h1 class="dc-nt__title">알림</h1>
    <button class="dc-nt__read" type="button">모두 읽음</button>
    <button class="dc-nt__ico" type="button"><span aria-hidden="true">⚙</span><span class="dc-sr">알림 설정</span></button>
  </header>

  <div class="dc-nt__filters" role="group" aria-label="알림 종류 고르기">
    <button class="dc-nt__chip dc-nt__chip--on" type="button" aria-pressed="true">전체 <span class="dc-nt__chip-num">2</span></button>
    <button class="dc-nt__chip" type="button" aria-pressed="false">급여</button>
    <button class="dc-nt__chip" type="button" aria-pressed="false">계약</button>
    <button class="dc-nt__chip" type="button" aria-pressed="false">근무</button>
    <button class="dc-nt__chip" type="button" aria-pressed="false">공지</button>
  </div>

  <main class="dc-nt__body">
    <h2 class="dc-nt__day">오늘</h2>
    <ul class="dc-nt__list">
      <li>
        <a class="dc-nt__item dc-nt__item--new" href="#">
          <span class="dc-nt__ava dc-nt__ava--ok" aria-hidden="true">₩</span>
          <span class="dc-nt__txt">
            <span class="dc-nt__head"><span class="dc-nt__name">8월 급여명세서가 도착했어요</span><span class="dc-nt__time">14:20</span></span>
            <span class="dc-nt__msg">실지급 2,099,400원 · 9월 10일 입금 예정입니다. 공제 내역을 확인해 주세요.</span>
          </span>
          <span class="dc-nt__dot" aria-hidden="true"></span>
          <span class="dc-sr">읽지 않음</span>
        </a>
      </li>
      <li>
        <a class="dc-nt__item dc-nt__item--new" href="#">
          <span class="dc-nt__ava dc-nt__ava--brand" aria-hidden="true">✎</span>
          <span class="dc-nt__txt">
            <span class="dc-nt__head"><span class="dc-nt__name">근로계약서 서명 요청</span><span class="dc-nt__time">11:05</span></span>
            <span class="dc-nt__msg">미소식품 · 주방보조 · 시급 10,320원. 9월 14일까지 서명하면 됩니다.</span>
            <span class="dc-nt__act">지금 서명하기</span>
          </span>
          <span class="dc-nt__dot" aria-hidden="true"></span>
          <span class="dc-sr">읽지 않음</span>
        </a>
      </li>
      <li>
        <a class="dc-nt__item" href="#">
          <span class="dc-nt__ava dc-nt__ava--warn" aria-hidden="true">!</span>
          <span class="dc-nt__txt">
            <span class="dc-nt__head"><span class="dc-nt__name">목요일 연장근로 2시간이 빠졌어요</span><span class="dc-nt__time">09:42</span></span>
            <span class="dc-nt__msg">출퇴근 기록과 급여가 다릅니다. 상담사에게 보낼 수 있습니다.</span>
          </span>
        </a>
      </li>
    </ul>

    <h2 class="dc-nt__day">어제</h2>
    <ul class="dc-nt__list">
      <li>
        <a class="dc-nt__item" href="#">
          <span class="dc-nt__ava dc-nt__ava--info" aria-hidden="true">☏</span>
          <span class="dc-nt__txt">
            <span class="dc-nt__head"><span class="dc-nt__name">김현수 팀장이 메시지를 보냈어요</span><span class="dc-nt__time">어제 18:31</span></span>
            <span class="dc-nt__msg">“다음 주 월요일 오전 9시 출근으로 바뀌었어요.”</span>
          </span>
        </a>
      </li>
      <li>
        <a class="dc-nt__item" href="#">
          <span class="dc-nt__ava" aria-hidden="true">🛈</span>
          <span class="dc-nt__txt">
            <span class="dc-nt__head"><span class="dc-nt__name">추석 연휴 상담센터 운영 안내</span><span class="dc-nt__time">어제 10:00</span></span>
            <span class="dc-nt__msg">9월 24일부터 26일까지는 네팔어 상담이 오후에만 열립니다.</span>
          </span>
        </a>
      </li>
    </ul>
    <p class="dc-nt__end">30일이 지난 알림은 자동으로 지워집니다</p>
  </main>

  <nav class="dc-nt__tabs" aria-label="주요 메뉴">
    <a class="dc-nt__tab" href="#">
      <span class="dc-nt__tab-ico" aria-hidden="true">⌂</span>
      <span class="dc-nt__tab-lbl">홈</span>
    </a>
    <a class="dc-nt__tab" href="#">
      <span class="dc-nt__tab-ico" aria-hidden="true">▤</span>
      <span class="dc-nt__tab-lbl">명세서</span>
    </a>
    <a class="dc-nt__tab" href="#" aria-current="page">
      <span class="dc-nt__tab-ico" aria-hidden="true">◔<span class="dc-nt__badge">2</span></span>
      <span class="dc-nt__tab-lbl">알림</span>
      <span class="dc-sr">읽지 않은 알림 2건</span>
    </a>
    <a class="dc-nt__tab" href="#">
      <span class="dc-nt__tab-ico" aria-hidden="true">◉</span>
      <span class="dc-nt__tab-lbl">내 정보</span>
    </a>
  </nav>
</div>
.dc-nt { display:flex; flex-direction:column; height:100vh; overflow:hidden; background:var(--dc-bg); color:var(--dc-text); font-family:var(--dc-font); }
.dc-nt__top { flex:0 0 auto; display:flex; align-items:center; gap:var(--dc-1); padding:calc(var(--dc-safe-top) + var(--dc-2)) var(--dc-2) var(--dc-2) var(--dc-4); background:var(--dc-surface); }
.dc-nt__title { flex:1 1 auto; font-size:22px; font-weight:800; letter-spacing:-.03em; color:var(--dc-text); }
.dc-nt__read { display:inline-flex; align-items:center; min-height:44px; padding:0 var(--dc-3); border:0; border-radius:var(--dc-r-sm); background:transparent; color:var(--dc-brand-text); font-size:14px; font-weight:700; }
.dc-nt__read:active { background:var(--dc-sunken); }
.dc-nt__ico { display:grid; place-items:center; width:44px; height:44px; border:0; border-radius:var(--dc-r-full); background:transparent; color:var(--dc-text-sub); font-size:19px; line-height:1; }
.dc-nt__ico:active { background:var(--dc-sunken); }
.dc-nt__filters { flex:0 0 auto; display:flex; gap:var(--dc-2); padding:var(--dc-1) var(--dc-4) var(--dc-3); overflow-x:auto; background:var(--dc-surface); border-bottom:1px solid var(--dc-line); scrollbar-width:none; }
.dc-nt__filters::-webkit-scrollbar { display:none; }
.dc-nt__chip { flex:0 0 auto; display:inline-flex; align-items:center; gap:var(--dc-1); min-height:36px; padding:0 var(--dc-3); border:1px solid var(--dc-line-field); border-radius:var(--dc-r-full); background:var(--dc-surface); color:var(--dc-text-sub); font-family:inherit; font-size:13px; font-weight:700; white-space:nowrap; }
.dc-nt__chip--on { border-color:var(--dc-brand); background:var(--dc-brand-soft); color:var(--dc-brand-text); }
.dc-nt__chip-num { font-family:var(--dc-mono); font-size:12px; }
.dc-nt__body { flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding-bottom:var(--dc-5); }
.dc-nt__day { position:sticky; top:0; z-index:1; padding:var(--dc-3) var(--dc-4) var(--dc-2); background:var(--dc-bg); font-size:12px; font-weight:800; letter-spacing:.02em; color:var(--dc-text-mute); }
.dc-nt__list { display:flex; flex-direction:column; }
.dc-nt__item { position:relative; display:flex; align-items:flex-start; gap:var(--dc-3); padding:var(--dc-3) var(--dc-5) var(--dc-3) var(--dc-4); border-bottom:1px solid var(--dc-line); background:var(--dc-bg); text-decoration:none; }
.dc-nt__item:active { background:var(--dc-sunken); }
.dc-nt__item--new { background:var(--dc-brand-soft); }
.dc-nt__item--new .dc-nt__time { color:var(--dc-text-sub); }
.dc-nt__ava { flex:0 0 auto; display:grid; place-items:center; width:40px; height:40px; border-radius:var(--dc-r-full); background:var(--dc-sunken); color:var(--dc-text-sub); font-size:17px; font-weight:800; }
.dc-nt__ava--ok { background:var(--dc-ok-soft); color:var(--dc-ok); }
.dc-nt__ava--brand { background:var(--dc-surface); border:1px solid var(--dc-brand); color:var(--dc-brand-text); }
.dc-nt__ava--warn { background:var(--dc-warn-soft); color:var(--dc-warn); }
.dc-nt__ava--info { background:var(--dc-info-soft); color:var(--dc-info); }
.dc-nt__txt { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
.dc-nt__head { display:flex; align-items:baseline; gap:var(--dc-2); }
.dc-nt__name { flex:1 1 auto; min-width:0; font-size:14px; font-weight:700; line-height:1.4; color:var(--dc-text); }
.dc-nt__time { flex:0 0 auto; font-size:11px; color:var(--dc-text-mute); white-space:nowrap; }
.dc-nt__msg { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; font-size:13px; line-height:1.5; color:var(--dc-text-sub); }
.dc-nt__act { align-self:flex-start; margin-top:var(--dc-2); padding:var(--dc-1) var(--dc-3); border-radius:var(--dc-r-full); background:var(--dc-brand); color:var(--dc-text-on); font-size:12px; font-weight:800; }
.dc-nt__dot { position:absolute; top:calc(50% - 4px); right:var(--dc-3); width:8px; height:8px; border-radius:var(--dc-r-full); background:var(--dc-brand); }
.dc-nt__end { padding:var(--dc-5) var(--dc-4); text-align:center; font-size:12px; color:var(--dc-text-mute); }
.dc-nt__body--empty { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--dc-3); padding:var(--dc-7) var(--dc-6); text-align:center; }
.dc-nt__empty-art { display:grid; place-items:center; width:72px; height:72px; border-radius:var(--dc-r-full); background:var(--dc-sunken); color:var(--dc-text-mute); font-size:30px; }
.dc-nt__empty-title { font-size:18px; font-weight:800; color:var(--dc-text); }
.dc-nt__empty-body { max-width:30ch; font-size:14px; line-height:1.6; color:var(--dc-text-sub); }
.dc-nt__empty-btn { min-height:48px; padding:0 var(--dc-5); border:1px solid var(--dc-line-field); border-radius:var(--dc-r-sm); background:var(--dc-surface); color:var(--dc-text); font-family:inherit; font-size:15px; font-weight:700; }
.dc-nt__empty-btn:active { background:var(--dc-sunken); }
.dc-nt__tabs { flex:0 0 auto; display:flex; padding-bottom:var(--dc-safe-bottom); background:var(--dc-surface); border-top:1px solid var(--dc-line); }
.dc-nt__tab { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; min-height:56px; padding:var(--dc-2) var(--dc-1); color:var(--dc-text-mute); text-decoration:none; }
.dc-nt__tab:active { background:var(--dc-sunken); }
.dc-nt__tab[aria-current="page"] { color:var(--dc-brand-text); }
.dc-nt__tab-ico { position:relative; font-size:20px; line-height:1; }
.dc-nt__tab-lbl { font-size:11px; font-weight:700; letter-spacing:-.01em; }
.dc-nt__badge { position:absolute; top:-5px; left:13px; min-width:18px; height:18px; padding:0 4px; border-radius:var(--dc-r-full); background:var(--dc-danger); color:var(--dc-text-on); font-size:11px; font-weight:800; line-height:18px; text-align:center; }

Cara memakainya

  • Tandai yang belum dibaca dengan dua cara: latar bernuansa dan titik; titik saja terlalu kecil
  • Kelompokkan per hari (Hari ini, Kemarin) — jam saja tidak memberi tahu harinya
  • Potong isi pada dua baris dan simpan detailnya di balik ketukan
  • Beri tombol aksi hanya pada baris yang memang harus dikerjakan sekarang

Hal yang perlu diwaspadai

  • Jangan menandai belum dibaca hanya dengan warna — biarkan dc-sr membacakan "belum dibaca"
  • Angka badge di bilah tab harus sama dengan jumlah baris yang belum dibaca
  • Bilah atas pakai --dc-safe-top, bilah tab bawah pakai --dc-safe-bottom

Berikutnya