Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions AndroidApp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo
353 changes: 353 additions & 0 deletions AndroidApp/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,353 @@
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
ScrollView,
TouchableOpacity,
SafeAreaView,
StatusBar,
Image,
Alert,
} from 'react-native';
import { StatusBar as ExpoStatusBar } from 'expo-status-bar';

interface MenuItem {
id: number;
title: string;
description: string;
icon: string;
color: string;
}

export default function App() {
const [selectedTab, setSelectedTab] = useState('home');

const menuItems: MenuItem[] = [
{
id: 1,
title: '홈',
description: '메인 화면으로 이동',
icon: '🏠',
color: '#4CAF50',
},
{
id: 2,
title: '설정',
description: '앱 설정을 관리',
icon: '⚙️',
color: '#2196F3',
},
{
id: 3,
title: '프로필',
description: '사용자 정보 확인',
icon: '👤',
color: '#FF9800',
},
{
id: 4,
title: '알림',
description: '새로운 알림 확인',
icon: '🔔',
color: '#E91E63',
},
{
id: 5,
title: '도움말',
description: '앱 사용법 안내',
icon: '❓',
color: '#9C27B0',
},
{
id: 6,
title: '정보',
description: '앱 정보 및 버전',
icon: 'ℹ️',
color: '#607D8B',
},
];

const handleMenuPress = (item: MenuItem) => {
Alert.alert(
item.title,
`${item.description}\n\n이 기능을 실행하시겠습니까?`,
[
{
text: '취소',
style: 'cancel',
},
{
text: '확인',
onPress: () => {
Alert.alert('성공', `${item.title} 기능이 실행되었습니다!`);
},
},
]
);
};

const renderHomeContent = () => (
<ScrollView style={styles.content}>
<View style={styles.header}>
<Text style={styles.welcomeText}>안녕하세요! 👋</Text>
<Text style={styles.subtitle}>오늘도 좋은 하루 되세요</Text>
</View>

<View style={styles.statsContainer}>
<View style={styles.statCard}>
<Text style={styles.statNumber}>12</Text>
<Text style={styles.statLabel}>완료된 작업</Text>
</View>
<View style={styles.statCard}>
<Text style={styles.statNumber}>5</Text>
<Text style={styles.statLabel}>새 알림</Text>
</View>
<View style={styles.statCard}>
<Text style={styles.statNumber}>89%</Text>
<Text style={styles.statLabel}>성과율</Text>
</View>
</View>

<Text style={styles.sectionTitle}>메뉴</Text>
<View style={styles.menuGrid}>
{menuItems.map((item) => (
<TouchableOpacity
key={item.id}
style={[styles.menuItem, { backgroundColor: item.color }]}
onPress={() => handleMenuPress(item)}
>
<Text style={styles.menuIcon}>{item.icon}</Text>
<Text style={styles.menuTitle}>{item.title}</Text>
<Text style={styles.menuDescription}>{item.description}</Text>
</TouchableOpacity>
))}
</View>
</ScrollView>
);

const renderTabContent = () => {
switch (selectedTab) {
case 'home':
return renderHomeContent();
case 'search':
return (
<View style={styles.content}>
<Text style={styles.sectionTitle}>검색</Text>
<Text style={styles.placeholderText}>검색 기능이 준비 중입니다...</Text>
</View>
);
case 'favorites':
return (
<View style={styles.content}>
<Text style={styles.sectionTitle}>즐겨찾기</Text>
<Text style={styles.placeholderText}>즐겨찾기 목록이 비어있습니다.</Text>
</View>
);
case 'profile':
return (
<View style={styles.content}>
<Text style={styles.sectionTitle}>프로필</Text>
<Text style={styles.placeholderText}>사용자 정보를 불러오는 중...</Text>
</View>
);
default:
return renderHomeContent();
}
};

return (
<SafeAreaView style={styles.container}>
<ExpoStatusBar style="light" />

{/* Header */}
<View style={styles.headerContainer}>
<Text style={styles.appTitle}>안드로이드 앱</Text>
<Text style={styles.appVersion}>v1.0.0</Text>
</View>

{/* Main Content */}
{renderTabContent()}

{/* Bottom Navigation */}
<View style={styles.bottomNav}>
<TouchableOpacity
style={[styles.navItem, selectedTab === 'home' && styles.navItemActive]}
onPress={() => setSelectedTab('home')}
>
<Text style={styles.navIcon}>🏠</Text>
<Text style={styles.navLabel}>홈</Text>
</TouchableOpacity>

<TouchableOpacity
style={[styles.navItem, selectedTab === 'search' && styles.navItemActive]}
onPress={() => setSelectedTab('search')}
>
<Text style={styles.navIcon}>🔍</Text>
<Text style={styles.navLabel}>검색</Text>
</TouchableOpacity>

<TouchableOpacity
style={[styles.navItem, selectedTab === 'favorites' && styles.navItemActive]}
onPress={() => setSelectedTab('favorites')}
>
<Text style={styles.navIcon}>⭐</Text>
<Text style={styles.navLabel}>즐겨찾기</Text>
</TouchableOpacity>

<TouchableOpacity
style={[styles.navItem, selectedTab === 'profile' && styles.navItemActive]}
onPress={() => setSelectedTab('profile')}
>
<Text style={styles.navIcon}>👤</Text>
<Text style={styles.navLabel}>프로필</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
headerContainer: {
backgroundColor: '#2196F3',
paddingTop: 20,
paddingBottom: 15,
paddingHorizontal: 20,
alignItems: 'center',
},
appTitle: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
appVersion: {
fontSize: 12,
color: 'rgba(255, 255, 255, 0.8)',
marginTop: 2,
},
content: {
flex: 1,
padding: 20,
},
header: {
marginBottom: 30,
},
welcomeText: {
fontSize: 28,
fontWeight: 'bold',
color: '#333',
marginBottom: 5,
},
subtitle: {
fontSize: 16,
color: '#666',
},
statsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 30,
},
statCard: {
flex: 1,
backgroundColor: 'white',
padding: 15,
borderRadius: 10,
marginHorizontal: 5,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 3.84,
elevation: 5,
},
statNumber: {
fontSize: 24,
fontWeight: 'bold',
color: '#2196F3',
},
statLabel: {
fontSize: 12,
color: '#666',
marginTop: 5,
},
sectionTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
marginBottom: 15,
},
menuGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
},
menuItem: {
width: '48%',
backgroundColor: '#4CAF50',
padding: 20,
borderRadius: 15,
marginBottom: 15,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 3.84,
elevation: 5,
},
menuIcon: {
fontSize: 32,
marginBottom: 10,
},
menuTitle: {
fontSize: 16,
fontWeight: 'bold',
color: 'white',
marginBottom: 5,
},
menuDescription: {
fontSize: 12,
color: 'rgba(255, 255, 255, 0.8)',
textAlign: 'center',
},
placeholderText: {
fontSize: 16,
color: '#666',
textAlign: 'center',
marginTop: 50,
},
bottomNav: {
flexDirection: 'row',
backgroundColor: 'white',
paddingVertical: 10,
paddingHorizontal: 20,
borderTopWidth: 1,
borderTopColor: '#e0e0e0',
},
navItem: {
flex: 1,
alignItems: 'center',
paddingVertical: 8,
},
navItemActive: {
backgroundColor: 'rgba(33, 150, 243, 0.1)',
borderRadius: 10,
},
navIcon: {
fontSize: 20,
marginBottom: 4,
},
navLabel: {
fontSize: 12,
color: '#666',
},
});
Loading