168 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
//
 | 
						|
//  CharacterDetailGalleryView.swift
 | 
						|
//  SodaLive
 | 
						|
//
 | 
						|
//  Created by klaus on 9/1/25.
 | 
						|
//
 | 
						|
 | 
						|
import SwiftUI
 | 
						|
 | 
						|
struct CharacterDetailGalleryView: View {
 | 
						|
    @StateObject var viewModel = CharacterDetailGalleryViewModel()
 | 
						|
    
 | 
						|
    private let columns = Array(repeating: GridItem(.flexible(), spacing: 2), count: 3)
 | 
						|
    
 | 
						|
    // 갤러리 데이터
 | 
						|
    private let ownedCount: Int = 104
 | 
						|
    private let totalCount: Int = 259
 | 
						|
    
 | 
						|
    // 계산된 속성들
 | 
						|
    private var ownershipPercentage: Int {
 | 
						|
        guard totalCount > 0 else { return 0 }
 | 
						|
        return Int(round(Double(ownedCount) / Double(totalCount) * 100))
 | 
						|
    }
 | 
						|
    
 | 
						|
    private var progressBarWidth: CGFloat {
 | 
						|
        let maxWidth: CGFloat = 352 // 전체 진행률 바의 최대 너비
 | 
						|
        guard totalCount > 0 else { return 0 }
 | 
						|
        let percentage = Double(ownedCount) / Double(totalCount)
 | 
						|
        return maxWidth * percentage
 | 
						|
    }
 | 
						|
    
 | 
						|
    var body: some View {
 | 
						|
        BaseView(isLoading: $viewModel.isLoading) {
 | 
						|
            VStack(spacing: 0) {
 | 
						|
                // 상단 여백 24px
 | 
						|
                Spacer()
 | 
						|
                    .frame(height: 24)
 | 
						|
                
 | 
						|
                // 보유 정보 섹션
 | 
						|
                collectionInfoView()
 | 
						|
                    .padding(.horizontal, 24)
 | 
						|
                    .padding(.bottom, 8)
 | 
						|
                
 | 
						|
                // 갤러리 그리드
 | 
						|
                LazyVGrid(columns: columns, spacing: 2) {
 | 
						|
                    ForEach(0..<4, id: \.self) { index in
 | 
						|
                        galleryImageView(index: index)
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                .padding(.horizontal, 0)
 | 
						|
                
 | 
						|
                Spacer()
 | 
						|
            }
 | 
						|
            .background(Color(hex: "#131313"))
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    @ViewBuilder
 | 
						|
    private func collectionInfoView() -> some View {
 | 
						|
        VStack(spacing: 8) {
 | 
						|
            // 상단 정보 (계산된 % 보유중, 정보 아이콘, 개수)
 | 
						|
            HStack {
 | 
						|
                Text("\(ownershipPercentage)% 보유중")
 | 
						|
                    .font(.custom(Font.preBold.rawValue, size: 18))
 | 
						|
                    .foregroundColor(.white)
 | 
						|
                
 | 
						|
                Spacer()
 | 
						|
            
 | 
						|
                HStack(spacing: 4) {
 | 
						|
                    Text("\(ownedCount)")
 | 
						|
                        .font(.custom(Font.preRegular.rawValue, size: 16))
 | 
						|
                        .foregroundColor(Color(hex: "#FDD453"))
 | 
						|
                    
 | 
						|
                    Text("/")
 | 
						|
                        .font(.custom(Font.preRegular.rawValue, size: 16))
 | 
						|
                        .foregroundColor(.white)
 | 
						|
                    
 | 
						|
                    Text("\(totalCount)개")
 | 
						|
                        .font(.custom(Font.preRegular.rawValue, size: 16))
 | 
						|
                        .foregroundColor(.white)
 | 
						|
                }
 | 
						|
            }
 | 
						|
            
 | 
						|
            // 진행률 바
 | 
						|
            GeometryReader { geometry in
 | 
						|
                ZStack(alignment: .leading) {
 | 
						|
                    // 배경 바
 | 
						|
                    RoundedRectangle(cornerRadius: 999)
 | 
						|
                        .foregroundColor(Color(hex: "#37474F"))
 | 
						|
                        .frame(height: 9)
 | 
						|
                    
 | 
						|
                    // 진행률 바 (계산된 퍼센트)
 | 
						|
                    RoundedRectangle(cornerRadius: 999)
 | 
						|
                        .fill(
 | 
						|
                            LinearGradient(
 | 
						|
                                colors: [Color(hex: "#80D8FF"), Color(hex: "#6D5ED7")],
 | 
						|
                                startPoint: .leading,
 | 
						|
                                endPoint: .trailing
 | 
						|
                            )
 | 
						|
                        )
 | 
						|
                        .frame(width: min(progressBarWidth, geometry.size.width), height: 9)
 | 
						|
                }
 | 
						|
            }
 | 
						|
            .frame(height: 9)
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    @ViewBuilder
 | 
						|
    private func galleryImageView(index: Int) -> some View {
 | 
						|
        ZStack {
 | 
						|
            // 이미지
 | 
						|
            AsyncImage(url: URL(string: "https://picsum.photos/400/500")) { image in
 | 
						|
                image
 | 
						|
                    .resizable()
 | 
						|
                    .aspectRatio(contentMode: .fill)
 | 
						|
            } placeholder: {
 | 
						|
                Rectangle()
 | 
						|
                    .fill(Color.gray.opacity(0.3))
 | 
						|
            }
 | 
						|
            .frame(width: 132, height: 165)
 | 
						|
            .clipped()
 | 
						|
            .cornerRadius(0)
 | 
						|
            
 | 
						|
            // 자물쇠가 있는 이미지들 (index 2, 3)
 | 
						|
            if index >= 2 {
 | 
						|
                // 어두운 오버레이
 | 
						|
                Rectangle()
 | 
						|
                    .fill(Color.black.opacity(0.2))
 | 
						|
                    .frame(width: 132, height: 165)
 | 
						|
                
 | 
						|
                // 자물쇠 아이콘과 코인 정보
 | 
						|
                VStack(spacing: 8) {
 | 
						|
                    // 자물쇠 아이콘
 | 
						|
                    Image("ic_new_lock")
 | 
						|
                        .resizable()
 | 
						|
                        .scaledToFit()
 | 
						|
                        .frame(width: 24)
 | 
						|
                    
 | 
						|
                    // 코인 정보 배경
 | 
						|
                    HStack(spacing: 4) {
 | 
						|
                        Image("ic_can")
 | 
						|
                            .resizable()
 | 
						|
                            .scaledToFit()
 | 
						|
                            .frame(width: 16)
 | 
						|
                        
 | 
						|
                        Text("20")
 | 
						|
                            .font(.custom(Font.preBold.rawValue, size: 16))
 | 
						|
                            .foregroundColor(Color(hex: "#263238"))
 | 
						|
                    }
 | 
						|
                    .padding(.horizontal, 12)
 | 
						|
                    .padding(.vertical, 6)
 | 
						|
                    .background(Color(hex: "#B5E7FA"))
 | 
						|
                    .cornerRadius(30)
 | 
						|
                    .overlay {
 | 
						|
                        RoundedRectangle(cornerRadius: 30)
 | 
						|
                            .strokeBorder(lineWidth: 1)
 | 
						|
                            .foregroundColor(.button)
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#Preview {
 | 
						|
    CharacterDetailGalleryView()
 | 
						|
}
 |