Skip to content

Commit

Permalink
Giao diện của Profile
Browse files Browse the repository at this point in the history
  • Loading branch information
VuDucHuan2811 committed Oct 21, 2024
1 parent 8fa365f commit aaeceeb
Show file tree
Hide file tree
Showing 7 changed files with 302 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ fun HomeScreen(
}
}
}

Original file line number Diff line number Diff line change
@@ -1,70 +1,332 @@
package com.pwhs.quickmem.presentation.app.profile

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.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.material3.Button
import androidx.compose.material3.Scaffold
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.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.*
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.compose.ui.draw.clip
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 com.pwhs.quickmem.R
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.generated.destinations.WelcomeScreenDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator

@Composable
@Destination<RootGraph>
fun ProfileScreen(
modifier: Modifier = Modifier,
viewModel: ProfileViewModel = hiltViewModel(),
navigator: DestinationsNavigator
navigateToSettings: () -> Unit = {},
navigateToShare: () -> Unit = {}
) {
val uiState by viewModel.uiState.collectAsState()
LaunchedEffect(key1 = true) {
viewModel.uiEvent.collect { event ->
when (event) {
is ProfileUiEvent.LoadProfile -> TODO()
ProfileUiEvent.Logout -> {
navigator.navigateUp()
navigator.navigate(WelcomeScreenDestination) {
popUpTo(WelcomeScreenDestination) { inclusive = true }
var tabIndex by remember { mutableIntStateOf(0) }
val tabTitles = listOf("Profile", "Statistics")

Scaffold(
modifier = modifier,
bottomBar = { /* Add a bottom bar if needed */ }
) { innerPadding ->
Box(
modifier = Modifier
.background(Color.Transparent)
.padding(innerPadding)
) {
Image(
painter = painterResource(id = R.drawable.background_topbar),
contentDescription = "Background Image",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxWidth().height(58.dp)
)


LazyColumn {
item {
ProfileTopAppBar(
onSettingsClick = navigateToSettings,
onShareClick = navigateToShare
)
}
item {
ProfileTabRow(tabIndex = tabIndex, tabTitles = tabTitles, onTabSelected = { tabIndex = it })
}
item {
ProfileTabContent(tabIndex = tabIndex, onLogout = { /* Handle logout here */ })
}
}
}
}
}


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfileTopAppBar(
onSettingsClick: () -> Unit,
onShareClick: () -> Unit
) {
CenterAlignedTopAppBar(
title = {},
navigationIcon = {

Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(end = 30.dp)
) {
Box(
modifier = Modifier
.size(40.dp)
.background(Color.White, shape = CircleShape)
.border(1.dp, Color.Gray, shape = CircleShape)
) {
IconButton(onClick = onSettingsClick, modifier = Modifier.fillMaxSize()) {
Icon(
imageVector = Icons.Default.Settings,
contentDescription = "Settings",
tint = Color.Gray,
)
}
}

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

Box(
modifier = Modifier
.size(40.dp)
.background(Color.White, shape = CircleShape)
.border(1.dp, Color.Gray, shape = CircleShape)
) {
IconButton(onClick = onShareClick, modifier = Modifier.fillMaxSize()) {
Icon(
imageVector = Icons.Default.Share,
contentDescription = "Share Profile",
tint = Color.Gray,
)
}
}
}
},
actions = {},
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent
)
)
}

@Composable
fun ProfileTabRow(tabIndex: Int, tabTitles: List<String>, onTabSelected: (Int) -> Unit) {
TabRow(
selectedTabIndex = tabIndex,
indicator = { tabPositions ->
TabRowDefaults.SecondaryIndicator(
Modifier.tabIndicatorOffset(tabPositions[tabIndex]),
color = MaterialTheme.colorScheme.primary,
)
},
contentColor = MaterialTheme.colorScheme.onSurface,
) {
tabTitles.forEachIndexed { index, title ->
Tab(
text = {
Text(
title,
style = MaterialTheme.typography.titleMedium.copy(
fontWeight = FontWeight.Bold,
color = if (tabIndex == index) Color.Black else Color.Gray
)
)
},
selected = tabIndex == index,
onClick = { onTabSelected(index) }
)
}
}
Profile(
onLogout = { viewModel.onEvent(ProfileUiAction.Logout) }
}

@Composable
fun ProfileTabContent(tabIndex: Int, onLogout: () -> Unit) {
when (tabIndex) {
0 -> ProfileOverviewScreen()
1 -> StatisticsScreen()
}
}

@Composable
fun ProfileOverviewScreen() {
ProfileContent()
}

@Composable
fun StatisticsScreen() {
Text(
text = "Statistics Content",
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.bodyLarge
)
}

@Composable
fun Profile(
modifier: Modifier = Modifier,
onLogout: () -> Unit = {}
) {
Scaffold { innerPadding ->
fun ProfileContent() {
var name by remember { mutableStateOf("Huấn") }
var email by remember { mutableStateOf("huanhvph35061@fpt.edu.vn") }
var status by remember { mutableStateOf("Student (high / secondary school)") }

Box(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.border(1.dp, Color.Gray, shape = MaterialTheme.shapes.small)
.clip(MaterialTheme.shapes.small)
.padding(16.dp)
) {
Column(
modifier = modifier
.fillMaxSize()
.padding(innerPadding),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text("Profile Screen")
Button(
onClick = onLogout

OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") },
modifier = Modifier.fillMaxWidth()
)


OutlinedTextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
modifier = Modifier.fillMaxWidth()
)


Text(
text = "Please confirm your email address via the email we sent you",
color = Color.Red,
style = MaterialTheme.typography.bodySmall
)

Box(
modifier = Modifier
.align(Alignment.Start)
.height(38.dp)
.border(1.dp, Color.Gray, shape = RoundedCornerShape(25.dp))
.clip(RoundedCornerShape(25.dp))
.clickable { /* Add resend email functionality */ }
.padding(8.dp)
.background(Color.White)
) {
Text(
text = "Resend email",
color = Color.Black,
modifier = Modifier.padding(2.dp)
)
}


OutlinedTextField(
value = status,
onValueChange = { /* Implement logic to change status */ },
label = { Text("Status") },
readOnly = true,
modifier = Modifier.fillMaxWidth()
)

Box(
modifier = Modifier
.align(Alignment.Start)
.height(38.dp)
.border(1.dp, Color.Gray, shape = RoundedCornerShape(25.dp))
.clip(RoundedCornerShape(25.dp))
.clickable { /* Add resend email functionality */ }
.padding(8.dp)
.background(Color.White)
) {
Text("Logout")
Text(
text = "Edit education information",
color = Color.Black,
modifier = Modifier.padding(2.dp)
)
}

Box(
modifier = Modifier
.fillMaxWidth()
.border(1.dp, Color.Gray, shape = MaterialTheme.shapes.small)
.clip(MaterialTheme.shapes.small)
.padding(16.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp)
) {

Image(
painter = painterResource(id = R.drawable.share_togethe),
contentDescription = null,
modifier = Modifier
.width(250.dp)
.height(130.dp)
.clip(RoundedCornerShape(20.dp))
.align(Alignment.CenterHorizontally)
)

Text("Study together", style = MaterialTheme.typography.titleMedium)
Text("Friends referred: 0", style = MaterialTheme.typography.bodySmall)

Box(
modifier = Modifier
.fillMaxWidth()
.height(38.dp)
.border(1.dp, Color.Gray, shape = RoundedCornerShape(25.dp))
.clip(RoundedCornerShape(25.dp))
.clickable { /* Add share functionality */ }
.background(Color.White)
) {

Text(
text = "Share",
color = Color.Black,
modifier = Modifier
.padding(12.dp)
.align(Alignment.Center)
)
}
}
}

}
}
}
}



@Preview(showBackground = true)
@Composable
fun PreviewProfileScreen() {
ProfileScreen()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package com.pwhs.quickmem.presentation.app.profile

data class ProfileUiState(
val isLoading: Boolean = false,
val error: String = "",
val error: String? = null,

)
Binary file added app/src/main/res/drawable/background_topbar.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/ic_setting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/ic_share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/share_togethe.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit aaeceeb

Please sign in to comment.