EAS PBB I

 Nama: Muhammad Ghani Taufiqurrahman Atmaja

NRP: 5025201110

Kelas: PPB I


EAS PPB I


Soal:

  1. Buat spesifikasi dan deskripsi aplikasi yang mampu dibuat berdasarkan studi kasus diatas?

Jawaban:


Nama Aplikasi:

Alfamind


Deskripsi Aplikasi:

Alfamind adalah toko virtual yang memungkinkan pengguna atau store owner memiliki toko Alfamart tanpa perlu membangun toko fisik. Dengan hanya menggunakan smartphone, store owner dapat menjual produk langsung ke konsumen tanpa harus khawatir tentang stok dan distribusi barang. Sebagai bisnis digital yang dikembangkan oleh induk perusahaan untuk meningkatkan skala bisnis dan penjualan, Alfamind saat ini memiliki 3.500 store owner yang menjual produk UMKM dari 120 pemasok terpilih oleh Alfamart. Untuk menghindari gangguan pada bisnis Alfamart yang menjual kebutuhan sehari-hari, Alfamind fokus pada produk UMKM seperti fesyen dan perabot rumah tangga. Dengan modal awal berupa deposito sebesar Rp 1.000.000 yang bisa digunakan untuk berbelanja produk, store owner dapat langsung memiliki toko Alfamart.


Spesifikasi:

Bahasa Pemrograman: Kotlin (Android Studio)

Device: Android


  1. Buat use case dan flowchart yang akan diimplementasi?

Jawaban:

Use Case:



Flowchart:


  1. Gambarkan UI yang akan diimplementasikan?


  1. Implementasi Rancangan?

MainActivity.kt:

package com.exapmple.uasppbi.presentation

import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.compose.rememberNavController
import com.exapmple.uasppbi.presentation.graphs.root_graph.RootNavigationGraph
import com.exapmple.uasppbi.presentation.ui.theme.easppbi
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JexmonTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
ShowScreen(LocalContext.current)
}
}
}
}
}

@Composable
private fun ShowScreen(context: Context) {
val navHostController = rememberNavController()



RootNavigationGraph(navHostController = navHostController, context = context)
}

OnBoardingScreen.kt:

package com.exapmple.uasppbi.presentation.screens.on_boarding_screen.component

import androidx.compose.animation.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.eritlab.jexmon.R
import com.exapmple.uasppbi.presentation.common.CustomDefaultBtn
import com.exapmple.uasppbi.presentation.graphs.auth_graph.AuthScreen
import com.exapmple.uasppbi.presentation.ui.theme.PrimaryColor
import ccom.exapmple.uasppbi.presentation.ui.theme.TextColor
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.rememberPagerState

@OptIn(ExperimentalPagerApi::class, ExperimentalAnimationApi::class)
@Composable
fun SplashScreen(navController: NavController) {
val splashImageList = listOf(
R.drawable.splash_1,
R.drawable.splash_2,
R.drawable.splash_3,
)
val currentPosition = remember { mutableStateOf(0) }
val animate = remember { mutableStateOf(true) }
val pagerState = rememberPagerState()

Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceAround
) {
AnimatedContent(
targetState = animate.value,
modifier = Modifier
.fillMaxWidth(),
transitionSpec = {
slideInHorizontally(
initialOffsetX = { value ->
value
}
) with slideOutHorizontally(
targetOffsetX = { value ->
-value
}
)
},
content = {
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(0.6f)
.padding(top = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "ALFAMIND",
fontSize = 50.sp,
color = MaterialTheme.colors.PrimaryColor,
fontWeight = FontWeight.Bold,
fontFamily = FontFamily(Font(R.font.muli_bold)),
)
Spacer(modifier = Modifier.height(5.dp))
when (currentPosition.value) {
0 -> {
Text(
text = buildAnnotatedString {
append(text = "Selamat Datang Di ")
withStyle(
style = SpanStyle(
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.TextColor,
)
) {
append("AlfaMind.")
}
append(" Mari Mulai Belanja!")
},
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
textAlign = TextAlign.Center,
fontFamily = FontFamily(Font(R.font.muli)),
)
}
1 -> {
Text(
text = "Kita membantu warga dalam \nBerbelanja barang",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
textAlign = TextAlign.Center
)
}
else -> {
Text(
text = "Memudahkan menemukan barang yang.\nDiinginkan dan murah meriah",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
textAlign = TextAlign.Center
)

}
}
Spacer(modifier = Modifier.height(30.dp))

Image(
painter = painterResource(id = splashImageList[currentPosition.value]),
contentDescription = "Splash Image",
modifier = Modifier.padding(40.dp)
)
}
}
)


DotIndicator(splashImageList.size, currentPosition.value)

CustomDefaultBtn(btnText = "Lanjut", shapeSize = 10f) {
if (currentPosition.value < 2) {
currentPosition.value++
animate.value = !animate.value
} else {
navController.navigate(AuthScreen.SignInScreen.route)
}
}
}
}
SignUpScreen.kt:
package com.eritlab.jexmon.presentation.screens.sign_up_screen.component

