This is a dating app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

252 lines
9.2 KiB

package com.example.dattingapp
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material.icons.outlined.ChatBubbleOutline
import androidx.compose.material3.*
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.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
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 coil.compose.AsyncImage
class LikeAndMatchScreen {
}
data class Profile(
val name: String,
val age: Int,
val distance: String,
val matchPercentage: Int,
val tags: List<String>,
val imageUrl: String,
val hasUnread: Boolean = false
)
@Composable
fun ProfileGrid(profiles: List<Profile>, modifier: Modifier = Modifier) {
LazyVerticalGrid(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = modifier.fillMaxSize()
) {
items(profiles) { profile ->
ProfileCard(profile = profile)
}
}
}
@Composable
fun ProfileCard(profile: Profile, modifier: Modifier = Modifier) {
Card(
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.White),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
modifier = modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
// Image with Overlays
Box(
modifier = Modifier
.fillMaxWidth()
.height(180.dp)
.clip(RoundedCornerShape(12.dp))
) {
AsyncImage(
model = profile.imageUrl,
contentDescription = profile.name,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
// Gradient Overlay for Text Readability
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.7f)),
startY = 100f
)
)
)
// Match Badge
Surface(
shape = RoundedCornerShape(20.dp),
color = Color.White.copy(alpha = 0.9f),
modifier = Modifier
.padding(8.dp)
.align(Alignment.TopStart)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
) {
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = null,
tint = Color(0xFF6C5CE7),
modifier = Modifier.size(12.dp)
)
Text(
text = "${profile.matchPercentage}%",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF2D3436)
)
}
}
// Notification Dot
if (profile.hasUnread) {
Box(
modifier = Modifier
.padding(8.dp)
.size(8.dp)
.clip(CircleShape)
.background(Color(0xFF6C5CE7))
.align(Alignment.TopEnd)
)
}
// Name, Age & Distance
Column(
modifier = Modifier
.align(Alignment.BottomStart)
.padding(8.dp)
) {
Text(
text = "${profile.name}, ${profile.age}",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(2.dp)
) {
Icon(
imageVector = Icons.Default.LocationOn,
contentDescription = null,
tint = Color.White.copy(alpha = 0.8f),
modifier = Modifier.size(10.dp)
)
Text(
text = profile.distance,
color = Color.White.copy(alpha = 0.8f),
fontSize = 10.sp
)
}
}
}
// Tags Row
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.fillMaxWidth()
) {
profile.tags.take(2).forEach { tag ->
Surface(
shape = RoundedCornerShape(6.dp),
color = Color(0xFFF1F2F6),
modifier = Modifier.weight(1f)
) {
Text(
text = tag,
fontSize = 10.sp,
color = Color(0xFF636E72),
modifier = Modifier.padding(vertical = 4.dp, horizontal = 4.dp),
maxLines = 1
)
}
}
}
// Action Buttons
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().padding(10.dp)
) {
IconButton(
onClick = { },
modifier = Modifier
.size(22.dp)
.background(Color(0xFFF8F9FA), CircleShape)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "Pass",
tint = Color(0xFF636E72),
modifier = Modifier.size(16.dp)
)
}
IconButton(
onClick = { },
modifier = Modifier
.size(22.dp)
.background(Color(0xFFF1EFFE), CircleShape)
) {
Icon(
imageVector = Icons.Outlined.ChatBubbleOutline,
contentDescription = "Message",
tint = Color(0xFF6C5CE7),
modifier = Modifier.size(16.dp)
)
}
IconButton(
onClick = { },
modifier = Modifier
.size(22.dp)
.background(Color(0xFFD63031), CircleShape)
) {
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "Like",
tint = Color.White,
modifier = Modifier.size(16.dp)
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun ProfileGridPreview() {
val sampleProfiles = listOf(
Profile("Elena", 24, "2 miles away", 98, listOf("Photography", "Coffee"), "", true),
Profile("Sarah", 26, "4 miles away", 94, listOf("Travel", "Music"), ""),
Profile("Julian", 27, "3 miles away", 91, listOf("Music Prod", "Vinyl"), ""),
Profile("Maya", 25, "5 miles away", 89, listOf("Surfing", "Yoga"), "")
)
ProfileGrid(profiles = sampleProfiles)
}