feat: Implement session management and routing for general creation

- Added session initialization in main.ts to manage user sessions.
- Updated router to include a new route for joining or creating a general.
- Enhanced session store with methods for managing session tokens and user profiles.
- Introduced new components for displaying city, general, nation, and command information.
- Implemented loading states and error handling in the main view.
- Created a skeleton loader component for better user experience during data fetching.
- Updated TypeScript definitions for route metadata to include new authentication requirements.
This commit is contained in:
2026-01-16 15:57:56 +00:00
parent 15625f2c28
commit f8159728ca
20 changed files with 1342 additions and 18 deletions
@@ -0,0 +1,74 @@
<script setup lang="ts">
import SkeletonLines from '../ui/SkeletonLines.vue';
interface NationInfo {
id: number;
name: string;
color: string;
level: number;
gold: number;
rice: number;
tech: number;
typeCode: string;
capitalCityId: number | null;
}
const props = defineProps<{
nation: NationInfo | null;
loading: boolean;
}>();
</script>
<template>
<div class="nation-card">
<div v-if="props.loading">
<SkeletonLines :lines="4" />
</div>
<div v-else-if="!props.nation" class="empty">국가 정보를 불러오지 못했습니다.</div>
<div v-else class="nation-body">
<div class="title">
<span class="color" :style="{ backgroundColor: props.nation.color }" />
{{ props.nation.name }} (Lv {{ props.nation.level }})
</div>
<div class="grid">
<div>국고 {{ props.nation.gold }}</div>
<div>국량 {{ props.nation.rice }}</div>
<div>기술 {{ props.nation.tech }}</div>
<div>체제 {{ props.nation.typeCode }}</div>
<div>수도 {{ props.nation.capitalCityId ?? '-' }}</div>
</div>
</div>
</div>
</template>
<style scoped>
.nation-card {
display: flex;
flex-direction: column;
gap: 8px;
}
.title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 600;
}
.color {
width: 14px;
height: 14px;
border: 1px solid rgba(232, 221, 196, 0.6);
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
gap: 6px;
font-size: 0.85rem;
}
.empty {
color: rgba(232, 221, 196, 0.6);
}
</style>