feat: complete placement analysis workflow
This commit is contained in:
1 parent
dd3ea911f6
commit
7b713bffe3
452 files changed
+97115
-24
No files matched your search
+102
-10
@@ -1,5 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import cardSummary from '$lib/data/cards-summary.json';
|
||||
import type { CardListPreferences, UserData } from '$lib/models/user-data';
|
||||
import { loadBrowserData, saveBrowserData } from '$lib/storage/browser-storage';
|
||||
|
||||
type CardType = '큐트' | '퓨어' | '해피';
|
||||
type HighestStat = '퍼포먼스' | '테크닉' | '센스';
|
||||
@@ -58,6 +61,39 @@
|
||||
let selectedGenerations = [...generationOptions];
|
||||
let expandedCardId: string | null = null;
|
||||
let selectedSkillLevel = 1;
|
||||
let collection: UserData['collection'] = {};
|
||||
let memberBoards: UserData['memberBoards'] = {};
|
||||
let boardCards: UserData['boardCards'] = {};
|
||||
let savedDecks: UserData['savedDecks'] = [];
|
||||
let memoryCount = 0;
|
||||
let memberPowerUpPercent = 0;
|
||||
let storageReady = false;
|
||||
let currentUserData: UserData;
|
||||
|
||||
$: currentUserData = {
|
||||
schemaVersion: 1,
|
||||
updatedAt: new Date().toISOString(),
|
||||
memoryCount,
|
||||
memberPowerUpPercent,
|
||||
collection,
|
||||
memberBoards,
|
||||
boardCards,
|
||||
savedDecks,
|
||||
preferences: currentPreferences()
|
||||
};
|
||||
|
||||
$: if (storageReady) {
|
||||
try {
|
||||
saveBrowserData(currentUserData);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
try {
|
||||
applyUserData(loadBrowserData(defaultPreferences()));
|
||||
storageReady = true;
|
||||
} catch {}
|
||||
});
|
||||
|
||||
$: filteredCards = cards.filter((card) =>
|
||||
selectedTypes.includes(card.type)
|
||||
@@ -91,6 +127,46 @@
|
||||
selectedGenerations = [...generationOptions];
|
||||
}
|
||||
|
||||
function defaultPreferences(): CardListPreferences {
|
||||
return {
|
||||
types: [...typeOptions],
|
||||
stats: [...statOptions],
|
||||
activeConditions: [...skillConditionOptions],
|
||||
specialConditions: [...skillConditionOptions],
|
||||
activeProbabilities: [...activeProbabilityOptions],
|
||||
cardVariants: [...cardVariantOptions],
|
||||
generations: [...generationOptions]
|
||||
};
|
||||
}
|
||||
|
||||
function currentPreferences(): CardListPreferences {
|
||||
return {
|
||||
types: [...selectedTypes],
|
||||
stats: [...selectedStats],
|
||||
activeConditions: [...selectedActiveConditions],
|
||||
specialConditions: [...selectedSpecialConditions],
|
||||
activeProbabilities: [...selectedActiveProbabilities],
|
||||
cardVariants: [...selectedCardVariants],
|
||||
generations: [...selectedGenerations]
|
||||
};
|
||||
}
|
||||
|
||||
function applyUserData(data: UserData) {
|
||||
selectedTypes = data.preferences.types.filter((value): value is CardType => typeOptions.includes(value as CardType));
|
||||
selectedStats = data.preferences.stats.filter((value): value is HighestStat => statOptions.includes(value as HighestStat));
|
||||
selectedActiveConditions = data.preferences.activeConditions.filter((value): value is SkillConditionStatus => skillConditionOptions.includes(value as SkillConditionStatus));
|
||||
selectedSpecialConditions = data.preferences.specialConditions.filter((value): value is SkillConditionStatus => skillConditionOptions.includes(value as SkillConditionStatus));
|
||||
selectedActiveProbabilities = data.preferences.activeProbabilities.filter((value): value is ActiveProbability => activeProbabilityOptions.includes(value as ActiveProbability));
|
||||
selectedCardVariants = data.preferences.cardVariants.filter((value) => cardVariantOptions.includes(value));
|
||||
selectedGenerations = data.preferences.generations.filter((value) => generationOptions.includes(value));
|
||||
collection = data.collection;
|
||||
memberBoards = data.memberBoards;
|
||||
boardCards = data.boardCards;
|
||||
savedDecks = data.savedDecks;
|
||||
memoryCount = data.memoryCount;
|
||||
memberPowerUpPercent = data.memberPowerUpPercent;
|
||||
}
|
||||
|
||||
function cardVariantStatus(card: CardSummary): string {
|
||||
return card.versionName || '일반';
|
||||
}
|
||||
@@ -192,14 +268,16 @@
|
||||
<h1>카드 목록</h1>
|
||||
<p class="description">카드의 기본 정보를 한눈에 확인하세요.</p>
|
||||
</div>
|
||||
<p class="total">
|
||||
<strong>{filteredCards.length}</strong>
|
||||
{#if filteredCards.length === cards.length}
|
||||
장
|
||||
{:else}
|
||||
<span>/ {cards.length}장</span>
|
||||
{/if}
|
||||
</p>
|
||||
<div class="header-side">
|
||||
<p class="total">
|
||||
<strong>{filteredCards.length}</strong>
|
||||
{#if filteredCards.length === cards.length}
|
||||
장
|
||||
{:else}
|
||||
<span>/ {cards.length}장</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="filters" aria-labelledby="filter-heading">
|
||||
@@ -547,7 +625,7 @@
|
||||
main {
|
||||
width: min(1120px, calc(100% - 40px));
|
||||
margin: 0 auto;
|
||||
padding: 64px 0 80px;
|
||||
padding: 36px 0 80px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
@@ -601,6 +679,13 @@
|
||||
color: #8a92a2;
|
||||
}
|
||||
|
||||
.header-side {
|
||||
display: grid;
|
||||
justify-items: end;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
|
||||
.filters {
|
||||
margin-bottom: 20px;
|
||||
padding: 22px 24px 24px;
|
||||
@@ -1321,6 +1406,7 @@
|
||||
color: #747e90;
|
||||
}
|
||||
|
||||
|
||||
.filters {
|
||||
border-color: rgb(255 255 255 / 8%);
|
||||
background: rgb(22 28 39 / 84%);
|
||||
@@ -1511,6 +1597,7 @@
|
||||
|
||||
.page-header {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.description {
|
||||
@@ -1518,7 +1605,12 @@
|
||||
}
|
||||
|
||||
.total {
|
||||
margin-top: 4px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-side {
|
||||
width: 100%;
|
||||
justify-items: start;
|
||||
}
|
||||
|
||||
.filters {
|
||||
|
||||
Reference in new issue
Block a user