Browse Source

friend profile

master
osman160128 3 weeks ago
parent
commit
17930a1671
  1. 278
      app/src/main/java/com/example/dattingapp/FriendProfile.kt
  2. 71
      app/src/main/java/com/example/dattingapp/homes/MeetScreen.kt
  3. 9
      app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeApiService.kt
  4. 74
      app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeDataClass.kt
  5. 69
      app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeViewModelClass.kt
  6. 30
      app/src/main/java/com/example/dattingapp/permission/PermissionHelper.kt
  7. 1
      app/src/main/java/com/example/dattingapp/registration/RegisterRequest.kt
  8. 64
      app/src/main/java/com/example/dattingapp/registration/RegistrationScreen.kt
  9. 8
      app/src/main/java/com/example/dattingapp/ui/theme/Color.kt

278
app/src/main/java/com/example/dattingapp/FriendProfile.kt

@ -1,5 +1,6 @@
package com.example.dattingapp
import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@ -17,46 +18,107 @@ 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.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.ArrowBack
import androidx.compose.material.icons.filled.ChatBubble
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.MoreHoriz
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.outlined.LocationOn
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import com.example.dattingapp.homes.networkandapi.FriendProfileMedia
import com.example.dattingapp.homes.networkandapi.FriendProfileResponse
import com.example.dattingapp.homes.networkandapi.FriendProfileUiState
import com.example.dattingapp.homes.networkandapi.FriendProfileViewModel
import com.example.dattingapp.homes.networkandapi.MeetUserProfile
import com.example.dattingapp.homes.networkandapi.SwipeRequest
import com.example.dattingapp.homes.networkandapi.SwipeViewModel
import com.example.dattingapp.ui.theme.AccentPurple
import com.example.dattingapp.ui.theme.DattingAPPTheme
import com.example.dattingapp.ui.theme.textDark
import com.example.dattingapp.ui.theme.BadgePink
import com.example.dattingapp.ui.theme.gradientBrush
import com.example.dattingapp.ui.theme.purpleButtonColor
import java.nio.file.WatchEvent
import java.time.LocalDate
import java.time.Period
import java.time.format.DateTimeFormatter
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.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.ui.unit.dp
class FriendProfile : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// Read extras passed from the Intent
val userId = intent.getIntExtra("USER_ID", -1)
setContent {
DattingAPPTheme {
val context = LocalContext.current
val viewModel: FriendProfileViewModel = viewModel()
FriendProfileScreen()
// 2. Collect state from ViewModel
val uiState by viewModel.friendProfileUiState.collectAsState()
// 3. Trigger network call once when screen loads
LaunchedEffect(Unit) {
viewModel.fetchUserProfile(context,userId)
}
when (val state = uiState) {
is FriendProfileUiState.Loading -> {
// Show loading indicator
}
is FriendProfileUiState.Success -> {
val friendProfileData = state.friendProfile
FriendProfileScreen(friendProfileData,context)
}
is FriendProfileUiState.Error -> {
// Show error message
}
FriendProfileUiState.Idle -> {
// Idle state
}
}
}
}
@ -65,13 +127,24 @@ class FriendProfile : ComponentActivity() {
@Composable
fun FriendProfileScreen(
friendProfileData: FriendProfileResponse,
context: Context,
swipeViewModel: SwipeViewModel= viewModel() ,
onBackClick:()->Unit={},
onMoreClick:()->Unit={},
onMessageClick:()->Unit={},
onLikeClick:()->Unit={},
onStarClick:()->Unit={},
onCancelClick:()->Unit={},
){
val age = remember(friendProfileData.birthDate) {
calculateAge(friendProfileData.birthDate)
}
Column(
modifier = Modifier
.fillMaxSize()
@ -119,11 +192,14 @@ fun FriendProfileScreen(
}
}
Image(
painter = painterResource(id = R.drawable.locationpermissionbg),
// Assuming 'profileImageUrl' is passed into your composable from FriendProfileResponse
AsyncImage(
model = friendProfileData?.profileImageUrl, // Pass the String URL from FriendProfileResponse
contentDescription = "Profile Avatar",
placeholder = painterResource(id = R.drawable.locationpermissionbg), // Placeholder while loading
error = painterResource(id = R.drawable.locationpermissionbg), // Fallback if URL fails or is null
modifier = Modifier
.padding(start = 20.dp) // Move padding to the VERY TOP of modifier chain
.padding(start = 20.dp)
.align(Alignment.BottomStart)
.size(100.dp)
.clip(CircleShape)
@ -139,12 +215,16 @@ fun FriendProfileScreen(
.padding(horizontal = 20.dp)
){
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
val displayName = friendProfileData.fullName ?: "User"
val nameAndAge = if (age != null) "$displayName, $age" else displayName
Text(
text = "Elena",
text = nameAndAge,
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = textDark
@ -213,6 +293,8 @@ fun FriendProfileScreen(
color = Color.Gray
)
}
Surface(
onClick = {
// Handle bio click action here (e.g., expand bio or navigate)
@ -222,25 +304,207 @@ fun FriendProfileScreen(
color = Color(0xFFF9F9F9),
shadowElevation = 1.dp
) {
val displayBio= friendProfileData.bio ?: ""
Text(
text = "\"Always looking for the best flat white in the city. Amateur photographer, professional dog petter. Let...\"",
text = displayBio,
fontSize = 13.sp,
color = Color(0xFF4A4A4A),
modifier = Modifier.padding(12.dp),
maxLines = 2,
lineHeight = 18.sp
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Message Button (Gradient Background)
Button(
onClick = onMessageClick,
modifier = Modifier
.weight(1f)
.height(48.dp)
.background(
brush = gradientBrush,
shape = RoundedCornerShape(10.dp)
),
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = Color.White
),
shape = RoundedCornerShape(10.dp)
) {
Icon(
imageVector = Icons.Default.ChatBubble,
contentDescription = "Message",
modifier = Modifier.size(18.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "Message",
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
// Heart Button
IconButton(
onClick = {
// Option 1: Invoke callback directly if handleSwipeAction is inside the parent screen
onLikeClick()
// Option 2: Call handleSwipeAction directly here
handleLikeAndDislikeAction(
context = context,
direction = "right", // Or "like", matching your API endpoint expected value
profile = friendProfileData, // Your MeetUserProfile instance
swipeViewModel = swipeViewModel
)
},
modifier = Modifier
.size(48.dp)
.background(
color = purpleButtonColor,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "Like",
tint = Color(0xFFE2C4FF), // Soft light purple icon color
modifier = Modifier.size(20.dp)
)
}
// Star Button
IconButton(
onClick = {
onStarClick()
handleLikeAndDislikeAction(
context = context,
direction = "right", // Or "like", matching your API endpoint expected value
profile = friendProfileData, // Your MeetUserProfile instance
swipeViewModel = swipeViewModel
)
},
modifier = Modifier
.size(48.dp)
.background(
color = purpleButtonColor,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(
imageVector = Icons.Default.Star,
contentDescription = "Favorite",
tint = Color(0xFFE2C4FF), // Soft light purple icon color
modifier = Modifier.size(20.dp)
)
}
IconButton(
onClick = {
onStarClick()
handleLikeAndDislikeAction(
context = context,
direction = "right", // Or "like", matching your API endpoint expected value
profile = friendProfileData, // Your MeetUserProfile instance
swipeViewModel = swipeViewModel
)
},
modifier = Modifier
.size(48.dp)
.background(
color = purpleButtonColor,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "Favorite",
tint = Color(0xFFE2C4FF), // Soft light purple icon color
modifier = Modifier.size(20.dp)
)
}
}
}
//
// LazyVerticalGrid(
// columns = GridCells.Fixed(3),
// contentPadding = PaddingValues(12.dp),
// horizontalArrangement = Arrangement.spacedBy(8.dp),
// verticalArrangement = Arrangement.spacedBy(8.dp),
// modifier = Modifier.fillMaxSize()
// ) {
// items(
// items = uiState.items,
// key = { post -> post.id }
// ) { item ->
// PostGridItem(item = item)
// }
// }
}
}
private fun handleLikeAndDislikeAction(
context: Context,
direction:String,
profile: FriendProfileResponse,
swipeViewModel: SwipeViewModel
) {
val targetUserId = profile.id
val swipeRequest = SwipeRequest(targetUserId, direction)
swipeViewModel.sendSwipeResponse(context, swipeRequest)
}
//calculte age
private fun calculateAge(birthDateStr: String?): Int? {
if (birthDateStr.isNullOrBlank()) return null
return try {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val birthDate = LocalDate.parse(birthDateStr.take(10), formatter)
Period.between(birthDate, LocalDate.now()).years
} catch (e: Exception) {
null
}
}
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun FriendProfileScreenPreview() {
DattingAPPTheme {
FriendProfileScreen()
val mockProfileResponse = FriendProfileResponse(
id = 101,
fullName = "Elena Rostova",
gender = "Female",
birthDate = "1999-05-14",
city = "San Francisco",
country = "USA",
relationshipGoal = "Long-term relationship",
bio = "Always looking for the best flat white in the city. Amateur photographer, professional dog petter.",
profileImageUrl = "https://via.placeholder.com/150",
videoUrl = null,
compatibilityPercentage = 98,
media = null
)
FriendProfileScreen(
friendProfileData = mockProfileResponse,
context = LocalContext.current,
onBackClick = {},
onMoreClick = {},
onMessageClick = {},
onLikeClick = {},
onStarClick = {}
)
}
}

71
app/src/main/java/com/example/dattingapp/homes/MeetScreen.kt

@ -1,9 +1,11 @@
package com.example.dattingapp.homes
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.compose.animation.core.Animatable
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
@ -20,6 +22,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
@ -29,6 +32,7 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.example.dattingapp.FriendProfile
import com.example.dattingapp.homes.networkandapi.MeetUserProfile
import com.example.dattingapp.homes.networkandapi.SwipeRequest
import com.example.dattingapp.homes.networkandapi.SwipeViewModel
@ -199,10 +203,11 @@ private fun ProfileCardItem(
val token = remember(context) {
TokenManager.getInstance(context).getAccessToken()
}
val defaultPainter = rememberVectorPainter(Icons.Default.Person)
AsyncImage(
model = ImageRequest.Builder(context)
.data(photoUrl)
.data(photoUrl.takeIf { !it.isNullOrBlank() })
.apply {
if (!token.isNullOrBlank()) {
val authHeader = if (token.startsWith("Bearer ", ignoreCase = true)) token else "Bearer $token"
@ -211,6 +216,9 @@ private fun ProfileCardItem(
}
.crossfade(true)
.build(),
placeholder = defaultPainter,
error = defaultPainter,
fallback = defaultPainter, // Shows Icons.Default.Person immediately when photoUrl is null/blank
contentDescription = "Profile Image",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop,
@ -299,6 +307,16 @@ private fun ProfileCardItem(
.fillMaxWidth(0.70f)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
val intent = Intent(context, FriendProfile::class.java).apply {
putExtra("USER_ID",profile.id )
}
context.startActivity(intent)
},
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
@ -397,3 +415,54 @@ private fun handleSwipeAction(
swipeViewModel.sendSwipeResponse(context, swipeRequest)
}
// ==========================================
// PREVIEWS & MOCK DATA
// ==========================================
private val mockProfiles = listOf(
MeetUserProfile(
id = 1,
fullName = "Sophia Chen",
birthDate = "1998-06-15",
city = "San Francisco",
country = "USA",
distanceKm = 4.2,
bio = "Coffee enthusiast, UI designer, and full-time dog lover 🐶✨ Looking for someone to explore new coffee shops with!",
compatibilityPercentage = 92,
media = null, // Triggers fallback default Person icon
gender = "Male",
videoUrl = null
),
MeetUserProfile(
id = 2,
fullName = "Alex Rivera",
birthDate = "1995-11-03",
city = "Los Angeles",
country = "USA",
distanceKm = 12.0,
bio = "Software engineer by day, musician by night 🎸 Let's jam or talk about tech!",
compatibilityPercentage = 85,
media = null,
gender = "Male",
videoUrl = null
)
)
@Preview(name = "Discovery Screen - Loaded State", showBackground = true)
@Composable
fun MeetDiscoveryScreenPreview() {
MaterialTheme {
MeetDiscoveryScreen(
profiles = mockProfiles,
isLoading = false,
errorMessage = null,
onAddClick = {},
onSearchClick = {},
onSuperLikeClick = {},
onRejectClick = {},
onLikeClick = {}
)
}
}

9
app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeApiService.kt

@ -4,6 +4,7 @@ import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
interface HomeApiService {
@ -17,8 +18,14 @@ interface HomeApiService {
suspend fun getCurrentUserProfile(): Response<MyProfileResponse>
@POST("api/v1/meet/swipes")
suspend fun recordSwipe(
suspend fun sendSwipe(
@Body request: SwipeRequest
): Response<SwipeResponse>
@GET("api/v1/users/{user_id}")
suspend fun getFriendProfile(
@Path("user_id") userId: Int
): Response<FriendProfileResponse>
}

74
app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeDataClass.kt

@ -92,27 +92,6 @@ data class MediaItem(
get() = resolveMediaUrl(url)
}
//swife data
// Request payload
data class SwipeRequest(
@SerializedName("target_user_id")
val targetUserId: Int,
@SerializedName("direction")
val direction: String // "like", "dislike", "super_like"
)
data class SwipeResponse(
@SerializedName("direction")
val direction: String?,
@SerializedName("matched")
val matched: Boolean = false,
@SerializedName("match_id")
val matchId: Int? = null
)
//feeling data for create post
data class VibeFeeling(
val name: String,
@ -145,3 +124,56 @@ val vibeFeelingsList = listOf(
VibeFeeling("Coding", "💻", "Activities"),
VibeFeeling("Gaming", "🎮", "Activities")
)
// Request Model for Swipe
data class SwipeRequest(
@SerializedName("target_user_id")
val targetUserId: Int,
@SerializedName("direction")
val direction: String
)
// Response Model
data class SwipeResponse(
@SerializedName("direction")
val direction: String?,
@SerializedName("matched")
val matched: Boolean?,
@SerializedName("match_id")
val matchId: Long?
)
// data class friend profile
data class FriendProfileMedia(
val id: Int,
@SerializedName("media_type")
val mediaType: String?,
val url: String?
)
data class FriendProfileResponse(
val id: Int,
@SerializedName("full_name")
val fullName: String?,
val gender: String?,
@SerializedName("birth_date")
val birthDate: String?,
val city: String?,
val country: String?,
@SerializedName("relationship_goal")
val relationshipGoal: String?,
val bio: String?,
@SerializedName("profile_image_url")
val profileImageUrl: String?,
@SerializedName("video_url")
val videoUrl: String?,
@SerializedName("compatibility_percentage")
val compatibilityPercentage: Int?,
val media: List<FriendProfileMedia>?
)

69
app/src/main/java/com/example/dattingapp/homes/networkandapi/HomeViewModelClass.kt

@ -159,7 +159,7 @@ class MyProfileViewModel : ViewModel() {
// Swife ViewModel---------------------------------------------------------------------------------------
//for ViewModel swife --------------------------------------------------------------------------------------
sealed interface SwipeUiState {
object Idle : SwipeUiState
@ -189,7 +189,7 @@ class SwipeViewModel : ViewModel() {
try {
val response = HomeNetworkModule
.getApiService(appContext)
.recordSwipe(swipeRequest)
.sendSwipe(swipeRequest)
val statusCode = response.code()
Log.d("swipe code", "Response Code: $statusCode")
@ -224,3 +224,68 @@ class SwipeViewModel : ViewModel() {
}
}
//for friend profile --------------------------------------------------------------------------------------
sealed interface FriendProfileUiState {
object Idle : FriendProfileUiState
object Loading : FriendProfileUiState
data class Success(val friendProfile: FriendProfileResponse) : FriendProfileUiState
data class Error(val message: String) : FriendProfileUiState
}
class FriendProfileViewModel : ViewModel() {
private val _friendProfileUiState = MutableStateFlow<FriendProfileUiState>(FriendProfileUiState.Idle)
val friendProfileUiState: StateFlow<FriendProfileUiState> = _friendProfileUiState.asStateFlow()
fun fetchUserProfile(context: Context, userId: Int) {
if (_friendProfileUiState.value is FriendProfileUiState.Loading) return
val appContext = context.applicationContext
viewModelScope.launch {
_friendProfileUiState.value = FriendProfileUiState.Loading
if (TokenManager.getInstance(appContext).getAccessToken().isNullOrBlank()) {
Log.e("MeetApi", "No access token in user_tokens preferences")
_friendProfileUiState.value = FriendProfileUiState.Error("No access token found. Please log in again.")
return@launch
}
try {
val response = HomeNetworkModule
.getApiService(appContext)
.getFriendProfile(userId)
val statusCode = response.code()
Log.d("userProfile code", "Response Code: $statusCode")
if (!response.isSuccessful) {
response.errorBody()?.close()
val message = when (response.code()) {
401 -> "Authentication failed. Please log in again."
403 -> "The server refused access to this profile."
404 -> "User profile was not found."
else -> "Request failed: HTTP ${response.code()}."
}
_friendProfileUiState.value = FriendProfileUiState.Error(message)
return@launch
}
val profileData = response.body()
if (profileData != null) {
_friendProfileUiState.value = FriendProfileUiState.Success(profileData)
} else {
_friendProfileUiState.value = FriendProfileUiState.Error("Profile data is empty.")
}
} catch (e: Exception) {
Log.e("MeetApi", "Unexpected request failure", e)
_friendProfileUiState.value = FriendProfileUiState.Error("Request failed: ${e.javaClass.simpleName}")
}
}
}
}

30
app/src/main/java/com/example/dattingapp/permission/PermissionHelper.kt

@ -28,7 +28,7 @@ class PermissionHelper(private val activity: ComponentActivity) {
permissionLauncher = activity.registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
// Check if all permissions requested are granted
// Check if at least one requested location permission (or all requested) is granted
val allGranted = permissions.entries.all { it.value }
onResult?.invoke(allGranted)
}
@ -57,6 +57,23 @@ class PermissionHelper(private val activity: ComponentActivity) {
}
}
/**
* Helper to check location permission specifically (either FINE or COARSE)
*/
fun hasLocationPermission(): Boolean {
val fineGranted = ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
val coarseGranted = ContextCompat.checkSelfPermission(
activity,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED
return fineGranted || coarseGranted
}
/**
* Request standard runtime permissions: NOTIFICATION, GALLERY, AUDIO, or LOCATION
*/
@ -71,6 +88,17 @@ class PermissionHelper(private val activity: ComponentActivity) {
}
}
/**
* Direct method to request Location Permission
*/
fun requestLocationPermission(callback: (Boolean) -> Unit) {
if (hasLocationPermission()) {
callback(true)
} else {
requestPermissions(PermissionType.LOCATION, callback)
}
}
/**
* Request Special Permission: Draw Over Other Apps
*/

1
app/src/main/java/com/example/dattingapp/registration/RegisterRequest.kt

@ -7,6 +7,7 @@ data class RegisterRequest(
@SerializedName("email_or_phone") val emailOrPhone: String,
@SerializedName("password") val password: String,
@SerializedName("confirm_password") val confirmPassword: String,
@SerializedName("relationship_goal") val relationshipGoal: String,
@SerializedName("full_name") val fullName: String,
@SerializedName("gender") val gender: String,
@SerializedName("birth_date") val birthDate: String,

64
app/src/main/java/com/example/dattingapp/registration/RegistrationScreen.kt

@ -122,7 +122,7 @@ fun RegistrationFlowContainer(
var selectedBirthDateMillis by rememberSaveable { mutableStateOf<Long?>(null) }
var addressInput by rememberSaveable { mutableStateOf("") }
var selectedGender by rememberSaveable { mutableStateOf("") }
var selectedRealationStatus by remember { mutableStateOf<String?>(null) }
var selectedRealationStatus by remember { mutableStateOf("") }
val scrollState = rememberScrollState()
@ -408,6 +408,7 @@ fun RegistrationFlowContainer(
emailOrPhone = contact,
password = passwordInput,
confirmPassword = confirmPasswordInput,
relationshipGoal = selectedRealationStatus.lowercase(Locale.ROOT).replace(" ", "_"),
fullName = nameInput.trim(),
gender = selectedGender.lowercase(Locale.ROOT),
birthDate = formattedDate,
@ -1496,6 +1497,7 @@ fun UniquePulseLoader(
data class VibeOption(
val title: String,
val value: String, // Value sent to backend API
val description: String,
val icon: ImageVector,
val iconBgColor: Color,
@ -1511,6 +1513,7 @@ fun VibeCheckScreen(
listOf(
VibeOption(
title = "Serious Relationship",
value = "serious_relationship",
description = "Looking for the one",
icon = Icons.Default.FavoriteBorder,
iconBgColor = Color(0xFFFFE3E3),
@ -1518,6 +1521,7 @@ fun VibeCheckScreen(
),
VibeOption(
title = "Casual Dates",
value = "casual_dates",
description = "Drinks & good times",
icon = Icons.Default.LocalBar,
iconBgColor = Color(0xFFEDE7F6),
@ -1525,6 +1529,7 @@ fun VibeCheckScreen(
),
VibeOption(
title = "New Friends",
value = "new_friends",
description = "Expand my circle",
icon = Icons.Default.People,
iconBgColor = Color(0xFFFFE0B2),
@ -1532,6 +1537,7 @@ fun VibeCheckScreen(
),
VibeOption(
title = "Marriage",
value = "marriage",
description = "Seeing where things go",
icon = Icons.Default.CompassCalibration,
iconBgColor = Color(0xFFE0E0E0),
@ -1540,72 +1546,26 @@ fun VibeCheckScreen(
)
}
val backgroundBrush = Brush.verticalGradient(
colors = listOf(
Color(0xFFFFF0F3),
Color(0xFFFFFFFF),
Color(0xFFFFF0F5)
)
)
Box(
modifier = Modifier
.fillMaxSize()
.background(backgroundBrush)
.padding(horizontal = 24.dp, vertical = 32.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "VibeCheck",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFFB0003A)
)
Spacer(modifier = Modifier.height(32.dp))
Text(
text = "What's your vibe?",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF1E293B)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Select your main goal right now to help us find theright connections.",
fontSize = 13.sp,
color = Color(0xFF64748B),
textAlign = TextAlign.Center,
lineHeight = 18.sp
)
Spacer(modifier = Modifier.height(48.dp))
// ... rest of background and header layout ...
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
vibeOptions.forEach { option ->
val isSelected = option.title == selectedRealationStatus
// Check selection against option.value
val isSelected = option.value == selectedRealationStatus
VibeCard(
option = option,
isSelected = isSelected,
onClick = {
onRelationSelected(option.title)
// Send backend value instead of UI title
onRelationSelected(option.value)
}
)
}
}
}
}
}
@Composable
fun VibeCard(
option: VibeOption,

8
app/src/main/java/com/example/dattingapp/ui/theme/Color.kt

@ -111,3 +111,11 @@ val SectionHeaderColor = Color(0xFF757575)
val CardBackgroundColor = Color.White
val LinkTextColor = Color(0xFF7B1FA2)
val UnreadDotColor = Color(0xFFD32F2F)
val gradientBrush = Brush.horizontalGradient(
colors = listOf(
Color(0xFFB00040), // Dark Pink/Magenta
Color(0xFF6B00B0) // Deep Purple
)
)
val purpleButtonColor = Color(0xFF6B00F5)
Loading…
Cancel
Save