feat(mobile): Phase M-1 모바일 프로젝트 기반 + V3 마스터 플랜
- V3 모바일 마스터 플랜 작성 (docs/v3/00-mobile-master-plan.md) 11개 Phase, 5주 로드맵, 전략 결정사항 확정 - 7개 디자인 HTML 레퍼런스 저장 (docs/v3/designs/) - app.json → app.config.ts 전환 + 환경변수 체계 - 5탭 네비게이션 (DASH/HIST/REC FAB/TALK/SET) - metro.config.js monorepo 격리 (root RN 0.84 충돌 해결) - ui-native 테마 디자인 목업 색상 동기화 - SafeArea 적용 (useSafeAreaInsets) - DEV 로그인 우회 (__DEV__ 전용) - Supabase .env 연동 - iOS 시뮬레이터 검증 완료
This commit is contained in:
parent
ffca07d120
commit
211673bc6c
30 changed files with 15010 additions and 525 deletions
155
apps/mobile/app/(tabs)/dash.tsx
Normal file
155
apps/mobile/app/(tabs)/dash.tsx
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
// apps/mobile/app/(tabs)/dash.tsx
|
||||
// 대시보드 탭 — 세션 통계, 사용량, 시스템 상태
|
||||
// Phase M-2에서 디자인(docs/v3/designs/dashboard.html) 정밀 적용
|
||||
|
||||
import { View, ScrollView, StyleSheet } from 'react-native'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { MetalCard, PhosphorText, Led, d3roNativePalette } from '@d3ro/ui-native'
|
||||
|
||||
export default function DashScreen(): React.ReactElement {
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={[styles.content, { paddingTop: insets.top + 8, paddingBottom: insets.bottom + 100 }]}
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<View style={styles.headerLeft}>
|
||||
<Led color="amber" size={8} />
|
||||
<PhosphorText variant="label" color="muted" style={styles.headerLabel}>
|
||||
D3RO-VOICE
|
||||
</PhosphorText>
|
||||
</View>
|
||||
<View style={styles.headerRight}>
|
||||
<PhosphorText variant="label" color="muted">
|
||||
v1.0.0
|
||||
</PhosphorText>
|
||||
<Led color="green" size={6} />
|
||||
<Led color="amber" size={6} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Session Overview */}
|
||||
<MetalCard inset style={styles.overviewCard}>
|
||||
<View style={styles.overviewHeader}>
|
||||
<PhosphorText variant="small" color="muted">
|
||||
SESSION OVERVIEW
|
||||
</PhosphorText>
|
||||
</View>
|
||||
<View style={styles.bigNumber}>
|
||||
<PhosphorText variant="hero" color="amber">
|
||||
0
|
||||
</PhosphorText>
|
||||
<PhosphorText variant="body" color="muted" style={{ marginLeft: 12 }}>
|
||||
TODAY
|
||||
</PhosphorText>
|
||||
</View>
|
||||
<View style={styles.overviewFooter}>
|
||||
<View>
|
||||
<PhosphorText variant="label" color="muted">WORDS</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
</View>
|
||||
<View style={{ alignItems: 'flex-end' }}>
|
||||
<PhosphorText variant="label" color="muted">STREAK</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
</View>
|
||||
</View>
|
||||
</MetalCard>
|
||||
|
||||
{/* 2x2 Stats Grid */}
|
||||
<View style={styles.statsGrid}>
|
||||
<MetalCard style={styles.statCard}>
|
||||
<PhosphorText variant="label" color="muted">REC</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
<PhosphorText variant="label" color="muted">MIN</PhosphorText>
|
||||
</MetalCard>
|
||||
<MetalCard style={styles.statCard}>
|
||||
<PhosphorText variant="label" color="muted">WORDS</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
</MetalCard>
|
||||
<MetalCard style={styles.statCard}>
|
||||
<PhosphorText variant="label" color="muted">TODAY</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
</MetalCard>
|
||||
<MetalCard style={styles.statCard}>
|
||||
<PhosphorText variant="label" color="muted">STREAK</PhosphorText>
|
||||
<PhosphorText variant="value" color="amber">0</PhosphorText>
|
||||
</MetalCard>
|
||||
</View>
|
||||
|
||||
{/* Backend Info */}
|
||||
<MetalCard style={styles.infoCard}>
|
||||
<PhosphorText variant="small" color="muted">BACKEND</PhosphorText>
|
||||
<View style={styles.infoRow}>
|
||||
<Led color="green" size={6} />
|
||||
<PhosphorText variant="body" color="amber" style={{ marginLeft: 8 }}>
|
||||
CLOUD (CLAUDE)
|
||||
</PhosphorText>
|
||||
</View>
|
||||
</MetalCard>
|
||||
|
||||
<MetalCard style={styles.infoCard}>
|
||||
<PhosphorText variant="small" color="muted">TIER</PhosphorText>
|
||||
<View style={styles.infoRow}>
|
||||
<Led color="amber" size={6} />
|
||||
<PhosphorText variant="body" color="amber" style={{ marginLeft: 8 }}>
|
||||
FREE
|
||||
</PhosphorText>
|
||||
</View>
|
||||
</MetalCard>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: d3roNativePalette.bg.app },
|
||||
content: { padding: 20 },
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 12
|
||||
},
|
||||
headerLeft: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||
headerRight: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||
headerLabel: { letterSpacing: 3 },
|
||||
overviewCard: {
|
||||
padding: 20,
|
||||
marginBottom: 12
|
||||
},
|
||||
overviewHeader: { marginBottom: 16 },
|
||||
bigNumber: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'baseline',
|
||||
marginBottom: 24
|
||||
},
|
||||
overviewFooter: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: 'rgba(255,255,255,0.04)',
|
||||
paddingTop: 12
|
||||
},
|
||||
statsGrid: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 12,
|
||||
marginBottom: 12
|
||||
},
|
||||
statCard: {
|
||||
width: '47%',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 16,
|
||||
gap: 4
|
||||
},
|
||||
infoCard: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
paddingVertical: 14
|
||||
},
|
||||
infoRow: { flexDirection: 'row', alignItems: 'center' }
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue