feat: 설정 화면 구현 (JSA-37)
- SettingsScreen 컴포넌트 추가 (언어선택, BGM 토글, 앱 버전, 게임 초기화) - 게임 데이터 초기화: 2단계 확인 다이얼로그 (localStorage 전체 삭제 후 리로드) - 언어 설정: 한국어/English 세그먼트 버튼 (language 상태 persist) - BGM 토글 스위치 (bgmEnabled 상태 persist) - 마지막 저장 시각 및 오프라인 보상 최대 24시간 안내 텍스트 - BottomTabBar에 ⚙️ 설정 탭 추가 - useGameStore에 TabName 'settings', Language 타입 및 관련 액션 추가 Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
71
src/components/BottomTabBar.tsx
Normal file
71
src/components/BottomTabBar.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { css } from '@emotion/react';
|
||||
import type { TabName } from '../store/useGameStore';
|
||||
|
||||
interface TabItem {
|
||||
key: TabName;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
const TABS: TabItem[] = [
|
||||
{ key: 'elements', label: '원소', icon: '⚗️' },
|
||||
{ key: 'evolution', label: '강화', icon: '⬆️' },
|
||||
{ key: 'fusion', label: '합성', icon: '✨' },
|
||||
{ key: 'shop', label: '상점', icon: '🛒' },
|
||||
{ key: 'settings', label: '설정', icon: '⚙️' },
|
||||
];
|
||||
|
||||
interface BottomTabBarProps {
|
||||
activeTab: TabName;
|
||||
onTabChange: (tab: TabName) => void;
|
||||
}
|
||||
|
||||
const containerStyle = css`
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||
z-index: 100;
|
||||
`;
|
||||
|
||||
const tabItemStyle = css`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 0 10px;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
gap: 4px;
|
||||
`;
|
||||
|
||||
const iconStyle = css`
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
`;
|
||||
|
||||
const labelStyle = (active: boolean) => css`
|
||||
font-size: 10px;
|
||||
font-weight: ${active ? 600 : 400};
|
||||
color: ${active ? '#3182F6' : '#8b8b8b'};
|
||||
letter-spacing: -0.2px;
|
||||
`;
|
||||
|
||||
export function BottomTabBar({ activeTab, onTabChange }: BottomTabBarProps) {
|
||||
return (
|
||||
<nav css={containerStyle}>
|
||||
{TABS.map((tab) => (
|
||||
<button key={tab.key} css={tabItemStyle} onClick={() => onTabChange(tab.key)}>
|
||||
<span css={iconStyle}>{tab.icon}</span>
|
||||
<span css={labelStyle(activeTab === tab.key)}>{tab.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user