ETS PBB I 2024

ETS PBB - Redesign Aplikasi Traveloka

Nama: Muhammad Ghani Taufiqurrahman Atmaja
NRP : 5025201110
Kelas: PPB - I

Pertanyaan:

  1. Gambarkan dan Jelaskan siklus aktivitas dari aplikasi Android?

  2. Penggunaan aplikasi Android yang sesuai  di bidang apa saja? Jelaskan dan berikan contohnya.

  3. Bukalah aplikasi Mobile yang berkaitan dengan sistem Tiket yang anda punya. Tuliskan dan jelaskan kegunaan fitur yang sering dipakai.

  4. Redesign dan aplikasi sesuai dengan fitur yang dipakai.

  5. Implementasi dalam bentuk aplikasi Android halaman masuk dan akses fitur yang sering dipakai.

  6. Dokumentasikan dan Demokan dalam Video Youtube dari aplikasi yang telah dibangun.


Jawaban:


  1. 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.

  1. 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.

  1. 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:

    1. 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.

  1. 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).

  1. Berikut redesign dari fitur aplikasi yang sering digunakan:



  2. Berikut merupakan implementasi dari aplikasi Android Traveloka dengan membuat fitur authentication dan pemesanan tiket, sebagai berikut: Source Code: OnboardingScreen.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 = {})
    }
    }
    LoginScreen.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 = {})
    }
    }
    HomeScreen.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 = {})
    }
    }
    FindTicketScreen.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 = {})
    }
    }
    OrderSuccessScreen.kt:
    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 = {})
    }
    }
    Screenshoots:


  3. Dokumentasi dan Demo: Youtube

Comments

Popular posts from this blog

Tugas 1 - Sejarah Mobile Phone dan Perkembangan Teknologi Pemrograman Aplikasi Mobile

Tugas 2 PPB I

Tugas 3 PPB I