Skip to content
Merged
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
2 changes: 2 additions & 0 deletions Keychy/Keychy/Core/DesignSystem/Typography/Typography.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct Typography {
static let suit14R18 = Typography(font: .custom(.suitRegular, size: 14), lineSpacing: 4)

/// 13
static let suit13B = Typography(font: .custom(.suitBold, size: 13), lineSpacing: 0)
static let suit13SB = Typography(font: .custom(.suitSemiBold, size: 13), lineSpacing: 0)
static let suit13M = Typography(font: .custom(.suitMedium, size: 13), lineSpacing: 0)

Expand All @@ -65,6 +66,7 @@ struct Typography {
/// 10
static let suit10R = Typography(font: .custom(.suitRegular, size: 10), lineSpacing: 0)
static let suit10SB = Typography(font: .custom(.suitSemiBold, size: 10), lineSpacing: 0)
static let suit10H = Typography(font: .custom(.suitHeavy, size: 10), lineSpacing: 0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우리 앱 폰트 진짜 다양하게 쓰는듯. ㅋㅋ

/// 9
static let suit9B = Typography(font: .custom(.suitBold, size: 9), lineSpacing: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ class CollectionViewModel {
var selectedKeyrings: [Keyring] = []
var hasNetworkError: Bool = false

// MARK: - 탭 토글 (true = 키링, false = 뭉치)
var collectionToggle: Bool = true {
didSet {
// 탭 전환 시 초기화
if !collectionToggle {
// 뭉치 탭으로 전환 시
selectedSort = "최신순"
}
}
}

// Firestore 문서 ID 매핑: 로컬 Keyring(UUID) -> Firestore 문서 ID(String)
var keyringDocumentIdByLocalId: [UUID: String] = [:]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,48 +143,36 @@ extension KeyringEditView {

private var completeToolbarItem: some ToolbarContent {
ToolbarItem(placement: .topBarTrailing) {
if isCompleteEnabled {
Button(role: .confirm, action: {
// 네트워크 체크
guard NetworkManager.shared.isConnected else {
ToastManager.shared.show()
return
}

viewModel.updateKeyring(
keyring: keyring,
name: editedName,
memo: editedMemo,
tags: editedTags
) { success in
if success {
router.reset()
TabBarManager.show()
}
}
}) {
Image(.recCheck)
.resizable()
.renderingMode(.template)
.foregroundStyle(.white100)
.frame(width: 32, height: 32)

Button {
guard isCompleteEnabled else { return }

// 네트워크 체크
guard NetworkManager.shared.isConnected else {
ToastManager.shared.show()
return
}
}
else {
Button(action: {
// disabled
}) {
Image(.recCheck)
.resizable()
.renderingMode(.template)
.foregroundStyle(.gray300)
.frame(width: 32, height: 32)

viewModel.updateKeyring(
keyring: keyring,
name: editedName,
memo: editedMemo,
tags: editedTags
) { success in
if success {
router.reset()
TabBarManager.show()

//TODO: 수정완료 후 pop (데이터 새로고침 로직 추가 예정)
//router.pop()
}
}
.disabled(true)
} label: {
Text("완료")
.typography(.suit17B)
.foregroundStyle(isCompleteEnabled ? .main500 : .gray200)
}

.frame(width: 56, height: 44)
.disabled(!isCompleteEnabled)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ struct CollectionCellView: View {
@State private var isLoading: Bool = true
@State private var cachedImage: UIImage?
@State private var scene: KeyringCellScene?
@State private var rotation: CGFloat = 0.0

// 카드 스타일
private let radius: CGFloat = 10
private let lineWidth: CGFloat = 2

var body: some View {
ZStack {
Expand All @@ -26,14 +31,27 @@ struct CollectionCellView: View {
LoadingAlert(type: .short40, message: nil)
}
}

// NEW 키링 그라데이션 보더
if keyring.isNew {
newKeyringBorder
}

// 비활성 상태 오버레이 (포장중, 출품중)
if let info = keyring.status.overlayInfo {
statusOverlay(info: info)
if let status = keyring.status.overlayInfo {
statusOverlay(status: keyring.status)
}
}
.cornerRadius(radius)
.onAppear {
loadContent()

// NEW 키링의 회전 애니메이션 시작
if keyring.isNew {
withAnimation(.linear(duration: 4).repeatForever(autoreverses: false)) {
rotation = 360
}
}
}
.onDisappear {
if let keyringID = keyring.documentId {
Expand Down Expand Up @@ -65,6 +83,39 @@ struct CollectionCellView: View {
}
}

// MARK: - NEW 키링 그라데이션 보더
private var newKeyringBorder: some View {
ZStack {
// 기본 보더
RoundedRectangle(cornerRadius: radius, style: .continuous)
.strokeBorder(NewIndicatorColor.main, lineWidth: lineWidth)
.overlay {
RoundedRectangle(cornerRadius: radius, style: .continuous)
.stroke(Color.black.opacity(0.25), lineWidth: lineWidth + 2)
.blur(radius: 1)
.mask(
RoundedRectangle(cornerRadius: radius, style: .continuous)
)
}

// 회전하는 그라데이션 보더
AngularGradient(
gradient: Gradient(colors: [
NewIndicatorColor.main,
NewIndicatorColor.light,
NewIndicatorColor.sub,
NewIndicatorColor.main
]),
center: .center,
angle: .degrees(rotation)
)
.mask {
RoundedRectangle(cornerRadius: radius, style: .continuous)
.strokeBorder(lineWidth: lineWidth)
}
}
}

// 컨텐츠 로딩
private func loadContent() {
guard let keyringID = keyring.documentId else {
Expand Down Expand Up @@ -146,13 +197,19 @@ struct CollectionCellView: View {
}

// MARK: - 상태 오버레이
private func statusOverlay(info: String) -> some View {
RoundedRectangle(cornerRadius: 10)
.fill(.black50)
.overlay {
VStack {
Text(info)
.typography(.suit13M)
private func statusOverlay(status: KeyringStatus) -> some View {
ZStack {
// 어두운 배경
RoundedRectangle(cornerRadius: 10)
.fill(.black20)

// 상태별 UI
VStack {
switch status {
case .packaged:
// 포장중: 텍스트만
Text(status.overlayInfo ?? "")
.typography(.suit13B)
.foregroundColor(.white100)
.padding(.vertical, 4)
.frame(maxWidth: .infinity)
Expand All @@ -162,10 +219,35 @@ struct CollectionCellView: View {
.frame(height: 26)
)

Spacer()
case .published:
// 출품중: 그라데이션 카드 디자인
Text(status.overlayInfo ?? "")
.typography(.suit13B)
.foregroundColor(.main500)
.padding(.vertical, 4)
.frame(maxWidth: .infinity)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(LinearGradient(
colors: [.gradient3, .gradient4],
startPoint: .leading,
endPoint: .trailing))
.frame(height: 26)
)
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(.main50, lineWidth:1)
)


default:
EmptyView()
}
.padding(5)

Spacer()
}
.padding(10)
}
}

// MARK: - 위젯 메타데이터 동기화
Expand Down Expand Up @@ -328,3 +410,11 @@ struct CollectionCellView: View {
}
}
}

// MARK: - NewColor 정의
enum NewIndicatorColor {
// Main
static let main = Color(hex: "#A72CFF")
static let light = Color(hex: "#C2FEFF")
static let sub = Color(hex: "#A863FF")
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,28 @@ extension CollectionView {
var alertOverlays: some View {
if let menuCategory = showingMenuFor {
categoryMenuView(menuCategory: menuCategory)
.zIndex(300)
}

if showRenameAlert {
renameAlertOverlay
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
.zIndex(301)
}

if showDeleteAlert || showDeleteCompleteAlert {
deleteAlertOverlay
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
.zIndex(302)
}

if showInvenExpandAlert || showPurchaseSuccessAlert || showPurchaseFailAlert {
invenAlertOverlay
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
.zIndex(303)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ extension CollectionView {
}
}

// 뭉치 데이터 로드
func fetchBundleData() {
let uid = UserManager.shared.userUID
guard !uid.isEmpty else { return }

bundleViewModel.fetchAllBundles(uid: uid) { success in
if !success {
print("뭉치 로드 실패")
}
}
}

// 키링 로드
func fetchUserKeyrings(uid: String) {
collectionViewModel.fetchUserKeyrings(uid: uid) { success in
Expand Down
Loading