0% found this document useful (0 votes)
11 views9 pages

Dashboard Code

The document contains a Kotlin implementation of a Dashboard screen using Jetpack Compose for an Android application. It features a user profile section, profile completeness indicator, and sections for new matches and latest updates, along with a bottom navigation bar. The layout is designed to be responsive and visually appealing, utilizing various Compose components such as LazyRow, Card, and CircularProgressIndicator.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views9 pages

Dashboard Code

The document contains a Kotlin implementation of a Dashboard screen using Jetpack Compose for an Android application. It features a user profile section, profile completeness indicator, and sections for new matches and latest updates, along with a bottom navigation bar. The layout is designed to be responsive and visually appealing, utilizing various Compose components such as LazyRow, Card, and CircularProgressIndicator.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

package com.eristaa.connect.presentation.

dashboard

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Group
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.TrendingUp
import androidx.compose.material.icons.filled.Verified
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.material3.ProgressIndicatorDefaults.drawStopIndicator
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
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.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
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.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.eristaa.connect.R

@Composable
fun DashboardScreen() {
Scaffold(
bottomBar = {
BottomNavigationBar() // Your custom bottom navigation bar
}
) { innerPadding ->
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.verticalScroll(rememberScrollState())
.padding(
10.dp,
innerPadding.calculateTopPadding(),
10.dp,
innerPadding.calculateBottomPadding()
),

) {
// Top Profile Section
Row(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp, 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
ProfileImageWithProgress(R.drawable.profile_pic, 0.78f)

Spacer(modifier = Modifier.width(12.dp))

Column(modifier = Modifier.weight(1f)) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text("Asutosh Jena", fontWeight = FontWeight.Bold, fontSize
= 20.sp)
Image(
painter = painterResource(id = R.drawable.verified),
contentDescription = "verified",
Modifier.size(30.dp)
)
Image(
painter = painterResource(id = R.drawable.shield_imgg),
contentDescription = "shield",
Modifier.size(25.dp)
)
}
Text("(Ristaa ID)", fontSize = 14.sp, color = Color.Gray)
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
"Free Member",
fontSize = 14.sp,
color = Color.Gray,
modifier = Modifier.padding(0.dp, 10.dp, 15.dp, 0.dp)
)

Button(
onClick = { /* Upgrade action */ },
contentPadding = PaddingValues(), // Remove default
padding to fill the gradient
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent // Make the
button's own container transparent
),
modifier = Modifier
.background( // Apply the gradient to a background
modifier
brush = Brush.horizontalGradient(
colors = listOf(Color(0xFFFF6F00),
Color.Blue)
),
shape = RoundedCornerShape(20.dp) // Apply
shape to the background as well
)
.height(30.dp)
.width(100.dp)
.padding(10.dp, 0.dp)
) {
// Apply padding to the content inside the button
Text(
"UPGRADE",
color = Color.White,
fontSize = 12.sp,
textAlign = TextAlign.Center
)
}
}
}

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

// Profile completeness section


Text("Complete Your Profile for Better Response", fontWeight =
FontWeight.Bold)
Spacer(modifier = Modifier.height(8.dp))
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text("Profile completeness", modifier = Modifier.weight(0.4f))
LinearProgressIndicator(
progress = { 0.78f },
gapSize = (-1).dp,
modifier = Modifier
.height(8.dp)
.weight(0.4f),
color = Color(0xFFFFA726),
strokeCap =
ProgressIndicatorDefaults.CircularDeterminateStrokeCap,
)
Text("78%", modifier = Modifier.weight(0.2f))
}

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

ProfileActionsLazyRowWithIndicator()

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

// New Matches
SectionTitle("New Matches")
LazyRow {
items(10) {
MatchItem()
}
}

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

// Latest Updates
SectionTitle("Latest Updates")
LazyRow {
items(10) {
MatchItem()
}
}

Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text("Who Viewed My Profile", fontWeight = FontWeight.Bold,
fontSize = 16.sp)
Text("View All", color = Color(0xFFFF6F00), fontSize = 14.sp)

Spacer(modifier = Modifier.height(16.dp))
LazyRow {
items(10) {
MatchItem()
}
}

// Bottom Navigation Bar (Simplified)


//BottomNavigationBar()
}
}
}

@Composable
fun ProfileActionsLazyRowWithIndicator() {
val map = remember { // Use remember for the map if it doesn't change
frequently
hashMapOf(
"Add Profile Picture" to R.drawable.profile_pic,
"Verify Profile" to R.drawable.verified,
"Add Family Details" to R.drawable.familly_pic,
"Add Horoscope Details" to R.drawable.logo,
)
}
val itemsList = map.entries.toList() // Convert map entries to a list for
easier indexing

val lazyListState = rememberLazyListState()

// More precise way to check if scrolling to end is possible for LazyListState


val canScrollForward by remember {
derivedStateOf {
lazyListState.canScrollForward
}
}

// State to track if the end is visible


val isScrolledToEnd by remember {
derivedStateOf {
val layoutInfo = lazyListState.layoutInfo
val visibleItemsInfo = layoutInfo.visibleItemsInfo
if (visibleItemsInfo.isEmpty() || itemsList.isEmpty()) {
!canScrollForward
} else {
val lastVisibleItemIndex = visibleItemsInfo.last().index
val totalItemsCount = layoutInfo.totalItemsCount
lastVisibleItemIndex == totalItemsCount - 1 &&
visibleItemsInfo.last().offset +
visibleItemsInfo.last().size <= layoutInfo.viewportEndOffset + 2 // +2 for small
tolerance
}
}
}

val showIndicator = canScrollForward && !isScrolledToEnd

Box(
modifier = Modifier.fillMaxWidth()
) {
LazyRow(
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(8.dp), // Use spacedBy for
consistent spacing
modifier = Modifier
.fillMaxWidth()
.padding(end = if (showIndicator) 36.dp else 0.dp), // Make space
for indicator
contentPadding = PaddingValues(horizontal = 8.dp)
) {
items(
count = itemsList.size,
key = { index -> itemsList[index].key } // Provide a stable key if
items can change
) { index ->
val entry = itemsList[index]
UpdateProfileCards(title = entry.key, image = entry.value)
}
}

if (showIndicator) {
Icon(
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
contentDescription = "Scroll for more",
tint = Color.Gray, // Or MaterialTheme.colorScheme.onSurfaceVariant
modifier = Modifier
.size(40.dp)
.align(Alignment.CenterEnd)
)
}
}
}

