├── README.md ├── Trackizer.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── CodeForAny.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── Trackizer ├── 3rdParty │ ├── CardStack │ │ └── CardStack.swift │ └── InfiniteWeekView │ │ ├── Models │ │ ├── Week.swift │ │ └── WeekStore.swift │ │ ├── Utils │ │ ├── Enums │ │ │ └── TimeDirection.swift │ │ ├── Extensions │ │ │ ├── Color+Extension.swift │ │ │ ├── Date+Extension.swift │ │ │ └── View+Extension.swift │ │ ├── Shapes │ │ │ └── CornerRadiusShape.swift │ │ └── ViewModifier │ │ │ └── CornerRadiusStyle.swift │ │ └── Views │ │ ├── InfiniteWeekView.swift │ │ └── Week │ │ ├── WeekHeaderView.swift │ │ ├── WeekView.swift │ │ └── WeeksTabView.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Trash.imageset │ │ ├── Contents.json │ │ └── Trash.png │ ├── add.imageset │ │ ├── Contents.json │ │ └── add.png │ ├── app_icon.imageset │ │ ├── Contents.json │ │ └── app_icon.png │ ├── app_logo.imageset │ │ ├── Contents.json │ │ └── app_logo.png │ ├── apple.imageset │ │ ├── Contents.json │ │ └── apple.png │ ├── apple_btn.imageset │ │ ├── Contents.json │ │ └── apple_btn.png │ ├── auto_&_transport.imageset │ │ ├── Contents.json │ │ └── auto_&_transport.png │ ├── back.imageset │ │ ├── Contents.json │ │ └── back.png │ ├── bottom_bar_bg.imageset │ │ ├── Contents.json │ │ └── bottom_bar_bg.png │ ├── budgets.imageset │ │ ├── Contents.json │ │ └── budgets.png │ ├── calendar.imageset │ │ ├── Contents.json │ │ └── calendar.png │ ├── card_blank.imageset │ │ ├── Contents.json │ │ └── card_blank.png │ ├── center_btn.imageset │ │ ├── Contents.json │ │ └── center_btn.png │ ├── chart.imageset │ │ ├── Contents.json │ │ └── chart.png │ ├── creditcards.imageset │ │ ├── Contents.json │ │ └── creditcards.png │ ├── dorp_down.imageset │ │ ├── Contents.json │ │ └── dorp_down.png │ ├── entertainment.imageset │ │ ├── Contents.json │ │ └── entertainment.png │ ├── face_id.imageset │ │ ├── Contents.json │ │ └── face_id.png │ ├── fb.imageset │ │ ├── Contents.json │ │ └── fb.png │ ├── fb_btn.imageset │ │ ├── Contents.json │ │ └── fb_btn.png │ ├── font.imageset │ │ ├── Contents.json │ │ └── font.png │ ├── google.imageset │ │ ├── Contents.json │ │ └── google.png │ ├── google_btn.imageset │ │ ├── Contents.json │ │ └── google_btn.png │ ├── hbo_logo.imageset │ │ ├── Contents.json │ │ └── hbo_logo.png │ ├── home.imageset │ │ ├── Contents.json │ │ └── home.png │ ├── home_bg.imageset │ │ ├── Contents.json │ │ └── home_bg.png │ ├── icloud.imageset │ │ ├── Contents.json │ │ └── icloud.png │ ├── light_theme.imageset │ │ ├── Contents.json │ │ └── light_theme.png │ ├── mastercard_logo.imageset │ │ ├── Contents.json │ │ └── mastercard_logo.png │ ├── minus.imageset │ │ ├── Contents.json │ │ └── minus.png │ ├── money.imageset │ │ ├── Contents.json │ │ └── money.png │ ├── netflix_logo.imageset │ │ ├── Contents.json │ │ └── netflix_logo.png │ ├── next.imageset │ │ ├── Contents.json │ │ └── next.png │ ├── onedrive_logo.imageset │ │ ├── Contents.json │ │ └── onedrive_logo.png │ ├── plus.imageset │ │ ├── Contents.json │ │ └── plus.png │ ├── primary_btn.imageset │ │ ├── Contents.json │ │ └── primary_btn.png │ ├── secodry_btn.imageset │ │ ├── Contents.json │ │ └── secodry_btn.png │ ├── security.imageset │ │ ├── Contents.json │ │ └── security.png │ ├── settings.imageset │ │ ├── Contents.json │ │ └── settings.png │ ├── sorting.imageset │ │ ├── Contents.json │ │ └── sorting.png │ ├── spotify_logo.imageset │ │ ├── Contents.json │ │ └── spotify_logo.png │ ├── u1.imageset │ │ ├── Contents.json │ │ └── u1.png │ ├── welcome_screen.imageset │ │ ├── Contents.json │ │ └── welcome_screen.png │ └── youtube_logo.imageset │ │ ├── Contents.json │ │ └── youtube_logo.png ├── Font │ ├── Inter-Bold.ttf │ ├── Inter-Medium.ttf │ ├── Inter-Regular.ttf │ └── Inter-SemiBold.ttf ├── Info.plist ├── Model │ ├── ArcModel.swift │ ├── BudgetModel.swift │ ├── CreditCardModel.swift │ └── SubscriptionModel.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── TrackizerApp.swift ├── UICommon │ ├── ArcShape.swift │ ├── BudgetRow.swift │ ├── CarouselView.swift │ ├── IconItemRow.swift │ ├── IconItemSwitchRow.swift │ ├── ItemRow.swift │ ├── PrimaryButton.swift │ ├── RoundTextField.swift │ ├── SecondaryButton.swift │ ├── SegmentButton.swift │ ├── StatusButton.swift │ ├── SubScriptionHomeRow.swift │ ├── SubscriptionCell.swift │ ├── UIExtension.swift │ └── UpcomingBillRow.swift ├── View │ ├── AddSubscription │ │ └── AddSubscruiptionView.swift │ ├── Budgets │ │ └── BudgetsView.swift │ ├── Calendar │ │ └── CalendarView.swift │ ├── Card │ │ └── CardsView.swift │ ├── Home │ │ └── HomeView.swift │ ├── Login │ │ ├── SignInView.swift │ │ ├── SignUpView.swift │ │ ├── SocialSignupView.swift │ │ └── WelcomView.swift │ ├── MainTab │ │ └── MainTabView.swift │ ├── Settings │ │ └── SettingsView.swift │ └── SubscriptionInfo │ │ └── SubscriptionInfoView.swift └── ViewModel │ └── UIStateModel.swift ├── TrackizerTests └── TrackizerTests.swift └── TrackizerUITests ├── TrackizerUITests.swift └── TrackizerUITestsLaunchTests.swift /README.md: -------------------------------------------------------------------------------- 1 | # Monthly Expenses Trackizer App UI UX Design Convent Into Native iOS SwiftUI Code 2 | 3 | # codeforany @codeforany 4 | 5 | - [Youtube Full Playlist: Monthly Expenses App UI UX Design Convent Into SwiftUI Code](https://www.youtube.com/playlist?list=PLzcRC7PA0xWSMzFDkfF6TGKrOw7DlUEA3) 6 | - [Youtube Channel: @codeforany](https://www.youtube.com/channel/UCdQTp9wRK5vAOlEQZf9PHSg) 7 | - [Youtube Channel Subscribe: @codeforany](https://www.youtube.com/channel/UCdQTp9wRK5vAOlEQZf9PHSg?sub_confirmation=1) 8 | 9 | - [Youtube Video Part-1: App Induction, Sign Up Flow UI](https://youtu.be/3YZJBKnlfGM) 10 | - [Youtube Video Part-2: Bottom TabView UI, Home Tab UI](https://youtu.be/8BGwHm6yxX4) 11 | - [Youtube Video Part-3: Spending Budgets Tab UI](https://youtu.be/C7VKLsRFVec) 12 | - [Youtube Video Part-4: Subscription Schedule Calendar Tab UI](https://youtu.be/ObFt9t1t7EA) 13 | - [Youtube Video Part-5: Add New Subscription UI](https://youtu.be/ir-VtpArd7s) 14 | - [Youtube Video Part-6: Subscription Info Details Screen UI](https://youtu.be/oTRJN5jVEgc) 15 | - [Youtube Video Part-7: App Settings Screen UI](https://youtu.be/hYIEU_xhUq4) 16 | - [Youtube Video Part-8: Add Credit Cards Tab UI](https://youtu.be/cbrIYTrqXgQ) 17 | 18 | UI UX App Design by: [symu.co](https://symu.co/) 19 | -------------------------------------------------------------------------------- /Trackizer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CB1A67712A5D9817007E34C4 /* TrackizerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67702A5D9817007E34C4 /* TrackizerApp.swift */; }; 11 | CB1A67752A5D981B007E34C4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67742A5D981B007E34C4 /* Assets.xcassets */; }; 12 | CB1A67782A5D981B007E34C4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67772A5D981B007E34C4 /* Preview Assets.xcassets */; }; 13 | CB1A67822A5D981C007E34C4 /* TrackizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67812A5D981C007E34C4 /* TrackizerTests.swift */; }; 14 | CB1A678C2A5D981C007E34C4 /* TrackizerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A678B2A5D981C007E34C4 /* TrackizerUITests.swift */; }; 15 | CB1A678E2A5D981C007E34C4 /* TrackizerUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A678D2A5D981C007E34C4 /* TrackizerUITestsLaunchTests.swift */; }; 16 | CB1A67A72A5D98E9007E34C4 /* Inter-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67A32A5D98E7007E34C4 /* Inter-Medium.ttf */; }; 17 | CB1A67A82A5D98E9007E34C4 /* Inter-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67A42A5D98E8007E34C4 /* Inter-SemiBold.ttf */; }; 18 | CB1A67A92A5D98E9007E34C4 /* Inter-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67A52A5D98E8007E34C4 /* Inter-Bold.ttf */; }; 19 | CB1A67AA2A5D98E9007E34C4 /* Inter-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CB1A67A62A5D98E9007E34C4 /* Inter-Regular.ttf */; }; 20 | CB1A67AD2A5D9941007E34C4 /* UIExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67AC2A5D9941007E34C4 /* UIExtension.swift */; }; 21 | CB1A67AF2A5D9D19007E34C4 /* WelcomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67AE2A5D9D19007E34C4 /* WelcomView.swift */; }; 22 | CB1A67B12A5DA21E007E34C4 /* PrimaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67B02A5DA21E007E34C4 /* PrimaryButton.swift */; }; 23 | CB1A67B32A5DA30B007E34C4 /* SecondaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67B22A5DA30B007E34C4 /* SecondaryButton.swift */; }; 24 | CB1A67B52A5DA3E5007E34C4 /* SocialSignupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67B42A5DA3E5007E34C4 /* SocialSignupView.swift */; }; 25 | CB1A67B72A5DA660007E34C4 /* SignUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67B62A5DA660007E34C4 /* SignUpView.swift */; }; 26 | CB1A67B92A5DA9E4007E34C4 /* RoundTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67B82A5DA9E4007E34C4 /* RoundTextField.swift */; }; 27 | CB1A67BB2A5DABA7007E34C4 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A67BA2A5DABA7007E34C4 /* SignInView.swift */; }; 28 | CB2363AE2A62DD7D00DA3548 /* AddSubscruiptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB2363AD2A62DD7D00DA3548 /* AddSubscruiptionView.swift */; }; 29 | CB2363B02A62E25600DA3548 /* UIStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB2363AF2A62E25600DA3548 /* UIStateModel.swift */; }; 30 | CB2363B42A62E2BF00DA3548 /* CarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB2363B32A62E2BF00DA3548 /* CarouselView.swift */; }; 31 | CB9A32E52A63A83C00D952FE /* SubscriptionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9A32E42A63A83C00D952FE /* SubscriptionInfoView.swift */; }; 32 | CB9A32E72A63AD1800D952FE /* ItemRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9A32E62A63AD1800D952FE /* ItemRow.swift */; }; 33 | CB9A32EA2A63C2EC00D952FE /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9A32E92A63C2EC00D952FE /* SettingsView.swift */; }; 34 | CB9A32EC2A63C59500D952FE /* IconItemRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9A32EB2A63C59500D952FE /* IconItemRow.swift */; }; 35 | CB9A32EE2A63C65F00D952FE /* IconItemSwitchRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9A32ED2A63C65F00D952FE /* IconItemSwitchRow.swift */; }; 36 | CBB865152A67060500B564D8 /* CardsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBB865142A67060500B564D8 /* CardsView.swift */; }; 37 | CBB865182A6706A100B564D8 /* CardStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBB865172A6706A100B564D8 /* CardStack.swift */; }; 38 | CBB8651A2A6706CB00B564D8 /* CreditCardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBB865192A6706CB00B564D8 /* CreditCardModel.swift */; }; 39 | CBC743182A5F245500C502BF /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC743172A5F245500C502BF /* MainTabView.swift */; }; 40 | CBC7431A2A5F281000C502BF /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC743192A5F281000C502BF /* HomeView.swift */; }; 41 | CBC7431C2A5F2ABC00C502BF /* SegmentButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC7431B2A5F2ABC00C502BF /* SegmentButton.swift */; }; 42 | CBC7431E2A5F2BCD00C502BF /* SubscriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC7431D2A5F2BCD00C502BF /* SubscriptionModel.swift */; }; 43 | CBC743202A5F303000C502BF /* SubScriptionHomeRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC7431F2A5F303000C502BF /* SubScriptionHomeRow.swift */; }; 44 | CBC743222A5F309900C502BF /* UpcomingBillRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC743212A5F309900C502BF /* UpcomingBillRow.swift */; }; 45 | CBC743242A5F328C00C502BF /* StatusButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC743232A5F328C00C502BF /* StatusButton.swift */; }; 46 | CBC743262A5F35B200C502BF /* ArcShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC743252A5F35B200C502BF /* ArcShape.swift */; }; 47 | CBC93D9A2A60757600D32911 /* BudgetsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC93D992A60757600D32911 /* BudgetsView.swift */; }; 48 | CBC93D9C2A6075A000D32911 /* BudgetModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC93D9B2A6075A000D32911 /* BudgetModel.swift */; }; 49 | CBC93D9E2A60782300D32911 /* BudgetRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC93D9D2A60782300D32911 /* BudgetRow.swift */; }; 50 | CBC93DA02A60805400D32911 /* ArcModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC93D9F2A60805400D32911 /* ArcModel.swift */; }; 51 | CBE289CA2A61D6C90086864C /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289C92A61D6C90086864C /* CalendarView.swift */; }; 52 | CBE289CC2A61D7990086864C /* SubscriptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289CB2A61D7990086864C /* SubscriptionCell.swift */; }; 53 | CBE289E32A61DB4D0086864C /* CornerRadiusStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D12A61DB440086864C /* CornerRadiusStyle.swift */; }; 54 | CBE289E42A61DB4D0086864C /* TimeDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D32A61DB440086864C /* TimeDirection.swift */; }; 55 | CBE289E52A61DB4D0086864C /* CornerRadiusShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D52A61DB440086864C /* CornerRadiusShape.swift */; }; 56 | CBE289E62A61DB4D0086864C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D72A61DB440086864C /* Date+Extension.swift */; }; 57 | CBE289E72A61DB4D0086864C /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D82A61DB440086864C /* Color+Extension.swift */; }; 58 | CBE289E82A61DB4D0086864C /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289D92A61DB440086864C /* View+Extension.swift */; }; 59 | CBE289E92A61DB4D0086864C /* WeeksTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289DC2A61DB450086864C /* WeeksTabView.swift */; }; 60 | CBE289EA2A61DB4D0086864C /* WeekHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289DD2A61DB450086864C /* WeekHeaderView.swift */; }; 61 | CBE289EB2A61DB4D0086864C /* WeekView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289DE2A61DB450086864C /* WeekView.swift */; }; 62 | CBE289EC2A61DB4D0086864C /* InfiniteWeekView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289DF2A61DB450086864C /* InfiniteWeekView.swift */; }; 63 | CBE289ED2A61DB4D0086864C /* WeekStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289E12A61DB4D0086864C /* WeekStore.swift */; }; 64 | CBE289EE2A61DB4D0086864C /* Week.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE289E22A61DB4D0086864C /* Week.swift */; }; 65 | /* End PBXBuildFile section */ 66 | 67 | /* Begin PBXContainerItemProxy section */ 68 | CB1A677E2A5D981C007E34C4 /* PBXContainerItemProxy */ = { 69 | isa = PBXContainerItemProxy; 70 | containerPortal = CB1A67652A5D9817007E34C4 /* Project object */; 71 | proxyType = 1; 72 | remoteGlobalIDString = CB1A676C2A5D9817007E34C4; 73 | remoteInfo = Trackizer; 74 | }; 75 | CB1A67882A5D981C007E34C4 /* PBXContainerItemProxy */ = { 76 | isa = PBXContainerItemProxy; 77 | containerPortal = CB1A67652A5D9817007E34C4 /* Project object */; 78 | proxyType = 1; 79 | remoteGlobalIDString = CB1A676C2A5D9817007E34C4; 80 | remoteInfo = Trackizer; 81 | }; 82 | /* End PBXContainerItemProxy section */ 83 | 84 | /* Begin PBXFileReference section */ 85 | CB1A676D2A5D9817007E34C4 /* Trackizer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Trackizer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | CB1A67702A5D9817007E34C4 /* TrackizerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackizerApp.swift; sourceTree = ""; }; 87 | CB1A67742A5D981B007E34C4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 88 | CB1A67772A5D981B007E34C4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 89 | CB1A677D2A5D981C007E34C4 /* TrackizerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrackizerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | CB1A67812A5D981C007E34C4 /* TrackizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackizerTests.swift; sourceTree = ""; }; 91 | CB1A67872A5D981C007E34C4 /* TrackizerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrackizerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 92 | CB1A678B2A5D981C007E34C4 /* TrackizerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackizerUITests.swift; sourceTree = ""; }; 93 | CB1A678D2A5D981C007E34C4 /* TrackizerUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackizerUITestsLaunchTests.swift; sourceTree = ""; }; 94 | CB1A67A32A5D98E7007E34C4 /* Inter-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-Medium.ttf"; sourceTree = ""; }; 95 | CB1A67A42A5D98E8007E34C4 /* Inter-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-SemiBold.ttf"; sourceTree = ""; }; 96 | CB1A67A52A5D98E8007E34C4 /* Inter-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-Bold.ttf"; sourceTree = ""; }; 97 | CB1A67A62A5D98E9007E34C4 /* Inter-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-Regular.ttf"; sourceTree = ""; }; 98 | CB1A67AB2A5D98F8007E34C4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 99 | CB1A67AC2A5D9941007E34C4 /* UIExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIExtension.swift; sourceTree = ""; }; 100 | CB1A67AE2A5D9D19007E34C4 /* WelcomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomView.swift; sourceTree = ""; }; 101 | CB1A67B02A5DA21E007E34C4 /* PrimaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryButton.swift; sourceTree = ""; }; 102 | CB1A67B22A5DA30B007E34C4 /* SecondaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondaryButton.swift; sourceTree = ""; }; 103 | CB1A67B42A5DA3E5007E34C4 /* SocialSignupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialSignupView.swift; sourceTree = ""; }; 104 | CB1A67B62A5DA660007E34C4 /* SignUpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpView.swift; sourceTree = ""; }; 105 | CB1A67B82A5DA9E4007E34C4 /* RoundTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundTextField.swift; sourceTree = ""; }; 106 | CB1A67BA2A5DABA7007E34C4 /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; 107 | CB2363AD2A62DD7D00DA3548 /* AddSubscruiptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSubscruiptionView.swift; sourceTree = ""; }; 108 | CB2363AF2A62E25600DA3548 /* UIStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStateModel.swift; sourceTree = ""; }; 109 | CB2363B32A62E2BF00DA3548 /* CarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselView.swift; sourceTree = ""; }; 110 | CB9A32E42A63A83C00D952FE /* SubscriptionInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionInfoView.swift; sourceTree = ""; }; 111 | CB9A32E62A63AD1800D952FE /* ItemRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemRow.swift; sourceTree = ""; }; 112 | CB9A32E92A63C2EC00D952FE /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 113 | CB9A32EB2A63C59500D952FE /* IconItemRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconItemRow.swift; sourceTree = ""; }; 114 | CB9A32ED2A63C65F00D952FE /* IconItemSwitchRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconItemSwitchRow.swift; sourceTree = ""; }; 115 | CBB865142A67060500B564D8 /* CardsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardsView.swift; sourceTree = ""; }; 116 | CBB865172A6706A100B564D8 /* CardStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardStack.swift; sourceTree = ""; }; 117 | CBB865192A6706CB00B564D8 /* CreditCardModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditCardModel.swift; sourceTree = ""; }; 118 | CBC743172A5F245500C502BF /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 119 | CBC743192A5F281000C502BF /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; 120 | CBC7431B2A5F2ABC00C502BF /* SegmentButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentButton.swift; sourceTree = ""; }; 121 | CBC7431D2A5F2BCD00C502BF /* SubscriptionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionModel.swift; sourceTree = ""; }; 122 | CBC7431F2A5F303000C502BF /* SubScriptionHomeRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubScriptionHomeRow.swift; sourceTree = ""; }; 123 | CBC743212A5F309900C502BF /* UpcomingBillRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpcomingBillRow.swift; sourceTree = ""; }; 124 | CBC743232A5F328C00C502BF /* StatusButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusButton.swift; sourceTree = ""; }; 125 | CBC743252A5F35B200C502BF /* ArcShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArcShape.swift; sourceTree = ""; }; 126 | CBC93D992A60757600D32911 /* BudgetsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetsView.swift; sourceTree = ""; }; 127 | CBC93D9B2A6075A000D32911 /* BudgetModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetModel.swift; sourceTree = ""; }; 128 | CBC93D9D2A60782300D32911 /* BudgetRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetRow.swift; sourceTree = ""; }; 129 | CBC93D9F2A60805400D32911 /* ArcModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArcModel.swift; sourceTree = ""; }; 130 | CBE289C92A61D6C90086864C /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = ""; }; 131 | CBE289CB2A61D7990086864C /* SubscriptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionCell.swift; sourceTree = ""; }; 132 | CBE289D12A61DB440086864C /* CornerRadiusStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CornerRadiusStyle.swift; sourceTree = ""; }; 133 | CBE289D32A61DB440086864C /* TimeDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeDirection.swift; sourceTree = ""; }; 134 | CBE289D52A61DB440086864C /* CornerRadiusShape.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CornerRadiusShape.swift; sourceTree = ""; }; 135 | CBE289D72A61DB440086864C /* Date+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Extension.swift"; sourceTree = ""; }; 136 | CBE289D82A61DB440086864C /* Color+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; 137 | CBE289D92A61DB440086864C /* View+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = ""; }; 138 | CBE289DC2A61DB450086864C /* WeeksTabView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeeksTabView.swift; sourceTree = ""; }; 139 | CBE289DD2A61DB450086864C /* WeekHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeekHeaderView.swift; sourceTree = ""; }; 140 | CBE289DE2A61DB450086864C /* WeekView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeekView.swift; sourceTree = ""; }; 141 | CBE289DF2A61DB450086864C /* InfiniteWeekView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfiniteWeekView.swift; sourceTree = ""; }; 142 | CBE289E12A61DB4D0086864C /* WeekStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeekStore.swift; sourceTree = ""; }; 143 | CBE289E22A61DB4D0086864C /* Week.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Week.swift; sourceTree = ""; }; 144 | /* End PBXFileReference section */ 145 | 146 | /* Begin PBXFrameworksBuildPhase section */ 147 | CB1A676A2A5D9817007E34C4 /* Frameworks */ = { 148 | isa = PBXFrameworksBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | CB1A677A2A5D981C007E34C4 /* Frameworks */ = { 155 | isa = PBXFrameworksBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | CB1A67842A5D981C007E34C4 /* Frameworks */ = { 162 | isa = PBXFrameworksBuildPhase; 163 | buildActionMask = 2147483647; 164 | files = ( 165 | ); 166 | runOnlyForDeploymentPostprocessing = 0; 167 | }; 168 | /* End PBXFrameworksBuildPhase section */ 169 | 170 | /* Begin PBXGroup section */ 171 | CB1A67642A5D9817007E34C4 = { 172 | isa = PBXGroup; 173 | children = ( 174 | CB1A676F2A5D9817007E34C4 /* Trackizer */, 175 | CB1A67802A5D981C007E34C4 /* TrackizerTests */, 176 | CB1A678A2A5D981C007E34C4 /* TrackizerUITests */, 177 | CB1A676E2A5D9817007E34C4 /* Products */, 178 | ); 179 | sourceTree = ""; 180 | }; 181 | CB1A676E2A5D9817007E34C4 /* Products */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | CB1A676D2A5D9817007E34C4 /* Trackizer.app */, 185 | CB1A677D2A5D981C007E34C4 /* TrackizerTests.xctest */, 186 | CB1A67872A5D981C007E34C4 /* TrackizerUITests.xctest */, 187 | ); 188 | name = Products; 189 | sourceTree = ""; 190 | }; 191 | CB1A676F2A5D9817007E34C4 /* Trackizer */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | CBE289CD2A61DB190086864C /* 3rdParty */, 195 | CB1A67AB2A5D98F8007E34C4 /* Info.plist */, 196 | CB1A679F2A5D987A007E34C4 /* UICommon */, 197 | CB1A679E2A5D9871007E34C4 /* Common */, 198 | CB1A679D2A5D9868007E34C4 /* Model */, 199 | CB1A679C2A5D985B007E34C4 /* ViewModel */, 200 | CB1A679B2A5D9851007E34C4 /* View */, 201 | CB1A679A2A5D983D007E34C4 /* Font */, 202 | CB1A67702A5D9817007E34C4 /* TrackizerApp.swift */, 203 | CB1A67742A5D981B007E34C4 /* Assets.xcassets */, 204 | CB1A67762A5D981B007E34C4 /* Preview Content */, 205 | ); 206 | path = Trackizer; 207 | sourceTree = ""; 208 | }; 209 | CB1A67762A5D981B007E34C4 /* Preview Content */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | CB1A67772A5D981B007E34C4 /* Preview Assets.xcassets */, 213 | ); 214 | path = "Preview Content"; 215 | sourceTree = ""; 216 | }; 217 | CB1A67802A5D981C007E34C4 /* TrackizerTests */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | CB1A67812A5D981C007E34C4 /* TrackizerTests.swift */, 221 | ); 222 | path = TrackizerTests; 223 | sourceTree = ""; 224 | }; 225 | CB1A678A2A5D981C007E34C4 /* TrackizerUITests */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | CB1A678B2A5D981C007E34C4 /* TrackizerUITests.swift */, 229 | CB1A678D2A5D981C007E34C4 /* TrackizerUITestsLaunchTests.swift */, 230 | ); 231 | path = TrackizerUITests; 232 | sourceTree = ""; 233 | }; 234 | CB1A679A2A5D983D007E34C4 /* Font */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | CB1A67A52A5D98E8007E34C4 /* Inter-Bold.ttf */, 238 | CB1A67A32A5D98E7007E34C4 /* Inter-Medium.ttf */, 239 | CB1A67A62A5D98E9007E34C4 /* Inter-Regular.ttf */, 240 | CB1A67A42A5D98E8007E34C4 /* Inter-SemiBold.ttf */, 241 | ); 242 | path = Font; 243 | sourceTree = ""; 244 | }; 245 | CB1A679B2A5D9851007E34C4 /* View */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | CBB865132A6705EB00B564D8 /* Card */, 249 | CB9A32E82A63C2DB00D952FE /* Settings */, 250 | CB9A32E32A63A80B00D952FE /* SubscriptionInfo */, 251 | CB2363AC2A62DD6000DA3548 /* AddSubscription */, 252 | CBE289C82A61D69A0086864C /* Calendar */, 253 | CBC93D982A60755900D32911 /* Budgets */, 254 | CB1A67A22A5D9895007E34C4 /* MainTab */, 255 | CB1A67A12A5D988C007E34C4 /* Home */, 256 | CB1A67A02A5D9885007E34C4 /* Login */, 257 | ); 258 | path = View; 259 | sourceTree = ""; 260 | }; 261 | CB1A679C2A5D985B007E34C4 /* ViewModel */ = { 262 | isa = PBXGroup; 263 | children = ( 264 | CB2363AF2A62E25600DA3548 /* UIStateModel.swift */, 265 | ); 266 | path = ViewModel; 267 | sourceTree = ""; 268 | }; 269 | CB1A679D2A5D9868007E34C4 /* Model */ = { 270 | isa = PBXGroup; 271 | children = ( 272 | CBC7431D2A5F2BCD00C502BF /* SubscriptionModel.swift */, 273 | CBC93D9B2A6075A000D32911 /* BudgetModel.swift */, 274 | CBC93D9F2A60805400D32911 /* ArcModel.swift */, 275 | CBB865192A6706CB00B564D8 /* CreditCardModel.swift */, 276 | ); 277 | path = Model; 278 | sourceTree = ""; 279 | }; 280 | CB1A679E2A5D9871007E34C4 /* Common */ = { 281 | isa = PBXGroup; 282 | children = ( 283 | ); 284 | path = Common; 285 | sourceTree = ""; 286 | }; 287 | CB1A679F2A5D987A007E34C4 /* UICommon */ = { 288 | isa = PBXGroup; 289 | children = ( 290 | CB1A67AC2A5D9941007E34C4 /* UIExtension.swift */, 291 | CB1A67B02A5DA21E007E34C4 /* PrimaryButton.swift */, 292 | CB1A67B22A5DA30B007E34C4 /* SecondaryButton.swift */, 293 | CB1A67B82A5DA9E4007E34C4 /* RoundTextField.swift */, 294 | CBC7431B2A5F2ABC00C502BF /* SegmentButton.swift */, 295 | CBC7431F2A5F303000C502BF /* SubScriptionHomeRow.swift */, 296 | CBC743212A5F309900C502BF /* UpcomingBillRow.swift */, 297 | CBC743232A5F328C00C502BF /* StatusButton.swift */, 298 | CBC743252A5F35B200C502BF /* ArcShape.swift */, 299 | CBC93D9D2A60782300D32911 /* BudgetRow.swift */, 300 | CBE289CB2A61D7990086864C /* SubscriptionCell.swift */, 301 | CB2363B32A62E2BF00DA3548 /* CarouselView.swift */, 302 | CB9A32E62A63AD1800D952FE /* ItemRow.swift */, 303 | CB9A32EB2A63C59500D952FE /* IconItemRow.swift */, 304 | CB9A32ED2A63C65F00D952FE /* IconItemSwitchRow.swift */, 305 | ); 306 | path = UICommon; 307 | sourceTree = ""; 308 | }; 309 | CB1A67A02A5D9885007E34C4 /* Login */ = { 310 | isa = PBXGroup; 311 | children = ( 312 | CB1A67AE2A5D9D19007E34C4 /* WelcomView.swift */, 313 | CB1A67B42A5DA3E5007E34C4 /* SocialSignupView.swift */, 314 | CB1A67B62A5DA660007E34C4 /* SignUpView.swift */, 315 | CB1A67BA2A5DABA7007E34C4 /* SignInView.swift */, 316 | ); 317 | path = Login; 318 | sourceTree = ""; 319 | }; 320 | CB1A67A12A5D988C007E34C4 /* Home */ = { 321 | isa = PBXGroup; 322 | children = ( 323 | CBC743192A5F281000C502BF /* HomeView.swift */, 324 | ); 325 | path = Home; 326 | sourceTree = ""; 327 | }; 328 | CB1A67A22A5D9895007E34C4 /* MainTab */ = { 329 | isa = PBXGroup; 330 | children = ( 331 | CBC743172A5F245500C502BF /* MainTabView.swift */, 332 | ); 333 | path = MainTab; 334 | sourceTree = ""; 335 | }; 336 | CB2363AC2A62DD6000DA3548 /* AddSubscription */ = { 337 | isa = PBXGroup; 338 | children = ( 339 | CB2363AD2A62DD7D00DA3548 /* AddSubscruiptionView.swift */, 340 | ); 341 | path = AddSubscription; 342 | sourceTree = ""; 343 | }; 344 | CB9A32E32A63A80B00D952FE /* SubscriptionInfo */ = { 345 | isa = PBXGroup; 346 | children = ( 347 | CB9A32E42A63A83C00D952FE /* SubscriptionInfoView.swift */, 348 | ); 349 | path = SubscriptionInfo; 350 | sourceTree = ""; 351 | }; 352 | CB9A32E82A63C2DB00D952FE /* Settings */ = { 353 | isa = PBXGroup; 354 | children = ( 355 | CB9A32E92A63C2EC00D952FE /* SettingsView.swift */, 356 | ); 357 | path = Settings; 358 | sourceTree = ""; 359 | }; 360 | CBB865132A6705EB00B564D8 /* Card */ = { 361 | isa = PBXGroup; 362 | children = ( 363 | CBB865142A67060500B564D8 /* CardsView.swift */, 364 | ); 365 | path = Card; 366 | sourceTree = ""; 367 | }; 368 | CBB865162A6706A100B564D8 /* CardStack */ = { 369 | isa = PBXGroup; 370 | children = ( 371 | CBB865172A6706A100B564D8 /* CardStack.swift */, 372 | ); 373 | path = CardStack; 374 | sourceTree = ""; 375 | }; 376 | CBC93D982A60755900D32911 /* Budgets */ = { 377 | isa = PBXGroup; 378 | children = ( 379 | CBC93D992A60757600D32911 /* BudgetsView.swift */, 380 | ); 381 | path = Budgets; 382 | sourceTree = ""; 383 | }; 384 | CBE289C82A61D69A0086864C /* Calendar */ = { 385 | isa = PBXGroup; 386 | children = ( 387 | CBE289C92A61D6C90086864C /* CalendarView.swift */, 388 | ); 389 | path = Calendar; 390 | sourceTree = ""; 391 | }; 392 | CBE289CD2A61DB190086864C /* 3rdParty */ = { 393 | isa = PBXGroup; 394 | children = ( 395 | CBB865162A6706A100B564D8 /* CardStack */, 396 | CBE289CE2A61DB260086864C /* InfiniteWeekView */, 397 | ); 398 | path = 3rdParty; 399 | sourceTree = ""; 400 | }; 401 | CBE289CE2A61DB260086864C /* InfiniteWeekView */ = { 402 | isa = PBXGroup; 403 | children = ( 404 | CBE289E02A61DB4D0086864C /* Models */, 405 | CBE289CF2A61DB440086864C /* Utils */, 406 | CBE289DA2A61DB450086864C /* Views */, 407 | ); 408 | path = InfiniteWeekView; 409 | sourceTree = ""; 410 | }; 411 | CBE289CF2A61DB440086864C /* Utils */ = { 412 | isa = PBXGroup; 413 | children = ( 414 | CBE289D02A61DB440086864C /* ViewModifier */, 415 | CBE289D22A61DB440086864C /* Enums */, 416 | CBE289D42A61DB440086864C /* Shapes */, 417 | CBE289D62A61DB440086864C /* Extensions */, 418 | ); 419 | path = Utils; 420 | sourceTree = ""; 421 | }; 422 | CBE289D02A61DB440086864C /* ViewModifier */ = { 423 | isa = PBXGroup; 424 | children = ( 425 | CBE289D12A61DB440086864C /* CornerRadiusStyle.swift */, 426 | ); 427 | path = ViewModifier; 428 | sourceTree = ""; 429 | }; 430 | CBE289D22A61DB440086864C /* Enums */ = { 431 | isa = PBXGroup; 432 | children = ( 433 | CBE289D32A61DB440086864C /* TimeDirection.swift */, 434 | ); 435 | path = Enums; 436 | sourceTree = ""; 437 | }; 438 | CBE289D42A61DB440086864C /* Shapes */ = { 439 | isa = PBXGroup; 440 | children = ( 441 | CBE289D52A61DB440086864C /* CornerRadiusShape.swift */, 442 | ); 443 | path = Shapes; 444 | sourceTree = ""; 445 | }; 446 | CBE289D62A61DB440086864C /* Extensions */ = { 447 | isa = PBXGroup; 448 | children = ( 449 | CBE289D72A61DB440086864C /* Date+Extension.swift */, 450 | CBE289D82A61DB440086864C /* Color+Extension.swift */, 451 | CBE289D92A61DB440086864C /* View+Extension.swift */, 452 | ); 453 | path = Extensions; 454 | sourceTree = ""; 455 | }; 456 | CBE289DA2A61DB450086864C /* Views */ = { 457 | isa = PBXGroup; 458 | children = ( 459 | CBE289DB2A61DB450086864C /* Week */, 460 | CBE289DF2A61DB450086864C /* InfiniteWeekView.swift */, 461 | ); 462 | path = Views; 463 | sourceTree = ""; 464 | }; 465 | CBE289DB2A61DB450086864C /* Week */ = { 466 | isa = PBXGroup; 467 | children = ( 468 | CBE289DC2A61DB450086864C /* WeeksTabView.swift */, 469 | CBE289DD2A61DB450086864C /* WeekHeaderView.swift */, 470 | CBE289DE2A61DB450086864C /* WeekView.swift */, 471 | ); 472 | path = Week; 473 | sourceTree = ""; 474 | }; 475 | CBE289E02A61DB4D0086864C /* Models */ = { 476 | isa = PBXGroup; 477 | children = ( 478 | CBE289E12A61DB4D0086864C /* WeekStore.swift */, 479 | CBE289E22A61DB4D0086864C /* Week.swift */, 480 | ); 481 | path = Models; 482 | sourceTree = ""; 483 | }; 484 | /* End PBXGroup section */ 485 | 486 | /* Begin PBXNativeTarget section */ 487 | CB1A676C2A5D9817007E34C4 /* Trackizer */ = { 488 | isa = PBXNativeTarget; 489 | buildConfigurationList = CB1A67912A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "Trackizer" */; 490 | buildPhases = ( 491 | CB1A67692A5D9817007E34C4 /* Sources */, 492 | CB1A676A2A5D9817007E34C4 /* Frameworks */, 493 | CB1A676B2A5D9817007E34C4 /* Resources */, 494 | ); 495 | buildRules = ( 496 | ); 497 | dependencies = ( 498 | ); 499 | name = Trackizer; 500 | productName = Trackizer; 501 | productReference = CB1A676D2A5D9817007E34C4 /* Trackizer.app */; 502 | productType = "com.apple.product-type.application"; 503 | }; 504 | CB1A677C2A5D981C007E34C4 /* TrackizerTests */ = { 505 | isa = PBXNativeTarget; 506 | buildConfigurationList = CB1A67942A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "TrackizerTests" */; 507 | buildPhases = ( 508 | CB1A67792A5D981C007E34C4 /* Sources */, 509 | CB1A677A2A5D981C007E34C4 /* Frameworks */, 510 | CB1A677B2A5D981C007E34C4 /* Resources */, 511 | ); 512 | buildRules = ( 513 | ); 514 | dependencies = ( 515 | CB1A677F2A5D981C007E34C4 /* PBXTargetDependency */, 516 | ); 517 | name = TrackizerTests; 518 | productName = TrackizerTests; 519 | productReference = CB1A677D2A5D981C007E34C4 /* TrackizerTests.xctest */; 520 | productType = "com.apple.product-type.bundle.unit-test"; 521 | }; 522 | CB1A67862A5D981C007E34C4 /* TrackizerUITests */ = { 523 | isa = PBXNativeTarget; 524 | buildConfigurationList = CB1A67972A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "TrackizerUITests" */; 525 | buildPhases = ( 526 | CB1A67832A5D981C007E34C4 /* Sources */, 527 | CB1A67842A5D981C007E34C4 /* Frameworks */, 528 | CB1A67852A5D981C007E34C4 /* Resources */, 529 | ); 530 | buildRules = ( 531 | ); 532 | dependencies = ( 533 | CB1A67892A5D981C007E34C4 /* PBXTargetDependency */, 534 | ); 535 | name = TrackizerUITests; 536 | productName = TrackizerUITests; 537 | productReference = CB1A67872A5D981C007E34C4 /* TrackizerUITests.xctest */; 538 | productType = "com.apple.product-type.bundle.ui-testing"; 539 | }; 540 | /* End PBXNativeTarget section */ 541 | 542 | /* Begin PBXProject section */ 543 | CB1A67652A5D9817007E34C4 /* Project object */ = { 544 | isa = PBXProject; 545 | attributes = { 546 | BuildIndependentTargetsInParallel = 1; 547 | LastSwiftUpdateCheck = 1430; 548 | LastUpgradeCheck = 1430; 549 | TargetAttributes = { 550 | CB1A676C2A5D9817007E34C4 = { 551 | CreatedOnToolsVersion = 14.3.1; 552 | }; 553 | CB1A677C2A5D981C007E34C4 = { 554 | CreatedOnToolsVersion = 14.3.1; 555 | TestTargetID = CB1A676C2A5D9817007E34C4; 556 | }; 557 | CB1A67862A5D981C007E34C4 = { 558 | CreatedOnToolsVersion = 14.3.1; 559 | TestTargetID = CB1A676C2A5D9817007E34C4; 560 | }; 561 | }; 562 | }; 563 | buildConfigurationList = CB1A67682A5D9817007E34C4 /* Build configuration list for PBXProject "Trackizer" */; 564 | compatibilityVersion = "Xcode 14.0"; 565 | developmentRegion = en; 566 | hasScannedForEncodings = 0; 567 | knownRegions = ( 568 | en, 569 | Base, 570 | ); 571 | mainGroup = CB1A67642A5D9817007E34C4; 572 | productRefGroup = CB1A676E2A5D9817007E34C4 /* Products */; 573 | projectDirPath = ""; 574 | projectRoot = ""; 575 | targets = ( 576 | CB1A676C2A5D9817007E34C4 /* Trackizer */, 577 | CB1A677C2A5D981C007E34C4 /* TrackizerTests */, 578 | CB1A67862A5D981C007E34C4 /* TrackizerUITests */, 579 | ); 580 | }; 581 | /* End PBXProject section */ 582 | 583 | /* Begin PBXResourcesBuildPhase section */ 584 | CB1A676B2A5D9817007E34C4 /* Resources */ = { 585 | isa = PBXResourcesBuildPhase; 586 | buildActionMask = 2147483647; 587 | files = ( 588 | CB1A67A82A5D98E9007E34C4 /* Inter-SemiBold.ttf in Resources */, 589 | CB1A67A92A5D98E9007E34C4 /* Inter-Bold.ttf in Resources */, 590 | CB1A67782A5D981B007E34C4 /* Preview Assets.xcassets in Resources */, 591 | CB1A67752A5D981B007E34C4 /* Assets.xcassets in Resources */, 592 | CB1A67AA2A5D98E9007E34C4 /* Inter-Regular.ttf in Resources */, 593 | CB1A67A72A5D98E9007E34C4 /* Inter-Medium.ttf in Resources */, 594 | ); 595 | runOnlyForDeploymentPostprocessing = 0; 596 | }; 597 | CB1A677B2A5D981C007E34C4 /* Resources */ = { 598 | isa = PBXResourcesBuildPhase; 599 | buildActionMask = 2147483647; 600 | files = ( 601 | ); 602 | runOnlyForDeploymentPostprocessing = 0; 603 | }; 604 | CB1A67852A5D981C007E34C4 /* Resources */ = { 605 | isa = PBXResourcesBuildPhase; 606 | buildActionMask = 2147483647; 607 | files = ( 608 | ); 609 | runOnlyForDeploymentPostprocessing = 0; 610 | }; 611 | /* End PBXResourcesBuildPhase section */ 612 | 613 | /* Begin PBXSourcesBuildPhase section */ 614 | CB1A67692A5D9817007E34C4 /* Sources */ = { 615 | isa = PBXSourcesBuildPhase; 616 | buildActionMask = 2147483647; 617 | files = ( 618 | CBC93D9C2A6075A000D32911 /* BudgetModel.swift in Sources */, 619 | CBC93D9E2A60782300D32911 /* BudgetRow.swift in Sources */, 620 | CBE289EE2A61DB4D0086864C /* Week.swift in Sources */, 621 | CBC743262A5F35B200C502BF /* ArcShape.swift in Sources */, 622 | CB1A67BB2A5DABA7007E34C4 /* SignInView.swift in Sources */, 623 | CB9A32EA2A63C2EC00D952FE /* SettingsView.swift in Sources */, 624 | CB1A67B92A5DA9E4007E34C4 /* RoundTextField.swift in Sources */, 625 | CB1A67B32A5DA30B007E34C4 /* SecondaryButton.swift in Sources */, 626 | CB9A32E72A63AD1800D952FE /* ItemRow.swift in Sources */, 627 | CB2363AE2A62DD7D00DA3548 /* AddSubscruiptionView.swift in Sources */, 628 | CBE289CA2A61D6C90086864C /* CalendarView.swift in Sources */, 629 | CB1A67AD2A5D9941007E34C4 /* UIExtension.swift in Sources */, 630 | CBE289E62A61DB4D0086864C /* Date+Extension.swift in Sources */, 631 | CBC93DA02A60805400D32911 /* ArcModel.swift in Sources */, 632 | CB1A67712A5D9817007E34C4 /* TrackizerApp.swift in Sources */, 633 | CBC7431A2A5F281000C502BF /* HomeView.swift in Sources */, 634 | CB1A67B72A5DA660007E34C4 /* SignUpView.swift in Sources */, 635 | CB1A67B52A5DA3E5007E34C4 /* SocialSignupView.swift in Sources */, 636 | CBE289E82A61DB4D0086864C /* View+Extension.swift in Sources */, 637 | CB1A67B12A5DA21E007E34C4 /* PrimaryButton.swift in Sources */, 638 | CBE289EB2A61DB4D0086864C /* WeekView.swift in Sources */, 639 | CBE289E72A61DB4D0086864C /* Color+Extension.swift in Sources */, 640 | CBB865152A67060500B564D8 /* CardsView.swift in Sources */, 641 | CBC7431C2A5F2ABC00C502BF /* SegmentButton.swift in Sources */, 642 | CBC743222A5F309900C502BF /* UpcomingBillRow.swift in Sources */, 643 | CBE289E52A61DB4D0086864C /* CornerRadiusShape.swift in Sources */, 644 | CBE289E92A61DB4D0086864C /* WeeksTabView.swift in Sources */, 645 | CBE289EA2A61DB4D0086864C /* WeekHeaderView.swift in Sources */, 646 | CBE289ED2A61DB4D0086864C /* WeekStore.swift in Sources */, 647 | CBC743202A5F303000C502BF /* SubScriptionHomeRow.swift in Sources */, 648 | CBC93D9A2A60757600D32911 /* BudgetsView.swift in Sources */, 649 | CB1A67AF2A5D9D19007E34C4 /* WelcomView.swift in Sources */, 650 | CBE289CC2A61D7990086864C /* SubscriptionCell.swift in Sources */, 651 | CB9A32EC2A63C59500D952FE /* IconItemRow.swift in Sources */, 652 | CBB8651A2A6706CB00B564D8 /* CreditCardModel.swift in Sources */, 653 | CBE289EC2A61DB4D0086864C /* InfiniteWeekView.swift in Sources */, 654 | CBE289E32A61DB4D0086864C /* CornerRadiusStyle.swift in Sources */, 655 | CB2363B42A62E2BF00DA3548 /* CarouselView.swift in Sources */, 656 | CB9A32E52A63A83C00D952FE /* SubscriptionInfoView.swift in Sources */, 657 | CBC743242A5F328C00C502BF /* StatusButton.swift in Sources */, 658 | CB9A32EE2A63C65F00D952FE /* IconItemSwitchRow.swift in Sources */, 659 | CBE289E42A61DB4D0086864C /* TimeDirection.swift in Sources */, 660 | CBC743182A5F245500C502BF /* MainTabView.swift in Sources */, 661 | CBC7431E2A5F2BCD00C502BF /* SubscriptionModel.swift in Sources */, 662 | CB2363B02A62E25600DA3548 /* UIStateModel.swift in Sources */, 663 | CBB865182A6706A100B564D8 /* CardStack.swift in Sources */, 664 | ); 665 | runOnlyForDeploymentPostprocessing = 0; 666 | }; 667 | CB1A67792A5D981C007E34C4 /* Sources */ = { 668 | isa = PBXSourcesBuildPhase; 669 | buildActionMask = 2147483647; 670 | files = ( 671 | CB1A67822A5D981C007E34C4 /* TrackizerTests.swift in Sources */, 672 | ); 673 | runOnlyForDeploymentPostprocessing = 0; 674 | }; 675 | CB1A67832A5D981C007E34C4 /* Sources */ = { 676 | isa = PBXSourcesBuildPhase; 677 | buildActionMask = 2147483647; 678 | files = ( 679 | CB1A678E2A5D981C007E34C4 /* TrackizerUITestsLaunchTests.swift in Sources */, 680 | CB1A678C2A5D981C007E34C4 /* TrackizerUITests.swift in Sources */, 681 | ); 682 | runOnlyForDeploymentPostprocessing = 0; 683 | }; 684 | /* End PBXSourcesBuildPhase section */ 685 | 686 | /* Begin PBXTargetDependency section */ 687 | CB1A677F2A5D981C007E34C4 /* PBXTargetDependency */ = { 688 | isa = PBXTargetDependency; 689 | target = CB1A676C2A5D9817007E34C4 /* Trackizer */; 690 | targetProxy = CB1A677E2A5D981C007E34C4 /* PBXContainerItemProxy */; 691 | }; 692 | CB1A67892A5D981C007E34C4 /* PBXTargetDependency */ = { 693 | isa = PBXTargetDependency; 694 | target = CB1A676C2A5D9817007E34C4 /* Trackizer */; 695 | targetProxy = CB1A67882A5D981C007E34C4 /* PBXContainerItemProxy */; 696 | }; 697 | /* End PBXTargetDependency section */ 698 | 699 | /* Begin XCBuildConfiguration section */ 700 | CB1A678F2A5D981C007E34C4 /* Debug */ = { 701 | isa = XCBuildConfiguration; 702 | buildSettings = { 703 | ALWAYS_SEARCH_USER_PATHS = NO; 704 | CLANG_ANALYZER_NONNULL = YES; 705 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 706 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 707 | CLANG_ENABLE_MODULES = YES; 708 | CLANG_ENABLE_OBJC_ARC = YES; 709 | CLANG_ENABLE_OBJC_WEAK = YES; 710 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 711 | CLANG_WARN_BOOL_CONVERSION = YES; 712 | CLANG_WARN_COMMA = YES; 713 | CLANG_WARN_CONSTANT_CONVERSION = YES; 714 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 715 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 716 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 717 | CLANG_WARN_EMPTY_BODY = YES; 718 | CLANG_WARN_ENUM_CONVERSION = YES; 719 | CLANG_WARN_INFINITE_RECURSION = YES; 720 | CLANG_WARN_INT_CONVERSION = YES; 721 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 722 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 723 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 724 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 725 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 726 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 727 | CLANG_WARN_STRICT_PROTOTYPES = YES; 728 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 729 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 730 | CLANG_WARN_UNREACHABLE_CODE = YES; 731 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 732 | COPY_PHASE_STRIP = NO; 733 | DEBUG_INFORMATION_FORMAT = dwarf; 734 | ENABLE_STRICT_OBJC_MSGSEND = YES; 735 | ENABLE_TESTABILITY = YES; 736 | GCC_C_LANGUAGE_STANDARD = gnu11; 737 | GCC_DYNAMIC_NO_PIC = NO; 738 | GCC_NO_COMMON_BLOCKS = YES; 739 | GCC_OPTIMIZATION_LEVEL = 0; 740 | GCC_PREPROCESSOR_DEFINITIONS = ( 741 | "DEBUG=1", 742 | "$(inherited)", 743 | ); 744 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 745 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 746 | GCC_WARN_UNDECLARED_SELECTOR = YES; 747 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 748 | GCC_WARN_UNUSED_FUNCTION = YES; 749 | GCC_WARN_UNUSED_VARIABLE = YES; 750 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 751 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 752 | MTL_FAST_MATH = YES; 753 | ONLY_ACTIVE_ARCH = YES; 754 | SDKROOT = iphoneos; 755 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 756 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 757 | }; 758 | name = Debug; 759 | }; 760 | CB1A67902A5D981C007E34C4 /* Release */ = { 761 | isa = XCBuildConfiguration; 762 | buildSettings = { 763 | ALWAYS_SEARCH_USER_PATHS = NO; 764 | CLANG_ANALYZER_NONNULL = YES; 765 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 766 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 767 | CLANG_ENABLE_MODULES = YES; 768 | CLANG_ENABLE_OBJC_ARC = YES; 769 | CLANG_ENABLE_OBJC_WEAK = YES; 770 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 771 | CLANG_WARN_BOOL_CONVERSION = YES; 772 | CLANG_WARN_COMMA = YES; 773 | CLANG_WARN_CONSTANT_CONVERSION = YES; 774 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 775 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 776 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 777 | CLANG_WARN_EMPTY_BODY = YES; 778 | CLANG_WARN_ENUM_CONVERSION = YES; 779 | CLANG_WARN_INFINITE_RECURSION = YES; 780 | CLANG_WARN_INT_CONVERSION = YES; 781 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 782 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 783 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 784 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 785 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 786 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 787 | CLANG_WARN_STRICT_PROTOTYPES = YES; 788 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 789 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 790 | CLANG_WARN_UNREACHABLE_CODE = YES; 791 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 792 | COPY_PHASE_STRIP = NO; 793 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 794 | ENABLE_NS_ASSERTIONS = NO; 795 | ENABLE_STRICT_OBJC_MSGSEND = YES; 796 | GCC_C_LANGUAGE_STANDARD = gnu11; 797 | GCC_NO_COMMON_BLOCKS = YES; 798 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 799 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 800 | GCC_WARN_UNDECLARED_SELECTOR = YES; 801 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 802 | GCC_WARN_UNUSED_FUNCTION = YES; 803 | GCC_WARN_UNUSED_VARIABLE = YES; 804 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 805 | MTL_ENABLE_DEBUG_INFO = NO; 806 | MTL_FAST_MATH = YES; 807 | SDKROOT = iphoneos; 808 | SWIFT_COMPILATION_MODE = wholemodule; 809 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 810 | VALIDATE_PRODUCT = YES; 811 | }; 812 | name = Release; 813 | }; 814 | CB1A67922A5D981C007E34C4 /* Debug */ = { 815 | isa = XCBuildConfiguration; 816 | buildSettings = { 817 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 818 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 819 | CODE_SIGN_STYLE = Automatic; 820 | CURRENT_PROJECT_VERSION = 1; 821 | DEVELOPMENT_ASSET_PATHS = "\"Trackizer/Preview Content\""; 822 | ENABLE_PREVIEWS = YES; 823 | GENERATE_INFOPLIST_FILE = YES; 824 | INFOPLIST_FILE = Trackizer/Info.plist; 825 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 826 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 827 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 828 | INFOPLIST_KEY_UIStatusBarStyle = ""; 829 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 830 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 831 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 832 | LD_RUNPATH_SEARCH_PATHS = ( 833 | "$(inherited)", 834 | "@executable_path/Frameworks", 835 | ); 836 | MARKETING_VERSION = 1.0; 837 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.Trackizer; 838 | PRODUCT_NAME = "$(TARGET_NAME)"; 839 | SWIFT_EMIT_LOC_STRINGS = YES; 840 | SWIFT_VERSION = 5.0; 841 | TARGETED_DEVICE_FAMILY = "1,2"; 842 | }; 843 | name = Debug; 844 | }; 845 | CB1A67932A5D981C007E34C4 /* Release */ = { 846 | isa = XCBuildConfiguration; 847 | buildSettings = { 848 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 849 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 850 | CODE_SIGN_STYLE = Automatic; 851 | CURRENT_PROJECT_VERSION = 1; 852 | DEVELOPMENT_ASSET_PATHS = "\"Trackizer/Preview Content\""; 853 | ENABLE_PREVIEWS = YES; 854 | GENERATE_INFOPLIST_FILE = YES; 855 | INFOPLIST_FILE = Trackizer/Info.plist; 856 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 857 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 858 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 859 | INFOPLIST_KEY_UIStatusBarStyle = ""; 860 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 861 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 862 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 863 | LD_RUNPATH_SEARCH_PATHS = ( 864 | "$(inherited)", 865 | "@executable_path/Frameworks", 866 | ); 867 | MARKETING_VERSION = 1.0; 868 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.Trackizer; 869 | PRODUCT_NAME = "$(TARGET_NAME)"; 870 | SWIFT_EMIT_LOC_STRINGS = YES; 871 | SWIFT_VERSION = 5.0; 872 | TARGETED_DEVICE_FAMILY = "1,2"; 873 | }; 874 | name = Release; 875 | }; 876 | CB1A67952A5D981C007E34C4 /* Debug */ = { 877 | isa = XCBuildConfiguration; 878 | buildSettings = { 879 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 880 | BUNDLE_LOADER = "$(TEST_HOST)"; 881 | CODE_SIGN_STYLE = Automatic; 882 | CURRENT_PROJECT_VERSION = 1; 883 | GENERATE_INFOPLIST_FILE = YES; 884 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 885 | MARKETING_VERSION = 1.0; 886 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.TrackizerTests; 887 | PRODUCT_NAME = "$(TARGET_NAME)"; 888 | SWIFT_EMIT_LOC_STRINGS = NO; 889 | SWIFT_VERSION = 5.0; 890 | TARGETED_DEVICE_FAMILY = "1,2"; 891 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Trackizer.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Trackizer"; 892 | }; 893 | name = Debug; 894 | }; 895 | CB1A67962A5D981C007E34C4 /* Release */ = { 896 | isa = XCBuildConfiguration; 897 | buildSettings = { 898 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 899 | BUNDLE_LOADER = "$(TEST_HOST)"; 900 | CODE_SIGN_STYLE = Automatic; 901 | CURRENT_PROJECT_VERSION = 1; 902 | GENERATE_INFOPLIST_FILE = YES; 903 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 904 | MARKETING_VERSION = 1.0; 905 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.TrackizerTests; 906 | PRODUCT_NAME = "$(TARGET_NAME)"; 907 | SWIFT_EMIT_LOC_STRINGS = NO; 908 | SWIFT_VERSION = 5.0; 909 | TARGETED_DEVICE_FAMILY = "1,2"; 910 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Trackizer.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Trackizer"; 911 | }; 912 | name = Release; 913 | }; 914 | CB1A67982A5D981C007E34C4 /* Debug */ = { 915 | isa = XCBuildConfiguration; 916 | buildSettings = { 917 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 918 | CODE_SIGN_STYLE = Automatic; 919 | CURRENT_PROJECT_VERSION = 1; 920 | GENERATE_INFOPLIST_FILE = YES; 921 | MARKETING_VERSION = 1.0; 922 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.TrackizerUITests; 923 | PRODUCT_NAME = "$(TARGET_NAME)"; 924 | SWIFT_EMIT_LOC_STRINGS = NO; 925 | SWIFT_VERSION = 5.0; 926 | TARGETED_DEVICE_FAMILY = "1,2"; 927 | TEST_TARGET_NAME = Trackizer; 928 | }; 929 | name = Debug; 930 | }; 931 | CB1A67992A5D981C007E34C4 /* Release */ = { 932 | isa = XCBuildConfiguration; 933 | buildSettings = { 934 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 935 | CODE_SIGN_STYLE = Automatic; 936 | CURRENT_PROJECT_VERSION = 1; 937 | GENERATE_INFOPLIST_FILE = YES; 938 | MARKETING_VERSION = 1.0; 939 | PRODUCT_BUNDLE_IDENTIFIER = com.codeforany.TrackizerUITests; 940 | PRODUCT_NAME = "$(TARGET_NAME)"; 941 | SWIFT_EMIT_LOC_STRINGS = NO; 942 | SWIFT_VERSION = 5.0; 943 | TARGETED_DEVICE_FAMILY = "1,2"; 944 | TEST_TARGET_NAME = Trackizer; 945 | }; 946 | name = Release; 947 | }; 948 | /* End XCBuildConfiguration section */ 949 | 950 | /* Begin XCConfigurationList section */ 951 | CB1A67682A5D9817007E34C4 /* Build configuration list for PBXProject "Trackizer" */ = { 952 | isa = XCConfigurationList; 953 | buildConfigurations = ( 954 | CB1A678F2A5D981C007E34C4 /* Debug */, 955 | CB1A67902A5D981C007E34C4 /* Release */, 956 | ); 957 | defaultConfigurationIsVisible = 0; 958 | defaultConfigurationName = Release; 959 | }; 960 | CB1A67912A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "Trackizer" */ = { 961 | isa = XCConfigurationList; 962 | buildConfigurations = ( 963 | CB1A67922A5D981C007E34C4 /* Debug */, 964 | CB1A67932A5D981C007E34C4 /* Release */, 965 | ); 966 | defaultConfigurationIsVisible = 0; 967 | defaultConfigurationName = Release; 968 | }; 969 | CB1A67942A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "TrackizerTests" */ = { 970 | isa = XCConfigurationList; 971 | buildConfigurations = ( 972 | CB1A67952A5D981C007E34C4 /* Debug */, 973 | CB1A67962A5D981C007E34C4 /* Release */, 974 | ); 975 | defaultConfigurationIsVisible = 0; 976 | defaultConfigurationName = Release; 977 | }; 978 | CB1A67972A5D981C007E34C4 /* Build configuration list for PBXNativeTarget "TrackizerUITests" */ = { 979 | isa = XCConfigurationList; 980 | buildConfigurations = ( 981 | CB1A67982A5D981C007E34C4 /* Debug */, 982 | CB1A67992A5D981C007E34C4 /* Release */, 983 | ); 984 | defaultConfigurationIsVisible = 0; 985 | defaultConfigurationName = Release; 986 | }; 987 | /* End XCConfigurationList section */ 988 | }; 989 | rootObject = CB1A67652A5D9817007E34C4 /* Project object */; 990 | } 991 | -------------------------------------------------------------------------------- /Trackizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Trackizer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Trackizer.xcodeproj/xcuserdata/CodeForAny.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Trackizer.xcodeproj/xcuserdata/CodeForAny.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Trackizer.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/CardStack/CardStack.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | /** 4 | A SwiftUI view that arranges its children in an interactive deck of cards. 5 | */ 6 | public struct CardStack: View where Data: RandomAccessCollection, Data.Element: Identifiable, Content: View { 7 | @State private var currentIndex: Double = 0.0 8 | @State private var previousIndex: Double = 0.0 9 | 10 | private let data: Data 11 | @ViewBuilder private let content: (Data.Element) -> Content 12 | @Binding var finalCurrentIndex: Int 13 | 14 | /// Creates a stack with the given content 15 | /// - Parameters: 16 | /// - data: The identifiable data for computing the list. 17 | /// - currentIndex: The index of the topmost card in the stack 18 | /// - content: A view builder that creates the view for a single card 19 | public init(_ data: Data, currentIndex: Binding = .constant(0), @ViewBuilder content: @escaping (Data.Element) -> Content) { 20 | self.data = data 21 | self.content = content 22 | _finalCurrentIndex = currentIndex 23 | } 24 | 25 | public var body: some View { 26 | ZStack { 27 | ForEach(Array(data.enumerated()), id: \.element.id) { (index, element) in 28 | content(element) 29 | .zIndex(zIndex(for: index)) 30 | .offset(x: xOffset(for: index), y: 0) 31 | .scaleEffect(scale(for: index), anchor: .center) 32 | .rotationEffect(.degrees(rotationDegrees(for: index))) 33 | } 34 | } 35 | .highPriorityGesture(dragGesture) 36 | } 37 | 38 | private var dragGesture: some Gesture { 39 | DragGesture() 40 | .onChanged { value in 41 | withAnimation(.interactiveSpring()) { 42 | let x = (value.translation.width / 300) - previousIndex 43 | self.currentIndex = -x 44 | } 45 | } 46 | .onEnded { value in 47 | self.snapToNearestAbsoluteIndex(value.predictedEndTranslation) 48 | self.previousIndex = self.currentIndex 49 | } 50 | } 51 | 52 | private func snapToNearestAbsoluteIndex(_ predictedEndTranslation: CGSize) { 53 | withAnimation(.interpolatingSpring(stiffness: 300, damping: 40)) { 54 | let translation = predictedEndTranslation.width 55 | if abs(translation) > 200 { 56 | if translation > 0 { 57 | self.goTo(round(self.previousIndex) - 1) 58 | } else { 59 | self.goTo(round(self.previousIndex) + 1) 60 | } 61 | } else { 62 | self.currentIndex = round(currentIndex) 63 | } 64 | } 65 | } 66 | 67 | private func goTo(_ index: Double) { 68 | let maxIndex = Double(data.count - 1) 69 | if index < 0 { 70 | self.currentIndex = 0 71 | } else if index > maxIndex { 72 | self.currentIndex = maxIndex 73 | } else { 74 | self.currentIndex = index 75 | } 76 | self.finalCurrentIndex = Int(index) 77 | } 78 | 79 | private func zIndex(for index: Int) -> Double { 80 | if (Double(index) + 0.5) < currentIndex { 81 | return -Double(data.count - index) 82 | } else { 83 | return Double(data.count - index) 84 | } 85 | } 86 | 87 | private func xOffset(for index: Int) -> CGFloat { 88 | let topCardProgress = currentPosition(for: index) 89 | let padding = 35.0 90 | let x = ((CGFloat(index) - currentIndex) * padding) 91 | if topCardProgress > 0 && topCardProgress < 0.99 && index < (data.count - 1) { 92 | return x * swingOutMultiplier(topCardProgress) 93 | } 94 | return x 95 | } 96 | 97 | private func scale(for index: Int) -> CGFloat { 98 | return 1.0 - (0.1 * abs(currentPosition(for: index))) 99 | } 100 | 101 | private func rotationDegrees(for index: Int) -> Double { 102 | return -currentPosition(for: index) * 2 103 | } 104 | 105 | private func currentPosition(for index: Int) -> Double { 106 | currentIndex - Double(index) 107 | } 108 | 109 | private func swingOutMultiplier(_ progress: Double) -> Double { 110 | return sin(Double.pi * progress) * 15 111 | } 112 | } 113 | 114 | struct CardStackView_Previews: PreviewProvider { 115 | 116 | struct DemoItem: Identifiable { 117 | let name: String 118 | let color: Color 119 | 120 | var id: String { 121 | name 122 | } 123 | } 124 | 125 | struct DemoView: View { 126 | @State private var currentIndex = 0 127 | @State private var tappedIndex: Int? = nil 128 | 129 | var body: some View { 130 | let colors = [ 131 | DemoItem(name: "Red", color: .red), 132 | DemoItem(name: "Orange", color: .orange), 133 | DemoItem(name: "Yellow", color: .yellow), 134 | DemoItem(name: "Green", color: .green), 135 | DemoItem(name: "Blue", color: .blue), 136 | DemoItem(name: "Purple", color: .purple), 137 | ] 138 | 139 | VStack { 140 | CardStack(colors, currentIndex: $currentIndex) { namedColor in 141 | RoundedRectangle(cornerRadius: 20, style: .continuous) 142 | .fill(namedColor.color) 143 | .overlay( 144 | Text(namedColor.name) 145 | .font(.largeTitle) 146 | .fontWeight(.bold) 147 | .foregroundColor(.white) 148 | ) 149 | .frame(height: 400) 150 | .onTapGesture { 151 | tappedIndex = currentIndex 152 | } 153 | .padding(50) 154 | 155 | } 156 | 157 | Text("Current card is \(currentIndex)") 158 | if let tappedIndex = tappedIndex { 159 | Text("Card \(tappedIndex) was tapped") 160 | } else { 161 | Text("No card has been tapped") 162 | } 163 | } 164 | } 165 | } 166 | 167 | static var previews: some View { 168 | DemoView() 169 | } 170 | 171 | } 172 | 173 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Models/Week.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Week.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import Foundation 9 | 10 | struct Week { 11 | let index: Int 12 | let dates: [Date] 13 | var referenceDate: Date 14 | } 15 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Models/WeekStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeekStore.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import Foundation 9 | 10 | class WeekStore: ObservableObject { 11 | @Published var weeks: [Week] = [] 12 | @Published var selectedDate: Date { 13 | didSet { 14 | calcWeeks(with: selectedDate) 15 | } 16 | } 17 | 18 | init(with date: Date = Date()) { 19 | self.selectedDate = Calendar.current.startOfDay(for: date) 20 | calcWeeks(with: selectedDate) 21 | } 22 | 23 | private func calcWeeks(with date: Date) { 24 | weeks = [ 25 | week(for: Calendar.current.date(byAdding: .day, value: -7, to: date)!, with: -1), 26 | week(for: date, with: 0), 27 | week(for: Calendar.current.date(byAdding: .day, value: 7, to: date)!, with: 1) 28 | ] 29 | } 30 | 31 | private func week(for date: Date, with index: Int) -> Week { 32 | var result: [Date] = .init() 33 | 34 | guard let startOfWeek = Calendar.current.date(from: Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: date)) else { return .init(index: index, dates: [], referenceDate: date) } 35 | 36 | (0...6).forEach { day in 37 | if let weekday = Calendar.current.date(byAdding: .day, value: day, to: startOfWeek) { 38 | result.append(weekday) 39 | } 40 | } 41 | 42 | return .init(index: index, dates: result, referenceDate: date) 43 | } 44 | 45 | func selectToday() { 46 | select(date: Date()) 47 | } 48 | 49 | func select(date: Date) { 50 | selectedDate = Calendar.current.startOfDay(for: date) 51 | } 52 | 53 | func update(to direction: TimeDirection) { 54 | switch direction { 55 | case .future: 56 | selectedDate = Calendar.current.date(byAdding: .day, value: 7, to: selectedDate)! 57 | 58 | case .past: 59 | selectedDate = Calendar.current.date(byAdding: .day, value: -7, to: selectedDate)! 60 | 61 | case .unknown: 62 | selectedDate = selectedDate 63 | } 64 | 65 | calcWeeks(with: selectedDate) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/Enums/TimeDirection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimeDirection.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import Foundation 9 | 10 | enum TimeDirection { 11 | case future 12 | case past 13 | case unknown 14 | } 15 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/Extensions/Color+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Color+Extension.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Color { 11 | static let section = Color("Section") 12 | static let element = Color("Element") 13 | } 14 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/Extensions/Date+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date+Extension.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Date { 11 | func monthToString() -> String { 12 | let dateFormatter = DateFormatter() 13 | dateFormatter.dateFormat = "LLLL" 14 | return dateFormatter.string(from: self) 15 | } 16 | 17 | func toString(format: String) -> String { 18 | let formatter = DateFormatter() 19 | formatter.calendar = Calendar.current 20 | formatter.dateFormat = format 21 | 22 | return formatter.string(from: self) 23 | } 24 | 25 | var yesterday: Date { 26 | Calendar.current.date(byAdding: .day, value: -1, to: self)! 27 | } 28 | 29 | var tomorrow: Date { 30 | Calendar.current.date(byAdding: .day, value: 1, to: self)! 31 | } 32 | 33 | private func isEqual(to date: Date, toGranularity component: Calendar.Component, in calendar: Calendar = .current) -> Bool { 34 | var customCalendar = Calendar(identifier: .gregorian) 35 | customCalendar.firstWeekday = 2 36 | 37 | return customCalendar.isDate(self, equalTo: date, toGranularity: component) 38 | } 39 | 40 | func isInSameWeek(as date: Date) -> Bool { 41 | isEqual(to: date, toGranularity: .weekOfYear) 42 | } 43 | 44 | func isInSameDay(as date: Date) -> Bool { 45 | isEqual(to: date, toGranularity: .day) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/Extensions/View+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // View+Extension.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import Foundation 9 | 10 | import SwiftUI 11 | 12 | extension View { 13 | func cornerRadius(radius: CGFloat, corners: UIRectCorner) -> some View { 14 | ModifiedContent(content: self, modifier: CornerRadiusStyle(radius: radius, corners: corners)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/Shapes/CornerRadiusShape.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CornerRadiusShape.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CornerRadiusShape: Shape { 11 | var radius = CGFloat.infinity 12 | var corners = UIRectCorner.allCorners 13 | 14 | func path(in rect: CGRect) -> Path { 15 | let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) 16 | return Path(path.cgPath) 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Utils/ViewModifier/CornerRadiusStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CornerRadiusStyle.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CornerRadiusStyle: ViewModifier { 11 | var radius: CGFloat 12 | var corners: UIRectCorner 13 | 14 | func body(content: Content) -> some View { 15 | content 16 | .clipShape(CornerRadiusShape(radius: radius, corners: corners)) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Views/InfiniteWeekView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InfiniteWeekView.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct InfiniteWeekView: View { 11 | @EnvironmentObject var weekStore: WeekStore 12 | 13 | 14 | var body: some View { 15 | GeometryReader { geometry in 16 | NavigationStack { 17 | ZStack { 18 | VStack { 19 | 20 | 21 | Spacer() 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | 29 | struct InfinityTabPageWrapperView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | InfiniteWeekView() 32 | .environmentObject(WeekStore()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Views/Week/WeekHeaderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeekHeaderView.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WeekHeaderView: View { 11 | @EnvironmentObject var weekStore: WeekStore 12 | @State var showDatePicker: Bool = false 13 | 14 | var body: some View { 15 | HStack { 16 | Text("3 subscriptions for today") 17 | .font(.customfont(.semibold, fontSize: 14)) 18 | .foregroundColor(.gray30) 19 | 20 | 21 | 22 | Spacer() 23 | 24 | Button { 25 | showDatePicker = true 26 | } label: { 27 | HStack{ 28 | Text(weekStore.selectedDate.monthToString()) 29 | .font(.customfont(.semibold, fontSize: 14)) 30 | 31 | 32 | Image(systemName: "chevron.down") 33 | .resizable() 34 | .frame(width: 10,height: 10) 35 | } 36 | 37 | } 38 | .foregroundColor(.white) 39 | .padding(.horizontal, 15) 40 | .padding(.vertical, 4) 41 | .background(Color.gray60.opacity( 0.2 )) 42 | .overlay { 43 | RoundedRectangle(cornerRadius: 16) 44 | .stroke( Color.gray70 , lineWidth: 1) 45 | } 46 | .cornerRadius(16) 47 | .sheet(isPresented: $showDatePicker) { 48 | VStack { 49 | DatePicker("Select Date", selection: $weekStore.selectedDate, displayedComponents: [.date] ) 50 | .datePickerStyle(GraphicalDatePickerStyle()) 51 | .cornerRadius(15) 52 | .padding() 53 | .presentationDetents([.height(400), .fraction(20), .medium, .large]) 54 | .onChange(of: weekStore.selectedDate, perform: { _ in 55 | showDatePicker = false 56 | }) 57 | .tint(.secondaryC) 58 | .colorScheme(.dark) 59 | 60 | Spacer() 61 | } 62 | .background(Color.gray80) 63 | 64 | 65 | } 66 | .ignoresSafeArea() 67 | } 68 | } 69 | } 70 | 71 | struct WeekHeaderView_Previews: PreviewProvider { 72 | static var previews: some View { 73 | WeekHeaderView() 74 | .environmentObject(WeekStore()) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Views/Week/WeekView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeekView.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WeekView: View { 11 | @EnvironmentObject var weekStore: WeekStore 12 | 13 | var week: Week 14 | 15 | var body: some View { 16 | HStack { 17 | ForEach(0..<7) { i in 18 | VStack { 19 | 20 | 21 | Text(week.dates[i].toString(format: "d")) 22 | .font(.customfont(.bold, fontSize: 20)) 23 | 24 | .frame(maxWidth: .infinity) 25 | .foregroundColor( .white) 26 | .padding(.top, 15) 27 | 28 | 29 | Text(week.dates[i].toString(format: "EEE").uppercased()) 30 | .font(.customfont(.semibold, fontSize: 12)) 31 | .foregroundColor(.gray30) 32 | .frame(maxWidth:.infinity) 33 | 34 | Spacer() 35 | 36 | Circle() 37 | .fill(Color.secondaryC) 38 | .frame(width: 5, height: 5) 39 | 40 | Spacer() 41 | 42 | 43 | }.onTapGesture { 44 | withAnimation { 45 | weekStore.selectedDate = week.dates[i] 46 | } 47 | } 48 | .frame(maxWidth: .infinity, minHeight: 110 , maxHeight: 110) 49 | .background(Color.gray60.opacity( week.dates[i] == weekStore.selectedDate ? 1.0 : 0.2 )) 50 | .overlay { 51 | RoundedRectangle(cornerRadius: 16) 52 | .stroke( Color.gray70 , lineWidth: 1) 53 | } 54 | .cornerRadius(16) 55 | } 56 | } 57 | .padding() 58 | } 59 | } 60 | 61 | struct WeekView_Previews: PreviewProvider { 62 | static var previews: some View { 63 | WeekView(week: .init(index: 1, dates: 64 | [ 65 | Date().yesterday.yesterday.yesterday, 66 | Date().yesterday.yesterday, 67 | Date().yesterday, 68 | Date(), 69 | Date().tomorrow, 70 | Date().tomorrow.tomorrow, 71 | Date().tomorrow.tomorrow.tomorrow 72 | ], 73 | referenceDate: Date())) 74 | .environmentObject(WeekStore()) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Trackizer/3rdParty/InfiniteWeekView/Views/Week/WeeksTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeeksTabView.swift 3 | // InfiniteWeekView 4 | // 5 | // Created by Philipp Knoblauch on 13.05.23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WeeksTabView: View { 11 | @EnvironmentObject var weekStore: WeekStore 12 | 13 | @State private var activeTab: Int = 1 14 | @State private var direction: TimeDirection = .unknown 15 | @State private var position = CGSize.zero 16 | @GestureState private var dragOffset = CGSize.zero 17 | 18 | let content: (_ week: Week) -> Content 19 | 20 | init(@ViewBuilder content: @escaping (_ week: Week) -> Content) { 21 | self.content = content 22 | } 23 | 24 | var body: some View { 25 | TabView(selection: $activeTab) { 26 | content(weekStore.weeks[0]) 27 | .frame(maxWidth: .infinity) 28 | .tag(0) 29 | 30 | content(weekStore.weeks[1]) 31 | .frame(maxWidth: .infinity) 32 | .tag(1) 33 | .onDisappear() { 34 | guard direction != .unknown else { return } 35 | weekStore.update(to: direction) 36 | direction = .unknown 37 | activeTab = 1 38 | } 39 | 40 | content(weekStore.weeks[2]) 41 | .frame(maxWidth: .infinity) 42 | .tag(2) 43 | } 44 | .tabViewStyle(.page(indexDisplayMode: .never)) 45 | .onChange(of: activeTab) { value in 46 | if value == 0 { 47 | direction = .past 48 | } else if value == 2 { 49 | direction = .future 50 | } 51 | } 52 | } 53 | } 54 | 55 | struct WeeksTabView_Previews: PreviewProvider { 56 | static var previews: some View { 57 | WeeksTabView() { week in 58 | WeekView(week: week) 59 | }.environmentObject(WeekStore()) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/Trash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Trash.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/Trash.imageset/Trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/Trash.imageset/Trash.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "add.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/add.imageset/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/add.imageset/add.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/app_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app_icon.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/app_icon.imageset/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/app_icon.imageset/app_icon.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/app_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/app_logo.imageset/app_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/app_logo.imageset/app_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/apple.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "apple.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/apple.imageset/apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/apple.imageset/apple.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/apple_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "apple_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/apple_btn.imageset/apple_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/apple_btn.imageset/apple_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/auto_&_transport.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "auto_&_transport.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/auto_&_transport.imageset/auto_&_transport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/auto_&_transport.imageset/auto_&_transport.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "back.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/back.imageset/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/back.imageset/back.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/bottom_bar_bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "bottom_bar_bg.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/bottom_bar_bg.imageset/bottom_bar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/bottom_bar_bg.imageset/bottom_bar_bg.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/budgets.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "budgets.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/budgets.imageset/budgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/budgets.imageset/budgets.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/calendar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "calendar.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/calendar.imageset/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/calendar.imageset/calendar.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/card_blank.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "card_blank.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/card_blank.imageset/card_blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/card_blank.imageset/card_blank.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/center_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "center_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/center_btn.imageset/center_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/center_btn.imageset/center_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/chart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "chart.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/chart.imageset/chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/chart.imageset/chart.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/creditcards.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "creditcards.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/creditcards.imageset/creditcards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/creditcards.imageset/creditcards.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/dorp_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "dorp_down.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/dorp_down.imageset/dorp_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/dorp_down.imageset/dorp_down.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/entertainment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "entertainment.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/entertainment.imageset/entertainment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/entertainment.imageset/entertainment.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/face_id.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "face_id.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/face_id.imageset/face_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/face_id.imageset/face_id.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/fb.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fb.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/fb.imageset/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/fb.imageset/fb.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/fb_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fb_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/fb_btn.imageset/fb_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/fb_btn.imageset/fb_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/font.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "font.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/font.imageset/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/font.imageset/font.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/google.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "google.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/google.imageset/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/google.imageset/google.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/google_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "google_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/google_btn.imageset/google_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/google_btn.imageset/google_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/hbo_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "hbo_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/hbo_logo.imageset/hbo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/hbo_logo.imageset/hbo_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "home.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/home.imageset/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/home.imageset/home.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/home_bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "home_bg.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/home_bg.imageset/home_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/home_bg.imageset/home_bg.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/icloud.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icloud.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/icloud.imageset/icloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/icloud.imageset/icloud.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/light_theme.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "light_theme.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/light_theme.imageset/light_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/light_theme.imageset/light_theme.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/mastercard_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "mastercard_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/mastercard_logo.imageset/mastercard_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/mastercard_logo.imageset/mastercard_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/minus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "minus.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/minus.imageset/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/minus.imageset/minus.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/money.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "money.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/money.imageset/money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/money.imageset/money.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/netflix_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "netflix_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/netflix_logo.imageset/netflix_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/netflix_logo.imageset/netflix_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/next.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "next.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/next.imageset/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/next.imageset/next.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/onedrive_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "onedrive_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/onedrive_logo.imageset/onedrive_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/onedrive_logo.imageset/onedrive_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/plus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "plus.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/plus.imageset/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/plus.imageset/plus.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/primary_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "primary_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/primary_btn.imageset/primary_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/primary_btn.imageset/primary_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/secodry_btn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "secodry_btn.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/secodry_btn.imageset/secodry_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/secodry_btn.imageset/secodry_btn.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/security.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "security.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/security.imageset/security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/security.imageset/security.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/settings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "settings.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/settings.imageset/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/settings.imageset/settings.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/sorting.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sorting.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/sorting.imageset/sorting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/sorting.imageset/sorting.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/spotify_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "spotify_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/spotify_logo.imageset/spotify_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/spotify_logo.imageset/spotify_logo.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/u1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "u1.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/u1.imageset/u1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/u1.imageset/u1.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/welcome_screen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "welcome_screen.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/welcome_screen.imageset/welcome_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/welcome_screen.imageset/welcome_screen.png -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/youtube_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "youtube_logo.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Trackizer/Assets.xcassets/youtube_logo.imageset/youtube_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Assets.xcassets/youtube_logo.imageset/youtube_logo.png -------------------------------------------------------------------------------- /Trackizer/Font/Inter-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Font/Inter-Bold.ttf -------------------------------------------------------------------------------- /Trackizer/Font/Inter-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Font/Inter-Medium.ttf -------------------------------------------------------------------------------- /Trackizer/Font/Inter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Font/Inter-Regular.ttf -------------------------------------------------------------------------------- /Trackizer/Font/Inter-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforany/montly_expenses_trackizer_app_swiftui/f9558a44e65534d07d7b57f11f88abc63550f21a/Trackizer/Font/Inter-SemiBold.ttf -------------------------------------------------------------------------------- /Trackizer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | Inter-Bold.ttf 8 | Inter-Medium.ttf 9 | Inter-Regular.ttf 10 | Inter-SemiBold.ttf 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Trackizer/Model/ArcModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArcModel.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 14/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ArcModel: Identifiable, Equatable { 11 | 12 | 13 | var id: UUID = UUID() 14 | var value: Double = 20 15 | var color: Color = .secondaryC 16 | var statVal: Double = 0 17 | 18 | static func == (lhs: ArcModel, rhs: ArcModel) -> Bool { 19 | return lhs.id == rhs.id 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Trackizer/Model/BudgetModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BudgetModel.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BudgetModel: Identifiable, Equatable { 11 | 12 | 13 | var id: UUID = UUID() 14 | var name: String = "" 15 | var icon: String = "" 16 | var spend_amount: String = "" 17 | var total_amount: String = "" 18 | var left_amount: String = "" 19 | var color: Color = .secondaryC 20 | var perSpend: Double = 0.0 21 | 22 | 23 | init(dict: NSDictionary) { 24 | self.name = dict.value(forKey: "name") as? String ?? "" 25 | self.icon = dict.value(forKey: "icon") as? String ?? "" 26 | self.spend_amount = dict.value(forKey: "spend_amount") as? String ?? "" 27 | self.total_amount = dict.value(forKey: "total_amount") as? String ?? "" 28 | self.left_amount = dict.value(forKey: "left_amount") as? String ?? "" 29 | self.color = dict.value(forKey: "color") as? Color ?? .secondaryC 30 | self.perSpend = ( (Double(self.left_amount ) ?? 0) / (Double(self.total_amount) ?? 1.0) ) 31 | } 32 | 33 | static func == (lhs: BudgetModel, rhs: BudgetModel) -> Bool { 34 | return lhs.id == rhs.id 35 | } 36 | 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Trackizer/Model/CreditCardModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CreditCardModel.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 18/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CreditCardModel: Identifiable { 11 | var id: UUID = UUID() 12 | var name: String = "" 13 | var number: String = "" 14 | var month_year: String = "" 15 | } 16 | -------------------------------------------------------------------------------- /Trackizer/Model/SubscriptionModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscriptionModel.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SubscriptionModel: Identifiable, Equatable { 11 | 12 | var id: UUID = UUID() 13 | var itemId: Int = 0 14 | var name: String = "" 15 | var price: String = "" 16 | var icon: String = "" 17 | 18 | 19 | init(dict: NSDictionary) { 20 | self.itemId = dict.value(forKey: "id") as? Int ?? 0 21 | self.name = dict.value(forKey: "name") as? String ?? "" 22 | self.price = dict.value(forKey: "price") as? String ?? "" 23 | self.icon = dict.value(forKey: "icon") as? String ?? "" 24 | } 25 | 26 | static func == (lhs: SubscriptionModel, rhs: SubscriptionModel) -> Bool { 27 | return lhs.id == rhs.id 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Trackizer/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Trackizer/TrackizerApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrackizerApp.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct TrackizerApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | 15 | NavigationView { 16 | WelcomView() 17 | } 18 | 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Trackizer/UICommon/ArcShape.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArcShape.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ArcShape: Shape { 11 | 12 | var start: Double = 0 13 | var end: Double = 270 14 | var width: Double = 15 15 | 16 | func path(in rect: CGRect) -> Path { 17 | var p = Path() 18 | let startVal = (start + 135) 19 | 20 | p.addArc(center: CGPoint(x: rect.width / 2, y: rect.height / 2), radius: rect.width / 2, startAngle: .degrees(startVal.truncatingRemainder(dividingBy: 360)), endAngle: .degrees((startVal + end).truncatingRemainder(dividingBy: 360)) , clockwise: false) 21 | 22 | return p.strokedPath(.init(lineWidth: width, lineCap: .round)) 23 | } 24 | } 25 | 26 | struct ArcShape180: Shape { 27 | 28 | var start: Double = 0 29 | var end: Double = 180 30 | var width: Double = 15 31 | 32 | func path(in rect: CGRect) -> Path { 33 | var p = Path() 34 | let startVal = (start + 180) 35 | 36 | p.addArc(center: CGPoint(x: rect.width / 2, y: rect.height), radius: rect.width / 2, startAngle: .degrees(startVal.truncatingRemainder(dividingBy: 360)), endAngle: .degrees((startVal + end).truncatingRemainder(dividingBy: 360)) , clockwise: false) 37 | 38 | return p.strokedPath(.init(lineWidth: width, lineCap: .round)) 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Trackizer/UICommon/BudgetRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BudgetRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BudgetRow: View { 11 | @State var bObj: BudgetModel = BudgetModel(dict: [ "name": "Auto & Transport", 12 | "icon": "auto_&_transport", 13 | "spend_amount": "25.99", 14 | "total_amount": "400", 15 | "left_amount": "250.01", 16 | "color": Color.secondaryG ] ) 17 | var body: some View { 18 | 19 | VStack{ 20 | HStack{ 21 | 22 | Image(bObj.icon) 23 | .resizable() 24 | .frame(width: 30, height: 30) 25 | .foregroundColor(.gray40) 26 | 27 | VStack{ 28 | Text(bObj.name) 29 | .font(.customfont(.semibold, fontSize: 14)) 30 | .foregroundColor(.white) 31 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 32 | 33 | Text("$\(bObj.left_amount) left to spend") 34 | .font(.customfont(.semibold, fontSize: 12)) 35 | .foregroundColor(.gray30) 36 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 37 | } 38 | 39 | VStack(alignment: .trailing){ 40 | Text("$\(bObj.total_amount)") 41 | .font(.customfont(.semibold, fontSize: 14)) 42 | .foregroundColor(.white) 43 | .frame(alignment: .trailing) 44 | 45 | Text("of $\(bObj.left_amount)") 46 | .font(.customfont(.semibold, fontSize: 12)) 47 | .foregroundColor(.gray30) 48 | .frame(alignment: .trailing) 49 | } 50 | } 51 | ProgressView(value: bObj.perSpend, total: 1) 52 | .tint(bObj.color) 53 | } 54 | 55 | .padding(15) 56 | .frame(minWidth: 0, maxWidth: .infinity) 57 | .background(Color.gray60.opacity( 0.2 )) 58 | .overlay { 59 | RoundedRectangle(cornerRadius: 12) 60 | .stroke( Color.gray70, lineWidth: 1) 61 | } 62 | .cornerRadius(12) 63 | } 64 | } 65 | 66 | struct BudgetRow_Previews: PreviewProvider { 67 | static var previews: some View { 68 | BudgetRow() 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Trackizer/UICommon/CarouselView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarouselView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 15/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct Carousel : View { 11 | let items: Items 12 | let numberOfItems: CGFloat //= 8 13 | let spacing: CGFloat //= 16 14 | let widthOfHiddenCards: CGFloat //= 32 15 | let totalSpacing: CGFloat 16 | let cardWidth: CGFloat 17 | 18 | @GestureState var isDetectingLongPress = false 19 | 20 | @EnvironmentObject var UIState: UIStateModel 21 | 22 | @inlinable public init( 23 | numberOfItems: CGFloat, 24 | spacing: CGFloat, 25 | widthOfHiddenCards: CGFloat, 26 | @ViewBuilder _ items: () -> Items) { 27 | 28 | self.items = items() 29 | self.numberOfItems = numberOfItems 30 | self.spacing = spacing 31 | self.widthOfHiddenCards = widthOfHiddenCards 32 | self.totalSpacing = (numberOfItems - 1) * spacing 33 | self.cardWidth = UIScreen.main.bounds.width - (widthOfHiddenCards*2) - (spacing*2) //279 34 | 35 | } 36 | 37 | var body: some View { 38 | 39 | let totalCanvasWidth: CGFloat = (cardWidth * numberOfItems) + totalSpacing 40 | let xOffsetToShift = (totalCanvasWidth - UIScreen.main.bounds.width) / 2 41 | let leftPadding = widthOfHiddenCards + spacing 42 | let totalMovement = cardWidth + spacing 43 | 44 | let activeOffset = xOffsetToShift + (leftPadding) - (totalMovement * CGFloat(UIState.activeCard)) 45 | let nextOffset = xOffsetToShift + (leftPadding) - (totalMovement * CGFloat(UIState.activeCard) + 1) 46 | 47 | var calcOffset = Float(activeOffset) 48 | 49 | if (calcOffset != Float(nextOffset)) { 50 | calcOffset = Float(activeOffset) + UIState.screenDrag 51 | } 52 | 53 | return HStack(alignment: .center, spacing: spacing) { 54 | items 55 | } 56 | .offset(x: CGFloat(calcOffset), y: 0) 57 | .gesture(DragGesture().updating($isDetectingLongPress) { currentState, gestureState, transaction in 58 | self.UIState.screenDrag = Float(currentState.translation.width) 59 | 60 | }.onEnded { value in 61 | self.UIState.screenDrag = 0 62 | 63 | if (value.translation.width < -50) { 64 | self.UIState.activeCard = self.UIState.activeCard + 1 65 | let impactMed = UIImpactFeedbackGenerator(style: .medium) 66 | impactMed.impactOccurred() 67 | } 68 | 69 | if (value.translation.width > 50) { 70 | self.UIState.activeCard = self.UIState.activeCard - 1 71 | let impactMed = UIImpactFeedbackGenerator(style: .medium) 72 | impactMed.impactOccurred() 73 | } 74 | }) 75 | } 76 | } 77 | 78 | struct Item: View { 79 | @EnvironmentObject var UIState: UIStateModel 80 | let cardWidth: CGFloat 81 | let cardHeight: CGFloat 82 | 83 | var _id: Int 84 | var content: Content 85 | 86 | @inlinable public init( 87 | _id: Int, 88 | spacing: CGFloat, 89 | widthOfHiddenCards: CGFloat, 90 | cardHeight: CGFloat, 91 | @ViewBuilder _ content: () -> Content 92 | ) { 93 | self.content = content() 94 | self.cardWidth = UIScreen.main.bounds.width - (widthOfHiddenCards*2) - (spacing*2) //279 95 | self.cardHeight = cardHeight 96 | self._id = _id 97 | } 98 | 99 | var body: some View { 100 | content 101 | .frame(width: cardWidth, height: _id == UIState.activeCard ? cardHeight : cardHeight - 60, alignment: .center) 102 | } 103 | } 104 | 105 | struct Canvas : View { 106 | let content: Content 107 | @EnvironmentObject var UIState: UIStateModel 108 | 109 | @inlinable init(@ViewBuilder _ content: () -> Content) { 110 | self.content = content() 111 | } 112 | 113 | var body: some View { 114 | content 115 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center) 116 | 117 | .background(Color.gray60.opacity(0.01).edgesIgnoringSafeArea(.all)) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Trackizer/UICommon/IconItemRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IconItemRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 16/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct IconItemRow: View { 11 | @State var icon: String = "face_id" 12 | @State var title: String = "Title" 13 | @State var value: String = "Value" 14 | 15 | var body: some View { 16 | HStack{ 17 | Image(icon) 18 | .resizable() 19 | .scaledToFit() 20 | .frame(width: 20, height: 20) 21 | 22 | Text(title) 23 | .font(.customfont(.semibold, fontSize: 14)) 24 | .foregroundColor(.white) 25 | 26 | Spacer() 27 | 28 | 29 | Text(value) 30 | .font(.customfont(.medium, fontSize: 14)) 31 | .foregroundColor(.gray30) 32 | 33 | Image("next") 34 | .resizable() 35 | .frame(width: 12, height: 12) 36 | } 37 | .padding(.horizontal, 20) 38 | .padding(.vertical, 8) 39 | } 40 | } 41 | 42 | struct IconItemRow_Previews: PreviewProvider { 43 | static var previews: some View { 44 | IconItemRow() 45 | .background(Color.gray60.opacity(0.2)) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Trackizer/UICommon/IconItemSwitchRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IconItemSwitchRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 16/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct IconItemSwitchRow: View { 11 | @State var icon: String = "face_id" 12 | @State var title: String = "Title" 13 | @Binding var value: Bool 14 | 15 | var body: some View { 16 | HStack{ 17 | Image(icon) 18 | .resizable() 19 | .scaledToFit() 20 | .frame(width: 20, height: 20) 21 | 22 | Text(title) 23 | .font(.customfont(.semibold, fontSize: 14)) 24 | .foregroundColor(.white) 25 | 26 | Spacer() 27 | 28 | 29 | Toggle(isOn: $value) { 30 | 31 | } 32 | } 33 | .padding(.horizontal, 20) 34 | .padding(.vertical, 8) 35 | } 36 | } 37 | 38 | struct IconItemSwitchRow_Previews: PreviewProvider { 39 | @State static var isNO: Bool = false 40 | static var previews: some View { 41 | IconItemSwitchRow( value: $isNO) 42 | .background(Color.gray60.opacity(0.2)) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Trackizer/UICommon/ItemRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ItemRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 16/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ItemRow: View { 11 | @State var title: String = "Title" 12 | @State var value: String = "Value" 13 | 14 | var body: some View { 15 | HStack{ 16 | Text(title) 17 | .font(.customfont(.semibold, fontSize: 14)) 18 | .foregroundColor(.white) 19 | Spacer() 20 | Text(value) 21 | .font(.customfont(.medium, fontSize: 14)) 22 | .foregroundColor(.gray30) 23 | 24 | Image("next") 25 | .resizable() 26 | .frame(width: 12, height: 12) 27 | } 28 | .padding(.horizontal, 20) 29 | .padding(.vertical, 15) 30 | } 31 | } 32 | 33 | struct ItemRow_Previews: PreviewProvider { 34 | static var previews: some View { 35 | ItemRow() 36 | .background(Color.gray60.opacity(0.2)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Trackizer/UICommon/PrimaryButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrimaryButton.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct PrimaryButton: View { 11 | @State var title: String = "Title" 12 | var onPressed: (()->())? 13 | 14 | var body: some View { 15 | Button { 16 | onPressed?() 17 | } label: { 18 | ZStack{ 19 | Image("primary_btn") 20 | .resizable() 21 | .scaledToFill() 22 | .padding(.horizontal, 20) 23 | .frame(width: .screenWidth, height: 48) 24 | 25 | Text(title) 26 | .font(.customfont(.semibold, fontSize: 14)) 27 | .padding(.horizontal, 20) 28 | } 29 | } 30 | .foregroundColor(.white) 31 | .shadow(color: .secondaryC.opacity(0.3), radius: 5, y: 3) 32 | } 33 | } 34 | 35 | struct PrimaryButton_Previews: PreviewProvider { 36 | static var previews: some View { 37 | PrimaryButton() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Trackizer/UICommon/RoundTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RoundTextField.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RoundTextField: View { 11 | 12 | @State var title: String = "Title" 13 | @Binding var text: String 14 | @State var keyboardType: UIKeyboardType = .default 15 | var textAlign:Alignment = .leading 16 | var isPassword: Bool = false 17 | 18 | var body: some View { 19 | VStack{ 20 | Text(title) 21 | .multilineTextAlignment(.leading) 22 | .font(.customfont(.regular, fontSize: 14)) 23 | .frame(minWidth: 0, maxWidth: .infinity, alignment: textAlign) 24 | 25 | .foregroundColor(.gray50) 26 | .padding(.bottom, 4) 27 | 28 | 29 | if(isPassword) { 30 | SecureField("", text: $text) 31 | .padding(15) 32 | 33 | .frame(height: 48) 34 | .overlay { 35 | RoundedRectangle(cornerRadius: 15) 36 | .stroke(Color.gray70, lineWidth: 1) 37 | } 38 | .foregroundColor(.white) 39 | .background(Color.gray60.opacity(0.05)) 40 | .cornerRadius(15) 41 | }else{ 42 | TextField("", text: $text) 43 | .padding(15) 44 | .keyboardType(keyboardType) 45 | .frame(height: 48) 46 | .overlay { 47 | RoundedRectangle(cornerRadius: 15) 48 | .stroke(Color.gray70, lineWidth: 1) 49 | } 50 | .foregroundColor(.white) 51 | .background(Color.gray60.opacity(0.05)) 52 | .cornerRadius(15) 53 | } 54 | 55 | 56 | 57 | } 58 | } 59 | } 60 | 61 | struct RoundTextField_Previews: PreviewProvider { 62 | @State static var txt: String = "" 63 | static var previews: some View { 64 | RoundTextField(text: $txt) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Trackizer/UICommon/SecondaryButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondaryButton.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SecondaryButton: View { 11 | @State var title: String = "Title" 12 | var onPressed: (()->())? 13 | 14 | var body: some View { 15 | Button { 16 | onPressed?() 17 | } label: { 18 | ZStack{ 19 | Image("secodry_btn") 20 | .resizable() 21 | .scaledToFill() 22 | .padding(.horizontal, 20) 23 | .frame(width: .infinity, height: 48) 24 | 25 | Text(title) 26 | .font(.customfont(.semibold, fontSize: 14)) 27 | .padding(.horizontal, 20) 28 | } 29 | } 30 | .foregroundColor(.white) 31 | 32 | } 33 | } 34 | 35 | struct SecondaryButton_Previews: PreviewProvider { 36 | static var previews: some View { 37 | SecondaryButton() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Trackizer/UICommon/SegmentButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SegmentButton.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SegmentButton: View { 11 | @State var title: String = "Title" 12 | var isActive: Bool = false 13 | var onPressed: ( ()->())? 14 | 15 | var body: some View { 16 | Button { 17 | onPressed?() 18 | } label: { 19 | Text(title) 20 | .font(.customfont(.semibold, fontSize: 12)) 21 | } 22 | .foregroundColor( isActive ? .white : .gray30 ) 23 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 42, maxHeight: 42) 24 | 25 | .background(Color.gray60.opacity( isActive ? 0.2 : 0.0 )) 26 | .overlay { 27 | RoundedRectangle(cornerRadius: 12) 28 | .stroke( isActive ? Color.gray70 : .clear, lineWidth: 1) 29 | } 30 | .cornerRadius(12) 31 | } 32 | } 33 | 34 | struct SegmentButton_Previews: PreviewProvider { 35 | static var previews: some View { 36 | SegmentButton() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Trackizer/UICommon/StatusButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatusButton.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct StatusButton: View { 11 | @State var title: String = "Title" 12 | @State var value: String = "10" 13 | @State var color: Color = .secondaryC 14 | var onPressed: (()->())? 15 | var body: some View { 16 | 17 | Button { 18 | onPressed?() 19 | } label: { 20 | ZStack(alignment: .top){ 21 | VStack{ 22 | VStack{ 23 | Text(title) 24 | .font(.customfont(.semibold, fontSize: 12)) 25 | .foregroundColor(.gray40) 26 | 27 | Text(value) 28 | .font(.customfont(.semibold, fontSize: 14)) 29 | .foregroundColor(.white) 30 | } 31 | } 32 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 68, maxHeight: 68) 33 | 34 | .background(Color.gray60.opacity( 0.2 )) 35 | .overlay { 36 | RoundedRectangle(cornerRadius: 16) 37 | .stroke( Color.gray30.opacity(0.5), lineWidth: 1) 38 | } 39 | .cornerRadius(16) 40 | 41 | Rectangle() 42 | .fill(color) 43 | .frame(width: 60, height: 1, alignment: .center) 44 | } 45 | } 46 | 47 | 48 | } 49 | } 50 | 51 | struct StatusButton_Previews: PreviewProvider { 52 | static var previews: some View { 53 | StatusButton() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Trackizer/UICommon/SubScriptionHomeRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubScriptionHomeRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SubScriptionHomeRow: View { 11 | @State var sObj: SubscriptionModel = SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 12 | var body: some View { 13 | HStack{ 14 | 15 | Image(sObj.icon) 16 | .resizable() 17 | .frame(width: 40, height: 40) 18 | 19 | Text(sObj.name) 20 | .font(.customfont(.semibold, fontSize: 14)) 21 | .foregroundColor(.white) 22 | 23 | Spacer() 24 | 25 | Text( "$\(sObj.price)" ) 26 | .font(.customfont(.semibold, fontSize: 14)) 27 | .foregroundColor(.white) 28 | 29 | 30 | 31 | } 32 | .padding(15) 33 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 64, maxHeight: 64) 34 | 35 | .background(Color.gray60.opacity( 0.2 )) 36 | .overlay { 37 | RoundedRectangle(cornerRadius: 12) 38 | .stroke( Color.gray70, lineWidth: 1) 39 | } 40 | .cornerRadius(12) 41 | } 42 | } 43 | 44 | struct SubScriptionHomeRow_Previews: PreviewProvider { 45 | static var previews: some View { 46 | SubScriptionHomeRow() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Trackizer/UICommon/SubscriptionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscriptionCell.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 15/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SubscriptionCell: View { 11 | @State var sObj: SubscriptionModel = SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 12 | var body: some View { 13 | VStack(alignment: .leading, spacing: 4){ 14 | 15 | Image(sObj.icon) 16 | .resizable() 17 | .frame(width: 45, height: 45) 18 | 19 | Spacer() 20 | 21 | Text(sObj.name) 22 | .font(.customfont(.semibold, fontSize: 14)) 23 | .foregroundColor(.white) 24 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 25 | 26 | 27 | 28 | Text( "$\(sObj.price)" ) 29 | .font(.customfont(.bold, fontSize: 20)) 30 | .foregroundColor(.white) 31 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 32 | 33 | 34 | 35 | } 36 | .padding(15) 37 | .frame(minWidth: 0, maxWidth: .infinity) 38 | .aspectRatio(1, contentMode: .fill) 39 | .background(Color.gray60.opacity( 0.2 )) 40 | .overlay { 41 | RoundedRectangle(cornerRadius: 12) 42 | .stroke( Color.gray70, lineWidth: 1) 43 | } 44 | .cornerRadius(12) 45 | } 46 | } 47 | 48 | struct SubscriptionCell_Previews: PreviewProvider { 49 | static var previews: some View { 50 | SubscriptionCell() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Trackizer/UICommon/UIExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIExtension.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | enum Inter: String { 11 | case regular = "Inter-Regular" 12 | case medium = "Inter-Medium" 13 | case semibold = "Inter-SemiBold" 14 | case bold = "Inter-Bold" 15 | } 16 | 17 | extension Font { 18 | 19 | static func customfont(_ font: Inter, fontSize: CGFloat) -> Font { 20 | custom(font.rawValue, size: fontSize) 21 | } 22 | } 23 | 24 | extension CGFloat { 25 | 26 | static var screenWidth: Double { 27 | return UIScreen.main.bounds.size.width 28 | } 29 | 30 | static var screenHeight: Double { 31 | return UIScreen.main.bounds.size.height 32 | } 33 | 34 | static func widthPer(per: Double) -> Double { 35 | return screenWidth * per 36 | } 37 | 38 | static func heightPer(per: Double) -> Double { 39 | return screenHeight * per 40 | } 41 | 42 | static var topInsets: Double { 43 | if let keyWindow = UIApplication.shared.keyWindow { 44 | return keyWindow.safeAreaInsets.top 45 | } 46 | return 0.0 47 | } 48 | 49 | static var bottomInsets: Double { 50 | if let keyWindow = UIApplication.shared.keyWindow { 51 | return keyWindow.safeAreaInsets.bottom 52 | } 53 | return 0.0 54 | } 55 | 56 | static var horizontalInsets: Double { 57 | if let keyWindow = UIApplication.shared.keyWindow { 58 | return keyWindow.safeAreaInsets.left + keyWindow.safeAreaInsets.right 59 | } 60 | return 0.0 61 | } 62 | 63 | static var verticalInsets: Double { 64 | if let keyWindow = UIApplication.shared.keyWindow { 65 | return keyWindow.safeAreaInsets.top + keyWindow.safeAreaInsets.bottom 66 | } 67 | return 0.0 68 | } 69 | 70 | } 71 | 72 | extension Color { 73 | 74 | static var primary: Color { 75 | return Color(hex: "5E00F5") 76 | } 77 | static var primary500: Color { 78 | return Color(hex: "7722FF") 79 | } 80 | static var primary20: Color { 81 | return Color(hex: "924EFF") 82 | } 83 | static var primary10: Color { 84 | return Color(hex: "AD7BFF") 85 | } 86 | static var primary5: Color { 87 | return Color(hex: "C9A7FF") 88 | } 89 | static var primary0: Color { 90 | return Color(hex: "E4D3FF") 91 | } 92 | 93 | static var secondaryC: Color { 94 | return Color(hex: "FF7966") 95 | } 96 | 97 | static var secondary50: Color { 98 | return Color(hex: "FFA699") 99 | } 100 | 101 | static var secondary0: Color { 102 | return Color(hex: "FFD2CC") 103 | } 104 | 105 | static var secondaryG: Color { 106 | return Color(hex: "00FAD9") 107 | } 108 | 109 | static var secondaryG50: Color { 110 | return Color(hex: "7DFFEE") 111 | } 112 | 113 | static var grayC: Color { 114 | return Color(hex: "0E0E12") 115 | } 116 | static var gray80: Color { 117 | return Color(hex: "1C1C23") 118 | } 119 | static var gray70: Color { 120 | return Color(hex: "353542") 121 | } 122 | static var gray60: Color { 123 | return Color(hex: "4E4E61") 124 | } 125 | static var gray50: Color { 126 | return Color(hex: "666680") 127 | } 128 | static var gray40: Color { 129 | return Color(hex: "83839C") 130 | } 131 | static var gray30: Color { 132 | return Color(hex: "A2A2B5") 133 | } 134 | static var gray20: Color { 135 | return Color(hex: "C1C1CD") 136 | } 137 | 138 | static var gray10: Color { 139 | return Color(hex: "E0E0E6") 140 | } 141 | 142 | static var primaryText: Color { 143 | return Color.white 144 | } 145 | 146 | static var secondaryText: Color { 147 | return .gray60 148 | } 149 | 150 | 151 | init(hex: String) { 152 | let hex = hex.trimmingCharacters(in: .alphanumerics.inverted) 153 | var int: UInt64 = 0 154 | Scanner(string: hex).scanHexInt64(&int) 155 | let a, r, g, b: UInt64 156 | switch hex.count { 157 | case 3: // RGB(12 -bit) 158 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) 159 | case 6: // RGB (24-bit) 160 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) 161 | case 8: // ARGB (32-bit) 162 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) 163 | default: 164 | (a, r, g, b) = (1, 1, 1, 0) 165 | } 166 | 167 | self.init( 168 | .sRGB, 169 | red: Double(r) / 255, 170 | green: Double(g) / 255, 171 | blue: Double(b) / 255, 172 | opacity: Double(a) / 255 173 | ) 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Trackizer/UICommon/UpcomingBillRow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UpcomingBillRow.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct UpcomingBillRow: View { 11 | @State var sObj: SubscriptionModel = SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 12 | var body: some View { 13 | HStack{ 14 | 15 | ZStack{ 16 | 17 | VStack{ 18 | Text("JUN") 19 | .font(.customfont(.medium, fontSize: 10)) 20 | .foregroundColor(.gray30) 21 | 22 | Text("25") 23 | .font(.customfont(.semibold, fontSize: 14)) 24 | .foregroundColor(.white) 25 | } 26 | 27 | } 28 | .frame(width: 40, height: 40) 29 | .background(Color.gray60.opacity( 0.2 )) 30 | .overlay { 31 | RoundedRectangle(cornerRadius: 12) 32 | .stroke( Color.gray70, lineWidth: 1) 33 | } 34 | .cornerRadius(12) 35 | 36 | Text(sObj.name) 37 | .font(.customfont(.semibold, fontSize: 14)) 38 | .foregroundColor(.white) 39 | 40 | Spacer() 41 | 42 | Text( "$\(sObj.price)" ) 43 | .font(.customfont(.semibold, fontSize: 14)) 44 | .foregroundColor(.white) 45 | 46 | 47 | 48 | } 49 | .padding(15) 50 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 64, maxHeight: 64) 51 | 52 | .background(Color.gray60.opacity( 0.2 )) 53 | .overlay { 54 | RoundedRectangle(cornerRadius: 12) 55 | .stroke( Color.gray70, lineWidth: 1) 56 | } 57 | .cornerRadius(12) 58 | } 59 | } 60 | 61 | struct UpcomingBillRow_Previews: PreviewProvider { 62 | static var previews: some View { 63 | UpcomingBillRow() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Trackizer/View/AddSubscription/AddSubscruiptionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddSubscruiptionView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 15/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct AddSubscruiptionView: View { 11 | var UIState: UIStateModel 12 | @State var txtDescription: String = "" 13 | 14 | @State var subArr: [SubscriptionModel] = [ 15 | SubscriptionModel(dict: ["id":0,"name":"HBO GO", "icon":"hbo_logo", "price": "5.99"] ) 16 | , 17 | SubscriptionModel(dict: ["id":1,"name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 18 | , 19 | SubscriptionModel(dict: ["id":2, 20 | "name": "YouTube Premium", 21 | "icon": "youtube_logo", 22 | "price": "18.99"] ) 23 | , 24 | SubscriptionModel(dict: ["id":3,"name": "Microsoft OneDrive", 25 | "icon": "onedrive_logo", 26 | "price": "29.99"] ) 27 | , 28 | SubscriptionModel(dict: ["name": "NetFlix", "icon": "netflix_logo", "price": "15.00"] ) 29 | ] 30 | 31 | @State var amountVal: Double = 0.09 32 | 33 | var body: some View { 34 | 35 | let spacing: CGFloat = 16 36 | let widthOfHiddenCards: CGFloat = 80 // UIScreen.main.bounds.width - 10 37 | let cardHeight: CGFloat = 200 38 | 39 | ScrollView { 40 | 41 | ZStack(alignment: .center) { 42 | 43 | Rectangle() 44 | .foregroundColor(.gray70.opacity(0.5)) 45 | .frame(width: .screenWidth ) 46 | .cornerRadius(25) 47 | 48 | VStack{ 49 | 50 | ZStack{ 51 | HStack{ 52 | Button { 53 | 54 | } label: { 55 | Image("back") 56 | .resizable() 57 | .frame(width: 25, height: 25) 58 | } 59 | 60 | Spacer() 61 | 62 | } 63 | 64 | HStack{ 65 | Spacer() 66 | 67 | Text("New") 68 | .font(.customfont(.regular, fontSize: 16)) 69 | 70 | 71 | Spacer() 72 | 73 | } 74 | } 75 | 76 | .foregroundColor(.gray30) 77 | 78 | 79 | Text("Add new\nsubscription") 80 | .font(.customfont(.bold, fontSize: 40)) 81 | .multilineTextAlignment(.center) 82 | .foregroundColor(.white) 83 | .padding(.vertical, 20) 84 | 85 | Canvas 86 | { 87 | Carousel( numberOfItems: CGFloat( subArr.count ), spacing: spacing, widthOfHiddenCards: widthOfHiddenCards ) 88 | { 89 | ForEach( subArr, id: \.self.id ) { item in 90 | Item( _id: Int(item.itemId), 91 | spacing: spacing, 92 | widthOfHiddenCards: widthOfHiddenCards, 93 | cardHeight: cardHeight ) 94 | { 95 | 96 | VStack{ 97 | 98 | Image(item.icon) 99 | .resizable() 100 | .scaledToFit() 101 | 102 | Spacer() 103 | .frame(height: 20) 104 | Text("\(item.name)") 105 | } 106 | 107 | 108 | } 109 | .foregroundColor( .gray30 ) 110 | .cornerRadius( 8 ) 111 | .shadow( radius: 4, x: 0, y: 4 ) 112 | .transition( AnyTransition.slide ) 113 | .animation( .spring() ) 114 | } 115 | } 116 | .environmentObject( self.UIState ) 117 | } 118 | .padding(.vertical, 20) 119 | 120 | 121 | } 122 | .padding(.top, .topInsets) 123 | .padding(.horizontal, 20) 124 | 125 | 126 | } 127 | .frame(width: .screenWidth ) 128 | 129 | RoundTextField(title: "Description", text: $txtDescription, textAlign: .center) 130 | .frame(width: .screenWidth - 40 ) 131 | .padding(.top, 20) 132 | 133 | HStack { 134 | 135 | Button { 136 | amountVal -= 0.1 137 | if(amountVal < 0.0) { 138 | amountVal = 0.0 139 | } 140 | } label: { 141 | Image("minus") 142 | .resizable() 143 | .frame(width: 50, height: 50) 144 | } 145 | .background(Color.gray60.opacity(0.2)) 146 | .overlay { 147 | RoundedRectangle(cornerRadius: 12) 148 | .stroke( 149 | Color.gray70 , lineWidth: 1) 150 | } 151 | .cornerRadius(16) 152 | 153 | Spacer() 154 | 155 | VStack(spacing:0){ 156 | Text("Mothly price") 157 | .font(.customfont(.semibold, fontSize: 12)) 158 | .foregroundColor(.gray40) 159 | Spacer() 160 | .frame(height: 4) 161 | Text("$\( amountVal, specifier: "%.2f" )") 162 | .font(.customfont(.bold, fontSize: 40)) 163 | .foregroundColor(.white) 164 | Spacer() 165 | .frame(height: 8) 166 | Rectangle() 167 | .fill(Color.gray70) 168 | .frame(width: 150, height: 1) 169 | } 170 | 171 | Spacer() 172 | 173 | 174 | 175 | Button { 176 | amountVal += 0.1 177 | } label: { 178 | Image("plus") 179 | .resizable() 180 | .frame(width: 50, height: 50) 181 | } 182 | .background(Color.gray60.opacity(0.2)) 183 | .overlay { 184 | RoundedRectangle(cornerRadius: 12) 185 | .stroke( 186 | Color.gray70 , lineWidth: 1) 187 | } 188 | .cornerRadius(16) 189 | 190 | 191 | } 192 | .padding(40) 193 | 194 | 195 | PrimaryButton(title: "Add this platform") { 196 | 197 | } 198 | .padding(.horizontal, 20) 199 | .padding(.bottom, .bottomInsets) 200 | 201 | 202 | } 203 | .background(Color.grayC) 204 | .ignoresSafeArea() 205 | } 206 | } 207 | 208 | struct AddSubscruiptionView_Previews: PreviewProvider { 209 | static var previews: some View { 210 | AddSubscruiptionView(UIState: UIStateModel()) 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /Trackizer/View/Budgets/BudgetsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BudgetsView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 13/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BudgetsView: View { 11 | @State var listArr: [BudgetModel] = [ 12 | BudgetModel(dict: [ "name": "Auto & Transport", 13 | "icon": "auto_&_transport", 14 | "spend_amount": "25.99", 15 | "total_amount": "400", 16 | "left_amount": "250.01", 17 | "color": Color.secondaryG ] ), 18 | 19 | BudgetModel(dict: [ "name": "Entertainment", 20 | "icon": "entertainment", 21 | "spend_amount": "50.99", 22 | "total_amount": "600", 23 | "left_amount": "300.01", 24 | "color": Color.secondaryC ] ), 25 | 26 | BudgetModel(dict: [ "name": "Security", 27 | "icon": "security", 28 | "spend_amount": "5.99", 29 | "total_amount": "600", 30 | "left_amount": "250.01", 31 | "color": Color.primary10 ] ) 32 | ] 33 | 34 | @State var arcArr : [ArcModel] = [] 35 | 36 | var body: some View { 37 | ScrollView { 38 | 39 | 40 | ZStack(alignment: .bottom){ 41 | 42 | 43 | ZStack { 44 | ArcShape180(width: 10) 45 | .foregroundColor(.gray.opacity(0.2)) 46 | 47 | ForEach(arcArr, id: \.id) { aObj in 48 | 49 | ArcShape180(start: aObj.statVal, end: aObj.value - 9, width: 14) 50 | .foregroundColor(aObj.color) 51 | .shadow( color: aObj.color.opacity(0.5), radius: 7) 52 | 53 | } 54 | } 55 | .frame(width: .widthPer(per: 0.5), height: .widthPer(per: 0.3)) 56 | 57 | 58 | VStack{ 59 | Text("$82,90") 60 | .font(.customfont(.bold, fontSize: 24)) 61 | .foregroundColor(.white) 62 | 63 | Text("of $2,0000 budget") 64 | .font(.customfont(.medium, fontSize: 12)) 65 | .foregroundColor(.gray30) 66 | } 67 | 68 | 69 | 70 | } 71 | .padding(.top, 64 ) 72 | .padding(.bottom, 30 ) 73 | 74 | 75 | Button { 76 | 77 | } label: { 78 | Text("Your budgets are on tack 👍") 79 | .font(.customfont(.semibold, fontSize: 14)) 80 | } 81 | .foregroundColor( .white ) 82 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 64, maxHeight: 64) 83 | 84 | 85 | .overlay { 86 | RoundedRectangle(cornerRadius: 16) 87 | .stroke( Color.gray70, lineWidth: 1) 88 | } 89 | .cornerRadius(16) 90 | .padding(.horizontal, 20) 91 | 92 | .padding(.vertical, 10) 93 | 94 | LazyVStack(spacing: 15) { 95 | ForEach( listArr , id: \.id) { bObj in 96 | 97 | BudgetRow(bObj: bObj) 98 | 99 | } 100 | } 101 | .padding(.horizontal, 20) 102 | 103 | 104 | Button { 105 | 106 | } label: { 107 | HStack{ 108 | Text("Add new category ") 109 | .font(.customfont(.semibold, fontSize: 14)) 110 | 111 | Image("add") 112 | .resizable() 113 | .frame(width: 14, height: 14) 114 | } 115 | 116 | } 117 | .foregroundColor( .gray30 ) 118 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 64, maxHeight: 64) 119 | 120 | 121 | .overlay { 122 | RoundedRectangle(cornerRadius: 16) 123 | .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [5,4]) ) 124 | .foregroundColor(.gray30.opacity(0.5)) 125 | 126 | //.stroke( Color.gray70, lineWidth: 1) 127 | } 128 | .cornerRadius(16) 129 | .padding(.horizontal, 20) 130 | .padding(.vertical, 10) 131 | 132 | 133 | } 134 | .onAppear{ 135 | getArcProgressData() 136 | } 137 | .background(Color.grayC) 138 | .ignoresSafeArea() 139 | } 140 | 141 | func getArcProgressData(){ 142 | 143 | var data = [ 144 | ArcModel(value: 20, color: .secondaryG), 145 | ArcModel(value: 45, color: .secondaryC), 146 | ArcModel(value: 70, color: .primary10) 147 | ] 148 | 149 | var val = 0.0 150 | 151 | for i in (0 ..< data.count) { 152 | data[i].statVal = val 153 | val = data[i].statVal + data[i].value + 2 154 | } 155 | 156 | arcArr = data 157 | 158 | } 159 | } 160 | 161 | struct BudgetsView_Previews: PreviewProvider { 162 | static var previews: some View { 163 | BudgetsView() 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Trackizer/View/Calendar/CalendarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 15/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CalendarView: View { 11 | @EnvironmentObject var weekStore: WeekStore 12 | @State var subArr: [SubscriptionModel] = [ 13 | SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 14 | , 15 | SubscriptionModel(dict: [ 16 | "name": "YouTube Premium", 17 | "icon": "youtube_logo", 18 | "price": "18.99"] ) 19 | , 20 | SubscriptionModel(dict: ["name": "Microsoft OneDrive", 21 | "icon": "onedrive_logo", 22 | "price": "29.99"] ) 23 | , 24 | SubscriptionModel(dict: ["name": "NetFlix", "icon": "netflix_logo", "price": "15.00"] ) 25 | ] 26 | let colums = [ 27 | GridItem(.adaptive(minimum: 200)), 28 | GridItem(.adaptive(minimum: 200)) 29 | ] 30 | 31 | var body: some View { 32 | ScrollView { 33 | 34 | ZStack(alignment: .top) { 35 | 36 | Rectangle() 37 | .foregroundColor(.gray70.opacity(0.5)) 38 | .frame(width: .screenWidth ) 39 | .cornerRadius(25) 40 | 41 | VStack{ 42 | Text("Calendar") 43 | .font(.customfont(.regular, fontSize: 16)) 44 | .foregroundColor(.gray30) 45 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .center) 46 | .padding(.horizontal, 20) 47 | .padding(.bottom, 20) 48 | 49 | Text("Subs\nSchedule") 50 | .font(.customfont(.bold, fontSize: 40)) 51 | .foregroundColor(.white) 52 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 53 | .padding(.horizontal, 20) 54 | 55 | WeekHeaderView() 56 | .padding(.horizontal, 20) 57 | 58 | WeeksTabView() { week in 59 | WeekView(week: week) 60 | } 61 | .frame(height: 110, alignment: .top) 62 | .padding(.vertical, 20) 63 | } 64 | .padding(.top, .topInsets) 65 | .padding(.bottom, 20) 66 | 67 | } 68 | .frame(width: .screenWidth ) 69 | 70 | VStack{ 71 | HStack{ 72 | Text("January") 73 | .font(.customfont(.bold, fontSize: 20)) 74 | .foregroundColor(.white) 75 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 76 | 77 | 78 | 79 | Text( "$24.98" ) 80 | .font(.customfont(.bold, fontSize: 20)) 81 | .foregroundColor(.white) 82 | 83 | } 84 | 85 | HStack{ 86 | Text("01.08.2023") 87 | .font(.customfont(.medium, fontSize: 12)) 88 | .foregroundColor(.gray30) 89 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 90 | 91 | 92 | 93 | Text( "in upcoming bills" ) 94 | .font(.customfont(.medium, fontSize: 12)) 95 | .foregroundColor(.gray30) 96 | 97 | } 98 | } 99 | .padding(20) 100 | 101 | LazyVGrid(columns: colums , spacing: 8) { 102 | 103 | ForEach(subArr) { sObj in 104 | SubscriptionCell(sObj: sObj) 105 | } 106 | } 107 | .padding(.horizontal,20) 108 | .padding(.bottom, 120) 109 | 110 | } 111 | .background(Color.grayC) 112 | .ignoresSafeArea() 113 | } 114 | } 115 | 116 | struct CalendarView_Previews: PreviewProvider { 117 | static var previews: some View { 118 | CalendarView() 119 | .environmentObject(WeekStore()) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Trackizer/View/Card/CardsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CardsView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 18/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CardsView: View { 11 | 12 | @State var cardArr: [CreditCardModel] = [ 13 | CreditCardModel(name: "Code for any 1", number: "**** **** **** 2789", month_year: "08/27"), 14 | CreditCardModel(name: "Code for any 2", number: "**** **** **** 2788", month_year: "07/27"), 15 | CreditCardModel(name: "Code for any 3", number: "**** **** **** 2754", month_year: "01/27"), 16 | CreditCardModel(name: "Code for any 4", number: "**** **** **** 2720", month_year: "03/28"), 17 | CreditCardModel(name: "Code for any 5", number: "**** **** **** 2730", month_year: "08/28"), 18 | ] 19 | 20 | @State var subArr: [SubscriptionModel] = [ 21 | SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 22 | , 23 | SubscriptionModel(dict: [ 24 | "name": "YouTube Premium", 25 | "icon": "youtube_logo", 26 | "price": "18.99"] ) 27 | , 28 | SubscriptionModel(dict: ["name": "Microsoft OneDrive", 29 | "icon": "onedrive_logo", 30 | "price": "29.99"] ) 31 | , 32 | SubscriptionModel(dict: ["name": "NetFlix", "icon": "netflix_logo", "price": "15.00"] ) 33 | ] 34 | 35 | var body: some View { 36 | ScrollView { 37 | 38 | 39 | VStack{ 40 | 41 | ZStack{ 42 | HStack{ 43 | Spacer() 44 | Button { 45 | 46 | } label: { 47 | Image("settings") 48 | .resizable() 49 | .frame(width: 25, height: 25) 50 | .foregroundColor(.gray30) 51 | } 52 | } 53 | 54 | HStack{ 55 | Spacer() 56 | 57 | Text("Credit Cards") 58 | .font(.customfont(.regular, fontSize: 16)) 59 | 60 | 61 | Spacer() 62 | 63 | } 64 | } 65 | .foregroundColor(.gray30) 66 | .padding(.horizontal, 20) 67 | 68 | CardStack(cardArr) { cObj in 69 | 70 | ZStack{ 71 | RoundedRectangle(cornerRadius: 20, style: .continuous) 72 | .fill(Color.gray70) 73 | .frame(width: 232, height: 350) 74 | .shadow(color: .black.opacity(0.2), radius: 4) 75 | 76 | Image("card_blank") 77 | .resizable() 78 | .scaledToFit() 79 | .frame(width: 232, height: 350) 80 | 81 | VStack(spacing: 8){ 82 | Spacer() 83 | .frame(height: 22) 84 | 85 | Image("mastercard_logo") 86 | .resizable() 87 | .scaledToFit() 88 | .frame(width: 50) 89 | 90 | Text("Virtual Card") 91 | .font(.customfont(.semibold, fontSize: 16)) 92 | 93 | Spacer() 94 | .frame(height: 107) 95 | 96 | Text(cObj.name) 97 | .font(.customfont(.semibold, fontSize: 12)) 98 | .foregroundColor(.gray20) 99 | 100 | 101 | Text(cObj.number) 102 | .font(.customfont(.semibold, fontSize: 16)) 103 | 104 | 105 | Text(cObj.month_year) 106 | .font(.customfont(.semibold, fontSize: 14)) 107 | 108 | 109 | Spacer() 110 | 111 | } 112 | .foregroundColor(.white) 113 | 114 | } 115 | } 116 | .padding(.vertical, 20) 117 | 118 | VStack{ 119 | Text("Subscriptions") 120 | .font(.customfont(.semibold, fontSize: 16)) 121 | 122 | HStack(spacing: 10){ 123 | 124 | Spacer() 125 | 126 | ForEach(subArr) { sObj in 127 | Image(sObj.icon) 128 | .resizable() 129 | .frame(width: 40, height: 40) 130 | } 131 | 132 | Spacer() 133 | 134 | } 135 | } 136 | .foregroundColor(.white) 137 | .padding(.top, 20) 138 | 139 | VStack{ 140 | Button { 141 | 142 | } label: { 143 | HStack{ 144 | Text("Add new card ") 145 | .font(.customfont(.semibold, fontSize: 14)) 146 | 147 | Image("add") 148 | .resizable() 149 | .frame(width: 14, height: 14) 150 | } 151 | 152 | } 153 | .foregroundColor( .gray30 ) 154 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 64, maxHeight: 64) 155 | .overlay { 156 | RoundedRectangle(cornerRadius: 16) 157 | .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [5,4]) ) 158 | .foregroundColor(.gray30.opacity(0.5)) 159 | 160 | //.stroke( Color.gray70, lineWidth: 1) 161 | } 162 | .cornerRadius(16) 163 | .padding(.horizontal, 20) 164 | .padding(.vertical, 20) 165 | 166 | Spacer() 167 | } 168 | .frame(width: .infinity, height: 300 ) 169 | .background(Color.gray70) 170 | .cornerRadius(radius: 24, corners: [.topLeft, .topRight]) 171 | .padding(.top, 40) 172 | 173 | } 174 | .padding(.top, .topInsets) 175 | } 176 | 177 | .background(Color.grayC) 178 | .ignoresSafeArea() 179 | } 180 | } 181 | 182 | struct CardsView_Previews: PreviewProvider { 183 | static var previews: some View { 184 | CardsView() 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /Trackizer/View/Home/HomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 12/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct HomeView: View { 11 | 12 | @State var isSubscription: Bool = true 13 | @State var subArr: [SubscriptionModel] = [ 14 | SubscriptionModel(dict: ["name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 15 | , 16 | SubscriptionModel(dict: [ 17 | "name": "YouTube Premium", 18 | "icon": "youtube_logo", 19 | "price": "18.99"] ) 20 | , 21 | SubscriptionModel(dict: ["name": "Microsoft OneDrive", 22 | "icon": "onedrive_logo", 23 | "price": "29.99"] ) 24 | , 25 | SubscriptionModel(dict: ["name": "NetFlix", "icon": "netflix_logo", "price": "15.00"] ) 26 | ] 27 | 28 | var body: some View { 29 | ScrollView { 30 | 31 | ZStack(alignment: .center) { 32 | 33 | Rectangle() 34 | .foregroundColor(.gray70.opacity(0.5)) 35 | .frame(width: .screenWidth, height: .widthPer(per: 1.1) ) 36 | .cornerRadius(25) 37 | 38 | 39 | Image("home_bg") 40 | .resizable() 41 | .scaledToFit() 42 | 43 | ZStack{ 44 | ArcShape() 45 | .foregroundColor(.gray.opacity(0.2)) 46 | 47 | ArcShape(start: 0, end: 230) 48 | .foregroundColor(.secondaryC) 49 | .shadow( color: .secondaryC.opacity(0.5) , radius: 7) 50 | } 51 | .frame(width: .widthPer(per: 0.72), height: .widthPer(per: 0.72) ) 52 | .padding(.bottom, 18) 53 | 54 | VStack(spacing: .widthPer(per: 0.07)){ 55 | Image("app_logo") 56 | .resizable() 57 | .scaledToFit() 58 | .frame(width: .widthPer(per: 0.25) ) 59 | 60 | Text("$1,235") 61 | .font(.customfont(.bold, fontSize: 40)) 62 | .foregroundColor(.white) 63 | 64 | Text("This month bills") 65 | .font(.customfont(.semibold, fontSize: 12)) 66 | .foregroundColor(.gray40) 67 | 68 | Button { 69 | 70 | } label: { 71 | Text("See your budget") 72 | .font(.customfont(.semibold, fontSize: 12)) 73 | } 74 | .foregroundColor( .white ) 75 | 76 | .padding(10) 77 | .background(Color.gray60.opacity( 0.2 )) 78 | .overlay { 79 | RoundedRectangle(cornerRadius: 16) 80 | .stroke( Color.gray70, lineWidth: 1) 81 | } 82 | .cornerRadius(16) 83 | } 84 | 85 | VStack{ 86 | Spacer() 87 | HStack{ 88 | StatusButton(title: "Active subs", value: "12") { 89 | 90 | } 91 | 92 | StatusButton(title: "highest subs", value: "$19.99",color: .primary10) { 93 | 94 | } 95 | 96 | StatusButton(title: "Lowest subs", value: "$5.99",color: .secondaryG) { 97 | 98 | } 99 | 100 | 101 | } 102 | } 103 | .padding() 104 | 105 | } 106 | .frame(width: .screenWidth, height: .widthPer(per: 1.1) ) 107 | 108 | HStack{ 109 | 110 | SegmentButton(title: "Your Subscription", isActive: isSubscription) { 111 | isSubscription.toggle() 112 | } 113 | 114 | SegmentButton(title: "Upcomming bills", isActive: !isSubscription) { 115 | isSubscription.toggle() 116 | } 117 | 118 | } 119 | .padding(8) 120 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 50, maxHeight: 50) 121 | .background(Color.black) 122 | .cornerRadius(15) 123 | .padding() 124 | 125 | if(isSubscription) { 126 | LazyVStack(spacing: 15) { 127 | ForEach( subArr , id: \.id) { sObj in 128 | 129 | SubScriptionHomeRow(sObj: sObj) 130 | 131 | } 132 | } 133 | .padding(.horizontal, 20) 134 | } 135 | 136 | if(!isSubscription) { 137 | LazyVStack(spacing: 15) { 138 | ForEach( subArr , id: \.id) { sObj in 139 | 140 | UpcomingBillRow(sObj: sObj) 141 | 142 | } 143 | } 144 | .padding(.horizontal, 20) 145 | } 146 | 147 | 148 | } 149 | .background(Color.grayC) 150 | .ignoresSafeArea() 151 | } 152 | } 153 | 154 | struct HomeView_Previews: PreviewProvider { 155 | static var previews: some View { 156 | HomeView() 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Trackizer/View/Login/SignInView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignInView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SignInView: View { 11 | @State var txtLogin: String = "" 12 | @State var txtPassword: String = "" 13 | @State var isRemember: Bool = false 14 | @State var showSignUp: Bool = false 15 | var body: some View { 16 | ZStack{ 17 | 18 | VStack{ 19 | 20 | Image("app_logo") 21 | .resizable() 22 | .scaledToFit() 23 | .frame(width: .widthPer(per: 0.5) ) 24 | .padding(.top, .topInsets + 8) 25 | 26 | 27 | Spacer() 28 | 29 | RoundTextField(title: "Login", text: $txtLogin, keyboardType: .emailAddress) 30 | 31 | .padding(.horizontal, 20) 32 | .padding(.bottom, 15) 33 | 34 | 35 | 36 | RoundTextField(title: "Passowrd", text: $txtPassword, isPassword: true) 37 | 38 | .padding(.horizontal, 20) 39 | .padding(.bottom, 20) 40 | 41 | 42 | 43 | HStack{ 44 | Button { 45 | isRemember = !isRemember 46 | } label: { 47 | 48 | HStack{ 49 | 50 | Image(systemName: isRemember ? "checkmark.square" : "square") 51 | .resizable() 52 | .frame(width: 20, height: 20) 53 | 54 | Text("Forgot Password") 55 | .multilineTextAlignment(.center) 56 | .font(.customfont(.regular, fontSize: 14)) 57 | } 58 | 59 | 60 | 61 | } 62 | .foregroundColor(.gray50) 63 | 64 | Spacer() 65 | Button { 66 | 67 | } label: { 68 | Text("Forgot Password") 69 | .multilineTextAlignment(.center) 70 | .font(.customfont(.regular, fontSize: 14)) 71 | 72 | } 73 | .foregroundColor(.gray50) 74 | 75 | } 76 | .padding(.horizontal, 20) 77 | .padding(.bottom, 15) 78 | 79 | PrimaryButton(title: "Sign In", onPressed: { 80 | 81 | }) 82 | 83 | Spacer() 84 | 85 | Text("if you don't have an account yet?") 86 | .multilineTextAlignment(.center) 87 | .font(.customfont(.regular, fontSize: 14)) 88 | .padding(.horizontal, 20) 89 | .foregroundColor(.white) 90 | .padding(.bottom, 20) 91 | 92 | SecondaryButton(title: "Sign Up", onPressed: { 93 | showSignUp.toggle() 94 | }) 95 | .background( NavigationLink(destination: SignUpView(), isActive: $showSignUp, label: { 96 | EmptyView() 97 | }) ) 98 | .padding(.bottom, .bottomInsets + 8) 99 | } 100 | } 101 | .navigationTitle("") 102 | .navigationBarHidden(true) 103 | .navigationBarBackButtonHidden(true) 104 | .ignoresSafeArea() 105 | .background(Color.grayC) 106 | } 107 | } 108 | 109 | struct SignInView_Previews: PreviewProvider { 110 | static var previews: some View { 111 | SignInView() 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Trackizer/View/Login/SignUpView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignUpView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SignUpView: View { 11 | 12 | @State var txtEmail: String = "" 13 | @State var txtPassword: String = "" 14 | @State var showSignIn: Bool = false 15 | 16 | var body: some View { 17 | ZStack{ 18 | 19 | VStack{ 20 | 21 | Image("app_logo") 22 | .resizable() 23 | .scaledToFit() 24 | .frame(width: .widthPer(per: 0.5) ) 25 | .padding(.top, .topInsets + 8) 26 | 27 | 28 | Spacer() 29 | 30 | RoundTextField(title: "E-mail Address", text: $txtEmail, keyboardType: .emailAddress) 31 | 32 | .padding(.horizontal, 20) 33 | .padding(.bottom, 15) 34 | 35 | 36 | 37 | RoundTextField(title: "Passowrd", text: $txtPassword, isPassword: true) 38 | 39 | .padding(.horizontal, 20) 40 | .padding(.bottom, 20) 41 | 42 | HStack { 43 | 44 | Rectangle() 45 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 5, maxHeight: 5) 46 | .padding(.horizontal, 1) 47 | 48 | Rectangle() 49 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 5, maxHeight: 5) 50 | .padding(.horizontal, 1) 51 | 52 | Rectangle() 53 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 5, maxHeight: 5) 54 | .padding(.horizontal, 1) 55 | 56 | Rectangle() 57 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 5, maxHeight: 5) 58 | .padding(.horizontal, 1) 59 | 60 | } 61 | .padding(.horizontal, 20) 62 | .foregroundColor(.gray70) 63 | .padding(.bottom, 20) 64 | 65 | Text("Use 8 or more characters with a mix of letters,\nnumbers & symbols.") 66 | .multilineTextAlignment(.leading) 67 | .font(.customfont(.regular, fontSize: 14)) 68 | .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) 69 | .padding(.horizontal, 20) 70 | .foregroundColor(.gray50) 71 | .padding(.bottom, 20) 72 | 73 | PrimaryButton(title: "Get Started, it's free!", onPressed: { 74 | 75 | }) 76 | 77 | Spacer() 78 | 79 | Text("Do you have already an account?") 80 | .multilineTextAlignment(.center) 81 | .font(.customfont(.regular, fontSize: 14)) 82 | .padding(.horizontal, 20) 83 | .foregroundColor(.white) 84 | .padding(.bottom, 20) 85 | 86 | SecondaryButton(title: "Sign In", onPressed: { 87 | showSignIn.toggle() 88 | }) 89 | .background( NavigationLink(destination: SignInView(), isActive: $showSignIn, label: { 90 | EmptyView() 91 | }) ) 92 | .padding(.bottom, .bottomInsets + 8) 93 | } 94 | } 95 | .navigationTitle("") 96 | .navigationBarHidden(true) 97 | .navigationBarBackButtonHidden(true) 98 | .ignoresSafeArea() 99 | .background(Color.grayC) 100 | } 101 | } 102 | 103 | struct SignUpView_Previews: PreviewProvider { 104 | static var previews: some View { 105 | SignUpView() 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Trackizer/View/Login/SocialSignupView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SocialSignupView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SocialSignupView: View { 11 | @State var showSignUp: Bool = false 12 | 13 | var body: some View { 14 | ZStack{ 15 | 16 | 17 | VStack{ 18 | 19 | Image("app_logo") 20 | .resizable() 21 | .scaledToFit() 22 | .frame(width: .widthPer(per: 0.5) ) 23 | .padding(.top, .topInsets + 8) 24 | 25 | Spacer() 26 | 27 | Button { 28 | 29 | } label: { 30 | ZStack{ 31 | Image("apple_btn") 32 | .resizable() 33 | .scaledToFill() 34 | .padding(.horizontal, 20) 35 | .frame(width: .screenWidth, height: 48) 36 | 37 | HStack{ 38 | 39 | Image("apple") 40 | .resizable() 41 | .scaledToFit() 42 | .frame(width: 15, height: 15) 43 | 44 | Text("Sign up with Apple") 45 | .font(.customfont(.semibold, fontSize: 14)) 46 | 47 | } 48 | .padding(.horizontal, 20) 49 | } 50 | } 51 | .foregroundColor(.white) 52 | .shadow(color: .black.opacity(0.3), radius: 5, y: 3) 53 | .padding(.bottom, 15) 54 | 55 | Button { 56 | 57 | } label: { 58 | ZStack{ 59 | Image("google_btn") 60 | .resizable() 61 | .scaledToFill() 62 | .padding(.horizontal, 20) 63 | .frame(width: .screenWidth, height: 48) 64 | 65 | HStack{ 66 | 67 | Image("google") 68 | .resizable() 69 | .scaledToFit() 70 | .frame(width: 15, height: 15) 71 | 72 | Text("Sign up with Google") 73 | .font(.customfont(.semibold, fontSize: 14)) 74 | 75 | } 76 | .padding(.horizontal, 20) 77 | } 78 | } 79 | .foregroundColor(.grayC) 80 | .shadow(color: .white.opacity(0.3), radius: 5, y: 3) 81 | .padding(.bottom, 15) 82 | 83 | Button { 84 | 85 | } label: { 86 | ZStack{ 87 | Image("fb_btn") 88 | .resizable() 89 | .scaledToFill() 90 | .padding(.horizontal, 20) 91 | .frame(width: .screenWidth, height: 48) 92 | 93 | HStack{ 94 | 95 | Image("fb") 96 | .resizable() 97 | .scaledToFit() 98 | .frame(width: 15, height: 15) 99 | 100 | Text("Sign up with Facebook") 101 | .font(.customfont(.semibold, fontSize: 14)) 102 | 103 | } 104 | .padding(.horizontal, 20) 105 | } 106 | } 107 | .foregroundColor(.white) 108 | .shadow(color: .blue.opacity(0.3), radius: 5, y: 3) 109 | .padding(.bottom, 25) 110 | 111 | Text("or") 112 | .multilineTextAlignment(.center) 113 | .font(.customfont(.regular, fontSize: 14)) 114 | .padding(.horizontal, 20) 115 | .foregroundColor(.white) 116 | .padding(.bottom, 25) 117 | 118 | 119 | 120 | SecondaryButton(title: "Sign up with E-mail", onPressed: { 121 | showSignUp.toggle() 122 | }) 123 | .background( NavigationLink(destination: SignUpView(), isActive: $showSignUp, label: { 124 | EmptyView() 125 | }) ) 126 | .padding(.bottom, 20) 127 | 128 | Text("By registering, you agree to our Terms of Use. Learn how we collect, use and share your data.") 129 | .multilineTextAlignment(.center) 130 | .font(.customfont(.regular, fontSize: 14)) 131 | .padding(.horizontal, 20) 132 | .foregroundColor(.gray60) 133 | .padding(.bottom, .bottomInsets + 8) 134 | } 135 | } 136 | .navigationTitle("") 137 | .navigationBarHidden(true) 138 | .navigationBarBackButtonHidden(true) 139 | .ignoresSafeArea() 140 | .background(Color.grayC) 141 | } 142 | } 143 | 144 | struct SocialSignupView_Previews: PreviewProvider { 145 | static var previews: some View { 146 | SocialSignupView() 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Trackizer/View/Login/WelcomView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WelcomView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WelcomView: View { 11 | 12 | @State var showSignIn: Bool = false 13 | @State var showSignUp: Bool = false 14 | 15 | var body: some View { 16 | ZStack{ 17 | Image("welcome_screen") 18 | .resizable() 19 | .scaledToFill() 20 | .frame(width: .screenWidth, height: .screenHeight) 21 | 22 | VStack{ 23 | 24 | Image("app_logo") 25 | .resizable() 26 | .scaledToFit() 27 | .frame(width: .widthPer(per: 0.5) ) 28 | .padding(.top, .topInsets + 8) 29 | 30 | 31 | Spacer() 32 | Text("Congue malesuada in ac justo, a tristique\nleo massa. Arcu leo leo urna risus.") 33 | .multilineTextAlignment(.center) 34 | .font(.customfont(.regular, fontSize: 14)) 35 | .padding(.horizontal, 20) 36 | .foregroundColor(.white) 37 | .padding(.bottom, 30) 38 | 39 | PrimaryButton(title: "Get Started", onPressed: { 40 | showSignUp.toggle() 41 | }) 42 | .background( NavigationLink(destination: SocialSignupView(), isActive: $showSignUp, label: { 43 | EmptyView() 44 | }) ) 45 | .padding(.bottom, 15) 46 | 47 | SecondaryButton(title: "I have an account", onPressed: { 48 | showSignIn.toggle() 49 | }) 50 | .background( NavigationLink(destination: SignInView(), isActive: $showSignIn, label: { 51 | EmptyView() 52 | }) ) 53 | .padding(.bottom, .bottomInsets) 54 | } 55 | } 56 | .navigationTitle("") 57 | .navigationBarHidden(true) 58 | .navigationBarBackButtonHidden(true) 59 | .ignoresSafeArea() 60 | } 61 | } 62 | 63 | struct WelcomView_Previews: PreviewProvider { 64 | static var previews: some View { 65 | WelcomView() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Trackizer/View/MainTab/MainTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainTabView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 12/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MainTabView: View { 11 | 12 | @State var selectTab: Int = 0 13 | 14 | var body: some View { 15 | ZStack{ 16 | 17 | if(selectTab == 0) { 18 | HomeView() 19 | .frame(width: .screenWidth, height: .screenHeight) 20 | } 21 | 22 | if(selectTab == 1) { 23 | BudgetsView() 24 | .frame(width: .screenWidth, height: .screenHeight) 25 | } 26 | 27 | if(selectTab == 2) { 28 | CalendarView() 29 | .frame(width: .screenWidth, height: .screenHeight) 30 | } 31 | 32 | if(selectTab == 3) { 33 | CardsView() 34 | .frame(width: .screenWidth, height: .screenHeight) 35 | } 36 | 37 | VStack{ 38 | Spacer() 39 | 40 | ZStack(alignment: .bottom){ 41 | 42 | 43 | 44 | ZStack(alignment: .center) { 45 | Image("bottom_bar_bg") 46 | .resizable() 47 | .scaledToFit() 48 | 49 | HStack(alignment: .center, spacing: 0){ 50 | 51 | Spacer() 52 | Button { 53 | selectTab = 0 54 | } label: { 55 | Image("home") 56 | .resizable() 57 | .frame(width: 20, height: 20) 58 | .padding() 59 | } 60 | .foregroundColor( selectTab == 0 ? .white : .gray30 ) 61 | 62 | Spacer() 63 | Button { 64 | selectTab = 1 65 | } label: { 66 | Image("budgets") 67 | .resizable() 68 | .frame(width: 20, height: 20) 69 | .padding() 70 | } 71 | .foregroundColor( selectTab == 1 ? .white : .gray30 ) 72 | 73 | 74 | Rectangle() 75 | .fill(.clear) 76 | .frame(width: 80, height: 0) 77 | 78 | Button { 79 | selectTab = 2 80 | } label: { 81 | Image("calendar") 82 | .resizable() 83 | .frame(width: 20, height: 20) 84 | .padding() 85 | } 86 | .foregroundColor( selectTab == 2 ? .white : .gray30 ) 87 | 88 | Spacer() 89 | Button { 90 | selectTab = 3 91 | } label: { 92 | Image("creditcards") 93 | .resizable() 94 | .frame(width: 20, height: 20) 95 | .padding() 96 | } 97 | .foregroundColor( selectTab == 3 ? .white : .gray30 ) 98 | Spacer() 99 | } 100 | } 101 | 102 | Button { 103 | 104 | } label: { 105 | Image("center_btn") 106 | .resizable() 107 | .frame(width: 50, height: 50) 108 | .padding() 109 | } 110 | .padding(.bottom, 6) 111 | .shadow(color: .secondaryC.opacity(0.5), radius: 6,y: 4) 112 | } 113 | } 114 | .padding(.horizontal, 20) 115 | .padding(.bottom , .bottomInsets) 116 | 117 | } 118 | .background(Color.grayC) 119 | .ignoresSafeArea() 120 | 121 | } 122 | } 123 | 124 | struct MainTabView_Previews: PreviewProvider { 125 | static var previews: some View { 126 | MainTabView() 127 | .environmentObject(WeekStore()) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Trackizer/View/Settings/SettingsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 16/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SettingsView: View { 11 | 12 | @State var isActive: Bool = false 13 | 14 | var body: some View { 15 | ScrollView { 16 | 17 | 18 | VStack{ 19 | 20 | ZStack{ 21 | HStack{ 22 | Button { 23 | 24 | } label: { 25 | Image("back") 26 | .resizable() 27 | .frame(width: 25, height: 25) 28 | } 29 | 30 | Spacer() 31 | 32 | } 33 | 34 | HStack{ 35 | Spacer() 36 | 37 | Text("Settings") 38 | .font(.customfont(.regular, fontSize: 16)) 39 | 40 | 41 | Spacer() 42 | 43 | } 44 | } 45 | .foregroundColor(.gray30) 46 | } 47 | .padding(.top, .topInsets) 48 | 49 | VStack(spacing: 4){ 50 | Image("u1") 51 | .resizable() 52 | .frame(width: 70, height: 70) 53 | Spacer() 54 | .frame(height: 15) 55 | Text("Code For Any") 56 | .font(.customfont(.bold, fontSize: 20)) 57 | .foregroundColor(.white) 58 | 59 | Text("codeforany@gmail.com") 60 | .font(.customfont(.medium, fontSize: 12)) 61 | .accentColor(.gray30) 62 | 63 | 64 | Spacer() 65 | .frame(height: 15) 66 | 67 | Button { 68 | 69 | } label: { 70 | Text("Edit Profile") 71 | .font(.customfont(.semibold, fontSize: 12)) 72 | } 73 | .foregroundColor( .white ) 74 | .padding(8) 75 | .background(Color.gray60.opacity( 0.2)) 76 | .overlay { 77 | RoundedRectangle(cornerRadius: 12) 78 | .stroke( Color.gray70 , lineWidth: 1) 79 | } 80 | .cornerRadius(12) 81 | 82 | } 83 | .padding(.top, 20) 84 | 85 | VStack(alignment: .leading, spacing: 8){ 86 | Text("General") 87 | .font(.customfont(.semibold, fontSize: 14)) 88 | .padding(.top, 8) 89 | 90 | VStack{ 91 | 92 | IconItemRow(icon: "face_id", title: "Security", value: "FaceID") 93 | 94 | IconItemSwitchRow(icon: "icloud", title: "iCloud Sync", value: $isActive) 95 | 96 | } 97 | .padding(.vertical, 10) 98 | .background(Color.gray60.opacity( 0.2)) 99 | .overlay { 100 | RoundedRectangle(cornerRadius: 16) 101 | .stroke( Color.gray70 , lineWidth: 1) 102 | } 103 | .cornerRadius(16) 104 | 105 | Text("My subscriptions") 106 | .font(.customfont(.semibold, fontSize: 14)) 107 | .padding(.top, 8) 108 | 109 | VStack{ 110 | 111 | IconItemRow(icon: "sorting", title: "Sorting", value: "Date") 112 | 113 | IconItemRow(icon: "chart", title: "Summary", value: "Average") 114 | 115 | IconItemRow(icon: "money", title: "Dafault currency", value: "USD ($)") 116 | } 117 | .padding(.vertical, 10) 118 | .background(Color.gray60.opacity( 0.2)) 119 | .overlay { 120 | RoundedRectangle(cornerRadius: 16) 121 | .stroke( Color.gray70 , lineWidth: 1) 122 | } 123 | .cornerRadius(16) 124 | 125 | Text("Appearance") 126 | .font(.customfont(.semibold, fontSize: 14)) 127 | .padding(.top, 8) 128 | 129 | VStack{ 130 | 131 | IconItemRow(icon: "app_icon", title: "App icon", value: "Default") 132 | 133 | IconItemRow(icon: "light_theme", title: "Theme", value: "Dark") 134 | 135 | IconItemRow(icon: "font", title: "Font", value: "Inter") 136 | } 137 | .padding(.vertical, 10) 138 | .background(Color.gray60.opacity( 0.2)) 139 | .overlay { 140 | RoundedRectangle(cornerRadius: 16) 141 | .stroke( Color.gray70 , lineWidth: 1) 142 | } 143 | .cornerRadius(16) 144 | } 145 | .foregroundColor(.white) 146 | 147 | } 148 | .padding(.horizontal, 20) 149 | .background(Color.grayC) 150 | .ignoresSafeArea() 151 | } 152 | } 153 | 154 | struct SettingsView_Previews: PreviewProvider { 155 | static var previews: some View { 156 | SettingsView() 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Trackizer/View/SubscriptionInfo/SubscriptionInfoView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscriptionInfoView.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 16/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SubscriptionInfoView: View { 11 | 12 | @Environment(\.presentationMode) var mode: Binding 13 | 14 | @State var sObj: SubscriptionModel = SubscriptionModel(dict: ["id":1,"name":"Spotify", "icon":"spotify_logo", "price": "5.99"] ) 15 | 16 | var body: some View { 17 | ScrollView { 18 | ZStack(alignment: .top) { 19 | 20 | VStack { 21 | VStack { 22 | HStack{ 23 | Button { 24 | mode.wrappedValue.dismiss() 25 | } label: { 26 | Image("dorp_down") 27 | .resizable() 28 | .frame(width: 20, height: 20) 29 | } 30 | 31 | Spacer() 32 | 33 | Text("Subscription Info") 34 | .font(.customfont(.regular, fontSize: 16)) 35 | 36 | 37 | Spacer() 38 | 39 | Button { 40 | mode.wrappedValue.dismiss() 41 | } label: { 42 | Image("Trash") 43 | .resizable() 44 | .frame(width: 20, height: 20) 45 | } 46 | 47 | } 48 | .foregroundColor(.gray30) 49 | .padding() 50 | Spacer() 51 | 52 | VStack(alignment: .center, spacing: 15){ 53 | 54 | Image(sObj.icon) 55 | .resizable() 56 | .scaledToFit() 57 | .frame(width: .widthPer(per: 0.25), height: .widthPer(per: 0.25)) 58 | 59 | Text(sObj.name) 60 | .font(.customfont(.bold, fontSize: 32)) 61 | .foregroundColor(.white) 62 | 63 | Text( "$\(sObj.price)" ) 64 | .font(.customfont(.bold, fontSize: 20)) 65 | .foregroundColor(.gray30) 66 | 67 | } 68 | 69 | Spacer() 70 | 71 | } 72 | .frame(width: .screenWidth - 40, height: .widthPer(per: 0.9) ) 73 | .background(Color.gray70) 74 | .cornerRadius(radius: 24, corners: [.topLeft, .topRight]) 75 | 76 | VStack { 77 | 78 | VStack{ 79 | ItemRow(title: "Name", value: sObj.name ) 80 | ItemRow(title: "Description", value: "Music app") 81 | ItemRow(title: "Category", value: "Enterteintment" ) 82 | ItemRow(title: "First payment", value: "08.07.2023" ) 83 | ItemRow(title: "Reminder", value: "Never" ) 84 | ItemRow(title: "Currency", value: "USD ($)" ) 85 | 86 | } 87 | .padding(.vertical, 15) 88 | .background(Color.gray20.opacity(0.2)) 89 | 90 | .cornerRadius(15) 91 | .overlay { 92 | RoundedRectangle(cornerRadius: 15) 93 | .stroke( Color.gray30.opacity(0.3), lineWidth: 1) 94 | } 95 | 96 | SecondaryButton( title: "Save", onPressed: { 97 | 98 | } ) 99 | .padding(.horizontal, 20) 100 | .padding(.top, 15) 101 | 102 | } 103 | .padding(20) 104 | 105 | } 106 | .background(Color(hex: "282833")) 107 | .frame(width: .screenWidth - 40) 108 | .cornerRadius(radius: 24, corners: .allCorners) 109 | .padding(.top, .topInsets) 110 | 111 | 112 | VStack{ 113 | Spacer() 114 | 115 | HStack{ 116 | Circle() 117 | .fill(Color.grayC) 118 | .frame(width: 30, height: 30) 119 | Rectangle() 120 | .fill(Color.clear) 121 | .frame( height: 1, alignment: .bottom) 122 | .overlay( 123 | RoundedRectangle(cornerRadius: 0) 124 | .stroke(style: StrokeStyle(lineWidth: 1, dash: [5])) 125 | .foregroundColor(Color.grayC) 126 | ) 127 | Circle() 128 | .fill(Color.grayC) 129 | .frame(width: 30, height: 30) 130 | } 131 | } 132 | 133 | .frame(width: .screenWidth - 15, height: .widthPer(per: 0.9) + 15 ) 134 | .padding(.top, .topInsets) 135 | 136 | 137 | 138 | 139 | } 140 | .padding(20) 141 | 142 | } 143 | .ignoresSafeArea() 144 | .background(Color.grayC) 145 | } 146 | } 147 | 148 | struct SubscriptionInfoView_Previews: PreviewProvider { 149 | static var previews: some View { 150 | SubscriptionInfoView() 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /Trackizer/ViewModel/UIStateModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIStateModel.swift 3 | // Trackizer 4 | // 5 | // Created by CodeForAny on 15/07/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | public class UIStateModel: ObservableObject 11 | { 12 | @Published var activeCard: Int = 0 13 | @Published var screenDrag: Float = 0.0 14 | } 15 | -------------------------------------------------------------------------------- /TrackizerTests/TrackizerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrackizerTests.swift 3 | // TrackizerTests 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import XCTest 9 | @testable import Trackizer 10 | 11 | final class TrackizerTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | // Any test you write for XCTest can be annotated as throws and async. 25 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. 26 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. 27 | } 28 | 29 | func testPerformanceExample() throws { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /TrackizerUITests/TrackizerUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrackizerUITests.swift 3 | // TrackizerUITests 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import XCTest 9 | 10 | final class TrackizerUITests: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use XCTAssert and related functions to verify your tests produce the correct results. 31 | } 32 | 33 | func testLaunchPerformance() throws { 34 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 35 | // This measures how long it takes to launch your application. 36 | measure(metrics: [XCTApplicationLaunchMetric()]) { 37 | XCUIApplication().launch() 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /TrackizerUITests/TrackizerUITestsLaunchTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrackizerUITestsLaunchTests.swift 3 | // TrackizerUITests 4 | // 5 | // Created by CodeForAny on 11/07/23. 6 | // 7 | 8 | import XCTest 9 | 10 | final class TrackizerUITestsLaunchTests: XCTestCase { 11 | 12 | override class var runsForEachTargetApplicationUIConfiguration: Bool { 13 | true 14 | } 15 | 16 | override func setUpWithError() throws { 17 | continueAfterFailure = false 18 | } 19 | 20 | func testLaunch() throws { 21 | let app = XCUIApplication() 22 | app.launch() 23 | 24 | // Insert steps here to perform after app launch but before taking a screenshot, 25 | // such as logging into a test account or navigating somewhere in the app 26 | 27 | let attachment = XCTAttachment(screenshot: app.screenshot()) 28 | attachment.name = "Launch Screen" 29 | attachment.lifetime = .keepAlways 30 | add(attachment) 31 | } 32 | } 33 | --------------------------------------------------------------------------------