import android.util.Patterns
import androidx.compose.animation.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
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.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.common.CustomDefaultBtn
import com.eritlab.jexmon.presentation.common.CustomTextField
import com.eritlab.jexmon.presentation.common.component.DefaultBackArrow
import com.eritlab.jexmon.presentation.common.component.ErrorSuggestion
import com.eritlab.jexmon.presentation.graphs.auth_graph.AuthScreen
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor
import com.eritlab.jexmon.presentation.ui.theme.PrimaryLightColor
import com.eritlab.jexmon.presentation.ui.theme.TextColor


@OptIn(ExperimentalAnimationApi::class)
@Composable
fun SignUpScreen(navController: NavController) {
var email by remember { mutableStateOf(TextFieldValue("")) }
var password by remember { mutableStateOf(TextFieldValue("")) }
var confirmPass by remember { mutableStateOf(TextFieldValue("")) }
var firstName by remember { mutableStateOf(TextFieldValue("")) }
var lastName by remember { mutableStateOf(TextFieldValue("")) }
var phoneNumber by remember { mutableStateOf(TextFieldValue("")) }
var address by remember { mutableStateOf(TextFieldValue("")) }
val emailErrorState = remember { mutableStateOf(false) }
val passwordErrorState = remember { mutableStateOf(false) }
val conPasswordErrorState = remember { mutableStateOf(false) }
val firstNameErrorState = remember { mutableStateOf(false) }
val lastNameErrorState = remember { mutableStateOf(false) }
val phoneNumberErrorState = remember { mutableStateOf(false) }
val addressErrorState = remember { mutableStateOf(false) }
val animate = remember { mutableStateOf(true) }


AnimatedContent(targetState = animate.value, transitionSpec = {
slideInHorizontally(
initialOffsetX = { value ->
value
}
) with slideOutHorizontally(
targetOffsetX = { value ->
-value
}
)
}) {
if (it) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
)
{
Box(modifier = Modifier.weight(0.7f)) {
DefaultBackArrow {
navController.popBackStack()
}
}
Box(modifier = Modifier.weight(1.0f)) {
Text(
text = "Sign Up",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp
)
}


}
Spacer(modifier = Modifier.height(50.dp))
Text(text = "Register Account", fontSize = 26.sp, fontWeight = FontWeight.Bold)
Text(
text = "Complete your details or continue\nwith social media.",
color = MaterialTheme.colors.TextColor,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(50.dp))
CustomTextField(
placeholder = "example@email.com",
trailingIcon = R.drawable.mail,
label = "Email",
errorState = emailErrorState,
keyboardType = KeyboardType.Email,
visualTransformation = VisualTransformation.None,
onChanged = { newEmail ->
email = newEmail
}
)

Spacer(modifier = Modifier.height(20.dp))
CustomTextField(
placeholder = "********",
trailingIcon = R.drawable.lock,
label = "Password",
keyboardType = KeyboardType.Password,
errorState = passwordErrorState,
visualTransformation = PasswordVisualTransformation(),
onChanged = { newPass ->
password = newPass
}
)


Spacer(modifier = Modifier.height(20.dp))
CustomTextField(
placeholder = "********",
trailingIcon = R.drawable.lock,
label = "Confirm Password",
keyboardType = KeyboardType.Password,
errorState = conPasswordErrorState,
visualTransformation = PasswordVisualTransformation(),
onChanged = { newPass ->
confirmPass = newPass
}
)

Spacer(modifier = Modifier.height(10.dp))
if (emailErrorState.value) {
ErrorSuggestion("Please enter valid email address.")
}
if (passwordErrorState.value) {
Row() {
ErrorSuggestion("Please enter valid password.")
}
}
if (conPasswordErrorState.value) {
ErrorSuggestion("Confirm Password miss matched.")
}
CustomDefaultBtn(shapeSize = 50f, btnText = "Continue") {
//email pattern
val pattern = Patterns.EMAIL_ADDRESS
val isEmailValid = pattern.matcher(email.text).matches()
val isPassValid = password.text.length >= 8
val conPassMatch = password == confirmPass
emailErrorState.value = !isEmailValid
passwordErrorState.value = !isPassValid
conPasswordErrorState.value = !conPassMatch
if (isEmailValid && isPassValid && conPassMatch) {
animate.value = !animate.value
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 50.dp),
verticalArrangement = Arrangement.Bottom
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(
space = 10.dp,
alignment = Alignment.CenterHorizontally
)
) {
Box(
modifier = Modifier
.size(50.dp)
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = CircleShape
),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = R.drawable.google_icon),
contentDescription = "Google Login Icon"
)
}
Box(
modifier = Modifier
.size(50.dp)
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = CircleShape
)
.clickable {

},
contentAlignment = Alignment.Center,
) {
Image(
painter = painterResource(id = R.drawable.twitter),
contentDescription = "Twitter Login Icon"
)
}
Box(
modifier = Modifier
.size(50.dp)
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = CircleShape
)
.clickable {

},
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = R.drawable.facebook_2),
contentDescription = "Facebook Login Icon"
)
}

}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 30.dp)
.clickable {

},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "By continuing you confirm that you agree",
color = MaterialTheme.colors.TextColor
)
Row()
{
Text(
text = "with our ",
color = MaterialTheme.colors.TextColor,
)
Text(
text = "Terms & Condition",
color = MaterialTheme.colors.PrimaryColor,
modifier = Modifier.clickable {

})
}

}
}


}
} else {
Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
)
{
Box(modifier = Modifier.weight(0.7f)) {
DefaultBackArrow {
animate.value = !animate.value
}
}
Box(modifier = Modifier.weight(1.0f)) {
Text(
text = "Sign Up",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp
)
}


}
Spacer(modifier = Modifier.height(50.dp))
Text(text = "Complete Profile", fontSize = 26.sp, fontWeight = FontWeight.Bold)
Text(
text = "Complete your details or continue\nwith social media.",
color = MaterialTheme.colors.TextColor,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(50.dp))
CustomTextField(
placeholder = "Enter your first name",
trailingIcon = R.drawable.user,
label = "First Name",
errorState = firstNameErrorState,
keyboardType = KeyboardType.Text,
visualTransformation = VisualTransformation.None,
onChanged = { newText ->
firstName = newText
}
)
Spacer(modifier = Modifier.height(20.dp))
CustomTextField(
placeholder = "Enter your last name",
trailingIcon = R.drawable.user,
label = "Last Name",
errorState = lastNameErrorState,
keyboardType = KeyboardType.Text,
visualTransformation = VisualTransformation.None,
onChanged = { newText ->
lastName = newText
}
)

