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
3 changes: 1 addition & 2 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.khigh.seniormap.ui.screens.HomeScreen
import com.khigh.seniormap.ui.screens.LoadingScreen
import com.khigh.seniormap.ui.screens.LoginScreen
import com.khigh.seniormap.ui.screens.guardian.GuardianHomeScreen
import com.khigh.seniormap.ui.screens.guardian.EditGuardianScreen
import com.khigh.seniormap.ui.screens.guardian.AddProtectedPersonScreen
import com.khigh.seniormap.viewmodel.AuthViewModel
import androidx.hilt.navigation.compose.hiltViewModel

Expand Down Expand Up @@ -56,20 +61,82 @@ fun AppNavigation(
Log.d("com.khigh.seniormap", "[AppNavigation] isAuthenticated: $isAuthenticated, authState: $authState")
NavHost(
navController = navController,
startDestination = if (isAuthenticated) "home" else "login"
startDestination = if (isAuthenticated) "guardian_home" else "login"
) {
// 로그인 화면
composable("login") {
LoginScreen(
onNavigateToHome = {
navController.navigate("home") {
navController.navigate("guardian_home") {
popUpTo("login") { inclusive = true }
}
}
)
}

// 홈 화면
// 보호인 홈 화면
composable("guardian_home") {
GuardianHomeScreen(
onNavigateToLogin = {
navController.navigate("login") {
popUpTo("guardian_home") { inclusive = true }
}
},
onNavigateToEdit = { guardianData ->
navController.navigate("edit_guardian/${guardianData.id}") {
// 뒤로 가기 시 홈 화면으로 돌아감
}
},
onNavigateToAdd = {
navController.navigate("add_protected_person")
}
)
}

// 피보호인 추가 화면
composable("add_protected_person") {
AddProtectedPersonScreen(
onNavigateBack = {
navController.popBackStack()
},
onSave = { protectedPersonData ->
// TODO: 실제로는 ViewModel을 통해 데이터를 저장해야 함
Log.d("AppNavigation", "Protected person added: $protectedPersonData")
navController.popBackStack()
}
)
}

// 피보호인 수정 화면
composable(
route = "edit_guardian/{guardianId}",
arguments = listOf(
navArgument("guardianId") { type = NavType.StringType }
)
) { backStackEntry ->
val guardianId = backStackEntry.arguments?.getString("guardianId") ?: ""
// TODO: 실제로는 ViewModel에서 guardianId로 데이터를 가져와야 함
val guardianData = com.khigh.seniormap.ui.screens.guardian.components.GuardianData(
id = guardianId,
name = "임시 피보호인",
location = "임시 위치",
isAtHome = true
)

EditGuardianScreen(
guardianData = guardianData,
onNavigateBack = {
navController.popBackStack()
},
onSave = { updatedGuardian ->
// TODO: 실제로는 ViewModel을 통해 데이터를 저장해야 함
Log.d("AppNavigation", "Guardian updated: $updatedGuardian")
navController.popBackStack()
}
)
}

// 기존 홈 화면 (필요시 유지)
composable("home") {
HomeScreen(
onNavigateToLogin = {
Expand Down
82 changes: 82 additions & 0 deletions app/src/main/java/com/khigh/seniormap/ui/screens/LocationUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.khigh.seniormap.ui.screens

import kotlin.math.*

/**
* 위치 관련 유틸리티 클래스
*
* 지리적 좌표 간의 거리 계산과 위치 상태 판단을 담당합니다.
*/
object LocationUtils {

/**
* 두 지점 간의 거리를 미터 단위로 계산합니다.
* Haversine 공식을 사용하여 지구의 곡률을 고려합니다.
*
* @param lat1 첫 번째 지점의 위도 (도)
* @param lon1 첫 번째 지점의 경도 (도)
* @param lat2 두 번째 지점의 위도 (도)
* @param lon2 두 번째 지점의 경도 (도)
* @return 두 지점 간의 거리 (미터)
*/
fun calculateDistance(
lat1: Double, lon1: Double,
lat2: Double, lon2: Double
): Double {
val earthRadius = 6371000.0 // 지구 반지름 (미터)

val dLat = Math.toRadians(lat2 - lat1)
val dLon = Math.toRadians(lon2 - lon1)

val a = sin(dLat / 2) * sin(dLat / 2) +
cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2)) *
sin(dLon / 2) * sin(dLon / 2)

val c = 2 * atan2(sqrt(a), sqrt(1 - a))

return earthRadius * c
}

/**
* 현재 위치가 집에 있는지 여부를 판단합니다.
*
* @param homeLat 집의 위도 (도)
* @param homeLon 집의 경도 (도)
* @param currentLat 현재 위치의 위도 (도)
* @param currentLon 현재 위치의 경도 (도)
* @param threshold 집으로 간주하는 거리 임계값 (미터, 기본값: 100m)
* @return 집에 있으면 true, 외출 중이면 false
*/
fun isAtHome(
homeLat: Double, homeLon: Double,
currentLat: Double, currentLon: Double,
threshold: Double = 100.0
): Boolean {
val distance = calculateDistance(homeLat, homeLon, currentLat, currentLon)
return distance <= threshold
}

/**
* 거리를 사람이 읽기 쉬운 형태로 변환합니다.
*
* @param distanceMeters 거리 (미터)
* @return 포맷된 거리 문자열
*/
fun formatDistance(distanceMeters: Double): String {
return when {
distanceMeters < 1000 -> "${distanceMeters.toInt()}m"
else -> "${(distanceMeters / 1000).roundToInt()}km"
}
}

/**
* 위도와 경도가 유효한지 확인합니다.
*
* @param latitude 위도
* @param longitude 경도
* @return 유효한 좌표이면 true
*/
fun isValidCoordinate(latitude: Double, longitude: Double): Boolean {
return latitude in -90.0..90.0 && longitude in -180.0..180.0
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/com/khigh/seniormap/ui/screens/LoginScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ fun LoginScreen(
onGoogleLogin = {
Log.d("com.khigh.seniormap", "[LoginScreen] Google login clicked")
authViewModel.loginWithOAuth(Google)
},
onTemporaryGuardianHome = {
Log.d("com.khigh.seniormap", "[LoginScreen] Temporary guardian home clicked")
onNavigateToHome()
}
)
}
Expand Down Expand Up @@ -163,6 +167,7 @@ fun LoginScreen(
private fun LoginButtonsSection(
onKakaoLogin: () -> Unit,
onGoogleLogin: () -> Unit,
onTemporaryGuardianHome: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
Expand Down Expand Up @@ -214,5 +219,18 @@ private fun LoginButtonsSection(
fontWeight = FontWeight.Medium
)
}

// 임시 보호인 홈 이동 버튼
Spacer(modifier = Modifier.height(24.dp))
TextButton(
onClick = onTemporaryGuardianHome,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "(임시) 보호인 홈 넘어가기",
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.primary
)
}
}
}
Loading