diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml index 1cd0eb8..6a251c8 100644 --- a/.idea/copilot.data.migration.agent.xml +++ b/.idea/copilot.data.migration.agent.xml @@ -12,6 +12,7 @@ @@ -49,8 +52,11 @@ - diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2fcf1e1..6e1b3d2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -61,4 +61,7 @@ dependencies { implementation("com.squareup.okhttp3:okhttp:4.11.0") implementation("androidx.compose.material3:material3:1.2.0") implementation("androidx.compose.material:material-icons-extended:") + + // Navigation for Compose + implementation("androidx.navigation:navigation-compose:2.6.0") } \ No newline at end of file diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/EvacuationMaps.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/EvacuationMaps.kt new file mode 100644 index 0000000..78bd56b --- /dev/null +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/EvacuationMaps.kt @@ -0,0 +1,58 @@ +package id.ac.ubharajaya.panicbutton + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController + +@Composable +fun EvacuationMapsScreen(navController: NavController, onBack: () -> Unit) { + Column(modifier = Modifier.fillMaxSize().padding(16.dp)) { + Text(text = "Peta Jalur Evakuasi", style = MaterialTheme.typography.titleLarge, modifier = Modifier.padding(bottom = 12.dp)) + + // Card 1 - Selatan + Card(modifier = Modifier.fillMaxWidth().padding(bottom = 12.dp).clickable { navController.navigate("evac_map/selatan") }, shape = RoundedCornerShape(12.dp), elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)) { + Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(12.dp)) { + Image(painter = painterResource(id = R.drawable.lantai_1_selatan), contentDescription = "Selatan", modifier = Modifier.size(120.dp)) + Spacer(modifier = Modifier.width(12.dp)) + Column { + Text(text = "Jalur Evakuasi Selatan", fontSize = 18.sp) + Spacer(modifier = Modifier.height(6.dp)) + Text(text = "Lihat detail jalur evakuasi lantai selatan.") + } + } + } + + // Card 2 - Utara + Card(modifier = Modifier.fillMaxWidth().padding(bottom = 12.dp).clickable { navController.navigate("evac_map/utara") }, shape = RoundedCornerShape(12.dp), elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)) { + Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(12.dp)) { + Image(painter = painterResource(id = R.drawable.lantai_1_utara), contentDescription = "Utara", modifier = Modifier.size(120.dp)) + Spacer(modifier = Modifier.width(12.dp)) + Column { + Text(text = "Jalur Evakuasi Utara", fontSize = 18.sp) + Spacer(modifier = Modifier.height(6.dp)) + Text(text = "Lihat detail jalur evakuasi lantai utara.") + } + } + } + } +} + +@Composable +fun EvacuationMapDetailScreen(drawableResId: Int, onBack: () -> Unit) { + Column(modifier = Modifier.fillMaxSize().padding(12.dp)) { + Text(text = "Detail Peta", style = MaterialTheme.typography.titleLarge, modifier = Modifier.padding(bottom = 12.dp)) + Image(painter = painterResource(id = drawableResId), contentDescription = "Map Detail", modifier = Modifier.fillMaxWidth().heightIn(max = 600.dp)) + } +} diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt index f17c8f2..8eb8aad 100644 --- a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt @@ -4,6 +4,12 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.compose.runtime.Composable +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.navArgument +import androidx.navigation.compose.rememberNavController import id.ac.ubharajaya.panicbutton.ui.theme.PanicButtonTheme class MainActivity : ComponentActivity() { @@ -13,8 +19,33 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { PanicButtonTheme { - MainScreen(viewModel = viewModel) + AppNav(viewModel = viewModel) } } } } + +@Composable +fun AppNav(viewModel: MainViewModel) { + val navController = rememberNavController() + NavHost(navController = navController, startDestination = "main") { + composable("main") { + MainScreen(viewModel = viewModel, onOpenEvacMaps = { navController.navigate("evac_maps") }) + } + composable("evac_maps") { + EvacuationMapsScreen(navController = navController, onBack = { navController.popBackStack() }) + } + composable( + route = "evac_map/{resName}", + arguments = listOf(navArgument("resName") { type = NavType.StringType }) + ) { backStackEntry -> + val resName = backStackEntry.arguments?.getString("resName") ?: "" + val resId = when (resName) { + "selatan" -> R.drawable.lantai_1_selatan + "utara" -> R.drawable.lantai_1_utara + else -> 0 + } + EvacuationMapDetailScreen(drawableResId = resId, onBack = { navController.popBackStack() }) + } + } +} diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainScreen.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainScreen.kt index 74be991..3702785 100644 --- a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainScreen.kt +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainScreen.kt @@ -21,15 +21,25 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.layout.IntrinsicSize @OptIn(ExperimentalMaterial3Api::class) @Composable -fun MainScreen(viewModel: MainViewModel) { +fun MainScreen(viewModel: MainViewModel, onOpenEvacMaps: () -> Unit) { Scaffold( modifier = Modifier.fillMaxSize(), bottomBar = { - PanicButton(onClick = { viewModel.sendAlert() }) + // wrap PanicButton in a Box so we can center it over the bottom bar + Box( + modifier = Modifier + .fillMaxWidth() + .height(120.dp), + contentAlignment = Alignment.TopCenter + ) { + PanicButton(onClick = { viewModel.sendAlert() }, buttonSize = 130.dp, shadowSize = 160.dp) + } } ) { paddingValues -> @@ -41,9 +51,34 @@ fun MainScreen(viewModel: MainViewModel) { horizontalAlignment = Alignment.CenterHorizontally ) { + // Emergency instruction text (darurat) + Text( + text = "JANGAN PANIK, SEGERA EVAKUASI DIRI ANDA KE TITIK KUMPUL", + color = MaterialTheme.colorScheme.error, + style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Bold), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + maxLines = 2, + ) + // Styled Emergency Condition Card EmergencyConditionCard(viewModel) + Spacer(Modifier.height(12.dp)) + + // Button to open evacuation maps + Button( + onClick = onOpenEvacMaps, + modifier = Modifier + .fillMaxWidth(0.6f) + .height(48.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary) + ) { + Text(text = "Lihat Peta Evakuasi", color = MaterialTheme.colorScheme.onPrimary) + } + // Tambahkan spacer di luar Card agar ada jarak dari bottom bar Spacer(Modifier.height(20.dp)) } diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/PanicButton.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/PanicButton.kt index 4cc8846..6792cf4 100644 --- a/app/src/main/java/id/ac/ubharajaya/panicbutton/PanicButton.kt +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/PanicButton.kt @@ -20,9 +20,11 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.unit.Dp @Composable -fun PanicButton(onClick: () -> Unit) { +fun PanicButton(onClick: () -> Unit, buttonSize: Dp = 170.dp, shadowSize: Dp = 210.dp) { + val scaleFactor = buttonSize.value / 170f val panicColor = Color(0xFFB71C1C) val darkShade = Color(0xFF7F0F0F) val lightAccent = Color(0xFFFF8A80) @@ -34,23 +36,23 @@ fun PanicButton(onClick: () -> Unit) { val gradient = Brush.verticalGradient(listOf(lightAccent, panicColor, darkShade)) Box(contentAlignment = Alignment.Center) { - Box( - modifier = Modifier - .size(210.dp) - .shadow(elevation = elevationAnim, shape = CircleShape) - .background(color = Color.Black.copy(alpha = 0.12f), shape = CircleShape) - ) Box( contentAlignment = Alignment.Center, modifier = Modifier - .size(170.dp) + .size(buttonSize) .scale(scaleAnim) - .shadow(elevation = elevationAnim, shape = CircleShape) + .shadow(elevation = elevationAnim * scaleFactor, shape = CircleShape) .background(brush = gradient, shape = CircleShape) .clickable(indication = null, interactionSource = interactionSource) { onClick() } ) { - Box(modifier = Modifier.size(70.dp).offset(x = (-24).dp, y = (-28).dp).background(color = Color.White.copy(alpha = 0.16f), shape = CircleShape)) - Text("!", color = Color.White, fontSize = 72.sp) + // highlight bubble (scaled) + val highlightSize = 70.dp * scaleFactor + val highlightOffsetX = (-24).dp * scaleFactor + val highlightOffsetY = (-28).dp * scaleFactor + + Box(modifier = Modifier.size(highlightSize).offset(x = highlightOffsetX, y = highlightOffsetY).background(color = Color.White.copy(alpha = 0.16f), shape = CircleShape)) + val fontSize = (72f * scaleFactor).sp + Text("!", color = Color.White, fontSize = fontSize) } } } diff --git a/app/src/main/res/drawable/lantai_1_selatan.jpg b/app/src/main/res/drawable/lantai_1_selatan.jpg new file mode 100644 index 0000000..1d24604 Binary files /dev/null and b/app/src/main/res/drawable/lantai_1_selatan.jpg differ diff --git a/app/src/main/res/drawable/lantai_1_utara.jpg b/app/src/main/res/drawable/lantai_1_utara.jpg new file mode 100644 index 0000000..26e5580 Binary files /dev/null and b/app/src/main/res/drawable/lantai_1_utara.jpg differ