@Composable
fun UpdateProfileCards(title: String, image: Int) {
Card(
elevation = CardDefaults.cardElevation(5.dp),
colors = CardDefaults.cardColors(Color.White),
modifier = Modifier
.size(130.dp)
.padding(3.dp)
) {
ProfileActionItem(title, image)
}
}

@Composable
fun SectionTitle(title: String) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(title, fontWeight = FontWeight.Bold, fontSize = 16.sp)
Text("View All", color = Color(0xFFFF6F00), fontSize = 14.sp)
}
Spacer(modifier = Modifier.height(8.dp))
}

@Composable
fun MatchItem() {
Column(
modifier = Modifier
.width(80.dp)
.padding(4.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.size(60.dp)
.background(Color.LightGray, RoundedCornerShape(8.dp))
)
Text("Full Name", fontSize = 12.sp, maxLines = 1)
Text("28 Yrs | 5ft 2in", fontSize = 10.sp, color = Color.Gray)
}
}

@Composable
fun ProfileActionItem(label: String, icon: Int) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier =
Modifier.padding(3.dp)) {

Box(
modifier = Modifier
.size(70.dp)
.padding(10.dp)
.background(Color.White, RoundedCornerShape(22.dp)),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(id = icon),
contentDescription = label
)
}
Spacer(
modifier = Modifier
.height(5.dp)
.fillMaxWidth()
)
Text(
label,
fontSize = 13.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold
)

}
}

@Composable
fun BottomNavigationBar() {
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
.padding(vertical = 20.dp),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Icon(
Icons.Default.Home,
contentDescription = "Home",
modifier = Modifier.size(40.dp),
tint = Color(0xfff16a11)
)
Icon(
Icons.Default.Person,
contentDescription = "Profile",
modifier = Modifier.size(40.dp),
tint = Color(0xfff16a11)
)
Icon(
Icons.Default.Email,
contentDescription = "Messages",
modifier = Modifier.size(40.dp),
tint = Color(0xfff16a11)
)
Icon(
Icons.Default.Notifications,
contentDescription = "Notifications",
modifier = Modifier.size(40.dp),
tint = Color(0xfff16a11)
)
Icon(
Icons.Default.Settings,
modifier = Modifier.size(40.dp),
contentDescription = "Settings",
tint = Color(0xfff16a11)
)
}
}

@Composable
fun ProfileImageWithProgress(
imageUrl: Int,
progress: Float,
imageSize: Dp = 90.dp,
indicatorStrokeWidth: Dp = 4.dp,
indicatorColor: Color = Color(0xFFFFA726),
trackColor: Color = MaterialTheme.colorScheme.surfaceVariant
) {
val indicatorSize =
imageSize + (indicatorStrokeWidth * 2) // Ensure progress is outside the
image

Box(
contentAlignment = Alignment.Center,
modifier = Modifier.size(indicatorSize) // Box takes the size of the
indicator
) {
// Background track for the circular progress (optional, but good for
visual clarity)
// This is essentially a disabled or full CircularProgressIndicator acting
as a track
CircularProgressIndicator(
progress = { 1f }, // Full circle for the track
modifier = Modifier.size(indicatorSize),
color = trackColor,
strokeWidth = indicatorStrokeWidth
)

// The actual progress indicator


CircularProgressIndicator(
progress = { progress.coerceIn(0f, 1f) }, // Progress value
modifier = Modifier.size(indicatorSize),
color = indicatorColor,
strokeWidth = indicatorStrokeWidth,
// trackColor = Color.Transparent // Make the default track of this one
transparent
// if you're using a separate track indicator above.
// For M3, the main 'color' is the indicator, 'trackColor' is its
background.
// If you have a separate track composable like above,
// then the trackColor for *this* specific progress can be Transparent.
// However, CircularProgressIndicator in M3 doesn't have a separate
trackColor
// that is different from the progress for the *same* indicator.
// The above track is a separate composable.
)

Image(
painter = painterResource(id = imageUrl),
contentDescription = "Profile Picture",
contentScale = ContentScale.Crop, // Crop to fill the circle
modifier = Modifier
.size(imageSize)
.clip(CircleShape) // Clip image to a circle
// Optional: Add a small border to the image itself if desired
// .border(1.dp, Color.Gray, CircleShape)
)
}
}

@Preview
@Composable
fun DashboardPreview() {
DashboardScreen()
}

You might also like