fix: iOS fitness models — UUID strings, snapshot_ fields, convertFromSnakeCase compatibility
All checks were successful
Security Checks / dependency-audit (push) Successful in 12s
Security Checks / secret-scanning (push) Successful in 3s
Security Checks / dockerfile-lint (push) Successful in 3s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-03 01:44:53 -05:00
parent 4592e35732
commit e852e98812
23 changed files with 1745 additions and 512 deletions

View File

@@ -0,0 +1,5 @@
# This directory is a Syncthing folder marker.
# Do not delete.
folderID: pvf5v-v6cle
created: 2026-04-03T03:07:29Z

View File

@@ -0,0 +1,467 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
F0819A9915F94DECBA67FA89 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */; };
DD3F166E894F43848CE426C7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42807C65E9754543B46DBF62 /* ContentView.swift */; };
C9B59C679DF04512BF9F5C69 /* PlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F2CEB00333491ABEE288C5 /* PlatformApp.swift */; };
F35DB630BE0A46799AEC15A5 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F8C700FA4E43818AA54E03 /* APIClient.swift */; };
B20540C8E87F42C2AF4AB477 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4094EAAB413433FA0D70AB9 /* AuthManager.swift */; };
779FB7AAB0244CB68E5C69C8 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 879AEC4095F64FE7B851B6F9 /* LoginView.swift */; };
FB0A7F362F5944C0BF0365C5 /* AssistantChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F36ACA2BA1243B0B8954E8F /* AssistantChatView.swift */; };
45E92CD7F85A49BFA5C05F20 /* AssistantViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4073DF36CE74BB4A5B4F22A /* AssistantViewModel.swift */; };
2BC13A589E944CE3A4C6B708 /* FitnessAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E149FC023D964ADA86C96EB5 /* FitnessAPI.swift */; };
F7F65E02FB974FACA76AFAF4 /* FitnessModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DF9C7493C2402A8B8571DB /* FitnessModels.swift */; };
CF63000DFF4F4F728281A31D /* FitnessRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D82B05FA8D84CA98E18C0E2 /* FitnessRepository.swift */; };
400DCD1DE0534E9E856319F8 /* FoodSearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1822D8E4AFBF4B14A5E79050 /* FoodSearchViewModel.swift */; };
96AFE69ACFB54D97A7C3A4A0 /* GoalsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCDED359C0EE4CC2986AE602 /* GoalsViewModel.swift */; };
84CFFF27A99940B5875A65DA /* TemplatesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FED646258BA4DFA8D6078EC /* TemplatesViewModel.swift */; };
03EBDF20EDF547EDB4B177CF /* TodayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4F05CCCEE9A4E0FA6BC6795 /* TodayViewModel.swift */; };
92E276F3CA8D4400827B2F99 /* AddFoodSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C60F0E61463489689BC84E3 /* AddFoodSheet.swift */; };
C1D87BF5F61847BD952F5C65 /* EntryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3C34A418B5428A8B2A62B7 /* EntryDetailView.swift */; };
E48F9E44708544D781FC8ACD /* FitnessTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D994E5BA694983BA293390 /* FitnessTabView.swift */; };
2F5AF62DD13D4B0EB8E338A0 /* FoodLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27103840483E431EB0275752 /* FoodLibraryView.swift */; };
6FE7AC0C375242398A5118B4 /* FoodSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98379942DAA4FB992CE1A33 /* FoodSearchView.swift */; };
8064B019D0B742749713A35E /* GoalsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511884CFF6D40198C9A326B /* GoalsView.swift */; };
060E0115D90647A593BCF8B7 /* MealSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA9E7B0D02A4E13ADD734A4 /* MealSectionView.swift */; };
7902B9F4789C4C6FB080AF0D /* TemplatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E59243273F494E9C1F63CB /* TemplatesView.swift */; };
A74F6C2CDEF4487383684BB9 /* TodayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE2113036D74BBA9D3DA571 /* TodayView.swift */; };
75DB623876D54D0BAF32B59F /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0067210C0C4833BEF98835 /* HomeView.swift */; };
340D12BB6F234169953639F6 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F60B0BE1ED854A1F859C8B6F /* HomeViewModel.swift */; };
D2CF33B6FE4142CA9995E125 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D88C79EBC3A4E3791482B07 /* LoadingView.swift */; };
CF9C74396EA449D2BDEBAA09 /* MacroBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16A32CB0269E4AF79A96B241 /* MacroBar.swift */; };
C6D6C2D5882245A895C8B606 /* MacroRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF6CAF2179B48C6B338233C /* MacroRing.swift */; };
86D08C3CC8B34AEDB1254EC1 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C04E1FF020544D08EDD3CCA /* Color+Extensions.swift */; };
C367EA266AED4AB7842B8A6F /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929DC19B5C81454EB58087AA /* Date+Extensions.swift */; };
F1AA651AF622471EA697E2CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4C75844F44B444F4A8228158 /* Assets.xcassets */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Config.swift"; sourceTree = "<group>"; };
42807C65E9754543B46DBF62 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContentView.swift"; sourceTree = "<group>"; };
47F2CEB00333491ABEE288C5 /* PlatformApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PlatformApp.swift"; sourceTree = "<group>"; };
63F8C700FA4E43818AA54E03 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIClient.swift"; sourceTree = "<group>"; };
E4094EAAB413433FA0D70AB9 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AuthManager.swift"; sourceTree = "<group>"; };
879AEC4095F64FE7B851B6F9 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoginView.swift"; sourceTree = "<group>"; };
5F36ACA2BA1243B0B8954E8F /* AssistantChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssistantChatView.swift"; sourceTree = "<group>"; };
F4073DF36CE74BB4A5B4F22A /* AssistantViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssistantViewModel.swift"; sourceTree = "<group>"; };
E149FC023D964ADA86C96EB5 /* FitnessAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessAPI.swift"; sourceTree = "<group>"; };
B4DF9C7493C2402A8B8571DB /* FitnessModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessModels.swift"; sourceTree = "<group>"; };
6D82B05FA8D84CA98E18C0E2 /* FitnessRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessRepository.swift"; sourceTree = "<group>"; };
1822D8E4AFBF4B14A5E79050 /* FoodSearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodSearchViewModel.swift"; sourceTree = "<group>"; };
DCDED359C0EE4CC2986AE602 /* GoalsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GoalsViewModel.swift"; sourceTree = "<group>"; };
4FED646258BA4DFA8D6078EC /* TemplatesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TemplatesViewModel.swift"; sourceTree = "<group>"; };
B4F05CCCEE9A4E0FA6BC6795 /* TodayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TodayViewModel.swift"; sourceTree = "<group>"; };
8C60F0E61463489689BC84E3 /* AddFoodSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AddFoodSheet.swift"; sourceTree = "<group>"; };
3C3C34A418B5428A8B2A62B7 /* EntryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EntryDetailView.swift"; sourceTree = "<group>"; };
A5D994E5BA694983BA293390 /* FitnessTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessTabView.swift"; sourceTree = "<group>"; };
27103840483E431EB0275752 /* FoodLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodLibraryView.swift"; sourceTree = "<group>"; };
A98379942DAA4FB992CE1A33 /* FoodSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodSearchView.swift"; sourceTree = "<group>"; };
A511884CFF6D40198C9A326B /* GoalsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GoalsView.swift"; sourceTree = "<group>"; };
6EA9E7B0D02A4E13ADD734A4 /* MealSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MealSectionView.swift"; sourceTree = "<group>"; };
D0E59243273F494E9C1F63CB /* TemplatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TemplatesView.swift"; sourceTree = "<group>"; };
3CE2113036D74BBA9D3DA571 /* TodayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TodayView.swift"; sourceTree = "<group>"; };
FE0067210C0C4833BEF98835 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeView.swift"; sourceTree = "<group>"; };
F60B0BE1ED854A1F859C8B6F /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeViewModel.swift"; sourceTree = "<group>"; };
1D88C79EBC3A4E3791482B07 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoadingView.swift"; sourceTree = "<group>"; };
16A32CB0269E4AF79A96B241 /* MacroBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MacroBar.swift"; sourceTree = "<group>"; };
FDF6CAF2179B48C6B338233C /* MacroRing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MacroRing.swift"; sourceTree = "<group>"; };
1C04E1FF020544D08EDD3CCA /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = "<group>"; };
929DC19B5C81454EB58087AA /* Date+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
4C75844F44B444F4A8228158 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0FDDDCE767CF4BF6B6D41677 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4B7D1D629553482DA83FE35D /* Platform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Platform.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
037C8FC2A4954FCE91D25A60 /* Platform */ = {
isa = PBXGroup;
children = (
029D94F090324446B082BA63 /* Platform */,
B5E96950287B4399909152DA /* Products */,
);
sourceTree = "<group>";
};
B5E96950287B4399909152DA /* Products */ = {
isa = PBXGroup;
children = (
4B7D1D629553482DA83FE35D /* Platform.app */,
);
sourceTree = "<group>";
};
029D94F090324446B082BA63 /* Platform */ = {
isa = PBXGroup;
children = (
AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */,
42807C65E9754543B46DBF62 /* ContentView.swift */,
47F2CEB00333491ABEE288C5 /* PlatformApp.swift */,
0FDDDCE767CF4BF6B6D41677 /* Info.plist */,
4C75844F44B444F4A8228158 /* Assets.xcassets */,
0DA26F997DC3429889C0B23A /* Core */,
8CF6CD4493114827807F5F6D /* Features */,
047E80495324497B8522ACEC /* Shared */,
);
path = "Platform"; sourceTree = "<group>";
};
0DA26F997DC3429889C0B23A /* Core */ = {
isa = PBXGroup;
children = (
,
);
path = "Core"; sourceTree = "<group>";
};
8CF6CD4493114827807F5F6D /* Features */ = {
isa = PBXGroup;
children = (
824CFF8CF00F41C590FB148C /* Auth */,
DAD6984656494252A7E8A5DC /* Home */,
C94148B12F3443238D763D27 /* Fitness */,
64DDC35730F64FAFA4F2962C /* Assistant */,
);
path = "Features"; sourceTree = "<group>";
};
824CFF8CF00F41C590FB148C /* Auth */ = {
isa = PBXGroup;
children = (
,
);
path = "Auth"; sourceTree = "<group>";
};
DAD6984656494252A7E8A5DC /* Home */ = {
isa = PBXGroup;
children = (
,
);
path = "Home"; sourceTree = "<group>";
};
64DDC35730F64FAFA4F2962C /* Assistant */ = {
isa = PBXGroup;
children = (
,
);
path = "Assistant"; sourceTree = "<group>";
};
C94148B12F3443238D763D27 /* Fitness */ = {
isa = PBXGroup;
children = (
822A533A33DF4047882688E2 /* Models */,
969F179A1EB645CCBAECE591 /* API */,
A5B64A87024F4F66B4A5D8B4 /* Repository */,
4B89164541C1493A80664F6D /* ViewModels */,
BB4E0BAFB7DA45A68F0480A4 /* Views */,
);
path = "Fitness"; sourceTree = "<group>";
};
969F179A1EB645CCBAECE591 /* API */ = {
isa = PBXGroup;
children = (
,
);
path = "API"; sourceTree = "<group>";
};
822A533A33DF4047882688E2 /* Models */ = {
isa = PBXGroup;
children = (
,
);
path = "Models"; sourceTree = "<group>";
};
A5B64A87024F4F66B4A5D8B4 /* Repository */ = {
isa = PBXGroup;
children = (
,
);
path = "Repository"; sourceTree = "<group>";
};
4B89164541C1493A80664F6D /* ViewModels */ = {
isa = PBXGroup;
children = (
,
);
path = "ViewModels"; sourceTree = "<group>";
};
BB4E0BAFB7DA45A68F0480A4 /* Views */ = {
isa = PBXGroup;
children = (
,
);
path = "Views"; sourceTree = "<group>";
};
047E80495324497B8522ACEC /* Shared */ = {
isa = PBXGroup;
children = (
7F73AF13180C459B8275CD39 /* Components */,
D3B81404D3A24B66B6848BB6 /* Extensions */,
);
path = "Shared"; sourceTree = "<group>";
};
7F73AF13180C459B8275CD39 /* Components */ = {
isa = PBXGroup;
children = (
,
);
path = "Components"; sourceTree = "<group>";
};
D3B81404D3A24B66B6848BB6 /* Extensions */ = {
isa = PBXGroup;
children = (
,
);
path = "Extensions"; sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B66E7E9630EA415E95CE3A85 /* Platform */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0025AB77304B486EB7AE3B2B /* Build configuration list for PBXNativeTarget "Platform" */;
buildPhases = (
F8ADC26469734B15B38E123A /* Sources */,
078D546291EB4BBFA91F6661 /* Frameworks */,
841189B510034E9A81A14A8C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Platform;
productName = Platform;
productReference = 4B7D1D629553482DA83FE35D /* Platform.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1C4E1290ED4B4E0D832C6DD0 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1540;
};
buildConfigurationList = E9E082A339DE4D0DAF491E2B /* Build configuration list for PBXProject "Platform" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 037C8FC2A4954FCE91D25A60 /* Platform */;
productRefGroup = B5E96950287B4399909152DA /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B66E7E9630EA415E95CE3A85 /* Platform */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
841189B510034E9A81A14A8C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F1AA651AF622471EA697E2CA /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F8ADC26469734B15B38E123A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F0819A9915F94DECBA67FA89 /* Config.swift in Sources */,
DD3F166E894F43848CE426C7 /* ContentView.swift in Sources */,
C9B59C679DF04512BF9F5C69 /* PlatformApp.swift in Sources */,
F35DB630BE0A46799AEC15A5 /* APIClient.swift in Sources */,
B20540C8E87F42C2AF4AB477 /* AuthManager.swift in Sources */,
779FB7AAB0244CB68E5C69C8 /* LoginView.swift in Sources */,
FB0A7F362F5944C0BF0365C5 /* AssistantChatView.swift in Sources */,
45E92CD7F85A49BFA5C05F20 /* AssistantViewModel.swift in Sources */,
2BC13A589E944CE3A4C6B708 /* FitnessAPI.swift in Sources */,
F7F65E02FB974FACA76AFAF4 /* FitnessModels.swift in Sources */,
CF63000DFF4F4F728281A31D /* FitnessRepository.swift in Sources */,
400DCD1DE0534E9E856319F8 /* FoodSearchViewModel.swift in Sources */,
96AFE69ACFB54D97A7C3A4A0 /* GoalsViewModel.swift in Sources */,
84CFFF27A99940B5875A65DA /* TemplatesViewModel.swift in Sources */,
03EBDF20EDF547EDB4B177CF /* TodayViewModel.swift in Sources */,
92E276F3CA8D4400827B2F99 /* AddFoodSheet.swift in Sources */,
C1D87BF5F61847BD952F5C65 /* EntryDetailView.swift in Sources */,
E48F9E44708544D781FC8ACD /* FitnessTabView.swift in Sources */,
2F5AF62DD13D4B0EB8E338A0 /* FoodLibraryView.swift in Sources */,
6FE7AC0C375242398A5118B4 /* FoodSearchView.swift in Sources */,
8064B019D0B742749713A35E /* GoalsView.swift in Sources */,
060E0115D90647A593BCF8B7 /* MealSectionView.swift in Sources */,
7902B9F4789C4C6FB080AF0D /* TemplatesView.swift in Sources */,
A74F6C2CDEF4487383684BB9 /* TodayView.swift in Sources */,
75DB623876D54D0BAF32B59F /* HomeView.swift in Sources */,
340D12BB6F234169953639F6 /* HomeViewModel.swift in Sources */,
D2CF33B6FE4142CA9995E125 /* LoadingView.swift in Sources */,
CF9C74396EA449D2BDEBAA09 /* MacroBar.swift in Sources */,
C6D6C2D5882245A895C8B606 /* MacroRing.swift in Sources */,
86D08C3CC8B34AEDB1254EC1 /* Color+Extensions.swift in Sources */,
C367EA266AED4AB7842B8A6F /* Date+Extensions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXFrameworksBuildPhase section */
078D546291EB4BBFA91F6661 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin XCBuildConfiguration section */
B7446285A53C413C9BA0229C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASCETECHNOLOGIES_AWARE = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
D697F1D80CFA4E629D58BE0A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C29C67A4DC4943FB8112E677 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Platform/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
5289CC82B720470DA5F3181B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Platform/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
E9E082A339DE4D0DAF491E2B /* Build configuration list for PBXProject "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B7446285A53C413C9BA0229C /* Debug */,
D697F1D80CFA4E629D58BE0A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0025AB77304B486EB7AE3B2B /* Build configuration list for PBXNativeTarget "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C29C67A4DC4943FB8112E677 /* Debug */,
5289CC82B720470DA5F3181B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 1C4E1290ED4B4E0D832C6DD0 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -7,315 +7,78 @@
objects = {
/* Begin PBXBuildFile section */
F0819A9915F94DECBA67FA89 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */; };
DD3F166E894F43848CE426C7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42807C65E9754543B46DBF62 /* ContentView.swift */; };
C9B59C679DF04512BF9F5C69 /* PlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F2CEB00333491ABEE288C5 /* PlatformApp.swift */; };
F35DB630BE0A46799AEC15A5 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F8C700FA4E43818AA54E03 /* APIClient.swift */; };
B20540C8E87F42C2AF4AB477 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4094EAAB413433FA0D70AB9 /* AuthManager.swift */; };
779FB7AAB0244CB68E5C69C8 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 879AEC4095F64FE7B851B6F9 /* LoginView.swift */; };
FB0A7F362F5944C0BF0365C5 /* AssistantChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F36ACA2BA1243B0B8954E8F /* AssistantChatView.swift */; };
45E92CD7F85A49BFA5C05F20 /* AssistantViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4073DF36CE74BB4A5B4F22A /* AssistantViewModel.swift */; };
2BC13A589E944CE3A4C6B708 /* FitnessAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E149FC023D964ADA86C96EB5 /* FitnessAPI.swift */; };
F7F65E02FB974FACA76AFAF4 /* FitnessModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DF9C7493C2402A8B8571DB /* FitnessModels.swift */; };
CF63000DFF4F4F728281A31D /* FitnessRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D82B05FA8D84CA98E18C0E2 /* FitnessRepository.swift */; };
400DCD1DE0534E9E856319F8 /* FoodSearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1822D8E4AFBF4B14A5E79050 /* FoodSearchViewModel.swift */; };
96AFE69ACFB54D97A7C3A4A0 /* GoalsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCDED359C0EE4CC2986AE602 /* GoalsViewModel.swift */; };
84CFFF27A99940B5875A65DA /* TemplatesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FED646258BA4DFA8D6078EC /* TemplatesViewModel.swift */; };
03EBDF20EDF547EDB4B177CF /* TodayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4F05CCCEE9A4E0FA6BC6795 /* TodayViewModel.swift */; };
92E276F3CA8D4400827B2F99 /* AddFoodSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C60F0E61463489689BC84E3 /* AddFoodSheet.swift */; };
C1D87BF5F61847BD952F5C65 /* EntryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3C34A418B5428A8B2A62B7 /* EntryDetailView.swift */; };
E48F9E44708544D781FC8ACD /* FitnessTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D994E5BA694983BA293390 /* FitnessTabView.swift */; };
2F5AF62DD13D4B0EB8E338A0 /* FoodLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27103840483E431EB0275752 /* FoodLibraryView.swift */; };
6FE7AC0C375242398A5118B4 /* FoodSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98379942DAA4FB992CE1A33 /* FoodSearchView.swift */; };
8064B019D0B742749713A35E /* GoalsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511884CFF6D40198C9A326B /* GoalsView.swift */; };
060E0115D90647A593BCF8B7 /* MealSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA9E7B0D02A4E13ADD734A4 /* MealSectionView.swift */; };
7902B9F4789C4C6FB080AF0D /* TemplatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E59243273F494E9C1F63CB /* TemplatesView.swift */; };
A74F6C2CDEF4487383684BB9 /* TodayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE2113036D74BBA9D3DA571 /* TodayView.swift */; };
75DB623876D54D0BAF32B59F /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE0067210C0C4833BEF98835 /* HomeView.swift */; };
340D12BB6F234169953639F6 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F60B0BE1ED854A1F859C8B6F /* HomeViewModel.swift */; };
D2CF33B6FE4142CA9995E125 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D88C79EBC3A4E3791482B07 /* LoadingView.swift */; };
CF9C74396EA449D2BDEBAA09 /* MacroBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16A32CB0269E4AF79A96B241 /* MacroBar.swift */; };
C6D6C2D5882245A895C8B606 /* MacroRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF6CAF2179B48C6B338233C /* MacroRing.swift */; };
86D08C3CC8B34AEDB1254EC1 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C04E1FF020544D08EDD3CCA /* Color+Extensions.swift */; };
C367EA266AED4AB7842B8A6F /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929DC19B5C81454EB58087AA /* Date+Extensions.swift */; };
F1AA651AF622471EA697E2CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4C75844F44B444F4A8228158 /* Assets.xcassets */; };
A10001 /* PlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10001 /* PlatformApp.swift */; };
A10002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10002 /* ContentView.swift */; };
A10003 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10003 /* Config.swift */; };
A10004 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10004 /* APIClient.swift */; };
A10005 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10005 /* AuthManager.swift */; };
A10006 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10006 /* LoginView.swift */; };
A10007 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10007 /* HomeView.swift */; };
A10008 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10008 /* HomeViewModel.swift */; };
A10009 /* FitnessModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10009 /* FitnessModels.swift */; };
A10010 /* FitnessAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10010 /* FitnessAPI.swift */; };
A10011 /* FitnessRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10011 /* FitnessRepository.swift */; };
A10012 /* FitnessTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10012 /* FitnessTabView.swift */; };
A10013 /* TodayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10013 /* TodayView.swift */; };
A10014 /* MealSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10014 /* MealSectionView.swift */; };
A10015 /* FoodSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10015 /* FoodSearchView.swift */; };
A10016 /* AddFoodSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10016 /* AddFoodSheet.swift */; };
A10018 /* TemplatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10018 /* TemplatesView.swift */; };
A10019 /* GoalsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10019 /* GoalsView.swift */; };
A10020 /* EntryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10020 /* EntryDetailView.swift */; };
A10021 /* TodayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10021 /* TodayViewModel.swift */; };
A10022 /* FoodSearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10022 /* FoodSearchViewModel.swift */; };
A10024 /* TemplatesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10024 /* TemplatesViewModel.swift */; };
A10025 /* GoalsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10025 /* GoalsViewModel.swift */; };
A10026 /* MacroRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10026 /* MacroRing.swift */; };
A10027 /* MacroBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10027 /* MacroBar.swift */; };
A10028 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10028 /* LoadingView.swift */; };
A10029 /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10029 /* Date+Extensions.swift */; };
A10030 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10030 /* Color+Extensions.swift */; };
A10031 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B10031 /* Assets.xcassets */; };
A10032 /* FoodLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10032 /* FoodLibraryView.swift */; };
A10033 /* AssistantChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10033 /* AssistantChatView.swift */; };
A10034 /* AssistantViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10034 /* AssistantViewModel.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Config.swift"; sourceTree = "<group>"; };
42807C65E9754543B46DBF62 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContentView.swift"; sourceTree = "<group>"; };
47F2CEB00333491ABEE288C5 /* PlatformApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PlatformApp.swift"; sourceTree = "<group>"; };
63F8C700FA4E43818AA54E03 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIClient.swift"; sourceTree = "<group>"; };
E4094EAAB413433FA0D70AB9 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AuthManager.swift"; sourceTree = "<group>"; };
879AEC4095F64FE7B851B6F9 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoginView.swift"; sourceTree = "<group>"; };
5F36ACA2BA1243B0B8954E8F /* AssistantChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssistantChatView.swift"; sourceTree = "<group>"; };
F4073DF36CE74BB4A5B4F22A /* AssistantViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssistantViewModel.swift"; sourceTree = "<group>"; };
E149FC023D964ADA86C96EB5 /* FitnessAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessAPI.swift"; sourceTree = "<group>"; };
B4DF9C7493C2402A8B8571DB /* FitnessModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessModels.swift"; sourceTree = "<group>"; };
6D82B05FA8D84CA98E18C0E2 /* FitnessRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessRepository.swift"; sourceTree = "<group>"; };
1822D8E4AFBF4B14A5E79050 /* FoodSearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodSearchViewModel.swift"; sourceTree = "<group>"; };
DCDED359C0EE4CC2986AE602 /* GoalsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GoalsViewModel.swift"; sourceTree = "<group>"; };
4FED646258BA4DFA8D6078EC /* TemplatesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TemplatesViewModel.swift"; sourceTree = "<group>"; };
B4F05CCCEE9A4E0FA6BC6795 /* TodayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TodayViewModel.swift"; sourceTree = "<group>"; };
8C60F0E61463489689BC84E3 /* AddFoodSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AddFoodSheet.swift"; sourceTree = "<group>"; };
3C3C34A418B5428A8B2A62B7 /* EntryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EntryDetailView.swift"; sourceTree = "<group>"; };
A5D994E5BA694983BA293390 /* FitnessTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FitnessTabView.swift"; sourceTree = "<group>"; };
27103840483E431EB0275752 /* FoodLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodLibraryView.swift"; sourceTree = "<group>"; };
A98379942DAA4FB992CE1A33 /* FoodSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FoodSearchView.swift"; sourceTree = "<group>"; };
A511884CFF6D40198C9A326B /* GoalsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GoalsView.swift"; sourceTree = "<group>"; };
6EA9E7B0D02A4E13ADD734A4 /* MealSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MealSectionView.swift"; sourceTree = "<group>"; };
D0E59243273F494E9C1F63CB /* TemplatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TemplatesView.swift"; sourceTree = "<group>"; };
3CE2113036D74BBA9D3DA571 /* TodayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TodayView.swift"; sourceTree = "<group>"; };
FE0067210C0C4833BEF98835 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeView.swift"; sourceTree = "<group>"; };
F60B0BE1ED854A1F859C8B6F /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeViewModel.swift"; sourceTree = "<group>"; };
1D88C79EBC3A4E3791482B07 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoadingView.swift"; sourceTree = "<group>"; };
16A32CB0269E4AF79A96B241 /* MacroBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MacroBar.swift"; sourceTree = "<group>"; };
FDF6CAF2179B48C6B338233C /* MacroRing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MacroRing.swift"; sourceTree = "<group>"; };
1C04E1FF020544D08EDD3CCA /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = "<group>"; };
929DC19B5C81454EB58087AA /* Date+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
4C75844F44B444F4A8228158 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0FDDDCE767CF4BF6B6D41677 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4B7D1D629553482DA83FE35D /* Platform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Platform.app; sourceTree = BUILT_PRODUCTS_DIR; };
B10000 /* Platform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Platform.app; sourceTree = BUILT_PRODUCTS_DIR; };
B10001 /* PlatformApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformApp.swift; sourceTree = "<group>"; };
B10002 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
B10003 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
B10004 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
B10005 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = "<group>"; };
B10006 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
B10007 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
B10008 /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = "<group>"; };
B10009 /* FitnessModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessModels.swift; sourceTree = "<group>"; };
B10010 /* FitnessAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessAPI.swift; sourceTree = "<group>"; };
B10011 /* FitnessRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessRepository.swift; sourceTree = "<group>"; };
B10012 /* FitnessTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessTabView.swift; sourceTree = "<group>"; };
B10013 /* TodayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayView.swift; sourceTree = "<group>"; };
B10014 /* MealSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealSectionView.swift; sourceTree = "<group>"; };
B10015 /* FoodSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodSearchView.swift; sourceTree = "<group>"; };
B10016 /* AddFoodSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFoodSheet.swift; sourceTree = "<group>"; };
B10018 /* TemplatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatesView.swift; sourceTree = "<group>"; };
B10019 /* GoalsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalsView.swift; sourceTree = "<group>"; };
B10020 /* EntryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryDetailView.swift; sourceTree = "<group>"; };
B10021 /* TodayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewModel.swift; sourceTree = "<group>"; };
B10022 /* FoodSearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodSearchViewModel.swift; sourceTree = "<group>"; };
B10024 /* TemplatesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatesViewModel.swift; sourceTree = "<group>"; };
B10025 /* GoalsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalsViewModel.swift; sourceTree = "<group>"; };
B10026 /* MacroRing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacroRing.swift; sourceTree = "<group>"; };
B10027 /* MacroBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacroBar.swift; sourceTree = "<group>"; };
B10028 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
B10029 /* Date+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
B10030 /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = "<group>"; };
B10031 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
B10032 /* FoodLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodLibraryView.swift; sourceTree = "<group>"; };
B10033 /* AssistantChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssistantChatView.swift; sourceTree = "<group>"; };
B10034 /* AssistantViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssistantViewModel.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
037C8FC2A4954FCE91D25A60 /* Platform */ = {
isa = PBXGroup;
children = (
029D94F090324446B082BA63 /* Platform */,
B5E96950287B4399909152DA /* Products */,
);
sourceTree = "<group>";
};
B5E96950287B4399909152DA /* Products */ = {
isa = PBXGroup;
children = (
4B7D1D629553482DA83FE35D /* Platform.app */,
);
sourceTree = "<group>";
};
029D94F090324446B082BA63 /* Platform */ = {
isa = PBXGroup;
children = (
AF8A4F2EEC3A4EB6B78AA13E /* Config.swift */,
42807C65E9754543B46DBF62 /* ContentView.swift */,
47F2CEB00333491ABEE288C5 /* PlatformApp.swift */,
0FDDDCE767CF4BF6B6D41677 /* Info.plist */,
4C75844F44B444F4A8228158 /* Assets.xcassets */,
0DA26F997DC3429889C0B23A /* Core */,
8CF6CD4493114827807F5F6D /* Features */,
047E80495324497B8522ACEC /* Shared */,
);
path = "Platform"; sourceTree = "<group>";
};
0DA26F997DC3429889C0B23A /* Core */ = {
isa = PBXGroup;
children = (
,
);
path = "Core"; sourceTree = "<group>";
};
8CF6CD4493114827807F5F6D /* Features */ = {
isa = PBXGroup;
children = (
824CFF8CF00F41C590FB148C /* Auth */,
DAD6984656494252A7E8A5DC /* Home */,
C94148B12F3443238D763D27 /* Fitness */,
64DDC35730F64FAFA4F2962C /* Assistant */,
);
path = "Features"; sourceTree = "<group>";
};
824CFF8CF00F41C590FB148C /* Auth */ = {
isa = PBXGroup;
children = (
,
);
path = "Auth"; sourceTree = "<group>";
};
DAD6984656494252A7E8A5DC /* Home */ = {
isa = PBXGroup;
children = (
,
);
path = "Home"; sourceTree = "<group>";
};
64DDC35730F64FAFA4F2962C /* Assistant */ = {
isa = PBXGroup;
children = (
,
);
path = "Assistant"; sourceTree = "<group>";
};
C94148B12F3443238D763D27 /* Fitness */ = {
isa = PBXGroup;
children = (
822A533A33DF4047882688E2 /* Models */,
969F179A1EB645CCBAECE591 /* API */,
A5B64A87024F4F66B4A5D8B4 /* Repository */,
4B89164541C1493A80664F6D /* ViewModels */,
BB4E0BAFB7DA45A68F0480A4 /* Views */,
);
path = "Fitness"; sourceTree = "<group>";
};
969F179A1EB645CCBAECE591 /* API */ = {
isa = PBXGroup;
children = (
,
);
path = "API"; sourceTree = "<group>";
};
822A533A33DF4047882688E2 /* Models */ = {
isa = PBXGroup;
children = (
,
);
path = "Models"; sourceTree = "<group>";
};
A5B64A87024F4F66B4A5D8B4 /* Repository */ = {
isa = PBXGroup;
children = (
,
);
path = "Repository"; sourceTree = "<group>";
};
4B89164541C1493A80664F6D /* ViewModels */ = {
isa = PBXGroup;
children = (
,
);
path = "ViewModels"; sourceTree = "<group>";
};
BB4E0BAFB7DA45A68F0480A4 /* Views */ = {
isa = PBXGroup;
children = (
,
);
path = "Views"; sourceTree = "<group>";
};
047E80495324497B8522ACEC /* Shared */ = {
isa = PBXGroup;
children = (
7F73AF13180C459B8275CD39 /* Components */,
D3B81404D3A24B66B6848BB6 /* Extensions */,
);
path = "Shared"; sourceTree = "<group>";
};
7F73AF13180C459B8275CD39 /* Components */ = {
isa = PBXGroup;
children = (
,
);
path = "Components"; sourceTree = "<group>";
};
D3B81404D3A24B66B6848BB6 /* Extensions */ = {
isa = PBXGroup;
children = (
,
);
path = "Extensions"; sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B66E7E9630EA415E95CE3A85 /* Platform */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0025AB77304B486EB7AE3B2B /* Build configuration list for PBXNativeTarget "Platform" */;
buildPhases = (
F8ADC26469734B15B38E123A /* Sources */,
078D546291EB4BBFA91F6661 /* Frameworks */,
841189B510034E9A81A14A8C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Platform;
productName = Platform;
productReference = 4B7D1D629553482DA83FE35D /* Platform.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1C4E1290ED4B4E0D832C6DD0 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1540;
};
buildConfigurationList = E9E082A339DE4D0DAF491E2B /* Build configuration list for PBXProject "Platform" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 037C8FC2A4954FCE91D25A60 /* Platform */;
productRefGroup = B5E96950287B4399909152DA /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B66E7E9630EA415E95CE3A85 /* Platform */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
841189B510034E9A81A14A8C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F1AA651AF622471EA697E2CA /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F8ADC26469734B15B38E123A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F0819A9915F94DECBA67FA89 /* Config.swift in Sources */,
DD3F166E894F43848CE426C7 /* ContentView.swift in Sources */,
C9B59C679DF04512BF9F5C69 /* PlatformApp.swift in Sources */,
F35DB630BE0A46799AEC15A5 /* APIClient.swift in Sources */,
B20540C8E87F42C2AF4AB477 /* AuthManager.swift in Sources */,
779FB7AAB0244CB68E5C69C8 /* LoginView.swift in Sources */,
FB0A7F362F5944C0BF0365C5 /* AssistantChatView.swift in Sources */,
45E92CD7F85A49BFA5C05F20 /* AssistantViewModel.swift in Sources */,
2BC13A589E944CE3A4C6B708 /* FitnessAPI.swift in Sources */,
F7F65E02FB974FACA76AFAF4 /* FitnessModels.swift in Sources */,
CF63000DFF4F4F728281A31D /* FitnessRepository.swift in Sources */,
400DCD1DE0534E9E856319F8 /* FoodSearchViewModel.swift in Sources */,
96AFE69ACFB54D97A7C3A4A0 /* GoalsViewModel.swift in Sources */,
84CFFF27A99940B5875A65DA /* TemplatesViewModel.swift in Sources */,
03EBDF20EDF547EDB4B177CF /* TodayViewModel.swift in Sources */,
92E276F3CA8D4400827B2F99 /* AddFoodSheet.swift in Sources */,
C1D87BF5F61847BD952F5C65 /* EntryDetailView.swift in Sources */,
E48F9E44708544D781FC8ACD /* FitnessTabView.swift in Sources */,
2F5AF62DD13D4B0EB8E338A0 /* FoodLibraryView.swift in Sources */,
6FE7AC0C375242398A5118B4 /* FoodSearchView.swift in Sources */,
8064B019D0B742749713A35E /* GoalsView.swift in Sources */,
060E0115D90647A593BCF8B7 /* MealSectionView.swift in Sources */,
7902B9F4789C4C6FB080AF0D /* TemplatesView.swift in Sources */,
A74F6C2CDEF4487383684BB9 /* TodayView.swift in Sources */,
75DB623876D54D0BAF32B59F /* HomeView.swift in Sources */,
340D12BB6F234169953639F6 /* HomeViewModel.swift in Sources */,
D2CF33B6FE4142CA9995E125 /* LoadingView.swift in Sources */,
CF9C74396EA449D2BDEBAA09 /* MacroBar.swift in Sources */,
C6D6C2D5882245A895C8B606 /* MacroRing.swift in Sources */,
86D08C3CC8B34AEDB1254EC1 /* Color+Extensions.swift in Sources */,
C367EA266AED4AB7842B8A6F /* Date+Extensions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXFrameworksBuildPhase section */
078D546291EB4BBFA91F6661 /* Frameworks */ = {
C10001 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -324,81 +87,419 @@
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
G10000 = {
isa = PBXGroup;
children = (
G10001 /* Platform */,
G10099 /* Products */,
);
sourceTree = "<group>";
};
G10001 /* Platform */ = {
isa = PBXGroup;
children = (
B10001 /* PlatformApp.swift */,
B10002 /* ContentView.swift */,
B10003 /* Config.swift */,
B10031 /* Assets.xcassets */,
G10002 /* Core */,
G10003 /* Features */,
G10004 /* Shared */,
);
path = Platform;
sourceTree = "<group>";
};
G10002 /* Core */ = {
isa = PBXGroup;
children = (
B10004 /* APIClient.swift */,
B10005 /* AuthManager.swift */,
);
path = Core;
sourceTree = "<group>";
};
G10003 /* Features */ = {
isa = PBXGroup;
children = (
G10010 /* Auth */,
G10011 /* Home */,
G10012 /* Fitness */,
G10018 /* Assistant */,
);
path = Features;
sourceTree = "<group>";
};
G10004 /* Shared */ = {
isa = PBXGroup;
children = (
G10005 /* Components */,
G10006 /* Extensions */,
);
path = Shared;
sourceTree = "<group>";
};
G10005 /* Components */ = {
isa = PBXGroup;
children = (
B10026 /* MacroRing.swift */,
B10027 /* MacroBar.swift */,
B10028 /* LoadingView.swift */,
);
path = Components;
sourceTree = "<group>";
};
G10006 /* Extensions */ = {
isa = PBXGroup;
children = (
B10029 /* Date+Extensions.swift */,
B10030 /* Color+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
G10010 /* Auth */ = {
isa = PBXGroup;
children = (
B10006 /* LoginView.swift */,
);
path = Auth;
sourceTree = "<group>";
};
G10011 /* Home */ = {
isa = PBXGroup;
children = (
B10007 /* HomeView.swift */,
B10008 /* HomeViewModel.swift */,
);
path = Home;
sourceTree = "<group>";
};
G10012 /* Fitness */ = {
isa = PBXGroup;
children = (
G10013 /* Models */,
G10014 /* API */,
G10015 /* Repository */,
G10016 /* Views */,
G10017 /* ViewModels */,
);
path = Fitness;
sourceTree = "<group>";
};
G10013 /* Models */ = {
isa = PBXGroup;
children = (
B10009 /* FitnessModels.swift */,
);
path = Models;
sourceTree = "<group>";
};
G10014 /* API */ = {
isa = PBXGroup;
children = (
B10010 /* FitnessAPI.swift */,
);
path = API;
sourceTree = "<group>";
};
G10015 /* Repository */ = {
isa = PBXGroup;
children = (
B10011 /* FitnessRepository.swift */,
);
path = Repository;
sourceTree = "<group>";
};
G10016 /* Views */ = {
isa = PBXGroup;
children = (
B10012 /* FitnessTabView.swift */,
B10013 /* TodayView.swift */,
B10014 /* MealSectionView.swift */,
B10015 /* FoodSearchView.swift */,
B10016 /* AddFoodSheet.swift */,
B10018 /* TemplatesView.swift */,
B10019 /* GoalsView.swift */,
B10020 /* EntryDetailView.swift */,
B10032 /* FoodLibraryView.swift */,
);
path = Views;
sourceTree = "<group>";
};
G10017 /* ViewModels */ = {
isa = PBXGroup;
children = (
B10021 /* TodayViewModel.swift */,
B10022 /* FoodSearchViewModel.swift */,
B10024 /* TemplatesViewModel.swift */,
B10025 /* GoalsViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
};
G10018 /* Assistant */ = {
isa = PBXGroup;
children = (
B10033 /* AssistantChatView.swift */,
B10034 /* AssistantViewModel.swift */,
);
path = Assistant;
sourceTree = "<group>";
};
G10099 /* Products */ = {
isa = PBXGroup;
children = (
B10000 /* Platform.app */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
T10001 /* Platform */ = {
isa = PBXNativeTarget;
buildConfigurationList = CL10002 /* Build configuration list for PBXNativeTarget "Platform" */;
buildPhases = (
S10001 /* Sources */,
C10001 /* Frameworks */,
R10001 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Platform;
productName = Platform;
productReference = B10000 /* Platform.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
P10001 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1540;
TargetAttributes = {
T10001 = {
CreatedOnToolsVersion = 15.4;
};
};
};
buildConfigurationList = CL10001 /* Build configuration list for PBXProject "Platform" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = G10000;
productRefGroup = G10099 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
T10001 /* Platform */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
R10001 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A10031 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
S10001 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A10001 /* PlatformApp.swift in Sources */,
A10002 /* ContentView.swift in Sources */,
A10003 /* Config.swift in Sources */,
A10004 /* APIClient.swift in Sources */,
A10005 /* AuthManager.swift in Sources */,
A10006 /* LoginView.swift in Sources */,
A10007 /* HomeView.swift in Sources */,
A10008 /* HomeViewModel.swift in Sources */,
A10009 /* FitnessModels.swift in Sources */,
A10010 /* FitnessAPI.swift in Sources */,
A10011 /* FitnessRepository.swift in Sources */,
A10012 /* FitnessTabView.swift in Sources */,
A10013 /* TodayView.swift in Sources */,
A10014 /* MealSectionView.swift in Sources */,
A10015 /* FoodSearchView.swift in Sources */,
A10016 /* AddFoodSheet.swift in Sources */,
A10018 /* TemplatesView.swift in Sources */,
A10019 /* GoalsView.swift in Sources */,
A10020 /* EntryDetailView.swift in Sources */,
A10021 /* TodayViewModel.swift in Sources */,
A10022 /* FoodSearchViewModel.swift in Sources */,
A10024 /* TemplatesViewModel.swift in Sources */,
A10025 /* GoalsViewModel.swift in Sources */,
A10026 /* MacroRing.swift in Sources */,
A10027 /* MacroBar.swift in Sources */,
A10028 /* LoadingView.swift in Sources */,
A10029 /* Date+Extensions.swift in Sources */,
A10030 /* Color+Extensions.swift in Sources */,
A10032 /* FoodLibraryView.swift in Sources */,
A10033 /* AssistantChatView.swift in Sources */,
A10034 /* AssistantViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
B7446285A53C413C9BA0229C /* Debug */ = {
BC10001 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASCETECHNOLOGIES_AWARE = YES;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
D697F1D80CFA4E629D58BE0A /* Release */ = {
BC10002 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C29C67A4DC4943FB8112E677 /* Debug */ = {
BC10003 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = CRN5A2VZ79;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Platform/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.platform;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.Platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
@@ -408,28 +509,28 @@
};
name = Debug;
};
5289CC82B720470DA5F3181B /* Release */ = {
BC10004 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = CRN5A2VZ79;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Platform/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.platform;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.Platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
@@ -442,26 +543,25 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
E9E082A339DE4D0DAF491E2B /* Build configuration list for PBXProject "Platform" */ = {
CL10001 /* Build configuration list for PBXProject "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B7446285A53C413C9BA0229C /* Debug */,
D697F1D80CFA4E629D58BE0A /* Release */,
BC10001 /* Debug */,
BC10002 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0025AB77304B486EB7AE3B2B /* Build configuration list for PBXNativeTarget "Platform" */ = {
CL10002 /* Build configuration list for PBXNativeTarget "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C29C67A4DC4943FB8112E677 /* Debug */,
5289CC82B720470DA5F3181B /* Release */,
BC10003 /* Debug */,
BC10004 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 1C4E1290ED4B4E0D832C6DD0 /* Project object */;
rootObject = P10001 /* Project object */;
}

View File

@@ -0,0 +1,575 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
A10001 /* PlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10001 /* PlatformApp.swift */; };
A10002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10002 /* ContentView.swift */; };
A10003 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10003 /* Config.swift */; };
A10004 /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10004 /* APIClient.swift */; };
A10005 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10005 /* AuthManager.swift */; };
A10006 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10006 /* LoginView.swift */; };
A10007 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10007 /* HomeView.swift */; };
A10008 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10008 /* HomeViewModel.swift */; };
A10009 /* FitnessModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10009 /* FitnessModels.swift */; };
A10010 /* FitnessAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10010 /* FitnessAPI.swift */; };
A10011 /* FitnessRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10011 /* FitnessRepository.swift */; };
A10012 /* FitnessTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10012 /* FitnessTabView.swift */; };
A10013 /* TodayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10013 /* TodayView.swift */; };
A10014 /* MealSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10014 /* MealSectionView.swift */; };
A10015 /* FoodSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10015 /* FoodSearchView.swift */; };
A10016 /* AddFoodSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10016 /* AddFoodSheet.swift */; };
A10017 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10017 /* HistoryView.swift */; };
A10018 /* TemplatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10018 /* TemplatesView.swift */; };
A10019 /* GoalsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10019 /* GoalsView.swift */; };
A10020 /* EntryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10020 /* EntryDetailView.swift */; };
A10021 /* TodayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10021 /* TodayViewModel.swift */; };
A10022 /* FoodSearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10022 /* FoodSearchViewModel.swift */; };
A10023 /* HistoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10023 /* HistoryViewModel.swift */; };
A10024 /* TemplatesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10024 /* TemplatesViewModel.swift */; };
A10025 /* GoalsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10025 /* GoalsViewModel.swift */; };
A10026 /* MacroRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10026 /* MacroRing.swift */; };
A10027 /* MacroBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10027 /* MacroBar.swift */; };
A10028 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10028 /* LoadingView.swift */; };
A10029 /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10029 /* Date+Extensions.swift */; };
A10030 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10030 /* Color+Extensions.swift */; };
A10031 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B10031 /* Assets.xcassets */; };
A10032 /* FoodLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10032 /* FoodLibraryView.swift */; };
F2B322572F7F89B600368ED5 /* AssistantChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2B322562F7F89B600368ED5 /* AssistantChatView.swift */; };
F2B322592F7F89CC00368ED5 /* AssistantViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2B322582F7F89CC00368ED5 /* AssistantViewModel.swift */; };
F2B3225B2F7F89DC00368ED5 /* AssistantModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2B3225A2F7F89DC00368ED5 /* AssistantModels.swift */; };
F2B3225D2F7F89EF00368ED5 /* ImageCropView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2B3225C2F7F89EF00368ED5 /* ImageCropView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
B10000 /* Platform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Platform.app; sourceTree = BUILT_PRODUCTS_DIR; };
B10001 /* PlatformApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformApp.swift; sourceTree = "<group>"; };
B10002 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
B10003 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
B10004 /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
B10005 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = "<group>"; };
B10006 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
B10007 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
B10008 /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = "<group>"; };
B10009 /* FitnessModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessModels.swift; sourceTree = "<group>"; };
B10010 /* FitnessAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessAPI.swift; sourceTree = "<group>"; };
B10011 /* FitnessRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessRepository.swift; sourceTree = "<group>"; };
B10012 /* FitnessTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitnessTabView.swift; sourceTree = "<group>"; };
B10013 /* TodayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayView.swift; sourceTree = "<group>"; };
B10014 /* MealSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealSectionView.swift; sourceTree = "<group>"; };
B10015 /* FoodSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodSearchView.swift; sourceTree = "<group>"; };
B10016 /* AddFoodSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFoodSheet.swift; sourceTree = "<group>"; };
B10017 /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = "<group>"; };
B10018 /* TemplatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatesView.swift; sourceTree = "<group>"; };
B10019 /* GoalsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalsView.swift; sourceTree = "<group>"; };
B10020 /* EntryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryDetailView.swift; sourceTree = "<group>"; };
B10021 /* TodayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewModel.swift; sourceTree = "<group>"; };
B10022 /* FoodSearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodSearchViewModel.swift; sourceTree = "<group>"; };
B10023 /* HistoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryViewModel.swift; sourceTree = "<group>"; };
B10024 /* TemplatesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatesViewModel.swift; sourceTree = "<group>"; };
B10025 /* GoalsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalsViewModel.swift; sourceTree = "<group>"; };
B10026 /* MacroRing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacroRing.swift; sourceTree = "<group>"; };
B10027 /* MacroBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacroBar.swift; sourceTree = "<group>"; };
B10028 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
B10029 /* Date+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
B10030 /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = "<group>"; };
B10031 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
B10032 /* FoodLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoodLibraryView.swift; sourceTree = "<group>"; };
F2B322562F7F89B600368ED5 /* AssistantChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AssistantChatView.swift; path = Platform/Features/Assistant/AssistantChatView.swift; sourceTree = "<group>"; };
F2B322582F7F89CC00368ED5 /* AssistantViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AssistantViewModel.swift; path = Platform/Features/Assistant/AssistantViewModel.swift; sourceTree = "<group>"; };
F2B3225A2F7F89DC00368ED5 /* AssistantModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AssistantModels.swift; path = Platform/Features/Assistant/Models/AssistantModels.swift; sourceTree = "<group>"; };
F2B3225C2F7F89EF00368ED5 /* ImageCropView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ImageCropView.swift; path = Platform/Features/Home/ImageCropView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C10001 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
G10000 = {
isa = PBXGroup;
children = (
F2B3225C2F7F89EF00368ED5 /* ImageCropView.swift */,
F2B3225A2F7F89DC00368ED5 /* AssistantModels.swift */,
F2B322582F7F89CC00368ED5 /* AssistantViewModel.swift */,
F2B322562F7F89B600368ED5 /* AssistantChatView.swift */,
G10001 /* Platform */,
G10099 /* Products */,
);
sourceTree = "<group>";
};
G10001 /* Platform */ = {
isa = PBXGroup;
children = (
B10001 /* PlatformApp.swift */,
B10002 /* ContentView.swift */,
B10003 /* Config.swift */,
B10031 /* Assets.xcassets */,
G10002 /* Core */,
G10003 /* Features */,
G10004 /* Shared */,
);
path = Platform;
sourceTree = "<group>";
};
G10002 /* Core */ = {
isa = PBXGroup;
children = (
B10004 /* APIClient.swift */,
B10005 /* AuthManager.swift */,
);
path = Core;
sourceTree = "<group>";
};
G10003 /* Features */ = {
isa = PBXGroup;
children = (
G10010 /* Auth */,
G10011 /* Home */,
G10012 /* Fitness */,
);
path = Features;
sourceTree = "<group>";
};
G10004 /* Shared */ = {
isa = PBXGroup;
children = (
G10005 /* Components */,
G10006 /* Extensions */,
);
path = Shared;
sourceTree = "<group>";
};
G10005 /* Components */ = {
isa = PBXGroup;
children = (
B10026 /* MacroRing.swift */,
B10027 /* MacroBar.swift */,
B10028 /* LoadingView.swift */,
);
path = Components;
sourceTree = "<group>";
};
G10006 /* Extensions */ = {
isa = PBXGroup;
children = (
B10029 /* Date+Extensions.swift */,
B10030 /* Color+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
G10010 /* Auth */ = {
isa = PBXGroup;
children = (
B10006 /* LoginView.swift */,
);
path = Auth;
sourceTree = "<group>";
};
G10011 /* Home */ = {
isa = PBXGroup;
children = (
B10007 /* HomeView.swift */,
B10008 /* HomeViewModel.swift */,
);
path = Home;
sourceTree = "<group>";
};
G10012 /* Fitness */ = {
isa = PBXGroup;
children = (
G10013 /* Models */,
G10014 /* API */,
G10015 /* Repository */,
G10016 /* Views */,
G10017 /* ViewModels */,
);
path = Fitness;
sourceTree = "<group>";
};
G10013 /* Models */ = {
isa = PBXGroup;
children = (
B10009 /* FitnessModels.swift */,
);
path = Models;
sourceTree = "<group>";
};
G10014 /* API */ = {
isa = PBXGroup;
children = (
B10010 /* FitnessAPI.swift */,
);
path = API;
sourceTree = "<group>";
};
G10015 /* Repository */ = {
isa = PBXGroup;
children = (
B10011 /* FitnessRepository.swift */,
);
path = Repository;
sourceTree = "<group>";
};
G10016 /* Views */ = {
isa = PBXGroup;
children = (
B10012 /* FitnessTabView.swift */,
B10013 /* TodayView.swift */,
B10014 /* MealSectionView.swift */,
B10015 /* FoodSearchView.swift */,
B10016 /* AddFoodSheet.swift */,
B10017 /* HistoryView.swift */,
B10018 /* TemplatesView.swift */,
B10019 /* GoalsView.swift */,
B10020 /* EntryDetailView.swift */,
B10032 /* FoodLibraryView.swift */,
);
path = Views;
sourceTree = "<group>";
};
G10017 /* ViewModels */ = {
isa = PBXGroup;
children = (
B10021 /* TodayViewModel.swift */,
B10022 /* FoodSearchViewModel.swift */,
B10023 /* HistoryViewModel.swift */,
B10024 /* TemplatesViewModel.swift */,
B10025 /* GoalsViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
};
G10099 /* Products */ = {
isa = PBXGroup;
children = (
B10000 /* Platform.app */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
T10001 /* Platform */ = {
isa = PBXNativeTarget;
buildConfigurationList = CL10002 /* Build configuration list for PBXNativeTarget "Platform" */;
buildPhases = (
S10001 /* Sources */,
C10001 /* Frameworks */,
R10001 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Platform;
productName = Platform;
productReference = B10000 /* Platform.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
P10001 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1540;
TargetAttributes = {
T10001 = {
CreatedOnToolsVersion = 15.4;
};
};
};
buildConfigurationList = CL10001 /* Build configuration list for PBXProject "Platform" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = G10000;
productRefGroup = G10099 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
T10001 /* Platform */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
R10001 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A10031 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
S10001 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A10001 /* PlatformApp.swift in Sources */,
F2B322592F7F89CC00368ED5 /* AssistantViewModel.swift in Sources */,
A10002 /* ContentView.swift in Sources */,
A10003 /* Config.swift in Sources */,
A10004 /* APIClient.swift in Sources */,
A10005 /* AuthManager.swift in Sources */,
A10006 /* LoginView.swift in Sources */,
A10007 /* HomeView.swift in Sources */,
F2B322572F7F89B600368ED5 /* AssistantChatView.swift in Sources */,
A10008 /* HomeViewModel.swift in Sources */,
F2B3225B2F7F89DC00368ED5 /* AssistantModels.swift in Sources */,
A10009 /* FitnessModels.swift in Sources */,
A10010 /* FitnessAPI.swift in Sources */,
A10011 /* FitnessRepository.swift in Sources */,
A10012 /* FitnessTabView.swift in Sources */,
A10013 /* TodayView.swift in Sources */,
A10014 /* MealSectionView.swift in Sources */,
A10015 /* FoodSearchView.swift in Sources */,
A10016 /* AddFoodSheet.swift in Sources */,
A10017 /* HistoryView.swift in Sources */,
A10018 /* TemplatesView.swift in Sources */,
A10019 /* GoalsView.swift in Sources */,
A10020 /* EntryDetailView.swift in Sources */,
A10021 /* TodayViewModel.swift in Sources */,
A10022 /* FoodSearchViewModel.swift in Sources */,
A10023 /* HistoryViewModel.swift in Sources */,
A10024 /* TemplatesViewModel.swift in Sources */,
A10025 /* GoalsViewModel.swift in Sources */,
A10026 /* MacroRing.swift in Sources */,
A10027 /* MacroBar.swift in Sources */,
A10028 /* LoadingView.swift in Sources */,
A10029 /* Date+Extensions.swift in Sources */,
A10030 /* Color+Extensions.swift in Sources */,
F2B3225D2F7F89EF00368ED5 /* ImageCropView.swift in Sources */,
A10032 /* FoodLibraryView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
BC10001 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
BC10002 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
BC10003 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = CRN5A2VZ79;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.Platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
BC10004 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = CRN5A2VZ79;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = Platform;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.quadjourney.Platform;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CL10001 /* Build configuration list for PBXProject "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BC10001 /* Debug */,
BC10002 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CL10002 /* Build configuration list for PBXNativeTarget "Platform" */ = {
isa = XCConfigurationList;
buildConfigurations = (
BC10003 /* Debug */,
BC10004 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = P10001 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -38,6 +38,6 @@ struct MainTabView: View {
}
.tag(1)
}
.tint(.accent)
.tint(.accentWarm)
}
}

View File

@@ -33,10 +33,10 @@ struct AssistantChatView: View {
} label: {
Text(tab.rawValue)
.font(.subheadline.bold())
.foregroundStyle(selectedTab == tab ? Color.accent : Color.textSecondary)
.foregroundStyle(selectedTab == tab ? Color.accentWarm : Color.textSecondary)
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
.background(selectedTab == tab ? Color.accent.opacity(0.1) : Color.clear)
.background(selectedTab == tab ? Color.accentWarm.opacity(0.1) : Color.clear)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}
@@ -83,7 +83,7 @@ struct AssistantChatView: View {
if vm.isLoading {
HStack {
ProgressView()
.tint(Color.accent)
.tint(Color.accentWarm)
Text("Thinking...")
.font(.caption)
.foregroundStyle(Color.textSecondary)
@@ -122,7 +122,7 @@ struct AssistantChatView: View {
), matching: .images) {
Image(systemName: vm.photoData != nil ? "photo.fill" : "photo")
.font(.title3)
.foregroundStyle(vm.photoData != nil ? Color.accent : Color.textSecondary)
.foregroundStyle(vm.photoData != nil ? Color.accentWarm : Color.textSecondary)
}
TextField("Ask anything...", text: $vm.inputText)
@@ -141,7 +141,7 @@ struct AssistantChatView: View {
} label: {
Image(systemName: "arrow.up.circle.fill")
.font(.title2)
.foregroundStyle(vm.inputText.isEmpty && vm.photoData == nil ? Color.textTertiary : Color.accent)
.foregroundStyle(vm.inputText.isEmpty && vm.photoData == nil ? Color.textTertiary : Color.accentWarm)
}
.disabled(vm.inputText.isEmpty && vm.photoData == nil)
}
@@ -212,10 +212,10 @@ struct AssistantChatView: View {
Spacer()
Text(draft.mealType.capitalized)
.font(.caption2.bold())
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
.padding(.horizontal, 8)
.padding(.vertical, 3)
.background(Color.accent.opacity(0.1))
.background(Color.accentWarm.opacity(0.1))
.clipShape(RoundedRectangle(cornerRadius: 6))
}
@@ -276,10 +276,10 @@ struct AssistantChatView: View {
.font(.caption2)
.lineLimit(1)
}
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(Color.accent.opacity(0.08))
.background(Color.accentWarm.opacity(0.08))
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}

View File

@@ -13,7 +13,7 @@ struct LoginView: View {
VStack(spacing: 8) {
Image(systemName: "square.grid.2x2.fill")
.font(.system(size: 48))
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
Text("Platform")
.font(.system(size: 32, weight: .bold, design: .rounded))
.foregroundStyle(Color.textPrimary)
@@ -67,7 +67,7 @@ struct LoginView: View {
.frame(height: 48)
}
.buttonStyle(.borderedProminent)
.tint(Color.accent)
.tint(Color.accentWarm)
.clipShape(RoundedRectangle(cornerRadius: 12))
.padding(.horizontal, 32)
.disabled(username.isEmpty || password.isEmpty || isLoading)

View File

@@ -11,12 +11,12 @@ struct FitnessAPI {
try await api.post("/api/fitness/entries", body: req)
}
func updateEntry(id: Int, quantity: Double) async throws -> FoodEntry {
func updateEntry(id: String, quantity: Double) async throws -> FoodEntry {
struct Body: Encodable { let quantity: Double }
return try await api.patch("/api/fitness/entries/\(id)", body: Body(quantity: quantity))
}
func deleteEntry(id: Int) async throws {
func deleteEntry(id: String) async throws {
try await api.delete("/api/fitness/entries/\(id)")
}
@@ -33,7 +33,7 @@ struct FitnessAPI {
try await api.get("/api/fitness/foods/recent?limit=\(limit)")
}
func getFood(id: Int) async throws -> FoodItem {
func getFood(id: String) async throws -> FoodItem {
try await api.get("/api/fitness/foods/\(id)")
}
@@ -49,7 +49,7 @@ struct FitnessAPI {
try await api.get("/api/fitness/templates")
}
func logTemplate(id: Int, date: String) async throws {
func logTemplate(id: String, date: String) async throws {
struct Empty: Decodable {}
let _: Empty = try await api.post("/api/fitness/templates/\(id)/log?date=\(date)")
}

View File

@@ -32,175 +32,227 @@ enum MealType: String, Codable, CaseIterable, Identifiable {
}
// MARK: - Food Entry
// API fields (snake_case) are auto-converted to camelCase by decoder.
// The API returns snapshot_food_name, snapshot_calories, etc. no top-level food_name/calories.
struct FoodEntry: Identifiable, Codable {
let id: Int
let userId: Int?
let foodId: Int?
let id: String
let userId: String?
let foodId: String?
let mealType: MealType
let quantity: Double
let entryDate: String
let foodName: String
let calories: Double
let protein: Double
let carbs: Double
let fat: Double
let sugar: Double?
let fiber: Double?
let servingSize: String?
let imageFilename: String?
let entryType: String?
let unit: String?
let servingDescription: String?
let snapshotFoodName: String?
let snapshotServingLabel: String?
let snapshotCalories: Double
let snapshotProtein: Double
let snapshotCarbs: Double
let snapshotFat: Double
let snapshotSugar: Double?
let snapshotFiber: Double?
let foodImagePath: String?
let note: String?
let entryMethod: String?
enum CodingKeys: String, CodingKey {
case id
case userId = "user_id"
case foodId = "food_id"
case mealType = "meal_type"
case quantity
case entryDate = "entry_date"
case foodName = "food_name"
case snapshotFoodName = "snapshot_food_name"
case calories, protein, carbs, fat, sugar, fiber
case servingSize = "serving_size"
case imageFilename = "image_filename"
}
// Computed convenience accessors used by views
var foodName: String { snapshotFoodName ?? "Unknown" }
var calories: Double { snapshotCalories }
var protein: Double { snapshotProtein }
var carbs: Double { snapshotCarbs }
var fat: Double { snapshotFat }
var sugar: Double? { snapshotSugar }
var fiber: Double? { snapshotFiber }
var imageFilename: String? { foodImagePath }
// No CodingKeys needed convertFromSnakeCase handles all mappings.
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
id = try Self.decodeIntFlex(c, .id)
userId = try? Self.decodeIntFlex(c, .userId)
foodId = try? Self.decodeIntFlex(c, .foodId)
mealType = try c.decode(MealType.self, forKey: .mealType)
quantity = try Self.decodeDoubleFlex(c, .quantity)
entryDate = try c.decode(String.self, forKey: .entryDate)
// Handle food_name or snapshot_food_name
if let name = try? c.decode(String.self, forKey: .foodName) {
foodName = name
} else if let name = try? c.decode(String.self, forKey: .snapshotFoodName) {
foodName = name
} else {
foodName = "Unknown"
}
calories = try Self.decodeDoubleFlex(c, .calories)
protein = try Self.decodeDoubleFlex(c, .protein)
carbs = try Self.decodeDoubleFlex(c, .carbs)
fat = try Self.decodeDoubleFlex(c, .fat)
sugar = try? Self.decodeDoubleFlex(c, .sugar)
fiber = try? Self.decodeDoubleFlex(c, .fiber)
servingSize = try? c.decode(String.self, forKey: .servingSize)
imageFilename = try? c.decode(String.self, forKey: .imageFilename)
let c = try decoder.container(keyedBy: AnyCodingKey.self)
id = Self.decodeStringFlex(c, "id") ?? ""
userId = Self.decodeStringFlex(c, "userId")
foodId = Self.decodeStringFlex(c, "foodId")
mealType = (try? c.decode(MealType.self, forKey: AnyCodingKey("mealType"))) ?? .snack
quantity = Self.decodeDoubleFlex(c, "quantity") ?? 1.0
entryDate = (try? c.decode(String.self, forKey: AnyCodingKey("entryDate"))) ?? ""
entryType = try? c.decode(String.self, forKey: AnyCodingKey("entryType"))
unit = try? c.decode(String.self, forKey: AnyCodingKey("unit"))
servingDescription = try? c.decode(String.self, forKey: AnyCodingKey("servingDescription"))
snapshotFoodName = try? c.decode(String.self, forKey: AnyCodingKey("snapshotFoodName"))
snapshotServingLabel = try? c.decode(String.self, forKey: AnyCodingKey("snapshotServingLabel"))
snapshotCalories = Self.decodeDoubleFlex(c, "snapshotCalories") ?? 0
snapshotProtein = Self.decodeDoubleFlex(c, "snapshotProtein") ?? 0
snapshotCarbs = Self.decodeDoubleFlex(c, "snapshotCarbs") ?? 0
snapshotFat = Self.decodeDoubleFlex(c, "snapshotFat") ?? 0
snapshotSugar = Self.decodeDoubleFlex(c, "snapshotSugar")
snapshotFiber = Self.decodeDoubleFlex(c, "snapshotFiber")
foodImagePath = try? c.decode(String.self, forKey: AnyCodingKey("foodImagePath"))
note = try? c.decode(String.self, forKey: AnyCodingKey("note"))
entryMethod = try? c.decode(String.self, forKey: AnyCodingKey("entryMethod"))
}
func encode(to encoder: Encoder) throws {
var c = encoder.container(keyedBy: CodingKeys.self)
try c.encode(id, forKey: .id)
try c.encodeIfPresent(userId, forKey: .userId)
try c.encodeIfPresent(foodId, forKey: .foodId)
try c.encode(mealType, forKey: .mealType)
try c.encode(quantity, forKey: .quantity)
try c.encode(entryDate, forKey: .entryDate)
try c.encode(foodName, forKey: .foodName)
try c.encode(calories, forKey: .calories)
try c.encode(protein, forKey: .protein)
try c.encode(carbs, forKey: .carbs)
try c.encode(fat, forKey: .fat)
try c.encodeIfPresent(sugar, forKey: .sugar)
try c.encodeIfPresent(fiber, forKey: .fiber)
try c.encodeIfPresent(servingSize, forKey: .servingSize)
try c.encodeIfPresent(imageFilename, forKey: .imageFilename)
var c = encoder.container(keyedBy: AnyCodingKey.self)
try c.encode(id, forKey: AnyCodingKey("id"))
try c.encodeIfPresent(userId, forKey: AnyCodingKey("userId"))
try c.encodeIfPresent(foodId, forKey: AnyCodingKey("foodId"))
try c.encode(mealType, forKey: AnyCodingKey("mealType"))
try c.encode(quantity, forKey: AnyCodingKey("quantity"))
try c.encode(entryDate, forKey: AnyCodingKey("entryDate"))
try c.encodeIfPresent(snapshotFoodName, forKey: AnyCodingKey("snapshotFoodName"))
try c.encode(snapshotCalories, forKey: AnyCodingKey("snapshotCalories"))
try c.encode(snapshotProtein, forKey: AnyCodingKey("snapshotProtein"))
try c.encode(snapshotCarbs, forKey: AnyCodingKey("snapshotCarbs"))
try c.encode(snapshotFat, forKey: AnyCodingKey("snapshotFat"))
try c.encodeIfPresent(snapshotSugar, forKey: AnyCodingKey("snapshotSugar"))
try c.encodeIfPresent(snapshotFiber, forKey: AnyCodingKey("snapshotFiber"))
try c.encodeIfPresent(foodImagePath, forKey: AnyCodingKey("foodImagePath"))
}
// Flexible Int decoding
private static func decodeIntFlex(_ c: KeyedDecodingContainer<CodingKeys>, _ key: CodingKeys) throws -> Int {
if let v = try? c.decode(Int.self, forKey: key) { return v }
if let v = try? c.decode(Double.self, forKey: key) { return Int(v) }
if let v = try? c.decode(String.self, forKey: key), let i = Int(v) { return i }
throw DecodingError.typeMismatch(Int.self, .init(codingPath: [key], debugDescription: "Expected numeric"))
// Flexible decoding helpers
private static func decodeDoubleFlex(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String) -> Double? {
let k = AnyCodingKey(key)
if let v = try? c.decode(Double.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return Double(v) }
if let v = try? c.decode(String.self, forKey: k), let d = Double(v) { return d }
return nil
}
// Flexible Double decoding
private static func decodeDoubleFlex(_ c: KeyedDecodingContainer<CodingKeys>, _ key: CodingKeys) throws -> Double {
if let v = try? c.decode(Double.self, forKey: key) { return v }
if let v = try? c.decode(Int.self, forKey: key) { return Double(v) }
if let v = try? c.decode(String.self, forKey: key), let d = Double(v) { return d }
throw DecodingError.typeMismatch(Double.self, .init(codingPath: [key], debugDescription: "Expected numeric"))
private static func decodeStringFlex(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String) -> String? {
let k = AnyCodingKey(key)
if let v = try? c.decode(String.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return String(v) }
if let v = try? c.decode(Double.self, forKey: k) { return String(Int(v)) }
return nil
}
}
// MARK: - Food Item
// API: id (UUID string), name, brand, base_unit, calories_per_base, protein_per_base, etc.
struct FoodItem: Identifiable, Codable {
let id: Int
let id: String
let name: String
let calories: Double
let protein: Double
let carbs: Double
let fat: Double
let sugar: Double?
let fiber: Double?
let servingSize: String?
let brand: String?
let baseUnit: String?
let caloriesPerBase: Double
let proteinPerBase: Double
let carbsPerBase: Double
let fatPerBase: Double
let sugarPerBase: Double?
let fiberPerBase: Double?
let status: String?
let imageFilename: String?
let favorite: Bool?
enum CodingKeys: String, CodingKey {
case id, name, calories, protein, carbs, fat, sugar, fiber
case servingSize = "serving_size"
case imageFilename = "image_filename"
}
// Computed convenience accessors (used by views that reference .calories, .protein, etc.)
var calories: Double { caloriesPerBase }
var protein: Double { proteinPerBase }
var carbs: Double { carbsPerBase }
var fat: Double { fatPerBase }
var sugar: Double? { sugarPerBase }
var fiber: Double? { fiberPerBase }
var servingSize: String? { baseUnit }
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
if let v = try? c.decode(Int.self, forKey: .id) { id = v }
else if let v = try? c.decode(Double.self, forKey: .id) { id = Int(v) }
else { id = 0 }
name = try c.decode(String.self, forKey: .name)
calories = (try? c.decode(Double.self, forKey: .calories)) ?? Double((try? c.decode(Int.self, forKey: .calories)) ?? 0)
protein = (try? c.decode(Double.self, forKey: .protein)) ?? Double((try? c.decode(Int.self, forKey: .protein)) ?? 0)
carbs = (try? c.decode(Double.self, forKey: .carbs)) ?? Double((try? c.decode(Int.self, forKey: .carbs)) ?? 0)
fat = (try? c.decode(Double.self, forKey: .fat)) ?? Double((try? c.decode(Int.self, forKey: .fat)) ?? 0)
sugar = (try? c.decode(Double.self, forKey: .sugar)) ?? (try? c.decode(Int.self, forKey: .sugar)).map { Double($0) }
fiber = (try? c.decode(Double.self, forKey: .fiber)) ?? (try? c.decode(Int.self, forKey: .fiber)).map { Double($0) }
servingSize = try? c.decode(String.self, forKey: .servingSize)
imageFilename = try? c.decode(String.self, forKey: .imageFilename)
let c = try decoder.container(keyedBy: AnyCodingKey.self)
// id can be String or Int
if let v = try? c.decode(String.self, forKey: AnyCodingKey("id")) {
id = v
} else if let v = try? c.decode(Int.self, forKey: AnyCodingKey("id")) {
id = String(v)
} else {
id = ""
}
name = (try? c.decode(String.self, forKey: AnyCodingKey("name"))) ?? ""
brand = try? c.decode(String.self, forKey: AnyCodingKey("brand"))
baseUnit = try? c.decode(String.self, forKey: AnyCodingKey("baseUnit"))
caloriesPerBase = Self.doubleFlex(c, "caloriesPerBase")
proteinPerBase = Self.doubleFlex(c, "proteinPerBase")
carbsPerBase = Self.doubleFlex(c, "carbsPerBase")
fatPerBase = Self.doubleFlex(c, "fatPerBase")
sugarPerBase = Self.doubleFlexOpt(c, "sugarPerBase")
fiberPerBase = Self.doubleFlexOpt(c, "fiberPerBase")
status = try? c.decode(String.self, forKey: AnyCodingKey("status"))
imageFilename = try? c.decode(String.self, forKey: AnyCodingKey("imageFilename"))
favorite = try? c.decode(Bool.self, forKey: AnyCodingKey("favorite"))
}
private static func doubleFlex(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String) -> Double {
let k = AnyCodingKey(key)
if let v = try? c.decode(Double.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return Double(v) }
if let v = try? c.decode(String.self, forKey: k), let d = Double(v) { return d }
return 0
}
private static func doubleFlexOpt(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String) -> Double? {
let k = AnyCodingKey(key)
if let v = try? c.decode(Double.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return Double(v) }
if let v = try? c.decode(String.self, forKey: k), let d = Double(v) { return d }
return nil
}
}
// MARK: - Daily Goal
// API: id (UUID), calories, protein, carbs, fat, sugar, fiber, is_active
struct DailyGoal: Codable {
let id: String?
let calories: Double
let protein: Double
let carbs: Double
let fat: Double
let sugar: Double
let fiber: Double
enum CodingKeys: String, CodingKey {
case calories, protein, carbs, fat, sugar, fiber
}
let isActive: Int?
init(calories: Double = 2000, protein: Double = 150, carbs: Double = 250, fat: Double = 65, sugar: Double = 50, fiber: Double = 30) {
self.id = nil
self.calories = calories
self.protein = protein
self.carbs = carbs
self.fat = fat
self.sugar = sugar
self.fiber = fiber
self.isActive = nil
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
calories = (try? c.decode(Double.self, forKey: .calories)) ?? Double((try? c.decode(Int.self, forKey: .calories)) ?? 2000)
protein = (try? c.decode(Double.self, forKey: .protein)) ?? Double((try? c.decode(Int.self, forKey: .protein)) ?? 150)
carbs = (try? c.decode(Double.self, forKey: .carbs)) ?? Double((try? c.decode(Int.self, forKey: .carbs)) ?? 250)
fat = (try? c.decode(Double.self, forKey: .fat)) ?? Double((try? c.decode(Int.self, forKey: .fat)) ?? 65)
sugar = (try? c.decode(Double.self, forKey: .sugar)) ?? Double((try? c.decode(Int.self, forKey: .sugar)) ?? 50)
fiber = (try? c.decode(Double.self, forKey: .fiber)) ?? Double((try? c.decode(Int.self, forKey: .fiber)) ?? 30)
let c = try decoder.container(keyedBy: AnyCodingKey.self)
id = try? c.decode(String.self, forKey: AnyCodingKey("id"))
calories = Self.doubleFlex(c, "calories", default: 2000)
protein = Self.doubleFlex(c, "protein", default: 150)
carbs = Self.doubleFlex(c, "carbs", default: 250)
fat = Self.doubleFlex(c, "fat", default: 65)
sugar = Self.doubleFlex(c, "sugar", default: 50)
fiber = Self.doubleFlex(c, "fiber", default: 30)
if let v = try? c.decode(Int.self, forKey: AnyCodingKey("isActive")) {
isActive = v
} else if let v = try? c.decode(Double.self, forKey: AnyCodingKey("isActive")) {
isActive = Int(v)
} else {
isActive = nil
}
}
private static func doubleFlex(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String, default def: Double) -> Double {
let k = AnyCodingKey(key)
if let v = try? c.decode(Double.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return Double(v) }
if let v = try? c.decode(String.self, forKey: k), let d = Double(v) { return d }
return def
}
}
// MARK: - Meal Template
// API: id (UUID), name, meal_type, total_calories, total_protein, total_carbs, total_fat, item_count
struct MealTemplate: Identifiable, Codable {
let id: Int
let id: String
let name: String
let mealType: MealType
let totalCalories: Double?
@@ -209,35 +261,45 @@ struct MealTemplate: Identifiable, Codable {
let totalFat: Double?
let itemCount: Int?
enum CodingKeys: String, CodingKey {
case id, name
case mealType = "meal_type"
case totalCalories = "total_calories"
case totalProtein = "total_protein"
case totalCarbs = "total_carbs"
case totalFat = "total_fat"
case itemCount = "item_count"
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: AnyCodingKey.self)
if let v = try? c.decode(String.self, forKey: AnyCodingKey("id")) {
id = v
} else if let v = try? c.decode(Int.self, forKey: AnyCodingKey("id")) {
id = String(v)
} else {
id = ""
}
name = (try? c.decode(String.self, forKey: AnyCodingKey("name"))) ?? ""
mealType = (try? c.decode(MealType.self, forKey: AnyCodingKey("mealType"))) ?? .snack
totalCalories = Self.doubleFlexOpt(c, "totalCalories")
totalProtein = Self.doubleFlexOpt(c, "totalProtein")
totalCarbs = Self.doubleFlexOpt(c, "totalCarbs")
totalFat = Self.doubleFlexOpt(c, "totalFat")
if let v = try? c.decode(Int.self, forKey: AnyCodingKey("itemCount")) {
itemCount = v
} else if let v = try? c.decode(Double.self, forKey: AnyCodingKey("itemCount")) {
itemCount = Int(v)
} else {
itemCount = nil
}
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
if let v = try? c.decode(Int.self, forKey: .id) { id = v }
else if let v = try? c.decode(Double.self, forKey: .id) { id = Int(v) }
else { id = 0 }
name = try c.decode(String.self, forKey: .name)
mealType = try c.decode(MealType.self, forKey: .mealType)
totalCalories = (try? c.decode(Double.self, forKey: .totalCalories)) ?? (try? c.decode(Int.self, forKey: .totalCalories)).map { Double($0) }
totalProtein = (try? c.decode(Double.self, forKey: .totalProtein)) ?? (try? c.decode(Int.self, forKey: .totalProtein)).map { Double($0) }
totalCarbs = (try? c.decode(Double.self, forKey: .totalCarbs)) ?? (try? c.decode(Int.self, forKey: .totalCarbs)).map { Double($0) }
totalFat = (try? c.decode(Double.self, forKey: .totalFat)) ?? (try? c.decode(Int.self, forKey: .totalFat)).map { Double($0) }
itemCount = (try? c.decode(Int.self, forKey: .itemCount)) ?? (try? c.decode(Double.self, forKey: .itemCount)).map { Int($0) }
private static func doubleFlexOpt(_ c: KeyedDecodingContainer<AnyCodingKey>, _ key: String) -> Double? {
let k = AnyCodingKey(key)
if let v = try? c.decode(Double.self, forKey: k) { return v }
if let v = try? c.decode(Int.self, forKey: k) { return Double(v) }
if let v = try? c.decode(String.self, forKey: k), let d = Double(v) { return d }
return nil
}
}
// MARK: - Requests
// Note: APIClient uses encoder.keyEncodingStrategy = .convertToSnakeCase
// so camelCase properties are auto-converted to snake_case in JSON.
struct CreateEntryRequest: Encodable {
let foodId: Int?
let foodId: String?
let foodName: String
let mealType: String
let quantity: Double
@@ -248,15 +310,6 @@ struct CreateEntryRequest: Encodable {
let fat: Double
let sugar: Double?
let fiber: Double?
enum CodingKeys: String, CodingKey {
case foodId = "food_id"
case foodName = "food_name"
case mealType = "meal_type"
case quantity
case entryDate = "entry_date"
case calories, protein, carbs, fat, sugar, fiber
}
}
struct UpdateGoalsRequest: Encodable {
@@ -326,3 +379,25 @@ struct SourceLink: Identifiable {
self.href = (dict["href"] as? String) ?? ""
}
}
// MARK: - AnyCodingKey (flexible key lookup)
struct AnyCodingKey: CodingKey {
var stringValue: String
var intValue: Int?
init(_ string: String) {
self.stringValue = string
self.intValue = nil
}
init?(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init?(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}

View File

@@ -25,7 +25,7 @@ final class FitnessRepository {
isLoading = false
}
func deleteEntry(id: Int) async {
func deleteEntry(id: String) async {
do {
try await api.deleteEntry(id: id)
entries.removeAll { $0.id == id }
@@ -43,7 +43,7 @@ final class FitnessRepository {
}
}
func updateEntry(id: Int, quantity: Double) async -> FoodEntry? {
func updateEntry(id: String, quantity: Double) async -> FoodEntry? {
do {
let updated = try await api.updateEntry(id: id, quantity: quantity)
if let idx = entries.firstIndex(where: { $0.id == id }) {

View File

@@ -60,7 +60,7 @@ struct AddFoodSheet: View {
Button { if quantity > 0.5 { quantity -= 0.5 } } label: {
Image(systemName: "minus.circle.fill")
.font(.title2)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
Text(String(format: "%.1f", quantity))
.font(.title2.bold())
@@ -68,7 +68,7 @@ struct AddFoodSheet: View {
Button { quantity += 0.5 } label: {
Image(systemName: "plus.circle.fill")
.font(.title2)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
}
}
@@ -141,7 +141,7 @@ struct AddFoodSheet: View {
.frame(height: 48)
}
.buttonStyle(.borderedProminent)
.tint(Color.accent)
.tint(Color.accentWarm)
.clipShape(RoundedRectangle(cornerRadius: 12))
}
.padding(20)

View File

@@ -51,7 +51,7 @@ struct EntryDetailView: View {
Button { if quantity > 0.5 { quantity -= 0.5 } } label: {
Image(systemName: "minus.circle.fill")
.font(.title2)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
Text(String(format: "%.1f", quantity))
.font(.title2.bold())
@@ -59,7 +59,7 @@ struct EntryDetailView: View {
Button { quantity += 0.5 } label: {
Image(systemName: "plus.circle.fill")
.font(.title2)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
}
}
@@ -85,7 +85,7 @@ struct EntryDetailView: View {
.frame(height: 44)
}
.buttonStyle(.borderedProminent)
.tint(Color.accent)
.tint(Color.accentWarm)
.clipShape(RoundedRectangle(cornerRadius: 12))
}

View File

@@ -27,12 +27,12 @@ struct FitnessTabView: View {
Text(tab.rawValue)
.font(.subheadline)
.fontWeight(selectedTab == tab ? .bold : .medium)
.foregroundStyle(selectedTab == tab ? Color.accent : Color.textSecondary)
.foregroundStyle(selectedTab == tab ? Color.accentWarm : Color.textSecondary)
.padding(.bottom, 8)
.overlay(alignment: .bottom) {
if selectedTab == tab {
Rectangle()
.fill(Color.accent)
.fill(Color.accentWarm)
.frame(height: 2)
}
}
@@ -64,9 +64,9 @@ struct FitnessTabView: View {
.font(.title2.bold())
.foregroundStyle(.white)
.frame(width: 56, height: 56)
.background(Color.accent)
.background(Color.accentWarm)
.clipShape(Circle())
.shadow(color: Color.accent.opacity(0.3), radius: 8, y: 4)
.shadow(color: Color.accentWarm.opacity(0.3), radius: 8, y: 4)
}
.padding(.trailing, 20)
.padding(.bottom, 20)

View File

@@ -112,7 +112,7 @@ struct FoodSearchView: View {
}
Spacer()
Image(systemName: "plus.circle")
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
}
}

View File

@@ -38,7 +38,7 @@ struct GoalsView: View {
.frame(height: 48)
}
.buttonStyle(.borderedProminent)
.tint(Color.accent)
.tint(Color.accentWarm)
.clipShape(RoundedRectangle(cornerRadius: 12))
.padding(.horizontal, 16)
.disabled(vm.isSaving)

View File

@@ -90,7 +90,7 @@ struct TemplatesView: View {
.foregroundStyle(.white)
.padding(.horizontal, 12)
.padding(.vertical, 6)
.background(Color.accent)
.background(Color.accentWarm)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}

View File

@@ -12,7 +12,7 @@ struct TodayView: View {
Button { viewModel.previousDay() } label: {
Image(systemName: "chevron.left")
.font(.headline)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
Spacer()
Text(viewModel.displayDate)
@@ -22,7 +22,7 @@ struct TodayView: View {
Button { viewModel.nextDay() } label: {
Image(systemName: "chevron.right")
.font(.headline)
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
}
.padding(.horizontal, 20)

View File

@@ -58,7 +58,7 @@ struct HomeView: View {
} label: {
Image(systemName: "person.circle.fill")
.font(.title2)
.foregroundStyle(vm.backgroundImage != nil ? .white : Color.accent)
.foregroundStyle(vm.backgroundImage != nil ? .white : Color.accentWarm)
}
}
.padding(.horizontal, 20)
@@ -83,9 +83,9 @@ struct HomeView: View {
.font(.title2.bold())
.foregroundStyle(.white)
.frame(width: 56, height: 56)
.background(Color.accent)
.background(Color.accentWarm)
.clipShape(Circle())
.shadow(color: Color.accent.opacity(0.3), radius: 8, y: 4)
.shadow(color: Color.accentWarm.opacity(0.3), radius: 8, y: 4)
}
.padding(.trailing, 20)
.padding(.bottom, 20)

View File

@@ -6,7 +6,7 @@ struct LoadingView: View {
var body: some View {
VStack(spacing: 12) {
ProgressView()
.tint(.accent)
.tint(.accentWarm)
Text(message)
.font(.subheadline)
.foregroundStyle(Color.textSecondary)
@@ -32,7 +32,7 @@ struct ErrorBanner: View {
Task { await retry() }
}
.font(.subheadline.bold())
.foregroundStyle(Color.accent)
.foregroundStyle(Color.accentWarm)
}
}
.padding(12)

View File

@@ -27,8 +27,8 @@ extension Color {
static let canvas = Color(hex: "F5EFE6")
static let surface = Color(hex: "FFFFFF")
static let surfaceSecondary = Color(hex: "FAF7F2")
static let accent = Color(hex: "8B6914")
static let accentLight = Color(hex: "D4A843")
static let accentWarm = Color(hex: "8B6914")
static let accentWarmLight = Color(hex: "D4A843")
static let emerald = Color(hex: "059669")
static let textPrimary = Color(hex: "1C1917")
static let textSecondary = Color(hex: "78716C")