Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
eef8f24
[feat] #85: 탑바 추가
t1nm1ksun Sep 12, 2025
7bb3637
[feat] #85: 홈 추가 봉사정보 아이템 구현
t1nm1ksun Sep 12, 2025
8a0511f
[feat] #85: 홈 추가 봉사정보 화면 구현
t1nm1ksun Sep 12, 2025
a21e171
[feat] #85: 홈 추가 화면 프래그먼트 추가
t1nm1ksun Sep 17, 2025
a574ba3
[feat] #85: 홈 추가 화면 네비게이션 그래프 추가
t1nm1ksun Sep 17, 2025
099b75a
[chore] #85: 홈 화면 기관 버튼 리스트 중 병원 제거
t1nm1ksun Sep 17, 2025
cb392e8
[feat] #85: 홈 추가 화면 네비게이션 연결
t1nm1ksun Sep 17, 2025
42b1b91
Merge remote-tracking branch 'origin/develop' into feat-home-extra
t1nm1ksun Sep 17, 2025
2e25834
Merge remote-tracking branch 'origin/feat-home-api' into feat-home-extra
t1nm1ksun Sep 17, 2025
e39da26
resolve confilict
t1nm1ksun Sep 17, 2025
1953ac3
[feat] #85: 홈 추가 화면 분기처리
t1nm1ksun Sep 18, 2025
f9da914
[feat] #85: 홈 추가 화면 (봉사) 구현
t1nm1ksun Sep 21, 2025
026ab03
[feat] #85: 홈 추가 화면 (부서) 구현
t1nm1ksun Sep 21, 2025
e9d0670
[chore] #85: 스트링 포맷 최적화
t1nm1ksun Sep 21, 2025
a5145cd
[chore] #85: 홈 추가 화면 네비게이션 인자 타입 수정
t1nm1ksun Sep 21, 2025
81d83d1
[chore] #85: 탑 바 그림자 제거
t1nm1ksun Sep 22, 2025
4347c36
[feat] #85: 홈 추가 화면 데이터 sealed class 추가
t1nm1ksun Sep 22, 2025
1f2d9e3
[chore] #85: 홈 추가 화면 컴포넌트 아이템 여백 값 수정
t1nm1ksun Sep 22, 2025
967c5db
[feat] #85: 홈 추가 화면 sealed class 적용
t1nm1ksun Sep 22, 2025
8b4fe22
[feat] #85: 클립 보드 복사 기능 추가
t1nm1ksun Sep 22, 2025
b25a0ca
[feat] #85: 보호소, 동물병원 컴포넌트 아이템 구현
t1nm1ksun Sep 22, 2025
3139e0f
[feat] #85: 보호소, 동물병원 뷰 구현
t1nm1ksun Sep 22, 2025
f04aa7f
[chore] #85: 스트링 추출
t1nm1ksun Sep 22, 2025
63c166e
[chore] #85: 미사용 코드 삭제
t1nm1ksun Sep 22, 2025
4917ae0
Merge remote-tracking branch 'origin/develop' into feat-home-extra
t1nm1ksun Sep 22, 2025
4413764
[refactor] #85: 뷰모델 state 값 변경 함수 수정
t1nm1ksun Oct 6, 2025
b13126a
Merge remote-tracking branch 'origin/develop' into feat-home-extra
t1nm1ksun Oct 10, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.findu.domain.model.extra

interface HomeExtraDataType

data class Department(
val name: String,
val district: String,
val phone: String
) : HomeExtraDataType

data class VolunteerWork(
val institution: String,
val recruitmentPeriod: String,
val address: String,
val workPeriod: String,
val workTime: String,
val webLink: String
) : HomeExtraDataType