Spacer(modifier = Modifier.height(20.dp))
CustomTextField(
placeholder = "Enter your phone number",
trailingIcon = R.drawable.phone,
label = "Phone Number",
keyboardType = KeyboardType.Phone,
errorState = phoneNumberErrorState,
visualTransformation = VisualTransformation.None,
onChanged = { newNumber ->
phoneNumber = newNumber
}
)


Spacer(modifier = Modifier.height(20.dp))
CustomTextField(
placeholder = "example: Dhaka, Bangladesh",
trailingIcon = R.drawable.location_point,
label = "Address",
keyboardType = KeyboardType.Password,
errorState = addressErrorState,
visualTransformation = VisualTransformation.None,
onChanged = { newText ->
address = newText
}
)
Spacer(modifier = Modifier.height(10.dp))
if (firstNameErrorState.value || lastNameErrorState.value) {
ErrorSuggestion("Please enter valid name.")
}
if (phoneNumberErrorState.value) {
ErrorSuggestion("Please enter valid phone number.")
}
if (addressErrorState.value) {
ErrorSuggestion("Please enter valid address.")
}

CustomDefaultBtn(shapeSize = 50f, btnText = "Continue") {
val isPhoneValid = phoneNumber.text.isEmpty() || phoneNumber.text.length < 4
val isFNameValid = firstName.text.isEmpty() || firstName.text.length < 3
val isLNameValid = lastName.text.isEmpty() || lastName.text.length < 3
val isAddressValid = address.text.isEmpty() || address.text.length < 5
firstNameErrorState.value = !isFNameValid
lastNameErrorState.value = !isLNameValid
addressErrorState.value = !isAddressValid
phoneNumberErrorState.value = !isPhoneValid
if (!isFNameValid && !isLNameValid && !isAddressValid && !isPhoneValid) {
navController.navigate(AuthScreen.OTPScreen.route)
}
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 50.dp),
verticalArrangement = Arrangement.Bottom
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 30.dp)
.clickable {

},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "By continuing you confirm that you agree",
color = MaterialTheme.colors.TextColor
)
Row()
{
Text(
text = "with our ",
color = MaterialTheme.colors.TextColor,
)
Text(
text = "Terms & Condition",
color = MaterialTheme.colors.PrimaryColor,
modifier = Modifier.clickable {

})
}

}
}


}
}
}


SignInScreen.kt:
package com.eritlab.jexmon.presentation.screens.sign_success_screen.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.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.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.eritlab.jexmon.presentation.common.CustomDefaultBtn
import com.eritlab.jexmon.presentation.ui.theme.TextColor
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.graphs.Graph

@Composable
fun SignInScreen(navController: NavController) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
Text(
text = "Masuk Berhasil",
color = MaterialTheme.colors.TextColor,
fontWeight = FontWeight(700),
fontSize = 18.sp
)
}
Image(
painter = painterResource(id = R.drawable.success),
contentDescription = "Login Success Image"
)
Text(
text = "Masuk Berhasil",
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)

Spacer(modifier = Modifier.height(50.dp))

CustomDefaultBtn(shapeSize = 50f, btnText = "Lanjut") {
navController.navigate(Graph.HOME)
}
}


}
ProfileScreen.kt:
package com.eritlab.jexmon.presentation.screens.profile_screen.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.AlignmentLine
import androidx.compose.ui.modifier.modifierLocalConsumer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.HorizontalAnchorable
import com.eritlab.jexmon.presentation.common.component.DefaultBackArrow
import com.eritlab.jexmon.presentation.ui.theme.TextColor
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor

