diff --git a/Nick/Nike_compose/app/build.gradle.kts b/Nick/Nike_compose/app/build.gradle.kts index 104965f2..320b2846 100644 --- a/Nick/Nike_compose/app/build.gradle.kts +++ b/Nick/Nike_compose/app/build.gradle.kts @@ -58,4 +58,7 @@ dependencies { debugImplementation(libs.androidx.compose.ui.test.manifest) implementation("androidx.navigation:navigation-compose:2.9.8") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0") + implementation("io.coil-kt:coil-compose:2.7.0") + implementation("com.squareup.retrofit2:retrofit:2.11.0") + implementation("com.squareup.retrofit2:converter-gson:2.11.0") } \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/AndroidManifest.xml b/Nick/Nike_compose/app/src/main/AndroidManifest.xml index 43641432..5082e780 100644 --- a/Nick/Nike_compose/app/src/main/AndroidManifest.xml +++ b/Nick/Nike_compose/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ - + + diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/MainActivity.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/MainActivity.kt deleted file mode 100644 index fafdad29..00000000 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/MainActivity.kt +++ /dev/null @@ -1,167 +0,0 @@ -package com.clone.nike_compose - -import android.graphics.drawable.Drawable -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material3.Icon -import androidx.compose.material3.NavigationBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.navigation.NavController -import androidx.navigation.NavHost -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.currentBackStackEntryAsState -import androidx.navigation.compose.rememberNavController -import com.clone.nike_compose.ui.cart.CartScreen -import com.clone.nike_compose.ui.home.HomeScreen -import com.clone.nike_compose.ui.profile.ProfileScreen -import com.clone.nike_compose.ui.purchase.PurchaseScreen -import com.clone.nike_compose.ui.theme.Nike_composeTheme -import com.clone.nike_compose.ui.wish.WishScreen -import kotlinx.serialization.Serializable -import kotlinx.serialization.Serializer - -class MainActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - setContent { - MainScreen() - } - } -} - -sealed interface AppDestination { - @Serializable - data object Home: AppDestination - @Serializable - data object Cart: AppDestination - @Serializable - data object Profile: AppDestination - @Serializable - data object Purchase: AppDestination - @Serializable - data object Wish: AppDestination -} - -@Preview(showBackground = true) //미리보기 함수를 따로 만드는 경우도 있다고 함 -@Composable -fun PreviewMainScreen() -{ - Nike_composeTheme { - MainScreen() - } -} - -@Composable -fun MainScreen() { - val navController = rememberNavController() - - Scaffold( - bottomBar = { - BottomBar(navController) - } - ) { padding -> - - NavHost( - navController = navController, - startDestination = AppDestination.Home, - modifier = Modifier.padding(padding) - ) { - composable { - HomeScreen() - } - composable { - CartScreen(moveToPurchase = { navController.navigate(AppDestination.Purchase)}) - } - composable { - WishScreen() - } - composable { - ProfileScreen() - } - composable { - PurchaseScreen() - } - } - } -} - -data class BottomNavItem( - val route: T, - val label: String, - val icon: Int -) - -@Composable -fun BottomBar(navController: NavController) { - val items = listOf( - BottomNavItem( - route = AppDestination.Home, - label = "Home", - icon = R.drawable.icon_housesimple - ), - - BottomNavItem( - route = AppDestination.Purchase, - label = "Search", - icon = R.drawable.icon_listmagnifyingglass - - ), - - BottomNavItem( - route = AppDestination.Wish, - label = "Wish", - icon = R.drawable.icon_heartstraight - ), - - BottomNavItem( - route = AppDestination.Profile, - label = "Profile", - icon = R.drawable.icon_user - ), - - BottomNavItem( - route = AppDestination.Cart, - label = "Cart", - icon = R.drawable.icon_bagsimple - ) - ) - - NavigationBar { - val currentRoute = - navController.currentBackStackEntryAsState() - .value?.destination?.route - - items.forEach { item -> - NavigationBarItem( - selected = currentRoute == item.route::class.qualifiedName, - - onClick = { - navController.navigate(item.route) - }, - icon = { - Icon( - painter = painterResource(item.icon), - contentDescription = null - ) - }, - - label = {Text(item.label)} - ) - } - } -} - diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/NetworkModule.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/NetworkModule.kt new file mode 100644 index 00000000..986db2bb --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/NetworkModule.kt @@ -0,0 +1,14 @@ +package com.clone.nike_compose.core.api + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object NetworkModule { + val api: ReqresApi by lazy { + Retrofit.Builder() + .baseUrl("https://reqres.in/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(ReqresApi::class.java) + } +} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/ReqresApi.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/ReqresApi.kt new file mode 100644 index 00000000..7a994b7f --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/api/ReqresApi.kt @@ -0,0 +1,29 @@ +package com.clone.nike_compose.core.api + +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Query + +data class ReqresUsersResponse( + val page: Int, + val per_page: Int, + val total: Int, + val total_pages: Int, + val data: List +) + +data class UserDto( + val id: Int, + val email: String, + val first_name: String, + val last_name: String, + val avatar: String +) + +interface ReqresApi { + @GET("api/users") + suspend fun getUsers( + @Query("page") page: Int = 1, + @Header("x-api-key") apiKey: String + ): ReqresUsersResponse +} diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/data/Goods.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/data/Goods.kt new file mode 100644 index 00000000..1eaf0438 --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/data/Goods.kt @@ -0,0 +1,11 @@ +package com.clone.nike_compose.core.data + +data class Goods( + val goodsId: Int, + val goodsImgResId: Int, + val goodsName: String, + val category: String, + val numberOfColour: String, + val goodsPrice: String, + var isWished: Boolean +) \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/repository/ProfileRepository.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/repository/ProfileRepository.kt new file mode 100644 index 00000000..c35e74ce --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/core/repository/ProfileRepository.kt @@ -0,0 +1,15 @@ +package com.clone.nike_compose.core.repository + +import com.clone.nike_compose.core.api.ReqresApi +import com.clone.nike_compose.core.api.UserDto + +class ProfileRepository( + private val api: ReqresApi +) { + suspend fun loadUsers(): List { + return api.getUsers( + page = 1, + apiKey = "reqres_08962a9022be4a3499d4dbe5e1bbc482" + ).data + } +} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/cart/CartScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/cart/CartScreen.kt similarity index 86% rename from Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/cart/CartScreen.kt rename to Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/cart/CartScreen.kt index 9e0c931e..6435513a 100644 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/cart/CartScreen.kt +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/cart/CartScreen.kt @@ -1,10 +1,8 @@ -package com.clone.nike_compose.ui.cart +package com.clone.nike_compose.presentation.cart 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.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -21,11 +19,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController -import com.clone.nike_compose.AppDestination import com.clone.nike_compose.R -import com.clone.nike_compose.ui.home.HomeScreen @Preview(showBackground = true) @Composable diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/profile/ProfileScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/detail/DetailScreen.kt similarity index 54% rename from Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/profile/ProfileScreen.kt rename to Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/detail/DetailScreen.kt index 9b37eb20..3f01bd42 100644 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/profile/ProfileScreen.kt +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/detail/DetailScreen.kt @@ -1,18 +1,21 @@ -package com.clone.nike_compose.ui.profile +package com.clone.nike_compose.presentation.detail import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @Preview(showBackground = true) @Composable -fun PreviewProfileScreen() { +fun PreviewDetailScreen() { MaterialTheme { - ProfileScreen() + DetailScreen() } } @Composable -fun ProfileScreen() { +fun DetailScreen( + modifier: Modifier = Modifier +) { } \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/home/HomeScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/home/HomeScreen.kt new file mode 100644 index 00000000..b7d30951 --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/home/HomeScreen.kt @@ -0,0 +1,171 @@ +package com.clone.nike_compose.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.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.clone.nike_compose.R +import com.clone.nike_compose.core.data.Goods + +@Preview(showBackground = true) +@Composable +fun PreviewHomeScreen() { + MaterialTheme { + val sampleGoods = listOf( + Goods( + goodsId = 1, + goodsName = "Nike Air Max", + goodsPrice = "199,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 2, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ) + ) + + HomeScreen(sampleGoods) + } +} + +@Composable +fun HomeScreen( + newGoodsList: List +) { + LazyColumn( + modifier = Modifier + .padding(horizontal = 16.dp), + verticalArrangement = Arrangement.spacedBy(40.dp) + ) { + item { + HomeHeader() + } + + item { + HomeBanner() + } + + item { + HomeGoodsRow(newGoodsList) + } + } +} + +@Composable +fun HomeHeader() { + Column( + modifier = Modifier + .fillMaxWidth() + .padding( + start = 24.dp, + end = 24.dp, + top = 24.dp) + ) { + Text( + text = "Discover", + fontSize = 28.sp + ) + + Text( + text = "9월 4일 목요일", + fontSize = 16.sp + ) + } +} + +@Composable +fun HomeBanner() { + Image( + painter = painterResource(id = R.drawable.image_home_banner), + contentDescription = "홈 배너", + modifier = Modifier + .fillMaxWidth() + .height(500.dp), + contentScale = ContentScale.Crop + ) +} + +@Composable +fun HomeGoodsRow( + newGoodsList: List +) { + Text( + text = "What's new?", + fontSize = 16.sp + ) + + Text( + text = "나이키 최신 상품", + fontSize = 28.sp + ) + + + LazyRow( + modifier = Modifier.padding(top = 22.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + items(newGoodsList) { goods -> + HomeGoodsItem(goods) + } + } +} + + +@Composable +fun HomeGoodsItem( + goods: Goods +) { + Column( + modifier = Modifier.width(314.dp) + ) { + Image( + painter = painterResource(goods.goodsImgResId), + contentDescription = goods.goodsName, + modifier = Modifier + .fillMaxWidth() + .height(314.dp), + contentScale = ContentScale.Crop + ) + + Spacer(modifier = Modifier.height(20.dp)) + + Text( + text = goods.goodsName, + fontSize = 20.sp + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + text = goods.goodsPrice, + fontSize = 18.sp + ) + } +} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/main/MainActivity.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/main/MainActivity.kt new file mode 100644 index 00000000..6705de8c --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/main/MainActivity.kt @@ -0,0 +1,279 @@ +package com.clone.nike_compose.presentation.main + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import com.clone.nike_compose.R +import com.clone.nike_compose.core.data.Goods +import com.clone.nike_compose.presentation.cart.CartScreen +import com.clone.nike_compose.presentation.home.HomeScreen +import com.clone.nike_compose.presentation.profile.ProfileScreen +import com.clone.nike_compose.presentation.purchase.PurchaseScreen +import com.clone.nike_compose.presentation.theme.Nike_composeTheme +import com.clone.nike_compose.presentation.wish.WishScreen +import kotlinx.serialization.Serializable + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + MainScreen() + } + } +} + +val sampleNewGoods = listOf( + Goods( + goodsId = 1, + goodsName = "Jordan XXXVI", + goodsPrice = "US$185", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_jordan_xxxvi + ), + Goods( + goodsId = 2, + goodsName = "Air Force 1", + goodsPrice = "US$115", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_air_force_1 + ) +) + +val sampleGoods = listOf( + Goods( + goodsId = 1, + goodsName = "Nike Everyday Plus Cushioned", + goodsPrice = "US$10", + category = "Training Ankle Socks (6 Pairs)", + numberOfColour = "5 Colours", + isWished = false, + goodsImgResId = R.drawable.image_nike_everyday_plus_cushioned + ), + Goods( + goodsId = 2, + goodsName = "Jordan ENike Air Force 1 '07ssentials", + goodsPrice = "US$115", + category = "Men's shoes", + numberOfColour = "2 Colours", + isWished = false, + goodsImgResId = R.drawable.image_jordan_enike + ), + Goods( + goodsId = 3, + goodsName = "Jordan XXXVI", + goodsPrice = "US$185", + category = "Men's shoes", + numberOfColour = "1 Colour", + isWished = false, + goodsImgResId = R.drawable.image_jordan_xxxvi + ), + Goods( + goodsId = 4, + goodsName = "Air Force 1", + goodsPrice = "US$115", + category = "Men's shoes", + numberOfColour = "2 Colours", + isWished = false, + goodsImgResId = R.drawable.image_air_force_1 + ), + Goods( + goodsId = 5, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 6, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 7, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 8, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ) +) + +sealed interface AppDestination { + @Serializable + data object Home: AppDestination + @Serializable + data object Cart: AppDestination + @Serializable + data object Profile: AppDestination + @Serializable + data object Purchase: AppDestination + @Serializable + data object Wish: AppDestination +} + +@Preview(showBackground = true) //미리보기 함수를 따로 만드는 경우도 있다고 함 +@Composable +fun PreviewMainScreen() +{ + Nike_composeTheme { + MainScreen() + } +} + +@Composable +fun MainScreen() { + var purchaseGoodsList by remember { mutableStateOf(sampleGoods) } + var homeNewGoodsList by remember { mutableStateOf(sampleNewGoods) } + val wishGoodsList = purchaseGoodsList.filter { it.isWished } + + val navController = rememberNavController() + + Scaffold( + bottomBar = { + BottomBar(navController) + } + ) { padding -> + + NavHost( + navController = navController, + startDestination = AppDestination.Home, + modifier = Modifier.padding(padding) + ) { + composable { + HomeScreen(newGoodsList = homeNewGoodsList) + } + composable { + CartScreen(moveToPurchase = { navController.navigate(AppDestination.Purchase)}) + } + composable { + WishScreen(wishGoodsList = wishGoodsList) + } + composable { + ProfileScreen() + } + composable { + PurchaseScreen( + goodsList = purchaseGoodsList, + wishOnClick = { goodsId -> + purchaseGoodsList = purchaseGoodsList.map { goods -> + if (goods.goodsId == goodsId) { + goods.copy(isWished = !goods.isWished) + } else { + goods + } + } + } + ) + } + } + } +} + +data class BottomNavItem( + val route: T, + val label: String, + val icon: Int +) + +@Composable +fun BottomBar(navController: NavController) { + val items = listOf( + BottomNavItem( + route = AppDestination.Home, + label = "Home", + icon = R.drawable.icon_housesimple + ), + + BottomNavItem( + route = AppDestination.Purchase, + label = "Search", + icon = R.drawable.icon_listmagnifyingglass + + ), + + BottomNavItem( + route = AppDestination.Wish, + label = "Wish", + icon = R.drawable.icon_heartstraight + ), + + BottomNavItem( + route = AppDestination.Profile, + label = "Profile", + icon = R.drawable.icon_user + ), + + BottomNavItem( + route = AppDestination.Cart, + label = "Cart", + icon = R.drawable.icon_bagsimple + ) + ) + + NavigationBar { + val currentRoute = + navController.currentBackStackEntryAsState() + .value?.destination?.route + + items.forEach { item -> + NavigationBarItem( + selected = currentRoute == item.route::class.qualifiedName, + + onClick = { + navController.navigate(item.route) + }, + icon = { + Icon( + painter = painterResource(item.icon), + contentDescription = null + ) + }, + + label = {Text(item.label)} + ) + } + } +} + diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileScreen.kt new file mode 100644 index 00000000..8506d8bd --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileScreen.kt @@ -0,0 +1,241 @@ +package com.clone.nike_compose.presentation.profile + +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.PaddingValues +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.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.PageSize +import androidx.compose.foundation.pager.PagerState +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +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.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import coil.compose.AsyncImage +import com.clone.nike_compose.R + +@Preview(showBackground = true) +@Composable +fun PreviewProfileScreen() { + MaterialTheme { + ProfileScreenContent( + profileName = "George Bluth", + profileAvatar = "https://reqres.in/img/faces/1-image.jpg", + following = listOf( + "https://reqres.in/img/faces/2-image.jpg", + "https://reqres.in/img/faces/3-image.jpg", + "https://reqres.in/img/faces/4-image.jpg", + "https://reqres.in/img/faces/5-image.jpg" + ) + ) + } +} + +@Composable +fun ProfileScreen() { + val vm: ProfileViewModel = viewModel() + val state by vm.uiState.collectAsState() + + val profileName = state.profileUser?.let { "${it.first_name} ${it.last_name}" } ?: "닉네임" + val profileAvatar = state.profileUser?.avatar + val followingAvatars = state.following.map { it.avatar } + + ProfileScreenContent( + profileName = profileName, + profileAvatar = profileAvatar, + following = followingAvatars + ) +} + +@Composable +private fun ProfileScreenContent( + profileName: String, + profileAvatar: String?, + following: List +) { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF3F3F3)) + ) { + Surface( + modifier = Modifier.fillMaxWidth(), + color = Color.White + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(vertical = 20.dp) + ) { + if (!profileAvatar.isNullOrBlank()) { + AsyncImage( + model = profileAvatar, + contentDescription = "프로필", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(86.dp) + .clip(CircleShape) + ) + } else { + Box( + modifier = Modifier + .size(86.dp) + .clip(CircleShape) + .background(Color(0xFFD0D0D0)) + ) + } + + Spacer(Modifier.height(14.dp)) + Text( + text = profileName, + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold + ) + Spacer(Modifier.height(14.dp)) + + OutlinedButton( + onClick = {}, + shape = RoundedCornerShape(28.dp), + colors = ButtonDefaults.outlinedButtonColors(contentColor = Color.Black) + ) { + Text("프로필 수정") + } + + Spacer(Modifier.height(18.dp)) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + MidIcon("주문", R.drawable.ic_archive) + MidIcon("패스", R.drawable.ic_identificationcard) + MidIcon("이벤트", R.drawable.ic_calendarblank) + MidIcon("설정", R.drawable.ic_gear) + } + } + } + + Spacer(Modifier.height(8.dp)) + + Surface(color = Color.White, modifier = Modifier.fillMaxWidth()) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Column { + Text("나이키 멤버 혜택", fontWeight = FontWeight.SemiBold) + Text("0개 사용 가능", color = Color.Gray, style = MaterialTheme.typography.bodySmall) + } + Spacer(Modifier.weight(1f)) + Icon( + painter = painterResource(id = R.drawable.ic_arrow_right), + contentDescription = "right arrow", + modifier = Modifier.size(15.dp) + ) + } + } + + Spacer(Modifier.height(8.dp)) + + Surface(color = Color.White, modifier = Modifier.fillMaxWidth()) { + Column(modifier = Modifier.padding(vertical = 14.dp)) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text("팔로잉 (${following.size})", fontWeight = FontWeight.SemiBold) + Spacer(Modifier.weight(1f)) + Text("편집", color = Color.Gray, style = MaterialTheme.typography.bodySmall) + } + + Spacer(Modifier.height(12.dp)) + + val pagerState = rememberPagerState( + initialPage = 0, + pageCount = { following.size } + ) + + HorizontalPager( + state = pagerState, + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(horizontal = 16.dp), + pageSpacing = 8.dp, + pageSize = PageSize.Fixed(82.dp) + ) { page -> + val avatarUrl = following[page] + AsyncImage( + model = avatarUrl, + contentDescription = "following", + contentScale = ContentScale.Crop, + modifier = Modifier + .size(82.dp) + .clip(RoundedCornerShape(2.dp)) + .background(Color(0xFFD0D0D0)) + ) + } + + + } + } + + Surface(color = Color.White, modifier = Modifier.fillMaxWidth()) { + Column( + modifier = Modifier.padding(vertical = 14.dp), + verticalArrangement = Arrangement.Bottom) { + Text( + text = "회원 가입일: 2025년 9월", + color = Color.Gray, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + } + } + } +} + +@Composable +private fun MidIcon(label: String, iconRes: Int) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon( + painter = painterResource(id = iconRes), + contentDescription = label, + tint = Color(0xFF9A9A9A), + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.height(6.dp)) + Text(label, style = MaterialTheme.typography.bodySmall) + } +} + diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileViewModel.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileViewModel.kt new file mode 100644 index 00000000..e34bd4d2 --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/profile/ProfileViewModel.kt @@ -0,0 +1,55 @@ +package com.clone.nike_compose.presentation.profile + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.clone.nike_compose.core.api.NetworkModule +import com.clone.nike_compose.core.api.UserDto +import com.clone.nike_compose.core.repository.ProfileRepository +import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update + +data class ProfileUiState( + val isLoading: Boolean = true, + val profileUser: UserDto? = null, // id=1 + val following: List = emptyList(), + val error: String? = null +) + +class ProfileViewModel : ViewModel() { + private val repo = ProfileRepository(NetworkModule.api) + + private val _uiState = MutableStateFlow(ProfileUiState()) + val uiState: StateFlow = _uiState + + init { + load() + } + + private fun load() { + viewModelScope.launch { + _uiState.update { it.copy(isLoading = true, error = null) } + runCatching { repo.loadUsers() } + .onSuccess { users -> + val p = users.firstOrNull { it.id == 1 } + val f = users.filter { it.id != 1 } + _uiState.update { + it.copy( + isLoading = false, + profileUser = p, + following = f + ) + } + } + .onFailure { e -> + _uiState.update { + it.copy( + isLoading = false, + error = e.message ?: "불러오기 실패" + ) + } + } + } + } +} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/purchase/PurchaseScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/purchase/PurchaseScreen.kt new file mode 100644 index 00000000..423381a9 --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/purchase/PurchaseScreen.kt @@ -0,0 +1,202 @@ +package com.clone.nike_compose.presentation.purchase + +import androidx.compose.foundation.Image +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.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +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.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +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.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.clone.nike_compose.R +import com.clone.nike_compose.core.data.Goods + +@Preview(showBackground = true) +@Composable +fun PreviewPurchaseScreen() { + MaterialTheme { + PurchaseScreen( + goodsList = sampleGoods, + wishOnClick = {}) + } +} + +@Composable +fun PurchaseScreen( + goodsList: List, + wishOnClick: (Int) -> Unit) { + PurchaseGridList( + goodsList = goodsList, + wishOnClick = wishOnClick + ) +} + +@Composable +fun PurchaseGridList( + goodsList: List, + wishOnClick: (Int) -> Unit, +) { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.padding(7.dp) + ) { + items(goodsList) { goods -> + PurchaseGoodsItem( + goods, + wishOnClick + ) + } + } +} + +@Composable +fun PurchaseGoodsItem( + goods: Goods, + wishOnClick: (Int) -> Unit) { + Column { + Box { + Image( + painter = painterResource(goods.goodsImgResId), + contentDescription = goods.goodsName, + modifier = Modifier.size(184.dp) + ) + Image( + painter = painterResource( + if(goods.isWished) { + R.drawable.icon_wish_on + } else { + R.drawable.icon_wish_off + }), + contentDescription = "위시 버튼", + modifier = Modifier + .align(Alignment.TopEnd) + .padding(12.dp) + .size(34.dp) + .clickable { + wishOnClick(goods.goodsId) + } + ) + } + + Column( + verticalArrangement = Arrangement.spacedBy(5.dp), + modifier = Modifier.padding(horizontal = 14.dp) + ) { + Text( + text = goods.goodsName, + fontSize = 14.sp + ) + + Text( + text = goods.category, + fontSize = 14.sp + ) + + Text( + text = goods.numberOfColour, + fontSize = 14.sp + ) + + Text( + text = goods.goodsPrice, + fontSize = 14.sp + ) + + Spacer( + modifier = Modifier.height(41.dp) + ) + } + } +} + +val sampleGoods = listOf( + Goods( + goodsId = 1, + goodsName = "Nike Air Max", + goodsPrice = "199,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 2, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 3, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 4, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 5, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 6, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 7, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 8, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ) +) \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Color.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Color.kt similarity index 83% rename from Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Color.kt rename to Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Color.kt index b8151759..5beeb27c 100644 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Color.kt +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Color.kt @@ -1,4 +1,4 @@ -package com.clone.nike_compose.ui.theme +package com.clone.nike_compose.presentation.theme import androidx.compose.ui.graphics.Color diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Theme.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Theme.kt similarity index 96% rename from Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Theme.kt rename to Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Theme.kt index 0b6503a4..2e77cb31 100644 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Theme.kt +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Theme.kt @@ -1,6 +1,5 @@ -package com.clone.nike_compose.ui.theme +package com.clone.nike_compose.presentation.theme -import android.app.Activity import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Type.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Type.kt similarity index 95% rename from Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Type.kt rename to Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Type.kt index dfcf104a..2658e18f 100644 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/theme/Type.kt +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/theme/Type.kt @@ -1,4 +1,4 @@ -package com.clone.nike_compose.ui.theme +package com.clone.nike_compose.presentation.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/wish/WishScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/wish/WishScreen.kt new file mode 100644 index 00000000..c272e8cd --- /dev/null +++ b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/presentation/wish/WishScreen.kt @@ -0,0 +1,138 @@ +package com.clone.nike_compose.presentation.wish + +import androidx.compose.foundation.Image +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.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +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.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.clone.nike_compose.R +import com.clone.nike_compose.core.data.Goods +import com.clone.nike_compose.presentation.purchase.PurchaseGoodsItem + +@Preview(showBackground = true) +@Composable +fun PreviewWishScreen() { + MaterialTheme { + val sampleGoods = listOf( + Goods( + goodsId = 1, + goodsName = "Nike Air Max", + goodsPrice = "199,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ), + Goods( + goodsId = 2, + goodsName = "Nike Jordan", + goodsPrice = "239,000원", + category = "", + numberOfColour = "", + isWished = false, + goodsImgResId = R.drawable.image_home_banner + ) + ) + + WishScreen(sampleGoods) + } +} + +@Composable +fun WishScreen(wishGoodsList: List) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(vertical = 44.dp), + verticalArrangement = Arrangement.spacedBy(40.dp) + ) { + Text( + text = "위시리스트", + fontSize = 28.sp, + modifier = Modifier.padding(horizontal = 24.dp) + ) + + WishGridList(wishGoodsList) + } +} + +@Composable +fun WishGridList( + wishGoodsList: List +) { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier.padding(7.dp) + ) { + items(wishGoodsList) { goods -> + WishGoodsItem(goods) + } + } +} + +@Composable +fun WishGoodsItem(goods: Goods) { + Column { + Box { + Image( + painter = painterResource(goods.goodsImgResId), + contentDescription = goods.goodsName, + modifier = Modifier.size(184.dp) + ) + Image( + painter = painterResource(R.drawable.icon_wish_on), + contentDescription = "위시 버튼", + modifier = Modifier + .align(Alignment.TopEnd) + .padding(12.dp) + .size(34.dp) + ) + } + + Column( + verticalArrangement = Arrangement.spacedBy(5.dp), + modifier = Modifier.padding(horizontal = 14.dp) + ) { + Text( + text = goods.goodsName, + fontSize = 14.sp + ) + + Text( + text = goods.category, + fontSize = 14.sp + ) + + Text( + text = goods.numberOfColour, + fontSize = 14.sp + ) + + Text( + text = goods.goodsPrice, + fontSize = 14.sp + ) + + Spacer( + modifier = Modifier.height(41.dp) + ) + } + } +} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/home/HomeScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/home/HomeScreen.kt deleted file mode 100644 index 24d90d89..00000000 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/home/HomeScreen.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.clone.nike_compose.ui.home - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column -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.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.clone.nike_compose.R -import com.clone.nike_compose.ui.theme.Nike_composeTheme - -@Preview(showBackground = true) -@Composable -fun PreviewHomeScreen() { - MaterialTheme { - HomeScreen() - } -} - -@Composable -fun HomeScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - Column( - modifier = Modifier - .padding(24.dp) - ) { - Text( - text = "Discover" - ) - Text("9월 4일 목요일") - } - Image( - painter = painterResource(id = R.drawable.image_home_banner), - contentDescription = "홈 배너", - modifier = Modifier - .fillMaxWidth() - .height(500.dp) - ) - } -} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/purchase/PurchaseScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/purchase/PurchaseScreen.kt deleted file mode 100644 index 5130419b..00000000 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/purchase/PurchaseScreen.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.clone.nike_compose.ui.purchase - -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.tooling.preview.Preview - -@Preview(showBackground = true) -@Composable -fun PreviewPurchaseScreen() { - MaterialTheme { - PurchaseScreen() - } -} - -@Composable -fun PurchaseScreen() { - -} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/wish/WishScreen.kt b/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/wish/WishScreen.kt deleted file mode 100644 index 8133574f..00000000 --- a/Nick/Nike_compose/app/src/main/java/com/clone/nike_compose/ui/wish/WishScreen.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.clone.nike_compose.ui.wish - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp - -@Preview(showBackground = true) -@Composable -fun PreviewWishScreen() { - MaterialTheme { - WishScreen() - } -} - -@Composable -fun WishScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 24.dp, vertical = 44.dp) - ) { - Text( - text = "위시리스트" - ) - } -} \ No newline at end of file diff --git a/Nick/Nike_compose/app/src/main/res/drawable/image_jordan_enike.png b/Nick/Nike_compose/app/src/main/res/drawable/image_jordan_enike.png new file mode 100644 index 00000000..fc41659b Binary files /dev/null and b/Nick/Nike_compose/app/src/main/res/drawable/image_jordan_enike.png differ