data class Center(
val jurisdiction: List<String>,
val centerName: String,
val phoneNumber: String,
val address: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.findu.presentation.model

import com.example.findu.domain.model.extra.Center
import com.example.findu.domain.model.extra.Department
import com.example.findu.domain.model.extra.VolunteerWork
sealed interface HomeExtraContent {
data object None : HomeExtraContent
data class Centers(val list: List<Center>) : HomeExtraContent
data class Volunteers(val list: List<VolunteerWork>) : HomeExtraContent
data class Departments(val list: List<Department>) : HomeExtraContent
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.example.findu.R

enum class HomeButtonType(
enum class HomeExtraButtonType(
@DrawableRes val imageRes: Int,
@StringRes val nameRes: Int
) {
PROTECT_CENTER(
imageRes = R.drawable.img_home_protect_center,
nameRes = R.string.home_button_protect_center
),
HOSPITAL(
imageRes = R.drawable.img_home_hospital,
nameRes = R.string.home_button_hospital
),
PROTECT_PART(
PROTECT_DEPARTMENT(
imageRes = R.drawable.img_home_protect_part,
nameRes = R.string.home_button_protect_part
nameRes = R.string.home_button_PROTECT_DEPARTMENT
),
VOLUNTEER(
imageRes = R.drawable.img_home_volunteer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ fun FindUTopAppBar(
) {
Box(
modifier = modifier
.shadow(elevation = 1.dp)
.fillMaxWidth()
.height(56.dp)
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.example.findu.presentation.ui.extra

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.navigation.fragment.findNavController
import com.example.findu.databinding.FragmentHomeExtraBinding
import com.example.findu.presentation.model.HomeExtraContent
import com.example.findu.presentation.type.view.LoadState
import com.example.findu.presentation.ui.extra.view.ExtraHomeCenterScreen
import com.example.findu.presentation.ui.extra.view.ExtraHomeDepartmentScreen
import com.example.findu.presentation.ui.extra.view.ExtraHomeVolunteerScreen
import com.example.findu.presentation.ui.extra.viewmodel.HomeExtraUiEvent
import com.example.findu.presentation.ui.extra.viewmodel.HomeExtraViewModel
import com.example.findu.presentation.ui.home.dialog.HomeFindDialog
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class HomeExtraFragment : Fragment() {
private var _binding: FragmentHomeExtraBinding? = null
private val binding get() = _binding!!
private val homeExtraViewModel by viewModels<HomeExtraViewModel>()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeExtraBinding.inflate(inflater, container, false)
return binding.root
}


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val uiState by homeExtraViewModel.uiState.collectAsStateWithLifecycle()
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(homeExtraViewModel.uiEffect, lifecycleOwner) {
homeExtraViewModel.uiEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect { sideEffect ->
// when (sideEffect) {
//
// }
}
}

LaunchedEffect(uiState.homeExtraButtonType) {
homeExtraViewModel.handleEvent(HomeExtraUiEvent.LoadData)
}




when (uiState.loadState) {
LoadState.Idle -> Unit
LoadState.Loading -> Unit
LoadState.Success -> {
when (val content = uiState.content) {
is HomeExtraContent.Volunteers -> {
ExtraHomeVolunteerScreen(volunteerWorks = content.list)
}

is HomeExtraContent.Departments -> {
ExtraHomeDepartmentScreen(departments = content.list)
}

HomeExtraContent.None -> Unit
is HomeExtraContent.Centers -> {
ExtraHomeCenterScreen(centers = content.list)
}
}
}

LoadState.Error -> Unit
}
}
}
}


private fun showFindDialog() {
val dialog = HomeFindDialog(requireContext(), findNavController())
dialog.show()
}


override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.example.findu.presentation.ui.extra.component

import android.content.Intent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.Divider
import androidx.compose.material.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.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import com.example.findu.R
import com.example.findu.domain.model.extra.Center
import com.example.findu.presentation.ui.base.BaseVectorIcon
import com.example.findu.presentation.util.extension.noRippleClickable
import com.example.findu.ui.theme.FindUTheme

@Composable
fun ExtraCenterItem(
center: Center,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
val intent = Intent(Intent.ACTION_DIAL, "tel:${center.phoneNumber}".toUri())
val clipboardManager = LocalClipboardManager.current


Column(modifier = modifier.padding(top = 20.dp, start = 20.dp, end = 20.dp)) {

Text(
text = center.centerName,
style = FindUTheme.typography.head2SemiBold20,
color = FindUTheme.colors.gray6
)
Spacer(modifier = Modifier.height(5.dp))
center.jurisdiction.forEach {jurisdiction->
Text(
text = jurisdiction,
style = FindUTheme.typography.body1SemiBold16,
color = FindUTheme.colors.gray5
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(
text = "Tel) ${center.phoneNumber} >", modifier = Modifier.noRippleClickable {
context.startActivity(intent)
}, style = FindUTheme.typography.body1Regular16,
color = FindUTheme.colors.blue1
)
Spacer(modifier = Modifier.height(5.dp))

Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = center.centerName,
style = FindUTheme.typography.captionRegular12,
color = FindUTheme.colors.gray6
)
Spacer(modifier = Modifier.width(10.dp))
BaseVectorIcon(
vectorResource = R.drawable.ic_home_extra_copy_15,
modifier = Modifier.noRippleClickable {
clipboardManager.setText(AnnotatedString(center.address))
})
Text(
text = stringResource(R.string.home_extra_copy),
style = FindUTheme.typography.body2Regular14,
color = Color(0xFF00D1CA),
modifier = Modifier.noRippleClickable {
clipboardManager.setText(AnnotatedString(center.address))
}
)
}
Spacer(modifier = Modifier.height(20.dp))
Divider(
modifier = Modifier.fillMaxWidth(),
color = FindUTheme.colors.gray2,
thickness = 1.dp,
)
}
}

@Preview
@Composable
private fun ExtraCenterItemPreview() {
ExtraCenterItem(
center = Center(
jurisdiction = listOf("서울특별시 강남구", "서울특별시 서초구"),
centerName = "한국동물구조관리협회",
phoneNumber = "02-764-3708",
address = "서울특별시 강남구 삼성로 1 삼성빌딩 1층"
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.example.findu.presentation.ui.extra.component

import android.content.Intent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.Divider
import androidx.compose.material.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.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import com.example.findu.R
import com.example.findu.domain.model.extra.Department
import com.example.findu.presentation.ui.base.BaseVectorIcon
import com.example.findu.presentation.util.extension.noRippleClickable
import com.example.findu.ui.theme.FindUTheme

@Composable
fun ExtraDepartmentItem(
department: Department,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
val intent = Intent(Intent.ACTION_DIAL, "tel:${department.phone}".toUri())
val clipboardManager = LocalClipboardManager.current


Column(modifier = modifier.padding(top = 20.dp, start = 20.dp, end = 20.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = department.name,
style = FindUTheme.typography.head2SemiBold20,
color = FindUTheme.colors.gray6
)
Spacer(modifier = Modifier.width(10.dp))
BaseVectorIcon(
vectorResource = R.drawable.ic_home_extra_copy_15,
modifier = Modifier.noRippleClickable {
clipboardManager.setText(AnnotatedString(department.district))
})
Text(
text = stringResource(R.string.home_extra_copy),
style = FindUTheme.typography.body2Regular14,
color = Color(0xFF00D1CA),
modifier = Modifier.noRippleClickable {
clipboardManager.setText(AnnotatedString(department.district))
}
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(
text = "Tel) ${department.phone} >", modifier = Modifier.noRippleClickable {
context.startActivity(intent)
}, style = FindUTheme.typography.body1Regular16,
color = FindUTheme.colors.blue1
)
Spacer(modifier = Modifier.height(5.dp))
Text(
text = department.district,
style = FindUTheme.typography.captionRegular12,
color = FindUTheme.colors.gray5
)
Spacer(modifier = Modifier.height(20.dp))
Divider(
modifier = Modifier.fillMaxWidth(),
color = FindUTheme.colors.gray2,
thickness = 1.dp,
)
}
}

@Preview
@Composable
private fun ExtraDepartmentItemPreview() {
ExtraDepartmentItem(
department = Department(
name = "관광체육과 동물보호팀",
district = "서울특별시 용산구",
phone = "02-1234-1234"
)
)
}
Loading