Nguyễn Đình Triệu bắt đầu sự nghiệp chuyên nghiệp khi quyết định thôi học lớp 11 để thi tuyển vào đội trẻ CLB Hà Nội T&T. Tại đây, anh được đào tạo bài bản và hai năm sau được gọi vào đội tuyển U-19 Việt Nam chuẩn bị cho Vòng chung kết Giải vô địch bóng đá U-19 châu Á 2010.
Năm 2014, do không tìm được cơ hội chơi bóng chuyên nghiệp và hoàn cảnh gia đình khó khăn, Đình Triệu quyết định tạm dừng sự nghiệp. Anh chuyển vào Vũng Tàu, vừa làm bảo vệ ở một công ty dầu khí, vừa học văn hóa để lấy bằng tốt nghiệp THPT và sau đó thi đỗ Trường Đại học Giao thông vận tải Thành phố Hồ Chí Minh.
Năm 2019, sau những lời động viên của cựu tuyển thủ Nguyễn Minh Phương, Đình Triệu quyết định trở lại thi đấu chuyên nghiệp ở tuổi 28. Anh gia nhập CLB Bình Phước thi đấu tại Giải Hạng nhất quốc gia, đánh dấu sự trở lại của mình với bóng đá chuyên nghiệp.
Năm 2022, Đình Triệu chuyển đến CLB Hải Phòng thi đấu tại V-League. Ngay trong mùa giải đầu tiên, anh đã có những đóng góp quan trọng giúp Hải Phòng giành được danh hiệu á quân V-League 2022.
Đình Triệu từng được triệu tập vào đội tuyển U-19 Việt Nam để chuẩn bị cho Vòng chung kết Giải vô địch bóng đá U-19 châu Á 2010 khi anh còn thi đấu cho đội trẻ Hà Nội T&T.
Năm 2023, ở tuổi 31, Đình Triệu lần đầu được triệu tập lên đội tuyển quốc gia Việt Nam. Đây là một cột mốc đặc biệt trong sự nghiệp của anh khi trở thành một trong những cầu thủ được gọi lên đội tuyển ở độ tuổi muộn nhất.
Tại Giải vô địch bóng đá ASEAN 2024, Đình Triệu được tin tử# src/components/Navbar.jsx
import React from "react";
import { useState } from "react";
import { close, logo, menu } from "../assets";
import { navLinks } from "../constants";
<ul className="list-none sm:flex hidden justify-end items-center flex-1">
{navLinks.map((nav, index) => (
<li
key={nav.id}
className={`font-poppins font-normal cursor-pointer text-[16px] text-white ${
index === navLinks.length - 1 ? "mr-0" : "mr-10"
}`}
>
<a href={`#${nav.id}`}>{nav.title}</a>
</li>
))}
</ul>
<div className="sm:hidden flex flex-1 justify-end items-center">
<img
src={toggle ? close : menu}
alt="menu"
className="w-[28px] h-[28px] object-contain"
onClick={() => setToggle((prev) => !prev)}
/>
<div
className={`${
toggle ? "flex" : "hidden"
} p-6 bg-black-gradient absolute top-20 right-0 mx-4 my-2 min-w-[140px] rounded-xl sidebar`}
>
<ul className="list-none flex flex-col justify-end items-center flex-1">
{navLinks.map((nav, index) => (
<li
key={nav.id}
className={`font-poppins font-normal cursor-pointer text-[16px] text-white ${
index === navLinks.length - 1 ? "mb-0" : "mb-4"
}`}
>
<a href={`#${nav.id}`}>{nav.title}</a>
</li>
))}
</ul>
</div>
</div>
</nav>
);
};
export default Navbar;
# zohairhasan/AI-ML-Projects
README.md
AI & Machine Learning Projects
This repository contains a collection of AI and machine learning projects showcasing various techniques and applications.
Projects
1. Heart Disease Prediction Using Machine Learning
Folder : heart-disease-prediction/
A comprehensive machine learning project that predicts the likelihood of heart disease based on medical indicators.
Key Features :
- Data Preprocessing : Handles missing values, outliers, and feature scaling
- Exploratory Data Analysis : Visualizations and statistical analysis of medical data
- Multiple ML Models : Implements and compares various algorithms:
- Logistic Regression
- Random Forest
- Support Vector Machine (SVM)
- K-Nearest Neighbors (KNN)
- Gradient Boosting
- Model Evaluation : Cross-validation, ROC curves, confusion matrices, and performance metrics
- Feature Importance : Analysis of which medical factors are most predictive
Technologies Used : Python, Scikit-learn, Pandas, NumPy, Matplotlib, Seaborn
Dataset : Cleveland Heart Disease dataset with 14 medical attributes including age, sex, chest pain type, blood pressure, cholesterol levels, and more.
Getting Started
Prerequisites
Python 3.7+
Required packages are listed in each project's requirements.txt
file
Installation
Clone this repository:
bash
git clone https://github.com/yourusername/ai-ml-projects.git
cd ai-ml-projects
Navigate to the specific project folder and install dependencies:
bash
cd heart-disease-prediction
pip install -r requirements.txt
Run the Jupyter notebook or Python scripts as indicated in each project's README.
Repository Structure
ai-ml-projects/
│
├── heart-disease-prediction/
│ ├── data/
│ ├── notebooks/
│ ├── src/
│ ├── requirements.txt
│ └── README.md
│
├── README.md
└── .gitignore
Contributing
Feel free to contribute by:
- Adding new projects
- Improving existing code
- Fixing bugs
- Enhancing documentation
License
This project is licensed under the MIT License - see the LICENSE file for details.
For questions or collaboration opportunities, please reach out through GitHub issues or contact me directly.
# Aman-Singh-Rawat/ECommerceApp
package com.example.ecommerceapp.presentation.screens.home.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.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.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
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.Color
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.ecommerceapp.R
import com.example.ecommerceapp.ui.theme.ECommerceAppTheme
@Composable
fun HomeTopBar(modifier: Modifier = Modifier) {
Card(
modifier = modifier.fillMaxWidth(),
shape = RoundedCornerShape(bottomStart = 16.dp, bottomEnd = 16.dp),
colors = CardDefaults.cardColors(containerColor = Color.Blue)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(R.drawable.profile_pic),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(
text = "Good Morning 👋",
color = Color.White.copy(alpha = 0.8f),
fontSize = 12.sp
)
Text(
text = "Aman Singh",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 16.sp
)
}
}
Box(
modifier = Modifier
.size(40.dp)
.background(
Color.White.copy(alpha = 0.2f),
CircleShape
),
contentAlignment = Alignment.Center
) {
IconButton(onClick = { }) {
Icon(
imageVector = Icons.Default.Notifications,
contentDescription = "Notifications",
tint = Color.White
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.background(
Color.White.copy(alpha = 0.2f),
RoundedCornerShape(12.dp)
)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = "Search",
tint = Color.White.copy(alpha = 0.7f)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "Search any Product..",
color = Color.White.copy(alpha = 0.7f),
fontSize = 14.sp
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun PreviewHomeTopBar() {
ECommerceAppTheme {
HomeTopBar()
}
}End File# Aman-Singh-Rawat/ECommerceApp
app/src/main/java/com/example/ecommerceapp/presentation/screens/home/components/HomeTopBar.kt
package com.example.ecommerceapp.presentation.screens.home.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.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.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
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.Color
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.ecommerceapp.R
import com.example.ecommerceapp.ui.theme.ECommerceAppTheme
@Composable
fun HomeTopBar(
modifier: Modifier = Modifier,
onSearchClick: () -> Unit = {}
) {
Card(
modifier = modifier.fillMaxWidth(),
shape = RoundedCornerShape(bottomStart = 16.dp, bottomEnd = 16.dp),
colors = CardDefaults.cardColors(containerColor = Color.Blue)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
painter = painterResource(R.drawable.profile_pic),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(
text = "Good Morning 👋",
color = Color.White.copy(alpha = 0.8f),
fontSize = 12.sp
)
Text(
text = "Aman Singh",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 16.sp
)
}
}
Box(
modifier = Modifier
.size(40.dp)
.background(
Color.White.copy(alpha = 0.2f),
CircleShape
),
contentAlignment = Alignment.Center
) {
IconButton(onClick = { }) {
Icon(
imageVector = Icons.Default.Notifications,
contentDescription = "Notifications",
tint = Color.White
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.background(
Color.White.copy(alpha = 0.2f),
RoundedCornerShape(12.dp)
)
.clickable { onSearchClick() }
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = "Search",
tint = Color.White.copy(alpha = 0.7f)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "Search any Product..",
color = Color.White.copy(alpha = 0.7f),
fontSize = 14.sp
)
}
}
}
}
@Preview(showBackground = true)
@Composable
fun PreviewHomeTopBar() {
ECommerceAppTheme {
HomeTopBar()
}
}End File# Aman-Singh-Rawat/ECommerceApp
package com.example.ecommerceapp.presentation.screens.productdetails
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.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
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.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.ShoppingCart
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
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.Color
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.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage
import com.example.ecommerceapp.R
import com.example.ecommerceapp.presentation.screens.productdetails.components.ProductImagePager
import com.example.ecommerceapp.ui.theme.ECommerceAppTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProductDetailsScreen(
modifier: Modifier = Modifier,
productId: Int,
onNavigateBack: () -> Unit,
onAddToCart: () -> Unit = {},
viewModel: ProductDetailsViewModel = hiltViewModel()
) {
val state by viewModel.state.collectAsState()
Scaffold(
modifier = modifier.fillMaxSize(),
topBar = {
TopAppBar(
title = { Text("Product Details") },
navigationIcon = {
IconButton(onClick = onNavigateBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back"
)
}
},
actions = {
IconButton(onClick = { viewModel.toggleFavorite() }) {
Icon(
imageVector = if (state.isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription = if (state.isFavorite) "Remove from favorites" else "Add to favorites",
tint = if (state.isFavorite) Color.Red else Color.Gray
)
}
} ```kotlin
)
},
bottomBar = {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Button(
onClick = onAddToCart,
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary
)
) {
Icon(
imageVector = Icons.Default.ShoppingCart,
contentDescription = null,
modifier = Modifier.size(18.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text("Add to Cart")
}
Button(
onClick = { /* Handle buy now */ },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF4CAF50)
)
) {
Text("Buy Now")
}
}
}
) { paddingValues ->
if (state.isLoading) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Loading...")
}
} else if (state.error != null) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = state.error!!,
color = Color.Red
)
}
} else {
state.product?.let { product ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.verticalScroll(rememberScrollState())
) {
// Product Images
ProductImagePager(
images = product.images,
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
)
Spacer(modifier = Modifier.height(16.dp))
// Product Info
Column(
modifier = Modifier.padding(horizontal = 16.dp)
) {
// Title and Brand
Text(
text = product.title,
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = product.brand ?: "Unknown Brand",
fontSize = 16.sp,
color = Color.Gray
)
Spacer(modifier = Modifier.height(12.dp))
// Rating and Reviews
Row(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.Star,
contentDescription = null,
tint = Color(0xFFFFC107),
modifier = Modifier.size(20.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "${product.rating}",
fontSize = 16.sp,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "(${product.reviews?.size ?: 0} reviews)",
fontSize = 14.sp,
color = Color.Gray
)
}
Spacer(modifier = Modifier.height(16.dp))
// Price
Row(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "$${product.price}",
fontSize = 28.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
product.discountPercentage?.let { discount ->
if (discount > 0) {
Spacer(modifier = Modifier.width(12.dp))
val originalPrice = product.price / (1 - discount / 100)
Text(
text = "$${String.format("%.2f", originalPrice)}",
fontSize = 18.sp,
color = Color.Gray,
textDecoration = TextDecoration.LineThrough
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "${discount.toInt()}% OFF",
fontSize = 14.sp,
color = Color.Green,
fontWeight = FontWeight.Bold
)
}
}
}
Spacer(modifier = Modifier.height(20.dp))
// Stock Status
Row(
verticalAlignment = Alignment.CenterVertically
) {
val stockColor = if (product.stock > 10) Color.Green
else if (product.stock > 0) Color.Orange
else Color.Red
Box(
modifier = Modifier
.size(12.dp)
.background(stockColor, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = when {
product.stock > 10 -> "In Stock (${product.stock} available)"
product.stock > 0 -> "Limited Stock (${product.stock} left)"
else -> "Out of Stock"
},
fontSize = 14.sp,
color = stockColor,
fontWeight = FontWeight.Medium
)
}
Spacer(modifier = Modifier.height(24.dp))
// Description
Text(
text = "Description",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = product.description,
fontSize = 16.sp,
lineHeight = 24.sp,
color = Color.Gray
)
Spacer(modifier = Modifier.height(24.dp))
// Specifications
Text(
text = "Specifications",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(12.dp))
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = Color.Gray.copy(alpha = 0.1f)
)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
SpecificationRow("Category", product.category)
SpecificationRow("Brand", product.brand ?: "Unknown")
SpecificationRow("SKU", product.sku ?: "N/A")
SpecificationRow("Weight", "${product.weight ?: 0} kg")
product.dimensions?.let { dimensions ->
SpecificationRow(
"Dimensions",
"${dimensions.width} × ${dimensions.height} × ${dimensions.depth} cm"
)
}
SpecificationRow("Warranty", product.warrantyInformation ?: "N/A")
SpecificationRow("Shipping", product.shippingInformation ?: "N/A")
SpecificationRow("Return Policy", product.returnPolicy ?: "N/A")
}
}
Spacer(modifier = Modifier.height(24.dp))
// Reviews Section
if (!product.reviews.isNullOrEmpty()) {
Text(
text = "Customer Reviews",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(12.dp))
product.reviews.take(3).forEach { review ->
ReviewCard(
review = review,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
}
if (product.reviews.size > 3) {
Text(
text = "View all ${product.reviews.size} reviews",
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.clickable { /* Handle view all reviews */ }
)
}
}
Spacer(modifier = Modifier.height(100.dp)) // Bottom padding for FAB
}
}
}
}
}
}
@Composable
private fun SpecificationRow(
label: String,
value: String,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = label,
fontSize = 14.sp,
color = Color.Gray,
modifier = Modifier.weight(1f)
)
Text(
text = value,
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.weight(1f)
)
}
}
@Composable
private fun ReviewCard(
review: Review,
modifier: Modifier = Modifier
) {
Card(
modifier = modifier,
colors = CardDefaults.cardColors(
containerColor = Color.Gray.copy(alpha = 0.05f)
)
) {
Column(
modifier = Modifier.padding(12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = review.reviewerName,
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.weight(1f))
Row(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Default.Star,
contentDescription = null,
tint = Color(0xFFFFC107),
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "${review.rating}",
fontSize = 14.sp
)
}
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = review.comment,
fontSize = 14.sp,
color = Color.Gray,
lineHeight = 20.sp
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = review.date,
fontSize = 12.sp,
color = Color.Gray
)
}
}
}
@Preview(showBackground = true)
@Composable
fun PreviewProductDetailsScreen() {
ECommerceAppTheme {
ProductDetailsScreen(
productId = 1,
onNavigateBack = {}
)
}
}
```
This completes the ProductDetailsScreen with the following features:
Top App Bar with back navigation and favorite toggle
Product Image Pager for multiple product images
Product Information including:
Title and brand
Rating and reviews count
Price with discount display
Stock status with color-coded indicators
Detailed Description
Specifications Card with product details
Customer Reviews section showing recent reviews
Bottom Action Bar with "Add to Cart" and "Buy Now" buttons
Loading and Error States
The screen uses the ProductDetailsViewModel to manage state and handles user interactions like toggling favorites and adding items to cart.