@Composable
fun ProfileScreen(
onBackBtnClick: () -> Unit
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(15.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Box(modifier = Modifier.weight(0.5f)) {
DefaultBackArrow {
onBackBtnClick
}
}
Box(modifier = Modifier.weight(0.7f)) {
Text(
text = "Profile",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
}
}

Spacer(modifier = Modifier.height(30.dp))
ConstraintLayout(
modifier = Modifier
.fillMaxWidth()
) {
val (image, cameraIcon) = createRefs()
Image(
painter = painterResource(id = R.drawable.profile_image),
contentDescription = "Profile Image",
modifier = Modifier
.clip(CircleShape)
.constrainAs(image) {
linkTo(start = parent.start, end = parent.end)
}
)
Box(contentAlignment = Alignment.Center, modifier = Modifier.constrainAs(cameraIcon) {
bottom.linkTo(image.bottom)
end.linkTo(image.end)

}) {

IconButton(onClick = { /*TODO*/ }) {
Icon(
painter = painterResource(id = R.drawable.camera_icon),
contentDescription = "Change Picture",
modifier = Modifier.background(Color.LightGray)
)
}
}
}
Spacer(modifier = Modifier.height(60.dp))

Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)

.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.user_icon),
contentDescription = null,
modifier = Modifier.weight(0.05f), tint = MaterialTheme.colors.PrimaryColor
)
Text("Profile Picture", modifier = Modifier.weight(0.2f))
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
modifier = Modifier.weight(0.05f),
tint = MaterialTheme.colors.TextColor
)
}

Spacer(modifier = Modifier.height(15.dp))


Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)

.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.bell),
contentDescription = null,
modifier = Modifier.weight(0.05f), tint = MaterialTheme.colors.PrimaryColor
)
Text("Notification", modifier = Modifier.weight(0.2f))
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
modifier = Modifier.weight(0.05f),
tint = MaterialTheme.colors.TextColor
)
}


Spacer(modifier = Modifier.height(15.dp))


Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)

.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.settings),
contentDescription = null,
modifier = Modifier.weight(0.05f), tint = MaterialTheme.colors.PrimaryColor
)
Text("Settings", modifier = Modifier.weight(0.2f))
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
modifier = Modifier.weight(0.05f),
tint = MaterialTheme.colors.TextColor
)
}


Spacer(modifier = Modifier.height(15.dp))


Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)

.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.question_mark),
contentDescription = null,
modifier = Modifier.weight(0.05f), tint = MaterialTheme.colors.PrimaryColor
)
Text("Help Center", modifier = Modifier.weight(0.2f))
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
modifier = Modifier.weight(0.05f),
tint = MaterialTheme.colors.TextColor
)
}

Spacer(modifier = Modifier.height(15.dp))


Row(
modifier = Modifier
.fillMaxWidth()
.height(70.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.log_out),
contentDescription = null,
modifier = Modifier.weight(0.05f), tint = MaterialTheme.colors.PrimaryColor
)
Text("Logout", modifier = Modifier.weight(0.2f))
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
modifier = Modifier.weight(0.05f),
tint = MaterialTheme.colors.TextColor
)
}

}
}
ProductDetailScreen.kt:
package com.eritlab.jexmon.presentation.screens.product_detail_screen.component

import android.app.Activity
import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.graphics.toColorInt
import androidx.hilt.navigation.compose.hiltViewModel
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.common.CustomDefaultBtn
import com.eritlab.jexmon.presentation.screens.product_detail_screen.ProductDetailViewModel
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor
import com.eritlab.jexmon.presentation.ui.theme.PrimaryLightColor
import com.eritlab.jexmon.presentation.ui.theme.TextColor

@Composable
fun ProductDetailScreen(
viewModel: ProductDetailViewModel = hiltViewModel(),
popBack: () -> Unit
) {
val state = viewModel.state.value
val context = LocalContext.current
if (state.isLoading) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CircularProgressIndicator()
}
} else if (state.productDetail != null) {
val product = state.productDetail
var colorSelected by remember { mutableStateOf(product.colors[product.colors.size - 1]) }
var selectedPicture by remember { mutableStateOf(product.images[0]) }
var quantity by remember { mutableStateOf(1) }



Column(
modifier = Modifier
.fillMaxSize()
.background(color = Color(0x8DB3B0B0)),
horizontalAlignment = Alignment.CenterHorizontally,

) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 15.dp, end = 15.dp, top = 15.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
IconButton(
onClick = {
popBack()
},
modifier = Modifier
.background(color = Color.White, shape = CircleShape)
.clip(CircleShape)

) {
Image(
painter = painterResource(id = R.drawable.back_icon),
contentDescription = null
)
}
Row(
modifier = Modifier
.width(70.dp)
.background(color = Color.White, shape = RoundedCornerShape(8.dp))
.padding(3.dp)
.clip(RoundedCornerShape(8.dp)),
horizontalArrangement = Arrangement.spacedBy(
4.dp,
Alignment.CenterHorizontally
),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = product.rating.toString(),
fontWeight = FontWeight.Bold,
color = Color.Black
)
Image(
painter = painterResource(id = R.drawable.star_icon),
contentDescription = null
)
}


}
//image
Image(
painter = painterResource(id = selectedPicture),
contentDescription = null,
modifier = Modifier.size(250.dp)
)

