Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ dependencies {

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.runtime)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@
<activity
android:name=".presentation.main.MainActivity"
android:exported="false" />
<activity
android:name=".presentation.my.MyActivity"
android:exported="false"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".presentation.my.ModifyInformationActivity"
android:exported="false"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".presentation.my.AnimalAdministerActivity"
android:exported="false"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".presentation.my.MyInformationAdministerActivity"
android:exported="false"
android:windowSoftInputMode="adjustResize" />
</application>

</manifest>
10 changes: 10 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/data/datasource/MyService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package kr.ac.anu.mumu.data.datasource

import kr.ac.anu.mumu.data.model.MyResponse
import retrofit2.http.GET
import retrofit2.http.Path

interface MyService {
@GET("/api/users/profile/{id}")
suspend fun getUserProfile(@Path("id") userId: Int): MyResponse
}
18 changes: 18 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/data/model/MyDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kr.ac.anu.mumu.data.model

import com.google.gson.annotations.SerializedName

data class MyResponse(
val success: Boolean,
val message: String,
val user: MyDto
)

data class MyDto(
@SerializedName("user_id")
val userId: Int,
@SerializedName("login_id")
val loginId: String,
val name: String,
val phone: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package kr.ac.anu.mumu.data.repository

import kr.ac.anu.mumu.data.datasource.MyService
import kr.ac.anu.mumu.domain.model.MyInformation
import kr.ac.anu.mumu.domain.repository.MyRepository
import javax.inject.Inject

class MyRepositoryImpl @Inject constructor(
private val myService: MyService
) : MyRepository {

override suspend fun getUserProfile(userId: Int): Result<MyInformation> {
return try {
val response = myService.getUserProfile(userId)

val myInfo = MyInformation(
id = response.user.loginId,
name = response.user.name,
phone = response.user.phone
)

Result.success(myInfo)

} catch (e: Exception) {
Result.failure(e)
}
}
}
7 changes: 7 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kr.ac.anu.mumu.data.datasource.AuthService
import kr.ac.anu.mumu.data.datasource.JoinService
import kr.ac.anu.mumu.data.datasource.MyService
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton
Expand Down Expand Up @@ -33,4 +34,10 @@ object NetworkModule {
fun provideJoinService(retrofit: Retrofit): JoinService {
return retrofit.create(JoinService::class.java)
}

@Provides
@Singleton
fun provideMyService(retrofit: Retrofit): MyService {
return retrofit.create(MyService::class.java)
}
}
8 changes: 8 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kr.ac.anu.mumu.data.repository.JoinRepositoryImpl
import kr.ac.anu.mumu.data.repository.LoginRepositoryImpl
import kr.ac.anu.mumu.data.repository.MyRepositoryImpl
import kr.ac.anu.mumu.domain.repository.JoinRepository
import kr.ac.anu.mumu.domain.repository.LoginRepository
import kr.ac.anu.mumu.domain.repository.MyRepository
import javax.inject.Singleton

@Module
Expand All @@ -24,4 +26,10 @@ abstract class RepositoryModule {
abstract fun bindJoinRepository(
joinRepositoryImpl: JoinRepositoryImpl
): JoinRepository

@Binds
@Singleton
abstract fun bindMyRepository(
myRepositoryImpl: MyRepositoryImpl
): MyRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package kr.ac.anu.mumu.domain.model

data class MyInformation(
val id: String,
val name: String,
val phone: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package kr.ac.anu.mumu.domain.repository

import kr.ac.anu.mumu.domain.model.MyInformation

interface MyRepository {
suspend fun getUserProfile(userId: Int): Result<MyInformation>
}
14 changes: 14 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/domain/usecase/MyUseCase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kr.ac.anu.mumu.domain.usecase

import kr.ac.anu.mumu.domain.model.MyInformation
import kr.ac.anu.mumu.domain.model.User
import kr.ac.anu.mumu.domain.repository.MyRepository
import javax.inject.Inject

class MyUseCase @Inject constructor(
private val repository: MyRepository
){
suspend operator fun invoke(userId: Int): Result<MyInformation> {
return repository.getUserProfile(userId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package kr.ac.anu.mumu.presentation.my

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import kr.ac.anu.mumu.R

class AnimalAdministerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_animal_administer)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package kr.ac.anu.mumu.presentation.my

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import kr.ac.anu.mumu.R

class ModifyInformationActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_modify_information)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kr.ac.anu.mumu.presentation.my

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kr.ac.anu.mumu.R

class MumuLogoFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_mumu_logo, container, false)
}
}
73 changes: 73 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/presentation/my/MyActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package kr.ac.anu.mumu.presentation.my

import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kr.ac.anu.mumu.R
import kr.ac.anu.mumu.databinding.ActivityMyBinding
import kr.ac.anu.mumu.domain.model.MyInformation
import kr.ac.anu.mumu.presentation.login.LoginUiState
import kotlin.jvm.java

@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
private lateinit var binding: ActivityMyBinding

private val viewModel: MyViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityMyBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
viewModel.getUserProfile(1)

observerViewModel()
nextScreen()
}

private fun nextScreen() {
binding.layoutModifyInformation.setOnClickListener {
val intent = Intent(this, ModifyInformationActivity::class.java)
startActivity(intent)
}
binding.layoutAnimalAdminister.setOnClickListener {
val intent = Intent(this, AnimalAdministerActivity::class.java)
startActivity(intent)
}
binding.tvMyInformationAdminister1.setOnClickListener {
val intent = Intent(this, MyInformationAdministerActivity::class.java)
startActivity(intent)
}
}

private fun observerViewModel() {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
when (state) {
is MyUiState.Success -> {
binding.tvName.text = state.myInfo.name
}
else -> {}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package kr.ac.anu.mumu.presentation.my

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import kr.ac.anu.mumu.R

class MyInformationAdministerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_my_information_administer)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
38 changes: 38 additions & 0 deletions app/src/main/java/kr/ac/anu/mumu/presentation/my/MyViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package kr.ac.anu.mumu.presentation.my

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kr.ac.anu.mumu.domain.model.MyInformation
import kr.ac.anu.mumu.domain.usecase.MyUseCase
import javax.inject.Inject

sealed class MyUiState{
object Init: MyUiState()
object Loading: MyUiState()
data class Success(val myInfo: MyInformation): MyUiState()
data class Error(val message: String): MyUiState()
}
@HiltViewModel
class MyViewModel @Inject constructor(
private var myUseCase: MyUseCase
) : ViewModel() {
private val _uiState = MutableStateFlow<MyUiState>(MyUiState.Init)
val uiState: StateFlow<MyUiState> = _uiState.asStateFlow()

fun getUserProfile(userId: Int) {
viewModelScope.launch {
_uiState.value = MyUiState.Loading
val result = myUseCase(userId)
result.onSuccess { myInfo ->
_uiState.value = MyUiState.Success(myInfo)
}.onFailure { error ->
_uiState.value = MyUiState.Error(error.message ?: "프로필을 불러오는데 실패했습니다.")
}
}
}
}
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/bg_gray200_stroke.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@color/mumugray_200" />
<corners android:radius="@dimen/radius_1" />
<solid android:color="@color/white" />

</shape>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/bg_gray350_stroke.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/mumugray_350" />
<corners android:radius="@dimen/radius_1" />
<solid android:color="@color/white" />

</shape>
Loading