diff --git a/week7/app/src/main/java/com/example/nike/core/designsystem/component/ProductGrid.kt b/week7/app/src/main/java/com/example/nike/core/designsystem/component/ProductGrid.kt new file mode 100644 index 0000000..15096b0 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/core/designsystem/component/ProductGrid.kt @@ -0,0 +1,36 @@ +package com.example.nike.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun ProductGrid( + items: List, + key: (T) -> Any, // T가 ID를 보장하지 않으므로 외부에서 주입 + modifier: Modifier = Modifier, + itemContent: @Composable (T) -> Unit, +) { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = modifier, + contentPadding = PaddingValues( + vertical = 12.dp, + horizontal = 20.dp + ), + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalArrangement = Arrangement.spacedBy(40.dp) + ) { + items( + items, + key = key + ) { item -> + itemContent(item) + } + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/home/HomeScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/home/HomeScreen.kt index 5b9a816..46262b2 100644 --- a/week7/app/src/main/java/com/example/nike/presentation/home/HomeScreen.kt +++ b/week7/app/src/main/java/com/example/nike/presentation/home/HomeScreen.kt @@ -1,23 +1,31 @@ package com.example.nike.presentation.home import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues 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.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.nike.R import com.example.nike.core.designsystem.theme.NikeTheme +import com.example.nike.presentation.home.component.NewestItemCard +import com.example.nike.presentation.home.model.NewestItem @Composable fun HomeRoute( @@ -32,23 +40,42 @@ fun HomeRoute( private fun HomeScreen( modifier: Modifier = Modifier, ) { - Column( + LazyColumn( modifier = modifier .fillMaxSize() .padding( - horizontal = 17.dp, vertical = 50.dp - ) + ), ) { - Text ( - text = "Discover", + item { + TitleSection() + } + + item { + NewestItemCardSection() + } + } +} + +@Composable +private fun TitleSection( + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .padding( + horizontal = 17.dp, + ), + ) { + Text( + text = stringResource(R.string.home_title), color = Color.Black, fontSize = 28.sp, modifier = Modifier.padding(start = 24.dp) ) Spacer(modifier = Modifier.height(10.dp)) - Text ( - text = "9월 4일 목요일", + Text( + text = stringResource(R.string.home_date), color = Color(0xFF767676), fontSize = 16.sp, modifier = Modifier.padding(start = 24.dp) @@ -60,10 +87,72 @@ private fun HomeScreen( modifier = Modifier.fillMaxWidth(), contentScale = ContentScale.FillWidth ) + } +} +@Composable +private fun NewestItemCardSection( + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .padding( + top = 40.dp, + ), + ) { + Text( + text = stringResource(R.string.home_newest_sub_title), + color = Color.Black, + fontSize = 16.sp, + modifier = Modifier.padding( + horizontal = 42.dp + ) + ) + + Spacer(modifier = Modifier.height(12.dp)) + + Text( + text = stringResource(R.string.home_newest_title), + color = Color(0xFF767676), + fontSize = 28.sp, + modifier = Modifier.padding( + horizontal = 42.dp + ) + ) + + Spacer(modifier = Modifier.height(22.dp)) + + LazyRow( + modifier = Modifier + .fillMaxWidth(), + contentPadding = PaddingValues( + horizontal = 42.dp + ), + horizontalArrangement = Arrangement.spacedBy(6.dp) + ) { + items( + items = dummyProducts, + key = { it.id } + ) { product -> + NewestItemCard( + imageRes = product.imageRes, + name = product.name, + price = product.price + ) + } + } } } +// UI 작업용 더미데이터 선언, 추후 이동 +private val dummyProducts = listOf( + NewestItem(1, R.drawable.img_newest_1, "Air Jordan XXXVI", "US$185"), + NewestItem(2, R.drawable.img_newest_2, "Nike Dunk Low", "US$110"), + NewestItem(3, R.drawable.img_newest_3, "Nike Air Max 90", "US$130"), + NewestItem(4, R.drawable.img_newest_4, "Nike Blazer Mid", "US$100"), + NewestItem(5, R.drawable.img_newest_5, "Air Force 1 '07", "US$90"), +) + @Preview(showBackground = true) @Composable private fun HomeScreenPreview() { diff --git a/week7/app/src/main/java/com/example/nike/presentation/home/component/NewestItemCard.kt b/week7/app/src/main/java/com/example/nike/presentation/home/component/NewestItemCard.kt new file mode 100644 index 0000000..6f9dfdd --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/home/component/NewestItemCard.kt @@ -0,0 +1,54 @@ +package com.example.nike.presentation.home.component + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun NewestItemCard ( + @DrawableRes imageRes: Int, + name: String, + price: String, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .width(314.dp), + ) { + Image ( + painter = painterResource(imageRes), + contentDescription = null, + modifier = Modifier + .size(314.dp), + contentScale = ContentScale.Crop + ) + + Spacer(modifier = Modifier.height(20.dp)) + + Text( + text = name, + color = Color.Black, + fontSize = 14.sp + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + text = price, + color = Color(0xFF767676), + fontSize = 14.sp + ) + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/home/model/NewestItem.kt b/week7/app/src/main/java/com/example/nike/presentation/home/model/NewestItem.kt new file mode 100644 index 0000000..f1f4abd --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/home/model/NewestItem.kt @@ -0,0 +1,10 @@ +package com.example.nike.presentation.home.model + +import androidx.annotation.DrawableRes + +data class NewestItem( + val id: Int, + @get:DrawableRes val imageRes: Int, + val name: String, + val price: String, +) \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/PurchaseScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/PurchaseScreen.kt index ee7f455..70018ba 100644 --- a/week7/app/src/main/java/com/example/nike/presentation/purchase/PurchaseScreen.kt +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/PurchaseScreen.kt @@ -1,15 +1,24 @@ package com.example.nike.presentation.purchase -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Text +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.PagerState +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.sp +import com.example.nike.R import com.example.nike.core.designsystem.theme.NikeTheme +import com.example.nike.presentation.purchase.component.PurchaseTabRow +import com.example.nike.presentation.purchase.model.PurchaseCategory +import com.example.nike.presentation.purchase.model.PurchaseItem +import com.example.nike.presentation.purchase.tabscreen.AllTabScreen +import com.example.nike.presentation.purchase.tabscreen.SaleTabScreen +import com.example.nike.presentation.purchase.tabscreen.TopsTabScreen +import kotlinx.coroutines.CoroutineScope @Composable fun PurchaseRoute( @@ -24,18 +33,187 @@ fun PurchaseRoute( private fun PurchaseScreen( modifier: Modifier = Modifier, ) { - Box( - modifier = modifier.fillMaxSize(), - contentAlignment = Alignment.Center, + val pagerState: PagerState = rememberPagerState(pageCount = { 3 }) + val coroutineScope: CoroutineScope = rememberCoroutineScope() + + val products = remember { dummyProducts.shuffled() } + + Column( + modifier = modifier + .fillMaxSize(), ) { - Text( - text = "구매하기 화면", - color = Color.Black, - fontSize = 20.sp - ) + PurchaseTabRow(pagerState, coroutineScope) + + HorizontalPager( + state = pagerState, + modifier = Modifier.fillMaxSize() + ) { page -> + when (page) { + 0 -> AllTabScreen(items = products) + 1 -> TopsTabScreen(items = products) + 2 -> SaleTabScreen(items = products) + } + } } } +// UI 작업용 더미데이터 선언, 추후 이동 +private val dummyProducts = listOf( + PurchaseItem( + 1, + R.drawable.img_top_1, + "Nike Sportswear Club", + "Men's T-Shirt", + 4, + "US$35", + PurchaseCategory.TOPS + ), + PurchaseItem( + 2, + R.drawable.img_top_2, + "Nike Dri-FIT", + "Training T-Shirt", + 3, + "US$40", + PurchaseCategory.TOPS, + isOnSale = true + ), + PurchaseItem( + 3, + R.drawable.img_top_3, + "Nike Air", + "Women's Top", + 5, + "US$45", + PurchaseCategory.TOPS + ), + + PurchaseItem( + 4, + R.drawable.img_socks_1, + "Nike Everyday Plus Cushioned", + "Training Ankle Socks (6 Pairs)", + 5, + "US$10", + PurchaseCategory.SOCKS + ), + PurchaseItem( + 5, + R.drawable.img_socks_2, + "Nike Elite Crew", + "Basketball Socks", + 7, + "US$16", + PurchaseCategory.SOCKS, + isOnSale = true + ), + PurchaseItem( + 6, + R.drawable.img_socks_3, + "Nike Multiplier", + "Running Ankle Socks (2 Pairs)", + 3, + "US$14", + PurchaseCategory.SOCKS + ), + PurchaseItem( + 7, + R.drawable.img_socks_4, + "Nike Spark", + "Lightweight No-Show Socks", + 4, + "US$12", + PurchaseCategory.SOCKS + ), + + PurchaseItem( + 8, + R.drawable.img_shoes_1, + "Nike Air Force 1 '07", + "Women's Shoes", + 5, + "US$115", + PurchaseCategory.SHOES, + isBestSeller = true + ), + PurchaseItem( + 9, + R.drawable.img_shoes_2, + "Air Jordan XXXVI", + "Men's Shoes", + 2, + "US$185", + PurchaseCategory.SHOES, + isBestSeller = true + ), + PurchaseItem( + 10, + R.drawable.img_shoes_3, + "Nike Dunk Low", + "Men's Shoes", + 6, + "US$110", + PurchaseCategory.SHOES, + isOnSale = true + ), + PurchaseItem( + 11, + R.drawable.img_shoes_4, + "Nike Air Max 90", + "Women's Shoes", + 4, + "US$130", + PurchaseCategory.SHOES + ), + PurchaseItem( + 12, + R.drawable.img_shoes_5, + "Nike Blazer Mid '77", + "Men's Shoes", + 3, + "US$100", + PurchaseCategory.SHOES, + isBestSeller = true, + isOnSale = true + ), + PurchaseItem( + 13, + R.drawable.img_shoes_6, + "Nike React Infinity", + "Running Shoes", + 5, + "US$160", + PurchaseCategory.SHOES + ), + PurchaseItem( + 14, + R.drawable.img_shoes_7, + "Nike Pegasus 40", + "Men's Road Shoes", + 4, + "US$130", + PurchaseCategory.SHOES + ), + PurchaseItem( + 15, + R.drawable.img_shoes_8, + "Nike Free RN", + "Women's Running Shoes", + 3, + "US$100", + PurchaseCategory.SHOES + ), + PurchaseItem( + 16, + R.drawable.img_shoes_9, + "Nike Court Vision", + "Men's Shoes", + 2, + "US$80", + PurchaseCategory.SHOES + ), +) + @Preview(showBackground = true) @Composable private fun PurchaseScreenPreview() { diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseItemCard.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseItemCard.kt new file mode 100644 index 0000000..44843b6 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseItemCard.kt @@ -0,0 +1,98 @@ +package com.example.nike.presentation.purchase.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.nike.R +import com.example.nike.presentation.home.model.NewestItem +import com.example.nike.presentation.purchase.model.PurchaseItem + +@Composable +fun PurchaseItemCard( + item: PurchaseItem, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + ) { + Box ( + modifier = Modifier, + ) { + Image ( + painter = painterResource(item.imageRes), + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(1f), + contentScale = ContentScale.Crop + ) + + Icon ( + imageVector = ImageVector.vectorResource(R.drawable.ic_product_like_empty), + contentDescription = null, + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.TopEnd) + .padding(12.dp) + ) + } + + Spacer(modifier = Modifier.height(14.dp)) + + Column ( + modifier = Modifier, + verticalArrangement = Arrangement.spacedBy(5.dp) + ) { + if (item.isBestSeller) { + Text ( + text = stringResource(R.string.purchase_item_best_seller), + color = Color(0xFFFC5100), + fontSize = 14.sp, + ) + } + + Text ( + text = item.name, + color = Color.Black, + fontSize = 14.sp + ) + + Text ( + text = item.subName, + color = Color(0xFF767676), + fontSize = 14.sp + ) + + Text ( + text = stringResource(R.string.purchase_item_colours, item.colours), + color = Color(0xFF767676), + fontSize = 14.sp + ) + + Text ( + text = item.price, + color = Color.Black, + fontSize = 14.sp + ) + } + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseTabRow.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseTabRow.kt new file mode 100644 index 0000000..278d936 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/component/PurchaseTabRow.kt @@ -0,0 +1,73 @@ +package com.example.nike.presentation.purchase.component + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.PagerState +import androidx.compose.material3.ScrollableTabRow +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRow +import androidx.compose.material3.TabRowDefaults +import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.example.nike.R +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +private enum class PurchaseTab( + val titleResId: Int, +) { + ALL(R.string.purchase_tab_all), + TOPS(R.string.purchase_tab_tops), + SALE(R.string.purchase_tab_sale) +} + +@Composable +fun PurchaseTabRow( + pagerState: PagerState, + coroutineScope: CoroutineScope, +) { + ScrollableTabRow ( + selectedTabIndex = pagerState.currentPage, + containerColor = Color.White, + contentColor = Color.Black, + divider = {}, + edgePadding = 9.dp, + indicator = { tabPositions -> + TabRowDefaults.PrimaryIndicator( + modifier = Modifier + .tabIndicatorOffset(tabPositions[pagerState.currentPage]), + width = tabPositions[pagerState.currentPage].width, + height = 2.dp, + color = Color.Black, + ) + } + ) { + PurchaseTab.entries.forEachIndexed { index, tab -> + val isSelected = pagerState.currentPage == index + + Tab( + selected = isSelected, + onClick = { + coroutineScope.launch { + pagerState.animateScrollToPage(index) + } + }, + content = { + Text( + text = stringResource(tab.titleResId), + color = if (isSelected) Color.Black else Color(0xFF767676), + modifier = Modifier + .padding( + vertical = 20.dp, + horizontal = 24.dp + ) + ) + } + ) + } + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/model/PurchaseItem.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/model/PurchaseItem.kt new file mode 100644 index 0000000..e144efa --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/model/PurchaseItem.kt @@ -0,0 +1,17 @@ +package com.example.nike.presentation.purchase.model + +import androidx.annotation.DrawableRes + +enum class PurchaseCategory { TOPS, SOCKS, SHOES } + +data class PurchaseItem( + val id: Int, + @get:DrawableRes val imageRes: Int, + val name: String, + val subName: String, + val colours: Int, + val price: String, + val category: PurchaseCategory, + val isBestSeller: Boolean = false, + val isOnSale: Boolean = false, +) diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/AllTabScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/AllTabScreen.kt new file mode 100644 index 0000000..6b38d21 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/AllTabScreen.kt @@ -0,0 +1,22 @@ +package com.example.nike.presentation.purchase.tabscreen + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.example.nike.core.designsystem.component.ProductGrid +import com.example.nike.presentation.purchase.component.PurchaseItemCard +import com.example.nike.presentation.purchase.model.PurchaseItem + +@Composable +fun AllTabScreen( + items: List, + modifier: Modifier = Modifier, +) { + ProductGrid( + items = items, + key = { it.id }, + modifier = modifier.fillMaxSize() + ) { item -> + PurchaseItemCard(item) + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/SaleTabScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/SaleTabScreen.kt new file mode 100644 index 0000000..0ff5ac4 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/SaleTabScreen.kt @@ -0,0 +1,24 @@ +package com.example.nike.presentation.purchase.tabscreen + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.example.nike.core.designsystem.component.ProductGrid +import com.example.nike.presentation.purchase.component.PurchaseItemCard +import com.example.nike.presentation.purchase.model.PurchaseItem + +@Composable +fun SaleTabScreen( + items: List, + modifier: Modifier = Modifier, +) { + ProductGrid( + items = items.filter { + it.isOnSale + }, + key = { it.id }, + modifier = modifier.fillMaxSize() + ) { item -> + PurchaseItemCard(item) + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/TopsTabScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/TopsTabScreen.kt new file mode 100644 index 0000000..e6c804a --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/purchase/tabscreen/TopsTabScreen.kt @@ -0,0 +1,25 @@ +package com.example.nike.presentation.purchase.tabscreen + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.example.nike.core.designsystem.component.ProductGrid +import com.example.nike.presentation.purchase.component.PurchaseItemCard +import com.example.nike.presentation.purchase.model.PurchaseCategory +import com.example.nike.presentation.purchase.model.PurchaseItem + +@Composable +fun TopsTabScreen( + items: List, + modifier: Modifier = Modifier, +) { + ProductGrid( + items = items.filter { + it.category == PurchaseCategory.TOPS + }, + key = { it.id }, + modifier = modifier.fillMaxSize() + ) { item -> + PurchaseItemCard(item) + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/wishlist/WishlistScreen.kt b/week7/app/src/main/java/com/example/nike/presentation/wishlist/WishlistScreen.kt index af4f6a6..b08c967 100644 --- a/week7/app/src/main/java/com/example/nike/presentation/wishlist/WishlistScreen.kt +++ b/week7/app/src/main/java/com/example/nike/presentation/wishlist/WishlistScreen.kt @@ -1,17 +1,24 @@ package com.example.nike.presentation.wishlist -import androidx.compose.foundation.layout.Box +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.example.nike.R +import com.example.nike.core.designsystem.component.ProductGrid import com.example.nike.core.designsystem.theme.NikeTheme +import com.example.nike.presentation.wishlist.component.WishlistItemCard +import com.example.nike.presentation.wishlist.model.WishlistItem @Composable fun WishlistRoute( @@ -26,16 +33,15 @@ fun WishlistRoute( private fun WishlistScreen( modifier: Modifier = Modifier, ) { - Box( + Column( modifier = modifier .fillMaxSize() .padding( top = 28.dp ), - contentAlignment = Alignment.TopStart ) { Text( - text = "위시리스트", + text = stringResource(R.string.wishlist_title), color = Color.Black, fontSize = 28.sp, modifier = Modifier @@ -44,9 +50,34 @@ private fun WishlistScreen( horizontal = 24.dp ) ) + + Spacer(modifier = Modifier.height(12.dp)) + + ProductGrid( + items = dummyWishlist, + key = { it.id }, + ) { item -> + WishlistItemCard(item) + } } } +// UI 작업용 더미데이터 선언, 추후 이동 +private val dummyWishlist = listOf( + WishlistItem(1, R.drawable.img_shoes_1, "Nike Air Force 1 '07", "Women's Shoes", 5, "US$115"), + WishlistItem( + 2, + R.drawable.img_socks_1, + "Nike Everyday Plus Cushioned", + "Training Ankle Socks (6 Pairs)", + 5, + "US$10" + ), + WishlistItem(3, R.drawable.img_shoes_2, "Air Jordan XXXVI", "Men's Shoes", 2, "US$185"), + WishlistItem(4, R.drawable.img_top_1, "Nike Sportswear Club", "Men's T-Shirt", 4, "US$35"), + WishlistItem(5, R.drawable.img_shoes_3, "Nike Dunk Low", "Men's Shoes", 6, "US$110"), +) + @Preview(showBackground = true) @Composable private fun WishlistScreenPreview() { diff --git a/week7/app/src/main/java/com/example/nike/presentation/wishlist/component/WishlistItemCard.kt b/week7/app/src/main/java/com/example/nike/presentation/wishlist/component/WishlistItemCard.kt new file mode 100644 index 0000000..0e18268 --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/wishlist/component/WishlistItemCard.kt @@ -0,0 +1,70 @@ +package com.example.nike.presentation.wishlist.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.nike.R +import com.example.nike.presentation.wishlist.model.WishlistItem + +@Composable +fun WishlistItemCard( + item: WishlistItem, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + ) { + Image( + painter = painterResource(item.imageRes), + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(1f), + contentScale = ContentScale.Crop + ) + + Spacer(modifier = Modifier.height(14.dp)) + + Column( + modifier = Modifier, + verticalArrangement = Arrangement.spacedBy(5.dp) + ) { + Text( + text = item.name, + color = Color.Black, + fontSize = 14.sp + ) + + Text( + text = item.subName, + color = Color(0xFF767676), + fontSize = 14.sp + ) + + Text( + text = stringResource(R.string.wishlist_item_colours, item.colours), + color = Color(0xFF767676), + fontSize = 14.sp + ) + + Text( + text = item.price, + color = Color.Black, + fontSize = 14.sp + ) + } + } +} \ No newline at end of file diff --git a/week7/app/src/main/java/com/example/nike/presentation/wishlist/model/WishlistItem.kt b/week7/app/src/main/java/com/example/nike/presentation/wishlist/model/WishlistItem.kt new file mode 100644 index 0000000..59e3e6c --- /dev/null +++ b/week7/app/src/main/java/com/example/nike/presentation/wishlist/model/WishlistItem.kt @@ -0,0 +1,12 @@ +package com.example.nike.presentation.wishlist.model + +import androidx.annotation.DrawableRes + +data class WishlistItem( + val id: Int, + @get:DrawableRes val imageRes: Int, + val name: String, + val subName: String, + val colours: Int, + val price: String, +) \ No newline at end of file diff --git a/week7/app/src/main/res/drawable/ic_product_like_empty.xml b/week7/app/src/main/res/drawable/ic_product_like_empty.xml new file mode 100644 index 0000000..5999e01 --- /dev/null +++ b/week7/app/src/main/res/drawable/ic_product_like_empty.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/week7/app/src/main/res/drawable/ic_product_like_filled.xml b/week7/app/src/main/res/drawable/ic_product_like_filled.xml new file mode 100644 index 0000000..6cfe942 --- /dev/null +++ b/week7/app/src/main/res/drawable/ic_product_like_filled.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/week7/app/src/main/res/drawable/img_newest_1.png b/week7/app/src/main/res/drawable/img_newest_1.png new file mode 100644 index 0000000..63fdccc Binary files /dev/null and b/week7/app/src/main/res/drawable/img_newest_1.png differ diff --git a/week7/app/src/main/res/drawable/img_newest_2.png b/week7/app/src/main/res/drawable/img_newest_2.png new file mode 100644 index 0000000..4570edb Binary files /dev/null and b/week7/app/src/main/res/drawable/img_newest_2.png differ diff --git a/week7/app/src/main/res/drawable/img_newest_3.png b/week7/app/src/main/res/drawable/img_newest_3.png new file mode 100644 index 0000000..f10b96a Binary files /dev/null and b/week7/app/src/main/res/drawable/img_newest_3.png differ diff --git a/week7/app/src/main/res/drawable/img_newest_4.png b/week7/app/src/main/res/drawable/img_newest_4.png new file mode 100644 index 0000000..056e61d Binary files /dev/null and b/week7/app/src/main/res/drawable/img_newest_4.png differ diff --git a/week7/app/src/main/res/drawable/img_newest_5.png b/week7/app/src/main/res/drawable/img_newest_5.png new file mode 100644 index 0000000..1f3a757 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_newest_5.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_1.png b/week7/app/src/main/res/drawable/img_shoes_1.png new file mode 100644 index 0000000..94b25d3 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_1.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_2.png b/week7/app/src/main/res/drawable/img_shoes_2.png new file mode 100644 index 0000000..53b6272 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_2.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_3.png b/week7/app/src/main/res/drawable/img_shoes_3.png new file mode 100644 index 0000000..bc53580 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_3.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_4.png b/week7/app/src/main/res/drawable/img_shoes_4.png new file mode 100644 index 0000000..7cdc358 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_4.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_5.png b/week7/app/src/main/res/drawable/img_shoes_5.png new file mode 100644 index 0000000..35989ac Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_5.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_6.png b/week7/app/src/main/res/drawable/img_shoes_6.png new file mode 100644 index 0000000..3321568 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_6.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_7.png b/week7/app/src/main/res/drawable/img_shoes_7.png new file mode 100644 index 0000000..2ff9891 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_7.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_8.png b/week7/app/src/main/res/drawable/img_shoes_8.png new file mode 100644 index 0000000..ab66a80 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_8.png differ diff --git a/week7/app/src/main/res/drawable/img_shoes_9.png b/week7/app/src/main/res/drawable/img_shoes_9.png new file mode 100644 index 0000000..43f7e29 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_shoes_9.png differ diff --git a/week7/app/src/main/res/drawable/img_socks_1.png b/week7/app/src/main/res/drawable/img_socks_1.png new file mode 100644 index 0000000..e87e7e6 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_socks_1.png differ diff --git a/week7/app/src/main/res/drawable/img_socks_2.png b/week7/app/src/main/res/drawable/img_socks_2.png new file mode 100644 index 0000000..473094e Binary files /dev/null and b/week7/app/src/main/res/drawable/img_socks_2.png differ diff --git a/week7/app/src/main/res/drawable/img_socks_3.png b/week7/app/src/main/res/drawable/img_socks_3.png new file mode 100644 index 0000000..f96a8ce Binary files /dev/null and b/week7/app/src/main/res/drawable/img_socks_3.png differ diff --git a/week7/app/src/main/res/drawable/img_socks_4.png b/week7/app/src/main/res/drawable/img_socks_4.png new file mode 100644 index 0000000..5409b86 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_socks_4.png differ diff --git a/week7/app/src/main/res/drawable/img_top_1.png b/week7/app/src/main/res/drawable/img_top_1.png new file mode 100644 index 0000000..4aa2316 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_top_1.png differ diff --git a/week7/app/src/main/res/drawable/img_top_2.png b/week7/app/src/main/res/drawable/img_top_2.png new file mode 100644 index 0000000..64a3096 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_top_2.png differ diff --git a/week7/app/src/main/res/drawable/img_top_3.png b/week7/app/src/main/res/drawable/img_top_3.png new file mode 100644 index 0000000..8fbca33 Binary files /dev/null and b/week7/app/src/main/res/drawable/img_top_3.png differ diff --git a/week7/app/src/main/res/values/strings.xml b/week7/app/src/main/res/values/strings.xml index d9e3fc1..2dca00d 100644 --- a/week7/app/src/main/res/values/strings.xml +++ b/week7/app/src/main/res/values/strings.xml @@ -6,7 +6,21 @@ 위시리스트 장바구니 프로필 + + Discover + 9월 4일 목요일 + "What's new" + 나이키 최신 상품 + + 전체 + Tops&T-Shirts + sale + BestSeller + %d Colours 장바구니가 비어있습니다.\n제품을 추가하면 여기에 표시됩니다. 주문하기 + + 위시리스트 + %d Colours \ No newline at end of file