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.
931 lines
21 KiB
931 lines
21 KiB
package com.example.dattingapp
|
|
|
|
import android.os.Bundle
|
|
import android.widget.Toast
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.setContent
|
|
import androidx.activity.enableEdgeToEdge
|
|
import androidx.compose.foundation.Image
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.border
|
|
import androidx.compose.foundation.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.shape.CircleShape
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.filled.Check
|
|
import androidx.compose.material.icons.outlined.Edit
|
|
import androidx.compose.material.icons.outlined.GridView
|
|
import androidx.compose.material.icons.outlined.PersonPin
|
|
import androidx.compose.material.icons.outlined.Settings
|
|
import androidx.compose.material3.*
|
|
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.Brush
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.layout.ContentScale
|
|
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 com.example.dattingapp.ui.theme.BrandMagenta
|
|
import com.example.dattingapp.ui.theme.BrandPurple
|
|
import com.example.dattingapp.ui.theme.DattingAPPTheme
|
|
import com.example.dattingapp.ui.theme.textDark
|
|
import com.example.dattingapp.ui.theme.TextMuted
|
|
|
|
|
|
// ============================================================
|
|
// MY PROFILE ACTIVITY
|
|
// ============================================================
|
|
|
|
class MyProfile : ComponentActivity() {
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
enableEdgeToEdge()
|
|
|
|
setContent {
|
|
|
|
DattingAPPTheme {
|
|
|
|
MyProfileScreen(
|
|
|
|
onEditClick = {
|
|
|
|
Toast.makeText(
|
|
this,
|
|
"Edit Profile Clicked",
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
// TODO:
|
|
// startActivity(
|
|
// Intent(
|
|
// this,
|
|
// EditProfileActivity::class.java
|
|
// )
|
|
// )
|
|
},
|
|
|
|
onUpgradeClick = {
|
|
|
|
Toast.makeText(
|
|
this,
|
|
"Upgrade to Premium Clicked",
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
},
|
|
|
|
onSettingsClick = {
|
|
|
|
Toast.makeText(
|
|
this,
|
|
"Settings Clicked",
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
// TODO:
|
|
// startActivity(
|
|
// Intent(
|
|
// this,
|
|
// SettingsActivity::class.java
|
|
// )
|
|
// )
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// MY PROFILE SCREEN
|
|
// ============================================================
|
|
|
|
@Composable
|
|
fun MyProfileScreen(
|
|
|
|
onEditClick: () -> Unit = {},
|
|
|
|
onUpgradeClick: () -> Unit = {},
|
|
|
|
onSettingsClick: () -> Unit = {}
|
|
|
|
) {
|
|
|
|
var selectedTab by remember {
|
|
|
|
mutableIntStateOf(0)
|
|
}
|
|
|
|
|
|
// ========================================================
|
|
// FULL SCREEN SCROLL
|
|
// ========================================================
|
|
|
|
val scrollState =
|
|
rememberScrollState()
|
|
|
|
|
|
Column(
|
|
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.background(Color.White)
|
|
.verticalScroll(scrollState)
|
|
) {
|
|
|
|
|
|
// ====================================================
|
|
// HEADER
|
|
// ====================================================
|
|
|
|
Box(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(260.dp)
|
|
) {
|
|
|
|
|
|
// =================================================
|
|
// COVER IMAGE
|
|
// =================================================
|
|
|
|
Image(
|
|
|
|
painter =
|
|
painterResource(
|
|
id =
|
|
R.drawable.locationpermissionbg
|
|
),
|
|
|
|
contentDescription =
|
|
"Cover Banner",
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(200.dp),
|
|
|
|
contentScale =
|
|
ContentScale.Crop
|
|
)
|
|
|
|
|
|
// =================================================
|
|
// SETTINGS BUTTON
|
|
// =================================================
|
|
|
|
IconButton(
|
|
|
|
onClick =
|
|
onSettingsClick,
|
|
|
|
modifier = Modifier
|
|
.align(
|
|
Alignment.TopEnd
|
|
)
|
|
.padding(
|
|
top = 16.dp,
|
|
end = 16.dp
|
|
)
|
|
.size(36.dp)
|
|
.clip(
|
|
CircleShape
|
|
)
|
|
.background(
|
|
Color.Black.copy(
|
|
alpha = 0.3f
|
|
)
|
|
)
|
|
) {
|
|
|
|
Icon(
|
|
|
|
imageVector =
|
|
Icons.Outlined.Settings,
|
|
|
|
contentDescription =
|
|
"Settings",
|
|
|
|
tint =
|
|
Color.White,
|
|
|
|
modifier =
|
|
Modifier.size(20.dp)
|
|
)
|
|
}
|
|
|
|
|
|
// =================================================
|
|
// PROFILE IMAGE
|
|
// =================================================
|
|
|
|
Box(
|
|
|
|
modifier = Modifier
|
|
.align(
|
|
Alignment.BottomStart
|
|
)
|
|
.padding(
|
|
start = 24.dp
|
|
)
|
|
.size(110.dp)
|
|
) {
|
|
|
|
|
|
Image(
|
|
|
|
painter =
|
|
painterResource(
|
|
id =
|
|
R.drawable.locationpermissionbg
|
|
),
|
|
|
|
contentDescription =
|
|
"Profile Picture",
|
|
|
|
contentScale =
|
|
ContentScale.Crop,
|
|
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.clip(
|
|
CircleShape
|
|
)
|
|
.border(
|
|
width = 4.dp,
|
|
color = Color.White,
|
|
shape = CircleShape
|
|
)
|
|
)
|
|
|
|
|
|
// =================================================
|
|
// VERIFIED BADGE
|
|
// =================================================
|
|
|
|
Box(
|
|
|
|
modifier = Modifier
|
|
.align(
|
|
Alignment.BottomEnd
|
|
)
|
|
.size(28.dp)
|
|
.clip(
|
|
CircleShape
|
|
)
|
|
.background(
|
|
BrandMagenta
|
|
)
|
|
.border(
|
|
width = 2.dp,
|
|
color = Color.White,
|
|
shape = CircleShape
|
|
),
|
|
|
|
contentAlignment =
|
|
Alignment.Center
|
|
) {
|
|
|
|
Icon(
|
|
|
|
imageVector =
|
|
Icons.Default.Check,
|
|
|
|
contentDescription =
|
|
"Verified",
|
|
|
|
tint =
|
|
Color.White,
|
|
|
|
modifier =
|
|
Modifier.size(16.dp)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ====================================================
|
|
// USER INFORMATION
|
|
// ====================================================
|
|
|
|
Column(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(
|
|
horizontal = 24.dp,
|
|
vertical = 8.dp
|
|
)
|
|
) {
|
|
|
|
|
|
// =================================================
|
|
// NAME + EDIT
|
|
// =================================================
|
|
|
|
Row(
|
|
|
|
verticalAlignment =
|
|
Alignment.CenterVertically,
|
|
|
|
horizontalArrangement =
|
|
Arrangement.spacedBy(8.dp)
|
|
) {
|
|
|
|
Text(
|
|
|
|
text =
|
|
"Alex, 28",
|
|
|
|
fontSize =
|
|
22.sp,
|
|
|
|
fontWeight =
|
|
FontWeight.Bold,
|
|
|
|
color =
|
|
BrandMagenta
|
|
)
|
|
|
|
|
|
// EDIT BUTTON
|
|
|
|
OutlinedButton(
|
|
|
|
onClick =
|
|
onEditClick,
|
|
|
|
modifier =
|
|
Modifier.height(30.dp),
|
|
|
|
contentPadding =
|
|
PaddingValues(
|
|
horizontal = 10.dp,
|
|
vertical = 0.dp
|
|
),
|
|
|
|
border =
|
|
ButtonDefaults
|
|
.outlinedButtonBorder
|
|
.copy(
|
|
width = 1.dp
|
|
)
|
|
) {
|
|
|
|
Icon(
|
|
|
|
imageVector =
|
|
Icons.Outlined.Edit,
|
|
|
|
contentDescription =
|
|
null,
|
|
|
|
tint =
|
|
BrandMagenta,
|
|
|
|
modifier =
|
|
Modifier.size(14.dp)
|
|
)
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.width(4.dp)
|
|
)
|
|
|
|
|
|
Text(
|
|
|
|
text =
|
|
"Edit",
|
|
|
|
fontSize =
|
|
12.sp,
|
|
|
|
color =
|
|
BrandMagenta,
|
|
|
|
fontWeight =
|
|
FontWeight.Bold
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(4.dp)
|
|
)
|
|
|
|
|
|
// =================================================
|
|
// BIO
|
|
// =================================================
|
|
|
|
Text(
|
|
|
|
text =
|
|
"Adventure seeker, dog lover, and amateur chef. Let's find a vibe!",
|
|
|
|
fontSize =
|
|
13.sp,
|
|
|
|
color =
|
|
TextMuted,
|
|
|
|
lineHeight =
|
|
18.sp
|
|
)
|
|
}
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(12.dp)
|
|
)
|
|
|
|
|
|
// ====================================================
|
|
// PREMIUM BANNER
|
|
// ====================================================
|
|
|
|
Box(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(
|
|
horizontal = 16.dp
|
|
)
|
|
.clip(
|
|
RoundedCornerShape(16.dp)
|
|
)
|
|
.background(
|
|
|
|
brush =
|
|
Brush.horizontalGradient(
|
|
|
|
colors =
|
|
listOf(
|
|
BrandMagenta,
|
|
BrandPurple
|
|
)
|
|
)
|
|
)
|
|
.padding(16.dp)
|
|
) {
|
|
|
|
Row(
|
|
|
|
modifier =
|
|
Modifier.fillMaxWidth(),
|
|
|
|
horizontalArrangement =
|
|
Arrangement.SpaceBetween,
|
|
|
|
verticalAlignment =
|
|
Alignment.CenterVertically
|
|
) {
|
|
|
|
Column {
|
|
|
|
Text(
|
|
|
|
text =
|
|
"VibeCheck Premium",
|
|
|
|
color =
|
|
Color.White,
|
|
|
|
fontSize =
|
|
16.sp,
|
|
|
|
fontWeight =
|
|
FontWeight.Bold
|
|
)
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(2.dp)
|
|
)
|
|
|
|
|
|
Text(
|
|
|
|
text =
|
|
"Unlock unlimited likes & more",
|
|
|
|
color =
|
|
Color.White.copy(
|
|
alpha = 0.8f
|
|
),
|
|
|
|
fontSize =
|
|
12.sp
|
|
)
|
|
}
|
|
|
|
|
|
// UPGRADE BUTTON
|
|
|
|
Button(
|
|
|
|
onClick =
|
|
onUpgradeClick,
|
|
|
|
colors =
|
|
ButtonDefaults.buttonColors(
|
|
|
|
containerColor =
|
|
Color.White
|
|
),
|
|
|
|
shape =
|
|
RoundedCornerShape(20.dp),
|
|
|
|
contentPadding =
|
|
PaddingValues(
|
|
horizontal = 14.dp,
|
|
vertical = 4.dp
|
|
)
|
|
) {
|
|
|
|
Text(
|
|
|
|
text =
|
|
"Upgrade",
|
|
|
|
color =
|
|
BrandMagenta,
|
|
|
|
fontSize =
|
|
12.sp,
|
|
|
|
fontWeight =
|
|
FontWeight.Bold
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(16.dp)
|
|
)
|
|
|
|
|
|
// ====================================================
|
|
// STATISTICS
|
|
// ====================================================
|
|
|
|
Row(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(
|
|
horizontal = 16.dp
|
|
),
|
|
|
|
horizontalArrangement =
|
|
Arrangement.spacedBy(8.dp)
|
|
) {
|
|
|
|
StatCard(
|
|
|
|
number =
|
|
"24",
|
|
|
|
label =
|
|
"Likes",
|
|
|
|
modifier =
|
|
Modifier.weight(1f)
|
|
)
|
|
|
|
|
|
StatCard(
|
|
|
|
number =
|
|
"12",
|
|
|
|
label =
|
|
"Liked",
|
|
|
|
modifier =
|
|
Modifier.weight(1f)
|
|
)
|
|
|
|
|
|
StatCard(
|
|
|
|
number =
|
|
"Top",
|
|
|
|
label =
|
|
"Match",
|
|
|
|
numberColor =
|
|
BrandMagenta,
|
|
|
|
modifier =
|
|
Modifier.weight(1f)
|
|
)
|
|
|
|
|
|
StatCard(
|
|
|
|
number =
|
|
"8",
|
|
|
|
label =
|
|
"Matches",
|
|
|
|
modifier =
|
|
Modifier.weight(1f)
|
|
)
|
|
}
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(16.dp)
|
|
)
|
|
|
|
|
|
// ====================================================
|
|
// TABS
|
|
// ====================================================
|
|
|
|
TabRow(
|
|
|
|
selectedTabIndex =
|
|
selectedTab,
|
|
|
|
containerColor =
|
|
Color.White,
|
|
|
|
contentColor =
|
|
BrandMagenta,
|
|
|
|
divider = {
|
|
|
|
HorizontalDivider(
|
|
color =
|
|
Color(0xFFEEEEEE)
|
|
)
|
|
}
|
|
) {
|
|
|
|
|
|
// =================================================
|
|
// GRID TAB
|
|
// =================================================
|
|
|
|
Tab(
|
|
|
|
selected =
|
|
selectedTab == 0,
|
|
|
|
onClick = {
|
|
|
|
selectedTab = 0
|
|
},
|
|
|
|
icon = {
|
|
|
|
Icon(
|
|
|
|
imageVector =
|
|
Icons.Outlined.GridView,
|
|
|
|
contentDescription =
|
|
"Grid View"
|
|
)
|
|
}
|
|
)
|
|
|
|
|
|
// =================================================
|
|
// TAGGED TAB
|
|
// =================================================
|
|
|
|
Tab(
|
|
|
|
selected =
|
|
selectedTab == 1,
|
|
|
|
onClick = {
|
|
|
|
selectedTab = 1
|
|
},
|
|
|
|
icon = {
|
|
|
|
Icon(
|
|
|
|
imageVector =
|
|
Icons.Outlined.PersonPin,
|
|
|
|
contentDescription =
|
|
"Tagged View"
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
// ====================================================
|
|
// MEDIA GRID
|
|
// ====================================================
|
|
|
|
ProfileMediaGrid()
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(30.dp)
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// PROFILE MEDIA GRID
|
|
// ============================================================
|
|
|
|
@Composable
|
|
private fun ProfileMediaGrid() {
|
|
|
|
Column(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(2.dp)
|
|
) {
|
|
|
|
// 6 rows × 3 columns = 18 images
|
|
|
|
repeat(6) { rowIndex ->
|
|
|
|
Row(
|
|
|
|
modifier =
|
|
Modifier.fillMaxWidth()
|
|
) {
|
|
|
|
repeat(3) { columnIndex ->
|
|
|
|
val imageIndex =
|
|
rowIndex * 3 +
|
|
columnIndex
|
|
|
|
|
|
Image(
|
|
|
|
painter =
|
|
painterResource(
|
|
id =
|
|
R.drawable.locationpermissionbg
|
|
),
|
|
|
|
contentDescription =
|
|
"Profile Image $imageIndex",
|
|
|
|
modifier = Modifier
|
|
.weight(1f)
|
|
.aspectRatio(1f)
|
|
.padding(1.dp),
|
|
|
|
contentScale =
|
|
ContentScale.Crop
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// STAT CARD
|
|
// ============================================================
|
|
|
|
@Composable
|
|
private fun StatCard(
|
|
|
|
number: String,
|
|
|
|
label: String,
|
|
|
|
modifier: Modifier = Modifier,
|
|
|
|
numberColor: Color = textDark
|
|
|
|
) {
|
|
|
|
Card(
|
|
|
|
modifier =
|
|
modifier,
|
|
|
|
shape =
|
|
RoundedCornerShape(12.dp),
|
|
|
|
colors =
|
|
CardDefaults.cardColors(
|
|
|
|
containerColor =
|
|
Color(0xFFFAFAFA)
|
|
),
|
|
|
|
border =
|
|
CardDefaults
|
|
.outlinedCardBorder()
|
|
.copy(
|
|
width = 0.5.dp
|
|
)
|
|
) {
|
|
|
|
Column(
|
|
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(
|
|
vertical = 12.dp
|
|
),
|
|
|
|
horizontalAlignment =
|
|
Alignment.CenterHorizontally
|
|
) {
|
|
|
|
Text(
|
|
|
|
text =
|
|
number,
|
|
|
|
fontSize =
|
|
16.sp,
|
|
|
|
fontWeight =
|
|
FontWeight.Bold,
|
|
|
|
color =
|
|
numberColor
|
|
)
|
|
|
|
|
|
Spacer(
|
|
modifier =
|
|
Modifier.height(2.dp)
|
|
)
|
|
|
|
|
|
Text(
|
|
|
|
text =
|
|
label,
|
|
|
|
fontSize =
|
|
11.sp,
|
|
|
|
color =
|
|
TextMuted
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ============================================================
|
|
// PREVIEW
|
|
// ============================================================
|
|
|
|
@Preview(
|
|
|
|
showBackground = true,
|
|
|
|
showSystemUi = true,
|
|
|
|
name = "My Profile"
|
|
)
|
|
@Composable
|
|
fun MyProfileScreenPreview() {
|
|
|
|
DattingAPPTheme {
|
|
|
|
MyProfileScreen()
|
|
}
|
|
}
|