LazyRow(
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
items(product.images.size) {
IconButton(
onClick = {
selectedPicture = product.images[it]
},
modifier = Modifier
.size(50.dp)
.border(
width = 1.dp,
color = if (selectedPicture == product.images[it]) MaterialTheme.colors.PrimaryColor else Color.Transparent,
shape = RoundedCornerShape(10.dp)
)
.background(Color.White, shape = RoundedCornerShape(10.dp))
.padding(5.dp)
.clip(RoundedCornerShape(10.dp))
) {
Image(
painter = painterResource(id = product.images[it]),
contentDescription = null,
)

}
}

}
Spacer(modifier = Modifier.height(50.dp))
Column(
modifier = Modifier
.fillMaxWidth()
.background(
Color.White,
shape = RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp)
)
// .padding(15.dp)
) {

Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.weight(1f)
.padding(15.dp)
) {
Text(
text = product.title,
fontWeight = FontWeight.Bold,
fontSize = 18.sp
)

Spacer(modifier = Modifier.height(25.dp))

Text(
text = product.description,
fontSize = 16.sp,
color = MaterialTheme.colors.TextColor
)
Spacer(modifier = Modifier.height(25.dp))
Row(
horizontalArrangement = Arrangement.spacedBy(5.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "See more Details",
color = MaterialTheme.colors.PrimaryColor,
fontSize = 16.sp,

)
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = "",
tint = MaterialTheme.colors.PrimaryColor
)
}


}
IconButton(onClick = { /*TODO*/ }) {
Image(
painter = painterResource(id = R.drawable.heart_icon_2),
contentDescription = null,
colorFilter = ColorFilter.tint(Color.Red),
modifier = Modifier
.size(40.dp)
.background(
Color(0x75F44336),
shape = RoundedCornerShape(
topStart = 20.dp,
bottomStart = 20.dp
)
)
.padding(10.dp)
.weight(1f)
)
}
}

Row(
modifier = Modifier
.fillMaxWidth()
.background(
Color(0x8DB3B0B0),
shape = RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp)
)
.padding(15.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {

LazyRow(horizontalArrangement = Arrangement.spacedBy(5.dp)) {
items(product.colors.size) {
Box(
modifier = Modifier
.size(30.dp)
.border(
width = 1.dp,
color = if (colorSelected == product.colors[it]) MaterialTheme.colors.PrimaryColor else Color.Transparent,
shape = CircleShape
)
.padding(5.dp)
.background(color = product.colors[it], shape = CircleShape)
.clip(CircleShape)
.clickable {
colorSelected = product.colors[it]
}
)
}
}
Row(
verticalAlignment = Alignment.CenterVertically
) {
IconButton(
onClick = {
if (quantity > 1) {
quantity--
}
},
modifier = Modifier
.background(color = Color.White, shape = CircleShape)
.clip(CircleShape)

) {
Image(
painter = painterResource(id = R.drawable.remove),
contentDescription = null
)
}
Text(
text = quantity.toString(),
textAlign = TextAlign.Center,
modifier = Modifier
.width(35.dp)
.wrapContentHeight()
)
IconButton(
onClick = {
if (quantity < 5) {
quantity++
} else {
Toast.makeText(
context,
"You can add maximum 5 item at a time.",
Toast.LENGTH_SHORT
).show()
}
},
modifier = Modifier
.background(color = Color.White, shape = CircleShape)
.clip(CircleShape)

) {
Image(
painter = painterResource(id = R.drawable.plus_icon),
contentDescription = null
)
}
}
}


Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(
Color.White,
shape = RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp)
)
.clip(RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp)),
contentAlignment = Alignment.Center
) {
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.PrimaryColor,
contentColor = Color.White
),
modifier = Modifier
.width(200.dp)
.padding(top = 30.dp, bottom = 30.dp)
.height(60.dp)
.clip(RoundedCornerShape(15.dp)),
onClick = {
Toast.makeText(
context,
"Successfully added to cart",
Toast.LENGTH_SHORT
).show()

},
) {
Text(text = "Add to Cart", fontSize = 16.sp)
}
}


}


}

} else {
Toast.makeText(context, state.errorMessage, Toast.LENGTH_SHORT).show()
}


}
OTPScreen.kt:
package com.eritlab.jexmon.presentation.screens.otp_screen.component


import android.os.CountDownTimer
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.eritlab.jexmon.presentation.common.CustomDefaultBtn
import com.eritlab.jexmon.presentation.common.component.DefaultBackArrow
import com.eritlab.jexmon.presentation.graphs.auth_graph.AuthScreen
import com.eritlab.jexmon.presentation.screens.sign_in_screen.component.OTPTexField
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor
import com.eritlab.jexmon.presentation.ui.theme.TextColor


