릴리스: v1.2.6 목록 화면 카드 레이아웃 정리
This commit is contained in:
@@ -77,13 +77,17 @@ function submitSearch() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="head">
|
||||
<div class="head__left">
|
||||
<div class="kicker">Collection</div>
|
||||
<h2 class="title">{{ gameName || gameId }}</h2>
|
||||
<p class="desc">새 티어표를 만들거나, 다른 사람들이 올린 티어표를 카드형 목록으로 탐색할 수 있어요.</p>
|
||||
<section class="dashboardHero">
|
||||
<div class="dashboardHero__left">
|
||||
<div class="dashboardHero__eyebrow">Collection</div>
|
||||
<h2 class="dashboardHero__title">{{ gameName || gameId }}</h2>
|
||||
<p class="dashboardHero__desc">이 게임의 공개 티어표를 탐색하고, 바로 새 보드를 만들어 같은 흐름으로 이어갈 수 있어요.</p>
|
||||
</div>
|
||||
<div class="head__right">
|
||||
<div class="dashboardHero__right">
|
||||
<div class="dashboardStat">
|
||||
<span class="dashboardStat__label">Visible Lists</span>
|
||||
<strong class="dashboardStat__value">{{ tierLists.length }}</strong>
|
||||
</div>
|
||||
<button class="primary" @click="createNew">{{ auth.user ? '새로운 티어표 만들기' : '로그인 후 새 티어표 만들기' }}</button>
|
||||
</div>
|
||||
</section>
|
||||
@@ -91,7 +95,10 @@ function submitSearch() {
|
||||
<div v-if="error" class="error">{{ error }}</div>
|
||||
<section class="panel">
|
||||
<div class="panel__head">
|
||||
<div class="panel__title">공개 티어표</div>
|
||||
<div>
|
||||
<div class="panel__title">공개 티어표</div>
|
||||
<div class="panel__sub">제목이나 작성자로 빠르게 좁혀볼 수 있어요.</div>
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
<input v-model="query" class="searchBar__input" placeholder="제목 또는 작성자 검색" @keydown.enter.prevent="submitSearch" />
|
||||
<button class="searchBar__button" @click="submitSearch">검색</button>
|
||||
@@ -99,23 +106,23 @@ function submitSearch() {
|
||||
</div>
|
||||
<div v-if="tierLists.length === 0" class="empty">아직 공개 티어표가 없어요.</div>
|
||||
<div v-else class="list">
|
||||
<article v-for="t in tierLists" :key="t.id" class="row">
|
||||
<button class="row__body" @click="openTierList(t.id)">
|
||||
<div class="row__thumbWrap">
|
||||
<img v-if="tierListThumbnailUrl(t)" class="row__thumb" :src="tierListThumbnailUrl(t)" :alt="t.title" />
|
||||
<div v-else class="row__thumbPlaceholder"></div>
|
||||
<article v-for="t in tierLists" :key="t.id" class="boardCard">
|
||||
<button class="boardCard__body" @click="openTierList(t.id)">
|
||||
<div class="boardCard__thumbWrap">
|
||||
<img v-if="tierListThumbnailUrl(t)" class="boardCard__thumb" :src="tierListThumbnailUrl(t)" :alt="t.title" />
|
||||
<div v-else class="boardCard__thumbPlaceholder">대표 썸네일</div>
|
||||
</div>
|
||||
<div class="row__head">
|
||||
<div class="row__title">{{ t.title }}</div>
|
||||
<div class="row__author">
|
||||
<img v-if="avatarSrcOf(t)" class="row__avatar" :src="avatarSrcOf(t)" :alt="displayNameOf(t)" />
|
||||
<div v-else class="row__avatar row__avatar--fallback">{{ avatarFallbackOf(t) }}</div>
|
||||
<div class="boardCard__head">
|
||||
<div class="boardCard__title">{{ t.title }}</div>
|
||||
<div class="boardCard__author">
|
||||
<img v-if="avatarSrcOf(t)" class="boardCard__avatar" :src="avatarSrcOf(t)" :alt="displayNameOf(t)" />
|
||||
<div v-else class="boardCard__avatar boardCard__avatar--fallback">{{ avatarFallbackOf(t) }}</div>
|
||||
<span>by {{ displayNameOf(t) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="row__foot">
|
||||
<div class="row__meta">{{ fmt(t.updatedAt) }}</div>
|
||||
<div class="boardCard__foot">
|
||||
<div class="boardCard__meta">{{ fmt(t.updatedAt) }}</div>
|
||||
<div class="favoriteStat" :title="t.isFavorited ? '이미 즐겨찾기한 티어표' : '즐겨찾기 수'">
|
||||
{{ t.isFavorited ? '★' : '☆' }} {{ t.favoriteCount || 0 }}
|
||||
</div>
|
||||
@@ -126,44 +133,71 @@ function submitSearch() {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.head {
|
||||
.dashboardHero {
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: flex-end;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
padding: 4px 2px 18px;
|
||||
}
|
||||
.kicker {
|
||||
.dashboardHero__left {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
.dashboardHero__right {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.dashboardHero__eyebrow {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.42);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.title {
|
||||
.dashboardHero__title {
|
||||
margin: 4px 0 6px;
|
||||
font-size: 30px;
|
||||
font-size: 32px;
|
||||
letter-spacing: -0.04em;
|
||||
color: rgba(255, 255, 255, 0.96);
|
||||
}
|
||||
.desc {
|
||||
.dashboardHero__desc {
|
||||
margin: 0;
|
||||
color: rgba(255, 255, 255, 0.58);
|
||||
max-width: 720px;
|
||||
}
|
||||
.dashboardStat {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
min-width: 112px;
|
||||
padding: 10px 14px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.dashboardStat__label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.dashboardStat__value {
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
}
|
||||
.primary {
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(77, 127, 233, 0.96);
|
||||
background: rgba(77, 127, 233, 0.88);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
}
|
||||
.primary:hover {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
font-weight: 800;
|
||||
}
|
||||
.panel {
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
/* border: 1px solid rgba(255, 255, 255, 0.08); */
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
@@ -177,6 +211,12 @@ function submitSearch() {
|
||||
}
|
||||
.panel__title {
|
||||
font-weight: 800;
|
||||
font-size: 18px;
|
||||
}
|
||||
.panel__sub {
|
||||
margin-top: 6px;
|
||||
color: rgba(255, 255, 255, 0.56);
|
||||
font-size: 13px;
|
||||
}
|
||||
.panel__head {
|
||||
display: flex;
|
||||
@@ -201,8 +241,8 @@ function submitSearch() {
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
}
|
||||
.searchBar__button {
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
@@ -217,8 +257,8 @@ function submitSearch() {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 18px;
|
||||
}
|
||||
.row {
|
||||
border-radius: 14px;
|
||||
.boardCard {
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
background: rgba(62, 62, 62, 0.82);
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
@@ -227,11 +267,12 @@ function submitSearch() {
|
||||
align-content: start;
|
||||
min-height: 168px;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.row:hover {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
.boardCard:hover {
|
||||
background: rgba(70, 70, 70, 0.96);
|
||||
}
|
||||
.row__body {
|
||||
.boardCard__body {
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@@ -242,35 +283,42 @@ function submitSearch() {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
.row__thumbWrap {
|
||||
.boardCard__thumbWrap {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
background: #555;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.row__thumb {
|
||||
.boardCard__thumb {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.row__thumbPlaceholder {
|
||||
.boardCard__thumbPlaceholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #555;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.row__title {
|
||||
.boardCard__title {
|
||||
font-weight: 800;
|
||||
min-width: 0;
|
||||
font-size: 18px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.row__head {
|
||||
.boardCard__head {
|
||||
padding: 14px 14px 0;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
align-content: start;
|
||||
}
|
||||
.row__author {
|
||||
.boardCard__author {
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
@@ -278,7 +326,7 @@ function submitSearch() {
|
||||
opacity: 0.86;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.row__avatar {
|
||||
.boardCard__avatar {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 999px;
|
||||
@@ -286,17 +334,17 @@ function submitSearch() {
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.row__avatar--fallback {
|
||||
.boardCard__avatar--fallback {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
.row__meta {
|
||||
.boardCard__meta {
|
||||
opacity: 0.78;
|
||||
font-size: 13px;
|
||||
}
|
||||
.row__foot {
|
||||
.boardCard__foot {
|
||||
padding: 0 14px 14px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
@@ -323,6 +371,13 @@ function submitSearch() {
|
||||
}
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.dashboardHero__right {
|
||||
width: 100%;
|
||||
}
|
||||
.dashboardStat,
|
||||
.primary {
|
||||
width: 100%;
|
||||
}
|
||||
.list {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user