ETS PBB I 2024
ETS PBB - Redesign Aplikasi Traveloka
Pertanyaan:
- Gambarkan dan Jelaskan siklus aktivitas dari aplikasi Android? 
- Penggunaan aplikasi Android yang sesuai di bidang apa saja? Jelaskan dan berikan contohnya. 
- Bukalah aplikasi Mobile yang berkaitan dengan sistem Tiket yang anda punya. Tuliskan dan jelaskan kegunaan fitur yang sering dipakai. 
- Redesign dan aplikasi sesuai dengan fitur yang dipakai. 
- Implementasi dalam bentuk aplikasi Android halaman masuk dan akses fitur yang sering dipakai. 
- Dokumentasikan dan Demokan dalam Video Youtube dari aplikasi yang telah dibangun. 
Jawaban:
- Berikut gambaran dari Activity Cycle dari aplikasi Android: 
Penjelasan:
- onCreate(): Dipanggil saat aktivitas pertama kali dibuat. Di sini dapat menginisialisasi komponen-komponen penting seperti layout UI, variabel, dsb. 
- onStart(): Dipanggil saat aktivitas akan menjadi terlihat oleh pengguna. 
- onResume(): Dipanggil saat aktivitas mulai berinteraksi dengan pengguna. Aktivitas berada di puncak Activity Cycle dan disinilah aktivitas berjalan penuh. 
- onPause(): Dipanggil saat aktivitas kehilangan fokus tetapi masih terlihat oleh pengguna. Biasanya digunakan untuk menyimpan perubahan sementara. 
- onStop(): Dipanggil saat aktivitas tidak lagi terlihat oleh pengguna. Aktivitas akan berada dalam keadaan berhenti. 
- onRestart(): Dipanggil saat aktivitas yang berhenti akan dimulai lagi. 
- onDestroy(): Dipanggil sebelum aktivitas dihancurkan. Biasanya digunakan untuk membersihkan resource. 
- Penggunaan aplikasi Android dapat digunakan diberbagai bidang (terutama dibidang yang menawarkan jasa dengan menggunakan Software/SaaS [Software as a service] dalam melaksanakan bisnisnya) karena aplikasi ini sangat versatile dan mudah digunakan (dan dikembangankan), berikut contoh bidang yang dapat menggunakan aplikasi Android: 
- E-commerce: Aplikasi seperti Tokopedia, Shopee, dan Lazada memungkinkan pengguna untuk belanja online, membandingkan harga, dan membaca ulasan produk. 
- Pendidikan: Aplikasi seperti Ruangguru dan Zenius menyediakan materi pembelajaran, latihan soal, dan video tutorial untuk siswa. 
- Kesehatan: Aplikasi Halodoc dan Alodokter menyediakan konsultasi medis online, pemesanan obat, dan informasi kesehatan. 
- Transportasi: Aplikasi seperti Gojek dan Grab digunakan untuk memesan transportasi, pengantaran makanan, dan layanan lainnya. 
- Perjalanan dan Pemesanan Tiket: Aplikasi Traveloka dan Tiket.com digunakan untuk memesan tiket pesawat, kereta api, hotel, dan kegiatan wisata. 
- Aplikasi Mobile yang berkaitan dengan sistem Tiket yang sering saya pakai adalah Traveloka yang berguna untuk memesan Tiket Penerbangan dan Hotel, berikut fitur yang sering digunakan: 
- Booking (Pemesanan Tiket): 
Fitur ini merupakan fitur utama dalam aplikasi Traveloka karena tujuan aplikasi ini adalah membantu kita mempermudah pemesanan tiket pesawat melalui aplikasi mobile tanpa perlu memesan lewat website penerbangan yang dimana lebih ribet dan tidak dapat membandingkan harga antara maskapai.
- Transaction (History Pemesanan): 
Fitur ini merupakan fitur penting yang saya sering gunakan karena fitur ini membantu pengguna untuk melihat dan mengelola pemesanan tiket yang telah kita beli (mau yang sedang berjalan atau sudah berlalu).
- Berikut redesign dari fitur aplikasi yang sering digunakan: 
- Berikut merupakan implementasi dari aplikasi Android Traveloka dengan membuat fitur 
authentication dan pemesanan tiket, sebagai berikut:
Source Code:
OnboardingScreen.kt:
LoginScreen.kt:package com.example.travelokabaru.ui.screen.authentication 
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 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.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.example.travelokabaru.R
 import com.example.travelokabaru.ui.components.BackgroundImage
 import com.example.travelokabaru.ui.theme.TravelokabaruTheme
 @Composable
 fun OnboardingScreen(
 navigateToRegistration: (() -> Unit),
 navigateToLogin: (() -> Unit)
 ) {
 Box(
 modifier = Modifier
 .fillMaxSize()
 .background(MaterialTheme.colorScheme.surface)
 ) {
 BackgroundImage(
 image = painterResource(id = R.drawable.background),
 alpha = 0.7f
 )
 Column(
 horizontalAlignment = Alignment.CenterHorizontally,
 verticalArrangement = Arrangement.Center,
 modifier = Modifier
 .fillMaxSize()
 .padding(32.dp)
 ) {
 Header()
 Spacer(modifier = Modifier.height(350.dp))
 Action(
 navigateToRegistration = navigateToRegistration,
 navigateToLogin = navigateToLogin
 )
 }
 }
 }
 @Composable
 private fun Header() {
 Image(
 painter = painterResource(id = R.drawable.ic_traveloka),
 contentDescription = null,
 modifier = Modifier.width(500.dp)
 )
 }
 @Composable
 private fun Action(
 navigateToRegistration: (() -> Unit),
 navigateToLogin: (() -> Unit)
 ) {
 Column(
 horizontalAlignment = Alignment.CenterHorizontally
 ) {
 Button(
 onClick = navigateToLogin,
 modifier = Modifier.width(240.dp)
 ) {
 Text(text = "Login")
 }
 Spacer(modifier = Modifier.height(7.dp))
 Button(
 onClick = navigateToLogin,
 colors = ButtonDefaults.buttonColors(
 containerColor = MaterialTheme.colorScheme.tertiaryContainer,
 contentColor = MaterialTheme.colorScheme.onTertiaryContainer
 ),
 modifier = Modifier.width(240.dp)
 ) {
 Text(text = "Register")
 }
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun LightThemePreview() {
 TravelokabaruTheme {
 OnboardingScreen(navigateToRegistration = {}, navigateToLogin = {})
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun DarkThemePreview() {
 TravelokabaruTheme(
 darkTheme = true
 ) {
 OnboardingScreen(navigateToRegistration = {}, navigateToLogin = {})
 }
 }HomeScreen.kt:package com.example.travelokabaru.ui.screen.authentication 
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Email
 import androidx.compose.material3.Button
 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.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.example.travelokabaru.R
 import com.example.travelokabaru.ui.components.CustomOutlinedButtonWithIcon
 import com.example.travelokabaru.ui.components.CustomOutlinedPasswordField
 import com.example.travelokabaru.ui.components.CustomOutlinedTextField
 import com.example.travelokabaru.ui.theme.TravelokabaruTheme
 @Composable
 fun LoginScreen(
 navigateToHome: (() -> Unit)
 ) {
 Box(
 modifier = Modifier
 .background(MaterialTheme.colorScheme.surface)
 .fillMaxSize()
 .padding(32.dp)
 ) {
 Column(
 verticalArrangement = Arrangement.spacedBy(20.dp)
 ) {
 Header()
 Main(navigateToHome = navigateToHome)
 }
 Footer()
 }
 }
 @Composable
 private fun Header() {
 Column {
 Spacer(modifier = Modifier.height(8.dp))
 Text(
 text = "Login Account",
 style = MaterialTheme.typography.headlineMedium,
 color = MaterialTheme.colorScheme.onSurface,
 fontWeight = FontWeight.Bold
 )
 Spacer(modifier = Modifier.height(8.dp))
 Text(
 text = "Please login with registered account",
 style = MaterialTheme.typography.bodyMedium,
 color = MaterialTheme.colorScheme.surfaceTint
 )
 }
 }
 @Composable
 private fun Main(
 navigateToHome: (() -> Unit)
 ) {
 Column(
 verticalArrangement = Arrangement.spacedBy(20.dp)
 ) {
 Spacer(modifier = Modifier.height(4.dp))
 CustomOutlinedTextField(
 label = "Email or Phone Number",
 placeholder = "Enter your email or phone number",
 trailingIcon = Icons.Default.Email
 )
 CustomOutlinedPasswordField(
 label = "Password",
 placeholder = "Enter your password",
 )
 Text(
 text = "Forget Password?",
 style = MaterialTheme.typography.bodyMedium,
 color = MaterialTheme.colorScheme.tertiary,
 textAlign = TextAlign.End,
 modifier = Modifier
 .fillMaxWidth()
 .clickable { }
 )
 }
 Spacer(modifier = Modifier.height(4.dp))
 Button(
 onClick = navigateToHome,
 modifier = Modifier.fillMaxWidth()
 ) {
 Text(text = "Login")
 }
 Text(
 text = "Or using another method",
 style = MaterialTheme.typography.bodyMedium,
 color = MaterialTheme.colorScheme.onSurfaceVariant,
 textAlign = TextAlign.Center,
 modifier = Modifier.fillMaxWidth()
 )
 Column(
 verticalArrangement = Arrangement.spacedBy(12.dp)
 ) {
 CustomOutlinedButtonWithIcon(
 label = "Sign In with Google",
 icon = painterResource(id = R.drawable.ic_google),
 onClick = {}
 )
 CustomOutlinedButtonWithIcon(
 label = "Sign In with Facebook",
 icon = painterResource(id = R.drawable.ic_facebook),
 onClick = {}
 )
 }
 }
 @Composable
 private fun Footer() {
 Row(
 verticalAlignment = Alignment.Bottom,
 horizontalArrangement = Arrangement.Center,
 modifier = Modifier.fillMaxSize()
 ) {
 Image(
 painter = painterResource(id = R.drawable.ic_traveloka),
 contentDescription = null,
 modifier = Modifier.height(90.dp)
 )
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun LightThemePreview() {
 TravelokabaruTheme {
 LoginScreen(navigateToHome = {})
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun DarkThemePreview() {
 TravelokabaruTheme(
 darkTheme = true
 ) {
 LoginScreen(navigateToHome = {})
 }
 }FindTicketScreen.kt:package com.example.travelokabaru.ui.screen.home 
 import android.app.Activity
 import androidx.activity.compose.BackHandler
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyRow
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.SwapHoriz
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.CardDefaults
 import androidx.compose.material3.Checkbox
 import androidx.compose.material3.Divider
 import androidx.compose.material3.ElevatedCard
 import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextField
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.example.travelokabaru.R
 import com.example.travelokabaru.data.HomeData
 import com.example.travelokabaru.data.articleData
 import com.example.travelokabaru.data.promoData
 import com.example.travelokabaru.ui.components.HomeTopBar
 import com.example.travelokabaru.ui.theme.TravelokabaruTheme
 @Composable
 fun HomeScreen(
 navigateToFindTicket: (() -> Unit),
 ) {
 Scaffold(
 topBar = {
 HomeTopBar()
 },
 ) { innerPadding ->
 val context = LocalContext.current
 BackHandler {
 (context as? Activity)?.finish()
 }
 Column(
 modifier = Modifier
 .fillMaxSize()
 .padding(innerPadding)
 ) {
 LazyColumn(
 verticalArrangement = Arrangement.spacedBy(16.dp),
 modifier = Modifier
 .fillMaxSize()
 .padding(16.dp)
 ) {
 // item {
 // Header()
 // }
 item {
 FindTiketCard(
 navigateToFindTicket = navigateToFindTicket
 )
 }
 item {
 Section(title = "Popular Routes ✨", data = promoData)
 }
 item {
 Section(title = "Hot Promos 🔥", data = articleData)
 }
 }
 }
 }
 }
 @Composable
 private fun Section(
 title: String,
 data: List<HomeData>
 ) {
 Column(
 verticalArrangement = Arrangement.spacedBy(16.dp),
 modifier = Modifier.fillMaxWidth()
 ) {
 Row(
 horizontalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier.fillMaxWidth()
 ) {
 Text(
 text = title,
 style = MaterialTheme.typography.titleMedium,
 fontWeight = FontWeight.Bold
 )
 Text(
 text = "See All",
 style = MaterialTheme.typography.titleSmall,
 color = MaterialTheme.colorScheme.scrim,
 fontWeight = FontWeight.Bold,
 modifier = Modifier.clickable { }
 )
 }
 LazyRow(
 horizontalArrangement = Arrangement.spacedBy(16.dp),
 modifier = Modifier.fillMaxWidth()
 ) {
 items(data) { item ->
 Column(
 verticalArrangement = Arrangement.spacedBy(6.dp),
 modifier = Modifier.width(150.dp)
 ) {
 Image(
 painter = item.image,
 contentDescription = null,
 contentScale = ContentScale.Crop,
 modifier = Modifier
 .size(width = 150.dp, height = 150.dp)
 .clip(RoundedCornerShape(16.dp))
 )
 Text(
 text = item.title,
 maxLines = 1,
 overflow = TextOverflow.Ellipsis,
 textAlign = TextAlign.Center,
 style = MaterialTheme.typography.bodyMedium,
 modifier = Modifier.fillMaxWidth()
 )
 }
 }
 }
 }
 }
 @Composable
 private fun FindTiketCard(
 navigateToFindTicket: (() -> Unit)
 ) {
 ElevatedCard(
 elevation = CardDefaults.cardElevation(
 defaultElevation = 10.dp
 ),
 colors = CardDefaults.cardColors(
 containerColor = MaterialTheme.colorScheme.primary
 ),
 modifier = Modifier
 .fillMaxWidth()
 ) {
 // var checked by remember {
 // mutableStateOf(false)
 // }
 Column(
 horizontalAlignment = Alignment.CenterHorizontally,
 modifier = Modifier
 .padding(16.dp)
 ) {
 Spacer(modifier = Modifier.height(10.dp))
 Row (verticalAlignment = Alignment.CenterVertically,
 horizontalArrangement = Arrangement.Start,
 ){
 TextField(
 value = "Jakarta, Indonesia",
 onValueChange = {},
 label = { Text("From") },
 modifier = Modifier.fillMaxWidth()
 )
 }
 Spacer(modifier = Modifier.height(6.dp))
 Row (verticalAlignment = Alignment.CenterVertically,
 horizontalArrangement = Arrangement.Start,
 ){
 TextField(
 value = "New York, USA",
 onValueChange = {},
 label = { Text("To") },
 modifier = Modifier.fillMaxWidth()
 )
 }
 Spacer(modifier = Modifier.height(6.dp))
 Row(verticalAlignment = Alignment.CenterVertically,
 horizontalArrangement = Arrangement.Start,
 modifier = Modifier.fillMaxWidth()
 ) {
 Checkbox(
 checked = false,
 onCheckedChange = {}
 )
 Text(text = "Round Trip")
 }
 // Spacer(modifier = Modifier.height(1.dp))
 // Divider()
 // Spacer(modifier = Modifier.height(2.dp))
 Row(
 verticalAlignment = Alignment.CenterVertically,
 horizontalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier.fillMaxWidth()
 ) {
 Column(
 modifier = Modifier.clickable { }
 ) {
 Text(
 text = "Depature Date",
 style = MaterialTheme.typography.titleSmall,
 fontWeight = FontWeight.Bold,
 modifier = Modifier.alpha(0.7f)
 )
 Text(
 text = "Saturday, 18 Mei 2024",
 style = MaterialTheme.typography.bodySmall,
 )
 }
 Button(
 onClick = navigateToFindTicket,
 colors = ButtonDefaults.buttonColors(
 containerColor = MaterialTheme.colorScheme.tertiaryContainer,
 contentColor = MaterialTheme.colorScheme.scrim
 ),
 ) {
 Text(text = "Find Ticket")
 }
 }
 }
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun LightThemePreview() {
 TravelokabaruTheme {
 HomeScreen(navigateToFindTicket = {})
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun DarkThemePreview() {
 TravelokabaruTheme(
 darkTheme = true
 ) {
 HomeScreen(navigateToFindTicket = {})
 }
 }OrderSuccessScreen.kt:package com.example.travelokabaru.ui.screen.ticket 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.ArrowForward
 import androidx.compose.material3.CardDefaults
 import androidx.compose.material3.Divider
 import androidx.compose.material3.ElevatedCard
 import androidx.compose.material3.FilledIconButton
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButtonDefaults
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.example.travelokabaru.data.Ticket
 import com.example.travelokabaru.data.ticketList
 import com.example.travelokabaru.ui.components.CustomCenterAlignedTopBar
 import com.example.travelokabaru.ui.theme.TravelokabaruTheme
 @Composable
 fun FindTicketScreen(
 navigateToOrderTicket: (() -> Unit),
 navigateBack: (() -> Unit)
 ) {
 Scaffold(
 topBar = {
 CustomCenterAlignedTopBar(title="Search Ticket", navigateBack = navigateBack,)
 },
 ) { innerPadding ->
 Column(
 modifier = Modifier
 .background(MaterialTheme.colorScheme.surface)
 .fillMaxSize()
 .padding(innerPadding)
 ) {
 Row(
 horizontalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier
 .fillMaxWidth()
 .padding(16.dp)
 ) {
 DateCard(date = "16", day = "Thr")
 DateCard(date = "17", day = "Fri")
 DateCard(date = "18", day = "San", now = true)
 DateCard(date = "19", day = "Sun")
 DateCard(date = "20", day = "Mon")
 }
 LazyColumn(
 verticalArrangement = Arrangement.spacedBy(14.dp),
 modifier = Modifier
 .fillMaxWidth()
 .padding(12.dp)
 ) {
 items(ticketList) { ticket ->
 TicketCard(
 data = ticket,
 navigateToOrderTicket = navigateToOrderTicket
 )
 }
 }
 }
 }
 }
 @Composable
 private fun TicketCard(
 data: Ticket,
 navigateToOrderTicket: (() -> Unit)
 ) {
 ElevatedCard(
 elevation = CardDefaults.cardElevation(
 defaultElevation = 6.dp
 ),
 modifier = Modifier
 .fillMaxWidth()
 ) {
 Row(
 horizontalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier
 .fillMaxWidth()
 .padding(16.dp)
 ) {
 Column(
 verticalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier.size(width = 250.dp, height = 100.dp)
 ) {
 Text(
 text = data.argo,
 style = MaterialTheme.typography.titleSmall,
 modifier = Modifier.fillMaxWidth()
 )
 Row(
 horizontalArrangement = Arrangement.SpaceBetween,
 verticalAlignment = Alignment.CenterVertically,
 modifier = Modifier.fillMaxWidth()
 ) {
 Column {
 Text(
 text = "JKT",
 style = MaterialTheme.typography.labelMedium,
 )
 Text(
 text = data.startLeaving,
 style = MaterialTheme.typography.bodySmall,
 modifier = Modifier.alpha(0.7f)
 )
 }
 Divider(Modifier.width(150.dp))
 Column(
 horizontalAlignment = Alignment.End
 ) {
 Text(
 text = "NYC",
 style = MaterialTheme.typography.labelMedium,
 fontWeight = FontWeight.Bold,
 )
 Text(
 text = data.arrive,
 style = MaterialTheme.typography.bodySmall,
 modifier = Modifier.alpha(0.7f)
 )
 }
 }
 Row(
 horizontalArrangement = Arrangement.SpaceBetween,
 modifier = Modifier.fillMaxWidth()
 ) {
 Text(
 text = data.argoClass,
 style = MaterialTheme.typography.bodySmall,
 color = MaterialTheme.colorScheme.onPrimary,
 modifier = Modifier
 .background(MaterialTheme.colorScheme.primary)
 .padding(vertical = 4.dp, horizontal = 8.dp)
 )
 Text(
 text = data.estimatedTime,
 style = MaterialTheme.typography.bodySmall,
 )
 }
 }
 Column(
 verticalArrangement = Arrangement.SpaceBetween,
 horizontalAlignment = Alignment.End,
 modifier = Modifier.size(width = 250.dp, height = 100.dp)
 ) {
 Column(
 verticalArrangement = Arrangement.spacedBy(4.dp),
 horizontalAlignment = Alignment.End
 ) {
 Text(
 text = data.price,
 style = MaterialTheme.typography.labelMedium,
 fontWeight = FontWeight.Bold
 )
 Text(
 text = "Sisa " + data.ticketRemaining.toString(),
 style = MaterialTheme.typography.bodySmall,
 color = MaterialTheme.colorScheme.error
 )
 }
 FilledIconButton(
 onClick = navigateToOrderTicket,
 colors = IconButtonDefaults.filledIconButtonColors(
 containerColor = MaterialTheme.colorScheme.tertiaryContainer,
 contentColor = MaterialTheme.colorScheme.onTertiaryContainer
 ),
 modifier = Modifier.size(30.dp)
 ) {
 Icon(
 imageVector = Icons.Default.ArrowForward,
 contentDescription = null,
 )
 }
 }
 }
 }
 }
 @Composable
 private fun DateCard(
 date: String,
 day: String,
 now: Boolean = false
 ) {
 ElevatedCard(
 elevation = CardDefaults.cardElevation(
 defaultElevation = 8.dp
 ),
 colors = CardDefaults.cardColors(
 containerColor = if (now) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface
 ),
 modifier = Modifier.clickable { }
 ) {
 Column(
 horizontalAlignment = Alignment.CenterHorizontally,
 modifier = Modifier.padding(20.dp)
 ) {
 Text(
 text = date,
 style = MaterialTheme.typography.titleMedium,
 fontWeight = FontWeight.Bold
 )
 Text(
 text = day,
 style = MaterialTheme.typography.bodySmall
 )
 }
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun LightThemePreview() {
 TravelokabaruTheme {
 FindTicketScreen(navigateToOrderTicket = {}, navigateBack = {})
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun DarkThemePreview() {
 TravelokabaruTheme(
 darkTheme = true
 ) {
 FindTicketScreen(navigateToOrderTicket = {}, navigateBack = {})
 }
 }Screenshoots:package com.example.travelokabaru.ui.screen.ticket 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.CheckCircle
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Icon
 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.draw.alpha
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.example.travelokabaru.R
 import com.example.travelokabaru.ui.components.BackgroundImage
 import com.example.travelokabaru.ui.theme.TravelokabaruTheme
 @Composable
 fun OrderSuccessScreen(
 navigateToHome: (() -> Unit)
 ) {
 Box(
 modifier = Modifier
 .fillMaxSize()
 .background(MaterialTheme.colorScheme.surface)
 ) {
 BackgroundImage(
 image = painterResource(id = R.drawable.background_2),
 )
 Column(
 verticalArrangement = Arrangement.Bottom,
 modifier = Modifier.fillMaxSize()
 ) {
 Column(
 horizontalAlignment = Alignment.CenterHorizontally,
 verticalArrangement = Arrangement.spacedBy(12.dp),
 modifier = Modifier
 .clip(RoundedCornerShape(topStart = 32.dp, topEnd = 32.dp))
 .background(MaterialTheme.colorScheme.surface)
 .fillMaxWidth()
 .padding(32.dp)
 ) {
 Icon(
 imageVector = Icons.Default.CheckCircle,
 tint = MaterialTheme.colorScheme.primary,
 contentDescription = null,
 modifier = Modifier.size(100.dp)
 )
 Column(
 verticalArrangement = Arrangement.spacedBy(16.dp)
 ) {
 Text(
 text = "Payment Successful",
 style = MaterialTheme.typography.headlineLarge,
 fontWeight = FontWeight.Bold,
 textAlign = TextAlign.Center,
 color = MaterialTheme.colorScheme.onSurface
 )
 }
 Button(
 onClick = navigateToHome,
 colors = ButtonDefaults.buttonColors(
 containerColor = MaterialTheme.colorScheme.tertiaryContainer,
 contentColor = MaterialTheme.colorScheme.onTertiaryContainer
 ),
 ) {
 Text(text = "Back to Home")
 }
 }
 }
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun LightThemePreview() {
 TravelokabaruTheme {
 OrderSuccessScreen(navigateToHome = {})
 }
 }
 @Preview(showBackground = true)
 @Composable
 private fun DarkThemePreview() {
 TravelokabaruTheme(
 darkTheme = true
 ) {
 OrderSuccessScreen(navigateToHome = {})
 }
 }
- Dokumentasi dan Demo: Youtube
Comments
Post a Comment