@Composable
fun OTPScreen(navController: NavController) {
//otp mutable list
var otp1 by remember { mutableStateOf(TextFieldValue("")) }
var otp2 by remember { mutableStateOf(TextFieldValue("")) }
var otp3 by remember { mutableStateOf(TextFieldValue("")) }
var otp4 by remember { mutableStateOf(TextFieldValue("")) }
var otp5 by remember { mutableStateOf(TextFieldValue("")) }
val focusRequester1 = FocusRequester()
val focusRequester2 = FocusRequester()
val focusRequester3 = FocusRequester()
val focusRequester4 = FocusRequester()
val focusRequester5 = FocusRequester()

//count down
val timer = object : CountDownTimer(12000, 1000) {
override fun onTick(millisUntilFinished: Long) {

}

override fun onFinish() {

}
}


Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
)
{
Box(modifier = Modifier.weight(0.5f)) {
DefaultBackArrow {
// navController.popBackStack()
}
}
Box(modifier = Modifier.weight(1.0f)) {
Text(
text = "OTP Verification",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
fontWeight = FontWeight(700)
)
}
}
Spacer(modifier = Modifier.height(50.dp))
Text(text = "OTP Verification", fontSize = 26.sp, fontWeight = FontWeight.Bold)
Text(
text = buildAnnotatedString {
append("We sent your code to +8801737-***\nThis code is expired in ")
withStyle(
style = SpanStyle(
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.PrimaryColor,
)
) {
append("120s")
}
},
color = MaterialTheme.colors.TextColor,
textAlign = TextAlign.Center
)

Spacer(modifier = Modifier.height(50.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
OTPTexField(focusRequester = focusRequester1) { newText ->
otp1 = newText
if (otp1.text.isNotEmpty()) {
focusRequester2.requestFocus()
}
}
OTPTexField(focusRequester = focusRequester2) { newText ->
otp2 = newText
if (otp2.text.length == 1) {
focusRequester3.requestFocus()
} else {
focusRequester1.requestFocus()
}
}
OTPTexField(focusRequester = focusRequester3) { newText ->
otp3 = newText
if (otp3.text.length == 1) {
focusRequester4.requestFocus()
} else {
focusRequester2.requestFocus()
}
}
OTPTexField(focusRequester = focusRequester4) { newText ->
otp4 = newText
if (otp4.text.length == 1) {
focusRequester5.requestFocus()
} else {
focusRequester3.requestFocus()
}
}
OTPTexField(focusRequester = focusRequester5) { newText ->
otp5 = newText
if (otp5.text.isEmpty()) {
focusRequester4.requestFocus()
}
}
}

Spacer(modifier = Modifier.fillMaxHeight(0.3f))
CustomDefaultBtn(shapeSize = 50f, btnText = "Verify") {
if ((otp1.text + otp2.text + otp3.text + otp4.text + otp5.text).length == 5) {
navController.navigate(AuthScreen.SignInScreen.route)
}
}
Spacer(modifier = Modifier.fillMaxHeight(0.3f))
Text(
text = "Resend OTP Code",
style = TextStyle(textDecoration = TextDecoration.Underline),
color = MaterialTheme.colors.TextColor,
fontWeight = FontWeight(500),
modifier = Modifier.clickable {

})
}
}
DashboardScreen.kt:
package com.eritlab.jexmon.presentation.screens.dashboard_screen.component

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
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 androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import androidx.core.graphics.toColor
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.graphs.Graph
import com.eritlab.jexmon.presentation.graphs.detail_graph.DetailScreen
import com.eritlab.jexmon.presentation.screens.dashboard_screen.DashboardViewModel
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor
import com.eritlab.jexmon.presentation.ui.theme.PrimaryLightColor
import com.eritlab.jexmon.presentation.ui.theme.SecondaryColor
import com.eritlab.jexmon.presentation.ui.theme.TextColor
import dagger.hilt.android.lifecycle.HiltViewModel

@Composable
fun DashboardScreen(
popularProductState: LazyListState = rememberLazyListState(),
suggestionProductState: LazyListState = rememberLazyListState(),
productViewModel: DashboardViewModel = hiltViewModel(),
onItemClick: (Int) -> Unit
) {

val state = productViewModel.state.value

Column(
modifier = Modifier
.fillMaxSize()
.padding(start = 15.dp, end = 15.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.height(90.dp)
.background(color = Color(0xFF4a3298), shape = RoundedCornerShape(10.dp))
.padding(15.dp),
verticalArrangement = Arrangement.Center
) {
Text("A Spring Surprise", color = Color.White)
Text(
"Cashback 25%",
color = Color.White,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
}
Spacer(modifier = Modifier.height(15.dp))
Row(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.drawable.flash_icon),
contentDescription = "Flash Deal",
modifier = Modifier
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(10.dp)
)
.size(50.dp)

.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(10.dp)
)
Text(text = "Flash\nDeal", fontSize = 14.sp, textAlign = TextAlign.Center)
}

Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.drawable.bill_icon),
contentDescription = "Bill",
modifier = Modifier
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(10.dp)
)
.size(50.dp)

.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(10.dp)
)
Text(text = "Bill", fontSize = 14.sp, textAlign = TextAlign.Center)
}


Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.drawable.game_icon),
contentDescription = "Game",
modifier = Modifier
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(10.dp)
)
.size(50.dp)

