Skip to content

Commit

Permalink
Merge pull request #411 from PermanentOrg/feature/VSP-1354-Redeem-Sto…
Browse files Browse the repository at this point in the history
…rage

VSP-1354 [iOS] Redeem Code screen.
  • Loading branch information
luciancerbu-vsp authored Jan 25, 2024
2 parents aa158cf + 881a426 commit 20efe41
Show file tree
Hide file tree
Showing 90 changed files with 1,518 additions and 612 deletions.
144 changes: 114 additions & 30 deletions Permanent.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

31 changes: 25 additions & 6 deletions Permanent/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import UIKit
import GooglePlaces
import GoogleMaps
import StripeApplePay
import SwiftUI
import KeychainSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand Down Expand Up @@ -84,12 +86,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

case "app":
if url.pathComponents.count >= 3, url.pathComponents[2] == "pr" && url.pathComponents[3] == "manage" {
if rootViewController.isDrawerRootActive {
return navigateFromSharedArchive()
} else {
saveSharedArchiveToken()
return false
if let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
{
if let redeemCode = components.queryItems?.first(where: { $0.name == "promoCode" })?.value {
if let authData = KeychainSwift().getData(SessionKeychainHandler.keychainAuthDataKey),
let session = try? JSONDecoder().decode(PermSession.self, from: authData),
let archiveId = session.selectedArchive?.archiveID,
archiveId != .zero {
let storageViewModel = StateObject(wrappedValue: StorageViewModel(reddemCode: redeemCode))
let storageView = StorageView(viewModel: storageViewModel)

let host = UIHostingController(rootView: storageView)
self.window?.rootViewController?.present(host, animated: true, completion: nil)

return true
}
}
if components.path == "/app/pr/manage" {
if rootViewController.isDrawerRootActive {
return navigateFromSharedArchive()
} else {
saveSharedArchiveToken()
return false
}
}
}
return false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// BottomInfoMessageView.swift
// Permanent
//
// Created by Lucian Cerbu on 10.01.2024.

import SwiftUI

struct BottomInfoMessageView: View {
var alertTextTitle: String
var alertTextDescription: String
var closeAction: (() -> Void)

var body: some View {
ZStack {
Color(.success25)
HStack(alignment: .top) {
Image(.checkmarkGreen)
VStack(alignment: .leading) {
Text(alertTextTitle)
.textStyle(SmallXRegularTextStyle())
.foregroundColor(.blue900)
Text(alertTextDescription)
.textStyle(SmallXXXRegularTextStyle())
.foregroundColor(.blue600)
}
Spacer()
Button(action: closeAction) {
Image(.closeGreen)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 16)
}
.cornerRadius(12)
.frame(height: 80)
.shadow(color: Color(red: 0.07, green: 0.11, blue: 0.29).opacity(0.12), radius: 16, x: 0, y: 24)
.overlay(
RoundedRectangle(cornerRadius: 12)
.inset(by: 0.5)
.stroke(Color(.success200), lineWidth: 1)
)
.padding(.bottom, 24)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// BottomInvalidAlertMessageView.swift
// Permanent
//
// Created by Lucian Cerbu on 21.12.2023.

import SwiftUI

struct BottomInvalidAlertMessageView: View {
var alertTextTitle: String
var alertTextDescription: String
var closeAction: (() -> Void)

var body: some View {
ZStack {
Color(.error25)
HStack(alignment: .top) {
Image(.explanationMarkRed)
VStack(alignment: .leading) {
Text(alertTextTitle)
.textStyle(SmallXRegularTextStyle())
.foregroundColor(.error500)
Text(alertTextDescription)
.textStyle(SmallXXXRegularTextStyle())
.foregroundColor(.blue600)
}
Spacer()
Button(action: closeAction) {
Image(.closeNavigationRed)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 16)
}
.cornerRadius(12)
.frame(height: 80)
.shadow(color: Color(red: 0.07, green: 0.11, blue: 0.29).opacity(0.12), radius: 16, x: 0, y: 24)
.overlay(
RoundedRectangle(cornerRadius: 12)
.inset(by: 0.5)
.stroke(Color(.error200), lineWidth: 1)
)
.padding(.bottom, 24)
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// RoundButtonView.swift
// Permanent
//
// Created by Lucian Cerbu on 18.12.2023.

import SwiftUI

struct RoundButtonView: View {
var isDisabled: Bool
var isLoading: Bool
let text: String
let action: () -> Void

var body: some View {
Button(action: action, label: {
ZStack {
Color(isDisabled ? .blue200 : .blue900)
HStack() {
if isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.frame(width: 10, height: 10)
} else {
Text(text)
.textStyle(RegularSemiBoldTextStyle())
.foregroundColor(.white)
}
}
}
.frame(height: 56)
.cornerRadius(12)
})
.disabled(isDisabled || isLoading)
}
}
46 changes: 46 additions & 0 deletions Permanent/Common/Base/SwiftUIViews/CustomListItemView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// CustomListItemView.swift
// Permanent
//
// Created by Lucian Cerbu on 15.12.2023.

import SwiftUI

struct CustomListItemView: View {
var image: Image
var titleText: String
var descText: String

var body: some View {
VStack {
HStack(alignment: .top, spacing: 24) {
image
.resizable()
.foregroundColor(.blue900)
.scaledToFit()
.frame(width: 24, height: 24)
.padding(.leading, 10)
VStack(alignment: .leading, spacing: 8) {
HStack(spacing: 10) {
Text(titleText)
.textStyle(SmallXSemiBoldTextStyle())
.foregroundColor(.blue900)
if titleText == "Redeem code" {
NewBadgeView()
}
}
Text(descText)
.textStyle(SmallXXXRegularTextStyle())
.foregroundColor(.blue400)
.lineLimit(2)
.multilineTextAlignment(.leading)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.blue400)
.padding(.trailing, 10)
}
.padding(10)
}
}
}
52 changes: 52 additions & 0 deletions Permanent/Common/Base/SwiftUIViews/GradientCustomBarView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// GradientCustomBarView.swift
// Permanent
//
// Created by Lucian Cerbu on 15.12.2023.

import SwiftUI

struct GradientProgressBarView: View {
var value: String
var maxValue: String
var sizeRatio: Double
@State private var redraw = UUID()

var body: some View {
LazyVStack(spacing: 16) {
HStack {
HStack(spacing: 0) {
Text("\(value) ")
.textStyle(SmallXXXSemiBoldTextStyle())
.foregroundColor(.white)
if value.isNotEmpty {
Text("used")
.textStyle(SmallXXXRegularTextStyle())
.foregroundColor(.white)
}
}
Spacer()
Text("\(maxValue)")
.textStyle(SmallXXXSemiBoldTextStyle())
.foregroundColor(.white)
}
.padding(.horizontal)
ProgressView(value: sizeRatio)
.progressViewStyle(CustomBarProgressStyle(color: .white, height: 8, cornerRadius: 3))
.frame(height: 12)
.padding(.horizontal)
.id(redraw)
}
.onChange(of: sizeRatio, perform: { newValue in
updateRedraw()
})
.frame(maxHeight: 72)
.background(Gradient.purpleYellowGradient)
.cornerRadius(12)
.padding(16)
}

func updateRedraw() {
redraw = UUID()
}
}
31 changes: 31 additions & 0 deletions Permanent/Common/Base/SwiftUIViews/NewBadgeView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// NewBadgeView.swift
// Permanent
//
// Created by Lucian Cerbu on 15.12.2023.

import SwiftUI

struct NewBadgeView: View {
var body: some View {
HStack {
if #available(iOS 16, *) {
Text("NEW")
.textStyle(SmallXXXXXSemiBoldTextStyle())
.kerning(1.6)
.multilineTextAlignment(.center)
.foregroundColor(.white)
} else {
Text("NEW")
.textStyle(SmallXXXXXSemiBoldTextStyle())
.multilineTextAlignment(.center)
.foregroundColor(.white)
}
}
.frame(height: 24)
.padding(.horizontal, 8)
.padding(.vertical, 0)
.background(Color(.yellow))
.cornerRadius(20)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// RoundStyledTextFieldView.swift
// Permanent
//
// Created by Lucian Cerbu on 19.12.2023.

import SwiftUI

struct RoundStyledTextFieldView: View {
@Binding var text: String
var placeholderText: String
var invalidField: Bool
var doneAction: (() -> Void)

var body: some View {
ZStack {
Color(.white)
if #available(iOS 16.0, *) {
TextField(placeholderText, text: $text)
.modifier(RegularTextStyle())
.foregroundColor(Color.darkBlue)
.frame(height: 18)
.autocorrectionDisabled(true)
.autocapitalization(.none)
.padding(.horizontal)
.submitLabel(.done)
.onSubmit(doneAction)
} else {
TextField(placeholderText, text: $text, onCommit: doneAction)
.modifier(RegularTextStyle())
.foregroundColor(Color.darkBlue)
.frame(height: 18)
.autocorrectionDisabled(true)
.autocapitalization(.none)
.padding(.horizontal)
}
}
.frame(minHeight: 48, maxHeight: 48, alignment: .leading)
.cornerRadius(12)
.overlay(
RoundedRectangle(cornerRadius: 12)
.inset(by: 0.5)
.stroke(invalidField ? Color.error200 : Color.blue50)
)
}
}
27 changes: 26 additions & 1 deletion Permanent/Common/Constants/Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,32 @@ extension Color {
static var paleOrange = Color("PaleOrange")
static var lightGray = Color("LightGray")
static var lightRed = Color("LightRed")
static var error200 = Color("Error200")
static var error25 = Color(.error25)
static var error200 = Color(.error200)
static var error500 = Color(.error500)
static var barneyPurple = Color(.barneyPurple)
static var liniarBlue = Color(.liniarBlue)
static var blue25 = Color(.blue25)
static var blue50 = Color(.blue50)
static var blue200 = Color(.blue200)
static var blue300 = Color(.blue300)
static var blue400 = Color(.blue400)
static var blue700 = Color(.blue700)
static var blue600 = Color(.blue600)
static var blue900 = Color(.blue900)
static var yellow = Color(.yellow)
static var success25 = Color(.success25)
static var success200 = Color(.success200)
static var success500 = Color(.success500)
}

extension Gradient {
static var purpleYellowGradient = LinearGradient(gradient:
Gradient(colors: [
Color(red: 0.5, green: 0, blue: 0.5),
Color(red: 1, green: 0.6, blue: 0.2)
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
}
Loading

0 comments on commit 20efe41

Please sign in to comment.