.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(10.dp)
)
Text(text = "Game", fontSize = 14.sp, textAlign = TextAlign.Center)
}

Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.drawable.gift_icon),
contentDescription = "Daily Gift",
modifier = Modifier
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(10.dp)
)
.size(50.dp)

.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(10.dp)
)
Text(text = "Daily\nGift", fontSize = 14.sp, textAlign = TextAlign.Center)
}


Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.drawable.discover),
contentDescription = "More",
modifier = Modifier
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(10.dp)
)
.size(50.dp)

.clip(RoundedCornerShape(10.dp))
.clickable {

}
.padding(10.dp)
)
Text(text = "More", fontSize = 14.sp, textAlign = TextAlign.Center)
}
}

Spacer(modifier = Modifier.height(30.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "Special for you", fontWeight = FontWeight.Bold, fontSize = 16.sp)
Text(text = "See More", color = MaterialTheme.colors.TextColor)
}

Spacer(modifier = Modifier.height(15.dp))
//special offer cart
LazyRow(
state = popularProductState,
horizontalArrangement = Arrangement.spacedBy(10.dp),
contentPadding = PaddingValues(horizontal = 10.dp)
) {
item {
ConstraintLayout(
modifier = Modifier
.width(280.dp)
.clip(RoundedCornerShape(20.dp))
) {
//constrains
val (bannerText, bannerImage) = createRefs()
Image(
painter = painterResource(id = R.drawable.image_banner_3),
contentDescription = "",
modifier = Modifier.constrainAs(bannerImage) {}
)
Column(
modifier = Modifier
.background(Color(0x8DB3B0B0))
.padding(15.dp)
.constrainAs(bannerText) {
top.linkTo(bannerImage.top)
bottom.linkTo(bannerImage.bottom)
start.linkTo(bannerImage.start)
end.linkTo(bannerImage.end)
height = Dimension.fillToConstraints
width = Dimension.fillToConstraints
}
) {
Text(
text = "Fashion",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 18.sp
)
Spacer(modifier = Modifier.heightIn(15.dp))
Text(text = "85 Brands", color = Color.White)
}


}
}
item {
//second item
ConstraintLayout(
modifier = Modifier
.width(280.dp)
.clip(RoundedCornerShape(20.dp))
) {
//constrains
val (bannerText2, bannerImage2) = createRefs()
Image(
painter = painterResource(id = R.drawable.image_banner_2),
contentDescription = "",
modifier = Modifier.constrainAs(bannerImage2) {}
)
Column(
modifier = Modifier
.background(Color(0x8DB3B0B0))
.padding(15.dp)
.constrainAs(bannerText2) {
top.linkTo(bannerImage2.top)
bottom.linkTo(bannerImage2.bottom)
start.linkTo(bannerImage2.start)
end.linkTo(bannerImage2.end)
height = Dimension.fillToConstraints
width = Dimension.fillToConstraints
}
) {
Text(
text = "Mobile Phone & Gadget",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 18.sp
)
Spacer(modifier = Modifier.heightIn(15.dp))
Text(text = "15 Brands", color = Color.White)
}
}
}

}



Spacer(modifier = Modifier.height(15.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "Popular Product", fontWeight = FontWeight.Bold, fontSize = 16.sp)
Text(text = "See More", color = MaterialTheme.colors.TextColor)
}

Spacer(modifier = Modifier.height(8.dp))


//popular product
LazyRow(
state = suggestionProductState,
horizontalArrangement = Arrangement.spacedBy(10.dp),
contentPadding = PaddingValues(horizontal = 10.dp)
) {
items(state.product!!.size) {

//favourite state rememberable
var favouriteRemember by remember { mutableStateOf(state.product[it].isFavourite) }

Column {
Box(
modifier = Modifier
.size(150.dp)
.background(Color.LightGray, shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.clickable {
onItemClick(state.product[it].id)
},
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = state.product[it].images[0]),
contentDescription = state.product[it].description
)
}
Text(
text = state.product[it].title,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.width(150.dp)
)


Row(
modifier = Modifier
.width(150.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "$ ${state.product[it].price}",
fontWeight = FontWeight(600),
color = MaterialTheme.colors.PrimaryColor
)
Box(
modifier = Modifier
.size(20.dp)
.background(
MaterialTheme.colors.PrimaryLightColor,
shape = CircleShape
)
.clip(CircleShape)
.clickable {
favouriteRemember = !favouriteRemember
},
contentAlignment = Alignment.Center
) {

Image(
painter = painterResource(
id = if (favouriteRemember)
R.drawable.heart_icon_2
else R.drawable.heart_icon
),
contentDescription = "Favourite Icon",
modifier = Modifier.padding(3.dp),
colorFilter = if (favouriteRemember) ColorFilter.tint(
Color.Red
) else null
)
}
}

}
}
}
}
}
CartScreen.kt:
package com.eritlab.jexmon.presentation.screens.cart_screen.component

import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectVerticalDragGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.materialIcon
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.modifier.modifierLocalConsumer
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 androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import com.eritlab.jexmon.presentation.common.component.DefaultBackArrow
import com.eritlab.jexmon.presentation.ui.theme.TextColor
import com.eritlab.jexmon.R
import com.eritlab.jexmon.presentation.common.CustomDefaultBtn
import com.eritlab.jexmon.presentation.ui.theme.PrimaryColor
import com.eritlab.jexmon.presentation.ui.theme.PrimaryLightColor


@Preview(showBackground = true)
@Composable
fun CartScreen() {
var itemDrag by remember { mutableStateOf(0f) }


ConstraintLayout(modifier = Modifier.fillMaxSize(1f)) {
val (topBar, product, checkout) = createRefs()

Row(
modifier = Modifier
.padding(top = 15.dp, start = 15.dp, end = 15.dp)
.fillMaxWidth()
.constrainAs(topBar) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
},
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Box(modifier = Modifier.weight(0.5f)) {
DefaultBackArrow {

}
}
Box(modifier = Modifier.weight(0.7f)) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Your Cart",
color = MaterialTheme.colors.TextColor,
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "4 items",
textAlign = TextAlign.Center,
color = MaterialTheme.colors.TextColor,
)

}
}

}

Column(
modifier = Modifier
.fillMaxWidth()
.constrainAs(product) {
top.linkTo(topBar.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
.wrapContentHeight()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp)
.pointerInput(Unit) {
detectVerticalDragGestures { change, dragAmount ->
itemDrag = dragAmount
}
},
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Image(
painter = painterResource(id = R.drawable.ps4_console_white_1),
contentDescription = null,
modifier = Modifier
.size(80.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column() {
Text(
text = "Wireless Controller for PS4™",
fontWeight = FontWeight(700),
fontSize = 16.sp,

)
Spacer(modifier = Modifier.height(8.dp))
Row() {
Text(
text = "$79.99",
color = MaterialTheme.colors.PrimaryColor,
fontWeight = FontWeight.Bold
)
Text(text = " x1", color = MaterialTheme.colors.TextColor)
}
}
}







Row(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp)
.pointerInput(Unit) {
detectVerticalDragGestures { change, dragAmount ->
itemDrag = dragAmount
}
},
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Image(
painter = painterResource(id = R.drawable.shoes2),
contentDescription = null,
modifier = Modifier
.size(80.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column() {
Text(
text = "High Quality Sport Shoes",
fontWeight = FontWeight(700),
fontSize = 16.sp,

)
Spacer(modifier = Modifier.height(8.dp))
Row() {
Text(
text = "$100.25",
color = MaterialTheme.colors.PrimaryColor,
fontWeight = FontWeight.Bold
)
Text(text = " x1", color = MaterialTheme.colors.TextColor)
}
}
}



Row(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp)
.pointerInput(Unit) {
detectVerticalDragGestures { change, dragAmount ->
itemDrag = dragAmount
}
},
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Image(
painter = painterResource(id = R.drawable.image_popular_product_2),
contentDescription = null,
modifier = Modifier
.size(80.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column() {
Text(
text = "Nike Sport White - Man Pant",
fontWeight = FontWeight(700),
fontSize = 16.sp,

)
Spacer(modifier = Modifier.height(8.dp))
Row() {
Text(
text = "$49.99",
color = MaterialTheme.colors.PrimaryColor,
fontWeight = FontWeight.Bold
)
Text(text = " x1", color = MaterialTheme.colors.TextColor)
}
}
}



Row(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp)
.pointerInput(Unit) {
detectVerticalDragGestures { change, dragAmount ->
itemDrag = dragAmount
}
},
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Image(
painter = painterResource(id = R.drawable.glove),
contentDescription = null,
modifier = Modifier
.size(80.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(10.dp))
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column() {
Text(
text = "Gloves XC Omega - Polygon",
fontWeight = FontWeight(700),
fontSize = 16.sp,

)
Spacer(modifier = Modifier.height(8.dp))
Row() {
Text(
text = "$36.55",
color = MaterialTheme.colors.PrimaryColor,
fontWeight = FontWeight.Bold
)
Text(text = " x1", color = MaterialTheme.colors.TextColor)
}
}
}


}




Column(
modifier = Modifier
.wrapContentHeight()
.constrainAs(checkout) {
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
.background(
color = MaterialTheme.colors.PrimaryLightColor,
shape = RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp)
)
.clip(RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp))
.padding(20.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.receipt),
contentDescription = null,
tint = MaterialTheme.colors.PrimaryColor,
modifier = Modifier
.size(45.dp)
.background(Color(0x8DB3B0B0), shape = RoundedCornerShape(15.dp))
.padding(10.dp)
.clip(RoundedCornerShape(15.dp))
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
Text("Add vouture Code")
Icon(
painter = painterResource(id = R.drawable.arrow_right),
contentDescription = null,
)
}
}
//btn
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Column() {
Text(text = "Total")
Text(
text = "$266.78",
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.PrimaryColor
)

}
Box(
modifier = Modifier
.width(150.dp)
) {
CustomDefaultBtn(shapeSize = 15f, btnText = "Check Out") {

}
}

}


}

}
}

  1. Buat Presentasi dan demo implementasi upload di youtube, dan isi lembar monitoring?

https://youtu.be/EaaaOBzRYqs


Docs: Google Docs





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